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