Salome HOME
Use nodes and elements pointer instead on IDs
[modules/smesh.git] / src / SMESHDS / SMESHDS_Mesh.cxx
1 //  SMESH SMESHDS : management of mesh data and SMESH document
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 : Yves FRICAUD, OCC
26 //  Module : SMESH
27 //  $Header: 
28
29 #include "SMESHDS_Mesh.hxx"
30 #include "SMDS_VertexPosition.hxx"
31 #include "SMDS_EdgePosition.hxx"
32 #include "SMDS_FacePosition.hxx"
33 #include <TopExp_Explorer.hxx>
34 #include <TopExp.hxx>
35
36 #include "utilities.h"
37 //=======================================================================
38 //function : Create
39 //purpose  : 
40 //=======================================================================
41 SMESHDS_Mesh::SMESHDS_Mesh(int MeshID):myMeshID(MeshID)
42 {
43         myScript = new SMESHDS_Script();
44 }
45
46 //=======================================================================
47 //function : ShapeToMesh
48 //purpose  : 
49 //=======================================================================
50 void SMESHDS_Mesh::ShapeToMesh(const TopoDS_Shape & S)
51 {
52         myShape = S;
53         TopExp::MapShapes(myShape, myIndexToShape);
54 }
55
56 //=======================================================================
57 //function : AddHypothesis
58 //purpose  : 
59 //=======================================================================
60
61 bool SMESHDS_Mesh::AddHypothesis(const TopoDS_Shape & SS,
62         const SMESHDS_Hypothesis * H)
63 {
64         list<const SMESHDS_Hypothesis *>& alist=myShapeToHypothesis[SS];
65
66         //Check if the Hypothesis is still present
67         list<const SMESHDS_Hypothesis*>::iterator ith=alist.begin();
68
69         for (; ith!=alist.end(); ith++)
70                 if (H == *ith) return false;
71
72         alist.push_back(H);
73         return true;
74 }
75
76 //=======================================================================
77 //function : RemoveHypothesis
78 //purpose  : 
79 //=======================================================================
80
81 bool SMESHDS_Mesh::RemoveHypothesis(const TopoDS_Shape & S,
82         const SMESHDS_Hypothesis * H)
83 {
84         ShapeToHypothesis::iterator its=myShapeToHypothesis.find(S);
85         if(its!=myShapeToHypothesis.end())
86         {
87                 list<const SMESHDS_Hypothesis*>::iterator ith=(*its).second.begin();
88
89                 for (; ith!=(*its).second.end(); ith++)
90                         if (H == *ith)
91                         {
92                                 (*its).second.erase(ith);
93                                 return true;
94                         }
95         }
96         return false;
97 }
98
99 //=======================================================================
100 //function : AddNode
101 //purpose  : 
102 //=======================================================================
103 SMDS_MeshNode* SMESHDS_Mesh::AddNode(double x, double y, double z)
104 {
105         SMDS_MeshNode* node = SMDS_Mesh::AddNode(x, y, z);
106         if(node!=NULL) myScript->AddNode(node->GetID(), x, y, z);
107         return node;
108 }
109
110 //=======================================================================
111 //function : MoveNode
112 //purpose  : 
113 //=======================================================================
114 void SMESHDS_Mesh::MoveNode(const SMDS_MeshNode *n, double x, double y, double z)
115 {
116         SMDS_MeshNode * node=const_cast<SMDS_MeshNode*>(n);
117         node->setXYZ(x,y,z);
118         myScript->MoveNode(n->GetID(), x, y, z);
119 }
120
121 //=======================================================================
122 //function : AddEdge
123 //purpose  : 
124 //=======================================================================
125 SMDS_MeshEdge* SMESHDS_Mesh::AddEdge(const SMDS_MeshNode * n1,
126                 const SMDS_MeshNode * n2)
127 {
128         SMDS_MeshEdge* e = SMDS_Mesh::AddEdge(n1,n2);
129         if(e!=NULL) myScript->AddEdge(e->GetID(), n1->GetID(), n2->GetID());
130         return e;
131 }
132
133 //=======================================================================
134 //function :AddFace
135 //purpose  : 
136 //=======================================================================
137 SMDS_MeshFace* SMESHDS_Mesh::AddFace( const SMDS_MeshNode * n1,
138                 const SMDS_MeshNode * n2,
139                 const SMDS_MeshNode * n3)
140 {
141         SMDS_MeshFace *f = SMDS_Mesh::AddFace(n1, n2, n3);
142         if(f!=NULL) myScript->AddFace(f->GetID(), n1->GetID(), n2->GetID(),
143                 n3->GetID());
144         return f;
145 }
146
147 //=======================================================================
148 //function :AddFace
149 //purpose  : 
150 //=======================================================================
151 SMDS_MeshFace* SMESHDS_Mesh::AddFace(const SMDS_MeshNode * n1,
152                 const SMDS_MeshNode * n2,
153                 const SMDS_MeshNode * n3,
154                 const SMDS_MeshNode * n4)
155 {
156         SMDS_MeshFace *f = SMDS_Mesh::AddFace(n1, n2, n3, n4);
157         if(f!=NULL)
158                 myScript->AddFace(f->GetID(), n1->GetID(), n2->GetID(), n3->GetID(),
159                         n4->GetID());
160         return f;
161 }
162
163 //=======================================================================
164 //function :AddVolume
165 //purpose  : 
166 //=======================================================================
167 SMDS_MeshVolume* SMESHDS_Mesh::AddVolume(
168                 const SMDS_MeshNode * n1,
169                 const SMDS_MeshNode * n2,
170                 const SMDS_MeshNode * n3,
171                 const SMDS_MeshNode * n4)
172 {
173         SMDS_MeshVolume *f = SMDS_Mesh::AddVolume(n1, n2, n3, n4);
174         if(f!=NULL)
175                 myScript->AddVolume(f->GetID(), n1->GetID(), n2->GetID(), n3->GetID(),
176                         n4->GetID());
177         return f;
178 }
179
180 //=======================================================================
181 //function :AddVolume
182 //purpose  : 
183 //=======================================================================
184 SMDS_MeshVolume* SMESHDS_Mesh::AddVolume(
185                 const SMDS_MeshNode * n1,
186                 const SMDS_MeshNode * n2,
187                 const SMDS_MeshNode * n3,
188                 const SMDS_MeshNode * n4,
189                 const SMDS_MeshNode * n5)
190 {
191         SMDS_MeshVolume *v = SMDS_Mesh::AddVolume(n1, n2, n3, n4, n5);
192         if(v!=NULL)
193                 myScript->AddVolume(v->GetID(), n1->GetID(), n2->GetID(), n3->GetID(),
194                         n4->GetID(), n5->GetID());
195         return v;
196 }
197
198 //=======================================================================
199 //function :AddVolume
200 //purpose  : 
201 //=======================================================================
202 SMDS_MeshVolume* SMESHDS_Mesh::AddVolume(
203                 const SMDS_MeshNode * n1,
204                 const SMDS_MeshNode * n2,
205                 const SMDS_MeshNode * n3,
206                 const SMDS_MeshNode * n4,
207                 const SMDS_MeshNode * n5,
208                 const SMDS_MeshNode * n6)
209 {
210         SMDS_MeshVolume *v= SMDS_Mesh::AddVolume(n1, n2, n3, n4, n5, n6);
211         if(v!=NULL) 
212                 myScript->AddVolume(v->GetID(), n1->GetID(), n2->GetID(), n3->GetID(),
213                         n4->GetID(), n5->GetID(), n6->GetID());
214         return v;
215 }
216
217 //=======================================================================
218 //function :AddVolume
219 //purpose  : 
220 //=======================================================================
221 SMDS_MeshVolume* SMESHDS_Mesh::AddVolume(
222                 const SMDS_MeshNode * n1,
223                 const SMDS_MeshNode * n2,
224                 const SMDS_MeshNode * n3,
225                 const SMDS_MeshNode * n4,
226                 const SMDS_MeshNode * n5,
227                 const SMDS_MeshNode * n6,
228                 const SMDS_MeshNode * n7,
229                 const SMDS_MeshNode * n8)
230 {
231         SMDS_MeshVolume *v=
232                 SMDS_Mesh::AddVolume(n1, n2, n3, n4, n5, n6, n7, n8);
233         if(v!=NULL)
234                 myScript->AddVolume(v->GetID(), n1->GetID(), n2->GetID(), n3->GetID(),
235                         n4->GetID(), n5->GetID(), n6->GetID(), n7->GetID(), n8->GetID());
236         return v;
237 }
238
239 //=======================================================================
240 //function : RemoveNode
241 //purpose  : 
242 //=======================================================================
243 void SMESHDS_Mesh::RemoveNode(const SMDS_MeshNode * n)
244 {
245         SMDS_Mesh::RemoveNode(n);
246         myScript->RemoveNode(n->GetID());
247 }
248
249 //=======================================================================
250 //function : RemoveElement
251 //purpose  : 
252 //========================================================================
253 void SMESHDS_Mesh::RemoveElement(const SMDS_MeshElement * elt)
254 {
255         SMDS_Mesh::RemoveElement(elt);
256         myScript->RemoveElement(elt->GetID());
257 }
258
259 //=======================================================================
260 //function : SetNodeOnVolume
261 //purpose  : 
262 //=======================================================================
263 void SMESHDS_Mesh::SetNodeInVolume(SMDS_MeshNode * aNode,
264         const TopoDS_Shell & S)
265 {
266         if (myShape.IsNull()) MESSAGE("myShape is NULL");
267
268         int Index = myIndexToShape.FindIndex(S);
269
270         //Set Position on Node
271         //Handle (SMDS_FacePosition) aPos = new SMDS_FacePosition (myFaceToId(S),0.,0.);;
272         //aNode->SetPosition(aPos);
273
274         //Update or build submesh
275         map<int,SMESHDS_SubMesh*>::iterator it=myShapeIndexToSubMesh.find(Index);
276         if (it==myShapeIndexToSubMesh.end())
277                 myShapeIndexToSubMesh[Index]= new SMESHDS_SubMesh();
278
279         myShapeIndexToSubMesh[Index]->AddNode(aNode);
280 }
281
282 //=======================================================================
283 //function : SetNodeOnFace
284 //purpose  : 
285 //=======================================================================
286 void SMESHDS_Mesh::SetNodeOnFace(SMDS_MeshNode * aNode,
287         const TopoDS_Face & S)
288 {
289         if (myShape.IsNull()) MESSAGE("myShape is NULL");
290
291         int Index = myIndexToShape.FindIndex(S);
292
293         //Set Position on Node
294         aNode->SetPosition(new SMDS_FacePosition(Index, 0., 0.));
295
296         //Update or build submesh
297         map<int,SMESHDS_SubMesh*>::iterator it=myShapeIndexToSubMesh.find(Index);
298         if (it==myShapeIndexToSubMesh.end())
299                 myShapeIndexToSubMesh[Index]= new SMESHDS_SubMesh();
300
301         myShapeIndexToSubMesh[Index]->AddNode(aNode);
302 }
303
304 //=======================================================================
305 //function : SetNodeOnEdge
306 //purpose  : 
307 //=======================================================================
308 void SMESHDS_Mesh::SetNodeOnEdge(SMDS_MeshNode * aNode,
309         const TopoDS_Edge & S)
310 {
311         if (myShape.IsNull()) MESSAGE("myShape is NULL");
312
313         int Index = myIndexToShape.FindIndex(S);
314
315         //Set Position on Node
316         aNode->SetPosition(new SMDS_EdgePosition(Index, 0.));
317
318         //Update or build submesh
319         map<int,SMESHDS_SubMesh*>::iterator it=myShapeIndexToSubMesh.find(Index);
320         if (it==myShapeIndexToSubMesh.end())
321                 myShapeIndexToSubMesh[Index]= new SMESHDS_SubMesh();
322
323         myShapeIndexToSubMesh[Index]->AddNode(aNode);
324 }
325
326 //=======================================================================
327 //function : SetNodeOnVertex
328 //purpose  : 
329 //=======================================================================
330 void SMESHDS_Mesh::SetNodeOnVertex(SMDS_MeshNode * aNode,
331         const TopoDS_Vertex & S)
332 {
333         if (myShape.IsNull()) MESSAGE("myShape is NULL");
334
335         int Index = myIndexToShape.FindIndex(S);
336
337         //Set Position on Node
338         aNode->SetPosition(new SMDS_VertexPosition(Index));
339
340         //Update or build submesh
341         map<int,SMESHDS_SubMesh*>::iterator it=myShapeIndexToSubMesh.find(Index);
342         if (it==myShapeIndexToSubMesh.end())
343                 myShapeIndexToSubMesh[Index]= new SMESHDS_SubMesh();
344
345         myShapeIndexToSubMesh[Index]->AddNode(aNode);
346 }
347
348 //=======================================================================
349 //function : UnSetNodeOnShape
350 //purpose  : 
351 //=======================================================================
352 void SMESHDS_Mesh::UnSetNodeOnShape(const SMDS_MeshNode* aNode)
353 {
354         MESSAGE("not implemented");
355 }
356
357 //=======================================================================
358 //function : SetMeshElementOnShape
359 //purpose  : 
360 //=======================================================================
361 void SMESHDS_Mesh::SetMeshElementOnShape(const SMDS_MeshElement * anElement,
362         const TopoDS_Shape & S)
363 {
364         if (myShape.IsNull()) MESSAGE("myShape is NULL");
365
366         int Index = myIndexToShape.FindIndex(S);
367
368         if (myShapeIndexToSubMesh.find(Index)==myShapeIndexToSubMesh.end())
369                 myShapeIndexToSubMesh[Index]=new SMESHDS_SubMesh();
370
371         myShapeIndexToSubMesh[Index]->AddElement(anElement);
372 }
373
374 //=======================================================================
375 //function : UnSetMeshElementOnShape
376 //purpose  : 
377 //=======================================================================
378 void SMESHDS_Mesh::
379 UnSetMeshElementOnShape(const SMDS_MeshElement * anElement,
380         const TopoDS_Shape & S)
381 {
382         if (myShape.IsNull()) MESSAGE("myShape is NULL");
383
384         int Index = myIndexToShape.FindIndex(S);
385
386         if (myShapeIndexToSubMesh.find(Index)!=myShapeIndexToSubMesh.end())
387                 myShapeIndexToSubMesh[Index]->RemoveElement(anElement);
388 }
389
390 //=======================================================================
391 //function : ShapeToMesh
392 //purpose  : 
393 //=======================================================================
394 TopoDS_Shape SMESHDS_Mesh::ShapeToMesh() const
395 {
396         return myShape;
397 }
398
399 ///////////////////////////////////////////////////////////////////////////////
400 /// Return the sub mesh linked to the a given TopoDS_Shape or NULL if the given
401 /// TopoDS_Shape is unknown
402 ///////////////////////////////////////////////////////////////////////////////
403 SMESHDS_SubMesh * SMESHDS_Mesh::MeshElements(const TopoDS_Shape & S)
404 {
405         if (myShape.IsNull()) MESSAGE("myShape is NULL");
406
407         int Index = myIndexToShape.FindIndex(S);
408         if (myShapeIndexToSubMesh.find(Index)!=myShapeIndexToSubMesh.end())
409                 return myShapeIndexToSubMesh[Index];
410         else
411                 return NULL;
412 }
413
414 //=======================================================================
415 //function : GetHypothesis
416 //purpose  : 
417 //=======================================================================
418
419 const list<const SMESHDS_Hypothesis*>& SMESHDS_Mesh::GetHypothesis(
420         const TopoDS_Shape & S) const
421 {
422         if (myShapeToHypothesis.find(S)!=myShapeToHypothesis.end())
423                 return myShapeToHypothesis.find(S)->second;
424
425         static list<const SMESHDS_Hypothesis*> empty;
426         return empty;
427 }
428
429 //=======================================================================
430 //function : GetScript
431 //purpose  : 
432 //=======================================================================
433 SMESHDS_Script* SMESHDS_Mesh::GetScript()
434 {
435         return myScript;
436 }
437
438 //=======================================================================
439 //function : ClearScript
440 //purpose  : 
441 //=======================================================================
442 void SMESHDS_Mesh::ClearScript()
443 {
444         myScript->Clear();
445 }
446
447 //=======================================================================
448 //function : HasMeshElements
449 //purpose  : 
450 //=======================================================================
451 bool SMESHDS_Mesh::HasMeshElements(const TopoDS_Shape & S)
452 {
453         if (myShape.IsNull()) MESSAGE("myShape is NULL");
454         int Index = myIndexToShape.FindIndex(S);
455         return myShapeIndexToSubMesh.find(Index)!=myShapeIndexToSubMesh.end();
456 }
457
458 //=======================================================================
459 //function : HasHypothesis
460 //purpose  : 
461 //=======================================================================
462 bool SMESHDS_Mesh::HasHypothesis(const TopoDS_Shape & S)
463 {
464         return myShapeToHypothesis.find(S)!=myShapeToHypothesis.end();
465 }
466
467 //=======================================================================
468 //function : NewSubMesh 
469 //purpose  : 
470 //=======================================================================
471 void SMESHDS_Mesh::NewSubMesh(int Index)
472 {
473         if (myShapeIndexToSubMesh.find(Index)==myShapeIndexToSubMesh.end())
474         {
475                 SMESHDS_SubMesh* SM = new SMESHDS_SubMesh();
476                 myShapeIndexToSubMesh[Index]=SM;
477         }
478 }
479
480 //=======================================================================
481 //function : IndexToShape
482 //purpose  : 
483 //=======================================================================
484 TopoDS_Shape SMESHDS_Mesh::IndexToShape(int ShapeIndex)
485 {
486         return myIndexToShape.FindKey(ShapeIndex);
487 }
488
489 //=======================================================================
490 //function : ShapeToIndex
491 //purpose  : 
492 //=======================================================================
493 int SMESHDS_Mesh::ShapeToIndex(const TopoDS_Shape & S)
494 {
495         if (myShape.IsNull()) MESSAGE("myShape is NULL");
496         return myIndexToShape.FindIndex(S);
497 }
498
499 //=======================================================================
500 //function : SetNodeOnVolume
501 //purpose  : 
502 //=======================================================================
503 void SMESHDS_Mesh::SetNodeInVolume(const SMDS_MeshNode* aNode, int Index)
504 {
505         //Set Position on Node
506         //Handle (SMDS_FacePosition) aPos = new SMDS_FacePosition (myFaceToId(S),0.,0.);;
507         //aNode->SetPosition(aPos);
508
509         //Update or build submesh
510         if (myShapeIndexToSubMesh.find(Index)==myShapeIndexToSubMesh.end())
511                 myShapeIndexToSubMesh[Index]=new SMESHDS_SubMesh();
512
513         myShapeIndexToSubMesh[Index]->AddNode(aNode);
514 }
515
516 //=======================================================================
517 //function : SetNodeOnFace
518 //purpose  : 
519 //=======================================================================
520 void SMESHDS_Mesh::SetNodeOnFace(SMDS_MeshNode* aNode, int Index)
521 {
522         //Set Position on Node
523         aNode->SetPosition(new SMDS_FacePosition(Index, 0., 0.));
524
525         //Update or build submesh
526         if (myShapeIndexToSubMesh.find(Index)==myShapeIndexToSubMesh.end())
527                 myShapeIndexToSubMesh[Index]=new SMESHDS_SubMesh();
528
529         myShapeIndexToSubMesh[Index]->AddNode(aNode);
530 }
531
532 //=======================================================================
533 //function : SetNodeOnEdge
534 //purpose  : 
535 //=======================================================================
536 void SMESHDS_Mesh::SetNodeOnEdge(SMDS_MeshNode* aNode, int Index)
537 {
538         //Set Position on Node
539         aNode->SetPosition(new SMDS_EdgePosition(Index, 0.));
540
541         //Update or build submesh
542         if (myShapeIndexToSubMesh.find(Index)==myShapeIndexToSubMesh.end())
543                 myShapeIndexToSubMesh[Index]=new SMESHDS_SubMesh();
544
545         myShapeIndexToSubMesh[Index]->AddNode(aNode);
546 }
547
548 //=======================================================================
549 //function : SetNodeOnVertex
550 //purpose  : 
551 //=======================================================================
552 void SMESHDS_Mesh::SetNodeOnVertex(SMDS_MeshNode* aNode, int Index)
553 {
554         //Set Position on Node
555         aNode->SetPosition(new SMDS_VertexPosition(Index));
556
557         //Update or build submesh
558         if (myShapeIndexToSubMesh.find(Index)==myShapeIndexToSubMesh.end())
559                 myShapeIndexToSubMesh[Index]=new SMESHDS_SubMesh();
560
561         myShapeIndexToSubMesh[Index]->AddNode(aNode);
562 }
563
564 //=======================================================================
565 //function : SetMeshElementOnShape
566 //purpose  : 
567 //=======================================================================
568 void SMESHDS_Mesh::SetMeshElementOnShape(const SMDS_MeshElement* anElement,
569         int Index)
570 {
571         if (myShapeIndexToSubMesh.find(Index)==myShapeIndexToSubMesh.end())
572                 myShapeIndexToSubMesh[Index]=new SMESHDS_SubMesh();
573
574         myShapeIndexToSubMesh[Index]->AddElement(anElement);
575 }
576
577 SMESHDS_Mesh::~SMESHDS_Mesh()
578 {
579 }