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