Salome HOME
correct previous integration (Porting to Python 2.6)
[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   if (elt->GetType() == SMDSAbs_Node) {
820     RemoveFreeNode( static_cast<const SMDS_MeshNode*>(elt), subMesh);
821     return;
822   }
823
824   if (hasConstructionEdges() || hasConstructionFaces())
825     // this methods is only for meshes without descendants
826     return;
827
828   myScript->RemoveElement(elt->GetID());
829
830   // Rm from group
831   // Node can belong to several groups
832   if ( fromGroups && !myGroups.empty() ) {
833     set<SMESHDS_GroupBase*>::iterator GrIt = myGroups.begin();
834     for (; GrIt != myGroups.end(); GrIt++) {
835       SMESHDS_Group* group = dynamic_cast<SMESHDS_Group*>(*GrIt);
836       if (group && !group->IsEmpty())
837         group->SMDSGroup().Remove(elt);
838     }
839   }
840
841   // Rm from sub-mesh
842   // Element should belong to only one sub-mesh
843   if( subMesh )
844     subMesh->RemoveElement(elt, /*deleted=*/false);
845
846   SMDS_Mesh::RemoveFreeElement(elt);
847 }
848
849 //================================================================================
850 /*!
851  * \brief Remove all data from the mesh
852  */
853 //================================================================================
854
855 void SMESHDS_Mesh::ClearMesh()
856 {
857   myScript->ClearMesh();
858   SMDS_Mesh::Clear();
859
860   // clear submeshes
861   map<int,SMESHDS_SubMesh*>::iterator sub, subEnd = myShapeIndexToSubMesh.end();
862   for ( sub = myShapeIndexToSubMesh.begin(); sub != subEnd; ++sub )
863     sub->second->Clear();
864
865   // clear groups
866   TGroups::iterator group, groupEnd = myGroups.end();
867   for ( group = myGroups.begin(); group != groupEnd; ++group ) {
868     if ( SMESHDS_Group* g = dynamic_cast<SMESHDS_Group*>(*group)) {
869       SMDSAbs_ElementType groupType = g->GetType();
870       g->Clear();
871       g->SetType( groupType );
872     }
873   }
874 }
875
876 //================================================================================
877 /*!
878  * \brief return submesh by shape
879   * \param shape - the subshape
880   * \retval SMESHDS_SubMesh* - the found submesh
881   *
882  * search of submeshes is optimized
883  */
884 //================================================================================
885
886 SMESHDS_SubMesh* SMESHDS_Mesh::getSubmesh( const TopoDS_Shape & shape )
887 {
888   if ( shape.IsNull() )
889     return 0;
890
891   if ( !myCurSubShape.IsNull() && shape.IsSame( myCurSubShape ))
892     return myCurSubMesh;
893
894   getSubmesh( ShapeToIndex( shape ));
895   myCurSubShape = shape;
896   return myCurSubMesh;
897 }
898
899 //================================================================================
900 /*!
901  * \brief return submesh by subshape index
902   * \param Index - the subshape index
903   * \retval SMESHDS_SubMesh* - the found submesh
904  * search of submeshes is optimized
905  */
906 //================================================================================
907
908 SMESHDS_SubMesh* SMESHDS_Mesh::getSubmesh( const int Index )
909 {
910   //Update or build submesh
911   if ( Index != myCurSubID ) {
912     map<int,SMESHDS_SubMesh*>::iterator it = myShapeIndexToSubMesh.find( Index );
913     if ( it == myShapeIndexToSubMesh.end() )
914       it = myShapeIndexToSubMesh.insert( make_pair(Index, new SMESHDS_SubMesh() )).first;
915     myCurSubMesh = it->second;
916     myCurSubID = Index;
917     myCurSubShape.Nullify(); // myCurSubShape no more corresponds to submesh
918   }
919   return myCurSubMesh;
920 }
921
922 //================================================================================
923 /*!
924  * \brief Add element or node to submesh
925   * \param elem - element to add
926   * \param subMesh - submesh to be filled in
927  */
928 //================================================================================
929
930 bool SMESHDS_Mesh::add(const SMDS_MeshElement* elem, SMESHDS_SubMesh* subMesh )
931 {
932   if ( elem && subMesh ) {
933     if ( elem->GetType() == SMDSAbs_Node )
934       subMesh->AddNode( static_cast<const SMDS_MeshNode* >( elem ));
935     else
936       subMesh->AddElement( elem );
937     return true;
938   }
939   return false;
940 }
941
942 namespace {
943
944   //================================================================================
945   /*!
946    * \brief Creates a node position in volume
947    */
948   //================================================================================
949
950   inline SMDS_PositionPtr volumePosition(int volId)
951   {
952     SMDS_SpacePosition* pos = new SMDS_SpacePosition();
953     pos->SetShapeId( volId );
954     return SMDS_PositionPtr(pos);
955   }
956 }
957
958 //=======================================================================
959 //function : SetNodeOnVolume
960 //purpose  : 
961 //=======================================================================
962 void SMESHDS_Mesh::SetNodeInVolume(SMDS_MeshNode *      aNode,
963                                    const TopoDS_Shell & S)
964 {
965   if ( add( aNode, getSubmesh(S) ))
966     aNode->SetPosition ( volumePosition( myCurSubID ));
967 }
968 //=======================================================================
969 //function : SetNodeOnVolume
970 //purpose  : 
971 //=======================================================================
972 void SMESHDS_Mesh::SetNodeInVolume(SMDS_MeshNode *      aNode,
973                                    const TopoDS_Solid & S)
974 {
975   if ( add( aNode, getSubmesh(S) ))
976     aNode->SetPosition ( volumePosition( myCurSubID ));
977 }
978
979 //=======================================================================
980 //function : SetNodeOnFace
981 //purpose  : 
982 //=======================================================================
983 void SMESHDS_Mesh::SetNodeOnFace(SMDS_MeshNode *     aNode,
984                                  const TopoDS_Face & S,
985                                  double              u,
986                                  double              v)
987 {
988   if ( add( aNode, getSubmesh(S) ))
989     aNode->SetPosition(SMDS_PositionPtr(new SMDS_FacePosition(myCurSubID, u, v)));
990 }
991
992 //=======================================================================
993 //function : SetNodeOnEdge
994 //purpose  : 
995 //=======================================================================
996 void SMESHDS_Mesh::SetNodeOnEdge(SMDS_MeshNode *     aNode,
997                                  const TopoDS_Edge & S,
998                                  double              u)
999 {
1000   if ( add( aNode, getSubmesh(S) ))
1001     aNode->SetPosition(SMDS_PositionPtr(new SMDS_EdgePosition(myCurSubID, u)));
1002 }
1003
1004 //=======================================================================
1005 //function : SetNodeOnVertex
1006 //purpose  : 
1007 //=======================================================================
1008 void SMESHDS_Mesh::SetNodeOnVertex(SMDS_MeshNode *       aNode,
1009                                    const TopoDS_Vertex & S)
1010 {
1011   if ( add( aNode, getSubmesh(S) ))
1012     aNode->SetPosition(SMDS_PositionPtr(new SMDS_VertexPosition(myCurSubID)));
1013 }
1014
1015 //=======================================================================
1016 //function : UnSetNodeOnShape
1017 //purpose  : 
1018 //=======================================================================
1019 void SMESHDS_Mesh::UnSetNodeOnShape(const SMDS_MeshNode* aNode)
1020 {
1021   if ( aNode && aNode->GetPosition() ) {
1022     map<int,SMESHDS_SubMesh*>::iterator it =
1023       myShapeIndexToSubMesh.find( aNode->GetPosition()->GetShapeId() );
1024     if ( it != myShapeIndexToSubMesh.end() )
1025       it->second->RemoveNode( aNode, /*deleted=*/false );
1026   }
1027 }
1028
1029 //=======================================================================
1030 //function : SetMeshElementOnShape
1031 //purpose  : 
1032 //=======================================================================
1033 void SMESHDS_Mesh::SetMeshElementOnShape(const SMDS_MeshElement * anElement,
1034                                          const TopoDS_Shape &     S)
1035 {
1036   add( anElement, getSubmesh(S) );
1037 }
1038
1039 //=======================================================================
1040 //function : UnSetMeshElementOnShape
1041 //purpose  : 
1042 //=======================================================================
1043 void SMESHDS_Mesh::UnSetMeshElementOnShape(const SMDS_MeshElement * elem,
1044                                            const TopoDS_Shape &     S)
1045 {
1046   int Index = myIndexToShape.FindIndex(S);
1047
1048   map<int,SMESHDS_SubMesh*>::iterator it = myShapeIndexToSubMesh.find( Index );
1049   if ( it != myShapeIndexToSubMesh.end() )
1050     if ( elem->GetType() == SMDSAbs_Node )
1051       it->second->RemoveNode( static_cast<const SMDS_MeshNode* >( elem ), /*deleted=*/false );
1052     else
1053       it->second->RemoveElement( elem, /*deleted=*/false );
1054 }
1055
1056 //=======================================================================
1057 //function : ShapeToMesh
1058 //purpose  : 
1059 //=======================================================================
1060 TopoDS_Shape SMESHDS_Mesh::ShapeToMesh() const
1061 {
1062         return myShape;
1063 }
1064
1065 //=======================================================================
1066 //function : IsGroupOfSubShapes
1067 //purpose  : return true if at least one subshape of theShape is a subshape
1068 //           of myShape or theShape == myShape
1069 //=======================================================================
1070
1071 bool SMESHDS_Mesh::IsGroupOfSubShapes (const TopoDS_Shape& theShape) const
1072 {
1073   if ( myShape.IsSame( theShape ))
1074     return true;
1075
1076   for ( TopoDS_Iterator it( theShape ); it.More(); it.Next() ) {
1077     if (myIndexToShape.Contains( it.Value() ) ||
1078         IsGroupOfSubShapes( it.Value() ))
1079       return true;
1080   }
1081   
1082   return false;
1083 }
1084
1085 ///////////////////////////////////////////////////////////////////////////////
1086 /// Return the sub mesh linked to the a given TopoDS_Shape or NULL if the given
1087 /// TopoDS_Shape is unknown
1088 ///////////////////////////////////////////////////////////////////////////////
1089 SMESHDS_SubMesh * SMESHDS_Mesh::MeshElements(const TopoDS_Shape & S) const
1090 {
1091   int Index = ShapeToIndex(S);
1092   TShapeIndexToSubMesh::const_iterator anIter = myShapeIndexToSubMesh.find(Index);
1093   if (anIter != myShapeIndexToSubMesh.end())
1094     return anIter->second;
1095   else
1096     return NULL;
1097 }
1098
1099 ///////////////////////////////////////////////////////////////////////////////
1100 /// Return the sub mesh by Id of shape it is linked to
1101 ///////////////////////////////////////////////////////////////////////////////
1102 SMESHDS_SubMesh * SMESHDS_Mesh::MeshElements(const int Index)
1103 {
1104   TShapeIndexToSubMesh::const_iterator anIter = myShapeIndexToSubMesh.find(Index);
1105   if (anIter != myShapeIndexToSubMesh.end())
1106     return anIter->second;
1107   else
1108     return NULL;
1109 }
1110
1111 //=======================================================================
1112 //function : SubMeshIndices
1113 //purpose  : 
1114 //=======================================================================
1115 list<int> SMESHDS_Mesh::SubMeshIndices()
1116 {
1117   list<int> anIndices;
1118   std::map<int,SMESHDS_SubMesh*>::iterator anIter = myShapeIndexToSubMesh.begin();
1119   for (; anIter != myShapeIndexToSubMesh.end(); anIter++) {
1120     anIndices.push_back((*anIter).first);
1121   }
1122   return anIndices;
1123 }
1124
1125 //=======================================================================
1126 //function : GetHypothesis
1127 //purpose  : 
1128 //=======================================================================
1129
1130 const list<const SMESHDS_Hypothesis*>&
1131 SMESHDS_Mesh::GetHypothesis(const TopoDS_Shape & S) const
1132 {
1133   if ( myShapeToHypothesis.IsBound( S.Oriented(TopAbs_FORWARD) ) ) // ignore orientation of S
1134      return myShapeToHypothesis.Find( S.Oriented(TopAbs_FORWARD) );
1135
1136   static list<const SMESHDS_Hypothesis*> empty;
1137   return empty;
1138 }
1139
1140 //=======================================================================
1141 //function : GetScript
1142 //purpose  : 
1143 //=======================================================================
1144 SMESHDS_Script* SMESHDS_Mesh::GetScript()
1145 {
1146         return myScript;
1147 }
1148
1149 //=======================================================================
1150 //function : ClearScript
1151 //purpose  : 
1152 //=======================================================================
1153 void SMESHDS_Mesh::ClearScript()
1154 {
1155         myScript->Clear();
1156 }
1157
1158 //=======================================================================
1159 //function : HasMeshElements
1160 //purpose  : 
1161 //=======================================================================
1162 bool SMESHDS_Mesh::HasMeshElements(const TopoDS_Shape & S)
1163 {
1164         if (myShape.IsNull()) MESSAGE("myShape is NULL");
1165         int Index = myIndexToShape.FindIndex(S);
1166         return myShapeIndexToSubMesh.find(Index)!=myShapeIndexToSubMesh.end();
1167 }
1168
1169 //=======================================================================
1170 //function : HasHypothesis
1171 //purpose  : 
1172 //=======================================================================
1173 bool SMESHDS_Mesh::HasHypothesis(const TopoDS_Shape & S)
1174 {
1175   return myShapeToHypothesis.IsBound(S.Oriented(TopAbs_FORWARD));
1176 }
1177
1178 //=======================================================================
1179 //function : NewSubMesh 
1180 //purpose  : 
1181 //=======================================================================
1182 SMESHDS_SubMesh * SMESHDS_Mesh::NewSubMesh(int Index)
1183 {
1184   SMESHDS_SubMesh* SM = 0;
1185   TShapeIndexToSubMesh::iterator anIter = myShapeIndexToSubMesh.find(Index);
1186   if (anIter == myShapeIndexToSubMesh.end())
1187   {
1188     SM = new SMESHDS_SubMesh();
1189     myShapeIndexToSubMesh[Index]=SM;
1190   }
1191   else
1192     SM = anIter->second;
1193   return SM;
1194 }
1195
1196 //=======================================================================
1197 //function : AddCompoundSubmesh
1198 //purpose  : 
1199 //=======================================================================
1200
1201 int SMESHDS_Mesh::AddCompoundSubmesh(const TopoDS_Shape& S,
1202                                      TopAbs_ShapeEnum    type)
1203 {
1204   int aMainIndex = 0;
1205   if ( IsGroupOfSubShapes( S ) || (S.ShapeType() == TopAbs_VERTEX && myIndexToShape.Contains(S)) )
1206   {
1207     aMainIndex = myIndexToShape.Add( S );
1208     bool all = ( type == TopAbs_SHAPE );
1209     if ( all ) // corresponding simple submesh may exist
1210       aMainIndex = -aMainIndex;
1211     //MESSAGE("AddCompoundSubmesh index = " << aMainIndex );
1212     SMESHDS_SubMesh * aNewSub = NewSubMesh( aMainIndex );
1213     if ( !aNewSub->IsComplexSubmesh() ) // is empty
1214     {
1215       int shapeType = Max( TopAbs_SOLID, all ? myShape.ShapeType() : type );
1216       int typeLimit = all ? TopAbs_VERTEX : type;
1217       for ( ; shapeType <= typeLimit; shapeType++ )
1218       {
1219         TopExp_Explorer exp( S, TopAbs_ShapeEnum( shapeType ));
1220         for ( ; exp.More(); exp.Next() )
1221         {
1222           int index = myIndexToShape.FindIndex( exp.Current() );
1223           if ( index )
1224             aNewSub->AddSubMesh( NewSubMesh( index ));
1225         }
1226       }
1227     }
1228   }
1229   return aMainIndex;
1230 }
1231
1232 //=======================================================================
1233 //function : IndexToShape
1234 //purpose  : 
1235 //=======================================================================
1236 const TopoDS_Shape& SMESHDS_Mesh::IndexToShape(int ShapeIndex) const
1237 {
1238         return myIndexToShape.FindKey(ShapeIndex);
1239 }
1240
1241 //=======================================================================
1242 //function : ShapeToIndex
1243 //purpose  : 
1244 //=======================================================================
1245 int SMESHDS_Mesh::ShapeToIndex(const TopoDS_Shape & S) const
1246 {
1247   if (myShape.IsNull())
1248     MESSAGE("myShape is NULL");
1249
1250   int index = myIndexToShape.FindIndex(S);
1251   
1252   return index;
1253 }
1254
1255 //=======================================================================
1256 //function : SetNodeOnVolume
1257 //purpose  : 
1258 //=======================================================================
1259 void SMESHDS_Mesh::SetNodeInVolume(const SMDS_MeshNode* aNode, int Index)
1260 {
1261   if ( add( aNode, getSubmesh( Index )))
1262     ((SMDS_MeshNode*) aNode)->SetPosition( volumePosition( Index ));
1263 }
1264
1265 //=======================================================================
1266 //function : SetNodeOnFace
1267 //purpose  : 
1268 //=======================================================================
1269 void SMESHDS_Mesh::SetNodeOnFace(SMDS_MeshNode* aNode, int Index, double u, double v)
1270 {
1271   //Set Position on Node
1272   if ( add( aNode, getSubmesh( Index )))
1273     aNode->SetPosition(SMDS_PositionPtr(new SMDS_FacePosition(Index, u, v)));
1274 }
1275
1276 //=======================================================================
1277 //function : SetNodeOnEdge
1278 //purpose  : 
1279 //=======================================================================
1280 void SMESHDS_Mesh::SetNodeOnEdge(SMDS_MeshNode* aNode,
1281                                  int            Index,
1282                                  double         u)
1283 {
1284   //Set Position on Node
1285   if ( add( aNode, getSubmesh( Index )))
1286     aNode->SetPosition(SMDS_PositionPtr(new SMDS_EdgePosition(Index, u)));
1287 }
1288
1289 //=======================================================================
1290 //function : SetNodeOnVertex
1291 //purpose  : 
1292 //=======================================================================
1293 void SMESHDS_Mesh::SetNodeOnVertex(SMDS_MeshNode* aNode, int Index)
1294 {
1295   //Set Position on Node
1296   if ( add( aNode, getSubmesh( Index )))
1297     aNode->SetPosition(SMDS_PositionPtr(new SMDS_VertexPosition(Index)));
1298 }
1299
1300 //=======================================================================
1301 //function : SetMeshElementOnShape
1302 //purpose  : 
1303 //=======================================================================
1304 void SMESHDS_Mesh::SetMeshElementOnShape(const SMDS_MeshElement* anElement,
1305                                          int                     Index)
1306 {
1307   add( anElement, getSubmesh( Index ));
1308 }
1309
1310 //=======================================================================
1311 //function : ~SMESHDS_Mesh
1312 //purpose  : 
1313 //=======================================================================
1314 SMESHDS_Mesh::~SMESHDS_Mesh()
1315 {
1316   // myScript
1317   delete myScript;
1318   // submeshes
1319   TShapeIndexToSubMesh::iterator i_sm = myShapeIndexToSubMesh.begin();
1320   for ( ; i_sm != myShapeIndexToSubMesh.end(); ++i_sm )
1321     delete i_sm->second;
1322 }
1323
1324
1325 //********************************************************************
1326 //********************************************************************
1327 //********                                                   *********
1328 //*****       Methods for addition of quadratic elements        ******
1329 //********                                                   *********
1330 //********************************************************************
1331 //********************************************************************
1332
1333 //=======================================================================
1334 //function : AddEdgeWithID
1335 //purpose  : 
1336 //=======================================================================
1337 SMDS_MeshEdge* SMESHDS_Mesh::AddEdgeWithID(int n1, int n2, int n12, int ID) 
1338 {
1339   SMDS_MeshEdge* anElem = SMDS_Mesh::AddEdgeWithID(n1,n2,n12,ID);
1340   if(anElem) myScript->AddEdge(ID,n1,n2,n12);
1341   return anElem;
1342 }
1343
1344 //=======================================================================
1345 //function : AddEdge
1346 //purpose  : 
1347 //=======================================================================
1348 SMDS_MeshEdge* SMESHDS_Mesh::AddEdge(const SMDS_MeshNode* n1,
1349                                      const SMDS_MeshNode* n2,
1350                                      const SMDS_MeshNode* n12)
1351 {
1352   SMDS_MeshEdge* anElem = SMDS_Mesh::AddEdge(n1,n2,n12);
1353   if(anElem) myScript->AddEdge(anElem->GetID(), 
1354                                n1->GetID(), 
1355                                n2->GetID(),
1356                                n12->GetID());
1357   return anElem;
1358 }
1359
1360 //=======================================================================
1361 //function : AddEdgeWithID
1362 //purpose  : 
1363 //=======================================================================
1364 SMDS_MeshEdge* SMESHDS_Mesh::AddEdgeWithID(const SMDS_MeshNode * n1,
1365                                            const SMDS_MeshNode * n2, 
1366                                            const SMDS_MeshNode * n12, 
1367                                            int ID)
1368 {
1369   return AddEdgeWithID(n1->GetID(),
1370                        n2->GetID(),
1371                        n12->GetID(),
1372                        ID);
1373 }
1374
1375
1376 //=======================================================================
1377 //function : AddFace
1378 //purpose  : 
1379 //=======================================================================
1380 SMDS_MeshFace* SMESHDS_Mesh::AddFace(const SMDS_MeshNode * n1,
1381                                      const SMDS_MeshNode * n2,
1382                                      const SMDS_MeshNode * n3,
1383                                      const SMDS_MeshNode * n12,
1384                                      const SMDS_MeshNode * n23,
1385                                      const SMDS_MeshNode * n31)
1386 {
1387   SMDS_MeshFace *anElem = SMDS_Mesh::AddFace(n1,n2,n3,n12,n23,n31);
1388   if(anElem) myScript->AddFace(anElem->GetID(), 
1389                                n1->GetID(), n2->GetID(), n3->GetID(),
1390                                n12->GetID(), n23->GetID(), n31->GetID());
1391   return anElem;
1392 }
1393
1394 //=======================================================================
1395 //function : AddFaceWithID
1396 //purpose  : 
1397 //=======================================================================
1398 SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(int n1, int n2, int n3,
1399                                            int n12,int n23,int n31, int ID)
1400 {
1401   SMDS_MeshFace *anElem = SMDS_Mesh::AddFaceWithID(n1,n2,n3,n12,n23,n31,ID);
1402   if(anElem) myScript->AddFace(ID,n1,n2,n3,n12,n23,n31);
1403   return anElem;
1404 }
1405
1406 //=======================================================================
1407 //function : AddFaceWithID
1408 //purpose  : 
1409 //=======================================================================
1410 SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
1411                                            const SMDS_MeshNode * n2,
1412                                            const SMDS_MeshNode * n3,
1413                                            const SMDS_MeshNode * n12,
1414                                            const SMDS_MeshNode * n23,
1415                                            const SMDS_MeshNode * n31, 
1416                                            int ID)
1417 {
1418   return AddFaceWithID(n1->GetID(), n2->GetID(), n3->GetID(),
1419                        n12->GetID(), n23->GetID(), n31->GetID(),
1420                        ID);
1421 }
1422
1423
1424 //=======================================================================
1425 //function : AddFace
1426 //purpose  : 
1427 //=======================================================================
1428 SMDS_MeshFace* SMESHDS_Mesh::AddFace(const SMDS_MeshNode * n1,
1429                                      const SMDS_MeshNode * n2,
1430                                      const SMDS_MeshNode * n3,
1431                                      const SMDS_MeshNode * n4,
1432                                      const SMDS_MeshNode * n12,
1433                                      const SMDS_MeshNode * n23,
1434                                      const SMDS_MeshNode * n34,
1435                                      const SMDS_MeshNode * n41)
1436 {
1437   SMDS_MeshFace *anElem = SMDS_Mesh::AddFace(n1,n2,n3,n4,n12,n23,n34,n41);
1438   if(anElem) myScript->AddFace(anElem->GetID(), 
1439                                n1->GetID(), n2->GetID(), n3->GetID(), n4->GetID(),
1440                                n12->GetID(), n23->GetID(), n34->GetID(), n41->GetID());
1441   return anElem;
1442 }
1443
1444 //=======================================================================
1445 //function : AddFaceWithID
1446 //purpose  : 
1447 //=======================================================================
1448 SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(int n1, int n2, int n3, int n4,
1449                                            int n12,int n23,int n34,int n41, int ID)
1450 {
1451   SMDS_MeshFace *anElem = SMDS_Mesh::AddFaceWithID(n1,n2,n3,n4,n12,n23,n34,n41,ID);
1452   if(anElem) myScript->AddFace(ID,n1,n2,n3,n4,n12,n23,n34,n41);
1453   return anElem;
1454 }
1455
1456 //=======================================================================
1457 //function : AddFaceWithID
1458 //purpose  : 
1459 //=======================================================================
1460 SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
1461                                            const SMDS_MeshNode * n2,
1462                                            const SMDS_MeshNode * n3,
1463                                            const SMDS_MeshNode * n4,
1464                                            const SMDS_MeshNode * n12,
1465                                            const SMDS_MeshNode * n23,
1466                                            const SMDS_MeshNode * n34, 
1467                                            const SMDS_MeshNode * n41, 
1468                                            int ID)
1469 {
1470   return AddFaceWithID(n1->GetID(), n2->GetID(), n3->GetID(), n4->GetID(),
1471                        n12->GetID(), n23->GetID(), n34->GetID(), n41->GetID(),
1472                        ID);
1473 }
1474
1475
1476 //=======================================================================
1477 //function : AddVolume
1478 //purpose  : 
1479 //=======================================================================
1480 SMDS_MeshVolume* SMESHDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
1481                                          const SMDS_MeshNode * n2, 
1482                                          const SMDS_MeshNode * n3,
1483                                          const SMDS_MeshNode * n4,
1484                                          const SMDS_MeshNode * n12,
1485                                          const SMDS_MeshNode * n23,
1486                                          const SMDS_MeshNode * n31,
1487                                          const SMDS_MeshNode * n14, 
1488                                          const SMDS_MeshNode * n24,
1489                                          const SMDS_MeshNode * n34)
1490 {
1491   SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolume(n1,n2,n3,n4,n12,n23,n31,n14,n24,n34);
1492   if(anElem) myScript->AddVolume(anElem->GetID(), 
1493                                  n1->GetID(), n2->GetID(), n3->GetID(), n4->GetID(),
1494                                  n12->GetID(), n23->GetID(), n31->GetID(),
1495                                  n14->GetID(), n24->GetID(), n34->GetID());
1496   return anElem;
1497 }
1498
1499 //=======================================================================
1500 //function : AddVolumeWithID
1501 //purpose  : 
1502 //=======================================================================
1503 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4,
1504                                                int n12,int n23,int n31,
1505                                                int n14,int n24,int n34, int ID)
1506 {
1507   SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolumeWithID(n1,n2,n3,n4,n12,n23,
1508                                                        n31,n14,n24,n34,ID);
1509   if(anElem) myScript->AddVolume(ID,n1,n2,n3,n4,n12,n23,n31,n14,n24,n34);
1510   return anElem;
1511 }
1512         
1513 //=======================================================================
1514 //function : AddVolumeWithID
1515 //purpose  : 2d order tetrahedron of 10 nodes
1516 //=======================================================================
1517 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
1518                                                const SMDS_MeshNode * n2,
1519                                                const SMDS_MeshNode * n3,
1520                                                const SMDS_MeshNode * n4,
1521                                                const SMDS_MeshNode * n12,
1522                                                const SMDS_MeshNode * n23,
1523                                                const SMDS_MeshNode * n31,
1524                                                const SMDS_MeshNode * n14, 
1525                                                const SMDS_MeshNode * n24,
1526                                                const SMDS_MeshNode * n34,
1527                                                int ID)
1528 {
1529   return AddVolumeWithID(n1->GetID(), n2->GetID(), n3->GetID(), n4->GetID(),
1530                          n12->GetID(), n23->GetID(), n31->GetID(),
1531                          n14->GetID(), n24->GetID(), n34->GetID(), ID);
1532 }
1533
1534
1535 //=======================================================================
1536 //function : AddVolume
1537 //purpose  : 
1538 //=======================================================================
1539 SMDS_MeshVolume* SMESHDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
1540                                          const SMDS_MeshNode * n2, 
1541                                          const SMDS_MeshNode * n3,
1542                                          const SMDS_MeshNode * n4,
1543                                          const SMDS_MeshNode * n5, 
1544                                          const SMDS_MeshNode * n12,
1545                                          const SMDS_MeshNode * n23,
1546                                          const SMDS_MeshNode * n34,
1547                                          const SMDS_MeshNode * n41,
1548                                          const SMDS_MeshNode * n15, 
1549                                          const SMDS_MeshNode * n25,
1550                                          const SMDS_MeshNode * n35,
1551                                          const SMDS_MeshNode * n45)
1552 {
1553   SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolume(n1,n2,n3,n4,n5,n12,n23,n34,n41,
1554                                                  n15,n25,n35,n45);
1555   if(anElem)
1556     myScript->AddVolume(anElem->GetID(), n1->GetID(), n2->GetID(),
1557                         n3->GetID(), n4->GetID(), n5->GetID(),
1558                         n12->GetID(), n23->GetID(), n34->GetID(), n41->GetID(),
1559                         n15->GetID(), n25->GetID(), n35->GetID(), n45->GetID());
1560   return anElem;
1561 }
1562
1563 //=======================================================================
1564 //function : AddVolumeWithID
1565 //purpose  : 
1566 //=======================================================================
1567 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4, int n5,
1568                                                int n12,int n23,int n34,int n41,
1569                                                int n15,int n25,int n35,int n45, int ID)
1570 {
1571   SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolumeWithID(n1,n2,n3,n4,n5,
1572                                                        n12,n23,n34,n41,
1573                                                        n15,n25,n35,n45,ID);
1574   if(anElem) myScript->AddVolume(ID,n1,n2,n3,n4,n5,n12,n23,n34,n41,
1575                                  n15,n25,n35,n45);
1576   return anElem;
1577 }
1578         
1579 //=======================================================================
1580 //function : AddVolumeWithID
1581 //purpose  : 2d order pyramid of 13 nodes
1582 //=======================================================================
1583 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
1584                                                const SMDS_MeshNode * n2,
1585                                                const SMDS_MeshNode * n3,
1586                                                const SMDS_MeshNode * n4,
1587                                                const SMDS_MeshNode * n5, 
1588                                                const SMDS_MeshNode * n12,
1589                                                const SMDS_MeshNode * n23,
1590                                                const SMDS_MeshNode * n34,
1591                                                const SMDS_MeshNode * n41,
1592                                                const SMDS_MeshNode * n15, 
1593                                                const SMDS_MeshNode * n25,
1594                                                const SMDS_MeshNode * n35,
1595                                                const SMDS_MeshNode * n45,
1596                                                int ID)
1597 {
1598   return AddVolumeWithID(n1->GetID(), n2->GetID(), n3->GetID(),
1599                          n4->GetID(), n5->GetID(),
1600                          n12->GetID(), n23->GetID(), n34->GetID(), n41->GetID(),
1601                          n15->GetID(), n25->GetID(), n35->GetID(), n45->GetID(),
1602                          ID);
1603 }
1604
1605
1606 //=======================================================================
1607 //function : AddVolume
1608 //purpose  : 
1609 //=======================================================================
1610 SMDS_MeshVolume* SMESHDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
1611                                          const SMDS_MeshNode * n2, 
1612                                          const SMDS_MeshNode * n3,
1613                                          const SMDS_MeshNode * n4,
1614                                          const SMDS_MeshNode * n5, 
1615                                          const SMDS_MeshNode * n6, 
1616                                          const SMDS_MeshNode * n12,
1617                                          const SMDS_MeshNode * n23,
1618                                          const SMDS_MeshNode * n31, 
1619                                          const SMDS_MeshNode * n45,
1620                                          const SMDS_MeshNode * n56,
1621                                          const SMDS_MeshNode * n64, 
1622                                          const SMDS_MeshNode * n14,
1623                                          const SMDS_MeshNode * n25,
1624                                          const SMDS_MeshNode * n36)
1625 {
1626   SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolume(n1,n2,n3,n4,n5,n6,n12,n23,n31,
1627                                                  n45,n56,n64,n14,n25,n36);
1628   if(anElem)
1629     myScript->AddVolume(anElem->GetID(), n1->GetID(), n2->GetID(),
1630                         n3->GetID(), n4->GetID(), n5->GetID(), n6->GetID(),
1631                         n12->GetID(), n23->GetID(), n31->GetID(),
1632                         n45->GetID(), n56->GetID(), n64->GetID(),
1633                         n14->GetID(), n25->GetID(), n36->GetID());
1634   return anElem;
1635 }
1636
1637 //=======================================================================
1638 //function : AddVolumeWithID
1639 //purpose  : 
1640 //=======================================================================
1641 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(int n1, int n2, int n3,
1642                                                int n4, int n5, int n6,
1643                                                int n12,int n23,int n31,
1644                                                int n45,int n56,int n64,
1645                                                int n14,int n25,int n36, int ID)
1646 {
1647   SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolumeWithID(n1,n2,n3,n4,n5,n6,
1648                                                        n12,n23,n31,
1649                                                        n45,n56,n64,
1650                                                        n14,n25,n36,ID);
1651   if(anElem) myScript->AddVolume(ID,n1,n2,n3,n4,n5,n6,n12,n23,n31,
1652                                  n45,n56,n64,n14,n25,n36);
1653   return anElem;
1654 }
1655         
1656 //=======================================================================
1657 //function : AddVolumeWithID
1658 //purpose  : 2d order Pentahedron with 15 nodes
1659 //=======================================================================
1660 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
1661                                                const SMDS_MeshNode * n2,
1662                                                const SMDS_MeshNode * n3,
1663                                                const SMDS_MeshNode * n4,
1664                                                const SMDS_MeshNode * n5, 
1665                                                const SMDS_MeshNode * n6, 
1666                                                const SMDS_MeshNode * n12,
1667                                                const SMDS_MeshNode * n23,
1668                                                const SMDS_MeshNode * n31, 
1669                                                const SMDS_MeshNode * n45,
1670                                                const SMDS_MeshNode * n56,
1671                                                const SMDS_MeshNode * n64, 
1672                                                const SMDS_MeshNode * n14,
1673                                                const SMDS_MeshNode * n25,
1674                                                const SMDS_MeshNode * n36,
1675                                                int ID)
1676 {
1677   return AddVolumeWithID(n1->GetID(), n2->GetID(), n3->GetID(),
1678                          n4->GetID(), n5->GetID(), n6->GetID(),
1679                          n12->GetID(), n23->GetID(), n31->GetID(),
1680                          n45->GetID(), n56->GetID(), n64->GetID(),
1681                          n14->GetID(), n25->GetID(), n36->GetID(),
1682                          ID);
1683 }
1684
1685
1686 //=======================================================================
1687 //function : AddVolume
1688 //purpose  : 
1689 //=======================================================================
1690 SMDS_MeshVolume* SMESHDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
1691                                          const SMDS_MeshNode * n2, 
1692                                          const SMDS_MeshNode * n3,
1693                                          const SMDS_MeshNode * n4,
1694                                          const SMDS_MeshNode * n5, 
1695                                          const SMDS_MeshNode * n6, 
1696                                          const SMDS_MeshNode * n7,
1697                                          const SMDS_MeshNode * n8, 
1698                                          const SMDS_MeshNode * n12,
1699                                          const SMDS_MeshNode * n23,
1700                                          const SMDS_MeshNode * n34,
1701                                          const SMDS_MeshNode * n41, 
1702                                          const SMDS_MeshNode * n56,
1703                                          const SMDS_MeshNode * n67,
1704                                          const SMDS_MeshNode * n78,
1705                                          const SMDS_MeshNode * n85, 
1706                                          const SMDS_MeshNode * n15,
1707                                          const SMDS_MeshNode * n26,
1708                                          const SMDS_MeshNode * n37,
1709                                          const SMDS_MeshNode * n48)
1710 {
1711   SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolume(n1,n2,n3,n4,n5,n6,n7,n8,
1712                                                  n12,n23,n34,n41,
1713                                                  n56,n67,n78,n85,
1714                                                  n15,n26,n37,n48);
1715   if(anElem)
1716     myScript->AddVolume(anElem->GetID(), n1->GetID(), n2->GetID(),
1717                         n3->GetID(), n4->GetID(), n5->GetID(),
1718                         n6->GetID(), n7->GetID(), n8->GetID(),
1719                         n12->GetID(), n23->GetID(), n34->GetID(), n41->GetID(),
1720                         n56->GetID(), n67->GetID(), n78->GetID(), n85->GetID(),
1721                         n15->GetID(), n26->GetID(), n37->GetID(), n48->GetID());
1722   return anElem;
1723 }
1724
1725 //=======================================================================
1726 //function : AddVolumeWithID
1727 //purpose  : 
1728 //=======================================================================
1729 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4,
1730                                                int n5, int n6, int n7, int n8,
1731                                                int n12,int n23,int n34,int n41,
1732                                                int n56,int n67,int n78,int n85,
1733                                                int n15,int n26,int n37,int n48, int ID)
1734 {
1735   SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolumeWithID(n1,n2,n3,n4,n5,n6,n7,n8,
1736                                                        n12,n23,n34,n41,
1737                                                        n56,n67,n78,n85,
1738                                                        n15,n26,n37,n48,ID);
1739   if(anElem) myScript->AddVolume(ID,n1,n2,n3,n4,n5,n6,n7,n8,n12,n23,n34,n41,
1740                                  n56,n67,n78,n85,n15,n26,n37,n48);
1741   return anElem;
1742 }
1743         
1744 //=======================================================================
1745 //function : AddVolumeWithID
1746 //purpose  : 2d order Hexahedrons with 20 nodes
1747 //=======================================================================
1748 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
1749                                                const SMDS_MeshNode * n2,
1750                                                const SMDS_MeshNode * n3,
1751                                                const SMDS_MeshNode * n4,
1752                                                const SMDS_MeshNode * n5, 
1753                                                const SMDS_MeshNode * n6, 
1754                                                const SMDS_MeshNode * n7,
1755                                                const SMDS_MeshNode * n8, 
1756                                                const SMDS_MeshNode * n12,
1757                                                const SMDS_MeshNode * n23,
1758                                                const SMDS_MeshNode * n34,
1759                                                const SMDS_MeshNode * n41, 
1760                                                const SMDS_MeshNode * n56,
1761                                                const SMDS_MeshNode * n67,
1762                                                const SMDS_MeshNode * n78,
1763                                                const SMDS_MeshNode * n85, 
1764                                                const SMDS_MeshNode * n15,
1765                                                const SMDS_MeshNode * n26,
1766                                                const SMDS_MeshNode * n37,
1767                                                const SMDS_MeshNode * n48,
1768                                                int ID)
1769 {
1770   return AddVolumeWithID(n1->GetID(), n2->GetID(), n3->GetID(), n4->GetID(),
1771                          n5->GetID(), n6->GetID(), n7->GetID(), n8->GetID(),
1772                          n12->GetID(), n23->GetID(), n34->GetID(), n41->GetID(),
1773                          n56->GetID(), n67->GetID(), n78->GetID(), n85->GetID(),
1774                          n15->GetID(), n26->GetID(), n37->GetID(), n48->GetID(),
1775                          ID);
1776 }
1777
1778