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