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