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