Salome HOME
Join modifications from branch OCC_debug_for_3_2_0b1
[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
31 #include "SMESHDS_Group.hxx"
32 #include "SMDS_VertexPosition.hxx"
33 #include "SMDS_EdgePosition.hxx"
34 #include "SMDS_FacePosition.hxx"
35 #include "SMESHDS_GroupOnGeom.hxx"
36 #include <TopExp_Explorer.hxx>
37 #include <TopExp.hxx>
38 #include <TopoDS_Iterator.hxx>
39
40 #include "utilities.h"
41
42 using namespace std;
43
44 //=======================================================================
45 //function : Create
46 //purpose  : 
47 //=======================================================================
48 SMESHDS_Mesh::SMESHDS_Mesh(int theMeshID, bool theIsEmbeddedMode):
49   myMeshID(theMeshID),
50   myIsEmbeddedMode(theIsEmbeddedMode),
51   myCurSubID(-1)
52 {
53   myScript = new SMESHDS_Script(theIsEmbeddedMode);
54   myCurSubMesh = 0;
55 }
56
57 //=======================================================================
58 bool SMESHDS_Mesh::IsEmbeddedMode()
59 {
60   return myIsEmbeddedMode;
61 }
62
63 //=======================================================================
64 //function : ShapeToMesh
65 //purpose  : 
66 //=======================================================================
67 void SMESHDS_Mesh::ShapeToMesh(const TopoDS_Shape & S)
68 {
69   if ( !myShape.IsNull() && S.IsNull() )
70   {
71     // removal of a shape to mesh, delete ...
72     // - hypotheses
73     myShapeToHypothesis.clear();
74     // - shape indices in SMDS_Position of nodes
75     map<int,SMESHDS_SubMesh*>::iterator i_sub = myShapeIndexToSubMesh.begin();
76     for ( ; i_sub != myShapeIndexToSubMesh.end(); i_sub++ ) {
77       if ( !i_sub->second->IsComplexSubmesh() ) {
78         SMDS_NodeIteratorPtr nIt = i_sub->second->GetNodes();
79         while ( nIt->more() )
80           nIt->next()->GetPosition()->SetShapeId( 0 );
81       }
82     }
83     // - sub-meshes
84     myIndexToShape.Clear();
85     myShapeIndexToSubMesh.clear();
86     // - groups on geometry
87     set<SMESHDS_GroupBase*>::iterator gr = myGroups.begin();
88     while ( gr != myGroups.end() ) {
89       if ( dynamic_cast<SMESHDS_GroupOnGeom*>( *gr ))
90         myGroups.erase( gr++ );
91       else
92         gr++;
93     }
94   }
95   else {
96     myShape = S;
97     if ( !S.IsNull() )
98       TopExp::MapShapes(myShape, myIndexToShape);
99   }
100 }
101
102 //=======================================================================
103 //function : AddHypothesis
104 //purpose  : 
105 //=======================================================================
106
107 bool SMESHDS_Mesh::AddHypothesis(const TopoDS_Shape & SS,
108         const SMESHDS_Hypothesis * H)
109 {
110         list<const SMESHDS_Hypothesis *>& alist=myShapeToHypothesis[SS];
111
112         //Check if the Hypothesis is still present
113         list<const SMESHDS_Hypothesis*>::iterator ith=alist.begin();
114
115         for (; ith!=alist.end(); ith++)
116                 if (H == *ith) return false;
117
118         alist.push_back(H);
119         return true;
120 }
121
122 //=======================================================================
123 //function : RemoveHypothesis
124 //purpose  : 
125 //=======================================================================
126
127 bool SMESHDS_Mesh::RemoveHypothesis(const TopoDS_Shape & S,
128         const SMESHDS_Hypothesis * H)
129 {
130         ShapeToHypothesis::iterator its=myShapeToHypothesis.find(S);
131         if(its!=myShapeToHypothesis.end())
132         {
133                 list<const SMESHDS_Hypothesis*>::iterator ith=(*its).second.begin();
134
135                 for (; ith!=(*its).second.end(); ith++)
136                         if (H == *ith)
137                         {
138                                 (*its).second.erase(ith);
139                                 return true;
140                         }
141         }
142         return false;
143 }
144
145 //=======================================================================
146 //function : AddNode
147 //purpose  : 
148 //=======================================================================
149 SMDS_MeshNode* SMESHDS_Mesh::AddNode(double x, double y, double z){
150   SMDS_MeshNode* node = SMDS_Mesh::AddNode(x, y, z);
151   if(node!=NULL) myScript->AddNode(node->GetID(), x, y, z);
152   return node;
153 }
154
155 SMDS_MeshNode* SMESHDS_Mesh::AddNodeWithID(double x, double y, double z, int ID){
156   SMDS_MeshNode* node = SMDS_Mesh::AddNodeWithID(x,y,z,ID);
157   if(node!=NULL) myScript->AddNode(node->GetID(), x, y, z);
158   return node;
159 }
160
161 //=======================================================================
162 //function : MoveNode
163 //purpose  : 
164 //=======================================================================
165 void SMESHDS_Mesh::MoveNode(const SMDS_MeshNode *n, double x, double y, double z)
166 {
167   SMDS_MeshNode * node=const_cast<SMDS_MeshNode*>(n);
168   node->setXYZ(x,y,z);
169   myScript->MoveNode(n->GetID(), x, y, z);
170 }
171
172 //=======================================================================
173 //function : ChangeElementNodes
174 //purpose  : 
175 //=======================================================================
176
177 bool SMESHDS_Mesh::ChangeElementNodes(const SMDS_MeshElement * elem,
178                                       const SMDS_MeshNode    * nodes[],
179                                       const int                nbnodes)
180 {
181   if ( ! SMDS_Mesh::ChangeElementNodes( elem, nodes, nbnodes ))
182     return false;
183
184   vector<int> IDs( nbnodes );
185   for ( int i = 0; i < nbnodes; i++ )
186     IDs [ i ] = nodes[ i ]->GetID();
187   myScript->ChangeElementNodes( elem->GetID(), &IDs[0], nbnodes);
188
189   return true;
190 }
191
192 //=======================================================================
193 //function : ChangePolygonNodes
194 //purpose  : 
195 //=======================================================================
196 bool SMESHDS_Mesh::ChangePolygonNodes
197                    (const SMDS_MeshElement *     elem,
198                     vector<const SMDS_MeshNode*> nodes)
199 {
200   ASSERT(nodes.size() > 3);
201
202   return ChangeElementNodes(elem, &nodes[0], nodes.size());
203 }
204
205 //=======================================================================
206 //function : ChangePolyhedronNodes
207 //purpose  : 
208 //=======================================================================
209 bool SMESHDS_Mesh::ChangePolyhedronNodes
210                    (const SMDS_MeshElement * elem,
211                     std::vector<const SMDS_MeshNode*> nodes,
212                     std::vector<int>                  quantities)
213 {
214   ASSERT(nodes.size() > 3);
215
216   if (!SMDS_Mesh::ChangePolyhedronNodes(elem, nodes, quantities))
217     return false;
218
219   int i, len = nodes.size();
220   std::vector<int> nodes_ids (len);
221   for (i = 0; i < len; i++) {
222     nodes_ids[i] = nodes[i]->GetID();
223   }
224   myScript->ChangePolyhedronNodes(elem->GetID(), nodes_ids, quantities);
225
226   return true;
227 }
228
229 //=======================================================================
230 //function : Renumber
231 //purpose  : 
232 //=======================================================================
233
234 void SMESHDS_Mesh::Renumber (const bool isNodes, const int startID, const int deltaID)
235 {
236   SMDS_Mesh::Renumber( isNodes, startID, deltaID );
237   myScript->Renumber( isNodes, startID, deltaID );
238 }
239
240 //=======================================================================
241 //function :AddEdgeWithID
242 //purpose  : 
243 //=======================================================================
244 SMDS_MeshEdge* SMESHDS_Mesh::AddEdgeWithID(int n1, int n2, int ID)
245 {
246   SMDS_MeshEdge* anElem = SMDS_Mesh::AddEdgeWithID(n1,n2,ID);
247   if(anElem) myScript->AddEdge(ID,n1,n2);
248   return anElem;
249 }
250
251 SMDS_MeshEdge* SMESHDS_Mesh::AddEdgeWithID(const SMDS_MeshNode * n1,
252                                            const SMDS_MeshNode * n2, 
253                                            int ID)
254 {
255   return AddEdgeWithID(n1->GetID(),
256                        n2->GetID(),
257                        ID);
258 }
259
260 SMDS_MeshEdge* SMESHDS_Mesh::AddEdge(const SMDS_MeshNode * n1,
261                                      const SMDS_MeshNode * n2)
262 {
263   SMDS_MeshEdge* anElem = SMDS_Mesh::AddEdge(n1,n2);
264   if(anElem) myScript->AddEdge(anElem->GetID(), 
265                                n1->GetID(), 
266                                n2->GetID());
267   return anElem;
268 }
269
270 //=======================================================================
271 //function :AddFace
272 //purpose  : 
273 //=======================================================================
274 SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(int n1, int n2, int n3, int ID)
275 {
276   SMDS_MeshFace *anElem = SMDS_Mesh::AddFaceWithID(n1, n2, n3, ID);
277   if(anElem) myScript->AddFace(ID,n1,n2,n3);
278   return anElem;
279 }
280
281 SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
282                                            const SMDS_MeshNode * n2,
283                                            const SMDS_MeshNode * n3, 
284                                            int ID)
285 {
286   return AddFaceWithID(n1->GetID(),
287                        n2->GetID(),
288                        n3->GetID(),
289                        ID);
290 }
291
292 SMDS_MeshFace* SMESHDS_Mesh::AddFace( const SMDS_MeshNode * n1,
293                                       const SMDS_MeshNode * n2,
294                                       const SMDS_MeshNode * n3)
295 {
296   SMDS_MeshFace *anElem = SMDS_Mesh::AddFace(n1, n2, n3);
297   if(anElem) myScript->AddFace(anElem->GetID(), 
298                                n1->GetID(), 
299                                n2->GetID(),
300                                n3->GetID());
301   return anElem;
302 }
303
304 //=======================================================================
305 //function :AddFace
306 //purpose  : 
307 //=======================================================================
308 SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(int n1, int n2, int n3, int n4, int ID)
309 {
310   SMDS_MeshFace *anElem = SMDS_Mesh::AddFaceWithID(n1, n2, n3, n4, ID);
311   if(anElem) myScript->AddFace(ID, n1, n2, n3, n4);
312   return anElem;
313 }
314
315 SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
316                                            const SMDS_MeshNode * n2,
317                                            const SMDS_MeshNode * n3,
318                                            const SMDS_MeshNode * n4, 
319                                            int ID)
320 {
321   return AddFaceWithID(n1->GetID(),
322                        n2->GetID(),
323                        n3->GetID(),
324                        n4->GetID(),
325                        ID);
326 }
327
328 SMDS_MeshFace* SMESHDS_Mesh::AddFace(const SMDS_MeshNode * n1,
329                                      const SMDS_MeshNode * n2,
330                                      const SMDS_MeshNode * n3,
331                                      const SMDS_MeshNode * n4)
332 {
333   SMDS_MeshFace *anElem = SMDS_Mesh::AddFace(n1, n2, n3, n4);
334   if(anElem) myScript->AddFace(anElem->GetID(), 
335                                n1->GetID(), 
336                                n2->GetID(), 
337                                n3->GetID(),
338                                n4->GetID());
339   return anElem;
340 }
341
342 //=======================================================================
343 //function :AddVolume
344 //purpose  : 
345 //=======================================================================
346 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4, int ID)
347 {
348   SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, ID);
349   if(anElem) myScript->AddVolume(ID, n1, n2, n3, n4);
350   return anElem;
351 }
352
353 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
354                                                const SMDS_MeshNode * n2,
355                                                const SMDS_MeshNode * n3,
356                                                const SMDS_MeshNode * n4, 
357                                                int ID)
358 {
359   return AddVolumeWithID(n1->GetID(), 
360                          n2->GetID(), 
361                          n3->GetID(),
362                          n4->GetID(),
363                          ID);
364 }
365
366 SMDS_MeshVolume* SMESHDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
367                                          const SMDS_MeshNode * n2,
368                                          const SMDS_MeshNode * n3,
369                                          const SMDS_MeshNode * n4)
370 {
371   SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolume(n1, n2, n3, n4);
372   if(anElem) myScript->AddVolume(anElem->GetID(), 
373                                  n1->GetID(), 
374                                  n2->GetID(), 
375                                  n3->GetID(),
376                                  n4->GetID());
377   return anElem;
378 }
379
380 //=======================================================================
381 //function :AddVolume
382 //purpose  : 
383 //=======================================================================
384 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4, int n5, int ID)
385 {
386   SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, ID);
387   if(anElem) myScript->AddVolume(ID, n1, n2, n3, n4, n5);
388   return anElem;
389 }
390
391 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
392                                                const SMDS_MeshNode * n2,
393                                                const SMDS_MeshNode * n3,
394                                                const SMDS_MeshNode * n4,
395                                                const SMDS_MeshNode * n5, 
396                                                int ID)
397 {
398   return AddVolumeWithID(n1->GetID(), 
399                          n2->GetID(), 
400                          n3->GetID(),
401                          n4->GetID(), 
402                          n5->GetID(),
403                          ID);
404 }
405
406 SMDS_MeshVolume* SMESHDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
407                                          const SMDS_MeshNode * n2,
408                                          const SMDS_MeshNode * n3,
409                                          const SMDS_MeshNode * n4,
410                                          const SMDS_MeshNode * n5)
411 {
412   SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolume(n1, n2, n3, n4, n5);
413   if(anElem) myScript->AddVolume(anElem->GetID(), 
414                                  n1->GetID(), 
415                                  n2->GetID(), 
416                                  n3->GetID(),
417                                  n4->GetID(), 
418                                  n5->GetID());
419   return anElem;
420 }
421
422 //=======================================================================
423 //function :AddVolume
424 //purpose  : 
425 //=======================================================================
426 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4, int n5, int n6, int ID)
427 {
428   SMDS_MeshVolume *anElem= SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, ID);
429   if(anElem) myScript->AddVolume(ID, n1, n2, n3, n4, n5, n6);
430   return anElem;
431 }
432
433 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
434                                                const SMDS_MeshNode * n2,
435                                                const SMDS_MeshNode * n3,
436                                                const SMDS_MeshNode * n4,
437                                                const SMDS_MeshNode * n5,
438                                                const SMDS_MeshNode * n6, 
439                                                int ID)
440 {
441   return AddVolumeWithID(n1->GetID(), 
442                          n2->GetID(), 
443                          n3->GetID(),
444                          n4->GetID(), 
445                          n5->GetID(), 
446                          n6->GetID(),
447                          ID);
448 }
449
450 SMDS_MeshVolume* SMESHDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
451                                          const SMDS_MeshNode * n2,
452                                          const SMDS_MeshNode * n3,
453                                          const SMDS_MeshNode * n4,
454                                          const SMDS_MeshNode * n5,
455                                          const SMDS_MeshNode * n6)
456 {
457   SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolume(n1, n2, n3, n4, n5, n6);
458   if(anElem) myScript->AddVolume(anElem->GetID(), 
459                                  n1->GetID(), 
460                                  n2->GetID(), 
461                                  n3->GetID(),
462                                  n4->GetID(), 
463                                  n5->GetID(), 
464                                  n6->GetID());
465   return anElem;
466 }
467
468 //=======================================================================
469 //function :AddVolume
470 //purpose  : 
471 //=======================================================================
472 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4, int n5, int n6, int n7, int n8, int ID)
473 {
474   SMDS_MeshVolume *anElem= SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, n7, n8, ID);
475   if(anElem) myScript->AddVolume(ID, n1, n2, n3, n4, n5, n6, n7, n8);
476   return anElem;
477 }
478
479 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
480                                                const SMDS_MeshNode * n2,
481                                                const SMDS_MeshNode * n3,
482                                                const SMDS_MeshNode * n4,
483                                                const SMDS_MeshNode * n5,
484                                                const SMDS_MeshNode * n6,
485                                                const SMDS_MeshNode * n7,
486                                                const SMDS_MeshNode * n8, 
487                                                int ID)
488 {
489   return AddVolumeWithID(n1->GetID(), 
490                          n2->GetID(), 
491                          n3->GetID(),
492                          n4->GetID(), 
493                          n5->GetID(), 
494                          n6->GetID(), 
495                          n7->GetID(), 
496                          n8->GetID(),
497                          ID);
498 }
499
500 SMDS_MeshVolume* SMESHDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
501                                          const SMDS_MeshNode * n2,
502                                          const SMDS_MeshNode * n3,
503                                          const SMDS_MeshNode * n4,
504                                          const SMDS_MeshNode * n5,
505                                          const SMDS_MeshNode * n6,
506                                          const SMDS_MeshNode * n7,
507                                          const SMDS_MeshNode * n8)
508 {
509   SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolume(n1, n2, n3, n4, n5, n6, n7, n8);
510   if(anElem) myScript->AddVolume(anElem->GetID(), 
511                                  n1->GetID(), 
512                                  n2->GetID(), 
513                                  n3->GetID(),
514                                  n4->GetID(), 
515                                  n5->GetID(), 
516                                  n6->GetID(), 
517                                  n7->GetID(), 
518                                  n8->GetID());
519   return anElem;
520 }
521
522 //=======================================================================
523 //function : AddPolygonalFace
524 //purpose  : 
525 //=======================================================================
526 SMDS_MeshFace* SMESHDS_Mesh::AddPolygonalFaceWithID (std::vector<int> nodes_ids,
527                                                      const int        ID)
528 {
529   SMDS_MeshFace *anElem = SMDS_Mesh::AddPolygonalFaceWithID(nodes_ids, ID);
530   if (anElem) {
531     myScript->AddPolygonalFace(ID, nodes_ids);
532   }
533   return anElem;
534 }
535
536 SMDS_MeshFace* SMESHDS_Mesh::AddPolygonalFaceWithID
537                              (std::vector<const SMDS_MeshNode*> nodes,
538                               const int                         ID)
539 {
540   SMDS_MeshFace *anElem = SMDS_Mesh::AddPolygonalFaceWithID(nodes, ID);
541   if (anElem) {
542     int i, len = nodes.size();
543     std::vector<int> nodes_ids (len);
544     for (i = 0; i < len; i++) {
545       nodes_ids[i] = nodes[i]->GetID();
546     }
547     myScript->AddPolygonalFace(ID, nodes_ids);
548   }
549   return anElem;
550 }
551
552 SMDS_MeshFace* SMESHDS_Mesh::AddPolygonalFace
553                              (std::vector<const SMDS_MeshNode*> nodes)
554 {
555   SMDS_MeshFace *anElem = SMDS_Mesh::AddPolygonalFace(nodes);
556   if (anElem) {
557     int i, len = nodes.size();
558     std::vector<int> nodes_ids (len);
559     for (i = 0; i < len; i++) {
560       nodes_ids[i] = nodes[i]->GetID();
561     }
562     myScript->AddPolygonalFace(anElem->GetID(), nodes_ids);
563   }
564   return anElem;
565 }
566
567 //=======================================================================
568 //function : AddPolyhedralVolume
569 //purpose  : 
570 //=======================================================================
571 SMDS_MeshVolume* SMESHDS_Mesh::AddPolyhedralVolumeWithID (std::vector<int> nodes_ids,
572                                                           std::vector<int> quantities,
573                                                           const int        ID)
574 {
575   SMDS_MeshVolume *anElem = SMDS_Mesh::AddPolyhedralVolumeWithID(nodes_ids, quantities, ID);
576   if (anElem) {
577     myScript->AddPolyhedralVolume(ID, nodes_ids, quantities);
578   }
579   return anElem;
580 }
581
582 SMDS_MeshVolume* SMESHDS_Mesh::AddPolyhedralVolumeWithID
583                                (std::vector<const SMDS_MeshNode*> nodes,
584                                 std::vector<int>                  quantities,
585                                 const int                         ID)
586 {
587   SMDS_MeshVolume *anElem = SMDS_Mesh::AddPolyhedralVolumeWithID(nodes, quantities, ID);
588   if (anElem) {
589     int i, len = nodes.size();
590     std::vector<int> nodes_ids (len);
591     for (i = 0; i < len; i++) {
592       nodes_ids[i] = nodes[i]->GetID();
593     }
594     myScript->AddPolyhedralVolume(ID, nodes_ids, quantities);
595   }
596   return anElem;
597 }
598
599 SMDS_MeshVolume* SMESHDS_Mesh::AddPolyhedralVolume
600                                (std::vector<const SMDS_MeshNode*> nodes,
601                                 std::vector<int>                  quantities)
602 {
603   SMDS_MeshVolume *anElem = SMDS_Mesh::AddPolyhedralVolume(nodes, quantities);
604   if (anElem) {
605     int i, len = nodes.size();
606     std::vector<int> nodes_ids (len);
607     for (i = 0; i < len; i++) {
608       nodes_ids[i] = nodes[i]->GetID();
609     }
610     myScript->AddPolyhedralVolume(anElem->GetID(), nodes_ids, quantities);
611   }
612   return anElem;
613 }
614
615 //=======================================================================
616 //function : removeFromContainers
617 //purpose  : 
618 //=======================================================================
619
620 static void removeFromContainers (map<int,SMESHDS_SubMesh*>&     theSubMeshes,
621                                   set<SMESHDS_GroupBase*>&       theGroups,
622                                   list<const SMDS_MeshElement*>& theElems,
623                                   const bool                     isNode)
624 {
625   if ( theElems.empty() )
626     return;
627
628   // Rm from group
629   // Element can belong to several groups
630   if ( !theGroups.empty() )
631   {
632     set<SMESHDS_GroupBase*>::iterator GrIt = theGroups.begin();
633     for ( ; GrIt != theGroups.end(); GrIt++ )
634     {
635       SMESHDS_Group* group = dynamic_cast<SMESHDS_Group*>( *GrIt );
636       if ( !group || group->IsEmpty() ) continue;
637
638       list<const SMDS_MeshElement *>::iterator elIt = theElems.begin();
639       for ( ; elIt != theElems.end(); elIt++ )
640       {
641         group->SMDSGroup().Remove( *elIt );
642         if ( group->IsEmpty() ) break;
643       }
644     }
645   }
646
647   // Rm from sub-meshes
648   // Element should belong to only one sub-mesh
649   map<int,SMESHDS_SubMesh*>::iterator SubIt = theSubMeshes.begin();
650   for ( ; SubIt != theSubMeshes.end(); SubIt++ )
651   {
652     int size = isNode ? (*SubIt).second->NbNodes() : (*SubIt).second->NbElements();
653     if ( size == 0 ) continue;
654
655     list<const SMDS_MeshElement *>::iterator elIt = theElems.begin();
656     while ( elIt != theElems.end() )
657     {
658       bool removed = false;
659       if ( isNode )
660         removed = (*SubIt).second->RemoveNode( static_cast<const SMDS_MeshNode*> (*elIt) );
661       else
662         removed = (*SubIt).second->RemoveElement( *elIt );
663
664       if (removed)
665       {
666         elIt = theElems.erase( elIt );
667         if ( theElems.empty() )
668           return; // all elements are found and removed
669       }
670       else
671       {
672         elIt++ ;
673       }
674     }
675   }
676 }
677   
678 //=======================================================================
679 //function : RemoveNode
680 //purpose  : 
681 //=======================================================================
682 void SMESHDS_Mesh::RemoveNode(const SMDS_MeshNode * n)
683 {
684   myScript->RemoveNode(n->GetID());
685   
686   list<const SMDS_MeshElement *> removedElems;
687   list<const SMDS_MeshElement *> removedNodes;
688
689   SMDS_Mesh::RemoveElement( n, removedElems, removedNodes, true );
690
691   removeFromContainers( myShapeIndexToSubMesh, myGroups, removedElems, false );
692   removeFromContainers( myShapeIndexToSubMesh, myGroups, removedNodes, true );
693 }
694
695 //=======================================================================
696 //function : RemoveFreeNode
697 //purpose  : 
698 //=======================================================================
699 void SMESHDS_Mesh::RemoveFreeNode(const SMDS_MeshNode * n, SMESHDS_SubMesh * subMesh)
700 {
701   myScript->RemoveNode(n->GetID());
702
703   // Rm from group
704   // Node can belong to several groups
705   if (!myGroups.empty()) {
706     set<SMESHDS_GroupBase*>::iterator GrIt = myGroups.begin();
707     for (; GrIt != myGroups.end(); GrIt++) {
708       SMESHDS_Group* group = dynamic_cast<SMESHDS_Group*>(*GrIt);
709       if (!group || group->IsEmpty()) continue;
710       group->SMDSGroup().Remove(n);
711     }
712   }
713
714   // Rm from sub-mesh
715   // Node should belong to only one sub-mesh
716   if( subMesh )
717     subMesh->RemoveNode(n);
718
719   SMDS_Mesh::RemoveFreeElement(n);
720 }
721
722 //=======================================================================
723 //function : RemoveElement
724 //purpose  : 
725 //========================================================================
726 void SMESHDS_Mesh::RemoveElement(const SMDS_MeshElement * elt)
727 {
728   if (elt->GetType() == SMDSAbs_Node)
729   {
730     RemoveNode( static_cast<const SMDS_MeshNode*>( elt ));
731     return;
732   }
733
734   myScript->RemoveElement(elt->GetID());
735
736   list<const SMDS_MeshElement *> removedElems;
737   list<const SMDS_MeshElement *> removedNodes;
738
739   SMDS_Mesh::RemoveElement(elt, removedElems, removedNodes, false);
740   
741   removeFromContainers( myShapeIndexToSubMesh, myGroups, removedElems, false );
742 }
743
744 //=======================================================================
745 //function : RemoveFreeElement
746 //purpose  : 
747 //========================================================================
748 void SMESHDS_Mesh::RemoveFreeElement(const SMDS_MeshElement * elt, SMESHDS_SubMesh * subMesh)
749 {
750   if (elt->GetType() == SMDSAbs_Node) {
751     RemoveFreeNode( static_cast<const SMDS_MeshNode*>(elt), subMesh);
752     return;
753   }
754
755   if (hasConstructionEdges() || hasConstructionFaces())
756     // this methods is only for meshes without descendants
757     return;
758
759   myScript->RemoveElement(elt->GetID());
760
761   // Rm from group
762   // Node can belong to several groups
763   if (!myGroups.empty()) {
764     set<SMESHDS_GroupBase*>::iterator GrIt = myGroups.begin();
765     for (; GrIt != myGroups.end(); GrIt++) {
766       SMESHDS_Group* group = dynamic_cast<SMESHDS_Group*>(*GrIt);
767       if (!group || group->IsEmpty()) continue;
768       group->SMDSGroup().Remove(elt);
769     }
770   }
771
772   // Rm from sub-mesh
773   // Element should belong to only one sub-mesh
774   if( subMesh )
775     subMesh->RemoveElement(elt);
776
777   SMDS_Mesh::RemoveFreeElement(elt);
778 }
779
780 //================================================================================
781 /*!
782  * \brief return submesh by shape
783   * \param shape - the subshape
784   * \retval SMESHDS_SubMesh* - the found submesh
785   *
786  * search of submeshes is optimized
787  */
788 //================================================================================
789
790 SMESHDS_SubMesh* SMESHDS_Mesh::getSubmesh( const TopoDS_Shape & shape )
791 {
792   if ( shape.IsNull() )
793     return 0;
794
795   if ( !myCurSubShape.IsNull() && shape.IsSame( myCurSubShape ))
796     return myCurSubMesh;
797
798   getSubmesh( ShapeToIndex( shape ));
799   myCurSubShape = shape;
800   return myCurSubMesh;
801 }
802
803 //================================================================================
804 /*!
805  * \brief return submesh by subshape index
806   * \param Index - the subshape index
807   * \retval SMESHDS_SubMesh* - the found submesh
808  * search of submeshes is optimized
809  */
810 //================================================================================
811
812 SMESHDS_SubMesh* SMESHDS_Mesh::getSubmesh( const int Index )
813 {
814   //Update or build submesh
815   if ( Index != myCurSubID ) {
816     map<int,SMESHDS_SubMesh*>::iterator it = myShapeIndexToSubMesh.find( Index );
817     if ( it == myShapeIndexToSubMesh.end() )
818       it = myShapeIndexToSubMesh.insert( make_pair(Index, new SMESHDS_SubMesh() )).first;
819     myCurSubMesh = it->second;
820     myCurSubID = Index;
821     myCurSubShape.Nullify(); // myCurSubShape no more corresponds to submesh
822   }
823   return myCurSubMesh;
824 }
825
826 //================================================================================
827 /*!
828  * \brief Add element or node to submesh
829   * \param elem - element to add
830   * \param subMesh - submesh to be filled in
831  */
832 //================================================================================
833
834 bool SMESHDS_Mesh::add(const SMDS_MeshElement* elem, SMESHDS_SubMesh* subMesh )
835 {
836   if ( elem && subMesh ) {
837     if ( elem->GetType() == SMDSAbs_Node )
838       subMesh->AddNode( static_cast<const SMDS_MeshNode* >( elem ));
839     else
840       subMesh->AddElement( elem );
841     return true;
842   }
843   return false;
844 }
845
846 //=======================================================================
847 //function : SetNodeOnVolume
848 //purpose  : 
849 //=======================================================================
850 void SMESHDS_Mesh::SetNodeInVolume(SMDS_MeshNode *      aNode,
851                                    const TopoDS_Shell & S)
852 {
853   if ( add( aNode, getSubmesh(S) ))
854     const_cast<SMDS_Position*>( aNode->GetPosition().get() )->SetShapeId( myCurSubID );
855 }
856 //=======================================================================
857 //function : SetNodeOnVolume
858 //purpose  : 
859 //=======================================================================
860 void SMESHDS_Mesh::SetNodeInVolume(SMDS_MeshNode *      aNode,
861                                    const TopoDS_Solid & S)
862 {
863   if ( add( aNode, getSubmesh(S) ))
864     const_cast<SMDS_Position*>( aNode->GetPosition().get() )->SetShapeId( myCurSubID );
865 }
866
867 //=======================================================================
868 //function : SetNodeOnFace
869 //purpose  : 
870 //=======================================================================
871 void SMESHDS_Mesh::SetNodeOnFace(SMDS_MeshNode *     aNode,
872                                  const TopoDS_Face & S,
873                                  double              u,
874                                  double              v)
875 {
876   if ( add( aNode, getSubmesh(S) ))
877     aNode->SetPosition(SMDS_PositionPtr(new SMDS_FacePosition(myCurSubID, u, v)));
878 }
879
880 //=======================================================================
881 //function : SetNodeOnEdge
882 //purpose  : 
883 //=======================================================================
884 void SMESHDS_Mesh::SetNodeOnEdge(SMDS_MeshNode *     aNode,
885                                  const TopoDS_Edge & S,
886                                  double              u)
887 {
888   if ( add( aNode, getSubmesh(S) ))
889     aNode->SetPosition(SMDS_PositionPtr(new SMDS_EdgePosition(myCurSubID, u)));
890 }
891
892 //=======================================================================
893 //function : SetNodeOnVertex
894 //purpose  : 
895 //=======================================================================
896 void SMESHDS_Mesh::SetNodeOnVertex(SMDS_MeshNode *       aNode,
897                                    const TopoDS_Vertex & S)
898 {
899   if ( add( aNode, getSubmesh(S) ))
900     aNode->SetPosition(SMDS_PositionPtr(new SMDS_VertexPosition(myCurSubID)));
901 }
902
903 //=======================================================================
904 //function : UnSetNodeOnShape
905 //purpose  : 
906 //=======================================================================
907 void SMESHDS_Mesh::UnSetNodeOnShape(const SMDS_MeshNode* aNode)
908 {
909   if ( aNode && aNode->GetPosition() ) {
910     map<int,SMESHDS_SubMesh*>::iterator it =
911       myShapeIndexToSubMesh.find( aNode->GetPosition()->GetShapeId() );
912     if ( it != myShapeIndexToSubMesh.end() )
913       it->second->RemoveNode( aNode );
914   }
915 }
916
917 //=======================================================================
918 //function : SetMeshElementOnShape
919 //purpose  : 
920 //=======================================================================
921 void SMESHDS_Mesh::SetMeshElementOnShape(const SMDS_MeshElement * anElement,
922                                          const TopoDS_Shape &     S)
923 {
924   add( anElement, getSubmesh(S) );
925 }
926
927 //=======================================================================
928 //function : UnSetMeshElementOnShape
929 //purpose  : 
930 //=======================================================================
931 void SMESHDS_Mesh::UnSetMeshElementOnShape(const SMDS_MeshElement * elem,
932                                            const TopoDS_Shape &     S)
933 {
934   int Index = myIndexToShape.FindIndex(S);
935
936   map<int,SMESHDS_SubMesh*>::iterator it = myShapeIndexToSubMesh.find( Index );
937   if ( it != myShapeIndexToSubMesh.end() )
938     if ( elem->GetType() == SMDSAbs_Node )
939       it->second->RemoveNode( static_cast<const SMDS_MeshNode* >( elem ));
940     else
941       it->second->RemoveElement( elem );
942 }
943
944 //=======================================================================
945 //function : ShapeToMesh
946 //purpose  : 
947 //=======================================================================
948 TopoDS_Shape SMESHDS_Mesh::ShapeToMesh() const
949 {
950         return myShape;
951 }
952
953 //=======================================================================
954 //function : IsGroupOfSubShapes
955 //purpose  : return true if at least one subshape of theShape is a subshape
956 //           of myShape or theShape == myShape
957 //=======================================================================
958
959 bool SMESHDS_Mesh::IsGroupOfSubShapes (const TopoDS_Shape& theShape) const
960 {
961   if ( myShape.IsSame( theShape ))
962     return true;
963
964   for ( TopoDS_Iterator it( theShape ); it.More(); it.Next() ) {
965     if (myIndexToShape.Contains( it.Value() ) ||
966         IsGroupOfSubShapes( it.Value() ))
967       return true;
968   }
969   
970   return false;
971 }
972
973 ///////////////////////////////////////////////////////////////////////////////
974 /// Return the sub mesh linked to the a given TopoDS_Shape or NULL if the given
975 /// TopoDS_Shape is unknown
976 ///////////////////////////////////////////////////////////////////////////////
977 SMESHDS_SubMesh * SMESHDS_Mesh::MeshElements(const TopoDS_Shape & S) const
978 {
979   int Index = ShapeToIndex(S);
980   TShapeIndexToSubMesh::const_iterator anIter = myShapeIndexToSubMesh.find(Index);
981   if (anIter != myShapeIndexToSubMesh.end())
982     return anIter->second;
983   else
984     return NULL;
985 }
986
987 ///////////////////////////////////////////////////////////////////////////////
988 /// Return the sub mesh by Id of shape it is linked to
989 ///////////////////////////////////////////////////////////////////////////////
990 SMESHDS_SubMesh * SMESHDS_Mesh::MeshElements(const int Index)
991 {
992   TShapeIndexToSubMesh::const_iterator anIter = myShapeIndexToSubMesh.find(Index);
993   if (anIter != myShapeIndexToSubMesh.end())
994     return anIter->second;
995   else
996     return NULL;
997 }
998
999 //=======================================================================
1000 //function : SubMeshIndices
1001 //purpose  : 
1002 //=======================================================================
1003 list<int> SMESHDS_Mesh::SubMeshIndices()
1004 {
1005   list<int> anIndices;
1006   std::map<int,SMESHDS_SubMesh*>::iterator anIter = myShapeIndexToSubMesh.begin();
1007   for (; anIter != myShapeIndexToSubMesh.end(); anIter++) {
1008     anIndices.push_back((*anIter).first);
1009   }
1010   return anIndices;
1011 }
1012
1013 //=======================================================================
1014 //function : GetHypothesis
1015 //purpose  : 
1016 //=======================================================================
1017
1018 const list<const SMESHDS_Hypothesis*>& SMESHDS_Mesh::GetHypothesis(
1019         const TopoDS_Shape & S) const
1020 {
1021         if (myShapeToHypothesis.find(S)!=myShapeToHypothesis.end())
1022                 return myShapeToHypothesis.find(S)->second;
1023
1024         static list<const SMESHDS_Hypothesis*> empty;
1025         return empty;
1026 }
1027
1028 //=======================================================================
1029 //function : GetScript
1030 //purpose  : 
1031 //=======================================================================
1032 SMESHDS_Script* SMESHDS_Mesh::GetScript()
1033 {
1034         return myScript;
1035 }
1036
1037 //=======================================================================
1038 //function : ClearScript
1039 //purpose  : 
1040 //=======================================================================
1041 void SMESHDS_Mesh::ClearScript()
1042 {
1043         myScript->Clear();
1044 }
1045
1046 //=======================================================================
1047 //function : HasMeshElements
1048 //purpose  : 
1049 //=======================================================================
1050 bool SMESHDS_Mesh::HasMeshElements(const TopoDS_Shape & S)
1051 {
1052         if (myShape.IsNull()) MESSAGE("myShape is NULL");
1053         int Index = myIndexToShape.FindIndex(S);
1054         return myShapeIndexToSubMesh.find(Index)!=myShapeIndexToSubMesh.end();
1055 }
1056
1057 //=======================================================================
1058 //function : HasHypothesis
1059 //purpose  : 
1060 //=======================================================================
1061 bool SMESHDS_Mesh::HasHypothesis(const TopoDS_Shape & S)
1062 {
1063         return myShapeToHypothesis.find(S)!=myShapeToHypothesis.end();
1064 }
1065
1066 //=======================================================================
1067 //function : NewSubMesh 
1068 //purpose  : 
1069 //=======================================================================
1070 SMESHDS_SubMesh * SMESHDS_Mesh::NewSubMesh(int Index)
1071 {
1072   SMESHDS_SubMesh* SM = 0;
1073   TShapeIndexToSubMesh::iterator anIter = myShapeIndexToSubMesh.find(Index);
1074   if (anIter == myShapeIndexToSubMesh.end())
1075   {
1076     SM = new SMESHDS_SubMesh();
1077     myShapeIndexToSubMesh[Index]=SM;
1078   }
1079   else
1080     SM = anIter->second;
1081   return SM;
1082 }
1083
1084 //=======================================================================
1085 //function : AddCompoundSubmesh
1086 //purpose  : 
1087 //=======================================================================
1088
1089 int SMESHDS_Mesh::AddCompoundSubmesh(const TopoDS_Shape& S,
1090                                      TopAbs_ShapeEnum    type)
1091 {
1092   int aMainIndex = 0;
1093   if ( IsGroupOfSubShapes( S ) || (S.ShapeType() == TopAbs_VERTEX && myIndexToShape.Contains(S)) )
1094   {
1095     aMainIndex = myIndexToShape.Add( S );
1096     bool all = ( type == TopAbs_SHAPE );
1097     if ( all ) // corresponding simple submesh may exist
1098       aMainIndex = -aMainIndex;
1099     //MESSAGE("AddCompoundSubmesh index = " << aMainIndex );
1100     SMESHDS_SubMesh * aNewSub = NewSubMesh( aMainIndex );
1101     if ( !aNewSub->IsComplexSubmesh() ) // is empty
1102     {
1103       int shapeType = all ? myShape.ShapeType() : type;
1104       int typeLimit = all ? TopAbs_VERTEX : type;
1105       for ( ; shapeType <= typeLimit; shapeType++ )
1106       {
1107         TopExp_Explorer exp( S, TopAbs_ShapeEnum( shapeType ));
1108         for ( ; exp.More(); exp.Next() )
1109         {
1110           int index = myIndexToShape.FindIndex( exp.Current() );
1111           if ( index )
1112             aNewSub->AddSubMesh( NewSubMesh( index ));
1113         }
1114       }
1115     }
1116   }
1117   return aMainIndex;
1118 }
1119
1120 //=======================================================================
1121 //function : IndexToShape
1122 //purpose  : 
1123 //=======================================================================
1124 const TopoDS_Shape& SMESHDS_Mesh::IndexToShape(int ShapeIndex) const
1125 {
1126         return myIndexToShape.FindKey(ShapeIndex);
1127 }
1128
1129 //=======================================================================
1130 //function : ShapeToIndex
1131 //purpose  : 
1132 //=======================================================================
1133 int SMESHDS_Mesh::ShapeToIndex(const TopoDS_Shape & S) const
1134 {
1135   if (myShape.IsNull())
1136     MESSAGE("myShape is NULL");
1137
1138   int index = myIndexToShape.FindIndex(S);
1139   
1140   return index;
1141 }
1142
1143 //=======================================================================
1144 //function : SetNodeOnVolume
1145 //purpose  : 
1146 //=======================================================================
1147 void SMESHDS_Mesh::SetNodeInVolume(const SMDS_MeshNode* aNode, int Index)
1148 {
1149   if ( add( aNode, getSubmesh( Index )))
1150     const_cast<SMDS_Position*>( aNode->GetPosition().get() )->SetShapeId( Index );
1151 }
1152
1153 //=======================================================================
1154 //function : SetNodeOnFace
1155 //purpose  : 
1156 //=======================================================================
1157 void SMESHDS_Mesh::SetNodeOnFace(SMDS_MeshNode* aNode, int Index, double u, double v)
1158 {
1159   //Set Position on Node
1160   if ( add( aNode, getSubmesh( Index )))
1161     aNode->SetPosition(SMDS_PositionPtr(new SMDS_FacePosition(Index, u, v)));
1162 }
1163
1164 //=======================================================================
1165 //function : SetNodeOnEdge
1166 //purpose  : 
1167 //=======================================================================
1168 void SMESHDS_Mesh::SetNodeOnEdge(SMDS_MeshNode* aNode,
1169                                  int            Index,
1170                                  double         u)
1171 {
1172   //Set Position on Node
1173   if ( add( aNode, getSubmesh( Index )))
1174     aNode->SetPosition(SMDS_PositionPtr(new SMDS_EdgePosition(Index, u)));
1175 }
1176
1177 //=======================================================================
1178 //function : SetNodeOnVertex
1179 //purpose  : 
1180 //=======================================================================
1181 void SMESHDS_Mesh::SetNodeOnVertex(SMDS_MeshNode* aNode, int Index)
1182 {
1183   //Set Position on Node
1184   if ( add( aNode, getSubmesh( Index )))
1185     aNode->SetPosition(SMDS_PositionPtr(new SMDS_VertexPosition(Index)));
1186 }
1187
1188 //=======================================================================
1189 //function : SetMeshElementOnShape
1190 //purpose  : 
1191 //=======================================================================
1192 void SMESHDS_Mesh::SetMeshElementOnShape(const SMDS_MeshElement* anElement,
1193                                          int                     Index)
1194 {
1195   add( anElement, getSubmesh( Index ));
1196 }
1197
1198 SMESHDS_Mesh::~SMESHDS_Mesh()
1199 {
1200   delete myScript;
1201 }
1202
1203
1204
1205 //********************************************************************
1206 //********************************************************************
1207 //********                                                   *********
1208 //*****       Methods for addition of quadratic elements        ******
1209 //********                                                   *********
1210 //********************************************************************
1211 //********************************************************************
1212
1213 //=======================================================================
1214 //function : AddEdgeWithID
1215 //purpose  : 
1216 //=======================================================================
1217 SMDS_MeshEdge* SMESHDS_Mesh::AddEdgeWithID(int n1, int n2, int n12, int ID) 
1218 {
1219   SMDS_MeshEdge* anElem = SMDS_Mesh::AddEdgeWithID(n1,n2,n12,ID);
1220   if(anElem) myScript->AddEdge(ID,n1,n2,n12);
1221   return anElem;
1222 }
1223
1224 //=======================================================================
1225 //function : AddEdge
1226 //purpose  : 
1227 //=======================================================================
1228 SMDS_MeshEdge* SMESHDS_Mesh::AddEdge(const SMDS_MeshNode* n1,
1229                                      const SMDS_MeshNode* n2,
1230                                      const SMDS_MeshNode* n12)
1231 {
1232   SMDS_MeshEdge* anElem = SMDS_Mesh::AddEdge(n1,n2,n12);
1233   if(anElem) myScript->AddEdge(anElem->GetID(), 
1234                                n1->GetID(), 
1235                                n2->GetID(),
1236                                n12->GetID());
1237   return anElem;
1238 }
1239
1240 //=======================================================================
1241 //function : AddEdgeWithID
1242 //purpose  : 
1243 //=======================================================================
1244 SMDS_MeshEdge* SMESHDS_Mesh::AddEdgeWithID(const SMDS_MeshNode * n1,
1245                                            const SMDS_MeshNode * n2, 
1246                                            const SMDS_MeshNode * n12, 
1247                                            int ID)
1248 {
1249   return AddEdgeWithID(n1->GetID(),
1250                        n2->GetID(),
1251                        n12->GetID(),
1252                        ID);
1253 }
1254
1255
1256 //=======================================================================
1257 //function : AddFace
1258 //purpose  : 
1259 //=======================================================================
1260 SMDS_MeshFace* SMESHDS_Mesh::AddFace(const SMDS_MeshNode * n1,
1261                                      const SMDS_MeshNode * n2,
1262                                      const SMDS_MeshNode * n3,
1263                                      const SMDS_MeshNode * n12,
1264                                      const SMDS_MeshNode * n23,
1265                                      const SMDS_MeshNode * n31)
1266 {
1267   SMDS_MeshFace *anElem = SMDS_Mesh::AddFace(n1,n2,n3,n12,n23,n31);
1268   if(anElem) myScript->AddFace(anElem->GetID(), 
1269                                n1->GetID(), n2->GetID(), n3->GetID(),
1270                                n12->GetID(), n23->GetID(), n31->GetID());
1271   return anElem;
1272 }
1273
1274 //=======================================================================
1275 //function : AddFaceWithID
1276 //purpose  : 
1277 //=======================================================================
1278 SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(int n1, int n2, int n3,
1279                                            int n12,int n23,int n31, int ID)
1280 {
1281   SMDS_MeshFace *anElem = SMDS_Mesh::AddFaceWithID(n1,n2,n3,n12,n23,n31,ID);
1282   if(anElem) myScript->AddFace(ID,n1,n2,n3,n12,n23,n31);
1283   return anElem;
1284 }
1285
1286 //=======================================================================
1287 //function : AddFaceWithID
1288 //purpose  : 
1289 //=======================================================================
1290 SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
1291                                            const SMDS_MeshNode * n2,
1292                                            const SMDS_MeshNode * n3,
1293                                            const SMDS_MeshNode * n12,
1294                                            const SMDS_MeshNode * n23,
1295                                            const SMDS_MeshNode * n31, 
1296                                            int ID)
1297 {
1298   return AddFaceWithID(n1->GetID(), n2->GetID(), n3->GetID(),
1299                        n12->GetID(), n23->GetID(), n31->GetID(),
1300                        ID);
1301 }
1302
1303
1304 //=======================================================================
1305 //function : AddFace
1306 //purpose  : 
1307 //=======================================================================
1308 SMDS_MeshFace* SMESHDS_Mesh::AddFace(const SMDS_MeshNode * n1,
1309                                      const SMDS_MeshNode * n2,
1310                                      const SMDS_MeshNode * n3,
1311                                      const SMDS_MeshNode * n4,
1312                                      const SMDS_MeshNode * n12,
1313                                      const SMDS_MeshNode * n23,
1314                                      const SMDS_MeshNode * n34,
1315                                      const SMDS_MeshNode * n41)
1316 {
1317   SMDS_MeshFace *anElem = SMDS_Mesh::AddFace(n1,n2,n3,n4,n12,n23,n34,n41);
1318   if(anElem) myScript->AddFace(anElem->GetID(), 
1319                                n1->GetID(), n2->GetID(), n3->GetID(), n4->GetID(),
1320                                n12->GetID(), n23->GetID(), n34->GetID(), n41->GetID());
1321   return anElem;
1322 }
1323
1324 //=======================================================================
1325 //function : AddFaceWithID
1326 //purpose  : 
1327 //=======================================================================
1328 SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(int n1, int n2, int n3, int n4,
1329                                            int n12,int n23,int n34,int n41, int ID)
1330 {
1331   SMDS_MeshFace *anElem = SMDS_Mesh::AddFaceWithID(n1,n2,n3,n4,n12,n23,n34,n41,ID);
1332   if(anElem) myScript->AddFace(ID,n1,n2,n3,n4,n12,n23,n34,n41);
1333   return anElem;
1334 }
1335
1336 //=======================================================================
1337 //function : AddFaceWithID
1338 //purpose  : 
1339 //=======================================================================
1340 SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
1341                                            const SMDS_MeshNode * n2,
1342                                            const SMDS_MeshNode * n3,
1343                                            const SMDS_MeshNode * n4,
1344                                            const SMDS_MeshNode * n12,
1345                                            const SMDS_MeshNode * n23,
1346                                            const SMDS_MeshNode * n34, 
1347                                            const SMDS_MeshNode * n41, 
1348                                            int ID)
1349 {
1350   return AddFaceWithID(n1->GetID(), n2->GetID(), n3->GetID(), n4->GetID(),
1351                        n12->GetID(), n23->GetID(), n34->GetID(), n41->GetID(),
1352                        ID);
1353 }
1354
1355
1356 //=======================================================================
1357 //function : AddVolume
1358 //purpose  : 
1359 //=======================================================================
1360 SMDS_MeshVolume* SMESHDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
1361                                          const SMDS_MeshNode * n2, 
1362                                          const SMDS_MeshNode * n3,
1363                                          const SMDS_MeshNode * n4,
1364                                          const SMDS_MeshNode * n12,
1365                                          const SMDS_MeshNode * n23,
1366                                          const SMDS_MeshNode * n31,
1367                                          const SMDS_MeshNode * n14, 
1368                                          const SMDS_MeshNode * n24,
1369                                          const SMDS_MeshNode * n34)
1370 {
1371   SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolume(n1,n2,n3,n4,n12,n23,n31,n14,n24,n34);
1372   if(anElem) myScript->AddVolume(anElem->GetID(), 
1373                                  n1->GetID(), n2->GetID(), n3->GetID(), n4->GetID(),
1374                                  n12->GetID(), n23->GetID(), n31->GetID(),
1375                                  n14->GetID(), n24->GetID(), n34->GetID());
1376   return anElem;
1377 }
1378
1379 //=======================================================================
1380 //function : AddVolumeWithID
1381 //purpose  : 
1382 //=======================================================================
1383 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4,
1384                                                int n12,int n23,int n31,
1385                                                int n14,int n24,int n34, int ID)
1386 {
1387   SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolumeWithID(n1,n2,n3,n4,n12,n23,
1388                                                        n31,n14,n24,n34,ID);
1389   if(anElem) myScript->AddVolume(ID,n1,n2,n3,n4,n12,n23,n31,n14,n24,n34);
1390   return anElem;
1391 }
1392         
1393 //=======================================================================
1394 //function : AddVolumeWithID
1395 //purpose  : 2d order tetrahedron of 10 nodes
1396 //=======================================================================
1397 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
1398                                                const SMDS_MeshNode * n2,
1399                                                const SMDS_MeshNode * n3,
1400                                                const SMDS_MeshNode * n4,
1401                                                const SMDS_MeshNode * n12,
1402                                                const SMDS_MeshNode * n23,
1403                                                const SMDS_MeshNode * n31,
1404                                                const SMDS_MeshNode * n14, 
1405                                                const SMDS_MeshNode * n24,
1406                                                const SMDS_MeshNode * n34,
1407                                                int ID)
1408 {
1409   return AddVolumeWithID(n1->GetID(), n2->GetID(), n3->GetID(), n4->GetID(),
1410                          n12->GetID(), n23->GetID(), n31->GetID(),
1411                          n14->GetID(), n24->GetID(), n34->GetID(), ID);
1412 }
1413
1414
1415 //=======================================================================
1416 //function : AddVolume
1417 //purpose  : 
1418 //=======================================================================
1419 SMDS_MeshVolume* SMESHDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
1420                                          const SMDS_MeshNode * n2, 
1421                                          const SMDS_MeshNode * n3,
1422                                          const SMDS_MeshNode * n4,
1423                                          const SMDS_MeshNode * n5, 
1424                                          const SMDS_MeshNode * n12,
1425                                          const SMDS_MeshNode * n23,
1426                                          const SMDS_MeshNode * n34,
1427                                          const SMDS_MeshNode * n41,
1428                                          const SMDS_MeshNode * n15, 
1429                                          const SMDS_MeshNode * n25,
1430                                          const SMDS_MeshNode * n35,
1431                                          const SMDS_MeshNode * n45)
1432 {
1433   SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolume(n1,n2,n3,n4,n5,n12,n23,n34,n41,
1434                                                  n15,n25,n35,n45);
1435   if(anElem)
1436     myScript->AddVolume(anElem->GetID(), n1->GetID(), n2->GetID(),
1437                         n3->GetID(), n4->GetID(), n5->GetID(),
1438                         n12->GetID(), n23->GetID(), n34->GetID(), n41->GetID(),
1439                         n15->GetID(), n25->GetID(), n35->GetID(), n45->GetID());
1440   return anElem;
1441 }
1442
1443 //=======================================================================
1444 //function : AddVolumeWithID
1445 //purpose  : 
1446 //=======================================================================
1447 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4, int n5,
1448                                                int n12,int n23,int n34,int n41,
1449                                                int n15,int n25,int n35,int n45, int ID)
1450 {
1451   SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolumeWithID(n1,n2,n3,n4,n5,
1452                                                        n12,n23,n34,n41,
1453                                                        n15,n25,n35,n45,ID);
1454   if(anElem) myScript->AddVolume(ID,n1,n2,n3,n4,n5,n12,n23,n34,n41,
1455                                  n15,n25,n35,n45);
1456   return anElem;
1457 }
1458         
1459 //=======================================================================
1460 //function : AddVolumeWithID
1461 //purpose  : 2d order pyramid of 13 nodes
1462 //=======================================================================
1463 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
1464                                                const SMDS_MeshNode * n2,
1465                                                const SMDS_MeshNode * n3,
1466                                                const SMDS_MeshNode * n4,
1467                                                const SMDS_MeshNode * n5, 
1468                                                const SMDS_MeshNode * n12,
1469                                                const SMDS_MeshNode * n23,
1470                                                const SMDS_MeshNode * n34,
1471                                                const SMDS_MeshNode * n41,
1472                                                const SMDS_MeshNode * n15, 
1473                                                const SMDS_MeshNode * n25,
1474                                                const SMDS_MeshNode * n35,
1475                                                const SMDS_MeshNode * n45,
1476                                                int ID)
1477 {
1478   return AddVolumeWithID(n1->GetID(), n2->GetID(), n3->GetID(),
1479                          n4->GetID(), n5->GetID(),
1480                          n12->GetID(), n23->GetID(), n34->GetID(), n41->GetID(),
1481                          n15->GetID(), n25->GetID(), n35->GetID(), n45->GetID(),
1482                          ID);
1483 }
1484
1485
1486 //=======================================================================
1487 //function : AddVolume
1488 //purpose  : 
1489 //=======================================================================
1490 SMDS_MeshVolume* SMESHDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
1491                                          const SMDS_MeshNode * n2, 
1492                                          const SMDS_MeshNode * n3,
1493                                          const SMDS_MeshNode * n4,
1494                                          const SMDS_MeshNode * n5, 
1495                                          const SMDS_MeshNode * n6, 
1496                                          const SMDS_MeshNode * n12,
1497                                          const SMDS_MeshNode * n23,
1498                                          const SMDS_MeshNode * n31, 
1499                                          const SMDS_MeshNode * n45,
1500                                          const SMDS_MeshNode * n56,
1501                                          const SMDS_MeshNode * n64, 
1502                                          const SMDS_MeshNode * n14,
1503                                          const SMDS_MeshNode * n25,
1504                                          const SMDS_MeshNode * n36)
1505 {
1506   SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolume(n1,n2,n3,n4,n5,n6,n12,n23,n31,
1507                                                  n45,n56,n64,n14,n25,n36);
1508   if(anElem)
1509     myScript->AddVolume(anElem->GetID(), n1->GetID(), n2->GetID(),
1510                         n3->GetID(), n4->GetID(), n5->GetID(), n6->GetID(),
1511                         n12->GetID(), n23->GetID(), n31->GetID(),
1512                         n45->GetID(), n56->GetID(), n64->GetID(),
1513                         n14->GetID(), n25->GetID(), n36->GetID());
1514   return anElem;
1515 }
1516
1517 //=======================================================================
1518 //function : AddVolumeWithID
1519 //purpose  : 
1520 //=======================================================================
1521 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(int n1, int n2, int n3,
1522                                                int n4, int n5, int n6,
1523                                                int n12,int n23,int n31,
1524                                                int n45,int n56,int n64,
1525                                                int n14,int n25,int n36, int ID)
1526 {
1527   SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolumeWithID(n1,n2,n3,n4,n5,n6,
1528                                                        n12,n23,n31,
1529                                                        n45,n56,n64,
1530                                                        n14,n25,n36,ID);
1531   if(anElem) myScript->AddVolume(ID,n1,n2,n3,n4,n5,n6,n12,n23,n31,
1532                                  n45,n56,n64,n14,n25,n36);
1533   return anElem;
1534 }
1535         
1536 //=======================================================================
1537 //function : AddVolumeWithID
1538 //purpose  : 2d order Pentahedron with 15 nodes
1539 //=======================================================================
1540 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
1541                                                const SMDS_MeshNode * n2,
1542                                                const SMDS_MeshNode * n3,
1543                                                const SMDS_MeshNode * n4,
1544                                                const SMDS_MeshNode * n5, 
1545                                                const SMDS_MeshNode * n6, 
1546                                                const SMDS_MeshNode * n12,
1547                                                const SMDS_MeshNode * n23,
1548                                                const SMDS_MeshNode * n31, 
1549                                                const SMDS_MeshNode * n45,
1550                                                const SMDS_MeshNode * n56,
1551                                                const SMDS_MeshNode * n64, 
1552                                                const SMDS_MeshNode * n14,
1553                                                const SMDS_MeshNode * n25,
1554                                                const SMDS_MeshNode * n36,
1555                                                int ID)
1556 {
1557   return AddVolumeWithID(n1->GetID(), n2->GetID(), n3->GetID(),
1558                          n4->GetID(), n5->GetID(), n6->GetID(),
1559                          n12->GetID(), n23->GetID(), n31->GetID(),
1560                          n45->GetID(), n56->GetID(), n64->GetID(),
1561                          n14->GetID(), n25->GetID(), n36->GetID(),
1562                          ID);
1563 }
1564
1565
1566 //=======================================================================
1567 //function : AddVolume
1568 //purpose  : 
1569 //=======================================================================
1570 SMDS_MeshVolume* SMESHDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
1571                                          const SMDS_MeshNode * n2, 
1572                                          const SMDS_MeshNode * n3,
1573                                          const SMDS_MeshNode * n4,
1574                                          const SMDS_MeshNode * n5, 
1575                                          const SMDS_MeshNode * n6, 
1576                                          const SMDS_MeshNode * n7,
1577                                          const SMDS_MeshNode * n8, 
1578                                          const SMDS_MeshNode * n12,
1579                                          const SMDS_MeshNode * n23,
1580                                          const SMDS_MeshNode * n34,
1581                                          const SMDS_MeshNode * n41, 
1582                                          const SMDS_MeshNode * n56,
1583                                          const SMDS_MeshNode * n67,
1584                                          const SMDS_MeshNode * n78,
1585                                          const SMDS_MeshNode * n85, 
1586                                          const SMDS_MeshNode * n15,
1587                                          const SMDS_MeshNode * n26,
1588                                          const SMDS_MeshNode * n37,
1589                                          const SMDS_MeshNode * n48)
1590 {
1591   SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolume(n1,n2,n3,n4,n5,n6,n7,n8,
1592                                                  n12,n23,n34,n41,
1593                                                  n56,n67,n78,n85,
1594                                                  n15,n26,n37,n48);
1595   if(anElem)
1596     myScript->AddVolume(anElem->GetID(), n1->GetID(), n2->GetID(),
1597                         n3->GetID(), n4->GetID(), n5->GetID(),
1598                         n6->GetID(), n7->GetID(), n8->GetID(),
1599                         n12->GetID(), n23->GetID(), n34->GetID(), n41->GetID(),
1600                         n56->GetID(), n67->GetID(), n78->GetID(), n85->GetID(),
1601                         n15->GetID(), n26->GetID(), n37->GetID(), n48->GetID());
1602   return anElem;
1603 }
1604
1605 //=======================================================================
1606 //function : AddVolumeWithID
1607 //purpose  : 
1608 //=======================================================================
1609 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4,
1610                                                int n5, int n6, int n7, int n8,
1611                                                int n12,int n23,int n34,int n41,
1612                                                int n56,int n67,int n78,int n85,
1613                                                int n15,int n26,int n37,int n48, int ID)
1614 {
1615   SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolumeWithID(n1,n2,n3,n4,n5,n6,n7,n8,
1616                                                        n12,n23,n34,n41,
1617                                                        n56,n67,n78,n85,
1618                                                        n15,n26,n37,n48,ID);
1619   if(anElem) myScript->AddVolume(ID,n1,n2,n3,n4,n5,n6,n7,n8,n12,n23,n34,n41,
1620                                  n56,n67,n78,n85,n15,n26,n37,n48);
1621   return anElem;
1622 }
1623         
1624 //=======================================================================
1625 //function : AddVolumeWithID
1626 //purpose  : 2d order Hexahedrons with 20 nodes
1627 //=======================================================================
1628 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
1629                                                const SMDS_MeshNode * n2,
1630                                                const SMDS_MeshNode * n3,
1631                                                const SMDS_MeshNode * n4,
1632                                                const SMDS_MeshNode * n5, 
1633                                                const SMDS_MeshNode * n6, 
1634                                                const SMDS_MeshNode * n7,
1635                                                const SMDS_MeshNode * n8, 
1636                                                const SMDS_MeshNode * n12,
1637                                                const SMDS_MeshNode * n23,
1638                                                const SMDS_MeshNode * n34,
1639                                                const SMDS_MeshNode * n41, 
1640                                                const SMDS_MeshNode * n56,
1641                                                const SMDS_MeshNode * n67,
1642                                                const SMDS_MeshNode * n78,
1643                                                const SMDS_MeshNode * n85, 
1644                                                const SMDS_MeshNode * n15,
1645                                                const SMDS_MeshNode * n26,
1646                                                const SMDS_MeshNode * n37,
1647                                                const SMDS_MeshNode * n48,
1648                                                int ID)
1649 {
1650   return AddVolumeWithID(n1->GetID(), n2->GetID(), n3->GetID(), n4->GetID(),
1651                          n5->GetID(), n6->GetID(), n7->GetID(), n8->GetID(),
1652                          n12->GetID(), n23->GetID(), n34->GetID(), n41->GetID(),
1653                          n56->GetID(), n67->GetID(), n78->GetID(), n85->GetID(),
1654                          n15->GetID(), n26->GetID(), n37->GetID(), n48->GetID(),
1655                          ID);
1656 }
1657
1658