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