Salome HOME
Merge from V6_3_BR 06/06/2011
[modules/smesh.git] / src / SMESHDS / SMESHDS_Mesh.cxx
1 // Copyright (C) 2007-2011  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
5 //
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License.
10 //
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 // Lesser General Public License for more details.
15 //
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
19 //
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 //
22
23 //  SMESH SMESHDS : management of mesh data and SMESH document
24 //  File   : SMESH_Mesh.cxx
25 //  Author : Yves FRICAUD, OCC
26 //  Module : SMESH
27 //  $Header: 
28 //
29 #include "SMESHDS_Mesh.hxx"
30
31 #include "SMESHDS_Group.hxx"
32 #include "SMDS_VertexPosition.hxx"
33 #include "SMDS_EdgePosition.hxx"
34 #include "SMDS_FacePosition.hxx"
35 #include "SMDS_SpacePosition.hxx"
36 #include "SMDS_Downward.hxx"
37 #include "SMESHDS_GroupOnGeom.hxx"
38
39 #include <Standard_ErrorHandler.hxx>
40 #include <Standard_OutOfRange.hxx>
41 #include <TopExp.hxx>
42 #include <TopExp_Explorer.hxx>
43 #include <TopoDS_Iterator.hxx>
44
45 #include "utilities.h"
46
47 using namespace std;
48
49 /*Standard_Boolean IsEqual( const TopoDS_Shape& S1, const TopoDS_Shape& S2 ) 
50   {
51     return S1.IsSame( S2 );
52   }*/
53
54 //=======================================================================
55 //function : Create
56 //purpose  : 
57 //=======================================================================
58 SMESHDS_Mesh::SMESHDS_Mesh(int theMeshID, bool theIsEmbeddedMode):
59   myMeshID(theMeshID),
60   myIsEmbeddedMode(theIsEmbeddedMode),
61   myCurSubID(-1)
62 {
63   myScript = new SMESHDS_Script(theIsEmbeddedMode);
64   myCurSubMesh = 0;
65   SetPersistentId(theMeshID);
66 }
67
68 //=======================================================================
69 bool SMESHDS_Mesh::IsEmbeddedMode()
70 {
71   return myIsEmbeddedMode;
72 }
73
74 //================================================================================
75 /*!
76  * \brief Store ID persistent during lifecycle
77  */
78 //================================================================================
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   if ( !theSubMeshes.empty() )
718   {
719     SMESHDS_Mesh* mesh = theSubMeshes.begin()->second->getParent();
720     list<const SMDS_MeshElement *>::iterator elIt = theElems.begin();
721     if ( isNode ) {
722       for ( ; elIt != theElems.end(); ++elIt )
723         if ( SMESHDS_SubMesh* sm = mesh->MeshElements( (*elIt)->getshapeId() ))
724           sm->RemoveNode( static_cast<const SMDS_MeshNode*> (*elIt), deleted );
725     }
726     else {
727       for ( ; elIt != theElems.end(); ++elIt )
728         if ( SMESHDS_SubMesh* sm = mesh->MeshElements( (*elIt)->getshapeId() ))
729           sm->RemoveElement( *elIt, deleted );
730     }
731   }
732 }
733
734 //=======================================================================
735 //function : RemoveNode
736 //purpose  : 
737 //=======================================================================
738 void SMESHDS_Mesh::RemoveNode(const SMDS_MeshNode * n)
739 {
740   if ( n->NbInverseElements() == 0 && !(hasConstructionEdges() || hasConstructionFaces()))
741   {
742     SMESHDS_SubMesh* subMesh=0;
743     map<int,SMESHDS_SubMesh*>::iterator SubIt =
744       myShapeIndexToSubMesh.find( n->getshapeId() );
745     if ( SubIt != myShapeIndexToSubMesh.end() )
746       subMesh = SubIt->second;
747     else
748       SubIt = myShapeIndexToSubMesh.begin();
749     for ( ; !subMesh && SubIt != myShapeIndexToSubMesh.end(); SubIt++ )
750       if (!SubIt->second->IsComplexSubmesh() && SubIt->second->Contains( n ))
751         subMesh = SubIt->second;
752
753     RemoveFreeNode( n, subMesh, true);
754     return;
755   }
756     
757   myScript->RemoveNode(n->GetID());
758   
759   list<const SMDS_MeshElement *> removedElems;
760   list<const SMDS_MeshElement *> removedNodes;
761
762   SMDS_Mesh::RemoveElement( n, removedElems, removedNodes, true );
763
764   removeFromContainers( myShapeIndexToSubMesh, myGroups, removedElems, false );
765   removeFromContainers( myShapeIndexToSubMesh, myGroups, removedNodes, true );
766 }
767
768 //=======================================================================
769 //function : RemoveFreeNode
770 //purpose  : 
771 //=======================================================================
772 void SMESHDS_Mesh::RemoveFreeNode(const SMDS_MeshNode * n,
773                                   SMESHDS_SubMesh *     subMesh,
774                                   bool                  fromGroups)
775 {
776   myScript->RemoveNode(n->GetID());
777
778   // Rm from group
779   // Node can belong to several groups
780   if (fromGroups && !myGroups.empty()) {
781     set<SMESHDS_GroupBase*>::iterator GrIt = myGroups.begin();
782     for (; GrIt != myGroups.end(); GrIt++) {
783       SMESHDS_Group* group = dynamic_cast<SMESHDS_Group*>(*GrIt);
784       if (!group || group->IsEmpty()) continue;
785       group->SMDSGroup().Remove(n);
786     }
787   }
788
789   // Rm from sub-mesh
790   // Node should belong to only one sub-mesh
791   if( subMesh )
792     subMesh->RemoveNode(n,/*deleted=*/false);
793
794   SMDS_Mesh::RemoveFreeElement(n);
795 }
796
797 //=======================================================================
798 //function : RemoveElement
799 //purpose  : 
800 //========================================================================
801 void SMESHDS_Mesh::RemoveElement(const SMDS_MeshElement * elt)
802 {
803   if (elt->GetType() == SMDSAbs_Node)
804   {
805     RemoveNode( static_cast<const SMDS_MeshNode*>( elt ));
806     return;
807   }
808   if (!hasConstructionEdges() && !hasConstructionFaces())
809   {
810     SMESHDS_SubMesh* subMesh=0;
811     map<int,SMESHDS_SubMesh*>::iterator SubIt = myShapeIndexToSubMesh.begin();
812     for ( ; !subMesh && SubIt != myShapeIndexToSubMesh.end(); SubIt++ )
813       if (!SubIt->second->IsComplexSubmesh() && SubIt->second->Contains( elt ))
814         subMesh = SubIt->second;
815     //MESSAGE("subMesh " << elt->getshapeId());
816     RemoveFreeElement( elt, subMesh, true);
817     return;
818   }
819  
820   myScript->RemoveElement(elt->GetID());
821
822   list<const SMDS_MeshElement *> removedElems;
823   list<const SMDS_MeshElement *> removedNodes;
824
825   SMDS_Mesh::RemoveElement(elt, removedElems, removedNodes, false);
826   
827   removeFromContainers( myShapeIndexToSubMesh, myGroups, removedElems, false );
828 }
829
830 //=======================================================================
831 //function : RemoveFreeElement
832 //purpose  : 
833 //========================================================================
834 void SMESHDS_Mesh::RemoveFreeElement(const SMDS_MeshElement * elt,
835                                      SMESHDS_SubMesh *        subMesh,
836                                      bool                     fromGroups)
837 {
838   //MESSAGE(" --------------------------------> SMESHDS_Mesh::RemoveFreeElement " << subMesh << " " << fromGroups);
839   if (elt->GetType() == SMDSAbs_Node) {
840     RemoveFreeNode( static_cast<const SMDS_MeshNode*>(elt), subMesh);
841     return;
842   }
843
844   if (hasConstructionEdges() || hasConstructionFaces())
845     // this methods is only for meshes without descendants
846     return;
847
848   myScript->RemoveElement(elt->GetID());
849
850   // Rm from group
851   // Node can belong to several groups
852   if ( fromGroups && !myGroups.empty() ) {
853     set<SMESHDS_GroupBase*>::iterator GrIt = myGroups.begin();
854     for (; GrIt != myGroups.end(); GrIt++) {
855       SMESHDS_Group* group = dynamic_cast<SMESHDS_Group*>(*GrIt);
856       if (group && !group->IsEmpty())
857         group->SMDSGroup().Remove(elt);
858     }
859   }
860
861   // Rm from sub-mesh
862   // Element should belong to only one sub-mesh
863   if( subMesh )
864     subMesh->RemoveElement(elt, /*deleted=*/false);
865
866   SMDS_Mesh::RemoveFreeElement(elt);
867 }
868
869 //================================================================================
870 /*!
871  * \brief Remove all data from the mesh
872  */
873 //================================================================================
874
875 void SMESHDS_Mesh::ClearMesh()
876 {
877   myScript->ClearMesh();
878   SMDS_Mesh::Clear();
879
880   // clear submeshes
881   map<int,SMESHDS_SubMesh*>::iterator sub, subEnd = myShapeIndexToSubMesh.end();
882   for ( sub = myShapeIndexToSubMesh.begin(); sub != subEnd; ++sub )
883     sub->second->Clear();
884
885   // clear groups
886   TGroups::iterator group, groupEnd = myGroups.end();
887   for ( group = myGroups.begin(); group != groupEnd; ++group ) {
888     if ( SMESHDS_Group* g = dynamic_cast<SMESHDS_Group*>(*group)) {
889       SMDSAbs_ElementType groupType = g->GetType();
890       g->Clear();
891       g->SetType( groupType );
892     }
893   }
894 }
895
896 //================================================================================
897 /*!
898  * \brief return submesh by shape
899   * \param shape - the subshape
900   * \retval SMESHDS_SubMesh* - the found submesh
901   *
902  * search of submeshes is optimized
903  */
904 //================================================================================
905
906 SMESHDS_SubMesh* SMESHDS_Mesh::getSubmesh( const TopoDS_Shape & shape )
907 {
908   if ( shape.IsNull() )
909     return 0;
910
911   if ( !myCurSubShape.IsNull() && shape.IsSame( myCurSubShape ))
912     return myCurSubMesh;
913
914   getSubmesh( ShapeToIndex( shape ));
915   myCurSubShape = shape;
916   return myCurSubMesh;
917 }
918
919 //================================================================================
920 /*!
921  * \brief return submesh by subshape index
922   * \param Index - the subshape index
923   * \retval SMESHDS_SubMesh* - the found submesh
924  * search of submeshes is optimized
925  */
926 //================================================================================
927
928 SMESHDS_SubMesh* SMESHDS_Mesh::getSubmesh( const int Index )
929 {
930   //Update or build submesh
931   if ( Index != myCurSubID ) {
932     map<int,SMESHDS_SubMesh*>::iterator it = myShapeIndexToSubMesh.find( Index );
933     if ( it == myShapeIndexToSubMesh.end() )
934       it = myShapeIndexToSubMesh.insert( make_pair(Index, new SMESHDS_SubMesh(this, Index) )).first;
935     myCurSubMesh = it->second;
936     myCurSubID = Index;
937     myCurSubShape.Nullify(); // myCurSubShape no more corresponds to submesh
938   }
939   return myCurSubMesh;
940 }
941
942 //================================================================================
943 /*!
944  * \brief Add element or node to submesh
945   * \param elem - element to add
946   * \param subMesh - submesh to be filled in
947  */
948 //================================================================================
949
950 bool SMESHDS_Mesh::add(const SMDS_MeshElement* elem, SMESHDS_SubMesh* subMesh )
951 {
952   if ( elem && subMesh ) {
953     if ( elem->GetType() == SMDSAbs_Node )
954       subMesh->AddNode( static_cast<const SMDS_MeshNode* >( elem ));
955     else
956       subMesh->AddElement( elem );
957     return true;
958   }
959   return false;
960 }
961
962 //=======================================================================
963 //function : SetNodeOnVolume
964 //purpose  : 
965 //=======================================================================
966 void SMESHDS_Mesh::SetNodeInVolume(SMDS_MeshNode *      aNode,
967                                    const TopoDS_Shell & S)
968 {
969   if ( add( aNode, getSubmesh(S) ))
970     aNode->SetPosition ( SMDS_SpacePosition::originSpacePosition() );
971 }
972
973 //=======================================================================
974 //function : SetNodeOnVolume
975 //purpose  : 
976 //=======================================================================
977 void SMESHDS_Mesh::SetNodeInVolume(SMDS_MeshNode *      aNode,
978                                    const TopoDS_Solid & S)
979 {
980   if ( add( aNode, getSubmesh(S) ))
981     aNode->SetPosition ( SMDS_SpacePosition::originSpacePosition() );
982 }
983
984 //=======================================================================
985 //function : SetNodeOnFace
986 //purpose  : 
987 //=======================================================================
988 void SMESHDS_Mesh::SetNodeOnFace(SMDS_MeshNode *     aNode,
989                                  const TopoDS_Face & S,
990                                  double              u,
991                                  double              v)
992 {
993   if ( add( aNode, getSubmesh(S) ))
994     aNode->SetPosition(SMDS_PositionPtr(new SMDS_FacePosition( u, v)));
995 }
996
997 //=======================================================================
998 //function : SetNodeOnEdge
999 //purpose  : 
1000 //=======================================================================
1001 void SMESHDS_Mesh::SetNodeOnEdge(SMDS_MeshNode *     aNode,
1002                                  const TopoDS_Edge & S,
1003                                  double              u)
1004 {
1005   if ( add( aNode, getSubmesh(S) ))
1006     aNode->SetPosition(SMDS_PositionPtr(new SMDS_EdgePosition(u)));
1007 }
1008
1009 //=======================================================================
1010 //function : SetNodeOnVertex
1011 //purpose  : 
1012 //=======================================================================
1013 void SMESHDS_Mesh::SetNodeOnVertex(SMDS_MeshNode *       aNode,
1014                                    const TopoDS_Vertex & S)
1015 {
1016   if ( add( aNode, getSubmesh(S) ))
1017     aNode->SetPosition(SMDS_PositionPtr(new SMDS_VertexPosition()));
1018 }
1019
1020 //=======================================================================
1021 //function : UnSetNodeOnShape
1022 //purpose  : 
1023 //=======================================================================
1024 void SMESHDS_Mesh::UnSetNodeOnShape(const SMDS_MeshNode* aNode)
1025 {
1026   int shapeId = aNode->getshapeId();
1027   if (shapeId >= 0)
1028     {
1029       map<int, SMESHDS_SubMesh*>::iterator it = myShapeIndexToSubMesh.find(shapeId);
1030       if (it != myShapeIndexToSubMesh.end())
1031         it->second->RemoveNode(aNode, /*deleted=*/false);
1032     }
1033 }
1034
1035 //=======================================================================
1036 //function : SetMeshElementOnShape
1037 //purpose  : 
1038 //=======================================================================
1039 void SMESHDS_Mesh::SetMeshElementOnShape(const SMDS_MeshElement * anElement,
1040                                          const TopoDS_Shape &     S)
1041 {
1042   add( anElement, getSubmesh(S) );
1043 }
1044
1045 //=======================================================================
1046 //function : UnSetMeshElementOnShape
1047 //purpose  : 
1048 //=======================================================================
1049 void SMESHDS_Mesh::UnSetMeshElementOnShape(const SMDS_MeshElement * elem,
1050                                            const TopoDS_Shape &     S)
1051 {
1052   int Index = myIndexToShape.FindIndex(S);
1053
1054   map<int,SMESHDS_SubMesh*>::iterator it = myShapeIndexToSubMesh.find( Index );
1055   if ( it != myShapeIndexToSubMesh.end() )
1056     {
1057       if (elem->GetType() == SMDSAbs_Node)
1058         it->second->RemoveNode(static_cast<const SMDS_MeshNode*> (elem), /*deleted=*/false);
1059       else
1060         it->second->RemoveElement(elem, /*deleted=*/false);
1061     }
1062 }
1063
1064 //=======================================================================
1065 //function : ShapeToMesh
1066 //purpose  : 
1067 //=======================================================================
1068 TopoDS_Shape SMESHDS_Mesh::ShapeToMesh() const
1069 {
1070         return myShape;
1071 }
1072
1073 //=======================================================================
1074 //function : IsGroupOfSubShapes
1075 //purpose  : return true if at least one subshape of theShape is a subshape
1076 //           of myShape or theShape == myShape
1077 //=======================================================================
1078
1079 bool SMESHDS_Mesh::IsGroupOfSubShapes (const TopoDS_Shape& theShape) const
1080 {
1081   if ( myIndexToShape.Contains(theShape) )
1082     return true;
1083
1084   for ( TopoDS_Iterator it( theShape ); it.More(); it.Next() )
1085     if (IsGroupOfSubShapes( it.Value() ))
1086       return true;
1087
1088   return false;
1089 }
1090
1091 ///////////////////////////////////////////////////////////////////////////////
1092 /// Return the sub mesh linked to the a given TopoDS_Shape or NULL if the given
1093 /// TopoDS_Shape is unknown
1094 ///////////////////////////////////////////////////////////////////////////////
1095 SMESHDS_SubMesh * SMESHDS_Mesh::MeshElements(const TopoDS_Shape & S) const
1096 {
1097   int Index = ShapeToIndex(S);
1098   TShapeIndexToSubMesh::const_iterator anIter = myShapeIndexToSubMesh.find(Index);
1099   if (anIter != myShapeIndexToSubMesh.end())
1100     return anIter->second;
1101   else
1102     return NULL;
1103 }
1104
1105 ///////////////////////////////////////////////////////////////////////////////
1106 /// Return the sub mesh by Id of shape it is linked to
1107 ///////////////////////////////////////////////////////////////////////////////
1108 SMESHDS_SubMesh * SMESHDS_Mesh::MeshElements(const int Index) const
1109 {
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 //function : SubMeshIndices
1119 //purpose  : 
1120 //=======================================================================
1121 list<int> SMESHDS_Mesh::SubMeshIndices() const
1122 {
1123   list<int> anIndices;
1124   std::map<int,SMESHDS_SubMesh*>::const_iterator anIter = myShapeIndexToSubMesh.begin();
1125   for (; anIter != myShapeIndexToSubMesh.end(); anIter++) {
1126     anIndices.push_back((*anIter).first);
1127   }
1128   return anIndices;
1129 }
1130
1131 //=======================================================================
1132 //function : GetHypothesis
1133 //purpose  : 
1134 //=======================================================================
1135
1136 const list<const SMESHDS_Hypothesis*>&
1137 SMESHDS_Mesh::GetHypothesis(const TopoDS_Shape & S) const
1138 {
1139   if ( myShapeToHypothesis.IsBound( S.Oriented(TopAbs_FORWARD) ) ) // ignore orientation of S
1140      return myShapeToHypothesis.Find( S.Oriented(TopAbs_FORWARD) );
1141
1142   static list<const SMESHDS_Hypothesis*> empty;
1143   return empty;
1144 }
1145
1146 //=======================================================================
1147 //function : GetScript
1148 //purpose  : 
1149 //=======================================================================
1150 SMESHDS_Script* SMESHDS_Mesh::GetScript()
1151 {
1152         return myScript;
1153 }
1154
1155 //=======================================================================
1156 //function : ClearScript
1157 //purpose  : 
1158 //=======================================================================
1159 void SMESHDS_Mesh::ClearScript()
1160 {
1161         myScript->Clear();
1162 }
1163
1164 //=======================================================================
1165 //function : HasMeshElements
1166 //purpose  : 
1167 //=======================================================================
1168 bool SMESHDS_Mesh::HasMeshElements(const TopoDS_Shape & S) const
1169 {
1170         if (myShape.IsNull()) MESSAGE("myShape is NULL");
1171         int Index = myIndexToShape.FindIndex(S);
1172         return myShapeIndexToSubMesh.find(Index)!=myShapeIndexToSubMesh.end();
1173 }
1174
1175 //=======================================================================
1176 //function : HasHypothesis
1177 //purpose  : 
1178 //=======================================================================
1179 bool SMESHDS_Mesh::HasHypothesis(const TopoDS_Shape & S)
1180 {
1181   return myShapeToHypothesis.IsBound(S.Oriented(TopAbs_FORWARD));
1182 }
1183
1184 //=======================================================================
1185 //function : NewSubMesh 
1186 //purpose  : 
1187 //=======================================================================
1188 SMESHDS_SubMesh * SMESHDS_Mesh::NewSubMesh(int Index)
1189 {
1190   SMESHDS_SubMesh* SM = 0;
1191   TShapeIndexToSubMesh::iterator anIter = myShapeIndexToSubMesh.find(Index);
1192   if (anIter == myShapeIndexToSubMesh.end())
1193   {
1194     SM = new SMESHDS_SubMesh(this, Index);
1195     myShapeIndexToSubMesh[Index]=SM;
1196   }
1197   else
1198     SM = anIter->second;
1199   return SM;
1200 }
1201
1202 //=======================================================================
1203 //function : AddCompoundSubmesh
1204 //purpose  : 
1205 //=======================================================================
1206
1207 int SMESHDS_Mesh::AddCompoundSubmesh(const TopoDS_Shape& S,
1208                                      TopAbs_ShapeEnum    type)
1209 {
1210   int aMainIndex = 0;
1211   if ( IsGroupOfSubShapes( S ))
1212   {
1213     aMainIndex = myIndexToShape.Add( S );
1214     bool all = ( type == TopAbs_SHAPE );
1215     if ( all ) // corresponding simple submesh may exist
1216       aMainIndex = -aMainIndex;
1217     //MESSAGE("AddCompoundSubmesh index = " << aMainIndex );
1218     SMESHDS_SubMesh * aNewSub = NewSubMesh( aMainIndex );
1219     if ( !aNewSub->IsComplexSubmesh() ) // is empty
1220     {
1221       int shapeType = Max( TopAbs_SOLID, all ? myShape.ShapeType() : type );
1222       int typeLimit = all ? TopAbs_VERTEX : type;
1223       for ( ; shapeType <= typeLimit; shapeType++ )
1224       {
1225         TopExp_Explorer exp( S, TopAbs_ShapeEnum( shapeType ));
1226         for ( ; exp.More(); exp.Next() )
1227         {
1228           int index = myIndexToShape.FindIndex( exp.Current() );
1229           if ( index )
1230             aNewSub->AddSubMesh( NewSubMesh( index ));
1231         }
1232       }
1233     }
1234   }
1235   return aMainIndex;
1236 }
1237
1238 //=======================================================================
1239 //function : IndexToShape
1240 //purpose  : 
1241 //=======================================================================
1242 const TopoDS_Shape& SMESHDS_Mesh::IndexToShape(int ShapeIndex) const
1243 {
1244   try
1245   {
1246     return myIndexToShape.FindKey(ShapeIndex);
1247   }
1248   catch ( Standard_OutOfRange )
1249   {
1250   }
1251   static TopoDS_Shape nullShape;
1252   return nullShape;
1253 }
1254
1255 //================================================================================
1256 /*!
1257  * \brief Return max index of sub-mesh
1258  */
1259 //================================================================================
1260
1261 int SMESHDS_Mesh::MaxSubMeshIndex() const
1262 {
1263   return myShapeIndexToSubMesh.empty() ? 0 : myShapeIndexToSubMesh.rbegin()->first;
1264 }
1265
1266 //=======================================================================
1267 //function : ShapeToIndex
1268 //purpose  : 
1269 //=======================================================================
1270 int SMESHDS_Mesh::ShapeToIndex(const TopoDS_Shape & S) const
1271 {
1272   if (myShape.IsNull())
1273     MESSAGE("myShape is NULL");
1274
1275   int index = myIndexToShape.FindIndex(S);
1276   
1277   return index;
1278 }
1279
1280 //=======================================================================
1281 //function : SetNodeOnVolume
1282 //purpose  : 
1283 //=======================================================================
1284 void SMESHDS_Mesh::SetNodeInVolume(const SMDS_MeshNode* aNode, int Index)
1285 {
1286   //add(aNode, getSubmesh(Index));
1287   if ( add( aNode, getSubmesh( Index )))
1288     ((SMDS_MeshNode*) aNode)->SetPosition( SMDS_SpacePosition::originSpacePosition());
1289 }
1290
1291 //=======================================================================
1292 //function : SetNodeOnFace
1293 //purpose  : 
1294 //=======================================================================
1295 void SMESHDS_Mesh::SetNodeOnFace(SMDS_MeshNode* aNode, int Index, double u, double v)
1296 {
1297   //Set Position on Node
1298   if ( add( aNode, getSubmesh( Index )))
1299     aNode->SetPosition(SMDS_PositionPtr(new SMDS_FacePosition( u, v)));
1300 }
1301
1302 //=======================================================================
1303 //function : SetNodeOnEdge
1304 //purpose  : 
1305 //=======================================================================
1306 void SMESHDS_Mesh::SetNodeOnEdge(SMDS_MeshNode* aNode,
1307                                  int            Index,
1308                                  double         u)
1309 {
1310   //Set Position on Node
1311   if ( add( aNode, getSubmesh( Index )))
1312     aNode->SetPosition(SMDS_PositionPtr(new SMDS_EdgePosition(u)));
1313 }
1314
1315 //=======================================================================
1316 //function : SetNodeOnVertex
1317 //purpose  : 
1318 //=======================================================================
1319 void SMESHDS_Mesh::SetNodeOnVertex(SMDS_MeshNode* aNode, int Index)
1320 {
1321   //Set Position on Node
1322   if ( add( aNode, getSubmesh( Index )))
1323     aNode->SetPosition(SMDS_PositionPtr(new SMDS_VertexPosition()));
1324 }
1325
1326 //=======================================================================
1327 //function : SetMeshElementOnShape
1328 //purpose  : 
1329 //=======================================================================
1330 void SMESHDS_Mesh::SetMeshElementOnShape(const SMDS_MeshElement* anElement,
1331                                          int                     Index)
1332 {
1333   add( anElement, getSubmesh( Index ));
1334 }
1335
1336 //=======================================================================
1337 //function : ~SMESHDS_Mesh
1338 //purpose  : 
1339 //=======================================================================
1340 SMESHDS_Mesh::~SMESHDS_Mesh()
1341 {
1342   // myScript
1343   delete myScript;
1344   // submeshes
1345   TShapeIndexToSubMesh::iterator i_sm = myShapeIndexToSubMesh.begin();
1346   for ( ; i_sm != myShapeIndexToSubMesh.end(); ++i_sm )
1347     delete i_sm->second;
1348 }
1349
1350
1351 //********************************************************************
1352 //********************************************************************
1353 //********                                                   *********
1354 //*****       Methods for addition of quadratic elements        ******
1355 //********                                                   *********
1356 //********************************************************************
1357 //********************************************************************
1358
1359 //=======================================================================
1360 //function : AddEdgeWithID
1361 //purpose  : 
1362 //=======================================================================
1363 SMDS_MeshEdge* SMESHDS_Mesh::AddEdgeWithID(int n1, int n2, int n12, int ID) 
1364 {
1365   SMDS_MeshEdge* anElem = SMDS_Mesh::AddEdgeWithID(n1,n2,n12,ID);
1366   if(anElem) myScript->AddEdge(ID,n1,n2,n12);
1367   return anElem;
1368 }
1369
1370 //=======================================================================
1371 //function : AddEdge
1372 //purpose  : 
1373 //=======================================================================
1374 SMDS_MeshEdge* SMESHDS_Mesh::AddEdge(const SMDS_MeshNode* n1,
1375                                      const SMDS_MeshNode* n2,
1376                                      const SMDS_MeshNode* n12)
1377 {
1378   SMDS_MeshEdge* anElem = SMDS_Mesh::AddEdge(n1,n2,n12);
1379   if(anElem) myScript->AddEdge(anElem->GetID(), 
1380                                n1->GetID(), 
1381                                n2->GetID(),
1382                                n12->GetID());
1383   return anElem;
1384 }
1385
1386 //=======================================================================
1387 //function : AddEdgeWithID
1388 //purpose  : 
1389 //=======================================================================
1390 SMDS_MeshEdge* SMESHDS_Mesh::AddEdgeWithID(const SMDS_MeshNode * n1,
1391                                            const SMDS_MeshNode * n2, 
1392                                            const SMDS_MeshNode * n12, 
1393                                            int ID)
1394 {
1395   return AddEdgeWithID(n1->GetID(),
1396                        n2->GetID(),
1397                        n12->GetID(),
1398                        ID);
1399 }
1400
1401
1402 //=======================================================================
1403 //function : AddFace
1404 //purpose  : 
1405 //=======================================================================
1406 SMDS_MeshFace* SMESHDS_Mesh::AddFace(const SMDS_MeshNode * n1,
1407                                      const SMDS_MeshNode * n2,
1408                                      const SMDS_MeshNode * n3,
1409                                      const SMDS_MeshNode * n12,
1410                                      const SMDS_MeshNode * n23,
1411                                      const SMDS_MeshNode * n31)
1412 {
1413   SMDS_MeshFace *anElem = SMDS_Mesh::AddFace(n1,n2,n3,n12,n23,n31);
1414   if(anElem) myScript->AddFace(anElem->GetID(), 
1415                                n1->GetID(), n2->GetID(), n3->GetID(),
1416                                n12->GetID(), n23->GetID(), n31->GetID());
1417   return anElem;
1418 }
1419
1420 //=======================================================================
1421 //function : AddFaceWithID
1422 //purpose  : 
1423 //=======================================================================
1424 SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(int n1, int n2, int n3,
1425                                            int n12,int n23,int n31, int ID)
1426 {
1427   SMDS_MeshFace *anElem = SMDS_Mesh::AddFaceWithID(n1,n2,n3,n12,n23,n31,ID);
1428   if(anElem) myScript->AddFace(ID,n1,n2,n3,n12,n23,n31);
1429   return anElem;
1430 }
1431
1432 //=======================================================================
1433 //function : AddFaceWithID
1434 //purpose  : 
1435 //=======================================================================
1436 SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
1437                                            const SMDS_MeshNode * n2,
1438                                            const SMDS_MeshNode * n3,
1439                                            const SMDS_MeshNode * n12,
1440                                            const SMDS_MeshNode * n23,
1441                                            const SMDS_MeshNode * n31, 
1442                                            int ID)
1443 {
1444   return AddFaceWithID(n1->GetID(), n2->GetID(), n3->GetID(),
1445                        n12->GetID(), n23->GetID(), n31->GetID(),
1446                        ID);
1447 }
1448
1449
1450 //=======================================================================
1451 //function : AddFace
1452 //purpose  : 
1453 //=======================================================================
1454 SMDS_MeshFace* SMESHDS_Mesh::AddFace(const SMDS_MeshNode * n1,
1455                                      const SMDS_MeshNode * n2,
1456                                      const SMDS_MeshNode * n3,
1457                                      const SMDS_MeshNode * n4,
1458                                      const SMDS_MeshNode * n12,
1459                                      const SMDS_MeshNode * n23,
1460                                      const SMDS_MeshNode * n34,
1461                                      const SMDS_MeshNode * n41)
1462 {
1463   SMDS_MeshFace *anElem = SMDS_Mesh::AddFace(n1,n2,n3,n4,n12,n23,n34,n41);
1464   if(anElem) myScript->AddFace(anElem->GetID(), 
1465                                n1->GetID(), n2->GetID(), n3->GetID(), n4->GetID(),
1466                                n12->GetID(), n23->GetID(), n34->GetID(), n41->GetID());
1467   return anElem;
1468 }
1469
1470 //=======================================================================
1471 //function : AddFaceWithID
1472 //purpose  : 
1473 //=======================================================================
1474 SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(int n1, int n2, int n3, int n4,
1475                                            int n12,int n23,int n34,int n41, int ID)
1476 {
1477   SMDS_MeshFace *anElem = SMDS_Mesh::AddFaceWithID(n1,n2,n3,n4,n12,n23,n34,n41,ID);
1478   if(anElem) myScript->AddFace(ID,n1,n2,n3,n4,n12,n23,n34,n41);
1479   return anElem;
1480 }
1481
1482 //=======================================================================
1483 //function : AddFaceWithID
1484 //purpose  : 
1485 //=======================================================================
1486 SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
1487                                            const SMDS_MeshNode * n2,
1488                                            const SMDS_MeshNode * n3,
1489                                            const SMDS_MeshNode * n4,
1490                                            const SMDS_MeshNode * n12,
1491                                            const SMDS_MeshNode * n23,
1492                                            const SMDS_MeshNode * n34, 
1493                                            const SMDS_MeshNode * n41, 
1494                                            int ID)
1495 {
1496   return AddFaceWithID(n1->GetID(), n2->GetID(), n3->GetID(), n4->GetID(),
1497                        n12->GetID(), n23->GetID(), n34->GetID(), n41->GetID(),
1498                        ID);
1499 }
1500
1501
1502 //=======================================================================
1503 //function : AddVolume
1504 //purpose  : 
1505 //=======================================================================
1506 SMDS_MeshVolume* SMESHDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
1507                                          const SMDS_MeshNode * n2, 
1508                                          const SMDS_MeshNode * n3,
1509                                          const SMDS_MeshNode * n4,
1510                                          const SMDS_MeshNode * n12,
1511                                          const SMDS_MeshNode * n23,
1512                                          const SMDS_MeshNode * n31,
1513                                          const SMDS_MeshNode * n14, 
1514                                          const SMDS_MeshNode * n24,
1515                                          const SMDS_MeshNode * n34)
1516 {
1517   SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolume(n1,n2,n3,n4,n12,n23,n31,n14,n24,n34);
1518   if(anElem) myScript->AddVolume(anElem->GetID(), 
1519                                  n1->GetID(), n2->GetID(), n3->GetID(), n4->GetID(),
1520                                  n12->GetID(), n23->GetID(), n31->GetID(),
1521                                  n14->GetID(), n24->GetID(), n34->GetID());
1522   return anElem;
1523 }
1524
1525 //=======================================================================
1526 //function : AddVolumeWithID
1527 //purpose  : 
1528 //=======================================================================
1529 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4,
1530                                                int n12,int n23,int n31,
1531                                                int n14,int n24,int n34, int ID)
1532 {
1533   SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolumeWithID(n1,n2,n3,n4,n12,n23,
1534                                                        n31,n14,n24,n34,ID);
1535   if(anElem) myScript->AddVolume(ID,n1,n2,n3,n4,n12,n23,n31,n14,n24,n34);
1536   return anElem;
1537 }
1538         
1539 //=======================================================================
1540 //function : AddVolumeWithID
1541 //purpose  : 2d order tetrahedron of 10 nodes
1542 //=======================================================================
1543 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
1544                                                const SMDS_MeshNode * n2,
1545                                                const SMDS_MeshNode * n3,
1546                                                const SMDS_MeshNode * n4,
1547                                                const SMDS_MeshNode * n12,
1548                                                const SMDS_MeshNode * n23,
1549                                                const SMDS_MeshNode * n31,
1550                                                const SMDS_MeshNode * n14, 
1551                                                const SMDS_MeshNode * n24,
1552                                                const SMDS_MeshNode * n34,
1553                                                int ID)
1554 {
1555   return AddVolumeWithID(n1->GetID(), n2->GetID(), n3->GetID(), n4->GetID(),
1556                          n12->GetID(), n23->GetID(), n31->GetID(),
1557                          n14->GetID(), n24->GetID(), n34->GetID(), ID);
1558 }
1559
1560
1561 //=======================================================================
1562 //function : AddVolume
1563 //purpose  : 
1564 //=======================================================================
1565 SMDS_MeshVolume* SMESHDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
1566                                          const SMDS_MeshNode * n2, 
1567                                          const SMDS_MeshNode * n3,
1568                                          const SMDS_MeshNode * n4,
1569                                          const SMDS_MeshNode * n5, 
1570                                          const SMDS_MeshNode * n12,
1571                                          const SMDS_MeshNode * n23,
1572                                          const SMDS_MeshNode * n34,
1573                                          const SMDS_MeshNode * n41,
1574                                          const SMDS_MeshNode * n15, 
1575                                          const SMDS_MeshNode * n25,
1576                                          const SMDS_MeshNode * n35,
1577                                          const SMDS_MeshNode * n45)
1578 {
1579   SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolume(n1,n2,n3,n4,n5,n12,n23,n34,n41,
1580                                                  n15,n25,n35,n45);
1581   if(anElem)
1582     myScript->AddVolume(anElem->GetID(), n1->GetID(), n2->GetID(),
1583                         n3->GetID(), n4->GetID(), n5->GetID(),
1584                         n12->GetID(), n23->GetID(), n34->GetID(), n41->GetID(),
1585                         n15->GetID(), n25->GetID(), n35->GetID(), n45->GetID());
1586   return anElem;
1587 }
1588
1589 //=======================================================================
1590 //function : AddVolumeWithID
1591 //purpose  : 
1592 //=======================================================================
1593 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4, int n5,
1594                                                int n12,int n23,int n34,int n41,
1595                                                int n15,int n25,int n35,int n45, int ID)
1596 {
1597   SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolumeWithID(n1,n2,n3,n4,n5,
1598                                                        n12,n23,n34,n41,
1599                                                        n15,n25,n35,n45,ID);
1600   if(anElem) myScript->AddVolume(ID,n1,n2,n3,n4,n5,n12,n23,n34,n41,
1601                                  n15,n25,n35,n45);
1602   return anElem;
1603 }
1604         
1605 //=======================================================================
1606 //function : AddVolumeWithID
1607 //purpose  : 2d order pyramid of 13 nodes
1608 //=======================================================================
1609 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
1610                                                const SMDS_MeshNode * n2,
1611                                                const SMDS_MeshNode * n3,
1612                                                const SMDS_MeshNode * n4,
1613                                                const SMDS_MeshNode * n5, 
1614                                                const SMDS_MeshNode * n12,
1615                                                const SMDS_MeshNode * n23,
1616                                                const SMDS_MeshNode * n34,
1617                                                const SMDS_MeshNode * n41,
1618                                                const SMDS_MeshNode * n15, 
1619                                                const SMDS_MeshNode * n25,
1620                                                const SMDS_MeshNode * n35,
1621                                                const SMDS_MeshNode * n45,
1622                                                int ID)
1623 {
1624   return AddVolumeWithID(n1->GetID(), n2->GetID(), n3->GetID(),
1625                          n4->GetID(), n5->GetID(),
1626                          n12->GetID(), n23->GetID(), n34->GetID(), n41->GetID(),
1627                          n15->GetID(), n25->GetID(), n35->GetID(), n45->GetID(),
1628                          ID);
1629 }
1630
1631
1632 //=======================================================================
1633 //function : AddVolume
1634 //purpose  : 
1635 //=======================================================================
1636 SMDS_MeshVolume* SMESHDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
1637                                          const SMDS_MeshNode * n2, 
1638                                          const SMDS_MeshNode * n3,
1639                                          const SMDS_MeshNode * n4,
1640                                          const SMDS_MeshNode * n5, 
1641                                          const SMDS_MeshNode * n6, 
1642                                          const SMDS_MeshNode * n12,
1643                                          const SMDS_MeshNode * n23,
1644                                          const SMDS_MeshNode * n31, 
1645                                          const SMDS_MeshNode * n45,
1646                                          const SMDS_MeshNode * n56,
1647                                          const SMDS_MeshNode * n64, 
1648                                          const SMDS_MeshNode * n14,
1649                                          const SMDS_MeshNode * n25,
1650                                          const SMDS_MeshNode * n36)
1651 {
1652   SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolume(n1,n2,n3,n4,n5,n6,n12,n23,n31,
1653                                                  n45,n56,n64,n14,n25,n36);
1654   if(anElem)
1655     myScript->AddVolume(anElem->GetID(), n1->GetID(), n2->GetID(),
1656                         n3->GetID(), n4->GetID(), n5->GetID(), n6->GetID(),
1657                         n12->GetID(), n23->GetID(), n31->GetID(),
1658                         n45->GetID(), n56->GetID(), n64->GetID(),
1659                         n14->GetID(), n25->GetID(), n36->GetID());
1660   return anElem;
1661 }
1662
1663 //=======================================================================
1664 //function : AddVolumeWithID
1665 //purpose  : 
1666 //=======================================================================
1667 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(int n1, int n2, int n3,
1668                                                int n4, int n5, int n6,
1669                                                int n12,int n23,int n31,
1670                                                int n45,int n56,int n64,
1671                                                int n14,int n25,int n36, int ID)
1672 {
1673   SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolumeWithID(n1,n2,n3,n4,n5,n6,
1674                                                        n12,n23,n31,
1675                                                        n45,n56,n64,
1676                                                        n14,n25,n36,ID);
1677   if(anElem) myScript->AddVolume(ID,n1,n2,n3,n4,n5,n6,n12,n23,n31,
1678                                  n45,n56,n64,n14,n25,n36);
1679   return anElem;
1680 }
1681         
1682 //=======================================================================
1683 //function : AddVolumeWithID
1684 //purpose  : 2d order Pentahedron with 15 nodes
1685 //=======================================================================
1686 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
1687                                                const SMDS_MeshNode * n2,
1688                                                const SMDS_MeshNode * n3,
1689                                                const SMDS_MeshNode * n4,
1690                                                const SMDS_MeshNode * n5, 
1691                                                const SMDS_MeshNode * n6, 
1692                                                const SMDS_MeshNode * n12,
1693                                                const SMDS_MeshNode * n23,
1694                                                const SMDS_MeshNode * n31, 
1695                                                const SMDS_MeshNode * n45,
1696                                                const SMDS_MeshNode * n56,
1697                                                const SMDS_MeshNode * n64, 
1698                                                const SMDS_MeshNode * n14,
1699                                                const SMDS_MeshNode * n25,
1700                                                const SMDS_MeshNode * n36,
1701                                                int ID)
1702 {
1703   return AddVolumeWithID(n1->GetID(), n2->GetID(), n3->GetID(),
1704                          n4->GetID(), n5->GetID(), n6->GetID(),
1705                          n12->GetID(), n23->GetID(), n31->GetID(),
1706                          n45->GetID(), n56->GetID(), n64->GetID(),
1707                          n14->GetID(), n25->GetID(), n36->GetID(),
1708                          ID);
1709 }
1710
1711
1712 //=======================================================================
1713 //function : AddVolume
1714 //purpose  : 
1715 //=======================================================================
1716 SMDS_MeshVolume* SMESHDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
1717                                          const SMDS_MeshNode * n2, 
1718                                          const SMDS_MeshNode * n3,
1719                                          const SMDS_MeshNode * n4,
1720                                          const SMDS_MeshNode * n5, 
1721                                          const SMDS_MeshNode * n6, 
1722                                          const SMDS_MeshNode * n7,
1723                                          const SMDS_MeshNode * n8, 
1724                                          const SMDS_MeshNode * n12,
1725                                          const SMDS_MeshNode * n23,
1726                                          const SMDS_MeshNode * n34,
1727                                          const SMDS_MeshNode * n41, 
1728                                          const SMDS_MeshNode * n56,
1729                                          const SMDS_MeshNode * n67,
1730                                          const SMDS_MeshNode * n78,
1731                                          const SMDS_MeshNode * n85, 
1732                                          const SMDS_MeshNode * n15,
1733                                          const SMDS_MeshNode * n26,
1734                                          const SMDS_MeshNode * n37,
1735                                          const SMDS_MeshNode * n48)
1736 {
1737   SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolume(n1,n2,n3,n4,n5,n6,n7,n8,
1738                                                  n12,n23,n34,n41,
1739                                                  n56,n67,n78,n85,
1740                                                  n15,n26,n37,n48);
1741   if(anElem)
1742     myScript->AddVolume(anElem->GetID(), n1->GetID(), n2->GetID(),
1743                         n3->GetID(), n4->GetID(), n5->GetID(),
1744                         n6->GetID(), n7->GetID(), n8->GetID(),
1745                         n12->GetID(), n23->GetID(), n34->GetID(), n41->GetID(),
1746                         n56->GetID(), n67->GetID(), n78->GetID(), n85->GetID(),
1747                         n15->GetID(), n26->GetID(), n37->GetID(), n48->GetID());
1748   return anElem;
1749 }
1750
1751 //=======================================================================
1752 //function : AddVolumeWithID
1753 //purpose  : 
1754 //=======================================================================
1755 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4,
1756                                                int n5, int n6, int n7, int n8,
1757                                                int n12,int n23,int n34,int n41,
1758                                                int n56,int n67,int n78,int n85,
1759                                                int n15,int n26,int n37,int n48, int ID)
1760 {
1761   SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolumeWithID(n1,n2,n3,n4,n5,n6,n7,n8,
1762                                                        n12,n23,n34,n41,
1763                                                        n56,n67,n78,n85,
1764                                                        n15,n26,n37,n48,ID);
1765   if(anElem) myScript->AddVolume(ID,n1,n2,n3,n4,n5,n6,n7,n8,n12,n23,n34,n41,
1766                                  n56,n67,n78,n85,n15,n26,n37,n48);
1767   return anElem;
1768 }
1769         
1770 //=======================================================================
1771 //function : AddVolumeWithID
1772 //purpose  : 2d order Hexahedrons with 20 nodes
1773 //=======================================================================
1774 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
1775                                                const SMDS_MeshNode * n2,
1776                                                const SMDS_MeshNode * n3,
1777                                                const SMDS_MeshNode * n4,
1778                                                const SMDS_MeshNode * n5, 
1779                                                const SMDS_MeshNode * n6, 
1780                                                const SMDS_MeshNode * n7,
1781                                                const SMDS_MeshNode * n8, 
1782                                                const SMDS_MeshNode * n12,
1783                                                const SMDS_MeshNode * n23,
1784                                                const SMDS_MeshNode * n34,
1785                                                const SMDS_MeshNode * n41, 
1786                                                const SMDS_MeshNode * n56,
1787                                                const SMDS_MeshNode * n67,
1788                                                const SMDS_MeshNode * n78,
1789                                                const SMDS_MeshNode * n85, 
1790                                                const SMDS_MeshNode * n15,
1791                                                const SMDS_MeshNode * n26,
1792                                                const SMDS_MeshNode * n37,
1793                                                const SMDS_MeshNode * n48,
1794                                                int ID)
1795 {
1796   return AddVolumeWithID(n1->GetID(), n2->GetID(), n3->GetID(), n4->GetID(),
1797                          n5->GetID(), n6->GetID(), n7->GetID(), n8->GetID(),
1798                          n12->GetID(), n23->GetID(), n34->GetID(), n41->GetID(),
1799                          n56->GetID(), n67->GetID(), n78->GetID(), n85->GetID(),
1800                          n15->GetID(), n26->GetID(), n37->GetID(), n48->GetID(),
1801                          ID);
1802 }
1803
1804 void SMESHDS_Mesh::compactMesh()
1805 {
1806   int newNodeSize = 0;
1807   int nbNodes = myNodes.size();
1808   int nbVtkNodes = myGrid->GetNumberOfPoints();
1809   MESSAGE("nbNodes=" << nbNodes << " nbVtkNodes=" << nbVtkNodes);
1810   int nbNodeTemp = nbVtkNodes;
1811   if (nbNodes > nbVtkNodes)
1812     nbNodeTemp = nbNodes;
1813   vector<int> idNodesOldToNew;
1814   idNodesOldToNew.clear();
1815   idNodesOldToNew.resize(nbNodeTemp, -1); // all unused id will be -1
1816
1817   for (int i = 0; i < nbNodes; i++)
1818     {
1819       if (myNodes[i])
1820         {
1821           int vtkid = myNodes[i]->getVtkId();
1822           idNodesOldToNew[vtkid] = i; // old vtkId --> old smdsId (valid smdsId are >= 0)
1823           newNodeSize++;
1824         }
1825     }
1826   bool areNodesModified = (newNodeSize < nbVtkNodes);
1827   MESSAGE("------------------------- compactMesh Nodes Modified: " << areNodesModified);
1828   areNodesModified = true;
1829
1830   int newCellSize = 0;
1831   int nbCells = myCells.size();
1832   int nbVtkCells = myGrid->GetNumberOfCells();
1833   MESSAGE("nbCells=" << nbCells << " nbVtkCells=" << nbVtkCells);
1834   int nbCellTemp = nbVtkCells;
1835   if (nbCells > nbVtkCells)
1836     nbCellTemp = nbCells;
1837   vector<int> idCellsOldToNew;
1838   idCellsOldToNew.clear();
1839   idCellsOldToNew.resize(nbCellTemp, -1); // all unused id will be -1
1840
1841   for (int i = 0; i < nbCells; i++)
1842     {
1843       if (myCells[i])
1844         {
1845 //          //idCellsOldToNew[i] = myCellIdVtkToSmds[i]; // valid vtk indexes are > = 0
1846 //          int vtkid = myCells[i]->getVtkId();
1847 //          idCellsOldToNew[vtkid] = i; // old vtkId --> old smdsId (not used in input)
1848           newCellSize++;
1849         }
1850     }
1851   if (areNodesModified)
1852     myGrid->compactGrid(idNodesOldToNew, newNodeSize, idCellsOldToNew, newCellSize);
1853   else
1854     myGrid->compactGrid(idNodesOldToNew, 0, idCellsOldToNew, newCellSize);
1855
1856   int nbVtkPts = myGrid->GetNumberOfPoints();
1857   nbVtkCells = myGrid->GetNumberOfCells();
1858   if (nbVtkPts != newNodeSize)
1859     {
1860       MESSAGE("===> nbVtkPts != newNodeSize " << nbVtkPts << " " << newNodeSize);
1861       if (nbVtkPts > newNodeSize) newNodeSize = nbVtkPts; // several points with same SMDS Id
1862     }
1863   if (nbVtkCells != newCellSize)
1864     {
1865       MESSAGE("===> nbVtkCells != newCellSize " << nbVtkCells << " " << newCellSize);
1866       if (nbVtkCells > newCellSize) newCellSize = nbVtkCells; // several cells with same SMDS Id
1867     }
1868
1869   // --- SMDS_MeshNode and myNodes (id in SMDS and in VTK are the same), myNodeIdFactory
1870
1871   if (areNodesModified)
1872     {
1873       MESSAGE("-------------- modify myNodes");
1874       SetOfNodes newNodes;
1875       newNodes.resize(newNodeSize+1,0); // 0 not used, SMDS numbers 1..n
1876       int newSmdsId = 0;
1877       for (int i = 0; i < nbNodes; i++)
1878         {
1879           if (myNodes[i])
1880             {
1881               newSmdsId++; // SMDS id start to 1
1882               int oldVtkId = myNodes[i]->getVtkId();
1883               int newVtkId = idNodesOldToNew[oldVtkId];
1884               //MESSAGE("myNodes["<< i << "] vtkId " << oldVtkId << " --> " << newVtkId);
1885               myNodes[i]->setVtkId(newVtkId);
1886               myNodes[i]->setId(newSmdsId);
1887               newNodes[newSmdsId] = myNodes[i];
1888               //MESSAGE("myNodes["<< i << "] --> newNodes[" << newSmdsId << "]");
1889             }
1890         }
1891       myNodes.swap(newNodes);
1892       this->myNodeIDFactory->emptyPool(newSmdsId); // newSmdsId = number of nodes
1893       MESSAGE("myNodes.size " << myNodes.size());
1894     }
1895
1896   // --- SMDS_MeshCell, myCellIdVtkToSmds, myCellIdSmdsToVtk, myCells
1897
1898   int vtkIndexSize = myCellIdVtkToSmds.size();
1899   int maxVtkId = -1;
1900   for (int oldVtkId = 0; oldVtkId < vtkIndexSize; oldVtkId++)
1901     {
1902       int oldSmdsId = this->myCellIdVtkToSmds[oldVtkId];
1903       if (oldSmdsId > 0)
1904         {
1905           int newVtkId = idCellsOldToNew[oldVtkId];
1906           if (newVtkId > maxVtkId)
1907             maxVtkId = newVtkId;
1908           //MESSAGE("myCells["<< oldSmdsId << "] vtkId " << oldVtkId << " --> " << newVtkId);
1909           myCells[oldSmdsId]->setVtkId(newVtkId);
1910         }
1911     }
1912 //  MESSAGE("myCells.size()=" << myCells.size()
1913 //          << " myCellIdSmdsToVtk.size()=" << myCellIdSmdsToVtk.size()
1914 //          << " myCellIdVtkToSmds.size()=" << myCellIdVtkToSmds.size() );
1915
1916   SetOfCells newCells;
1917   //vector<int> newSmdsToVtk;
1918   vector<int> newVtkToSmds;
1919
1920   assert(maxVtkId < newCellSize);
1921   newCells.resize(newCellSize+1, 0); // 0 not used, SMDS numbers 1..n
1922   //newSmdsToVtk.resize(newCellSize+1, -1);
1923   newVtkToSmds.resize(newCellSize+1, -1);
1924
1925   int myCellsSize = myCells.size();
1926   int newSmdsId = 0;
1927   for (int i = 0; i < myCellsSize; i++)
1928     {
1929       if (myCells[i])
1930         {
1931           newSmdsId++; // SMDS id start to 1
1932           assert(newSmdsId <= newCellSize);
1933           newCells[newSmdsId] = myCells[i];
1934           newCells[newSmdsId]->setId(newSmdsId);
1935           //MESSAGE("myCells["<< i << "] --> newCells[" << newSmdsId << "]");
1936           int idvtk = myCells[i]->getVtkId();
1937           //newSmdsToVtk[newSmdsId] = idvtk;
1938           assert(idvtk < newCellSize);
1939           newVtkToSmds[idvtk] = newSmdsId;
1940         }
1941     }
1942
1943   myCells.swap(newCells);
1944   //myCellIdSmdsToVtk.swap(newSmdsToVtk);
1945   myCellIdVtkToSmds.swap(newVtkToSmds);
1946   MESSAGE("myCells.size()=" << myCells.size()
1947           << " myCellIdVtkToSmds.size()=" << myCellIdVtkToSmds.size() );
1948   this->myElementIDFactory->emptyPool(newSmdsId);
1949
1950   this->myScript->SetModified(true); // notify GUI client for buildPrs when update
1951
1952   // --- compact list myNodes and myElements in submeshes
1953
1954   map<int,SMESHDS_SubMesh*>::iterator it = myShapeIndexToSubMesh.begin();
1955   for(; it != myShapeIndexToSubMesh.end(); ++it)
1956     {
1957       (*it).second->compactList();
1958     }
1959
1960 }
1961
1962 void SMESHDS_Mesh::CleanDownWardConnectivity()
1963 {
1964   myGrid->CleanDownwardConnectivity();
1965 }
1966
1967 void SMESHDS_Mesh::BuildDownWardConnectivity(bool withEdges)
1968 {
1969   myGrid->BuildDownwardConnectivity(withEdges);
1970 }
1971
1972 /*! change some nodes in cell without modifying type or internal connectivity.
1973  * Nodes inverse connectivity is maintained up to date.
1974  * @param vtkVolId vtk id of the cell.
1975  * @param localClonedNodeIds map old node id to new node id.
1976  * @return ok if success.
1977  */
1978 bool SMESHDS_Mesh::ModifyCellNodes(int vtkVolId, std::map<int,int> localClonedNodeIds)
1979 {
1980   myGrid->ModifyCellNodes(vtkVolId, localClonedNodeIds);
1981   return true;
1982 }