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