Salome HOME
0020145: EDF 666 SMESH: Modifications of GEOM groups are not taken into account
[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 :AddEdgeWithID
253 //purpose  : 
254 //=======================================================================
255 SMDS_MeshEdge* SMESHDS_Mesh::AddEdgeWithID(int n1, int n2, int ID)
256 {
257   SMDS_MeshEdge* anElem = SMDS_Mesh::AddEdgeWithID(n1,n2,ID);
258   if(anElem) myScript->AddEdge(ID,n1,n2);
259   return anElem;
260 }
261
262 SMDS_MeshEdge* SMESHDS_Mesh::AddEdgeWithID(const SMDS_MeshNode * n1,
263                                            const SMDS_MeshNode * n2, 
264                                            int ID)
265 {
266   return AddEdgeWithID(n1->GetID(),
267                        n2->GetID(),
268                        ID);
269 }
270
271 SMDS_MeshEdge* SMESHDS_Mesh::AddEdge(const SMDS_MeshNode * n1,
272                                      const SMDS_MeshNode * n2)
273 {
274   SMDS_MeshEdge* anElem = SMDS_Mesh::AddEdge(n1,n2);
275   if(anElem) myScript->AddEdge(anElem->GetID(), 
276                                n1->GetID(), 
277                                n2->GetID());
278   return anElem;
279 }
280
281 //=======================================================================
282 //function :AddFace
283 //purpose  : 
284 //=======================================================================
285 SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(int n1, int n2, int n3, int ID)
286 {
287   SMDS_MeshFace *anElem = SMDS_Mesh::AddFaceWithID(n1, n2, n3, ID);
288   if(anElem) myScript->AddFace(ID,n1,n2,n3);
289   return anElem;
290 }
291
292 SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
293                                            const SMDS_MeshNode * n2,
294                                            const SMDS_MeshNode * n3, 
295                                            int ID)
296 {
297   return AddFaceWithID(n1->GetID(),
298                        n2->GetID(),
299                        n3->GetID(),
300                        ID);
301 }
302
303 SMDS_MeshFace* SMESHDS_Mesh::AddFace( const SMDS_MeshNode * n1,
304                                       const SMDS_MeshNode * n2,
305                                       const SMDS_MeshNode * n3)
306 {
307   SMDS_MeshFace *anElem = SMDS_Mesh::AddFace(n1, n2, n3);
308   if(anElem) myScript->AddFace(anElem->GetID(), 
309                                n1->GetID(), 
310                                n2->GetID(),
311                                n3->GetID());
312   return anElem;
313 }
314
315 //=======================================================================
316 //function :AddFace
317 //purpose  : 
318 //=======================================================================
319 SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(int n1, int n2, int n3, int n4, int ID)
320 {
321   SMDS_MeshFace *anElem = SMDS_Mesh::AddFaceWithID(n1, n2, n3, n4, ID);
322   if(anElem) myScript->AddFace(ID, n1, n2, n3, n4);
323   return anElem;
324 }
325
326 SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
327                                            const SMDS_MeshNode * n2,
328                                            const SMDS_MeshNode * n3,
329                                            const SMDS_MeshNode * n4, 
330                                            int ID)
331 {
332   return AddFaceWithID(n1->GetID(),
333                        n2->GetID(),
334                        n3->GetID(),
335                        n4->GetID(),
336                        ID);
337 }
338
339 SMDS_MeshFace* SMESHDS_Mesh::AddFace(const SMDS_MeshNode * n1,
340                                      const SMDS_MeshNode * n2,
341                                      const SMDS_MeshNode * n3,
342                                      const SMDS_MeshNode * n4)
343 {
344   SMDS_MeshFace *anElem = SMDS_Mesh::AddFace(n1, n2, n3, n4);
345   if(anElem) myScript->AddFace(anElem->GetID(), 
346                                n1->GetID(), 
347                                n2->GetID(), 
348                                n3->GetID(),
349                                n4->GetID());
350   return anElem;
351 }
352
353 //=======================================================================
354 //function :AddVolume
355 //purpose  : 
356 //=======================================================================
357 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4, int ID)
358 {
359   SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, ID);
360   if(anElem) myScript->AddVolume(ID, n1, n2, n3, n4);
361   return anElem;
362 }
363
364 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
365                                                const SMDS_MeshNode * n2,
366                                                const SMDS_MeshNode * n3,
367                                                const SMDS_MeshNode * n4, 
368                                                int ID)
369 {
370   return AddVolumeWithID(n1->GetID(), 
371                          n2->GetID(), 
372                          n3->GetID(),
373                          n4->GetID(),
374                          ID);
375 }
376
377 SMDS_MeshVolume* SMESHDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
378                                          const SMDS_MeshNode * n2,
379                                          const SMDS_MeshNode * n3,
380                                          const SMDS_MeshNode * n4)
381 {
382   SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolume(n1, n2, n3, n4);
383   if(anElem) myScript->AddVolume(anElem->GetID(), 
384                                  n1->GetID(), 
385                                  n2->GetID(), 
386                                  n3->GetID(),
387                                  n4->GetID());
388   return anElem;
389 }
390
391 //=======================================================================
392 //function :AddVolume
393 //purpose  : 
394 //=======================================================================
395 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4, int n5, int ID)
396 {
397   SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, ID);
398   if(anElem) myScript->AddVolume(ID, n1, n2, n3, n4, n5);
399   return anElem;
400 }
401
402 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
403                                                const SMDS_MeshNode * n2,
404                                                const SMDS_MeshNode * n3,
405                                                const SMDS_MeshNode * n4,
406                                                const SMDS_MeshNode * n5, 
407                                                int ID)
408 {
409   return AddVolumeWithID(n1->GetID(), 
410                          n2->GetID(), 
411                          n3->GetID(),
412                          n4->GetID(), 
413                          n5->GetID(),
414                          ID);
415 }
416
417 SMDS_MeshVolume* SMESHDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
418                                          const SMDS_MeshNode * n2,
419                                          const SMDS_MeshNode * n3,
420                                          const SMDS_MeshNode * n4,
421                                          const SMDS_MeshNode * n5)
422 {
423   SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolume(n1, n2, n3, n4, n5);
424   if(anElem) myScript->AddVolume(anElem->GetID(), 
425                                  n1->GetID(), 
426                                  n2->GetID(), 
427                                  n3->GetID(),
428                                  n4->GetID(), 
429                                  n5->GetID());
430   return anElem;
431 }
432
433 //=======================================================================
434 //function :AddVolume
435 //purpose  : 
436 //=======================================================================
437 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4, int n5, int n6, int ID)
438 {
439   SMDS_MeshVolume *anElem= SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, ID);
440   if(anElem) myScript->AddVolume(ID, n1, n2, n3, n4, n5, n6);
441   return anElem;
442 }
443
444 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
445                                                const SMDS_MeshNode * n2,
446                                                const SMDS_MeshNode * n3,
447                                                const SMDS_MeshNode * n4,
448                                                const SMDS_MeshNode * n5,
449                                                const SMDS_MeshNode * n6, 
450                                                int ID)
451 {
452   return AddVolumeWithID(n1->GetID(), 
453                          n2->GetID(), 
454                          n3->GetID(),
455                          n4->GetID(), 
456                          n5->GetID(), 
457                          n6->GetID(),
458                          ID);
459 }
460
461 SMDS_MeshVolume* SMESHDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
462                                          const SMDS_MeshNode * n2,
463                                          const SMDS_MeshNode * n3,
464                                          const SMDS_MeshNode * n4,
465                                          const SMDS_MeshNode * n5,
466                                          const SMDS_MeshNode * n6)
467 {
468   SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolume(n1, n2, n3, n4, n5, n6);
469   if(anElem) myScript->AddVolume(anElem->GetID(), 
470                                  n1->GetID(), 
471                                  n2->GetID(), 
472                                  n3->GetID(),
473                                  n4->GetID(), 
474                                  n5->GetID(), 
475                                  n6->GetID());
476   return anElem;
477 }
478
479 //=======================================================================
480 //function :AddVolume
481 //purpose  : 
482 //=======================================================================
483 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4, int n5, int n6, int n7, int n8, int ID)
484 {
485   SMDS_MeshVolume *anElem= SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, n7, n8, ID);
486   if(anElem) myScript->AddVolume(ID, n1, n2, n3, n4, n5, n6, n7, n8);
487   return anElem;
488 }
489
490 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
491                                                const SMDS_MeshNode * n2,
492                                                const SMDS_MeshNode * n3,
493                                                const SMDS_MeshNode * n4,
494                                                const SMDS_MeshNode * n5,
495                                                const SMDS_MeshNode * n6,
496                                                const SMDS_MeshNode * n7,
497                                                const SMDS_MeshNode * n8, 
498                                                int ID)
499 {
500   return AddVolumeWithID(n1->GetID(), 
501                          n2->GetID(), 
502                          n3->GetID(),
503                          n4->GetID(), 
504                          n5->GetID(), 
505                          n6->GetID(), 
506                          n7->GetID(), 
507                          n8->GetID(),
508                          ID);
509 }
510
511 SMDS_MeshVolume* SMESHDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
512                                          const SMDS_MeshNode * n2,
513                                          const SMDS_MeshNode * n3,
514                                          const SMDS_MeshNode * n4,
515                                          const SMDS_MeshNode * n5,
516                                          const SMDS_MeshNode * n6,
517                                          const SMDS_MeshNode * n7,
518                                          const SMDS_MeshNode * n8)
519 {
520   SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolume(n1, n2, n3, n4, n5, n6, n7, n8);
521   if(anElem) myScript->AddVolume(anElem->GetID(), 
522                                  n1->GetID(), 
523                                  n2->GetID(), 
524                                  n3->GetID(),
525                                  n4->GetID(), 
526                                  n5->GetID(), 
527                                  n6->GetID(), 
528                                  n7->GetID(), 
529                                  n8->GetID());
530   return anElem;
531 }
532
533 //=======================================================================
534 //function : AddPolygonalFace
535 //purpose  : 
536 //=======================================================================
537 SMDS_MeshFace* SMESHDS_Mesh::AddPolygonalFaceWithID (std::vector<int> nodes_ids,
538                                                      const int        ID)
539 {
540   SMDS_MeshFace *anElem = SMDS_Mesh::AddPolygonalFaceWithID(nodes_ids, ID);
541   if (anElem) {
542     myScript->AddPolygonalFace(ID, nodes_ids);
543   }
544   return anElem;
545 }
546
547 SMDS_MeshFace* SMESHDS_Mesh::AddPolygonalFaceWithID
548                              (std::vector<const SMDS_MeshNode*> nodes,
549                               const int                         ID)
550 {
551   SMDS_MeshFace *anElem = SMDS_Mesh::AddPolygonalFaceWithID(nodes, ID);
552   if (anElem) {
553     int i, len = nodes.size();
554     std::vector<int> nodes_ids (len);
555     for (i = 0; i < len; i++) {
556       nodes_ids[i] = nodes[i]->GetID();
557     }
558     myScript->AddPolygonalFace(ID, nodes_ids);
559   }
560   return anElem;
561 }
562
563 SMDS_MeshFace* SMESHDS_Mesh::AddPolygonalFace
564                              (std::vector<const SMDS_MeshNode*> nodes)
565 {
566   SMDS_MeshFace *anElem = SMDS_Mesh::AddPolygonalFace(nodes);
567   if (anElem) {
568     int i, len = nodes.size();
569     std::vector<int> nodes_ids (len);
570     for (i = 0; i < len; i++) {
571       nodes_ids[i] = nodes[i]->GetID();
572     }
573     myScript->AddPolygonalFace(anElem->GetID(), nodes_ids);
574   }
575   return anElem;
576 }
577
578 //=======================================================================
579 //function : AddPolyhedralVolume
580 //purpose  : 
581 //=======================================================================
582 SMDS_MeshVolume* SMESHDS_Mesh::AddPolyhedralVolumeWithID (std::vector<int> nodes_ids,
583                                                           std::vector<int> quantities,
584                                                           const int        ID)
585 {
586   SMDS_MeshVolume *anElem = SMDS_Mesh::AddPolyhedralVolumeWithID(nodes_ids, quantities, ID);
587   if (anElem) {
588     myScript->AddPolyhedralVolume(ID, nodes_ids, quantities);
589   }
590   return anElem;
591 }
592
593 SMDS_MeshVolume* SMESHDS_Mesh::AddPolyhedralVolumeWithID
594                                (std::vector<const SMDS_MeshNode*> nodes,
595                                 std::vector<int>                  quantities,
596                                 const int                         ID)
597 {
598   SMDS_MeshVolume *anElem = SMDS_Mesh::AddPolyhedralVolumeWithID(nodes, quantities, ID);
599   if (anElem) {
600     int i, len = nodes.size();
601     std::vector<int> nodes_ids (len);
602     for (i = 0; i < len; i++) {
603       nodes_ids[i] = nodes[i]->GetID();
604     }
605     myScript->AddPolyhedralVolume(ID, nodes_ids, quantities);
606   }
607   return anElem;
608 }
609
610 SMDS_MeshVolume* SMESHDS_Mesh::AddPolyhedralVolume
611                                (std::vector<const SMDS_MeshNode*> nodes,
612                                 std::vector<int>                  quantities)
613 {
614   SMDS_MeshVolume *anElem = SMDS_Mesh::AddPolyhedralVolume(nodes, quantities);
615   if (anElem) {
616     int i, len = nodes.size();
617     std::vector<int> nodes_ids (len);
618     for (i = 0; i < len; i++) {
619       nodes_ids[i] = nodes[i]->GetID();
620     }
621     myScript->AddPolyhedralVolume(anElem->GetID(), nodes_ids, quantities);
622   }
623   return anElem;
624 }
625
626 //=======================================================================
627 //function : removeFromContainers
628 //purpose  : 
629 //=======================================================================
630
631 static void removeFromContainers (map<int,SMESHDS_SubMesh*>&     theSubMeshes,
632                                   set<SMESHDS_GroupBase*>&       theGroups,
633                                   list<const SMDS_MeshElement*>& theElems,
634                                   const bool                     isNode)
635 {
636   if ( theElems.empty() )
637     return;
638
639   // Rm from group
640   // Element can belong to several groups
641   if ( !theGroups.empty() )
642   {
643     set<SMESHDS_GroupBase*>::iterator GrIt = theGroups.begin();
644     for ( ; GrIt != theGroups.end(); GrIt++ )
645     {
646       SMESHDS_Group* group = dynamic_cast<SMESHDS_Group*>( *GrIt );
647       if ( !group || group->IsEmpty() ) continue;
648
649       list<const SMDS_MeshElement *>::iterator elIt = theElems.begin();
650       for ( ; elIt != theElems.end(); elIt++ )
651       {
652         group->SMDSGroup().Remove( *elIt );
653         if ( group->IsEmpty() ) break;
654       }
655     }
656   }
657
658   const bool deleted=true;
659
660   // Rm from sub-meshes
661   // Element should belong to only one sub-mesh
662   map<int,SMESHDS_SubMesh*>::iterator SubIt = theSubMeshes.begin();
663   for ( ; SubIt != theSubMeshes.end(); SubIt++ )
664   {
665     int size = isNode ? (*SubIt).second->NbNodes() : (*SubIt).second->NbElements();
666     if ( size == 0 ) continue;
667
668     list<const SMDS_MeshElement *>::iterator elIt = theElems.begin();
669     while ( elIt != theElems.end() )
670     {
671       bool removed = false;
672       if ( isNode )
673         removed = (*SubIt).second->RemoveNode( static_cast<const SMDS_MeshNode*> (*elIt), deleted );
674       else
675         removed = (*SubIt).second->RemoveElement( *elIt, deleted );
676
677       if (removed)
678       {
679         elIt = theElems.erase( elIt );
680         if ( theElems.empty() )
681           return; // all elements are found and removed
682       }
683       else
684       {
685         elIt++ ;
686       }
687     }
688   }
689 }
690   
691 //=======================================================================
692 //function : RemoveNode
693 //purpose  : 
694 //=======================================================================
695 void SMESHDS_Mesh::RemoveNode(const SMDS_MeshNode * n)
696 {
697   if ( n->NbInverseElements() == 0 && !(hasConstructionEdges() || hasConstructionFaces()))
698   {
699     SMESHDS_SubMesh* subMesh=0;
700     map<int,SMESHDS_SubMesh*>::iterator SubIt =
701       myShapeIndexToSubMesh.find( n->GetPosition()->GetShapeId() );
702     if ( SubIt != myShapeIndexToSubMesh.end() )
703       subMesh = SubIt->second;
704     else
705       SubIt = myShapeIndexToSubMesh.begin();
706     for ( ; !subMesh && SubIt != myShapeIndexToSubMesh.end(); SubIt++ )
707       if (!SubIt->second->IsComplexSubmesh() && SubIt->second->Contains( n ))
708         subMesh = SubIt->second;
709
710     RemoveFreeNode( n, subMesh, true);
711     return;
712   }
713     
714   myScript->RemoveNode(n->GetID());
715   
716   list<const SMDS_MeshElement *> removedElems;
717   list<const SMDS_MeshElement *> removedNodes;
718
719   SMDS_Mesh::RemoveElement( n, removedElems, removedNodes, true );
720
721   removeFromContainers( myShapeIndexToSubMesh, myGroups, removedElems, false );
722   removeFromContainers( myShapeIndexToSubMesh, myGroups, removedNodes, true );
723 }
724
725 //=======================================================================
726 //function : RemoveFreeNode
727 //purpose  : 
728 //=======================================================================
729 void SMESHDS_Mesh::RemoveFreeNode(const SMDS_MeshNode * n,
730                                   SMESHDS_SubMesh *     subMesh,
731                                   bool                  fromGroups)
732 {
733   myScript->RemoveNode(n->GetID());
734
735   // Rm from group
736   // Node can belong to several groups
737   if (fromGroups && !myGroups.empty()) {
738     set<SMESHDS_GroupBase*>::iterator GrIt = myGroups.begin();
739     for (; GrIt != myGroups.end(); GrIt++) {
740       SMESHDS_Group* group = dynamic_cast<SMESHDS_Group*>(*GrIt);
741       if (!group || group->IsEmpty()) continue;
742       group->SMDSGroup().Remove(n);
743     }
744   }
745
746   // Rm from sub-mesh
747   // Node should belong to only one sub-mesh
748   if( subMesh )
749     subMesh->RemoveNode(n,/*deleted=*/false);
750
751   SMDS_Mesh::RemoveFreeElement(n);
752 }
753
754 //=======================================================================
755 //function : RemoveElement
756 //purpose  : 
757 //========================================================================
758 void SMESHDS_Mesh::RemoveElement(const SMDS_MeshElement * elt)
759 {
760   if (elt->GetType() == SMDSAbs_Node)
761   {
762     RemoveNode( static_cast<const SMDS_MeshNode*>( elt ));
763     return;
764   }
765   if (!hasConstructionEdges() && !hasConstructionFaces())
766   {
767     SMESHDS_SubMesh* subMesh=0;
768     map<int,SMESHDS_SubMesh*>::iterator SubIt = myShapeIndexToSubMesh.begin();
769     for ( ; !subMesh && SubIt != myShapeIndexToSubMesh.end(); SubIt++ )
770       if (!SubIt->second->IsComplexSubmesh() && SubIt->second->Contains( elt ))
771         subMesh = SubIt->second;
772
773     RemoveFreeElement( elt, subMesh, true);
774     return;
775   }
776  
777   myScript->RemoveElement(elt->GetID());
778
779   list<const SMDS_MeshElement *> removedElems;
780   list<const SMDS_MeshElement *> removedNodes;
781
782   SMDS_Mesh::RemoveElement(elt, removedElems, removedNodes, false);
783   
784   removeFromContainers( myShapeIndexToSubMesh, myGroups, removedElems, false );
785 }
786
787 //=======================================================================
788 //function : RemoveFreeElement
789 //purpose  : 
790 //========================================================================
791 void SMESHDS_Mesh::RemoveFreeElement(const SMDS_MeshElement * elt,
792                                      SMESHDS_SubMesh *        subMesh,
793                                      bool                     fromGroups)
794 {
795   if (elt->GetType() == SMDSAbs_Node) {
796     RemoveFreeNode( static_cast<const SMDS_MeshNode*>(elt), subMesh);
797     return;
798   }
799
800   if (hasConstructionEdges() || hasConstructionFaces())
801     // this methods is only for meshes without descendants
802     return;
803
804   myScript->RemoveElement(elt->GetID());
805
806   // Rm from group
807   // Node can belong to several groups
808   if ( fromGroups && !myGroups.empty() ) {
809     set<SMESHDS_GroupBase*>::iterator GrIt = myGroups.begin();
810     for (; GrIt != myGroups.end(); GrIt++) {
811       SMESHDS_Group* group = dynamic_cast<SMESHDS_Group*>(*GrIt);
812       if (group && !group->IsEmpty())
813         group->SMDSGroup().Remove(elt);
814     }
815   }
816
817   // Rm from sub-mesh
818   // Element should belong to only one sub-mesh
819   if( subMesh )
820     subMesh->RemoveElement(elt, /*deleted=*/false);
821
822   SMDS_Mesh::RemoveFreeElement(elt);
823 }
824
825 //================================================================================
826 /*!
827  * \brief Remove all data from the mesh
828  */
829 //================================================================================
830
831 void SMESHDS_Mesh::ClearMesh()
832 {
833   myScript->ClearMesh();
834   SMDS_Mesh::Clear();
835
836   // clear submeshes
837   map<int,SMESHDS_SubMesh*>::iterator sub, subEnd = myShapeIndexToSubMesh.end();
838   for ( sub = myShapeIndexToSubMesh.begin(); sub != subEnd; ++sub )
839     sub->second->Clear();
840
841   // clear groups
842   TGroups::iterator group, groupEnd = myGroups.end();
843   for ( group = myGroups.begin(); group != groupEnd; ++group ) {
844     if ( SMESHDS_Group* g = dynamic_cast<SMESHDS_Group*>(*group)) {
845       SMDSAbs_ElementType groupType = g->GetType();
846       g->Clear();
847       g->SetType( groupType );
848     }
849   }
850 }
851
852 //================================================================================
853 /*!
854  * \brief return submesh by shape
855   * \param shape - the subshape
856   * \retval SMESHDS_SubMesh* - the found submesh
857   *
858  * search of submeshes is optimized
859  */
860 //================================================================================
861
862 SMESHDS_SubMesh* SMESHDS_Mesh::getSubmesh( const TopoDS_Shape & shape )
863 {
864   if ( shape.IsNull() )
865     return 0;
866
867   if ( !myCurSubShape.IsNull() && shape.IsSame( myCurSubShape ))
868     return myCurSubMesh;
869
870   getSubmesh( ShapeToIndex( shape ));
871   myCurSubShape = shape;
872   return myCurSubMesh;
873 }
874
875 //================================================================================
876 /*!
877  * \brief return submesh by subshape index
878   * \param Index - the subshape index
879   * \retval SMESHDS_SubMesh* - the found submesh
880  * search of submeshes is optimized
881  */
882 //================================================================================
883
884 SMESHDS_SubMesh* SMESHDS_Mesh::getSubmesh( const int Index )
885 {
886   //Update or build submesh
887   if ( Index != myCurSubID ) {
888     map<int,SMESHDS_SubMesh*>::iterator it = myShapeIndexToSubMesh.find( Index );
889     if ( it == myShapeIndexToSubMesh.end() )
890       it = myShapeIndexToSubMesh.insert( make_pair(Index, new SMESHDS_SubMesh() )).first;
891     myCurSubMesh = it->second;
892     myCurSubID = Index;
893     myCurSubShape.Nullify(); // myCurSubShape no more corresponds to submesh
894   }
895   return myCurSubMesh;
896 }
897
898 //================================================================================
899 /*!
900  * \brief Add element or node to submesh
901   * \param elem - element to add
902   * \param subMesh - submesh to be filled in
903  */
904 //================================================================================
905
906 bool SMESHDS_Mesh::add(const SMDS_MeshElement* elem, SMESHDS_SubMesh* subMesh )
907 {
908   if ( elem && subMesh ) {
909     if ( elem->GetType() == SMDSAbs_Node )
910       subMesh->AddNode( static_cast<const SMDS_MeshNode* >( elem ));
911     else
912       subMesh->AddElement( elem );
913     return true;
914   }
915   return false;
916 }
917
918 namespace {
919
920   //================================================================================
921   /*!
922    * \brief Creates a node position in volume
923    */
924   //================================================================================
925
926   inline SMDS_PositionPtr volumePosition(int volId)
927   {
928     SMDS_SpacePosition* pos = new SMDS_SpacePosition();
929     pos->SetShapeId( volId );
930     return SMDS_PositionPtr(pos);
931   }
932 }
933
934 //=======================================================================
935 //function : SetNodeOnVolume
936 //purpose  : 
937 //=======================================================================
938 void SMESHDS_Mesh::SetNodeInVolume(SMDS_MeshNode *      aNode,
939                                    const TopoDS_Shell & S)
940 {
941   if ( add( aNode, getSubmesh(S) ))
942     aNode->SetPosition ( volumePosition( myCurSubID ));
943 }
944 //=======================================================================
945 //function : SetNodeOnVolume
946 //purpose  : 
947 //=======================================================================
948 void SMESHDS_Mesh::SetNodeInVolume(SMDS_MeshNode *      aNode,
949                                    const TopoDS_Solid & S)
950 {
951   if ( add( aNode, getSubmesh(S) ))
952     aNode->SetPosition ( volumePosition( myCurSubID ));
953 }
954
955 //=======================================================================
956 //function : SetNodeOnFace
957 //purpose  : 
958 //=======================================================================
959 void SMESHDS_Mesh::SetNodeOnFace(SMDS_MeshNode *     aNode,
960                                  const TopoDS_Face & S,
961                                  double              u,
962                                  double              v)
963 {
964   if ( add( aNode, getSubmesh(S) ))
965     aNode->SetPosition(SMDS_PositionPtr(new SMDS_FacePosition(myCurSubID, u, v)));
966 }
967
968 //=======================================================================
969 //function : SetNodeOnEdge
970 //purpose  : 
971 //=======================================================================
972 void SMESHDS_Mesh::SetNodeOnEdge(SMDS_MeshNode *     aNode,
973                                  const TopoDS_Edge & S,
974                                  double              u)
975 {
976   if ( add( aNode, getSubmesh(S) ))
977     aNode->SetPosition(SMDS_PositionPtr(new SMDS_EdgePosition(myCurSubID, u)));
978 }
979
980 //=======================================================================
981 //function : SetNodeOnVertex
982 //purpose  : 
983 //=======================================================================
984 void SMESHDS_Mesh::SetNodeOnVertex(SMDS_MeshNode *       aNode,
985                                    const TopoDS_Vertex & S)
986 {
987   if ( add( aNode, getSubmesh(S) ))
988     aNode->SetPosition(SMDS_PositionPtr(new SMDS_VertexPosition(myCurSubID)));
989 }
990
991 //=======================================================================
992 //function : UnSetNodeOnShape
993 //purpose  : 
994 //=======================================================================
995 void SMESHDS_Mesh::UnSetNodeOnShape(const SMDS_MeshNode* aNode)
996 {
997   if ( aNode && aNode->GetPosition() ) {
998     map<int,SMESHDS_SubMesh*>::iterator it =
999       myShapeIndexToSubMesh.find( aNode->GetPosition()->GetShapeId() );
1000     if ( it != myShapeIndexToSubMesh.end() )
1001       it->second->RemoveNode( aNode, /*deleted=*/false );
1002   }
1003 }
1004
1005 //=======================================================================
1006 //function : SetMeshElementOnShape
1007 //purpose  : 
1008 //=======================================================================
1009 void SMESHDS_Mesh::SetMeshElementOnShape(const SMDS_MeshElement * anElement,
1010                                          const TopoDS_Shape &     S)
1011 {
1012   add( anElement, getSubmesh(S) );
1013 }
1014
1015 //=======================================================================
1016 //function : UnSetMeshElementOnShape
1017 //purpose  : 
1018 //=======================================================================
1019 void SMESHDS_Mesh::UnSetMeshElementOnShape(const SMDS_MeshElement * elem,
1020                                            const TopoDS_Shape &     S)
1021 {
1022   int Index = myIndexToShape.FindIndex(S);
1023
1024   map<int,SMESHDS_SubMesh*>::iterator it = myShapeIndexToSubMesh.find( Index );
1025   if ( it != myShapeIndexToSubMesh.end() )
1026     if ( elem->GetType() == SMDSAbs_Node )
1027       it->second->RemoveNode( static_cast<const SMDS_MeshNode* >( elem ), /*deleted=*/false );
1028     else
1029       it->second->RemoveElement( elem, /*deleted=*/false );
1030 }
1031
1032 //=======================================================================
1033 //function : ShapeToMesh
1034 //purpose  : 
1035 //=======================================================================
1036 TopoDS_Shape SMESHDS_Mesh::ShapeToMesh() const
1037 {
1038         return myShape;
1039 }
1040
1041 //=======================================================================
1042 //function : IsGroupOfSubShapes
1043 //purpose  : return true if at least one subshape of theShape is a subshape
1044 //           of myShape or theShape == myShape
1045 //=======================================================================
1046
1047 bool SMESHDS_Mesh::IsGroupOfSubShapes (const TopoDS_Shape& theShape) const
1048 {
1049   if ( myShape.IsSame( theShape ))
1050     return true;
1051
1052   for ( TopoDS_Iterator it( theShape ); it.More(); it.Next() ) {
1053     if (myIndexToShape.Contains( it.Value() ) ||
1054         IsGroupOfSubShapes( it.Value() ))
1055       return true;
1056   }
1057   
1058   return false;
1059 }
1060
1061 ///////////////////////////////////////////////////////////////////////////////
1062 /// Return the sub mesh linked to the a given TopoDS_Shape or NULL if the given
1063 /// TopoDS_Shape is unknown
1064 ///////////////////////////////////////////////////////////////////////////////
1065 SMESHDS_SubMesh * SMESHDS_Mesh::MeshElements(const TopoDS_Shape & S) const
1066 {
1067   int Index = ShapeToIndex(S);
1068   TShapeIndexToSubMesh::const_iterator anIter = myShapeIndexToSubMesh.find(Index);
1069   if (anIter != myShapeIndexToSubMesh.end())
1070     return anIter->second;
1071   else
1072     return NULL;
1073 }
1074
1075 ///////////////////////////////////////////////////////////////////////////////
1076 /// Return the sub mesh by Id of shape it is linked to
1077 ///////////////////////////////////////////////////////////////////////////////
1078 SMESHDS_SubMesh * SMESHDS_Mesh::MeshElements(const int Index)
1079 {
1080   TShapeIndexToSubMesh::const_iterator anIter = myShapeIndexToSubMesh.find(Index);
1081   if (anIter != myShapeIndexToSubMesh.end())
1082     return anIter->second;
1083   else
1084     return NULL;
1085 }
1086
1087 //=======================================================================
1088 //function : SubMeshIndices
1089 //purpose  : 
1090 //=======================================================================
1091 list<int> SMESHDS_Mesh::SubMeshIndices()
1092 {
1093   list<int> anIndices;
1094   std::map<int,SMESHDS_SubMesh*>::iterator anIter = myShapeIndexToSubMesh.begin();
1095   for (; anIter != myShapeIndexToSubMesh.end(); anIter++) {
1096     anIndices.push_back((*anIter).first);
1097   }
1098   return anIndices;
1099 }
1100
1101 //=======================================================================
1102 //function : GetHypothesis
1103 //purpose  : 
1104 //=======================================================================
1105
1106 const list<const SMESHDS_Hypothesis*>&
1107 SMESHDS_Mesh::GetHypothesis(const TopoDS_Shape & S) const
1108 {
1109   if ( myShapeToHypothesis.IsBound( S.Oriented(TopAbs_FORWARD) ) ) // ignore orientation of S
1110      return myShapeToHypothesis.Find( S.Oriented(TopAbs_FORWARD) );
1111
1112   static list<const SMESHDS_Hypothesis*> empty;
1113   return empty;
1114 }
1115
1116 //=======================================================================
1117 //function : GetScript
1118 //purpose  : 
1119 //=======================================================================
1120 SMESHDS_Script* SMESHDS_Mesh::GetScript()
1121 {
1122         return myScript;
1123 }
1124
1125 //=======================================================================
1126 //function : ClearScript
1127 //purpose  : 
1128 //=======================================================================
1129 void SMESHDS_Mesh::ClearScript()
1130 {
1131         myScript->Clear();
1132 }
1133
1134 //=======================================================================
1135 //function : HasMeshElements
1136 //purpose  : 
1137 //=======================================================================
1138 bool SMESHDS_Mesh::HasMeshElements(const TopoDS_Shape & S)
1139 {
1140         if (myShape.IsNull()) MESSAGE("myShape is NULL");
1141         int Index = myIndexToShape.FindIndex(S);
1142         return myShapeIndexToSubMesh.find(Index)!=myShapeIndexToSubMesh.end();
1143 }
1144
1145 //=======================================================================
1146 //function : HasHypothesis
1147 //purpose  : 
1148 //=======================================================================
1149 bool SMESHDS_Mesh::HasHypothesis(const TopoDS_Shape & S)
1150 {
1151   return myShapeToHypothesis.IsBound(S.Oriented(TopAbs_FORWARD));
1152 }
1153
1154 //=======================================================================
1155 //function : NewSubMesh 
1156 //purpose  : 
1157 //=======================================================================
1158 SMESHDS_SubMesh * SMESHDS_Mesh::NewSubMesh(int Index)
1159 {
1160   SMESHDS_SubMesh* SM = 0;
1161   TShapeIndexToSubMesh::iterator anIter = myShapeIndexToSubMesh.find(Index);
1162   if (anIter == myShapeIndexToSubMesh.end())
1163   {
1164     SM = new SMESHDS_SubMesh();
1165     myShapeIndexToSubMesh[Index]=SM;
1166   }
1167   else
1168     SM = anIter->second;
1169   return SM;
1170 }
1171
1172 //=======================================================================
1173 //function : AddCompoundSubmesh
1174 //purpose  : 
1175 //=======================================================================
1176
1177 int SMESHDS_Mesh::AddCompoundSubmesh(const TopoDS_Shape& S,
1178                                      TopAbs_ShapeEnum    type)
1179 {
1180   int aMainIndex = 0;
1181   if ( IsGroupOfSubShapes( S ) || (S.ShapeType() == TopAbs_VERTEX && myIndexToShape.Contains(S)) )
1182   {
1183     aMainIndex = myIndexToShape.Add( S );
1184     bool all = ( type == TopAbs_SHAPE );
1185     if ( all ) // corresponding simple submesh may exist
1186       aMainIndex = -aMainIndex;
1187     //MESSAGE("AddCompoundSubmesh index = " << aMainIndex );
1188     SMESHDS_SubMesh * aNewSub = NewSubMesh( aMainIndex );
1189     if ( !aNewSub->IsComplexSubmesh() ) // is empty
1190     {
1191       int shapeType = Max( TopAbs_SOLID, all ? myShape.ShapeType() : type );
1192       int typeLimit = all ? TopAbs_VERTEX : type;
1193       for ( ; shapeType <= typeLimit; shapeType++ )
1194       {
1195         TopExp_Explorer exp( S, TopAbs_ShapeEnum( shapeType ));
1196         for ( ; exp.More(); exp.Next() )
1197         {
1198           int index = myIndexToShape.FindIndex( exp.Current() );
1199           if ( index )
1200             aNewSub->AddSubMesh( NewSubMesh( index ));
1201         }
1202       }
1203     }
1204   }
1205   return aMainIndex;
1206 }
1207
1208 //=======================================================================
1209 //function : IndexToShape
1210 //purpose  : 
1211 //=======================================================================
1212 const TopoDS_Shape& SMESHDS_Mesh::IndexToShape(int ShapeIndex) const
1213 {
1214         return myIndexToShape.FindKey(ShapeIndex);
1215 }
1216
1217 //=======================================================================
1218 //function : ShapeToIndex
1219 //purpose  : 
1220 //=======================================================================
1221 int SMESHDS_Mesh::ShapeToIndex(const TopoDS_Shape & S) const
1222 {
1223   if (myShape.IsNull())
1224     MESSAGE("myShape is NULL");
1225
1226   int index = myIndexToShape.FindIndex(S);
1227   
1228   return index;
1229 }
1230
1231 //=======================================================================
1232 //function : SetNodeOnVolume
1233 //purpose  : 
1234 //=======================================================================
1235 void SMESHDS_Mesh::SetNodeInVolume(const SMDS_MeshNode* aNode, int Index)
1236 {
1237   if ( add( aNode, getSubmesh( Index )))
1238     ((SMDS_MeshNode*) aNode)->SetPosition( volumePosition( Index ));
1239 }
1240
1241 //=======================================================================
1242 //function : SetNodeOnFace
1243 //purpose  : 
1244 //=======================================================================
1245 void SMESHDS_Mesh::SetNodeOnFace(SMDS_MeshNode* aNode, int Index, double u, double v)
1246 {
1247   //Set Position on Node
1248   if ( add( aNode, getSubmesh( Index )))
1249     aNode->SetPosition(SMDS_PositionPtr(new SMDS_FacePosition(Index, u, v)));
1250 }
1251
1252 //=======================================================================
1253 //function : SetNodeOnEdge
1254 //purpose  : 
1255 //=======================================================================
1256 void SMESHDS_Mesh::SetNodeOnEdge(SMDS_MeshNode* aNode,
1257                                  int            Index,
1258                                  double         u)
1259 {
1260   //Set Position on Node
1261   if ( add( aNode, getSubmesh( Index )))
1262     aNode->SetPosition(SMDS_PositionPtr(new SMDS_EdgePosition(Index, u)));
1263 }
1264
1265 //=======================================================================
1266 //function : SetNodeOnVertex
1267 //purpose  : 
1268 //=======================================================================
1269 void SMESHDS_Mesh::SetNodeOnVertex(SMDS_MeshNode* aNode, int Index)
1270 {
1271   //Set Position on Node
1272   if ( add( aNode, getSubmesh( Index )))
1273     aNode->SetPosition(SMDS_PositionPtr(new SMDS_VertexPosition(Index)));
1274 }
1275
1276 //=======================================================================
1277 //function : SetMeshElementOnShape
1278 //purpose  : 
1279 //=======================================================================
1280 void SMESHDS_Mesh::SetMeshElementOnShape(const SMDS_MeshElement* anElement,
1281                                          int                     Index)
1282 {
1283   add( anElement, getSubmesh( Index ));
1284 }
1285
1286 //=======================================================================
1287 //function : ~SMESHDS_Mesh
1288 //purpose  : 
1289 //=======================================================================
1290 SMESHDS_Mesh::~SMESHDS_Mesh()
1291 {
1292   // myScript
1293   delete myScript;
1294   // submeshes
1295   TShapeIndexToSubMesh::iterator i_sm = myShapeIndexToSubMesh.begin();
1296   for ( ; i_sm != myShapeIndexToSubMesh.end(); ++i_sm )
1297     delete i_sm->second;
1298 }
1299
1300
1301 //********************************************************************
1302 //********************************************************************
1303 //********                                                   *********
1304 //*****       Methods for addition of quadratic elements        ******
1305 //********                                                   *********
1306 //********************************************************************
1307 //********************************************************************
1308
1309 //=======================================================================
1310 //function : AddEdgeWithID
1311 //purpose  : 
1312 //=======================================================================
1313 SMDS_MeshEdge* SMESHDS_Mesh::AddEdgeWithID(int n1, int n2, int n12, int ID) 
1314 {
1315   SMDS_MeshEdge* anElem = SMDS_Mesh::AddEdgeWithID(n1,n2,n12,ID);
1316   if(anElem) myScript->AddEdge(ID,n1,n2,n12);
1317   return anElem;
1318 }
1319
1320 //=======================================================================
1321 //function : AddEdge
1322 //purpose  : 
1323 //=======================================================================
1324 SMDS_MeshEdge* SMESHDS_Mesh::AddEdge(const SMDS_MeshNode* n1,
1325                                      const SMDS_MeshNode* n2,
1326                                      const SMDS_MeshNode* n12)
1327 {
1328   SMDS_MeshEdge* anElem = SMDS_Mesh::AddEdge(n1,n2,n12);
1329   if(anElem) myScript->AddEdge(anElem->GetID(), 
1330                                n1->GetID(), 
1331                                n2->GetID(),
1332                                n12->GetID());
1333   return anElem;
1334 }
1335
1336 //=======================================================================
1337 //function : AddEdgeWithID
1338 //purpose  : 
1339 //=======================================================================
1340 SMDS_MeshEdge* SMESHDS_Mesh::AddEdgeWithID(const SMDS_MeshNode * n1,
1341                                            const SMDS_MeshNode * n2, 
1342                                            const SMDS_MeshNode * n12, 
1343                                            int ID)
1344 {
1345   return AddEdgeWithID(n1->GetID(),
1346                        n2->GetID(),
1347                        n12->GetID(),
1348                        ID);
1349 }
1350
1351
1352 //=======================================================================
1353 //function : AddFace
1354 //purpose  : 
1355 //=======================================================================
1356 SMDS_MeshFace* SMESHDS_Mesh::AddFace(const SMDS_MeshNode * n1,
1357                                      const SMDS_MeshNode * n2,
1358                                      const SMDS_MeshNode * n3,
1359                                      const SMDS_MeshNode * n12,
1360                                      const SMDS_MeshNode * n23,
1361                                      const SMDS_MeshNode * n31)
1362 {
1363   SMDS_MeshFace *anElem = SMDS_Mesh::AddFace(n1,n2,n3,n12,n23,n31);
1364   if(anElem) myScript->AddFace(anElem->GetID(), 
1365                                n1->GetID(), n2->GetID(), n3->GetID(),
1366                                n12->GetID(), n23->GetID(), n31->GetID());
1367   return anElem;
1368 }
1369
1370 //=======================================================================
1371 //function : AddFaceWithID
1372 //purpose  : 
1373 //=======================================================================
1374 SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(int n1, int n2, int n3,
1375                                            int n12,int n23,int n31, int ID)
1376 {
1377   SMDS_MeshFace *anElem = SMDS_Mesh::AddFaceWithID(n1,n2,n3,n12,n23,n31,ID);
1378   if(anElem) myScript->AddFace(ID,n1,n2,n3,n12,n23,n31);
1379   return anElem;
1380 }
1381
1382 //=======================================================================
1383 //function : AddFaceWithID
1384 //purpose  : 
1385 //=======================================================================
1386 SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
1387                                            const SMDS_MeshNode * n2,
1388                                            const SMDS_MeshNode * n3,
1389                                            const SMDS_MeshNode * n12,
1390                                            const SMDS_MeshNode * n23,
1391                                            const SMDS_MeshNode * n31, 
1392                                            int ID)
1393 {
1394   return AddFaceWithID(n1->GetID(), n2->GetID(), n3->GetID(),
1395                        n12->GetID(), n23->GetID(), n31->GetID(),
1396                        ID);
1397 }
1398
1399
1400 //=======================================================================
1401 //function : AddFace
1402 //purpose  : 
1403 //=======================================================================
1404 SMDS_MeshFace* SMESHDS_Mesh::AddFace(const SMDS_MeshNode * n1,
1405                                      const SMDS_MeshNode * n2,
1406                                      const SMDS_MeshNode * n3,
1407                                      const SMDS_MeshNode * n4,
1408                                      const SMDS_MeshNode * n12,
1409                                      const SMDS_MeshNode * n23,
1410                                      const SMDS_MeshNode * n34,
1411                                      const SMDS_MeshNode * n41)
1412 {
1413   SMDS_MeshFace *anElem = SMDS_Mesh::AddFace(n1,n2,n3,n4,n12,n23,n34,n41);
1414   if(anElem) myScript->AddFace(anElem->GetID(), 
1415                                n1->GetID(), n2->GetID(), n3->GetID(), n4->GetID(),
1416                                n12->GetID(), n23->GetID(), n34->GetID(), n41->GetID());
1417   return anElem;
1418 }
1419
1420 //=======================================================================
1421 //function : AddFaceWithID
1422 //purpose  : 
1423 //=======================================================================
1424 SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(int n1, int n2, int n3, int n4,
1425                                            int n12,int n23,int n34,int n41, int ID)
1426 {
1427   SMDS_MeshFace *anElem = SMDS_Mesh::AddFaceWithID(n1,n2,n3,n4,n12,n23,n34,n41,ID);
1428   if(anElem) myScript->AddFace(ID,n1,n2,n3,n4,n12,n23,n34,n41);
1429   return anElem;
1430 }
1431
1432 //=======================================================================
1433 //function : AddFaceWithID
1434 //purpose  : 
1435 //=======================================================================
1436 SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
1437                                            const SMDS_MeshNode * n2,
1438                                            const SMDS_MeshNode * n3,
1439                                            const SMDS_MeshNode * n4,
1440                                            const SMDS_MeshNode * n12,
1441                                            const SMDS_MeshNode * n23,
1442                                            const SMDS_MeshNode * n34, 
1443                                            const SMDS_MeshNode * n41, 
1444                                            int ID)
1445 {
1446   return AddFaceWithID(n1->GetID(), n2->GetID(), n3->GetID(), n4->GetID(),
1447                        n12->GetID(), n23->GetID(), n34->GetID(), n41->GetID(),
1448                        ID);
1449 }
1450
1451
1452 //=======================================================================
1453 //function : AddVolume
1454 //purpose  : 
1455 //=======================================================================
1456 SMDS_MeshVolume* SMESHDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
1457                                          const SMDS_MeshNode * n2, 
1458                                          const SMDS_MeshNode * n3,
1459                                          const SMDS_MeshNode * n4,
1460                                          const SMDS_MeshNode * n12,
1461                                          const SMDS_MeshNode * n23,
1462                                          const SMDS_MeshNode * n31,
1463                                          const SMDS_MeshNode * n14, 
1464                                          const SMDS_MeshNode * n24,
1465                                          const SMDS_MeshNode * n34)
1466 {
1467   SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolume(n1,n2,n3,n4,n12,n23,n31,n14,n24,n34);
1468   if(anElem) myScript->AddVolume(anElem->GetID(), 
1469                                  n1->GetID(), n2->GetID(), n3->GetID(), n4->GetID(),
1470                                  n12->GetID(), n23->GetID(), n31->GetID(),
1471                                  n14->GetID(), n24->GetID(), n34->GetID());
1472   return anElem;
1473 }
1474
1475 //=======================================================================
1476 //function : AddVolumeWithID
1477 //purpose  : 
1478 //=======================================================================
1479 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4,
1480                                                int n12,int n23,int n31,
1481                                                int n14,int n24,int n34, int ID)
1482 {
1483   SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolumeWithID(n1,n2,n3,n4,n12,n23,
1484                                                        n31,n14,n24,n34,ID);
1485   if(anElem) myScript->AddVolume(ID,n1,n2,n3,n4,n12,n23,n31,n14,n24,n34);
1486   return anElem;
1487 }
1488         
1489 //=======================================================================
1490 //function : AddVolumeWithID
1491 //purpose  : 2d order tetrahedron of 10 nodes
1492 //=======================================================================
1493 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
1494                                                const SMDS_MeshNode * n2,
1495                                                const SMDS_MeshNode * n3,
1496                                                const SMDS_MeshNode * n4,
1497                                                const SMDS_MeshNode * n12,
1498                                                const SMDS_MeshNode * n23,
1499                                                const SMDS_MeshNode * n31,
1500                                                const SMDS_MeshNode * n14, 
1501                                                const SMDS_MeshNode * n24,
1502                                                const SMDS_MeshNode * n34,
1503                                                int ID)
1504 {
1505   return AddVolumeWithID(n1->GetID(), n2->GetID(), n3->GetID(), n4->GetID(),
1506                          n12->GetID(), n23->GetID(), n31->GetID(),
1507                          n14->GetID(), n24->GetID(), n34->GetID(), ID);
1508 }
1509
1510
1511 //=======================================================================
1512 //function : AddVolume
1513 //purpose  : 
1514 //=======================================================================
1515 SMDS_MeshVolume* SMESHDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
1516                                          const SMDS_MeshNode * n2, 
1517                                          const SMDS_MeshNode * n3,
1518                                          const SMDS_MeshNode * n4,
1519                                          const SMDS_MeshNode * n5, 
1520                                          const SMDS_MeshNode * n12,
1521                                          const SMDS_MeshNode * n23,
1522                                          const SMDS_MeshNode * n34,
1523                                          const SMDS_MeshNode * n41,
1524                                          const SMDS_MeshNode * n15, 
1525                                          const SMDS_MeshNode * n25,
1526                                          const SMDS_MeshNode * n35,
1527                                          const SMDS_MeshNode * n45)
1528 {
1529   SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolume(n1,n2,n3,n4,n5,n12,n23,n34,n41,
1530                                                  n15,n25,n35,n45);
1531   if(anElem)
1532     myScript->AddVolume(anElem->GetID(), n1->GetID(), n2->GetID(),
1533                         n3->GetID(), n4->GetID(), n5->GetID(),
1534                         n12->GetID(), n23->GetID(), n34->GetID(), n41->GetID(),
1535                         n15->GetID(), n25->GetID(), n35->GetID(), n45->GetID());
1536   return anElem;
1537 }
1538
1539 //=======================================================================
1540 //function : AddVolumeWithID
1541 //purpose  : 
1542 //=======================================================================
1543 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4, int n5,
1544                                                int n12,int n23,int n34,int n41,
1545                                                int n15,int n25,int n35,int n45, int ID)
1546 {
1547   SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolumeWithID(n1,n2,n3,n4,n5,
1548                                                        n12,n23,n34,n41,
1549                                                        n15,n25,n35,n45,ID);
1550   if(anElem) myScript->AddVolume(ID,n1,n2,n3,n4,n5,n12,n23,n34,n41,
1551                                  n15,n25,n35,n45);
1552   return anElem;
1553 }
1554         
1555 //=======================================================================
1556 //function : AddVolumeWithID
1557 //purpose  : 2d order pyramid of 13 nodes
1558 //=======================================================================
1559 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
1560                                                const SMDS_MeshNode * n2,
1561                                                const SMDS_MeshNode * n3,
1562                                                const SMDS_MeshNode * n4,
1563                                                const SMDS_MeshNode * n5, 
1564                                                const SMDS_MeshNode * n12,
1565                                                const SMDS_MeshNode * n23,
1566                                                const SMDS_MeshNode * n34,
1567                                                const SMDS_MeshNode * n41,
1568                                                const SMDS_MeshNode * n15, 
1569                                                const SMDS_MeshNode * n25,
1570                                                const SMDS_MeshNode * n35,
1571                                                const SMDS_MeshNode * n45,
1572                                                int ID)
1573 {
1574   return AddVolumeWithID(n1->GetID(), n2->GetID(), n3->GetID(),
1575                          n4->GetID(), n5->GetID(),
1576                          n12->GetID(), n23->GetID(), n34->GetID(), n41->GetID(),
1577                          n15->GetID(), n25->GetID(), n35->GetID(), n45->GetID(),
1578                          ID);
1579 }
1580
1581
1582 //=======================================================================
1583 //function : AddVolume
1584 //purpose  : 
1585 //=======================================================================
1586 SMDS_MeshVolume* SMESHDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
1587                                          const SMDS_MeshNode * n2, 
1588                                          const SMDS_MeshNode * n3,
1589                                          const SMDS_MeshNode * n4,
1590                                          const SMDS_MeshNode * n5, 
1591                                          const SMDS_MeshNode * n6, 
1592                                          const SMDS_MeshNode * n12,
1593                                          const SMDS_MeshNode * n23,
1594                                          const SMDS_MeshNode * n31, 
1595                                          const SMDS_MeshNode * n45,
1596                                          const SMDS_MeshNode * n56,
1597                                          const SMDS_MeshNode * n64, 
1598                                          const SMDS_MeshNode * n14,
1599                                          const SMDS_MeshNode * n25,
1600                                          const SMDS_MeshNode * n36)
1601 {
1602   SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolume(n1,n2,n3,n4,n5,n6,n12,n23,n31,
1603                                                  n45,n56,n64,n14,n25,n36);
1604   if(anElem)
1605     myScript->AddVolume(anElem->GetID(), n1->GetID(), n2->GetID(),
1606                         n3->GetID(), n4->GetID(), n5->GetID(), n6->GetID(),
1607                         n12->GetID(), n23->GetID(), n31->GetID(),
1608                         n45->GetID(), n56->GetID(), n64->GetID(),
1609                         n14->GetID(), n25->GetID(), n36->GetID());
1610   return anElem;
1611 }
1612
1613 //=======================================================================
1614 //function : AddVolumeWithID
1615 //purpose  : 
1616 //=======================================================================
1617 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(int n1, int n2, int n3,
1618                                                int n4, int n5, int n6,
1619                                                int n12,int n23,int n31,
1620                                                int n45,int n56,int n64,
1621                                                int n14,int n25,int n36, int ID)
1622 {
1623   SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolumeWithID(n1,n2,n3,n4,n5,n6,
1624                                                        n12,n23,n31,
1625                                                        n45,n56,n64,
1626                                                        n14,n25,n36,ID);
1627   if(anElem) myScript->AddVolume(ID,n1,n2,n3,n4,n5,n6,n12,n23,n31,
1628                                  n45,n56,n64,n14,n25,n36);
1629   return anElem;
1630 }
1631         
1632 //=======================================================================
1633 //function : AddVolumeWithID
1634 //purpose  : 2d order Pentahedron with 15 nodes
1635 //=======================================================================
1636 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
1637                                                const SMDS_MeshNode * n2,
1638                                                const SMDS_MeshNode * n3,
1639                                                const SMDS_MeshNode * n4,
1640                                                const SMDS_MeshNode * n5, 
1641                                                const SMDS_MeshNode * n6, 
1642                                                const SMDS_MeshNode * n12,
1643                                                const SMDS_MeshNode * n23,
1644                                                const SMDS_MeshNode * n31, 
1645                                                const SMDS_MeshNode * n45,
1646                                                const SMDS_MeshNode * n56,
1647                                                const SMDS_MeshNode * n64, 
1648                                                const SMDS_MeshNode * n14,
1649                                                const SMDS_MeshNode * n25,
1650                                                const SMDS_MeshNode * n36,
1651                                                int ID)
1652 {
1653   return AddVolumeWithID(n1->GetID(), n2->GetID(), n3->GetID(),
1654                          n4->GetID(), n5->GetID(), n6->GetID(),
1655                          n12->GetID(), n23->GetID(), n31->GetID(),
1656                          n45->GetID(), n56->GetID(), n64->GetID(),
1657                          n14->GetID(), n25->GetID(), n36->GetID(),
1658                          ID);
1659 }
1660
1661
1662 //=======================================================================
1663 //function : AddVolume
1664 //purpose  : 
1665 //=======================================================================
1666 SMDS_MeshVolume* SMESHDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
1667                                          const SMDS_MeshNode * n2, 
1668                                          const SMDS_MeshNode * n3,
1669                                          const SMDS_MeshNode * n4,
1670                                          const SMDS_MeshNode * n5, 
1671                                          const SMDS_MeshNode * n6, 
1672                                          const SMDS_MeshNode * n7,
1673                                          const SMDS_MeshNode * n8, 
1674                                          const SMDS_MeshNode * n12,
1675                                          const SMDS_MeshNode * n23,
1676                                          const SMDS_MeshNode * n34,
1677                                          const SMDS_MeshNode * n41, 
1678                                          const SMDS_MeshNode * n56,
1679                                          const SMDS_MeshNode * n67,
1680                                          const SMDS_MeshNode * n78,
1681                                          const SMDS_MeshNode * n85, 
1682                                          const SMDS_MeshNode * n15,
1683                                          const SMDS_MeshNode * n26,
1684                                          const SMDS_MeshNode * n37,
1685                                          const SMDS_MeshNode * n48)
1686 {
1687   SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolume(n1,n2,n3,n4,n5,n6,n7,n8,
1688                                                  n12,n23,n34,n41,
1689                                                  n56,n67,n78,n85,
1690                                                  n15,n26,n37,n48);
1691   if(anElem)
1692     myScript->AddVolume(anElem->GetID(), n1->GetID(), n2->GetID(),
1693                         n3->GetID(), n4->GetID(), n5->GetID(),
1694                         n6->GetID(), n7->GetID(), n8->GetID(),
1695                         n12->GetID(), n23->GetID(), n34->GetID(), n41->GetID(),
1696                         n56->GetID(), n67->GetID(), n78->GetID(), n85->GetID(),
1697                         n15->GetID(), n26->GetID(), n37->GetID(), n48->GetID());
1698   return anElem;
1699 }
1700
1701 //=======================================================================
1702 //function : AddVolumeWithID
1703 //purpose  : 
1704 //=======================================================================
1705 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4,
1706                                                int n5, int n6, int n7, int n8,
1707                                                int n12,int n23,int n34,int n41,
1708                                                int n56,int n67,int n78,int n85,
1709                                                int n15,int n26,int n37,int n48, int ID)
1710 {
1711   SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolumeWithID(n1,n2,n3,n4,n5,n6,n7,n8,
1712                                                        n12,n23,n34,n41,
1713                                                        n56,n67,n78,n85,
1714                                                        n15,n26,n37,n48,ID);
1715   if(anElem) myScript->AddVolume(ID,n1,n2,n3,n4,n5,n6,n7,n8,n12,n23,n34,n41,
1716                                  n56,n67,n78,n85,n15,n26,n37,n48);
1717   return anElem;
1718 }
1719         
1720 //=======================================================================
1721 //function : AddVolumeWithID
1722 //purpose  : 2d order Hexahedrons with 20 nodes
1723 //=======================================================================
1724 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
1725                                                const SMDS_MeshNode * n2,
1726                                                const SMDS_MeshNode * n3,
1727                                                const SMDS_MeshNode * n4,
1728                                                const SMDS_MeshNode * n5, 
1729                                                const SMDS_MeshNode * n6, 
1730                                                const SMDS_MeshNode * n7,
1731                                                const SMDS_MeshNode * n8, 
1732                                                const SMDS_MeshNode * n12,
1733                                                const SMDS_MeshNode * n23,
1734                                                const SMDS_MeshNode * n34,
1735                                                const SMDS_MeshNode * n41, 
1736                                                const SMDS_MeshNode * n56,
1737                                                const SMDS_MeshNode * n67,
1738                                                const SMDS_MeshNode * n78,
1739                                                const SMDS_MeshNode * n85, 
1740                                                const SMDS_MeshNode * n15,
1741                                                const SMDS_MeshNode * n26,
1742                                                const SMDS_MeshNode * n37,
1743                                                const SMDS_MeshNode * n48,
1744                                                int ID)
1745 {
1746   return AddVolumeWithID(n1->GetID(), n2->GetID(), n3->GetID(), n4->GetID(),
1747                          n5->GetID(), n6->GetID(), n7->GetID(), n8->GetID(),
1748                          n12->GetID(), n23->GetID(), n34->GetID(), n41->GetID(),
1749                          n56->GetID(), n67->GetID(), n78->GetID(), n85->GetID(),
1750                          n15->GetID(), n26->GetID(), n37->GetID(), n48->GetID(),
1751                          ID);
1752 }
1753
1754