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