Salome HOME
Avoid too often Standard_OutOfRange
[modules/smesh.git] / src / SMESHDS / SMESHDS_Mesh.cxx
1 // Copyright (C) 2007-2014  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, or (at your option) any later version.
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 //
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 "SMDS_Downward.hxx"
36 #include "SMESHDS_GroupOnGeom.hxx"
37 #include "SMESHDS_Script.hxx"
38
39 #include <Standard_ErrorHandler.hxx>
40 #include <Standard_OutOfRange.hxx>
41 #include <TopExp.hxx>
42 #include <TopExp_Explorer.hxx>
43 #include <TopoDS_Edge.hxx>
44 #include <TopoDS_Face.hxx>
45 #include <TopoDS_Iterator.hxx>
46 #include <TopoDS_Shell.hxx>
47 #include <TopoDS_Solid.hxx>
48 #include <TopoDS_Vertex.hxx>
49
50 #include "utilities.h"
51
52 using namespace std;
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
206 void SMESHDS_Mesh::MoveNode(const SMDS_MeshNode *n, double x, double y, double z)
207 {
208   SMDS_Mesh::MoveNode( n, 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 :AddBallWithID
310 //purpose  : 
311 //=======================================================================
312
313 SMDS_BallElement* SMESHDS_Mesh::AddBallWithID(int node, double diameter, int ID)
314 {
315   SMDS_BallElement* anElem = SMDS_Mesh::AddBallWithID(node,diameter,ID);
316   if (anElem) myScript->AddBall(anElem->GetID(), node, diameter);
317   return anElem;
318 }
319
320 SMDS_BallElement* SMESHDS_Mesh::AddBallWithID(const SMDS_MeshNode * node,
321                                               double                diameter,
322                                               int                   ID)
323 {
324   SMDS_BallElement* anElem = SMDS_Mesh::AddBallWithID(node,diameter,ID);
325   if (anElem) myScript->AddBall(anElem->GetID(), node->GetID(), diameter);
326   return anElem;
327 }
328
329 SMDS_BallElement* SMESHDS_Mesh::AddBall (const SMDS_MeshNode * node,
330                                          double                diameter)
331 {
332   SMDS_BallElement* anElem = SMDS_Mesh::AddBall(node,diameter);
333   if (anElem) myScript->AddBall(anElem->GetID(), node->GetID(), diameter);
334   return anElem;
335 }
336
337 //=======================================================================
338 //function :AddEdgeWithID
339 //purpose  : 
340 //=======================================================================
341
342 SMDS_MeshEdge* SMESHDS_Mesh::AddEdgeWithID(int n1, int n2, int ID)
343 {
344   SMDS_MeshEdge* anElem = SMDS_Mesh::AddEdgeWithID(n1,n2,ID);
345   if(anElem) myScript->AddEdge(ID,n1,n2);
346   return anElem;
347 }
348
349 SMDS_MeshEdge* SMESHDS_Mesh::AddEdgeWithID(const SMDS_MeshNode * n1,
350                                            const SMDS_MeshNode * n2, 
351                                            int ID)
352 {
353   return AddEdgeWithID(n1->GetID(),
354                        n2->GetID(),
355                        ID);
356 }
357
358 SMDS_MeshEdge* SMESHDS_Mesh::AddEdge(const SMDS_MeshNode * n1,
359                                      const SMDS_MeshNode * n2)
360 {
361   SMDS_MeshEdge* anElem = SMDS_Mesh::AddEdge(n1,n2);
362   if(anElem) myScript->AddEdge(anElem->GetID(), 
363                                n1->GetID(), 
364                                n2->GetID());
365   return anElem;
366 }
367
368 //=======================================================================
369 //function :AddFace
370 //purpose  : 
371 //=======================================================================
372 SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(int n1, int n2, int n3, int ID)
373 {
374   SMDS_MeshFace *anElem = SMDS_Mesh::AddFaceWithID(n1, n2, n3, ID);
375   if(anElem) myScript->AddFace(ID,n1,n2,n3);
376   return anElem;
377 }
378
379 SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
380                                            const SMDS_MeshNode * n2,
381                                            const SMDS_MeshNode * n3, 
382                                            int ID)
383 {
384   return AddFaceWithID(n1->GetID(),
385                        n2->GetID(),
386                        n3->GetID(),
387                        ID);
388 }
389
390 SMDS_MeshFace* SMESHDS_Mesh::AddFace( const SMDS_MeshNode * n1,
391                                       const SMDS_MeshNode * n2,
392                                       const SMDS_MeshNode * n3)
393 {
394   SMDS_MeshFace *anElem = SMDS_Mesh::AddFace(n1, n2, n3);
395   if(anElem) myScript->AddFace(anElem->GetID(), 
396                                n1->GetID(), 
397                                n2->GetID(),
398                                n3->GetID());
399   return anElem;
400 }
401
402 //=======================================================================
403 //function :AddFace
404 //purpose  : 
405 //=======================================================================
406 SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(int n1, int n2, int n3, int n4, int ID)
407 {
408   SMDS_MeshFace *anElem = SMDS_Mesh::AddFaceWithID(n1, n2, n3, n4, ID);
409   if(anElem) myScript->AddFace(ID, n1, n2, n3, n4);
410   return anElem;
411 }
412
413 SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
414                                            const SMDS_MeshNode * n2,
415                                            const SMDS_MeshNode * n3,
416                                            const SMDS_MeshNode * n4, 
417                                            int ID)
418 {
419   return AddFaceWithID(n1->GetID(),
420                        n2->GetID(),
421                        n3->GetID(),
422                        n4->GetID(),
423                        ID);
424 }
425
426 SMDS_MeshFace* SMESHDS_Mesh::AddFace(const SMDS_MeshNode * n1,
427                                      const SMDS_MeshNode * n2,
428                                      const SMDS_MeshNode * n3,
429                                      const SMDS_MeshNode * n4)
430 {
431   SMDS_MeshFace *anElem = SMDS_Mesh::AddFace(n1, n2, n3, n4);
432   if(anElem) myScript->AddFace(anElem->GetID(), 
433                                n1->GetID(), 
434                                n2->GetID(), 
435                                n3->GetID(),
436                                n4->GetID());
437   return anElem;
438 }
439
440 //=======================================================================
441 //function :AddVolume
442 //purpose  : 
443 //=======================================================================
444 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4, int ID)
445 {
446   SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, ID);
447   if(anElem) myScript->AddVolume(ID, n1, n2, n3, n4);
448   return anElem;
449 }
450
451 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
452                                                const SMDS_MeshNode * n2,
453                                                const SMDS_MeshNode * n3,
454                                                const SMDS_MeshNode * n4, 
455                                                int ID)
456 {
457   return AddVolumeWithID(n1->GetID(), 
458                          n2->GetID(), 
459                          n3->GetID(),
460                          n4->GetID(),
461                          ID);
462 }
463
464 SMDS_MeshVolume* SMESHDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
465                                          const SMDS_MeshNode * n2,
466                                          const SMDS_MeshNode * n3,
467                                          const SMDS_MeshNode * n4)
468 {
469   SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolume(n1, n2, n3, n4);
470   if(anElem) myScript->AddVolume(anElem->GetID(), 
471                                  n1->GetID(), 
472                                  n2->GetID(), 
473                                  n3->GetID(),
474                                  n4->GetID());
475   return anElem;
476 }
477
478 //=======================================================================
479 //function :AddVolume
480 //purpose  : 
481 //=======================================================================
482 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4, int n5, int ID)
483 {
484   SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, ID);
485   if(anElem) myScript->AddVolume(ID, n1, n2, n3, n4, n5);
486   return anElem;
487 }
488
489 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
490                                                const SMDS_MeshNode * n2,
491                                                const SMDS_MeshNode * n3,
492                                                const SMDS_MeshNode * n4,
493                                                const SMDS_MeshNode * n5, 
494                                                int ID)
495 {
496   return AddVolumeWithID(n1->GetID(), 
497                          n2->GetID(), 
498                          n3->GetID(),
499                          n4->GetID(), 
500                          n5->GetID(),
501                          ID);
502 }
503
504 SMDS_MeshVolume* SMESHDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
505                                          const SMDS_MeshNode * n2,
506                                          const SMDS_MeshNode * n3,
507                                          const SMDS_MeshNode * n4,
508                                          const SMDS_MeshNode * n5)
509 {
510   SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolume(n1, n2, n3, n4, n5);
511   if(anElem) myScript->AddVolume(anElem->GetID(), 
512                                  n1->GetID(), 
513                                  n2->GetID(), 
514                                  n3->GetID(),
515                                  n4->GetID(), 
516                                  n5->GetID());
517   return anElem;
518 }
519
520 //=======================================================================
521 //function :AddVolume
522 //purpose  : 
523 //=======================================================================
524 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4, int n5, int n6, int ID)
525 {
526   SMDS_MeshVolume *anElem= SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, ID);
527   if(anElem) myScript->AddVolume(ID, n1, n2, n3, n4, n5, n6);
528   return anElem;
529 }
530
531 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
532                                                const SMDS_MeshNode * n2,
533                                                const SMDS_MeshNode * n3,
534                                                const SMDS_MeshNode * n4,
535                                                const SMDS_MeshNode * n5,
536                                                const SMDS_MeshNode * n6, 
537                                                int ID)
538 {
539   return AddVolumeWithID(n1->GetID(), 
540                          n2->GetID(), 
541                          n3->GetID(),
542                          n4->GetID(), 
543                          n5->GetID(), 
544                          n6->GetID(),
545                          ID);
546 }
547
548 SMDS_MeshVolume* SMESHDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
549                                          const SMDS_MeshNode * n2,
550                                          const SMDS_MeshNode * n3,
551                                          const SMDS_MeshNode * n4,
552                                          const SMDS_MeshNode * n5,
553                                          const SMDS_MeshNode * n6)
554 {
555   SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolume(n1, n2, n3, n4, n5, n6);
556   if(anElem) myScript->AddVolume(anElem->GetID(), 
557                                  n1->GetID(), 
558                                  n2->GetID(), 
559                                  n3->GetID(),
560                                  n4->GetID(), 
561                                  n5->GetID(), 
562                                  n6->GetID());
563   return anElem;
564 }
565
566 //=======================================================================
567 //function :AddVolume
568 //purpose  : 
569 //=======================================================================
570 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4, int n5, int n6, int n7, int n8, int ID)
571 {
572   SMDS_MeshVolume *anElem= SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, n7, n8, ID);
573   if(anElem) myScript->AddVolume(ID, n1, n2, n3, n4, n5, n6, n7, n8);
574   return anElem;
575 }
576
577 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
578                                                const SMDS_MeshNode * n2,
579                                                const SMDS_MeshNode * n3,
580                                                const SMDS_MeshNode * n4,
581                                                const SMDS_MeshNode * n5,
582                                                const SMDS_MeshNode * n6,
583                                                const SMDS_MeshNode * n7,
584                                                const SMDS_MeshNode * n8, 
585                                                int ID)
586 {
587   return AddVolumeWithID(n1->GetID(), 
588                          n2->GetID(), 
589                          n3->GetID(),
590                          n4->GetID(), 
591                          n5->GetID(), 
592                          n6->GetID(), 
593                          n7->GetID(), 
594                          n8->GetID(),
595                          ID);
596 }
597
598 SMDS_MeshVolume* SMESHDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
599                                          const SMDS_MeshNode * n2,
600                                          const SMDS_MeshNode * n3,
601                                          const SMDS_MeshNode * n4,
602                                          const SMDS_MeshNode * n5,
603                                          const SMDS_MeshNode * n6,
604                                          const SMDS_MeshNode * n7,
605                                          const SMDS_MeshNode * n8)
606 {
607   SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolume(n1, n2, n3, n4, n5, n6, n7, n8);
608   if(anElem) myScript->AddVolume(anElem->GetID(), 
609                                  n1->GetID(), 
610                                  n2->GetID(), 
611                                  n3->GetID(),
612                                  n4->GetID(), 
613                                  n5->GetID(), 
614                                  n6->GetID(), 
615                                  n7->GetID(), 
616                                  n8->GetID());
617   return anElem;
618 }
619
620
621 //=======================================================================
622 //function :AddVolume
623 //purpose  : add hexagonal prism
624 //=======================================================================
625 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4,
626                                                int n5, int n6, int n7, int n8,
627                                                int n9, int n10, int n11, int n12,
628                                                int ID)
629 {
630   SMDS_MeshVolume *anElem= SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, n7, n8, n9, n10, n11, n12, ID);
631   if(anElem) myScript->AddVolume(ID, n1, n2, n3, n4, n5, n6, n7, n8, n9, n10, n11, n12);
632   return anElem;
633 }
634
635 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
636                                                const SMDS_MeshNode * n2,
637                                                const SMDS_MeshNode * n3,
638                                                const SMDS_MeshNode * n4,
639                                                const SMDS_MeshNode * n5,
640                                                const SMDS_MeshNode * n6,
641                                                const SMDS_MeshNode * n7,
642                                                const SMDS_MeshNode * n8, 
643                                                const SMDS_MeshNode * n9, 
644                                                const SMDS_MeshNode * n10, 
645                                                const SMDS_MeshNode * n11, 
646                                                const SMDS_MeshNode * n12, 
647                                                int ID)
648 {
649   return AddVolumeWithID(n1->GetID(), 
650                          n2->GetID(),
651                          n3->GetID(),
652                          n4->GetID(),
653                          n5->GetID(),
654                          n6->GetID(),
655                          n7->GetID(),
656                          n8->GetID(),
657                          n9->GetID(),
658                          n10->GetID(),
659                          n11->GetID(),
660                          n12->GetID(),
661                          ID);
662 }
663
664 SMDS_MeshVolume* SMESHDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
665                                          const SMDS_MeshNode * n2,
666                                          const SMDS_MeshNode * n3,
667                                          const SMDS_MeshNode * n4,
668                                          const SMDS_MeshNode * n5,
669                                          const SMDS_MeshNode * n6,
670                                          const SMDS_MeshNode * n7,
671                                          const SMDS_MeshNode * n8, 
672                                          const SMDS_MeshNode * n9, 
673                                          const SMDS_MeshNode * n10, 
674                                          const SMDS_MeshNode * n11, 
675                                          const SMDS_MeshNode * n12)
676 {
677   SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolume(n1, n2, n3, n4, n5, n6, n7, n8, n9, n10, n11, n12);
678   if(anElem) myScript->AddVolume(anElem->GetID(), 
679                                  n1->GetID(),
680                                  n2->GetID(),
681                                  n3->GetID(),
682                                  n4->GetID(),
683                                  n5->GetID(),
684                                  n6->GetID(),
685                                  n7->GetID(),
686                                  n8->GetID(),
687                                  n9->GetID(),
688                                  n10->GetID(),
689                                  n11->GetID(),
690                                  n12->GetID());
691   return anElem;
692 }
693
694
695 //=======================================================================
696 //function : AddPolygonalFace
697 //purpose  : 
698 //=======================================================================
699 SMDS_MeshFace* SMESHDS_Mesh::AddPolygonalFaceWithID (const std::vector<int>& nodes_ids,
700                                                      const int               ID)
701 {
702   SMDS_MeshFace *anElem = SMDS_Mesh::AddPolygonalFaceWithID(nodes_ids, ID);
703   if (anElem) {
704     myScript->AddPolygonalFace(ID, nodes_ids);
705   }
706   return anElem;
707 }
708
709 SMDS_MeshFace* SMESHDS_Mesh::AddPolygonalFaceWithID
710                              (const std::vector<const SMDS_MeshNode*>& nodes,
711                               const int                                ID)
712 {
713   SMDS_MeshFace *anElem = SMDS_Mesh::AddPolygonalFaceWithID(nodes, ID);
714   if (anElem) {
715     int i, len = nodes.size();
716     std::vector<int> nodes_ids (len);
717     for (i = 0; i < len; i++) {
718       nodes_ids[i] = nodes[i]->GetID();
719     }
720     myScript->AddPolygonalFace(ID, nodes_ids);
721   }
722   return anElem;
723 }
724
725 SMDS_MeshFace* SMESHDS_Mesh::AddPolygonalFace
726                              (const std::vector<const SMDS_MeshNode*>& nodes)
727 {
728   SMDS_MeshFace *anElem = SMDS_Mesh::AddPolygonalFace(nodes);
729   if (anElem) {
730     int i, len = nodes.size();
731     std::vector<int> nodes_ids (len);
732     for (i = 0; i < len; i++) {
733       nodes_ids[i] = nodes[i]->GetID();
734     }
735     myScript->AddPolygonalFace(anElem->GetID(), nodes_ids);
736   }
737   return anElem;
738 }
739
740 //=======================================================================
741 //function : AddPolyhedralVolume
742 //purpose  : 
743 //=======================================================================
744 SMDS_MeshVolume* SMESHDS_Mesh::AddPolyhedralVolumeWithID (const std::vector<int>& nodes_ids,
745                                                           const std::vector<int>& quantities,
746                                                           const int               ID)
747 {
748   SMDS_MeshVolume *anElem = SMDS_Mesh::AddPolyhedralVolumeWithID(nodes_ids, quantities, ID);
749   if (anElem) {
750     myScript->AddPolyhedralVolume(ID, nodes_ids, quantities);
751   }
752   return anElem;
753 }
754
755 SMDS_MeshVolume* SMESHDS_Mesh::AddPolyhedralVolumeWithID
756                                (const std::vector<const SMDS_MeshNode*>& nodes,
757                                 const std::vector<int>&                  quantities,
758                                 const int                                ID)
759 {
760   SMDS_MeshVolume *anElem = SMDS_Mesh::AddPolyhedralVolumeWithID(nodes, quantities, ID);
761   if (anElem) {
762     int i, len = nodes.size();
763     std::vector<int> nodes_ids (len);
764     for (i = 0; i < len; i++) {
765       nodes_ids[i] = nodes[i]->GetID();
766     }
767     myScript->AddPolyhedralVolume(ID, nodes_ids, quantities);
768   }
769   return anElem;
770 }
771
772 SMDS_MeshVolume* SMESHDS_Mesh::AddPolyhedralVolume
773                                (const std::vector<const SMDS_MeshNode*>& nodes,
774                                 const std::vector<int>&                  quantities)
775 {
776   SMDS_MeshVolume *anElem = SMDS_Mesh::AddPolyhedralVolume(nodes, quantities);
777   if (anElem) {
778     int i, len = nodes.size();
779     std::vector<int> nodes_ids (len);
780     for (i = 0; i < len; i++) {
781       nodes_ids[i] = nodes[i]->GetID();
782     }
783     myScript->AddPolyhedralVolume(anElem->GetID(), nodes_ids, quantities);
784   }
785   return anElem;
786 }
787
788 //=======================================================================
789 //function : removeFromContainers
790 //purpose  : 
791 //=======================================================================
792
793 static void removeFromContainers (map<int,SMESHDS_SubMesh*>&     theSubMeshes,
794                                   set<SMESHDS_GroupBase*>&       theGroups,
795                                   list<const SMDS_MeshElement*>& theElems,
796                                   const bool                     isNode)
797 {
798   if ( theElems.empty() )
799     return;
800
801   // Rm from group
802   // Element can belong to several groups
803   if ( !theGroups.empty() )
804   {
805     set<SMESHDS_GroupBase*>::iterator GrIt = theGroups.begin();
806     for ( ; GrIt != theGroups.end(); GrIt++ )
807     {
808       SMESHDS_Group* group = dynamic_cast<SMESHDS_Group*>( *GrIt );
809       if ( !group || group->IsEmpty() ) continue;
810
811       list<const SMDS_MeshElement *>::iterator elIt = theElems.begin();
812       for ( ; elIt != theElems.end(); elIt++ )
813       {
814         group->SMDSGroup().Remove( *elIt );
815         if ( group->IsEmpty() ) break;
816       }
817     }
818   }
819
820   const bool deleted=true;
821
822   // Rm from sub-meshes
823   // Element should belong to only one sub-mesh
824   if ( !theSubMeshes.empty() )
825   {
826     SMESHDS_Mesh* mesh = theSubMeshes.begin()->second->GetParent();
827     list<const SMDS_MeshElement *>::iterator elIt = theElems.begin();
828     if ( isNode ) {
829       for ( ; elIt != theElems.end(); ++elIt )
830         if ( SMESHDS_SubMesh* sm = mesh->MeshElements( (*elIt)->getshapeId() ))
831           sm->RemoveNode( static_cast<const SMDS_MeshNode*> (*elIt), deleted );
832     }
833     else {
834       for ( ; elIt != theElems.end(); ++elIt )
835         if ( SMESHDS_SubMesh* sm = mesh->MeshElements( (*elIt)->getshapeId() ))
836           sm->RemoveElement( *elIt, deleted );
837     }
838   }
839 }
840
841 //=======================================================================
842 //function : RemoveNode
843 //purpose  : 
844 //=======================================================================
845 void SMESHDS_Mesh::RemoveNode(const SMDS_MeshNode * n)
846 {
847   if ( n->NbInverseElements() == 0 && !(hasConstructionEdges() || hasConstructionFaces()))
848   {
849     SMESHDS_SubMesh* subMesh=0;
850     map<int,SMESHDS_SubMesh*>::iterator SubIt =
851       myShapeIndexToSubMesh.find( n->getshapeId() );
852     if ( SubIt != myShapeIndexToSubMesh.end() )
853       subMesh = SubIt->second;
854     else
855       SubIt = myShapeIndexToSubMesh.begin();
856     for ( ; !subMesh && SubIt != myShapeIndexToSubMesh.end(); SubIt++ )
857       if (!SubIt->second->IsComplexSubmesh() && SubIt->second->Contains( n ))
858         subMesh = SubIt->second;
859
860     RemoveFreeNode( n, subMesh, true);
861     return;
862   }
863     
864   myScript->RemoveNode(n->GetID());
865   
866   list<const SMDS_MeshElement *> removedElems;
867   list<const SMDS_MeshElement *> removedNodes;
868
869   SMDS_Mesh::RemoveElement( n, removedElems, removedNodes, true );
870
871   removeFromContainers( myShapeIndexToSubMesh, myGroups, removedElems, false );
872   removeFromContainers( myShapeIndexToSubMesh, myGroups, removedNodes, true );
873 }
874
875 //=======================================================================
876 //function : RemoveFreeNode
877 //purpose  : 
878 //=======================================================================
879 void SMESHDS_Mesh::RemoveFreeNode(const SMDS_MeshNode * n,
880                                   SMESHDS_SubMesh *     subMesh,
881                                   bool                  fromGroups)
882 {
883   myScript->RemoveNode(n->GetID());
884
885   // Rm from group
886   // Node can belong to several groups
887   if (fromGroups && !myGroups.empty()) {
888     set<SMESHDS_GroupBase*>::iterator GrIt = myGroups.begin();
889     for (; GrIt != myGroups.end(); GrIt++) {
890       SMESHDS_Group* group = dynamic_cast<SMESHDS_Group*>(*GrIt);
891       if (group && !group->IsEmpty())
892         group->SMDSGroup().Remove(n);
893     }
894   }
895
896   // Rm from sub-mesh
897   // Node should belong to only one sub-mesh
898   if ( !subMesh || !subMesh->RemoveNode(n,/*deleted=*/false))
899     if (( subMesh = MeshElements( n->getshapeId() )))
900       subMesh->RemoveNode(n,/*deleted=*/false );
901
902   SMDS_Mesh::RemoveFreeElement(n);
903 }
904
905 //=======================================================================
906 //function : RemoveElement
907 //purpose  : 
908 //========================================================================
909 void SMESHDS_Mesh::RemoveElement(const SMDS_MeshElement * elt)
910 {
911   if (elt->GetType() == SMDSAbs_Node)
912   {
913     RemoveNode( static_cast<const SMDS_MeshNode*>( elt ));
914     return;
915   }
916   if (!hasConstructionEdges() && !hasConstructionFaces())
917   {
918     SMESHDS_SubMesh* subMesh=0;
919     if ( elt->getshapeId() > 0 )
920     {
921       map<int,SMESHDS_SubMesh*>::iterator SubIt = myShapeIndexToSubMesh.find( elt->getshapeId() );
922       if ( SubIt != myShapeIndexToSubMesh.end() )
923         subMesh = SubIt->second;
924     }
925     RemoveFreeElement( elt, subMesh, true);
926     return;
927   }
928  
929   myScript->RemoveElement(elt->GetID());
930
931   list<const SMDS_MeshElement *> removedElems;
932   list<const SMDS_MeshElement *> removedNodes;
933
934   SMDS_Mesh::RemoveElement(elt, removedElems, removedNodes, false);
935   
936   removeFromContainers( myShapeIndexToSubMesh, myGroups, removedElems, false );
937 }
938
939 //=======================================================================
940 //function : RemoveFreeElement
941 //purpose  : 
942 //========================================================================
943 void SMESHDS_Mesh::RemoveFreeElement(const SMDS_MeshElement * elt,
944                                      SMESHDS_SubMesh *        subMesh,
945                                      bool                     fromGroups)
946 {
947   //MESSAGE(" --------------------------------> SMESHDS_Mesh::RemoveFreeElement " << subMesh << " " << fromGroups);
948   if (elt->GetType() == SMDSAbs_Node) {
949     RemoveFreeNode( static_cast<const SMDS_MeshNode*>(elt), subMesh);
950     return;
951   }
952
953   if (hasConstructionEdges() || hasConstructionFaces())
954     // this methods is only for meshes without descendants
955     return;
956
957   myScript->RemoveElement(elt->GetID());
958
959   // Rm from group
960   // Node can belong to several groups
961   if ( fromGroups && !myGroups.empty() ) {
962     set<SMESHDS_GroupBase*>::iterator GrIt = myGroups.begin();
963     for (; GrIt != myGroups.end(); GrIt++) {
964       SMESHDS_Group* group = dynamic_cast<SMESHDS_Group*>(*GrIt);
965       if (group && !group->IsEmpty())
966         group->SMDSGroup().Remove(elt);
967     }
968   }
969
970   // Rm from sub-mesh
971   // Element should belong to only one sub-mesh
972   if( subMesh )
973     subMesh->RemoveElement(elt, /*deleted=*/false);
974
975   SMDS_Mesh::RemoveFreeElement(elt);
976 }
977
978 //================================================================================
979 /*!
980  * \brief Remove all data from the mesh
981  */
982 //================================================================================
983
984 void SMESHDS_Mesh::ClearMesh()
985 {
986   myScript->ClearMesh();
987   SMDS_Mesh::Clear();
988
989   // clear submeshes
990   map<int,SMESHDS_SubMesh*>::iterator sub, subEnd = myShapeIndexToSubMesh.end();
991   for ( sub = myShapeIndexToSubMesh.begin(); sub != subEnd; ++sub )
992     sub->second->Clear();
993
994   // clear groups
995   TGroups::iterator group, groupEnd = myGroups.end();
996   for ( group = myGroups.begin(); group != groupEnd; ++group ) {
997     if ( SMESHDS_Group* g = dynamic_cast<SMESHDS_Group*>(*group)) {
998       SMDSAbs_ElementType groupType = g->GetType();
999       g->Clear();
1000       g->SetType( groupType );
1001     }
1002     else
1003     {
1004       (*group)->Extent(); // to free cashed elements in GroupOnFilter's
1005     }
1006   }
1007 }
1008
1009 //================================================================================
1010 /*!
1011  * \brief return submesh by shape
1012   * \param shape - the sub-shape
1013   * \retval SMESHDS_SubMesh* - the found submesh
1014   *
1015  * search of submeshes is optimized
1016  */
1017 //================================================================================
1018
1019 SMESHDS_SubMesh* SMESHDS_Mesh::getSubmesh( const TopoDS_Shape & shape )
1020 {
1021   if ( shape.IsNull() )
1022     return 0;
1023
1024   if ( !myCurSubShape.IsNull() && shape.IsSame( myCurSubShape ))
1025     return myCurSubMesh;
1026
1027   getSubmesh( ShapeToIndex( shape ));
1028   myCurSubShape = shape;
1029   return myCurSubMesh;
1030 }
1031
1032 //================================================================================
1033 /*!
1034  * \brief return submesh by sub-shape index
1035   * \param Index - the sub-shape index
1036   * \retval SMESHDS_SubMesh* - the found submesh
1037  * search of submeshes is optimized
1038  */
1039 //================================================================================
1040
1041 SMESHDS_SubMesh* SMESHDS_Mesh::getSubmesh( const int Index )
1042 {
1043   //Update or build submesh
1044   if ( Index != myCurSubID ) {
1045     map<int,SMESHDS_SubMesh*>::iterator it = myShapeIndexToSubMesh.find( Index );
1046     if ( it == myShapeIndexToSubMesh.end() )
1047       it = myShapeIndexToSubMesh.insert( make_pair(Index, new SMESHDS_SubMesh(this, Index) )).first;
1048     myCurSubMesh = it->second;
1049     myCurSubID = Index;
1050     myCurSubShape.Nullify(); // myCurSubShape no more corresponds to submesh
1051   }
1052   return myCurSubMesh;
1053 }
1054
1055 //================================================================================
1056 /*!
1057  * \brief Add element or node to submesh
1058   * \param elem - element to add
1059   * \param subMesh - submesh to be filled in
1060  */
1061 //================================================================================
1062
1063 bool SMESHDS_Mesh::add(const SMDS_MeshElement* elem, SMESHDS_SubMesh* subMesh )
1064 {
1065   if ( elem && subMesh ) {
1066     if ( elem->GetType() == SMDSAbs_Node )
1067       subMesh->AddNode( static_cast<const SMDS_MeshNode* >( elem ));
1068     else
1069       subMesh->AddElement( elem );
1070     return true;
1071   }
1072   return false;
1073 }
1074
1075 //=======================================================================
1076 //function : SetNodeOnVolume
1077 //purpose  : 
1078 //=======================================================================
1079 void SMESHDS_Mesh::SetNodeInVolume(const SMDS_MeshNode* aNode,
1080                                    const TopoDS_Shell & S)
1081 {
1082   if ( add( aNode, getSubmesh(S) ))
1083     const_cast< SMDS_MeshNode* >
1084       ( aNode )->SetPosition( SMDS_SpacePosition::originSpacePosition() );
1085 }
1086
1087 //=======================================================================
1088 //function : SetNodeOnVolume
1089 //purpose  : 
1090 //=======================================================================
1091 void SMESHDS_Mesh::SetNodeInVolume(const SMDS_MeshNode *      aNode,
1092                                    const TopoDS_Solid & S)
1093 {
1094   if ( add( aNode, getSubmesh(S) ))
1095     const_cast< SMDS_MeshNode* >
1096       ( aNode )->SetPosition( SMDS_SpacePosition::originSpacePosition() );
1097 }
1098
1099 //=======================================================================
1100 //function : SetNodeOnFace
1101 //purpose  : 
1102 //=======================================================================
1103 void SMESHDS_Mesh::SetNodeOnFace(const SMDS_MeshNode *     aNode,
1104                                  const TopoDS_Face & S,
1105                                  double              u,
1106                                  double              v)
1107 {
1108   if ( add( aNode, getSubmesh(S) ))
1109     const_cast< SMDS_MeshNode* >
1110       ( aNode )->SetPosition(SMDS_PositionPtr(new SMDS_FacePosition( u, v)));
1111 }
1112
1113 //=======================================================================
1114 //function : SetNodeOnEdge
1115 //purpose  : 
1116 //=======================================================================
1117 void SMESHDS_Mesh::SetNodeOnEdge(const SMDS_MeshNode *     aNode,
1118                                  const TopoDS_Edge & S,
1119                                  double              u)
1120 {
1121   if ( add( aNode, getSubmesh(S) ))
1122     const_cast< SMDS_MeshNode* >
1123       ( aNode )->SetPosition(SMDS_PositionPtr(new SMDS_EdgePosition(u)));
1124 }
1125
1126 //=======================================================================
1127 //function : SetNodeOnVertex
1128 //purpose  : 
1129 //=======================================================================
1130 void SMESHDS_Mesh::SetNodeOnVertex(const SMDS_MeshNode *       aNode,
1131                                    const TopoDS_Vertex & S)
1132 {
1133   if ( add( aNode, getSubmesh(S) ))
1134     const_cast< SMDS_MeshNode* >
1135       ( aNode )->SetPosition(SMDS_PositionPtr(new SMDS_VertexPosition()));
1136 }
1137
1138 //=======================================================================
1139 //function : UnSetNodeOnShape
1140 //purpose  : 
1141 //=======================================================================
1142 void SMESHDS_Mesh::UnSetNodeOnShape(const SMDS_MeshNode* aNode)
1143 {
1144   int shapeId = aNode->getshapeId();
1145   if (shapeId >= 0)
1146     {
1147       map<int, SMESHDS_SubMesh*>::iterator it = myShapeIndexToSubMesh.find(shapeId);
1148       if (it != myShapeIndexToSubMesh.end())
1149         it->second->RemoveNode(aNode, /*deleted=*/false);
1150     }
1151 }
1152
1153 //=======================================================================
1154 //function : SetMeshElementOnShape
1155 //purpose  : 
1156 //=======================================================================
1157 void SMESHDS_Mesh::SetMeshElementOnShape(const SMDS_MeshElement * anElement,
1158                                          const TopoDS_Shape &     S)
1159 {
1160   add( anElement, getSubmesh(S) );
1161 }
1162
1163 //=======================================================================
1164 //function : UnSetMeshElementOnShape
1165 //purpose  : 
1166 //=======================================================================
1167 void SMESHDS_Mesh::UnSetMeshElementOnShape(const SMDS_MeshElement * elem,
1168                                            const TopoDS_Shape &     S)
1169 {
1170   int Index = myIndexToShape.FindIndex(S);
1171
1172   map<int,SMESHDS_SubMesh*>::iterator it = myShapeIndexToSubMesh.find( Index );
1173   if ( it != myShapeIndexToSubMesh.end() )
1174     {
1175       if (elem->GetType() == SMDSAbs_Node)
1176         it->second->RemoveNode(static_cast<const SMDS_MeshNode*> (elem), /*deleted=*/false);
1177       else
1178         it->second->RemoveElement(elem, /*deleted=*/false);
1179     }
1180 }
1181
1182 //=======================================================================
1183 //function : ShapeToMesh
1184 //purpose  : 
1185 //=======================================================================
1186 TopoDS_Shape SMESHDS_Mesh::ShapeToMesh() const
1187 {
1188         return myShape;
1189 }
1190
1191 //=======================================================================
1192 //function : IsGroupOfSubShapes
1193 //purpose  : return true if at least one sub-shape of theShape is a sub-shape
1194 //           of myShape or theShape == myShape
1195 //=======================================================================
1196
1197 bool SMESHDS_Mesh::IsGroupOfSubShapes (const TopoDS_Shape& theShape) const
1198 {
1199   if ( myIndexToShape.Contains(theShape) )
1200     return true;
1201
1202   for ( TopoDS_Iterator it( theShape ); it.More(); it.Next() )
1203     if (IsGroupOfSubShapes( it.Value() ))
1204       return true;
1205
1206   return false;
1207 }
1208
1209 ///////////////////////////////////////////////////////////////////////////////
1210 /// Return the sub mesh linked to the a given TopoDS_Shape or NULL if the given
1211 /// TopoDS_Shape is unknown
1212 ///////////////////////////////////////////////////////////////////////////////
1213 SMESHDS_SubMesh * SMESHDS_Mesh::MeshElements(const TopoDS_Shape & S) const
1214 {
1215   int Index = ShapeToIndex(S);
1216   TShapeIndexToSubMesh::const_iterator anIter = myShapeIndexToSubMesh.find(Index);
1217   if (anIter != myShapeIndexToSubMesh.end())
1218     return anIter->second;
1219   else
1220     return NULL;
1221 }
1222
1223 ///////////////////////////////////////////////////////////////////////////////
1224 /// Return the sub mesh by Id of shape it is linked to
1225 ///////////////////////////////////////////////////////////////////////////////
1226 SMESHDS_SubMesh * SMESHDS_Mesh::MeshElements(const int Index) const
1227 {
1228   TShapeIndexToSubMesh::const_iterator anIter = myShapeIndexToSubMesh.find(Index);
1229   if (anIter != myShapeIndexToSubMesh.end())
1230     return anIter->second;
1231   else
1232     return NULL;
1233 }
1234
1235 //=======================================================================
1236 //function : SubMeshIndices
1237 //purpose  : 
1238 //=======================================================================
1239 list<int> SMESHDS_Mesh::SubMeshIndices() const
1240 {
1241   list<int> anIndices;
1242   std::map<int,SMESHDS_SubMesh*>::const_iterator anIter = myShapeIndexToSubMesh.begin();
1243   for (; anIter != myShapeIndexToSubMesh.end(); anIter++) {
1244     anIndices.push_back((*anIter).first);
1245   }
1246   return anIndices;
1247 }
1248
1249 //=======================================================================
1250 //function : GetHypothesis
1251 //purpose  : 
1252 //=======================================================================
1253
1254 const list<const SMESHDS_Hypothesis*>&
1255 SMESHDS_Mesh::GetHypothesis(const TopoDS_Shape & S) const
1256 {
1257   if ( myShapeToHypothesis.IsBound( S.Oriented(TopAbs_FORWARD) ) ) // ignore orientation of S
1258      return myShapeToHypothesis.Find( S.Oriented(TopAbs_FORWARD) );
1259
1260   static list<const SMESHDS_Hypothesis*> empty;
1261   return empty;
1262 }
1263
1264 //================================================================================
1265 /*!
1266  * \brief returns true if the hypothesis is assigned to any sub-shape
1267  */
1268 //================================================================================
1269
1270 bool SMESHDS_Mesh::IsUsedHypothesis(const SMESHDS_Hypothesis * H) const
1271 {
1272   ShapeToHypothesis::Iterator s2h( myShapeToHypothesis );
1273   for ( ; s2h.More(); s2h.Next() )
1274     if ( std::find( s2h.Value().begin(), s2h.Value().end(), H ) != s2h.Value().end() )
1275       return true;
1276   return false;
1277 }
1278
1279 //=======================================================================
1280 //function : GetScript
1281 //purpose  : 
1282 //=======================================================================
1283 SMESHDS_Script* SMESHDS_Mesh::GetScript()
1284 {
1285         return myScript;
1286 }
1287
1288 //=======================================================================
1289 //function : ClearScript
1290 //purpose  : 
1291 //=======================================================================
1292 void SMESHDS_Mesh::ClearScript()
1293 {
1294         myScript->Clear();
1295 }
1296
1297 //=======================================================================
1298 //function : HasMeshElements
1299 //purpose  : 
1300 //=======================================================================
1301 bool SMESHDS_Mesh::HasMeshElements(const TopoDS_Shape & S) const
1302 {
1303         if (myShape.IsNull()) MESSAGE("myShape is NULL");
1304         int Index = myIndexToShape.FindIndex(S);
1305         return myShapeIndexToSubMesh.find(Index)!=myShapeIndexToSubMesh.end();
1306 }
1307
1308 //=======================================================================
1309 //function : HasHypothesis
1310 //purpose  : 
1311 //=======================================================================
1312 bool SMESHDS_Mesh::HasHypothesis(const TopoDS_Shape & S)
1313 {
1314   return myShapeToHypothesis.IsBound(S.Oriented(TopAbs_FORWARD));
1315 }
1316
1317 //=======================================================================
1318 //function : NewSubMesh 
1319 //purpose  : 
1320 //=======================================================================
1321 SMESHDS_SubMesh * SMESHDS_Mesh::NewSubMesh(int Index)
1322 {
1323   SMESHDS_SubMesh* SM = 0;
1324   TShapeIndexToSubMesh::iterator anIter = myShapeIndexToSubMesh.find(Index);
1325   if (anIter == myShapeIndexToSubMesh.end())
1326   {
1327     SM = new SMESHDS_SubMesh(this, Index);
1328     myShapeIndexToSubMesh[Index]=SM;
1329   }
1330   else
1331     SM = anIter->second;
1332   return SM;
1333 }
1334
1335 //=======================================================================
1336 //function : AddCompoundSubmesh
1337 //purpose  : 
1338 //=======================================================================
1339
1340 int SMESHDS_Mesh::AddCompoundSubmesh(const TopoDS_Shape& S,
1341                                      TopAbs_ShapeEnum    type)
1342 {
1343   int aMainIndex = 0;
1344   if ( IsGroupOfSubShapes( S ))
1345   {
1346     aMainIndex = myIndexToShape.Add( S );
1347     bool all = ( type == TopAbs_SHAPE );
1348     if ( all ) // corresponding simple submesh may exist
1349       aMainIndex = -aMainIndex;
1350     //MESSAGE("AddCompoundSubmesh index = " << aMainIndex );
1351     SMESHDS_SubMesh * aNewSub = NewSubMesh( aMainIndex );
1352     if ( !aNewSub->IsComplexSubmesh() ) // is empty
1353     {
1354       int shapeType = Max( TopAbs_SOLID, all ? myShape.ShapeType() : type );
1355       int typeLimit = all ? TopAbs_VERTEX : type;
1356       for ( ; shapeType <= typeLimit; shapeType++ )
1357       {
1358         TopExp_Explorer exp( S, TopAbs_ShapeEnum( shapeType ));
1359         for ( ; exp.More(); exp.Next() )
1360         {
1361           int index = myIndexToShape.FindIndex( exp.Current() );
1362           if ( index )
1363             aNewSub->AddSubMesh( NewSubMesh( index ));
1364         }
1365       }
1366     }
1367   }
1368   return aMainIndex;
1369 }
1370
1371 //=======================================================================
1372 //function : IndexToShape
1373 //purpose  : 
1374 //=======================================================================
1375 const TopoDS_Shape& SMESHDS_Mesh::IndexToShape(int ShapeIndex) const
1376 {
1377   try
1378   {
1379     if ( ShapeIndex > 0 )
1380       return myIndexToShape.FindKey(ShapeIndex);
1381   }
1382   catch ( Standard_OutOfRange )
1383   {
1384   }
1385   static TopoDS_Shape nullShape;
1386   return nullShape;
1387 }
1388
1389 //================================================================================
1390 /*!
1391  * \brief Return max index of sub-mesh
1392  */
1393 //================================================================================
1394
1395 int SMESHDS_Mesh::MaxSubMeshIndex() const
1396 {
1397   return myShapeIndexToSubMesh.empty() ? 0 : myShapeIndexToSubMesh.rbegin()->first;
1398 }
1399
1400 //=======================================================================
1401 //function : ShapeToIndex
1402 //purpose  : 
1403 //=======================================================================
1404 int SMESHDS_Mesh::ShapeToIndex(const TopoDS_Shape & S) const
1405 {
1406   if (myShape.IsNull())
1407     MESSAGE("myShape is NULL");
1408
1409   int index = myIndexToShape.FindIndex(S);
1410   
1411   return index;
1412 }
1413
1414 //=======================================================================
1415 //function : SetNodeOnVolume
1416 //purpose  : 
1417 //=======================================================================
1418 void SMESHDS_Mesh::SetNodeInVolume(const SMDS_MeshNode* aNode, int Index)
1419 {
1420   //add(aNode, getSubmesh(Index));
1421   if ( add( aNode, getSubmesh( Index )))
1422     ((SMDS_MeshNode*) aNode)->SetPosition( SMDS_SpacePosition::originSpacePosition());
1423 }
1424
1425 //=======================================================================
1426 //function : SetNodeOnFace
1427 //purpose  : 
1428 //=======================================================================
1429 void SMESHDS_Mesh::SetNodeOnFace(const SMDS_MeshNode* aNode, int Index, double u, double v)
1430 {
1431   //Set Position on Node
1432   if ( add( aNode, getSubmesh( Index )))
1433     const_cast< SMDS_MeshNode* >
1434       ( aNode )->SetPosition(SMDS_PositionPtr(new SMDS_FacePosition( u, v)));
1435 }
1436
1437 //=======================================================================
1438 //function : SetNodeOnEdge
1439 //purpose  : 
1440 //=======================================================================
1441 void SMESHDS_Mesh::SetNodeOnEdge(const SMDS_MeshNode* aNode,
1442                                  int                  Index,
1443                                  double               u)
1444 {
1445   //Set Position on Node
1446   if ( add( aNode, getSubmesh( Index )))
1447     const_cast< SMDS_MeshNode* >
1448       ( aNode )->SetPosition(SMDS_PositionPtr(new SMDS_EdgePosition(u)));
1449 }
1450
1451 //=======================================================================
1452 //function : SetNodeOnVertex
1453 //purpose  : 
1454 //=======================================================================
1455 void SMESHDS_Mesh::SetNodeOnVertex(const SMDS_MeshNode* aNode, int Index)
1456 {
1457   //Set Position on Node
1458   if ( add( aNode, getSubmesh( Index )))
1459     const_cast< SMDS_MeshNode* >
1460       ( aNode )->SetPosition(SMDS_PositionPtr(new SMDS_VertexPosition()));
1461 }
1462
1463 //=======================================================================
1464 //function : SetMeshElementOnShape
1465 //purpose  : 
1466 //=======================================================================
1467 void SMESHDS_Mesh::SetMeshElementOnShape(const SMDS_MeshElement* anElement,
1468                                          int                     Index)
1469 {
1470   add( anElement, getSubmesh( Index ));
1471 }
1472
1473 //=======================================================================
1474 //function : ~SMESHDS_Mesh
1475 //purpose  : 
1476 //=======================================================================
1477 SMESHDS_Mesh::~SMESHDS_Mesh()
1478 {
1479   // myScript
1480   delete myScript;
1481   // submeshes
1482   TShapeIndexToSubMesh::iterator i_sm = myShapeIndexToSubMesh.begin();
1483   for ( ; i_sm != myShapeIndexToSubMesh.end(); ++i_sm )
1484     delete i_sm->second;
1485 }
1486
1487
1488 //********************************************************************
1489 //********************************************************************
1490 //********                                                   *********
1491 //*****       Methods for addition of quadratic elements        ******
1492 //********                                                   *********
1493 //********************************************************************
1494 //********************************************************************
1495
1496 //=======================================================================
1497 //function : AddEdgeWithID
1498 //purpose  : 
1499 //=======================================================================
1500 SMDS_MeshEdge* SMESHDS_Mesh::AddEdgeWithID(int n1, int n2, int n12, int ID) 
1501 {
1502   SMDS_MeshEdge* anElem = SMDS_Mesh::AddEdgeWithID(n1,n2,n12,ID);
1503   if(anElem) myScript->AddEdge(ID,n1,n2,n12);
1504   return anElem;
1505 }
1506
1507 //=======================================================================
1508 //function : AddEdge
1509 //purpose  : 
1510 //=======================================================================
1511 SMDS_MeshEdge* SMESHDS_Mesh::AddEdge(const SMDS_MeshNode* n1,
1512                                      const SMDS_MeshNode* n2,
1513                                      const SMDS_MeshNode* n12)
1514 {
1515   SMDS_MeshEdge* anElem = SMDS_Mesh::AddEdge(n1,n2,n12);
1516   if(anElem) myScript->AddEdge(anElem->GetID(), 
1517                                n1->GetID(), 
1518                                n2->GetID(),
1519                                n12->GetID());
1520   return anElem;
1521 }
1522
1523 //=======================================================================
1524 //function : AddEdgeWithID
1525 //purpose  : 
1526 //=======================================================================
1527 SMDS_MeshEdge* SMESHDS_Mesh::AddEdgeWithID(const SMDS_MeshNode * n1,
1528                                            const SMDS_MeshNode * n2, 
1529                                            const SMDS_MeshNode * n12, 
1530                                            int ID)
1531 {
1532   return AddEdgeWithID(n1->GetID(),
1533                        n2->GetID(),
1534                        n12->GetID(),
1535                        ID);
1536 }
1537
1538
1539 //=======================================================================
1540 //function : AddFace
1541 //purpose  : 
1542 //=======================================================================
1543 SMDS_MeshFace* SMESHDS_Mesh::AddFace(const SMDS_MeshNode * n1,
1544                                      const SMDS_MeshNode * n2,
1545                                      const SMDS_MeshNode * n3,
1546                                      const SMDS_MeshNode * n12,
1547                                      const SMDS_MeshNode * n23,
1548                                      const SMDS_MeshNode * n31)
1549 {
1550   SMDS_MeshFace *anElem = SMDS_Mesh::AddFace(n1,n2,n3,n12,n23,n31);
1551   if(anElem) myScript->AddFace(anElem->GetID(), 
1552                                n1->GetID(), n2->GetID(), n3->GetID(),
1553                                n12->GetID(), n23->GetID(), n31->GetID());
1554   return anElem;
1555 }
1556
1557 //=======================================================================
1558 //function : AddFaceWithID
1559 //purpose  : 
1560 //=======================================================================
1561 SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(int n1, int n2, int n3,
1562                                            int n12,int n23,int n31, int ID)
1563 {
1564   SMDS_MeshFace *anElem = SMDS_Mesh::AddFaceWithID(n1,n2,n3,n12,n23,n31,ID);
1565   if(anElem) myScript->AddFace(ID,n1,n2,n3,n12,n23,n31);
1566   return anElem;
1567 }
1568
1569 //=======================================================================
1570 //function : AddFaceWithID
1571 //purpose  : 
1572 //=======================================================================
1573 SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
1574                                            const SMDS_MeshNode * n2,
1575                                            const SMDS_MeshNode * n3,
1576                                            const SMDS_MeshNode * n12,
1577                                            const SMDS_MeshNode * n23,
1578                                            const SMDS_MeshNode * n31, 
1579                                            int ID)
1580 {
1581   return AddFaceWithID(n1->GetID(), n2->GetID(), n3->GetID(),
1582                        n12->GetID(), n23->GetID(), n31->GetID(),
1583                        ID);
1584 }
1585
1586 //=======================================================================
1587 //function : AddFace
1588 //purpose  : 
1589 //=======================================================================
1590 SMDS_MeshFace* SMESHDS_Mesh::AddFace(const SMDS_MeshNode * n1,
1591                                      const SMDS_MeshNode * n2,
1592                                      const SMDS_MeshNode * n3,
1593                                      const SMDS_MeshNode * n12,
1594                                      const SMDS_MeshNode * n23,
1595                                      const SMDS_MeshNode * n31,
1596                                      const SMDS_MeshNode * nCenter)
1597 {
1598   SMDS_MeshFace *anElem = SMDS_Mesh::AddFace(n1,n2,n3,n12,n23,n31,nCenter);
1599   if(anElem) myScript->AddFace(anElem->GetID(), 
1600                                n1->GetID(), n2->GetID(), n3->GetID(),
1601                                n12->GetID(), n23->GetID(), n31->GetID(),
1602                                nCenter->GetID());
1603   return anElem;
1604 }
1605
1606 //=======================================================================
1607 //function : AddFaceWithID
1608 //purpose  : 
1609 //=======================================================================
1610 SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(int n1, int n2, int n3,
1611                                            int n12,int n23,int n31, int nCenter, int ID)
1612 {
1613   SMDS_MeshFace *anElem = SMDS_Mesh::AddFaceWithID(n1,n2,n3,n12,n23,n31,nCenter,ID);
1614   if(anElem) myScript->AddFace(ID,n1,n2,n3,n12,n23,n31,nCenter);
1615   return anElem;
1616 }
1617
1618 //=======================================================================
1619 //function : AddFaceWithID
1620 //purpose  : 
1621 //=======================================================================
1622 SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
1623                                            const SMDS_MeshNode * n2,
1624                                            const SMDS_MeshNode * n3,
1625                                            const SMDS_MeshNode * n12,
1626                                            const SMDS_MeshNode * n23,
1627                                            const SMDS_MeshNode * n31, 
1628                                            const SMDS_MeshNode * nCenter, 
1629                                            int ID)
1630 {
1631   return AddFaceWithID(n1->GetID(), n2->GetID(), n3->GetID(),
1632                        n12->GetID(), n23->GetID(), n31->GetID(),
1633                        nCenter->GetID(), ID);
1634 }
1635
1636
1637 //=======================================================================
1638 //function : AddFace
1639 //purpose  : 
1640 //=======================================================================
1641 SMDS_MeshFace* SMESHDS_Mesh::AddFace(const SMDS_MeshNode * n1,
1642                                      const SMDS_MeshNode * n2,
1643                                      const SMDS_MeshNode * n3,
1644                                      const SMDS_MeshNode * n4,
1645                                      const SMDS_MeshNode * n12,
1646                                      const SMDS_MeshNode * n23,
1647                                      const SMDS_MeshNode * n34,
1648                                      const SMDS_MeshNode * n41)
1649 {
1650   SMDS_MeshFace *anElem = SMDS_Mesh::AddFace(n1,n2,n3,n4,n12,n23,n34,n41);
1651   if(anElem) myScript->AddFace(anElem->GetID(), 
1652                                n1->GetID(), n2->GetID(), n3->GetID(), n4->GetID(),
1653                                n12->GetID(), n23->GetID(), n34->GetID(), n41->GetID());
1654   return anElem;
1655 }
1656
1657 //=======================================================================
1658 //function : AddFaceWithID
1659 //purpose  : 
1660 //=======================================================================
1661 SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(int n1, int n2, int n3, int n4,
1662                                            int n12,int n23,int n34,int n41, int ID)
1663 {
1664   SMDS_MeshFace *anElem = SMDS_Mesh::AddFaceWithID(n1,n2,n3,n4,n12,n23,n34,n41,ID);
1665   if(anElem) myScript->AddFace(ID,n1,n2,n3,n4,n12,n23,n34,n41);
1666   return anElem;
1667 }
1668
1669 //=======================================================================
1670 //function : AddFaceWithID
1671 //purpose  : 
1672 //=======================================================================
1673 SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
1674                                            const SMDS_MeshNode * n2,
1675                                            const SMDS_MeshNode * n3,
1676                                            const SMDS_MeshNode * n4,
1677                                            const SMDS_MeshNode * n12,
1678                                            const SMDS_MeshNode * n23,
1679                                            const SMDS_MeshNode * n34, 
1680                                            const SMDS_MeshNode * n41, 
1681                                            int ID)
1682 {
1683   return AddFaceWithID(n1->GetID(), n2->GetID(), n3->GetID(), n4->GetID(),
1684                        n12->GetID(), n23->GetID(), n34->GetID(), n41->GetID(),
1685                        ID);
1686 }
1687
1688
1689 //=======================================================================
1690 //function : AddFace
1691 //purpose  : 
1692 //=======================================================================
1693 SMDS_MeshFace* SMESHDS_Mesh::AddFace(const SMDS_MeshNode * n1,
1694                                      const SMDS_MeshNode * n2,
1695                                      const SMDS_MeshNode * n3,
1696                                      const SMDS_MeshNode * n4,
1697                                      const SMDS_MeshNode * n12,
1698                                      const SMDS_MeshNode * n23,
1699                                      const SMDS_MeshNode * n34,
1700                                      const SMDS_MeshNode * n41, 
1701                                      const SMDS_MeshNode * nCenter)
1702 {
1703   SMDS_MeshFace *anElem = SMDS_Mesh::AddFace(n1,n2,n3,n4,n12,n23,n34,n41,nCenter);
1704   if(anElem) myScript->AddFace(anElem->GetID(), 
1705                                n1->GetID(), n2->GetID(), n3->GetID(), n4->GetID(),
1706                                n12->GetID(), n23->GetID(), n34->GetID(), n41->GetID(),
1707                                nCenter->GetID());
1708   return anElem;
1709 }
1710
1711 //=======================================================================
1712 //function : AddFaceWithID
1713 //purpose  : 
1714 //=======================================================================
1715 SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(int n1, int n2, int n3, int n4,
1716                                            int n12,int n23,int n34,int n41,
1717                                            int nCenter, int ID)
1718 {
1719   SMDS_MeshFace *anElem = SMDS_Mesh::AddFaceWithID(n1,n2,n3,n4,n12,n23,n34,n41,nCenter,ID);
1720   if(anElem) myScript->AddFace(ID,n1,n2,n3,n4,n12,n23,n34,n41,nCenter);
1721   return anElem;
1722 }
1723
1724 //=======================================================================
1725 //function : AddFaceWithID
1726 //purpose  : 
1727 //=======================================================================
1728 SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
1729                                            const SMDS_MeshNode * n2,
1730                                            const SMDS_MeshNode * n3,
1731                                            const SMDS_MeshNode * n4,
1732                                            const SMDS_MeshNode * n12,
1733                                            const SMDS_MeshNode * n23,
1734                                            const SMDS_MeshNode * n34, 
1735                                            const SMDS_MeshNode * n41, 
1736                                            const SMDS_MeshNode * nCenter, 
1737                                            int ID)
1738 {
1739   return AddFaceWithID(n1->GetID(), n2->GetID(), n3->GetID(), n4->GetID(),
1740                        n12->GetID(), n23->GetID(), n34->GetID(), n41->GetID(),
1741                        nCenter->GetID(), ID);
1742 }
1743
1744
1745 //=======================================================================
1746 //function : AddVolume
1747 //purpose  : 
1748 //=======================================================================
1749 SMDS_MeshVolume* SMESHDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
1750                                          const SMDS_MeshNode * n2, 
1751                                          const SMDS_MeshNode * n3,
1752                                          const SMDS_MeshNode * n4,
1753                                          const SMDS_MeshNode * n12,
1754                                          const SMDS_MeshNode * n23,
1755                                          const SMDS_MeshNode * n31,
1756                                          const SMDS_MeshNode * n14, 
1757                                          const SMDS_MeshNode * n24,
1758                                          const SMDS_MeshNode * n34)
1759 {
1760   SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolume(n1,n2,n3,n4,n12,n23,n31,n14,n24,n34);
1761   if(anElem) myScript->AddVolume(anElem->GetID(), 
1762                                  n1->GetID(), n2->GetID(), n3->GetID(), n4->GetID(),
1763                                  n12->GetID(), n23->GetID(), n31->GetID(),
1764                                  n14->GetID(), n24->GetID(), n34->GetID());
1765   return anElem;
1766 }
1767
1768 //=======================================================================
1769 //function : AddVolumeWithID
1770 //purpose  : 
1771 //=======================================================================
1772 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4,
1773                                                int n12,int n23,int n31,
1774                                                int n14,int n24,int n34, int ID)
1775 {
1776   SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolumeWithID(n1,n2,n3,n4,n12,n23,
1777                                                        n31,n14,n24,n34,ID);
1778   if(anElem) myScript->AddVolume(ID,n1,n2,n3,n4,n12,n23,n31,n14,n24,n34);
1779   return anElem;
1780 }
1781         
1782 //=======================================================================
1783 //function : AddVolumeWithID
1784 //purpose  : 2d order tetrahedron of 10 nodes
1785 //=======================================================================
1786 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
1787                                                const SMDS_MeshNode * n2,
1788                                                const SMDS_MeshNode * n3,
1789                                                const SMDS_MeshNode * n4,
1790                                                const SMDS_MeshNode * n12,
1791                                                const SMDS_MeshNode * n23,
1792                                                const SMDS_MeshNode * n31,
1793                                                const SMDS_MeshNode * n14, 
1794                                                const SMDS_MeshNode * n24,
1795                                                const SMDS_MeshNode * n34,
1796                                                int ID)
1797 {
1798   return AddVolumeWithID(n1->GetID(), n2->GetID(), n3->GetID(), n4->GetID(),
1799                          n12->GetID(), n23->GetID(), n31->GetID(),
1800                          n14->GetID(), n24->GetID(), n34->GetID(), ID);
1801 }
1802
1803
1804 //=======================================================================
1805 //function : AddVolume
1806 //purpose  : 
1807 //=======================================================================
1808 SMDS_MeshVolume* SMESHDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
1809                                          const SMDS_MeshNode * n2, 
1810                                          const SMDS_MeshNode * n3,
1811                                          const SMDS_MeshNode * n4,
1812                                          const SMDS_MeshNode * n5, 
1813                                          const SMDS_MeshNode * n12,
1814                                          const SMDS_MeshNode * n23,
1815                                          const SMDS_MeshNode * n34,
1816                                          const SMDS_MeshNode * n41,
1817                                          const SMDS_MeshNode * n15, 
1818                                          const SMDS_MeshNode * n25,
1819                                          const SMDS_MeshNode * n35,
1820                                          const SMDS_MeshNode * n45)
1821 {
1822   SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolume(n1,n2,n3,n4,n5,n12,n23,n34,n41,
1823                                                  n15,n25,n35,n45);
1824   if(anElem)
1825     myScript->AddVolume(anElem->GetID(), n1->GetID(), n2->GetID(),
1826                         n3->GetID(), n4->GetID(), n5->GetID(),
1827                         n12->GetID(), n23->GetID(), n34->GetID(), n41->GetID(),
1828                         n15->GetID(), n25->GetID(), n35->GetID(), n45->GetID());
1829   return anElem;
1830 }
1831
1832 //=======================================================================
1833 //function : AddVolumeWithID
1834 //purpose  : 
1835 //=======================================================================
1836 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4, int n5,
1837                                                int n12,int n23,int n34,int n41,
1838                                                int n15,int n25,int n35,int n45, int ID)
1839 {
1840   SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolumeWithID(n1,n2,n3,n4,n5,
1841                                                        n12,n23,n34,n41,
1842                                                        n15,n25,n35,n45,ID);
1843   if(anElem) myScript->AddVolume(ID,n1,n2,n3,n4,n5,n12,n23,n34,n41,
1844                                  n15,n25,n35,n45);
1845   return anElem;
1846 }
1847         
1848 //=======================================================================
1849 //function : AddVolumeWithID
1850 //purpose  : 2d order pyramid of 13 nodes
1851 //=======================================================================
1852 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
1853                                                const SMDS_MeshNode * n2,
1854                                                const SMDS_MeshNode * n3,
1855                                                const SMDS_MeshNode * n4,
1856                                                const SMDS_MeshNode * n5, 
1857                                                const SMDS_MeshNode * n12,
1858                                                const SMDS_MeshNode * n23,
1859                                                const SMDS_MeshNode * n34,
1860                                                const SMDS_MeshNode * n41,
1861                                                const SMDS_MeshNode * n15, 
1862                                                const SMDS_MeshNode * n25,
1863                                                const SMDS_MeshNode * n35,
1864                                                const SMDS_MeshNode * n45,
1865                                                int ID)
1866 {
1867   return AddVolumeWithID(n1->GetID(), n2->GetID(), n3->GetID(),
1868                          n4->GetID(), n5->GetID(),
1869                          n12->GetID(), n23->GetID(), n34->GetID(), n41->GetID(),
1870                          n15->GetID(), n25->GetID(), n35->GetID(), n45->GetID(),
1871                          ID);
1872 }
1873
1874
1875 //=======================================================================
1876 //function : AddVolume
1877 //purpose  : 
1878 //=======================================================================
1879 SMDS_MeshVolume* SMESHDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
1880                                          const SMDS_MeshNode * n2, 
1881                                          const SMDS_MeshNode * n3,
1882                                          const SMDS_MeshNode * n4,
1883                                          const SMDS_MeshNode * n5, 
1884                                          const SMDS_MeshNode * n6, 
1885                                          const SMDS_MeshNode * n12,
1886                                          const SMDS_MeshNode * n23,
1887                                          const SMDS_MeshNode * n31, 
1888                                          const SMDS_MeshNode * n45,
1889                                          const SMDS_MeshNode * n56,
1890                                          const SMDS_MeshNode * n64, 
1891                                          const SMDS_MeshNode * n14,
1892                                          const SMDS_MeshNode * n25,
1893                                          const SMDS_MeshNode * n36)
1894 {
1895   SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolume(n1,n2,n3,n4,n5,n6,n12,n23,n31,
1896                                                  n45,n56,n64,n14,n25,n36);
1897   if(anElem)
1898     myScript->AddVolume(anElem->GetID(), n1->GetID(), n2->GetID(),
1899                         n3->GetID(), n4->GetID(), n5->GetID(), n6->GetID(),
1900                         n12->GetID(), n23->GetID(), n31->GetID(),
1901                         n45->GetID(), n56->GetID(), n64->GetID(),
1902                         n14->GetID(), n25->GetID(), n36->GetID());
1903   return anElem;
1904 }
1905
1906 //=======================================================================
1907 //function : AddVolumeWithID
1908 //purpose  : 
1909 //=======================================================================
1910 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(int n1, int n2, int n3,
1911                                                int n4, int n5, int n6,
1912                                                int n12,int n23,int n31,
1913                                                int n45,int n56,int n64,
1914                                                int n14,int n25,int n36, int ID)
1915 {
1916   SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolumeWithID(n1,n2,n3,n4,n5,n6,
1917                                                        n12,n23,n31,
1918                                                        n45,n56,n64,
1919                                                        n14,n25,n36,ID);
1920   if(anElem) myScript->AddVolume(ID,n1,n2,n3,n4,n5,n6,n12,n23,n31,
1921                                  n45,n56,n64,n14,n25,n36);
1922   return anElem;
1923 }
1924         
1925 //=======================================================================
1926 //function : AddVolumeWithID
1927 //purpose  : 2d order Pentahedron with 15 nodes
1928 //=======================================================================
1929 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
1930                                                const SMDS_MeshNode * n2,
1931                                                const SMDS_MeshNode * n3,
1932                                                const SMDS_MeshNode * n4,
1933                                                const SMDS_MeshNode * n5, 
1934                                                const SMDS_MeshNode * n6, 
1935                                                const SMDS_MeshNode * n12,
1936                                                const SMDS_MeshNode * n23,
1937                                                const SMDS_MeshNode * n31, 
1938                                                const SMDS_MeshNode * n45,
1939                                                const SMDS_MeshNode * n56,
1940                                                const SMDS_MeshNode * n64, 
1941                                                const SMDS_MeshNode * n14,
1942                                                const SMDS_MeshNode * n25,
1943                                                const SMDS_MeshNode * n36,
1944                                                int ID)
1945 {
1946   return AddVolumeWithID(n1->GetID(), n2->GetID(), n3->GetID(),
1947                          n4->GetID(), n5->GetID(), n6->GetID(),
1948                          n12->GetID(), n23->GetID(), n31->GetID(),
1949                          n45->GetID(), n56->GetID(), n64->GetID(),
1950                          n14->GetID(), n25->GetID(), n36->GetID(),
1951                          ID);
1952 }
1953
1954
1955 //=======================================================================
1956 //function : AddVolume
1957 //purpose  : add quadratic hexahedron
1958 //=======================================================================
1959 SMDS_MeshVolume* SMESHDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
1960                                          const SMDS_MeshNode * n2, 
1961                                          const SMDS_MeshNode * n3,
1962                                          const SMDS_MeshNode * n4,
1963                                          const SMDS_MeshNode * n5, 
1964                                          const SMDS_MeshNode * n6, 
1965                                          const SMDS_MeshNode * n7,
1966                                          const SMDS_MeshNode * n8, 
1967                                          const SMDS_MeshNode * n12,
1968                                          const SMDS_MeshNode * n23,
1969                                          const SMDS_MeshNode * n34,
1970                                          const SMDS_MeshNode * n41, 
1971                                          const SMDS_MeshNode * n56,
1972                                          const SMDS_MeshNode * n67,
1973                                          const SMDS_MeshNode * n78,
1974                                          const SMDS_MeshNode * n85, 
1975                                          const SMDS_MeshNode * n15,
1976                                          const SMDS_MeshNode * n26,
1977                                          const SMDS_MeshNode * n37,
1978                                          const SMDS_MeshNode * n48)
1979 {
1980   SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolume(n1,n2,n3,n4,n5,n6,n7,n8,
1981                                                  n12,n23,n34,n41,
1982                                                  n56,n67,n78,n85,
1983                                                  n15,n26,n37,n48);
1984   if(anElem)
1985     myScript->AddVolume(anElem->GetID(), n1->GetID(), n2->GetID(),
1986                         n3->GetID(), n4->GetID(), n5->GetID(),
1987                         n6->GetID(), n7->GetID(), n8->GetID(),
1988                         n12->GetID(), n23->GetID(), n34->GetID(), n41->GetID(),
1989                         n56->GetID(), n67->GetID(), n78->GetID(), n85->GetID(),
1990                         n15->GetID(), n26->GetID(), n37->GetID(), n48->GetID());
1991   return anElem;
1992 }
1993
1994 //=======================================================================
1995 //function : AddVolumeWithID
1996 //purpose  : 
1997 //=======================================================================
1998 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4,
1999                                                int n5, int n6, int n7, int n8,
2000                                                int n12,int n23,int n34,int n41,
2001                                                int n56,int n67,int n78,int n85,
2002                                                int n15,int n26,int n37,int n48, int ID)
2003 {
2004   SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolumeWithID(n1,n2,n3,n4,n5,n6,n7,n8,
2005                                                        n12,n23,n34,n41,
2006                                                        n56,n67,n78,n85,
2007                                                        n15,n26,n37,n48,ID);
2008   if(anElem) myScript->AddVolume(ID,n1,n2,n3,n4,n5,n6,n7,n8,n12,n23,n34,n41,
2009                                  n56,n67,n78,n85,n15,n26,n37,n48);
2010   return anElem;
2011 }
2012         
2013 //=======================================================================
2014 //function : AddVolumeWithID
2015 //purpose  : 2d order Hexahedrons with 20 nodes
2016 //=======================================================================
2017 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
2018                                                const SMDS_MeshNode * n2,
2019                                                const SMDS_MeshNode * n3,
2020                                                const SMDS_MeshNode * n4,
2021                                                const SMDS_MeshNode * n5, 
2022                                                const SMDS_MeshNode * n6, 
2023                                                const SMDS_MeshNode * n7,
2024                                                const SMDS_MeshNode * n8, 
2025                                                const SMDS_MeshNode * n12,
2026                                                const SMDS_MeshNode * n23,
2027                                                const SMDS_MeshNode * n34,
2028                                                const SMDS_MeshNode * n41, 
2029                                                const SMDS_MeshNode * n56,
2030                                                const SMDS_MeshNode * n67,
2031                                                const SMDS_MeshNode * n78,
2032                                                const SMDS_MeshNode * n85, 
2033                                                const SMDS_MeshNode * n15,
2034                                                const SMDS_MeshNode * n26,
2035                                                const SMDS_MeshNode * n37,
2036                                                const SMDS_MeshNode * n48,
2037                                                int ID)
2038 {
2039   return AddVolumeWithID(n1->GetID(), n2->GetID(), n3->GetID(), n4->GetID(),
2040                          n5->GetID(), n6->GetID(), n7->GetID(), n8->GetID(),
2041                          n12->GetID(), n23->GetID(), n34->GetID(), n41->GetID(),
2042                          n56->GetID(), n67->GetID(), n78->GetID(), n85->GetID(),
2043                          n15->GetID(), n26->GetID(), n37->GetID(), n48->GetID(),
2044                          ID);
2045 }
2046
2047 //=======================================================================
2048 //function : AddVolume
2049 //purpose  : add tri-quadratic hexahedron of 27 nodes
2050 //=======================================================================
2051
2052 SMDS_MeshVolume* SMESHDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
2053                                          const SMDS_MeshNode * n2, 
2054                                          const SMDS_MeshNode * n3,
2055                                          const SMDS_MeshNode * n4,
2056                                          const SMDS_MeshNode * n5, 
2057                                          const SMDS_MeshNode * n6, 
2058                                          const SMDS_MeshNode * n7,
2059                                          const SMDS_MeshNode * n8, 
2060                                          const SMDS_MeshNode * n12,
2061                                          const SMDS_MeshNode * n23,
2062                                          const SMDS_MeshNode * n34,
2063                                          const SMDS_MeshNode * n41, 
2064                                          const SMDS_MeshNode * n56,
2065                                          const SMDS_MeshNode * n67,
2066                                          const SMDS_MeshNode * n78,
2067                                          const SMDS_MeshNode * n85, 
2068                                          const SMDS_MeshNode * n15,
2069                                          const SMDS_MeshNode * n26,
2070                                          const SMDS_MeshNode * n37,
2071                                          const SMDS_MeshNode * n48, 
2072                                          const SMDS_MeshNode * n1234,
2073                                          const SMDS_MeshNode * n1256,
2074                                          const SMDS_MeshNode * n2367,
2075                                          const SMDS_MeshNode * n3478,
2076                                          const SMDS_MeshNode * n1458,
2077                                          const SMDS_MeshNode * n5678,
2078                                          const SMDS_MeshNode * nCenter)
2079 {
2080   SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolume(n1,n2,n3,n4,n5,n6,n7,n8,
2081                                                  n12,n23,n34,n41,
2082                                                  n56,n67,n78,n85,
2083                                                  n15,n26,n37,n48,
2084                                                  n1234,n1256,n2367,n3478,n1458,n5678,nCenter);
2085   if(anElem)
2086     myScript->AddVolume(anElem->GetID(), n1->GetID(), n2->GetID(),
2087                         n3->GetID(), n4->GetID(), n5->GetID(),
2088                         n6->GetID(), n7->GetID(), n8->GetID(),
2089                         n12->GetID(), n23->GetID(), n34->GetID(), n41->GetID(),
2090                         n56->GetID(), n67->GetID(), n78->GetID(), n85->GetID(),
2091                         n15->GetID(), n26->GetID(), n37->GetID(), n48->GetID(),
2092                         n1234->GetID(),n1256->GetID(),n2367->GetID(),n3478->GetID(),
2093                         n1458->GetID(),n5678->GetID(),nCenter->GetID());
2094   return anElem;
2095 }
2096
2097 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4,
2098                                                int n5, int n6, int n7, int n8,
2099                                                int n12,int n23,int n34,int n41,
2100                                                int n56,int n67,int n78,int n85,
2101                                                int n15,int n26,int n37,int n48,
2102                                                int n1234,int n1256,int n2367,int n3478,
2103                                                int n1458,int n5678,int nCenter,
2104                                                int ID)
2105 {
2106   SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolumeWithID(n1,n2,n3,n4,n5,n6,n7,n8,
2107                                                        n12,n23,n34,n41,
2108                                                        n56,n67,n78,n85,
2109                                                        n15,n26,n37,n48,
2110                                                        n1234, n1256, n2367, n3478,
2111                                                        n1458, n5678, nCenter,
2112                                                        ID);
2113   if(anElem) myScript->AddVolume(ID,n1,n2,n3,n4,n5,n6,n7,n8,n12,n23,n34,n41,
2114                                  n56,n67,n78,n85,n15,n26,n37,n48,
2115                                  n1234, n1256, n2367, n3478,
2116                                  n1458, n5678, nCenter);
2117   return anElem;
2118 }
2119
2120 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
2121                                                const SMDS_MeshNode * n2,
2122                                                const SMDS_MeshNode * n3,
2123                                                const SMDS_MeshNode * n4,
2124                                                const SMDS_MeshNode * n5, 
2125                                                const SMDS_MeshNode * n6, 
2126                                                const SMDS_MeshNode * n7,
2127                                                const SMDS_MeshNode * n8, 
2128                                                const SMDS_MeshNode * n12,
2129                                                const SMDS_MeshNode * n23,
2130                                                const SMDS_MeshNode * n34,
2131                                                const SMDS_MeshNode * n41, 
2132                                                const SMDS_MeshNode * n56,
2133                                                const SMDS_MeshNode * n67,
2134                                                const SMDS_MeshNode * n78,
2135                                                const SMDS_MeshNode * n85, 
2136                                                const SMDS_MeshNode * n15,
2137                                                const SMDS_MeshNode * n26,
2138                                                const SMDS_MeshNode * n37,
2139                                                const SMDS_MeshNode * n48, 
2140                                                const SMDS_MeshNode * n1234,
2141                                                const SMDS_MeshNode * n1256,
2142                                                const SMDS_MeshNode * n2367,
2143                                                const SMDS_MeshNode * n3478,
2144                                                const SMDS_MeshNode * n1458,
2145                                                const SMDS_MeshNode * n5678,
2146                                                const SMDS_MeshNode * nCenter,
2147                                                int ID)
2148 {
2149   return AddVolumeWithID(n1->GetID(), n2->GetID(), n3->GetID(), n4->GetID(),
2150                          n5->GetID(), n6->GetID(), n7->GetID(), n8->GetID(),
2151                          n12->GetID(), n23->GetID(), n34->GetID(), n41->GetID(),
2152                          n56->GetID(), n67->GetID(), n78->GetID(), n85->GetID(),
2153                          n15->GetID(), n26->GetID(), n37->GetID(), n48->GetID(),
2154                          n1234->GetID(),n1256->GetID(),n2367->GetID(),n3478->GetID(),
2155                          n1458->GetID(),n5678->GetID(),nCenter->GetID(), ID);
2156 }
2157
2158 void SMESHDS_Mesh::compactMesh()
2159 {
2160   int newNodeSize = 0;
2161   int nbNodes = myNodes.size();
2162   int nbVtkNodes = myGrid->GetNumberOfPoints();
2163   MESSAGE("nbNodes=" << nbNodes << " nbVtkNodes=" << nbVtkNodes);
2164   int nbNodeTemp = nbVtkNodes;
2165   if (nbNodes > nbVtkNodes)
2166     nbNodeTemp = nbNodes;
2167   vector<int> idNodesOldToNew;
2168   idNodesOldToNew.clear();
2169   idNodesOldToNew.resize(nbNodeTemp, -1); // all unused id will be -1
2170
2171   for (int i = 0; i < nbNodes; i++)
2172     {
2173       if (myNodes[i])
2174         {
2175           int vtkid = myNodes[i]->getVtkId();
2176           idNodesOldToNew[vtkid] = i; // old vtkId --> old smdsId (valid smdsId are >= 0)
2177           newNodeSize++;
2178         }
2179     }
2180   bool areNodesModified = (newNodeSize < nbVtkNodes);
2181   MESSAGE("------------------------- compactMesh Nodes Modified: " << areNodesModified);
2182   areNodesModified = true;
2183
2184   int newCellSize = 0;
2185   int nbCells = myCells.size();
2186   int nbVtkCells = myGrid->GetNumberOfCells();
2187   MESSAGE("nbCells=" << nbCells << " nbVtkCells=" << nbVtkCells);
2188   int nbCellTemp = nbVtkCells;
2189   if (nbCells > nbVtkCells)
2190     nbCellTemp = nbCells;
2191   vector<int> idCellsOldToNew;
2192   idCellsOldToNew.clear();
2193   idCellsOldToNew.resize(nbCellTemp, -1); // all unused id will be -1
2194
2195   for (int i = 0; i < nbCells; i++)
2196     {
2197       if (myCells[i])
2198         {
2199 //          //idCellsOldToNew[i] = myCellIdVtkToSmds[i]; // valid vtk indexes are > = 0
2200 //          int vtkid = myCells[i]->getVtkId();
2201 //          idCellsOldToNew[vtkid] = i; // old vtkId --> old smdsId (not used in input)
2202           newCellSize++;
2203         }
2204     }
2205   if (areNodesModified)
2206     myGrid->compactGrid(idNodesOldToNew, newNodeSize, idCellsOldToNew, newCellSize);
2207   else
2208     myGrid->compactGrid(idNodesOldToNew, 0, idCellsOldToNew, newCellSize);
2209
2210   int nbVtkPts = myGrid->GetNumberOfPoints();
2211   nbVtkCells = myGrid->GetNumberOfCells();
2212   if (nbVtkPts != newNodeSize)
2213     {
2214       MESSAGE("===> nbVtkPts != newNodeSize " << nbVtkPts << " " << newNodeSize);
2215       if (nbVtkPts > newNodeSize) newNodeSize = nbVtkPts; // several points with same SMDS Id
2216     }
2217   if (nbVtkCells != newCellSize)
2218     {
2219       MESSAGE("===> nbVtkCells != newCellSize " << nbVtkCells << " " << newCellSize);
2220       if (nbVtkCells > newCellSize) newCellSize = nbVtkCells; // several cells with same SMDS Id
2221     }
2222
2223   // --- SMDS_MeshNode and myNodes (id in SMDS and in VTK are the same), myNodeIdFactory
2224
2225   if (areNodesModified)
2226     {
2227       MESSAGE("-------------- modify myNodes");
2228       SetOfNodes newNodes;
2229       newNodes.resize(newNodeSize+1,0); // 0 not used, SMDS numbers 1..n
2230       int newSmdsId = 0;
2231       for (int i = 0; i < nbNodes; i++)
2232         {
2233           if (myNodes[i])
2234             {
2235               newSmdsId++; // SMDS id start to 1
2236               int oldVtkId = myNodes[i]->getVtkId();
2237               int newVtkId = idNodesOldToNew[oldVtkId];
2238               //MESSAGE("myNodes["<< i << "] vtkId " << oldVtkId << " --> " << newVtkId);
2239               myNodes[i]->setVtkId(newVtkId);
2240               myNodes[i]->setId(newSmdsId);
2241               newNodes[newSmdsId] = myNodes[i];
2242               //MESSAGE("myNodes["<< i << "] --> newNodes[" << newSmdsId << "]");
2243             }
2244         }
2245       myNodes.swap(newNodes);
2246       this->myNodeIDFactory->emptyPool(newSmdsId); // newSmdsId = number of nodes
2247       MESSAGE("myNodes.size " << myNodes.size());
2248     }
2249
2250   // --- SMDS_MeshCell, myCellIdVtkToSmds, myCellIdSmdsToVtk, myCells
2251
2252   int vtkIndexSize = myCellIdVtkToSmds.size();
2253   int maxVtkId = -1;
2254   for (int oldVtkId = 0; oldVtkId < vtkIndexSize; oldVtkId++)
2255     {
2256       int oldSmdsId = this->myCellIdVtkToSmds[oldVtkId];
2257       if (oldSmdsId > 0)
2258         {
2259           int newVtkId = idCellsOldToNew[oldVtkId];
2260           if (newVtkId > maxVtkId)
2261             maxVtkId = newVtkId;
2262           //MESSAGE("myCells["<< oldSmdsId << "] vtkId " << oldVtkId << " --> " << newVtkId);
2263           myCells[oldSmdsId]->setVtkId(newVtkId);
2264         }
2265     }
2266 //  MESSAGE("myCells.size()=" << myCells.size()
2267 //          << " myCellIdSmdsToVtk.size()=" << myCellIdSmdsToVtk.size()
2268 //          << " myCellIdVtkToSmds.size()=" << myCellIdVtkToSmds.size() );
2269
2270   SetOfCells newCells;
2271   //vector<int> newSmdsToVtk;
2272   vector<int> newVtkToSmds;
2273
2274   assert(maxVtkId < newCellSize);
2275   newCells.resize(newCellSize+1, 0); // 0 not used, SMDS numbers 1..n
2276   //newSmdsToVtk.resize(newCellSize+1, -1);
2277   newVtkToSmds.resize(newCellSize+1, -1);
2278
2279   int myCellsSize = myCells.size();
2280   int newSmdsId = 0;
2281   for (int i = 0; i < myCellsSize; i++)
2282     {
2283       if (myCells[i])
2284         {
2285           newSmdsId++; // SMDS id start to 1
2286           assert(newSmdsId <= newCellSize);
2287           newCells[newSmdsId] = myCells[i];
2288           newCells[newSmdsId]->setId(newSmdsId);
2289           //MESSAGE("myCells["<< i << "] --> newCells[" << newSmdsId << "]");
2290           int idvtk = myCells[i]->getVtkId();
2291           //newSmdsToVtk[newSmdsId] = idvtk;
2292           assert(idvtk < newCellSize);
2293           newVtkToSmds[idvtk] = newSmdsId;
2294         }
2295     }
2296
2297   myCells.swap(newCells);
2298   //myCellIdSmdsToVtk.swap(newSmdsToVtk);
2299   myCellIdVtkToSmds.swap(newVtkToSmds);
2300   MESSAGE("myCells.size()=" << myCells.size()
2301           << " myCellIdVtkToSmds.size()=" << myCellIdVtkToSmds.size() );
2302   this->myElementIDFactory->emptyPool(newSmdsId);
2303
2304   this->myScript->SetModified(true); // notify GUI client for buildPrs when update
2305
2306   // --- compact list myNodes and myElements in submeshes
2307
2308   map<int,SMESHDS_SubMesh*>::iterator it = myShapeIndexToSubMesh.begin();
2309   for(; it != myShapeIndexToSubMesh.end(); ++it)
2310     {
2311       (*it).second->compactList();
2312     }
2313
2314 }
2315
2316 void SMESHDS_Mesh::CleanDownWardConnectivity()
2317 {
2318   myGrid->CleanDownwardConnectivity();
2319 }
2320
2321 void SMESHDS_Mesh::BuildDownWardConnectivity(bool withEdges)
2322 {
2323   myGrid->BuildDownwardConnectivity(withEdges);
2324 }
2325
2326 /*! change some nodes in cell without modifying type or internal connectivity.
2327  * Nodes inverse connectivity is maintained up to date.
2328  * @param vtkVolId vtk id of the cell.
2329  * @param localClonedNodeIds map old node id to new node id.
2330  * @return ok if success.
2331  */
2332 bool SMESHDS_Mesh::ModifyCellNodes(int vtkVolId, std::map<int,int> localClonedNodeIds)
2333 {
2334   myGrid->ModifyCellNodes(vtkVolId, localClonedNodeIds);
2335   return true;
2336 }