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