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