Salome HOME
8489868cc5f0e33750e1608d4389b8543124aba9
[modules/smesh.git] / src / SMESHDS / SMESHDS_Mesh.cxx
1 // Copyright (C) 2007-2013  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
5 //
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License.
10 //
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 // Lesser General Public License for more details.
15 //
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
19 //
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 //
22
23 //  SMESH SMESHDS : management of mesh data and SMESH document
24 //  File   : SMESH_Mesh.cxx
25 //  Author : Yves FRICAUD, OCC
26 //  Module : SMESH
27 //
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 )
899     subMesh->RemoveNode(n,/*deleted=*/false);
900
901   SMDS_Mesh::RemoveFreeElement(n);
902 }
903
904 //=======================================================================
905 //function : RemoveElement
906 //purpose  : 
907 //========================================================================
908 void SMESHDS_Mesh::RemoveElement(const SMDS_MeshElement * elt)
909 {
910   if (elt->GetType() == SMDSAbs_Node)
911   {
912     RemoveNode( static_cast<const SMDS_MeshNode*>( elt ));
913     return;
914   }
915   if (!hasConstructionEdges() && !hasConstructionFaces())
916   {
917     SMESHDS_SubMesh* subMesh=0;
918     if ( elt->getshapeId() > 0 )
919     {
920       map<int,SMESHDS_SubMesh*>::iterator SubIt = myShapeIndexToSubMesh.find( elt->getshapeId() );
921       if ( SubIt != myShapeIndexToSubMesh.end() )
922         subMesh = SubIt->second;
923     }
924     RemoveFreeElement( elt, subMesh, true);
925     return;
926   }
927  
928   myScript->RemoveElement(elt->GetID());
929
930   list<const SMDS_MeshElement *> removedElems;
931   list<const SMDS_MeshElement *> removedNodes;
932
933   SMDS_Mesh::RemoveElement(elt, removedElems, removedNodes, false);
934   
935   removeFromContainers( myShapeIndexToSubMesh, myGroups, removedElems, false );
936 }
937
938 //=======================================================================
939 //function : RemoveFreeElement
940 //purpose  : 
941 //========================================================================
942 void SMESHDS_Mesh::RemoveFreeElement(const SMDS_MeshElement * elt,
943                                      SMESHDS_SubMesh *        subMesh,
944                                      bool                     fromGroups)
945 {
946   //MESSAGE(" --------------------------------> SMESHDS_Mesh::RemoveFreeElement " << subMesh << " " << fromGroups);
947   if (elt->GetType() == SMDSAbs_Node) {
948     RemoveFreeNode( static_cast<const SMDS_MeshNode*>(elt), subMesh);
949     return;
950   }
951
952   if (hasConstructionEdges() || hasConstructionFaces())
953     // this methods is only for meshes without descendants
954     return;
955
956   myScript->RemoveElement(elt->GetID());
957
958   // Rm from group
959   // Node can belong to several groups
960   if ( fromGroups && !myGroups.empty() ) {
961     set<SMESHDS_GroupBase*>::iterator GrIt = myGroups.begin();
962     for (; GrIt != myGroups.end(); GrIt++) {
963       SMESHDS_Group* group = dynamic_cast<SMESHDS_Group*>(*GrIt);
964       if (group && !group->IsEmpty())
965         group->SMDSGroup().Remove(elt);
966     }
967   }
968
969   // Rm from sub-mesh
970   // Element should belong to only one sub-mesh
971   if( subMesh )
972     subMesh->RemoveElement(elt, /*deleted=*/false);
973
974   SMDS_Mesh::RemoveFreeElement(elt);
975 }
976
977 //================================================================================
978 /*!
979  * \brief Remove all data from the mesh
980  */
981 //================================================================================
982
983 void SMESHDS_Mesh::ClearMesh()
984 {
985   myScript->ClearMesh();
986   SMDS_Mesh::Clear();
987
988   // clear submeshes
989   map<int,SMESHDS_SubMesh*>::iterator sub, subEnd = myShapeIndexToSubMesh.end();
990   for ( sub = myShapeIndexToSubMesh.begin(); sub != subEnd; ++sub )
991     sub->second->Clear();
992
993   // clear groups
994   TGroups::iterator group, groupEnd = myGroups.end();
995   for ( group = myGroups.begin(); group != groupEnd; ++group ) {
996     if ( SMESHDS_Group* g = dynamic_cast<SMESHDS_Group*>(*group)) {
997       SMDSAbs_ElementType groupType = g->GetType();
998       g->Clear();
999       g->SetType( groupType );
1000     }
1001     else
1002     {
1003       (*group)->Extent(); // to free cashed elements in GroupOnFilter's
1004     }
1005   }
1006 }
1007
1008 //================================================================================
1009 /*!
1010  * \brief return submesh by shape
1011   * \param shape - the sub-shape
1012   * \retval SMESHDS_SubMesh* - the found submesh
1013   *
1014  * search of submeshes is optimized
1015  */
1016 //================================================================================
1017
1018 SMESHDS_SubMesh* SMESHDS_Mesh::getSubmesh( const TopoDS_Shape & shape )
1019 {
1020   if ( shape.IsNull() )
1021     return 0;
1022
1023   if ( !myCurSubShape.IsNull() && shape.IsSame( myCurSubShape ))
1024     return myCurSubMesh;
1025
1026   getSubmesh( ShapeToIndex( shape ));
1027   myCurSubShape = shape;
1028   return myCurSubMesh;
1029 }
1030
1031 //================================================================================
1032 /*!
1033  * \brief return submesh by sub-shape index
1034   * \param Index - the sub-shape index
1035   * \retval SMESHDS_SubMesh* - the found submesh
1036  * search of submeshes is optimized
1037  */
1038 //================================================================================
1039
1040 SMESHDS_SubMesh* SMESHDS_Mesh::getSubmesh( const int Index )
1041 {
1042   //Update or build submesh
1043   if ( Index != myCurSubID ) {
1044     map<int,SMESHDS_SubMesh*>::iterator it = myShapeIndexToSubMesh.find( Index );
1045     if ( it == myShapeIndexToSubMesh.end() )
1046       it = myShapeIndexToSubMesh.insert( make_pair(Index, new SMESHDS_SubMesh(this, Index) )).first;
1047     myCurSubMesh = it->second;
1048     myCurSubID = Index;
1049     myCurSubShape.Nullify(); // myCurSubShape no more corresponds to submesh
1050   }
1051   return myCurSubMesh;
1052 }
1053
1054 //================================================================================
1055 /*!
1056  * \brief Add element or node to submesh
1057   * \param elem - element to add
1058   * \param subMesh - submesh to be filled in
1059  */
1060 //================================================================================
1061
1062 bool SMESHDS_Mesh::add(const SMDS_MeshElement* elem, SMESHDS_SubMesh* subMesh )
1063 {
1064   if ( elem && subMesh ) {
1065     if ( elem->GetType() == SMDSAbs_Node )
1066       subMesh->AddNode( static_cast<const SMDS_MeshNode* >( elem ));
1067     else
1068       subMesh->AddElement( elem );
1069     return true;
1070   }
1071   return false;
1072 }
1073
1074 //=======================================================================
1075 //function : SetNodeOnVolume
1076 //purpose  : 
1077 //=======================================================================
1078 void SMESHDS_Mesh::SetNodeInVolume(const SMDS_MeshNode* aNode,
1079                                    const TopoDS_Shell & S)
1080 {
1081   if ( add( aNode, getSubmesh(S) ))
1082     const_cast< SMDS_MeshNode* >
1083       ( aNode )->SetPosition( SMDS_SpacePosition::originSpacePosition() );
1084 }
1085
1086 //=======================================================================
1087 //function : SetNodeOnVolume
1088 //purpose  : 
1089 //=======================================================================
1090 void SMESHDS_Mesh::SetNodeInVolume(const SMDS_MeshNode *      aNode,
1091                                    const TopoDS_Solid & S)
1092 {
1093   if ( add( aNode, getSubmesh(S) ))
1094     const_cast< SMDS_MeshNode* >
1095       ( aNode )->SetPosition( SMDS_SpacePosition::originSpacePosition() );
1096 }
1097
1098 //=======================================================================
1099 //function : SetNodeOnFace
1100 //purpose  : 
1101 //=======================================================================
1102 void SMESHDS_Mesh::SetNodeOnFace(const SMDS_MeshNode *     aNode,
1103                                  const TopoDS_Face & S,
1104                                  double              u,
1105                                  double              v)
1106 {
1107   if ( add( aNode, getSubmesh(S) ))
1108     const_cast< SMDS_MeshNode* >
1109       ( aNode )->SetPosition(SMDS_PositionPtr(new SMDS_FacePosition( u, v)));
1110 }
1111
1112 //=======================================================================
1113 //function : SetNodeOnEdge
1114 //purpose  : 
1115 //=======================================================================
1116 void SMESHDS_Mesh::SetNodeOnEdge(const SMDS_MeshNode *     aNode,
1117                                  const TopoDS_Edge & S,
1118                                  double              u)
1119 {
1120   if ( add( aNode, getSubmesh(S) ))
1121     const_cast< SMDS_MeshNode* >
1122       ( aNode )->SetPosition(SMDS_PositionPtr(new SMDS_EdgePosition(u)));
1123 }
1124
1125 //=======================================================================
1126 //function : SetNodeOnVertex
1127 //purpose  : 
1128 //=======================================================================
1129 void SMESHDS_Mesh::SetNodeOnVertex(const SMDS_MeshNode *       aNode,
1130                                    const TopoDS_Vertex & S)
1131 {
1132   if ( add( aNode, getSubmesh(S) ))
1133     const_cast< SMDS_MeshNode* >
1134       ( aNode )->SetPosition(SMDS_PositionPtr(new SMDS_VertexPosition()));
1135 }
1136
1137 //=======================================================================
1138 //function : UnSetNodeOnShape
1139 //purpose  : 
1140 //=======================================================================
1141 void SMESHDS_Mesh::UnSetNodeOnShape(const SMDS_MeshNode* aNode)
1142 {
1143   int shapeId = aNode->getshapeId();
1144   if (shapeId >= 0)
1145     {
1146       map<int, SMESHDS_SubMesh*>::iterator it = myShapeIndexToSubMesh.find(shapeId);
1147       if (it != myShapeIndexToSubMesh.end())
1148         it->second->RemoveNode(aNode, /*deleted=*/false);
1149     }
1150 }
1151
1152 //=======================================================================
1153 //function : SetMeshElementOnShape
1154 //purpose  : 
1155 //=======================================================================
1156 void SMESHDS_Mesh::SetMeshElementOnShape(const SMDS_MeshElement * anElement,
1157                                          const TopoDS_Shape &     S)
1158 {
1159   add( anElement, getSubmesh(S) );
1160 }
1161
1162 //=======================================================================
1163 //function : UnSetMeshElementOnShape
1164 //purpose  : 
1165 //=======================================================================
1166 void SMESHDS_Mesh::UnSetMeshElementOnShape(const SMDS_MeshElement * elem,
1167                                            const TopoDS_Shape &     S)
1168 {
1169   int Index = myIndexToShape.FindIndex(S);
1170
1171   map<int,SMESHDS_SubMesh*>::iterator it = myShapeIndexToSubMesh.find( Index );
1172   if ( it != myShapeIndexToSubMesh.end() )
1173     {
1174       if (elem->GetType() == SMDSAbs_Node)
1175         it->second->RemoveNode(static_cast<const SMDS_MeshNode*> (elem), /*deleted=*/false);
1176       else
1177         it->second->RemoveElement(elem, /*deleted=*/false);
1178     }
1179 }
1180
1181 //=======================================================================
1182 //function : ShapeToMesh
1183 //purpose  : 
1184 //=======================================================================
1185 TopoDS_Shape SMESHDS_Mesh::ShapeToMesh() const
1186 {
1187         return myShape;
1188 }
1189
1190 //=======================================================================
1191 //function : IsGroupOfSubShapes
1192 //purpose  : return true if at least one sub-shape of theShape is a sub-shape
1193 //           of myShape or theShape == myShape
1194 //=======================================================================
1195
1196 bool SMESHDS_Mesh::IsGroupOfSubShapes (const TopoDS_Shape& theShape) const
1197 {
1198   if ( myIndexToShape.Contains(theShape) )
1199     return true;
1200
1201   for ( TopoDS_Iterator it( theShape ); it.More(); it.Next() )
1202     if (IsGroupOfSubShapes( it.Value() ))
1203       return true;
1204
1205   return false;
1206 }
1207
1208 ///////////////////////////////////////////////////////////////////////////////
1209 /// Return the sub mesh linked to the a given TopoDS_Shape or NULL if the given
1210 /// TopoDS_Shape is unknown
1211 ///////////////////////////////////////////////////////////////////////////////
1212 SMESHDS_SubMesh * SMESHDS_Mesh::MeshElements(const TopoDS_Shape & S) const
1213 {
1214   int Index = ShapeToIndex(S);
1215   TShapeIndexToSubMesh::const_iterator anIter = myShapeIndexToSubMesh.find(Index);
1216   if (anIter != myShapeIndexToSubMesh.end())
1217     return anIter->second;
1218   else
1219     return NULL;
1220 }
1221
1222 ///////////////////////////////////////////////////////////////////////////////
1223 /// Return the sub mesh by Id of shape it is linked to
1224 ///////////////////////////////////////////////////////////////////////////////
1225 SMESHDS_SubMesh * SMESHDS_Mesh::MeshElements(const int Index) const
1226 {
1227   TShapeIndexToSubMesh::const_iterator anIter = myShapeIndexToSubMesh.find(Index);
1228   if (anIter != myShapeIndexToSubMesh.end())
1229     return anIter->second;
1230   else
1231     return NULL;
1232 }
1233
1234 //=======================================================================
1235 //function : SubMeshIndices
1236 //purpose  : 
1237 //=======================================================================
1238 list<int> SMESHDS_Mesh::SubMeshIndices() const
1239 {
1240   list<int> anIndices;
1241   std::map<int,SMESHDS_SubMesh*>::const_iterator anIter = myShapeIndexToSubMesh.begin();
1242   for (; anIter != myShapeIndexToSubMesh.end(); anIter++) {
1243     anIndices.push_back((*anIter).first);
1244   }
1245   return anIndices;
1246 }
1247
1248 //=======================================================================
1249 //function : GetHypothesis
1250 //purpose  : 
1251 //=======================================================================
1252
1253 const list<const SMESHDS_Hypothesis*>&
1254 SMESHDS_Mesh::GetHypothesis(const TopoDS_Shape & S) const
1255 {
1256   if ( myShapeToHypothesis.IsBound( S.Oriented(TopAbs_FORWARD) ) ) // ignore orientation of S
1257      return myShapeToHypothesis.Find( S.Oriented(TopAbs_FORWARD) );
1258
1259   static list<const SMESHDS_Hypothesis*> empty;
1260   return empty;
1261 }
1262
1263 //================================================================================
1264 /*!
1265  * \brief returns true if the hypothesis is assigned to any sub-shape
1266  */
1267 //================================================================================
1268
1269 bool SMESHDS_Mesh::IsUsedHypothesis(const SMESHDS_Hypothesis * H) const
1270 {
1271   ShapeToHypothesis::Iterator s2h( myShapeToHypothesis );
1272   for ( ; s2h.More(); s2h.Next() )
1273     if ( std::find( s2h.Value().begin(), s2h.Value().end(), H ) != s2h.Value().end() )
1274       return true;
1275   return false;
1276 }
1277
1278 //=======================================================================
1279 //function : GetScript
1280 //purpose  : 
1281 //=======================================================================
1282 SMESHDS_Script* SMESHDS_Mesh::GetScript()
1283 {
1284         return myScript;
1285 }
1286
1287 //=======================================================================
1288 //function : ClearScript
1289 //purpose  : 
1290 //=======================================================================
1291 void SMESHDS_Mesh::ClearScript()
1292 {
1293         myScript->Clear();
1294 }
1295
1296 //=======================================================================
1297 //function : HasMeshElements
1298 //purpose  : 
1299 //=======================================================================
1300 bool SMESHDS_Mesh::HasMeshElements(const TopoDS_Shape & S) const
1301 {
1302         if (myShape.IsNull()) MESSAGE("myShape is NULL");
1303         int Index = myIndexToShape.FindIndex(S);
1304         return myShapeIndexToSubMesh.find(Index)!=myShapeIndexToSubMesh.end();
1305 }
1306
1307 //=======================================================================
1308 //function : HasHypothesis
1309 //purpose  : 
1310 //=======================================================================
1311 bool SMESHDS_Mesh::HasHypothesis(const TopoDS_Shape & S)
1312 {
1313   return myShapeToHypothesis.IsBound(S.Oriented(TopAbs_FORWARD));
1314 }
1315
1316 //=======================================================================
1317 //function : NewSubMesh 
1318 //purpose  : 
1319 //=======================================================================
1320 SMESHDS_SubMesh * SMESHDS_Mesh::NewSubMesh(int Index)
1321 {
1322   SMESHDS_SubMesh* SM = 0;
1323   TShapeIndexToSubMesh::iterator anIter = myShapeIndexToSubMesh.find(Index);
1324   if (anIter == myShapeIndexToSubMesh.end())
1325   {
1326     SM = new SMESHDS_SubMesh(this, Index);
1327     myShapeIndexToSubMesh[Index]=SM;
1328   }
1329   else
1330     SM = anIter->second;
1331   return SM;
1332 }
1333
1334 //=======================================================================
1335 //function : AddCompoundSubmesh
1336 //purpose  : 
1337 //=======================================================================
1338
1339 int SMESHDS_Mesh::AddCompoundSubmesh(const TopoDS_Shape& S,
1340                                      TopAbs_ShapeEnum    type)
1341 {
1342   int aMainIndex = 0;
1343   if ( IsGroupOfSubShapes( S ))
1344   {
1345     aMainIndex = myIndexToShape.Add( S );
1346     bool all = ( type == TopAbs_SHAPE );
1347     if ( all ) // corresponding simple submesh may exist
1348       aMainIndex = -aMainIndex;
1349     //MESSAGE("AddCompoundSubmesh index = " << aMainIndex );
1350     SMESHDS_SubMesh * aNewSub = NewSubMesh( aMainIndex );
1351     if ( !aNewSub->IsComplexSubmesh() ) // is empty
1352     {
1353       int shapeType = Max( TopAbs_SOLID, all ? myShape.ShapeType() : type );
1354       int typeLimit = all ? TopAbs_VERTEX : type;
1355       for ( ; shapeType <= typeLimit; shapeType++ )
1356       {
1357         TopExp_Explorer exp( S, TopAbs_ShapeEnum( shapeType ));
1358         for ( ; exp.More(); exp.Next() )
1359         {
1360           int index = myIndexToShape.FindIndex( exp.Current() );
1361           if ( index )
1362             aNewSub->AddSubMesh( NewSubMesh( index ));
1363         }
1364       }
1365     }
1366   }
1367   return aMainIndex;
1368 }
1369
1370 //=======================================================================
1371 //function : IndexToShape
1372 //purpose  : 
1373 //=======================================================================
1374 const TopoDS_Shape& SMESHDS_Mesh::IndexToShape(int ShapeIndex) const
1375 {
1376   try
1377   {
1378     return myIndexToShape.FindKey(ShapeIndex);
1379   }
1380   catch ( Standard_OutOfRange )
1381   {
1382   }
1383   static TopoDS_Shape nullShape;
1384   return nullShape;
1385 }
1386
1387 //================================================================================
1388 /*!
1389  * \brief Return max index of sub-mesh
1390  */
1391 //================================================================================
1392
1393 int SMESHDS_Mesh::MaxSubMeshIndex() const
1394 {
1395   return myShapeIndexToSubMesh.empty() ? 0 : myShapeIndexToSubMesh.rbegin()->first;
1396 }
1397
1398 //=======================================================================
1399 //function : ShapeToIndex
1400 //purpose  : 
1401 //=======================================================================
1402 int SMESHDS_Mesh::ShapeToIndex(const TopoDS_Shape & S) const
1403 {
1404   if (myShape.IsNull())
1405     MESSAGE("myShape is NULL");
1406
1407   int index = myIndexToShape.FindIndex(S);
1408   
1409   return index;
1410 }
1411
1412 //=======================================================================
1413 //function : SetNodeOnVolume
1414 //purpose  : 
1415 //=======================================================================
1416 void SMESHDS_Mesh::SetNodeInVolume(const SMDS_MeshNode* aNode, int Index)
1417 {
1418   //add(aNode, getSubmesh(Index));
1419   if ( add( aNode, getSubmesh( Index )))
1420     ((SMDS_MeshNode*) aNode)->SetPosition( SMDS_SpacePosition::originSpacePosition());
1421 }
1422
1423 //=======================================================================
1424 //function : SetNodeOnFace
1425 //purpose  : 
1426 //=======================================================================
1427 void SMESHDS_Mesh::SetNodeOnFace(const SMDS_MeshNode* aNode, int Index, double u, double v)
1428 {
1429   //Set Position on Node
1430   if ( add( aNode, getSubmesh( Index )))
1431     const_cast< SMDS_MeshNode* >
1432       ( aNode )->SetPosition(SMDS_PositionPtr(new SMDS_FacePosition( u, v)));
1433 }
1434
1435 //=======================================================================
1436 //function : SetNodeOnEdge
1437 //purpose  : 
1438 //=======================================================================
1439 void SMESHDS_Mesh::SetNodeOnEdge(const SMDS_MeshNode* aNode,
1440                                  int                  Index,
1441                                  double               u)
1442 {
1443   //Set Position on Node
1444   if ( add( aNode, getSubmesh( Index )))
1445     const_cast< SMDS_MeshNode* >
1446       ( aNode )->SetPosition(SMDS_PositionPtr(new SMDS_EdgePosition(u)));
1447 }
1448
1449 //=======================================================================
1450 //function : SetNodeOnVertex
1451 //purpose  : 
1452 //=======================================================================
1453 void SMESHDS_Mesh::SetNodeOnVertex(const SMDS_MeshNode* aNode, int Index)
1454 {
1455   //Set Position on Node
1456   if ( add( aNode, getSubmesh( Index )))
1457     const_cast< SMDS_MeshNode* >
1458       ( aNode )->SetPosition(SMDS_PositionPtr(new SMDS_VertexPosition()));
1459 }
1460
1461 //=======================================================================
1462 //function : SetMeshElementOnShape
1463 //purpose  : 
1464 //=======================================================================
1465 void SMESHDS_Mesh::SetMeshElementOnShape(const SMDS_MeshElement* anElement,
1466                                          int                     Index)
1467 {
1468   add( anElement, getSubmesh( Index ));
1469 }
1470
1471 //=======================================================================
1472 //function : ~SMESHDS_Mesh
1473 //purpose  : 
1474 //=======================================================================
1475 SMESHDS_Mesh::~SMESHDS_Mesh()
1476 {
1477   // myScript
1478   delete myScript;
1479   // submeshes
1480   TShapeIndexToSubMesh::iterator i_sm = myShapeIndexToSubMesh.begin();
1481   for ( ; i_sm != myShapeIndexToSubMesh.end(); ++i_sm )
1482     delete i_sm->second;
1483 }
1484
1485
1486 //********************************************************************
1487 //********************************************************************
1488 //********                                                   *********
1489 //*****       Methods for addition of quadratic elements        ******
1490 //********                                                   *********
1491 //********************************************************************
1492 //********************************************************************
1493
1494 //=======================================================================
1495 //function : AddEdgeWithID
1496 //purpose  : 
1497 //=======================================================================
1498 SMDS_MeshEdge* SMESHDS_Mesh::AddEdgeWithID(int n1, int n2, int n12, int ID) 
1499 {
1500   SMDS_MeshEdge* anElem = SMDS_Mesh::AddEdgeWithID(n1,n2,n12,ID);
1501   if(anElem) myScript->AddEdge(ID,n1,n2,n12);
1502   return anElem;
1503 }
1504
1505 //=======================================================================
1506 //function : AddEdge
1507 //purpose  : 
1508 //=======================================================================
1509 SMDS_MeshEdge* SMESHDS_Mesh::AddEdge(const SMDS_MeshNode* n1,
1510                                      const SMDS_MeshNode* n2,
1511                                      const SMDS_MeshNode* n12)
1512 {
1513   SMDS_MeshEdge* anElem = SMDS_Mesh::AddEdge(n1,n2,n12);
1514   if(anElem) myScript->AddEdge(anElem->GetID(), 
1515                                n1->GetID(), 
1516                                n2->GetID(),
1517                                n12->GetID());
1518   return anElem;
1519 }
1520
1521 //=======================================================================
1522 //function : AddEdgeWithID
1523 //purpose  : 
1524 //=======================================================================
1525 SMDS_MeshEdge* SMESHDS_Mesh::AddEdgeWithID(const SMDS_MeshNode * n1,
1526                                            const SMDS_MeshNode * n2, 
1527                                            const SMDS_MeshNode * n12, 
1528                                            int ID)
1529 {
1530   return AddEdgeWithID(n1->GetID(),
1531                        n2->GetID(),
1532                        n12->GetID(),
1533                        ID);
1534 }
1535
1536
1537 //=======================================================================
1538 //function : AddFace
1539 //purpose  : 
1540 //=======================================================================
1541 SMDS_MeshFace* SMESHDS_Mesh::AddFace(const SMDS_MeshNode * n1,
1542                                      const SMDS_MeshNode * n2,
1543                                      const SMDS_MeshNode * n3,
1544                                      const SMDS_MeshNode * n12,
1545                                      const SMDS_MeshNode * n23,
1546                                      const SMDS_MeshNode * n31)
1547 {
1548   SMDS_MeshFace *anElem = SMDS_Mesh::AddFace(n1,n2,n3,n12,n23,n31);
1549   if(anElem) myScript->AddFace(anElem->GetID(), 
1550                                n1->GetID(), n2->GetID(), n3->GetID(),
1551                                n12->GetID(), n23->GetID(), n31->GetID());
1552   return anElem;
1553 }
1554
1555 //=======================================================================
1556 //function : AddFaceWithID
1557 //purpose  : 
1558 //=======================================================================
1559 SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(int n1, int n2, int n3,
1560                                            int n12,int n23,int n31, int ID)
1561 {
1562   SMDS_MeshFace *anElem = SMDS_Mesh::AddFaceWithID(n1,n2,n3,n12,n23,n31,ID);
1563   if(anElem) myScript->AddFace(ID,n1,n2,n3,n12,n23,n31);
1564   return anElem;
1565 }
1566
1567 //=======================================================================
1568 //function : AddFaceWithID
1569 //purpose  : 
1570 //=======================================================================
1571 SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
1572                                            const SMDS_MeshNode * n2,
1573                                            const SMDS_MeshNode * n3,
1574                                            const SMDS_MeshNode * n12,
1575                                            const SMDS_MeshNode * n23,
1576                                            const SMDS_MeshNode * n31, 
1577                                            int ID)
1578 {
1579   return AddFaceWithID(n1->GetID(), n2->GetID(), n3->GetID(),
1580                        n12->GetID(), n23->GetID(), n31->GetID(),
1581                        ID);
1582 }
1583
1584 //=======================================================================
1585 //function : AddFace
1586 //purpose  : 
1587 //=======================================================================
1588 SMDS_MeshFace* SMESHDS_Mesh::AddFace(const SMDS_MeshNode * n1,
1589                                      const SMDS_MeshNode * n2,
1590                                      const SMDS_MeshNode * n3,
1591                                      const SMDS_MeshNode * n12,
1592                                      const SMDS_MeshNode * n23,
1593                                      const SMDS_MeshNode * n31,
1594                                      const SMDS_MeshNode * nCenter)
1595 {
1596   SMDS_MeshFace *anElem = SMDS_Mesh::AddFace(n1,n2,n3,n12,n23,n31,nCenter);
1597   if(anElem) myScript->AddFace(anElem->GetID(), 
1598                                n1->GetID(), n2->GetID(), n3->GetID(),
1599                                n12->GetID(), n23->GetID(), n31->GetID(),
1600                                nCenter->GetID());
1601   return anElem;
1602 }
1603
1604 //=======================================================================
1605 //function : AddFaceWithID
1606 //purpose  : 
1607 //=======================================================================
1608 SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(int n1, int n2, int n3,
1609                                            int n12,int n23,int n31, int nCenter, int ID)
1610 {
1611   SMDS_MeshFace *anElem = SMDS_Mesh::AddFaceWithID(n1,n2,n3,n12,n23,n31,nCenter,ID);
1612   if(anElem) myScript->AddFace(ID,n1,n2,n3,n12,n23,n31,nCenter);
1613   return anElem;
1614 }
1615
1616 //=======================================================================
1617 //function : AddFaceWithID
1618 //purpose  : 
1619 //=======================================================================
1620 SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
1621                                            const SMDS_MeshNode * n2,
1622                                            const SMDS_MeshNode * n3,
1623                                            const SMDS_MeshNode * n12,
1624                                            const SMDS_MeshNode * n23,
1625                                            const SMDS_MeshNode * n31, 
1626                                            const SMDS_MeshNode * nCenter, 
1627                                            int ID)
1628 {
1629   return AddFaceWithID(n1->GetID(), n2->GetID(), n3->GetID(),
1630                        n12->GetID(), n23->GetID(), n31->GetID(),
1631                        nCenter->GetID(), ID);
1632 }
1633
1634
1635 //=======================================================================
1636 //function : AddFace
1637 //purpose  : 
1638 //=======================================================================
1639 SMDS_MeshFace* SMESHDS_Mesh::AddFace(const SMDS_MeshNode * n1,
1640                                      const SMDS_MeshNode * n2,
1641                                      const SMDS_MeshNode * n3,
1642                                      const SMDS_MeshNode * n4,
1643                                      const SMDS_MeshNode * n12,
1644                                      const SMDS_MeshNode * n23,
1645                                      const SMDS_MeshNode * n34,
1646                                      const SMDS_MeshNode * n41)
1647 {
1648   SMDS_MeshFace *anElem = SMDS_Mesh::AddFace(n1,n2,n3,n4,n12,n23,n34,n41);
1649   if(anElem) myScript->AddFace(anElem->GetID(), 
1650                                n1->GetID(), n2->GetID(), n3->GetID(), n4->GetID(),
1651                                n12->GetID(), n23->GetID(), n34->GetID(), n41->GetID());
1652   return anElem;
1653 }
1654
1655 //=======================================================================
1656 //function : AddFaceWithID
1657 //purpose  : 
1658 //=======================================================================
1659 SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(int n1, int n2, int n3, int n4,
1660                                            int n12,int n23,int n34,int n41, int ID)
1661 {
1662   SMDS_MeshFace *anElem = SMDS_Mesh::AddFaceWithID(n1,n2,n3,n4,n12,n23,n34,n41,ID);
1663   if(anElem) myScript->AddFace(ID,n1,n2,n3,n4,n12,n23,n34,n41);
1664   return anElem;
1665 }
1666
1667 //=======================================================================
1668 //function : AddFaceWithID
1669 //purpose  : 
1670 //=======================================================================
1671 SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
1672                                            const SMDS_MeshNode * n2,
1673                                            const SMDS_MeshNode * n3,
1674                                            const SMDS_MeshNode * n4,
1675                                            const SMDS_MeshNode * n12,
1676                                            const SMDS_MeshNode * n23,
1677                                            const SMDS_MeshNode * n34, 
1678                                            const SMDS_MeshNode * n41, 
1679                                            int ID)
1680 {
1681   return AddFaceWithID(n1->GetID(), n2->GetID(), n3->GetID(), n4->GetID(),
1682                        n12->GetID(), n23->GetID(), n34->GetID(), n41->GetID(),
1683                        ID);
1684 }
1685
1686
1687 //=======================================================================
1688 //function : AddFace
1689 //purpose  : 
1690 //=======================================================================
1691 SMDS_MeshFace* SMESHDS_Mesh::AddFace(const SMDS_MeshNode * n1,
1692                                      const SMDS_MeshNode * n2,
1693                                      const SMDS_MeshNode * n3,
1694                                      const SMDS_MeshNode * n4,
1695                                      const SMDS_MeshNode * n12,
1696                                      const SMDS_MeshNode * n23,
1697                                      const SMDS_MeshNode * n34,
1698                                      const SMDS_MeshNode * n41, 
1699                                      const SMDS_MeshNode * nCenter)
1700 {
1701   SMDS_MeshFace *anElem = SMDS_Mesh::AddFace(n1,n2,n3,n4,n12,n23,n34,n41,nCenter);
1702   if(anElem) myScript->AddFace(anElem->GetID(), 
1703                                n1->GetID(), n2->GetID(), n3->GetID(), n4->GetID(),
1704                                n12->GetID(), n23->GetID(), n34->GetID(), n41->GetID(),
1705                                nCenter->GetID());
1706   return anElem;
1707 }
1708
1709 //=======================================================================
1710 //function : AddFaceWithID
1711 //purpose  : 
1712 //=======================================================================
1713 SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(int n1, int n2, int n3, int n4,
1714                                            int n12,int n23,int n34,int n41,
1715                                            int nCenter, int ID)
1716 {
1717   SMDS_MeshFace *anElem = SMDS_Mesh::AddFaceWithID(n1,n2,n3,n4,n12,n23,n34,n41,nCenter,ID);
1718   if(anElem) myScript->AddFace(ID,n1,n2,n3,n4,n12,n23,n34,n41,nCenter);
1719   return anElem;
1720 }
1721
1722 //=======================================================================
1723 //function : AddFaceWithID
1724 //purpose  : 
1725 //=======================================================================
1726 SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
1727                                            const SMDS_MeshNode * n2,
1728                                            const SMDS_MeshNode * n3,
1729                                            const SMDS_MeshNode * n4,
1730                                            const SMDS_MeshNode * n12,
1731                                            const SMDS_MeshNode * n23,
1732                                            const SMDS_MeshNode * n34, 
1733                                            const SMDS_MeshNode * n41, 
1734                                            const SMDS_MeshNode * nCenter, 
1735                                            int ID)
1736 {
1737   return AddFaceWithID(n1->GetID(), n2->GetID(), n3->GetID(), n4->GetID(),
1738                        n12->GetID(), n23->GetID(), n34->GetID(), n41->GetID(),
1739                        nCenter->GetID(), ID);
1740 }
1741
1742
1743 //=======================================================================
1744 //function : AddVolume
1745 //purpose  : 
1746 //=======================================================================
1747 SMDS_MeshVolume* SMESHDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
1748                                          const SMDS_MeshNode * n2, 
1749                                          const SMDS_MeshNode * n3,
1750                                          const SMDS_MeshNode * n4,
1751                                          const SMDS_MeshNode * n12,
1752                                          const SMDS_MeshNode * n23,
1753                                          const SMDS_MeshNode * n31,
1754                                          const SMDS_MeshNode * n14, 
1755                                          const SMDS_MeshNode * n24,
1756                                          const SMDS_MeshNode * n34)
1757 {
1758   SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolume(n1,n2,n3,n4,n12,n23,n31,n14,n24,n34);
1759   if(anElem) myScript->AddVolume(anElem->GetID(), 
1760                                  n1->GetID(), n2->GetID(), n3->GetID(), n4->GetID(),
1761                                  n12->GetID(), n23->GetID(), n31->GetID(),
1762                                  n14->GetID(), n24->GetID(), n34->GetID());
1763   return anElem;
1764 }
1765
1766 //=======================================================================
1767 //function : AddVolumeWithID
1768 //purpose  : 
1769 //=======================================================================
1770 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4,
1771                                                int n12,int n23,int n31,
1772                                                int n14,int n24,int n34, int ID)
1773 {
1774   SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolumeWithID(n1,n2,n3,n4,n12,n23,
1775                                                        n31,n14,n24,n34,ID);
1776   if(anElem) myScript->AddVolume(ID,n1,n2,n3,n4,n12,n23,n31,n14,n24,n34);
1777   return anElem;
1778 }
1779         
1780 //=======================================================================
1781 //function : AddVolumeWithID
1782 //purpose  : 2d order tetrahedron of 10 nodes
1783 //=======================================================================
1784 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
1785                                                const SMDS_MeshNode * n2,
1786                                                const SMDS_MeshNode * n3,
1787                                                const SMDS_MeshNode * n4,
1788                                                const SMDS_MeshNode * n12,
1789                                                const SMDS_MeshNode * n23,
1790                                                const SMDS_MeshNode * n31,
1791                                                const SMDS_MeshNode * n14, 
1792                                                const SMDS_MeshNode * n24,
1793                                                const SMDS_MeshNode * n34,
1794                                                int ID)
1795 {
1796   return AddVolumeWithID(n1->GetID(), n2->GetID(), n3->GetID(), n4->GetID(),
1797                          n12->GetID(), n23->GetID(), n31->GetID(),
1798                          n14->GetID(), n24->GetID(), n34->GetID(), ID);
1799 }
1800
1801
1802 //=======================================================================
1803 //function : AddVolume
1804 //purpose  : 
1805 //=======================================================================
1806 SMDS_MeshVolume* SMESHDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
1807                                          const SMDS_MeshNode * n2, 
1808                                          const SMDS_MeshNode * n3,
1809                                          const SMDS_MeshNode * n4,
1810                                          const SMDS_MeshNode * n5, 
1811                                          const SMDS_MeshNode * n12,
1812                                          const SMDS_MeshNode * n23,
1813                                          const SMDS_MeshNode * n34,
1814                                          const SMDS_MeshNode * n41,
1815                                          const SMDS_MeshNode * n15, 
1816                                          const SMDS_MeshNode * n25,
1817                                          const SMDS_MeshNode * n35,
1818                                          const SMDS_MeshNode * n45)
1819 {
1820   SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolume(n1,n2,n3,n4,n5,n12,n23,n34,n41,
1821                                                  n15,n25,n35,n45);
1822   if(anElem)
1823     myScript->AddVolume(anElem->GetID(), n1->GetID(), n2->GetID(),
1824                         n3->GetID(), n4->GetID(), n5->GetID(),
1825                         n12->GetID(), n23->GetID(), n34->GetID(), n41->GetID(),
1826                         n15->GetID(), n25->GetID(), n35->GetID(), n45->GetID());
1827   return anElem;
1828 }
1829
1830 //=======================================================================
1831 //function : AddVolumeWithID
1832 //purpose  : 
1833 //=======================================================================
1834 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4, int n5,
1835                                                int n12,int n23,int n34,int n41,
1836                                                int n15,int n25,int n35,int n45, int ID)
1837 {
1838   SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolumeWithID(n1,n2,n3,n4,n5,
1839                                                        n12,n23,n34,n41,
1840                                                        n15,n25,n35,n45,ID);
1841   if(anElem) myScript->AddVolume(ID,n1,n2,n3,n4,n5,n12,n23,n34,n41,
1842                                  n15,n25,n35,n45);
1843   return anElem;
1844 }
1845         
1846 //=======================================================================
1847 //function : AddVolumeWithID
1848 //purpose  : 2d order pyramid of 13 nodes
1849 //=======================================================================
1850 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
1851                                                const SMDS_MeshNode * n2,
1852                                                const SMDS_MeshNode * n3,
1853                                                const SMDS_MeshNode * n4,
1854                                                const SMDS_MeshNode * n5, 
1855                                                const SMDS_MeshNode * n12,
1856                                                const SMDS_MeshNode * n23,
1857                                                const SMDS_MeshNode * n34,
1858                                                const SMDS_MeshNode * n41,
1859                                                const SMDS_MeshNode * n15, 
1860                                                const SMDS_MeshNode * n25,
1861                                                const SMDS_MeshNode * n35,
1862                                                const SMDS_MeshNode * n45,
1863                                                int ID)
1864 {
1865   return AddVolumeWithID(n1->GetID(), n2->GetID(), n3->GetID(),
1866                          n4->GetID(), n5->GetID(),
1867                          n12->GetID(), n23->GetID(), n34->GetID(), n41->GetID(),
1868                          n15->GetID(), n25->GetID(), n35->GetID(), n45->GetID(),
1869                          ID);
1870 }
1871
1872
1873 //=======================================================================
1874 //function : AddVolume
1875 //purpose  : 
1876 //=======================================================================
1877 SMDS_MeshVolume* SMESHDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
1878                                          const SMDS_MeshNode * n2, 
1879                                          const SMDS_MeshNode * n3,
1880                                          const SMDS_MeshNode * n4,
1881                                          const SMDS_MeshNode * n5, 
1882                                          const SMDS_MeshNode * n6, 
1883                                          const SMDS_MeshNode * n12,
1884                                          const SMDS_MeshNode * n23,
1885                                          const SMDS_MeshNode * n31, 
1886                                          const SMDS_MeshNode * n45,
1887                                          const SMDS_MeshNode * n56,
1888                                          const SMDS_MeshNode * n64, 
1889                                          const SMDS_MeshNode * n14,
1890                                          const SMDS_MeshNode * n25,
1891                                          const SMDS_MeshNode * n36)
1892 {
1893   SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolume(n1,n2,n3,n4,n5,n6,n12,n23,n31,
1894                                                  n45,n56,n64,n14,n25,n36);
1895   if(anElem)
1896     myScript->AddVolume(anElem->GetID(), n1->GetID(), n2->GetID(),
1897                         n3->GetID(), n4->GetID(), n5->GetID(), n6->GetID(),
1898                         n12->GetID(), n23->GetID(), n31->GetID(),
1899                         n45->GetID(), n56->GetID(), n64->GetID(),
1900                         n14->GetID(), n25->GetID(), n36->GetID());
1901   return anElem;
1902 }
1903
1904 //=======================================================================
1905 //function : AddVolumeWithID
1906 //purpose  : 
1907 //=======================================================================
1908 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(int n1, int n2, int n3,
1909                                                int n4, int n5, int n6,
1910                                                int n12,int n23,int n31,
1911                                                int n45,int n56,int n64,
1912                                                int n14,int n25,int n36, int ID)
1913 {
1914   SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolumeWithID(n1,n2,n3,n4,n5,n6,
1915                                                        n12,n23,n31,
1916                                                        n45,n56,n64,
1917                                                        n14,n25,n36,ID);
1918   if(anElem) myScript->AddVolume(ID,n1,n2,n3,n4,n5,n6,n12,n23,n31,
1919                                  n45,n56,n64,n14,n25,n36);
1920   return anElem;
1921 }
1922         
1923 //=======================================================================
1924 //function : AddVolumeWithID
1925 //purpose  : 2d order Pentahedron with 15 nodes
1926 //=======================================================================
1927 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
1928                                                const SMDS_MeshNode * n2,
1929                                                const SMDS_MeshNode * n3,
1930                                                const SMDS_MeshNode * n4,
1931                                                const SMDS_MeshNode * n5, 
1932                                                const SMDS_MeshNode * n6, 
1933                                                const SMDS_MeshNode * n12,
1934                                                const SMDS_MeshNode * n23,
1935                                                const SMDS_MeshNode * n31, 
1936                                                const SMDS_MeshNode * n45,
1937                                                const SMDS_MeshNode * n56,
1938                                                const SMDS_MeshNode * n64, 
1939                                                const SMDS_MeshNode * n14,
1940                                                const SMDS_MeshNode * n25,
1941                                                const SMDS_MeshNode * n36,
1942                                                int ID)
1943 {
1944   return AddVolumeWithID(n1->GetID(), n2->GetID(), n3->GetID(),
1945                          n4->GetID(), n5->GetID(), n6->GetID(),
1946                          n12->GetID(), n23->GetID(), n31->GetID(),
1947                          n45->GetID(), n56->GetID(), n64->GetID(),
1948                          n14->GetID(), n25->GetID(), n36->GetID(),
1949                          ID);
1950 }
1951
1952
1953 //=======================================================================
1954 //function : AddVolume
1955 //purpose  : add quadratic hexahedron
1956 //=======================================================================
1957 SMDS_MeshVolume* SMESHDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
1958                                          const SMDS_MeshNode * n2, 
1959                                          const SMDS_MeshNode * n3,
1960                                          const SMDS_MeshNode * n4,
1961                                          const SMDS_MeshNode * n5, 
1962                                          const SMDS_MeshNode * n6, 
1963                                          const SMDS_MeshNode * n7,
1964                                          const SMDS_MeshNode * n8, 
1965                                          const SMDS_MeshNode * n12,
1966                                          const SMDS_MeshNode * n23,
1967                                          const SMDS_MeshNode * n34,
1968                                          const SMDS_MeshNode * n41, 
1969                                          const SMDS_MeshNode * n56,
1970                                          const SMDS_MeshNode * n67,
1971                                          const SMDS_MeshNode * n78,
1972                                          const SMDS_MeshNode * n85, 
1973                                          const SMDS_MeshNode * n15,
1974                                          const SMDS_MeshNode * n26,
1975                                          const SMDS_MeshNode * n37,
1976                                          const SMDS_MeshNode * n48)
1977 {
1978   SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolume(n1,n2,n3,n4,n5,n6,n7,n8,
1979                                                  n12,n23,n34,n41,
1980                                                  n56,n67,n78,n85,
1981                                                  n15,n26,n37,n48);
1982   if(anElem)
1983     myScript->AddVolume(anElem->GetID(), n1->GetID(), n2->GetID(),
1984                         n3->GetID(), n4->GetID(), n5->GetID(),
1985                         n6->GetID(), n7->GetID(), n8->GetID(),
1986                         n12->GetID(), n23->GetID(), n34->GetID(), n41->GetID(),
1987                         n56->GetID(), n67->GetID(), n78->GetID(), n85->GetID(),
1988                         n15->GetID(), n26->GetID(), n37->GetID(), n48->GetID());
1989   return anElem;
1990 }
1991
1992 //=======================================================================
1993 //function : AddVolumeWithID
1994 //purpose  : 
1995 //=======================================================================
1996 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4,
1997                                                int n5, int n6, int n7, int n8,
1998                                                int n12,int n23,int n34,int n41,
1999                                                int n56,int n67,int n78,int n85,
2000                                                int n15,int n26,int n37,int n48, int ID)
2001 {
2002   SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolumeWithID(n1,n2,n3,n4,n5,n6,n7,n8,
2003                                                        n12,n23,n34,n41,
2004                                                        n56,n67,n78,n85,
2005                                                        n15,n26,n37,n48,ID);
2006   if(anElem) myScript->AddVolume(ID,n1,n2,n3,n4,n5,n6,n7,n8,n12,n23,n34,n41,
2007                                  n56,n67,n78,n85,n15,n26,n37,n48);
2008   return anElem;
2009 }
2010         
2011 //=======================================================================
2012 //function : AddVolumeWithID
2013 //purpose  : 2d order Hexahedrons with 20 nodes
2014 //=======================================================================
2015 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
2016                                                const SMDS_MeshNode * n2,
2017                                                const SMDS_MeshNode * n3,
2018                                                const SMDS_MeshNode * n4,
2019                                                const SMDS_MeshNode * n5, 
2020                                                const SMDS_MeshNode * n6, 
2021                                                const SMDS_MeshNode * n7,
2022                                                const SMDS_MeshNode * n8, 
2023                                                const SMDS_MeshNode * n12,
2024                                                const SMDS_MeshNode * n23,
2025                                                const SMDS_MeshNode * n34,
2026                                                const SMDS_MeshNode * n41, 
2027                                                const SMDS_MeshNode * n56,
2028                                                const SMDS_MeshNode * n67,
2029                                                const SMDS_MeshNode * n78,
2030                                                const SMDS_MeshNode * n85, 
2031                                                const SMDS_MeshNode * n15,
2032                                                const SMDS_MeshNode * n26,
2033                                                const SMDS_MeshNode * n37,
2034                                                const SMDS_MeshNode * n48,
2035                                                int ID)
2036 {
2037   return AddVolumeWithID(n1->GetID(), n2->GetID(), n3->GetID(), n4->GetID(),
2038                          n5->GetID(), n6->GetID(), n7->GetID(), n8->GetID(),
2039                          n12->GetID(), n23->GetID(), n34->GetID(), n41->GetID(),
2040                          n56->GetID(), n67->GetID(), n78->GetID(), n85->GetID(),
2041                          n15->GetID(), n26->GetID(), n37->GetID(), n48->GetID(),
2042                          ID);
2043 }
2044
2045 //=======================================================================
2046 //function : AddVolume
2047 //purpose  : add tri-quadratic hexahedron of 27 nodes
2048 //=======================================================================
2049
2050 SMDS_MeshVolume* SMESHDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
2051                                          const SMDS_MeshNode * n2, 
2052                                          const SMDS_MeshNode * n3,
2053                                          const SMDS_MeshNode * n4,
2054                                          const SMDS_MeshNode * n5, 
2055                                          const SMDS_MeshNode * n6, 
2056                                          const SMDS_MeshNode * n7,
2057                                          const SMDS_MeshNode * n8, 
2058                                          const SMDS_MeshNode * n12,
2059                                          const SMDS_MeshNode * n23,
2060                                          const SMDS_MeshNode * n34,
2061                                          const SMDS_MeshNode * n41, 
2062                                          const SMDS_MeshNode * n56,
2063                                          const SMDS_MeshNode * n67,
2064                                          const SMDS_MeshNode * n78,
2065                                          const SMDS_MeshNode * n85, 
2066                                          const SMDS_MeshNode * n15,
2067                                          const SMDS_MeshNode * n26,
2068                                          const SMDS_MeshNode * n37,
2069                                          const SMDS_MeshNode * n48, 
2070                                          const SMDS_MeshNode * n1234,
2071                                          const SMDS_MeshNode * n1256,
2072                                          const SMDS_MeshNode * n2367,
2073                                          const SMDS_MeshNode * n3478,
2074                                          const SMDS_MeshNode * n1458,
2075                                          const SMDS_MeshNode * n5678,
2076                                          const SMDS_MeshNode * nCenter)
2077 {
2078   SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolume(n1,n2,n3,n4,n5,n6,n7,n8,
2079                                                  n12,n23,n34,n41,
2080                                                  n56,n67,n78,n85,
2081                                                  n15,n26,n37,n48,
2082                                                  n1234,n1256,n2367,n3478,n1458,n5678,nCenter);
2083   if(anElem)
2084     myScript->AddVolume(anElem->GetID(), n1->GetID(), n2->GetID(),
2085                         n3->GetID(), n4->GetID(), n5->GetID(),
2086                         n6->GetID(), n7->GetID(), n8->GetID(),
2087                         n12->GetID(), n23->GetID(), n34->GetID(), n41->GetID(),
2088                         n56->GetID(), n67->GetID(), n78->GetID(), n85->GetID(),
2089                         n15->GetID(), n26->GetID(), n37->GetID(), n48->GetID(),
2090                         n1234->GetID(),n1256->GetID(),n2367->GetID(),n3478->GetID(),
2091                         n1458->GetID(),n5678->GetID(),nCenter->GetID());
2092   return anElem;
2093 }
2094
2095 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4,
2096                                                int n5, int n6, int n7, int n8,
2097                                                int n12,int n23,int n34,int n41,
2098                                                int n56,int n67,int n78,int n85,
2099                                                int n15,int n26,int n37,int n48,
2100                                                int n1234,int n1256,int n2367,int n3478,
2101                                                int n1458,int n5678,int nCenter,
2102                                                int ID)
2103 {
2104   SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolumeWithID(n1,n2,n3,n4,n5,n6,n7,n8,
2105                                                        n12,n23,n34,n41,
2106                                                        n56,n67,n78,n85,
2107                                                        n15,n26,n37,n48,
2108                                                        n1234, n1256, n2367, n3478,
2109                                                        n1458, n5678, nCenter,
2110                                                        ID);
2111   if(anElem) myScript->AddVolume(ID,n1,n2,n3,n4,n5,n6,n7,n8,n12,n23,n34,n41,
2112                                  n56,n67,n78,n85,n15,n26,n37,n48,
2113                                  n1234, n1256, n2367, n3478,
2114                                  n1458, n5678, nCenter);
2115   return anElem;
2116 }
2117
2118 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
2119                                                const SMDS_MeshNode * n2,
2120                                                const SMDS_MeshNode * n3,
2121                                                const SMDS_MeshNode * n4,
2122                                                const SMDS_MeshNode * n5, 
2123                                                const SMDS_MeshNode * n6, 
2124                                                const SMDS_MeshNode * n7,
2125                                                const SMDS_MeshNode * n8, 
2126                                                const SMDS_MeshNode * n12,
2127                                                const SMDS_MeshNode * n23,
2128                                                const SMDS_MeshNode * n34,
2129                                                const SMDS_MeshNode * n41, 
2130                                                const SMDS_MeshNode * n56,
2131                                                const SMDS_MeshNode * n67,
2132                                                const SMDS_MeshNode * n78,
2133                                                const SMDS_MeshNode * n85, 
2134                                                const SMDS_MeshNode * n15,
2135                                                const SMDS_MeshNode * n26,
2136                                                const SMDS_MeshNode * n37,
2137                                                const SMDS_MeshNode * n48, 
2138                                                const SMDS_MeshNode * n1234,
2139                                                const SMDS_MeshNode * n1256,
2140                                                const SMDS_MeshNode * n2367,
2141                                                const SMDS_MeshNode * n3478,
2142                                                const SMDS_MeshNode * n1458,
2143                                                const SMDS_MeshNode * n5678,
2144                                                const SMDS_MeshNode * nCenter,
2145                                                int ID)
2146 {
2147   return AddVolumeWithID(n1->GetID(), n2->GetID(), n3->GetID(), n4->GetID(),
2148                          n5->GetID(), n6->GetID(), n7->GetID(), n8->GetID(),
2149                          n12->GetID(), n23->GetID(), n34->GetID(), n41->GetID(),
2150                          n56->GetID(), n67->GetID(), n78->GetID(), n85->GetID(),
2151                          n15->GetID(), n26->GetID(), n37->GetID(), n48->GetID(),
2152                          n1234->GetID(),n1256->GetID(),n2367->GetID(),n3478->GetID(),
2153                          n1458->GetID(),n5678->GetID(),nCenter->GetID(), ID);
2154 }
2155
2156 void SMESHDS_Mesh::compactMesh()
2157 {
2158   int newNodeSize = 0;
2159   int nbNodes = myNodes.size();
2160   int nbVtkNodes = myGrid->GetNumberOfPoints();
2161   MESSAGE("nbNodes=" << nbNodes << " nbVtkNodes=" << nbVtkNodes);
2162   int nbNodeTemp = nbVtkNodes;
2163   if (nbNodes > nbVtkNodes)
2164     nbNodeTemp = nbNodes;
2165   vector<int> idNodesOldToNew;
2166   idNodesOldToNew.clear();
2167   idNodesOldToNew.resize(nbNodeTemp, -1); // all unused id will be -1
2168
2169   for (int i = 0; i < nbNodes; i++)
2170     {
2171       if (myNodes[i])
2172         {
2173           int vtkid = myNodes[i]->getVtkId();
2174           idNodesOldToNew[vtkid] = i; // old vtkId --> old smdsId (valid smdsId are >= 0)
2175           newNodeSize++;
2176         }
2177     }
2178   bool areNodesModified = (newNodeSize < nbVtkNodes);
2179   MESSAGE("------------------------- compactMesh Nodes Modified: " << areNodesModified);
2180   areNodesModified = true;
2181
2182   int newCellSize = 0;
2183   int nbCells = myCells.size();
2184   int nbVtkCells = myGrid->GetNumberOfCells();
2185   MESSAGE("nbCells=" << nbCells << " nbVtkCells=" << nbVtkCells);
2186   int nbCellTemp = nbVtkCells;
2187   if (nbCells > nbVtkCells)
2188     nbCellTemp = nbCells;
2189   vector<int> idCellsOldToNew;
2190   idCellsOldToNew.clear();
2191   idCellsOldToNew.resize(nbCellTemp, -1); // all unused id will be -1
2192
2193   for (int i = 0; i < nbCells; i++)
2194     {
2195       if (myCells[i])
2196         {
2197 //          //idCellsOldToNew[i] = myCellIdVtkToSmds[i]; // valid vtk indexes are > = 0
2198 //          int vtkid = myCells[i]->getVtkId();
2199 //          idCellsOldToNew[vtkid] = i; // old vtkId --> old smdsId (not used in input)
2200           newCellSize++;
2201         }
2202     }
2203   if (areNodesModified)
2204     myGrid->compactGrid(idNodesOldToNew, newNodeSize, idCellsOldToNew, newCellSize);
2205   else
2206     myGrid->compactGrid(idNodesOldToNew, 0, idCellsOldToNew, newCellSize);
2207
2208   int nbVtkPts = myGrid->GetNumberOfPoints();
2209   nbVtkCells = myGrid->GetNumberOfCells();
2210   if (nbVtkPts != newNodeSize)
2211     {
2212       MESSAGE("===> nbVtkPts != newNodeSize " << nbVtkPts << " " << newNodeSize);
2213       if (nbVtkPts > newNodeSize) newNodeSize = nbVtkPts; // several points with same SMDS Id
2214     }
2215   if (nbVtkCells != newCellSize)
2216     {
2217       MESSAGE("===> nbVtkCells != newCellSize " << nbVtkCells << " " << newCellSize);
2218       if (nbVtkCells > newCellSize) newCellSize = nbVtkCells; // several cells with same SMDS Id
2219     }
2220
2221   // --- SMDS_MeshNode and myNodes (id in SMDS and in VTK are the same), myNodeIdFactory
2222
2223   if (areNodesModified)
2224     {
2225       MESSAGE("-------------- modify myNodes");
2226       SetOfNodes newNodes;
2227       newNodes.resize(newNodeSize+1,0); // 0 not used, SMDS numbers 1..n
2228       int newSmdsId = 0;
2229       for (int i = 0; i < nbNodes; i++)
2230         {
2231           if (myNodes[i])
2232             {
2233               newSmdsId++; // SMDS id start to 1
2234               int oldVtkId = myNodes[i]->getVtkId();
2235               int newVtkId = idNodesOldToNew[oldVtkId];
2236               //MESSAGE("myNodes["<< i << "] vtkId " << oldVtkId << " --> " << newVtkId);
2237               myNodes[i]->setVtkId(newVtkId);
2238               myNodes[i]->setId(newSmdsId);
2239               newNodes[newSmdsId] = myNodes[i];
2240               //MESSAGE("myNodes["<< i << "] --> newNodes[" << newSmdsId << "]");
2241             }
2242         }
2243       myNodes.swap(newNodes);
2244       this->myNodeIDFactory->emptyPool(newSmdsId); // newSmdsId = number of nodes
2245       MESSAGE("myNodes.size " << myNodes.size());
2246     }
2247
2248   // --- SMDS_MeshCell, myCellIdVtkToSmds, myCellIdSmdsToVtk, myCells
2249
2250   int vtkIndexSize = myCellIdVtkToSmds.size();
2251   int maxVtkId = -1;
2252   for (int oldVtkId = 0; oldVtkId < vtkIndexSize; oldVtkId++)
2253     {
2254       int oldSmdsId = this->myCellIdVtkToSmds[oldVtkId];
2255       if (oldSmdsId > 0)
2256         {
2257           int newVtkId = idCellsOldToNew[oldVtkId];
2258           if (newVtkId > maxVtkId)
2259             maxVtkId = newVtkId;
2260           //MESSAGE("myCells["<< oldSmdsId << "] vtkId " << oldVtkId << " --> " << newVtkId);
2261           myCells[oldSmdsId]->setVtkId(newVtkId);
2262         }
2263     }
2264 //  MESSAGE("myCells.size()=" << myCells.size()
2265 //          << " myCellIdSmdsToVtk.size()=" << myCellIdSmdsToVtk.size()
2266 //          << " myCellIdVtkToSmds.size()=" << myCellIdVtkToSmds.size() );
2267
2268   SetOfCells newCells;
2269   //vector<int> newSmdsToVtk;
2270   vector<int> newVtkToSmds;
2271
2272   assert(maxVtkId < newCellSize);
2273   newCells.resize(newCellSize+1, 0); // 0 not used, SMDS numbers 1..n
2274   //newSmdsToVtk.resize(newCellSize+1, -1);
2275   newVtkToSmds.resize(newCellSize+1, -1);
2276
2277   int myCellsSize = myCells.size();
2278   int newSmdsId = 0;
2279   for (int i = 0; i < myCellsSize; i++)
2280     {
2281       if (myCells[i])
2282         {
2283           newSmdsId++; // SMDS id start to 1
2284           assert(newSmdsId <= newCellSize);
2285           newCells[newSmdsId] = myCells[i];
2286           newCells[newSmdsId]->setId(newSmdsId);
2287           //MESSAGE("myCells["<< i << "] --> newCells[" << newSmdsId << "]");
2288           int idvtk = myCells[i]->getVtkId();
2289           //newSmdsToVtk[newSmdsId] = idvtk;
2290           assert(idvtk < newCellSize);
2291           newVtkToSmds[idvtk] = newSmdsId;
2292         }
2293     }
2294
2295   myCells.swap(newCells);
2296   //myCellIdSmdsToVtk.swap(newSmdsToVtk);
2297   myCellIdVtkToSmds.swap(newVtkToSmds);
2298   MESSAGE("myCells.size()=" << myCells.size()
2299           << " myCellIdVtkToSmds.size()=" << myCellIdVtkToSmds.size() );
2300   this->myElementIDFactory->emptyPool(newSmdsId);
2301
2302   this->myScript->SetModified(true); // notify GUI client for buildPrs when update
2303
2304   // --- compact list myNodes and myElements in submeshes
2305
2306   map<int,SMESHDS_SubMesh*>::iterator it = myShapeIndexToSubMesh.begin();
2307   for(; it != myShapeIndexToSubMesh.end(); ++it)
2308     {
2309       (*it).second->compactList();
2310     }
2311
2312 }
2313
2314 void SMESHDS_Mesh::CleanDownWardConnectivity()
2315 {
2316   myGrid->CleanDownwardConnectivity();
2317 }
2318
2319 void SMESHDS_Mesh::BuildDownWardConnectivity(bool withEdges)
2320 {
2321   myGrid->BuildDownwardConnectivity(withEdges);
2322 }
2323
2324 /*! change some nodes in cell without modifying type or internal connectivity.
2325  * Nodes inverse connectivity is maintained up to date.
2326  * @param vtkVolId vtk id of the cell.
2327  * @param localClonedNodeIds map old node id to new node id.
2328  * @return ok if success.
2329  */
2330 bool SMESHDS_Mesh::ModifyCellNodes(int vtkVolId, std::map<int,int> localClonedNodeIds)
2331 {
2332   myGrid->ModifyCellNodes(vtkVolId, localClonedNodeIds);
2333   return true;
2334 }