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