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