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