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