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