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