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