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