Salome HOME
Speed up "Clear mesh data"
[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   set<SMESHDS_GroupBase*>::iterator GrIt = myGroups.begin();
773   for (; GrIt != myGroups.end(); GrIt++) {
774     SMESHDS_Group* group = dynamic_cast<SMESHDS_Group*>(*GrIt);
775     if (group && !group->IsEmpty())
776       group->SMDSGroup().Remove(elt);
777   }
778
779   // Rm from sub-mesh
780   // Element should belong to only one sub-mesh
781   if( subMesh )
782     subMesh->RemoveElement(elt);
783
784   SMDS_Mesh::RemoveFreeElement(elt);
785 }
786
787 //================================================================================
788 /*!
789  * \brief Remove all data from the mesh
790  */
791 //================================================================================
792
793 void SMESHDS_Mesh::ClearMesh()
794 {
795   myScript->ClearMesh();
796   SMDS_Mesh::Clear();
797
798   // clear submeshes
799   map<int,SMESHDS_SubMesh*>::iterator sub, subEnd = myShapeIndexToSubMesh.end();
800   for ( sub = myShapeIndexToSubMesh.begin(); sub != subEnd; ++sub )
801     sub->second->Clear();
802
803   // clear groups
804   TGroups::iterator group, groupEnd = myGroups.end();
805   for ( group = myGroups.begin(); group != groupEnd; ++group ) {
806     if ( SMESHDS_Group* g = dynamic_cast<SMESHDS_Group*>(*group)) {
807       SMDSAbs_ElementType groupType = g->GetType();
808       g->Clear();
809       g->SetType( groupType );
810     }
811   }
812 }
813
814 //================================================================================
815 /*!
816  * \brief return submesh by shape
817   * \param shape - the subshape
818   * \retval SMESHDS_SubMesh* - the found submesh
819   *
820  * search of submeshes is optimized
821  */
822 //================================================================================
823
824 SMESHDS_SubMesh* SMESHDS_Mesh::getSubmesh( const TopoDS_Shape & shape )
825 {
826   if ( shape.IsNull() )
827     return 0;
828
829   if ( !myCurSubShape.IsNull() && shape.IsSame( myCurSubShape ))
830     return myCurSubMesh;
831
832   getSubmesh( ShapeToIndex( shape ));
833   myCurSubShape = shape;
834   return myCurSubMesh;
835 }
836
837 //================================================================================
838 /*!
839  * \brief return submesh by subshape index
840   * \param Index - the subshape index
841   * \retval SMESHDS_SubMesh* - the found submesh
842  * search of submeshes is optimized
843  */
844 //================================================================================
845
846 SMESHDS_SubMesh* SMESHDS_Mesh::getSubmesh( const int Index )
847 {
848   //Update or build submesh
849   if ( Index != myCurSubID ) {
850     map<int,SMESHDS_SubMesh*>::iterator it = myShapeIndexToSubMesh.find( Index );
851     if ( it == myShapeIndexToSubMesh.end() )
852       it = myShapeIndexToSubMesh.insert( make_pair(Index, new SMESHDS_SubMesh() )).first;
853     myCurSubMesh = it->second;
854     myCurSubID = Index;
855     myCurSubShape.Nullify(); // myCurSubShape no more corresponds to submesh
856   }
857   return myCurSubMesh;
858 }
859
860 //================================================================================
861 /*!
862  * \brief Add element or node to submesh
863   * \param elem - element to add
864   * \param subMesh - submesh to be filled in
865  */
866 //================================================================================
867
868 bool SMESHDS_Mesh::add(const SMDS_MeshElement* elem, SMESHDS_SubMesh* subMesh )
869 {
870   if ( elem && subMesh ) {
871     if ( elem->GetType() == SMDSAbs_Node )
872       subMesh->AddNode( static_cast<const SMDS_MeshNode* >( elem ));
873     else
874       subMesh->AddElement( elem );
875     return true;
876   }
877   return false;
878 }
879
880 namespace {
881
882   //================================================================================
883   /*!
884    * \brief Creates a node position in volume
885    */
886   //================================================================================
887
888   inline SMDS_PositionPtr volumePosition(int volId)
889   {
890     SMDS_SpacePosition* pos = new SMDS_SpacePosition();
891     pos->SetShapeId( volId );
892     return SMDS_PositionPtr(pos);
893   }
894 }
895
896 //=======================================================================
897 //function : SetNodeOnVolume
898 //purpose  : 
899 //=======================================================================
900 void SMESHDS_Mesh::SetNodeInVolume(SMDS_MeshNode *      aNode,
901                                    const TopoDS_Shell & S)
902 {
903   if ( add( aNode, getSubmesh(S) ))
904     aNode->SetPosition ( volumePosition( myCurSubID ));
905 }
906 //=======================================================================
907 //function : SetNodeOnVolume
908 //purpose  : 
909 //=======================================================================
910 void SMESHDS_Mesh::SetNodeInVolume(SMDS_MeshNode *      aNode,
911                                    const TopoDS_Solid & S)
912 {
913   if ( add( aNode, getSubmesh(S) ))
914     aNode->SetPosition ( volumePosition( myCurSubID ));
915 }
916
917 //=======================================================================
918 //function : SetNodeOnFace
919 //purpose  : 
920 //=======================================================================
921 void SMESHDS_Mesh::SetNodeOnFace(SMDS_MeshNode *     aNode,
922                                  const TopoDS_Face & S,
923                                  double              u,
924                                  double              v)
925 {
926   if ( add( aNode, getSubmesh(S) ))
927     aNode->SetPosition(SMDS_PositionPtr(new SMDS_FacePosition(myCurSubID, u, v)));
928 }
929
930 //=======================================================================
931 //function : SetNodeOnEdge
932 //purpose  : 
933 //=======================================================================
934 void SMESHDS_Mesh::SetNodeOnEdge(SMDS_MeshNode *     aNode,
935                                  const TopoDS_Edge & S,
936                                  double              u)
937 {
938   if ( add( aNode, getSubmesh(S) ))
939     aNode->SetPosition(SMDS_PositionPtr(new SMDS_EdgePosition(myCurSubID, u)));
940 }
941
942 //=======================================================================
943 //function : SetNodeOnVertex
944 //purpose  : 
945 //=======================================================================
946 void SMESHDS_Mesh::SetNodeOnVertex(SMDS_MeshNode *       aNode,
947                                    const TopoDS_Vertex & S)
948 {
949   if ( add( aNode, getSubmesh(S) ))
950     aNode->SetPosition(SMDS_PositionPtr(new SMDS_VertexPosition(myCurSubID)));
951 }
952
953 //=======================================================================
954 //function : UnSetNodeOnShape
955 //purpose  : 
956 //=======================================================================
957 void SMESHDS_Mesh::UnSetNodeOnShape(const SMDS_MeshNode* aNode)
958 {
959   if ( aNode && aNode->GetPosition() ) {
960     map<int,SMESHDS_SubMesh*>::iterator it =
961       myShapeIndexToSubMesh.find( aNode->GetPosition()->GetShapeId() );
962     if ( it != myShapeIndexToSubMesh.end() )
963       it->second->RemoveNode( aNode );
964   }
965 }
966
967 //=======================================================================
968 //function : SetMeshElementOnShape
969 //purpose  : 
970 //=======================================================================
971 void SMESHDS_Mesh::SetMeshElementOnShape(const SMDS_MeshElement * anElement,
972                                          const TopoDS_Shape &     S)
973 {
974   add( anElement, getSubmesh(S) );
975 }
976
977 //=======================================================================
978 //function : UnSetMeshElementOnShape
979 //purpose  : 
980 //=======================================================================
981 void SMESHDS_Mesh::UnSetMeshElementOnShape(const SMDS_MeshElement * elem,
982                                            const TopoDS_Shape &     S)
983 {
984   int Index = myIndexToShape.FindIndex(S);
985
986   map<int,SMESHDS_SubMesh*>::iterator it = myShapeIndexToSubMesh.find( Index );
987   if ( it != myShapeIndexToSubMesh.end() )
988     if ( elem->GetType() == SMDSAbs_Node )
989       it->second->RemoveNode( static_cast<const SMDS_MeshNode* >( elem ));
990     else
991       it->second->RemoveElement( elem );
992 }
993
994 //=======================================================================
995 //function : ShapeToMesh
996 //purpose  : 
997 //=======================================================================
998 TopoDS_Shape SMESHDS_Mesh::ShapeToMesh() const
999 {
1000         return myShape;
1001 }
1002
1003 //=======================================================================
1004 //function : IsGroupOfSubShapes
1005 //purpose  : return true if at least one subshape of theShape is a subshape
1006 //           of myShape or theShape == myShape
1007 //=======================================================================
1008
1009 bool SMESHDS_Mesh::IsGroupOfSubShapes (const TopoDS_Shape& theShape) const
1010 {
1011   if ( myShape.IsSame( theShape ))
1012     return true;
1013
1014   for ( TopoDS_Iterator it( theShape ); it.More(); it.Next() ) {
1015     if (myIndexToShape.Contains( it.Value() ) ||
1016         IsGroupOfSubShapes( it.Value() ))
1017       return true;
1018   }
1019   
1020   return false;
1021 }
1022
1023 ///////////////////////////////////////////////////////////////////////////////
1024 /// Return the sub mesh linked to the a given TopoDS_Shape or NULL if the given
1025 /// TopoDS_Shape is unknown
1026 ///////////////////////////////////////////////////////////////////////////////
1027 SMESHDS_SubMesh * SMESHDS_Mesh::MeshElements(const TopoDS_Shape & S) const
1028 {
1029   int Index = ShapeToIndex(S);
1030   TShapeIndexToSubMesh::const_iterator anIter = myShapeIndexToSubMesh.find(Index);
1031   if (anIter != myShapeIndexToSubMesh.end())
1032     return anIter->second;
1033   else
1034     return NULL;
1035 }
1036
1037 ///////////////////////////////////////////////////////////////////////////////
1038 /// Return the sub mesh by Id of shape it is linked to
1039 ///////////////////////////////////////////////////////////////////////////////
1040 SMESHDS_SubMesh * SMESHDS_Mesh::MeshElements(const int Index)
1041 {
1042   TShapeIndexToSubMesh::const_iterator anIter = myShapeIndexToSubMesh.find(Index);
1043   if (anIter != myShapeIndexToSubMesh.end())
1044     return anIter->second;
1045   else
1046     return NULL;
1047 }
1048
1049 //=======================================================================
1050 //function : SubMeshIndices
1051 //purpose  : 
1052 //=======================================================================
1053 list<int> SMESHDS_Mesh::SubMeshIndices()
1054 {
1055   list<int> anIndices;
1056   std::map<int,SMESHDS_SubMesh*>::iterator anIter = myShapeIndexToSubMesh.begin();
1057   for (; anIter != myShapeIndexToSubMesh.end(); anIter++) {
1058     anIndices.push_back((*anIter).first);
1059   }
1060   return anIndices;
1061 }
1062
1063 //=======================================================================
1064 //function : GetHypothesis
1065 //purpose  : 
1066 //=======================================================================
1067
1068 const list<const SMESHDS_Hypothesis*>&
1069 SMESHDS_Mesh::GetHypothesis(const TopoDS_Shape & S) const
1070 {
1071   if ( myShapeToHypothesis.IsBound( S.Oriented(TopAbs_FORWARD) ) ) // ignore orientation of S
1072      return myShapeToHypothesis.Find( S.Oriented(TopAbs_FORWARD) );
1073
1074   static list<const SMESHDS_Hypothesis*> empty;
1075   return empty;
1076 }
1077
1078 //=======================================================================
1079 //function : GetScript
1080 //purpose  : 
1081 //=======================================================================
1082 SMESHDS_Script* SMESHDS_Mesh::GetScript()
1083 {
1084         return myScript;
1085 }
1086
1087 //=======================================================================
1088 //function : ClearScript
1089 //purpose  : 
1090 //=======================================================================
1091 void SMESHDS_Mesh::ClearScript()
1092 {
1093         myScript->Clear();
1094 }
1095
1096 //=======================================================================
1097 //function : HasMeshElements
1098 //purpose  : 
1099 //=======================================================================
1100 bool SMESHDS_Mesh::HasMeshElements(const TopoDS_Shape & S)
1101 {
1102         if (myShape.IsNull()) MESSAGE("myShape is NULL");
1103         int Index = myIndexToShape.FindIndex(S);
1104         return myShapeIndexToSubMesh.find(Index)!=myShapeIndexToSubMesh.end();
1105 }
1106
1107 //=======================================================================
1108 //function : HasHypothesis
1109 //purpose  : 
1110 //=======================================================================
1111 bool SMESHDS_Mesh::HasHypothesis(const TopoDS_Shape & S)
1112 {
1113   return myShapeToHypothesis.IsBound(S.Oriented(TopAbs_FORWARD));
1114 }
1115
1116 //=======================================================================
1117 //function : NewSubMesh 
1118 //purpose  : 
1119 //=======================================================================
1120 SMESHDS_SubMesh * SMESHDS_Mesh::NewSubMesh(int Index)
1121 {
1122   SMESHDS_SubMesh* SM = 0;
1123   TShapeIndexToSubMesh::iterator anIter = myShapeIndexToSubMesh.find(Index);
1124   if (anIter == myShapeIndexToSubMesh.end())
1125   {
1126     SM = new SMESHDS_SubMesh();
1127     myShapeIndexToSubMesh[Index]=SM;
1128   }
1129   else
1130     SM = anIter->second;
1131   return SM;
1132 }
1133
1134 //=======================================================================
1135 //function : AddCompoundSubmesh
1136 //purpose  : 
1137 //=======================================================================
1138
1139 int SMESHDS_Mesh::AddCompoundSubmesh(const TopoDS_Shape& S,
1140                                      TopAbs_ShapeEnum    type)
1141 {
1142   int aMainIndex = 0;
1143   if ( IsGroupOfSubShapes( S ) || (S.ShapeType() == TopAbs_VERTEX && myIndexToShape.Contains(S)) )
1144   {
1145     aMainIndex = myIndexToShape.Add( S );
1146     bool all = ( type == TopAbs_SHAPE );
1147     if ( all ) // corresponding simple submesh may exist
1148       aMainIndex = -aMainIndex;
1149     //MESSAGE("AddCompoundSubmesh index = " << aMainIndex );
1150     SMESHDS_SubMesh * aNewSub = NewSubMesh( aMainIndex );
1151     if ( !aNewSub->IsComplexSubmesh() ) // is empty
1152     {
1153       int shapeType = all ? myShape.ShapeType() : type;
1154       int typeLimit = all ? TopAbs_VERTEX : type;
1155       for ( ; shapeType <= typeLimit; shapeType++ )
1156       {
1157         TopExp_Explorer exp( S, TopAbs_ShapeEnum( shapeType ));
1158         for ( ; exp.More(); exp.Next() )
1159         {
1160           int index = myIndexToShape.FindIndex( exp.Current() );
1161           if ( index )
1162             aNewSub->AddSubMesh( NewSubMesh( index ));
1163         }
1164       }
1165     }
1166   }
1167   return aMainIndex;
1168 }
1169
1170 //=======================================================================
1171 //function : IndexToShape
1172 //purpose  : 
1173 //=======================================================================
1174 const TopoDS_Shape& SMESHDS_Mesh::IndexToShape(int ShapeIndex) const
1175 {
1176         return myIndexToShape.FindKey(ShapeIndex);
1177 }
1178
1179 //=======================================================================
1180 //function : ShapeToIndex
1181 //purpose  : 
1182 //=======================================================================
1183 int SMESHDS_Mesh::ShapeToIndex(const TopoDS_Shape & S) const
1184 {
1185   if (myShape.IsNull())
1186     MESSAGE("myShape is NULL");
1187
1188   int index = myIndexToShape.FindIndex(S);
1189   
1190   return index;
1191 }
1192
1193 //=======================================================================
1194 //function : SetNodeOnVolume
1195 //purpose  : 
1196 //=======================================================================
1197 void SMESHDS_Mesh::SetNodeInVolume(const SMDS_MeshNode* aNode, int Index)
1198 {
1199   if ( add( aNode, getSubmesh( Index )))
1200     ((SMDS_MeshNode*) aNode)->SetPosition( volumePosition( Index ));
1201 }
1202
1203 //=======================================================================
1204 //function : SetNodeOnFace
1205 //purpose  : 
1206 //=======================================================================
1207 void SMESHDS_Mesh::SetNodeOnFace(SMDS_MeshNode* aNode, int Index, double u, double v)
1208 {
1209   //Set Position on Node
1210   if ( add( aNode, getSubmesh( Index )))
1211     aNode->SetPosition(SMDS_PositionPtr(new SMDS_FacePosition(Index, u, v)));
1212 }
1213
1214 //=======================================================================
1215 //function : SetNodeOnEdge
1216 //purpose  : 
1217 //=======================================================================
1218 void SMESHDS_Mesh::SetNodeOnEdge(SMDS_MeshNode* aNode,
1219                                  int            Index,
1220                                  double         u)
1221 {
1222   //Set Position on Node
1223   if ( add( aNode, getSubmesh( Index )))
1224     aNode->SetPosition(SMDS_PositionPtr(new SMDS_EdgePosition(Index, u)));
1225 }
1226
1227 //=======================================================================
1228 //function : SetNodeOnVertex
1229 //purpose  : 
1230 //=======================================================================
1231 void SMESHDS_Mesh::SetNodeOnVertex(SMDS_MeshNode* aNode, int Index)
1232 {
1233   //Set Position on Node
1234   if ( add( aNode, getSubmesh( Index )))
1235     aNode->SetPosition(SMDS_PositionPtr(new SMDS_VertexPosition(Index)));
1236 }
1237
1238 //=======================================================================
1239 //function : SetMeshElementOnShape
1240 //purpose  : 
1241 //=======================================================================
1242 void SMESHDS_Mesh::SetMeshElementOnShape(const SMDS_MeshElement* anElement,
1243                                          int                     Index)
1244 {
1245   add( anElement, getSubmesh( Index ));
1246 }
1247
1248 //=======================================================================
1249 //function : ~SMESHDS_Mesh
1250 //purpose  : 
1251 //=======================================================================
1252 SMESHDS_Mesh::~SMESHDS_Mesh()
1253 {
1254   // myScript
1255   delete myScript;
1256   // submeshes
1257   TShapeIndexToSubMesh::iterator i_sm = myShapeIndexToSubMesh.begin();
1258   for ( ; i_sm != myShapeIndexToSubMesh.end(); ++i_sm )
1259     delete i_sm->second;
1260 }
1261
1262
1263 //********************************************************************
1264 //********************************************************************
1265 //********                                                   *********
1266 //*****       Methods for addition of quadratic elements        ******
1267 //********                                                   *********
1268 //********************************************************************
1269 //********************************************************************
1270
1271 //=======================================================================
1272 //function : AddEdgeWithID
1273 //purpose  : 
1274 //=======================================================================
1275 SMDS_MeshEdge* SMESHDS_Mesh::AddEdgeWithID(int n1, int n2, int n12, int ID) 
1276 {
1277   SMDS_MeshEdge* anElem = SMDS_Mesh::AddEdgeWithID(n1,n2,n12,ID);
1278   if(anElem) myScript->AddEdge(ID,n1,n2,n12);
1279   return anElem;
1280 }
1281
1282 //=======================================================================
1283 //function : AddEdge
1284 //purpose  : 
1285 //=======================================================================
1286 SMDS_MeshEdge* SMESHDS_Mesh::AddEdge(const SMDS_MeshNode* n1,
1287                                      const SMDS_MeshNode* n2,
1288                                      const SMDS_MeshNode* n12)
1289 {
1290   SMDS_MeshEdge* anElem = SMDS_Mesh::AddEdge(n1,n2,n12);
1291   if(anElem) myScript->AddEdge(anElem->GetID(), 
1292                                n1->GetID(), 
1293                                n2->GetID(),
1294                                n12->GetID());
1295   return anElem;
1296 }
1297
1298 //=======================================================================
1299 //function : AddEdgeWithID
1300 //purpose  : 
1301 //=======================================================================
1302 SMDS_MeshEdge* SMESHDS_Mesh::AddEdgeWithID(const SMDS_MeshNode * n1,
1303                                            const SMDS_MeshNode * n2, 
1304                                            const SMDS_MeshNode * n12, 
1305                                            int ID)
1306 {
1307   return AddEdgeWithID(n1->GetID(),
1308                        n2->GetID(),
1309                        n12->GetID(),
1310                        ID);
1311 }
1312
1313
1314 //=======================================================================
1315 //function : AddFace
1316 //purpose  : 
1317 //=======================================================================
1318 SMDS_MeshFace* SMESHDS_Mesh::AddFace(const SMDS_MeshNode * n1,
1319                                      const SMDS_MeshNode * n2,
1320                                      const SMDS_MeshNode * n3,
1321                                      const SMDS_MeshNode * n12,
1322                                      const SMDS_MeshNode * n23,
1323                                      const SMDS_MeshNode * n31)
1324 {
1325   SMDS_MeshFace *anElem = SMDS_Mesh::AddFace(n1,n2,n3,n12,n23,n31);
1326   if(anElem) myScript->AddFace(anElem->GetID(), 
1327                                n1->GetID(), n2->GetID(), n3->GetID(),
1328                                n12->GetID(), n23->GetID(), n31->GetID());
1329   return anElem;
1330 }
1331
1332 //=======================================================================
1333 //function : AddFaceWithID
1334 //purpose  : 
1335 //=======================================================================
1336 SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(int n1, int n2, int n3,
1337                                            int n12,int n23,int n31, int ID)
1338 {
1339   SMDS_MeshFace *anElem = SMDS_Mesh::AddFaceWithID(n1,n2,n3,n12,n23,n31,ID);
1340   if(anElem) myScript->AddFace(ID,n1,n2,n3,n12,n23,n31);
1341   return anElem;
1342 }
1343
1344 //=======================================================================
1345 //function : AddFaceWithID
1346 //purpose  : 
1347 //=======================================================================
1348 SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
1349                                            const SMDS_MeshNode * n2,
1350                                            const SMDS_MeshNode * n3,
1351                                            const SMDS_MeshNode * n12,
1352                                            const SMDS_MeshNode * n23,
1353                                            const SMDS_MeshNode * n31, 
1354                                            int ID)
1355 {
1356   return AddFaceWithID(n1->GetID(), n2->GetID(), n3->GetID(),
1357                        n12->GetID(), n23->GetID(), n31->GetID(),
1358                        ID);
1359 }
1360
1361
1362 //=======================================================================
1363 //function : AddFace
1364 //purpose  : 
1365 //=======================================================================
1366 SMDS_MeshFace* SMESHDS_Mesh::AddFace(const SMDS_MeshNode * n1,
1367                                      const SMDS_MeshNode * n2,
1368                                      const SMDS_MeshNode * n3,
1369                                      const SMDS_MeshNode * n4,
1370                                      const SMDS_MeshNode * n12,
1371                                      const SMDS_MeshNode * n23,
1372                                      const SMDS_MeshNode * n34,
1373                                      const SMDS_MeshNode * n41)
1374 {
1375   SMDS_MeshFace *anElem = SMDS_Mesh::AddFace(n1,n2,n3,n4,n12,n23,n34,n41);
1376   if(anElem) myScript->AddFace(anElem->GetID(), 
1377                                n1->GetID(), n2->GetID(), n3->GetID(), n4->GetID(),
1378                                n12->GetID(), n23->GetID(), n34->GetID(), n41->GetID());
1379   return anElem;
1380 }
1381
1382 //=======================================================================
1383 //function : AddFaceWithID
1384 //purpose  : 
1385 //=======================================================================
1386 SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(int n1, int n2, int n3, int n4,
1387                                            int n12,int n23,int n34,int n41, int ID)
1388 {
1389   SMDS_MeshFace *anElem = SMDS_Mesh::AddFaceWithID(n1,n2,n3,n4,n12,n23,n34,n41,ID);
1390   if(anElem) myScript->AddFace(ID,n1,n2,n3,n4,n12,n23,n34,n41);
1391   return anElem;
1392 }
1393
1394 //=======================================================================
1395 //function : AddFaceWithID
1396 //purpose  : 
1397 //=======================================================================
1398 SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
1399                                            const SMDS_MeshNode * n2,
1400                                            const SMDS_MeshNode * n3,
1401                                            const SMDS_MeshNode * n4,
1402                                            const SMDS_MeshNode * n12,
1403                                            const SMDS_MeshNode * n23,
1404                                            const SMDS_MeshNode * n34, 
1405                                            const SMDS_MeshNode * n41, 
1406                                            int ID)
1407 {
1408   return AddFaceWithID(n1->GetID(), n2->GetID(), n3->GetID(), n4->GetID(),
1409                        n12->GetID(), n23->GetID(), n34->GetID(), n41->GetID(),
1410                        ID);
1411 }
1412
1413
1414 //=======================================================================
1415 //function : AddVolume
1416 //purpose  : 
1417 //=======================================================================
1418 SMDS_MeshVolume* SMESHDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
1419                                          const SMDS_MeshNode * n2, 
1420                                          const SMDS_MeshNode * n3,
1421                                          const SMDS_MeshNode * n4,
1422                                          const SMDS_MeshNode * n12,
1423                                          const SMDS_MeshNode * n23,
1424                                          const SMDS_MeshNode * n31,
1425                                          const SMDS_MeshNode * n14, 
1426                                          const SMDS_MeshNode * n24,
1427                                          const SMDS_MeshNode * n34)
1428 {
1429   SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolume(n1,n2,n3,n4,n12,n23,n31,n14,n24,n34);
1430   if(anElem) myScript->AddVolume(anElem->GetID(), 
1431                                  n1->GetID(), n2->GetID(), n3->GetID(), n4->GetID(),
1432                                  n12->GetID(), n23->GetID(), n31->GetID(),
1433                                  n14->GetID(), n24->GetID(), n34->GetID());
1434   return anElem;
1435 }
1436
1437 //=======================================================================
1438 //function : AddVolumeWithID
1439 //purpose  : 
1440 //=======================================================================
1441 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4,
1442                                                int n12,int n23,int n31,
1443                                                int n14,int n24,int n34, int ID)
1444 {
1445   SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolumeWithID(n1,n2,n3,n4,n12,n23,
1446                                                        n31,n14,n24,n34,ID);
1447   if(anElem) myScript->AddVolume(ID,n1,n2,n3,n4,n12,n23,n31,n14,n24,n34);
1448   return anElem;
1449 }
1450         
1451 //=======================================================================
1452 //function : AddVolumeWithID
1453 //purpose  : 2d order tetrahedron of 10 nodes
1454 //=======================================================================
1455 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
1456                                                const SMDS_MeshNode * n2,
1457                                                const SMDS_MeshNode * n3,
1458                                                const SMDS_MeshNode * n4,
1459                                                const SMDS_MeshNode * n12,
1460                                                const SMDS_MeshNode * n23,
1461                                                const SMDS_MeshNode * n31,
1462                                                const SMDS_MeshNode * n14, 
1463                                                const SMDS_MeshNode * n24,
1464                                                const SMDS_MeshNode * n34,
1465                                                int ID)
1466 {
1467   return AddVolumeWithID(n1->GetID(), n2->GetID(), n3->GetID(), n4->GetID(),
1468                          n12->GetID(), n23->GetID(), n31->GetID(),
1469                          n14->GetID(), n24->GetID(), n34->GetID(), ID);
1470 }
1471
1472
1473 //=======================================================================
1474 //function : AddVolume
1475 //purpose  : 
1476 //=======================================================================
1477 SMDS_MeshVolume* SMESHDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
1478                                          const SMDS_MeshNode * n2, 
1479                                          const SMDS_MeshNode * n3,
1480                                          const SMDS_MeshNode * n4,
1481                                          const SMDS_MeshNode * n5, 
1482                                          const SMDS_MeshNode * n12,
1483                                          const SMDS_MeshNode * n23,
1484                                          const SMDS_MeshNode * n34,
1485                                          const SMDS_MeshNode * n41,
1486                                          const SMDS_MeshNode * n15, 
1487                                          const SMDS_MeshNode * n25,
1488                                          const SMDS_MeshNode * n35,
1489                                          const SMDS_MeshNode * n45)
1490 {
1491   SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolume(n1,n2,n3,n4,n5,n12,n23,n34,n41,
1492                                                  n15,n25,n35,n45);
1493   if(anElem)
1494     myScript->AddVolume(anElem->GetID(), n1->GetID(), n2->GetID(),
1495                         n3->GetID(), n4->GetID(), n5->GetID(),
1496                         n12->GetID(), n23->GetID(), n34->GetID(), n41->GetID(),
1497                         n15->GetID(), n25->GetID(), n35->GetID(), n45->GetID());
1498   return anElem;
1499 }
1500
1501 //=======================================================================
1502 //function : AddVolumeWithID
1503 //purpose  : 
1504 //=======================================================================
1505 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4, int n5,
1506                                                int n12,int n23,int n34,int n41,
1507                                                int n15,int n25,int n35,int n45, int ID)
1508 {
1509   SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolumeWithID(n1,n2,n3,n4,n5,
1510                                                        n12,n23,n34,n41,
1511                                                        n15,n25,n35,n45,ID);
1512   if(anElem) myScript->AddVolume(ID,n1,n2,n3,n4,n5,n12,n23,n34,n41,
1513                                  n15,n25,n35,n45);
1514   return anElem;
1515 }
1516         
1517 //=======================================================================
1518 //function : AddVolumeWithID
1519 //purpose  : 2d order pyramid of 13 nodes
1520 //=======================================================================
1521 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
1522                                                const SMDS_MeshNode * n2,
1523                                                const SMDS_MeshNode * n3,
1524                                                const SMDS_MeshNode * n4,
1525                                                const SMDS_MeshNode * n5, 
1526                                                const SMDS_MeshNode * n12,
1527                                                const SMDS_MeshNode * n23,
1528                                                const SMDS_MeshNode * n34,
1529                                                const SMDS_MeshNode * n41,
1530                                                const SMDS_MeshNode * n15, 
1531                                                const SMDS_MeshNode * n25,
1532                                                const SMDS_MeshNode * n35,
1533                                                const SMDS_MeshNode * n45,
1534                                                int ID)
1535 {
1536   return AddVolumeWithID(n1->GetID(), n2->GetID(), n3->GetID(),
1537                          n4->GetID(), n5->GetID(),
1538                          n12->GetID(), n23->GetID(), n34->GetID(), n41->GetID(),
1539                          n15->GetID(), n25->GetID(), n35->GetID(), n45->GetID(),
1540                          ID);
1541 }
1542
1543
1544 //=======================================================================
1545 //function : AddVolume
1546 //purpose  : 
1547 //=======================================================================
1548 SMDS_MeshVolume* SMESHDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
1549                                          const SMDS_MeshNode * n2, 
1550                                          const SMDS_MeshNode * n3,
1551                                          const SMDS_MeshNode * n4,
1552                                          const SMDS_MeshNode * n5, 
1553                                          const SMDS_MeshNode * n6, 
1554                                          const SMDS_MeshNode * n12,
1555                                          const SMDS_MeshNode * n23,
1556                                          const SMDS_MeshNode * n31, 
1557                                          const SMDS_MeshNode * n45,
1558                                          const SMDS_MeshNode * n56,
1559                                          const SMDS_MeshNode * n64, 
1560                                          const SMDS_MeshNode * n14,
1561                                          const SMDS_MeshNode * n25,
1562                                          const SMDS_MeshNode * n36)
1563 {
1564   SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolume(n1,n2,n3,n4,n5,n6,n12,n23,n31,
1565                                                  n45,n56,n64,n14,n25,n36);
1566   if(anElem)
1567     myScript->AddVolume(anElem->GetID(), n1->GetID(), n2->GetID(),
1568                         n3->GetID(), n4->GetID(), n5->GetID(), n6->GetID(),
1569                         n12->GetID(), n23->GetID(), n31->GetID(),
1570                         n45->GetID(), n56->GetID(), n64->GetID(),
1571                         n14->GetID(), n25->GetID(), n36->GetID());
1572   return anElem;
1573 }
1574
1575 //=======================================================================
1576 //function : AddVolumeWithID
1577 //purpose  : 
1578 //=======================================================================
1579 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(int n1, int n2, int n3,
1580                                                int n4, int n5, int n6,
1581                                                int n12,int n23,int n31,
1582                                                int n45,int n56,int n64,
1583                                                int n14,int n25,int n36, int ID)
1584 {
1585   SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolumeWithID(n1,n2,n3,n4,n5,n6,
1586                                                        n12,n23,n31,
1587                                                        n45,n56,n64,
1588                                                        n14,n25,n36,ID);
1589   if(anElem) myScript->AddVolume(ID,n1,n2,n3,n4,n5,n6,n12,n23,n31,
1590                                  n45,n56,n64,n14,n25,n36);
1591   return anElem;
1592 }
1593         
1594 //=======================================================================
1595 //function : AddVolumeWithID
1596 //purpose  : 2d order Pentahedron with 15 nodes
1597 //=======================================================================
1598 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
1599                                                const SMDS_MeshNode * n2,
1600                                                const SMDS_MeshNode * n3,
1601                                                const SMDS_MeshNode * n4,
1602                                                const SMDS_MeshNode * n5, 
1603                                                const SMDS_MeshNode * n6, 
1604                                                const SMDS_MeshNode * n12,
1605                                                const SMDS_MeshNode * n23,
1606                                                const SMDS_MeshNode * n31, 
1607                                                const SMDS_MeshNode * n45,
1608                                                const SMDS_MeshNode * n56,
1609                                                const SMDS_MeshNode * n64, 
1610                                                const SMDS_MeshNode * n14,
1611                                                const SMDS_MeshNode * n25,
1612                                                const SMDS_MeshNode * n36,
1613                                                int ID)
1614 {
1615   return AddVolumeWithID(n1->GetID(), n2->GetID(), n3->GetID(),
1616                          n4->GetID(), n5->GetID(), n6->GetID(),
1617                          n12->GetID(), n23->GetID(), n31->GetID(),
1618                          n45->GetID(), n56->GetID(), n64->GetID(),
1619                          n14->GetID(), n25->GetID(), n36->GetID(),
1620                          ID);
1621 }
1622
1623
1624 //=======================================================================
1625 //function : AddVolume
1626 //purpose  : 
1627 //=======================================================================
1628 SMDS_MeshVolume* SMESHDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
1629                                          const SMDS_MeshNode * n2, 
1630                                          const SMDS_MeshNode * n3,
1631                                          const SMDS_MeshNode * n4,
1632                                          const SMDS_MeshNode * n5, 
1633                                          const SMDS_MeshNode * n6, 
1634                                          const SMDS_MeshNode * n7,
1635                                          const SMDS_MeshNode * n8, 
1636                                          const SMDS_MeshNode * n12,
1637                                          const SMDS_MeshNode * n23,
1638                                          const SMDS_MeshNode * n34,
1639                                          const SMDS_MeshNode * n41, 
1640                                          const SMDS_MeshNode * n56,
1641                                          const SMDS_MeshNode * n67,
1642                                          const SMDS_MeshNode * n78,
1643                                          const SMDS_MeshNode * n85, 
1644                                          const SMDS_MeshNode * n15,
1645                                          const SMDS_MeshNode * n26,
1646                                          const SMDS_MeshNode * n37,
1647                                          const SMDS_MeshNode * n48)
1648 {
1649   SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolume(n1,n2,n3,n4,n5,n6,n7,n8,
1650                                                  n12,n23,n34,n41,
1651                                                  n56,n67,n78,n85,
1652                                                  n15,n26,n37,n48);
1653   if(anElem)
1654     myScript->AddVolume(anElem->GetID(), n1->GetID(), n2->GetID(),
1655                         n3->GetID(), n4->GetID(), n5->GetID(),
1656                         n6->GetID(), n7->GetID(), n8->GetID(),
1657                         n12->GetID(), n23->GetID(), n34->GetID(), n41->GetID(),
1658                         n56->GetID(), n67->GetID(), n78->GetID(), n85->GetID(),
1659                         n15->GetID(), n26->GetID(), n37->GetID(), n48->GetID());
1660   return anElem;
1661 }
1662
1663 //=======================================================================
1664 //function : AddVolumeWithID
1665 //purpose  : 
1666 //=======================================================================
1667 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4,
1668                                                int n5, int n6, int n7, int n8,
1669                                                int n12,int n23,int n34,int n41,
1670                                                int n56,int n67,int n78,int n85,
1671                                                int n15,int n26,int n37,int n48, int ID)
1672 {
1673   SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolumeWithID(n1,n2,n3,n4,n5,n6,n7,n8,
1674                                                        n12,n23,n34,n41,
1675                                                        n56,n67,n78,n85,
1676                                                        n15,n26,n37,n48,ID);
1677   if(anElem) myScript->AddVolume(ID,n1,n2,n3,n4,n5,n6,n7,n8,n12,n23,n34,n41,
1678                                  n56,n67,n78,n85,n15,n26,n37,n48);
1679   return anElem;
1680 }
1681         
1682 //=======================================================================
1683 //function : AddVolumeWithID
1684 //purpose  : 2d order Hexahedrons with 20 nodes
1685 //=======================================================================
1686 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
1687                                                const SMDS_MeshNode * n2,
1688                                                const SMDS_MeshNode * n3,
1689                                                const SMDS_MeshNode * n4,
1690                                                const SMDS_MeshNode * n5, 
1691                                                const SMDS_MeshNode * n6, 
1692                                                const SMDS_MeshNode * n7,
1693                                                const SMDS_MeshNode * n8, 
1694                                                const SMDS_MeshNode * n12,
1695                                                const SMDS_MeshNode * n23,
1696                                                const SMDS_MeshNode * n34,
1697                                                const SMDS_MeshNode * n41, 
1698                                                const SMDS_MeshNode * n56,
1699                                                const SMDS_MeshNode * n67,
1700                                                const SMDS_MeshNode * n78,
1701                                                const SMDS_MeshNode * n85, 
1702                                                const SMDS_MeshNode * n15,
1703                                                const SMDS_MeshNode * n26,
1704                                                const SMDS_MeshNode * n37,
1705                                                const SMDS_MeshNode * n48,
1706                                                int ID)
1707 {
1708   return AddVolumeWithID(n1->GetID(), n2->GetID(), n3->GetID(), n4->GetID(),
1709                          n5->GetID(), n6->GetID(), n7->GetID(), n8->GetID(),
1710                          n12->GetID(), n23->GetID(), n34->GetID(), n41->GetID(),
1711                          n56->GetID(), n67->GetID(), n78->GetID(), n85->GetID(),
1712                          n15->GetID(), n26->GetID(), n37->GetID(), n48->GetID(),
1713                          ID);
1714 }
1715
1716