]> SALOME platform Git repositories - modules/smesh.git/blob - src/SMESHDS/SMESHDS_Mesh.cxx
Salome HOME
e7429e5a25cb28fa086b6477eca1931fc94b2f18
[modules/smesh.git] / src / SMESHDS / SMESHDS_Mesh.cxx
1 // Copyright (C) 2007-2020  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, or (at your option) any later version.
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 //  SMESH SMESHDS : management of mesh data and SMESH document
24 //  File   : SMESH_Mesh.cxx
25 //  Author : Yves FRICAUD, OCC
26 //  Module : SMESH
27 //
28 #include "SMESHDS_Mesh.hxx"
29
30 #include "SMDS_Downward.hxx"
31 #include "SMDS_EdgePosition.hxx"
32 #include "SMDS_FacePosition.hxx"
33 #include "SMDS_SpacePosition.hxx"
34 #include "SMDS_VertexPosition.hxx"
35 #include "SMESHDS_Group.hxx"
36 #include "SMESHDS_GroupOnGeom.hxx"
37 #include "SMESHDS_Script.hxx"
38 #include "SMESHDS_TSubMeshHolder.hxx"
39
40 #include <Standard_ErrorHandler.hxx>
41 #include <Standard_OutOfRange.hxx>
42 #include <TopExp.hxx>
43 #include <TopExp_Explorer.hxx>
44 #include <TopoDS_Edge.hxx>
45 #include <TopoDS_Face.hxx>
46 #include <TopoDS_Iterator.hxx>
47 #include <TopoDS_Shell.hxx>
48 #include <TopoDS_Solid.hxx>
49 #include <TopoDS_Vertex.hxx>
50
51 #include "utilities.h"
52
53 class SMESHDS_Mesh::SubMeshHolder : public SMESHDS_TSubMeshHolder< const SMESHDS_SubMesh >
54 {
55 };
56
57 //=======================================================================
58 //function : Create
59 //purpose  : 
60 //=======================================================================
61 SMESHDS_Mesh::SMESHDS_Mesh(int theMeshID, bool theIsEmbeddedMode):
62   myMeshID(theMeshID),
63   mySubMeshHolder( new SubMeshHolder ),
64   myIsEmbeddedMode(theIsEmbeddedMode)
65 {
66   myScript = new SMESHDS_Script(theIsEmbeddedMode);
67   SetPersistentId(theMeshID);
68 }
69
70 //=======================================================================
71 bool SMESHDS_Mesh::IsEmbeddedMode()
72 {
73   return myIsEmbeddedMode;
74 }
75
76 //================================================================================
77 /*!
78  * \brief Store ID persistent during lifecycle
79  *
80  * Initially it was used to have a persistent reference to the mesh from the hypothesis
81  */
82 //================================================================================
83
84 void SMESHDS_Mesh::SetPersistentId(int id)
85 {
86   if (NbNodes() == 0)
87     myPersistentID = id;
88 }
89 //================================================================================
90 /*!
91  * \brief Return ID persistent during lifecycle
92  */
93 //================================================================================
94
95 int SMESHDS_Mesh::GetPersistentId() const
96 {
97   return myPersistentID;
98 }
99
100 //=======================================================================
101 //function : ShapeToMesh
102 //purpose  : 
103 //=======================================================================
104 void SMESHDS_Mesh::ShapeToMesh(const TopoDS_Shape & S)
105 {
106   if ( !myShape.IsNull() && S.IsNull() ) // case: "save study" after geometry removal
107   {
108     // removal of a shape to mesh, delete ...
109     // - hypotheses
110     myShapeToHypothesis.Clear();
111     // - shape indices in SMDS_Position of nodes
112     SMESHDS_SubMeshIteratorPtr smIt = SubMeshes();
113     while ( SMESHDS_SubMesh* sm = const_cast< SMESHDS_SubMesh* >( smIt->next() )) {
114       if ( !sm->IsComplexSubmesh() ) {
115         SMDS_NodeIteratorPtr nIt = sm->GetNodes();
116         while ( nIt->more() )
117           sm->RemoveNode(nIt->next());
118       }
119     }
120     // - sub-meshes
121     mySubMeshHolder->DeleteAll();
122
123     myIndexToShape.Clear();
124     // - groups on geometry
125     std::set<SMESHDS_GroupBase*>::iterator gr = myGroups.begin();
126     while ( gr != myGroups.end() ) {
127       if ( dynamic_cast<SMESHDS_GroupOnGeom*>( *gr ))
128         myGroups.erase( gr++ );
129       else
130         gr++;
131     }
132   }
133   else {
134     myShape = S;
135     if ( !S.IsNull() )
136       TopExp::MapShapes(myShape, myIndexToShape);
137   }
138
139   SMDS_Mesh::setNbShapes( MaxShapeIndex() );
140 }
141
142 //=======================================================================
143 //function : AddHypothesis
144 //purpose  : 
145 //=======================================================================
146
147 bool SMESHDS_Mesh::AddHypothesis(const TopoDS_Shape & SS,
148                                  const SMESHDS_Hypothesis * H)
149 {
150   if (!myShapeToHypothesis.IsBound(SS/*.Oriented(TopAbs_FORWARD)*/)) {
151     std::list<const SMESHDS_Hypothesis *> aList;
152     myShapeToHypothesis.Bind(SS/*.Oriented(TopAbs_FORWARD)*/, aList);
153   }
154   std::list<const SMESHDS_Hypothesis *>& alist =
155     myShapeToHypothesis(SS/*.Oriented(TopAbs_FORWARD)*/); // ignore orientation of SS
156
157   //Check if the Hypothesis is still present
158   std::list<const SMESHDS_Hypothesis*>::iterator ith = find(alist.begin(),alist.end(), H );
159
160   if (alist.end() != ith) return false;
161
162   alist.push_back(H);
163   return true;
164 }
165
166 //=======================================================================
167 //function : RemoveHypothesis
168 //purpose  : 
169 //=======================================================================
170
171 bool SMESHDS_Mesh::RemoveHypothesis(const TopoDS_Shape &       S,
172                                     const SMESHDS_Hypothesis * H)
173 {
174   if( myShapeToHypothesis.IsBound( S/*.Oriented(TopAbs_FORWARD)*/ ) )
175   {
176     std::list<const SMESHDS_Hypothesis *>& alist=myShapeToHypothesis.ChangeFind( S/*.Oriented(TopAbs_FORWARD)*/ );
177     std::list<const SMESHDS_Hypothesis*>::iterator ith=find(alist.begin(),alist.end(), H );
178     if (ith != alist.end())
179     {
180       alist.erase(ith);
181       return true;
182     }
183   }
184   return false;
185 }
186
187 //=======================================================================
188 //function : AddNode
189 //purpose  : 
190 //=======================================================================
191 SMDS_MeshNode* SMESHDS_Mesh::AddNode(double x, double y, double z){
192   SMDS_MeshNode* node = SMDS_Mesh::AddNode(x, y, z);
193   if(node!=NULL) myScript->AddNode(node->GetID(), x, y, z);
194   return node;
195 }
196
197 SMDS_MeshNode* SMESHDS_Mesh::AddNodeWithID(double x, double y, double z, int ID){
198   SMDS_MeshNode* node = SMDS_Mesh::AddNodeWithID(x,y,z,ID);
199   if(node!=NULL) myScript->AddNode(node->GetID(), x, y, z);
200   return node;
201 }
202
203 //=======================================================================
204 //function : MoveNode
205 //purpose  : 
206 //=======================================================================
207
208 void SMESHDS_Mesh::MoveNode(const SMDS_MeshNode *n, double x, double y, double z)
209 {
210   SMDS_Mesh::MoveNode( n, x, y, z );
211   myScript->MoveNode(n->GetID(), x, y, z);
212 }
213
214 //=======================================================================
215 //function : ChangeElementNodes
216 //purpose  : Changed nodes of an element provided that nb of nodes does not change
217 //=======================================================================
218
219 bool SMESHDS_Mesh::ChangeElementNodes(const SMDS_MeshElement * elem,
220                                       const SMDS_MeshNode    * nodes[],
221                                       const int                nbnodes)
222 {
223   if ( ! SMDS_Mesh::ChangeElementNodes( elem, nodes, nbnodes ))
224     return false;
225
226   std::vector<int> IDs( nbnodes );
227   for ( int i = 0; i < nbnodes; i++ )
228     IDs [ i ] = nodes[ i ]->GetID();
229   myScript->ChangeElementNodes( elem->GetID(), &IDs[0], nbnodes);
230
231   return true;
232 }
233
234 //=======================================================================
235 //function : ChangePolygonNodes
236 //purpose  : 
237 //=======================================================================
238 bool SMESHDS_Mesh::ChangePolygonNodes
239 (const SMDS_MeshElement *     elem,
240  std::vector<const SMDS_MeshNode*> nodes)
241 {
242   ASSERT(nodes.size() > 3);
243
244   return ChangeElementNodes(elem, &nodes[0], nodes.size());
245 }
246
247 //=======================================================================
248 //function : ChangePolyhedronNodes
249 //purpose  :
250 //=======================================================================
251 bool SMESHDS_Mesh
252 ::ChangePolyhedronNodes (const SMDS_MeshElement *                 elem,
253                          const std::vector<const SMDS_MeshNode*>& nodes,
254                          const std::vector<int> &                 quantities)
255 {
256   ASSERT(nodes.size() > 3);
257
258   if ( !SMDS_Mesh::ChangePolyhedronNodes( elem, nodes, quantities ))
259     return false;
260
261   int i, len = nodes.size();
262   std::vector<int> nodes_ids (len);
263   for (i = 0; i < len; i++) {
264     nodes_ids[i] = nodes[i]->GetID();
265   }
266   myScript->ChangePolyhedronNodes(elem->GetID(), nodes_ids, quantities);
267
268   return true;
269 }
270
271 //=======================================================================
272 //function : Renumber
273 //purpose  :
274 //=======================================================================
275
276 void SMESHDS_Mesh::Renumber (const bool /*isNodes*/, const int /*startID*/, const int /*deltaID*/)
277 {
278   // TODO not possible yet to have node numbers not starting to O and continuous.
279   if ( !this->IsCompacted() )
280     this->CompactMesh();
281   //  SMDS_Mesh::Renumber( isNodes, startID, deltaID );
282   //  myScript->Renumber( isNodes, startID, deltaID );
283 }
284
285 //=======================================================================
286 //function : Add0DElement
287 //purpose  :
288 //=======================================================================
289 SMDS_Mesh0DElement* SMESHDS_Mesh::Add0DElementWithID(int nodeID, int ID)
290 {
291   SMDS_Mesh0DElement* anElem = SMDS_Mesh::Add0DElementWithID(nodeID, ID);
292   if (anElem) myScript->Add0DElement(ID, nodeID);
293   return anElem;
294 }
295
296 SMDS_Mesh0DElement* SMESHDS_Mesh::Add0DElementWithID
297 (const SMDS_MeshNode * node, int ID)
298 {
299   return Add0DElementWithID(node->GetID(), ID);
300 }
301
302 SMDS_Mesh0DElement* SMESHDS_Mesh::Add0DElement(const SMDS_MeshNode * node)
303 {
304   SMDS_Mesh0DElement* anElem = SMDS_Mesh::Add0DElement(node);
305   if (anElem) myScript->Add0DElement(anElem->GetID(), node->GetID());
306   return anElem;
307 }
308
309 //=======================================================================
310 //function :AddBallWithID
311 //purpose  : 
312 //=======================================================================
313
314 SMDS_BallElement* SMESHDS_Mesh::AddBallWithID(int node, double diameter, int ID)
315 {
316   SMDS_BallElement* anElem = SMDS_Mesh::AddBallWithID(node,diameter,ID);
317   if (anElem) myScript->AddBall(anElem->GetID(), node, diameter);
318   return anElem;
319 }
320
321 SMDS_BallElement* SMESHDS_Mesh::AddBallWithID(const SMDS_MeshNode * node,
322                                               double                diameter,
323                                               int                   ID)
324 {
325   SMDS_BallElement* anElem = SMDS_Mesh::AddBallWithID(node,diameter,ID);
326   if (anElem) myScript->AddBall(anElem->GetID(), node->GetID(), diameter);
327   return anElem;
328 }
329
330 SMDS_BallElement* SMESHDS_Mesh::AddBall (const SMDS_MeshNode * node,
331                                          double                diameter)
332 {
333   SMDS_BallElement* anElem = SMDS_Mesh::AddBall(node,diameter);
334   if (anElem) myScript->AddBall(anElem->GetID(), node->GetID(), diameter);
335   return anElem;
336 }
337
338 //=======================================================================
339 //function :AddEdgeWithID
340 //purpose  : 
341 //=======================================================================
342
343 SMDS_MeshEdge* SMESHDS_Mesh::AddEdgeWithID(int n1, int n2, int ID)
344 {
345   SMDS_MeshEdge* anElem = SMDS_Mesh::AddEdgeWithID(n1,n2,ID);
346   if(anElem) myScript->AddEdge(ID,n1,n2);
347   return anElem;
348 }
349
350 SMDS_MeshEdge* SMESHDS_Mesh::AddEdgeWithID(const SMDS_MeshNode * n1,
351                                            const SMDS_MeshNode * n2, 
352                                            int ID)
353 {
354   return AddEdgeWithID(n1->GetID(),
355                        n2->GetID(),
356                        ID);
357 }
358
359 SMDS_MeshEdge* SMESHDS_Mesh::AddEdge(const SMDS_MeshNode * n1,
360                                      const SMDS_MeshNode * n2)
361 {
362   SMDS_MeshEdge* anElem = SMDS_Mesh::AddEdge(n1,n2);
363   if(anElem) myScript->AddEdge(anElem->GetID(), 
364                                n1->GetID(), 
365                                n2->GetID());
366   return anElem;
367 }
368
369 //=======================================================================
370 //function :AddFace
371 //purpose  : 
372 //=======================================================================
373 SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(int n1, int n2, int n3, int ID)
374 {
375   SMDS_MeshFace *anElem = SMDS_Mesh::AddFaceWithID(n1, n2, n3, ID);
376   if(anElem) myScript->AddFace(ID,n1,n2,n3);
377   return anElem;
378 }
379
380 SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
381                                            const SMDS_MeshNode * n2,
382                                            const SMDS_MeshNode * n3, 
383                                            int ID)
384 {
385   return AddFaceWithID(n1->GetID(),
386                        n2->GetID(),
387                        n3->GetID(),
388                        ID);
389 }
390
391 SMDS_MeshFace* SMESHDS_Mesh::AddFace( const SMDS_MeshNode * n1,
392                                       const SMDS_MeshNode * n2,
393                                       const SMDS_MeshNode * n3)
394 {
395   SMDS_MeshFace *anElem = SMDS_Mesh::AddFace(n1, n2, n3);
396   if(anElem) myScript->AddFace(anElem->GetID(), 
397                                n1->GetID(), 
398                                n2->GetID(),
399                                n3->GetID());
400   return anElem;
401 }
402
403 //=======================================================================
404 //function :AddFace
405 //purpose  : 
406 //=======================================================================
407 SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(int n1, int n2, int n3, int n4, int ID)
408 {
409   SMDS_MeshFace *anElem = SMDS_Mesh::AddFaceWithID(n1, n2, n3, n4, ID);
410   if(anElem) myScript->AddFace(ID, n1, n2, n3, n4);
411   return anElem;
412 }
413
414 SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
415                                            const SMDS_MeshNode * n2,
416                                            const SMDS_MeshNode * n3,
417                                            const SMDS_MeshNode * n4, 
418                                            int ID)
419 {
420   return AddFaceWithID(n1->GetID(),
421                        n2->GetID(),
422                        n3->GetID(),
423                        n4->GetID(),
424                        ID);
425 }
426
427 SMDS_MeshFace* SMESHDS_Mesh::AddFace(const SMDS_MeshNode * n1,
428                                      const SMDS_MeshNode * n2,
429                                      const SMDS_MeshNode * n3,
430                                      const SMDS_MeshNode * n4)
431 {
432   SMDS_MeshFace *anElem = SMDS_Mesh::AddFace(n1, n2, n3, n4);
433   if(anElem) myScript->AddFace(anElem->GetID(), 
434                                n1->GetID(), 
435                                n2->GetID(), 
436                                n3->GetID(),
437                                n4->GetID());
438   return anElem;
439 }
440
441 //=======================================================================
442 //function :AddVolume
443 //purpose  : 
444 //=======================================================================
445 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4, int ID)
446 {
447   SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, ID);
448   if(anElem) myScript->AddVolume(ID, n1, n2, n3, n4);
449   return anElem;
450 }
451
452 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
453                                                const SMDS_MeshNode * n2,
454                                                const SMDS_MeshNode * n3,
455                                                const SMDS_MeshNode * n4, 
456                                                int ID)
457 {
458   return AddVolumeWithID(n1->GetID(), 
459                          n2->GetID(), 
460                          n3->GetID(),
461                          n4->GetID(),
462                          ID);
463 }
464
465 SMDS_MeshVolume* SMESHDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
466                                          const SMDS_MeshNode * n2,
467                                          const SMDS_MeshNode * n3,
468                                          const SMDS_MeshNode * n4)
469 {
470   SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolume(n1, n2, n3, n4);
471   if(anElem) myScript->AddVolume(anElem->GetID(), 
472                                  n1->GetID(), 
473                                  n2->GetID(), 
474                                  n3->GetID(),
475                                  n4->GetID());
476   return anElem;
477 }
478
479 //=======================================================================
480 //function :AddVolume
481 //purpose  : 
482 //=======================================================================
483 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4, int n5, int ID)
484 {
485   SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, ID);
486   if(anElem) myScript->AddVolume(ID, n1, n2, n3, n4, n5);
487   return anElem;
488 }
489
490 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
491                                                const SMDS_MeshNode * n2,
492                                                const SMDS_MeshNode * n3,
493                                                const SMDS_MeshNode * n4,
494                                                const SMDS_MeshNode * n5, 
495                                                int ID)
496 {
497   return AddVolumeWithID(n1->GetID(), 
498                          n2->GetID(), 
499                          n3->GetID(),
500                          n4->GetID(), 
501                          n5->GetID(),
502                          ID);
503 }
504
505 SMDS_MeshVolume* SMESHDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
506                                          const SMDS_MeshNode * n2,
507                                          const SMDS_MeshNode * n3,
508                                          const SMDS_MeshNode * n4,
509                                          const SMDS_MeshNode * n5)
510 {
511   SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolume(n1, n2, n3, n4, n5);
512   if(anElem) myScript->AddVolume(anElem->GetID(), 
513                                  n1->GetID(), 
514                                  n2->GetID(), 
515                                  n3->GetID(),
516                                  n4->GetID(), 
517                                  n5->GetID());
518   return anElem;
519 }
520
521 //=======================================================================
522 //function :AddVolume
523 //purpose  : 
524 //=======================================================================
525 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4, int n5, int n6, int ID)
526 {
527   SMDS_MeshVolume *anElem= SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, ID);
528   if(anElem) myScript->AddVolume(ID, n1, n2, n3, n4, n5, n6);
529   return anElem;
530 }
531
532 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
533                                                const SMDS_MeshNode * n2,
534                                                const SMDS_MeshNode * n3,
535                                                const SMDS_MeshNode * n4,
536                                                const SMDS_MeshNode * n5,
537                                                const SMDS_MeshNode * n6, 
538                                                int ID)
539 {
540   return AddVolumeWithID(n1->GetID(), 
541                          n2->GetID(), 
542                          n3->GetID(),
543                          n4->GetID(), 
544                          n5->GetID(), 
545                          n6->GetID(),
546                          ID);
547 }
548
549 SMDS_MeshVolume* SMESHDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
550                                          const SMDS_MeshNode * n2,
551                                          const SMDS_MeshNode * n3,
552                                          const SMDS_MeshNode * n4,
553                                          const SMDS_MeshNode * n5,
554                                          const SMDS_MeshNode * n6)
555 {
556   SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolume(n1, n2, n3, n4, n5, n6);
557   if(anElem) myScript->AddVolume(anElem->GetID(), 
558                                  n1->GetID(), 
559                                  n2->GetID(), 
560                                  n3->GetID(),
561                                  n4->GetID(), 
562                                  n5->GetID(), 
563                                  n6->GetID());
564   return anElem;
565 }
566
567 //=======================================================================
568 //function :AddVolume
569 //purpose  : 
570 //=======================================================================
571 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4, int n5, int n6, int n7, int n8, int ID)
572 {
573   SMDS_MeshVolume *anElem= SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, n7, n8, ID);
574   if(anElem) myScript->AddVolume(ID, n1, n2, n3, n4, n5, n6, n7, n8);
575   return anElem;
576 }
577
578 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
579                                                const SMDS_MeshNode * n2,
580                                                const SMDS_MeshNode * n3,
581                                                const SMDS_MeshNode * n4,
582                                                const SMDS_MeshNode * n5,
583                                                const SMDS_MeshNode * n6,
584                                                const SMDS_MeshNode * n7,
585                                                const SMDS_MeshNode * n8, 
586                                                int ID)
587 {
588   return AddVolumeWithID(n1->GetID(), 
589                          n2->GetID(), 
590                          n3->GetID(),
591                          n4->GetID(), 
592                          n5->GetID(), 
593                          n6->GetID(), 
594                          n7->GetID(), 
595                          n8->GetID(),
596                          ID);
597 }
598
599 SMDS_MeshVolume* SMESHDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
600                                          const SMDS_MeshNode * n2,
601                                          const SMDS_MeshNode * n3,
602                                          const SMDS_MeshNode * n4,
603                                          const SMDS_MeshNode * n5,
604                                          const SMDS_MeshNode * n6,
605                                          const SMDS_MeshNode * n7,
606                                          const SMDS_MeshNode * n8)
607 {
608   SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolume(n1, n2, n3, n4, n5, n6, n7, n8);
609   if(anElem) myScript->AddVolume(anElem->GetID(), 
610                                  n1->GetID(), 
611                                  n2->GetID(), 
612                                  n3->GetID(),
613                                  n4->GetID(), 
614                                  n5->GetID(), 
615                                  n6->GetID(), 
616                                  n7->GetID(), 
617                                  n8->GetID());
618   return anElem;
619 }
620
621
622 //=======================================================================
623 //function :AddVolume
624 //purpose  : add hexagonal prism
625 //=======================================================================
626 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4,
627                                                int n5, int n6, int n7, int n8,
628                                                int n9, int n10, int n11, int n12,
629                                                int ID)
630 {
631   SMDS_MeshVolume *anElem= SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, n7, n8, n9, n10, n11, n12, ID);
632   if(anElem) myScript->AddVolume(ID, n1, n2, n3, n4, n5, n6, n7, n8, n9, n10, n11, n12);
633   return anElem;
634 }
635
636 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
637                                                const SMDS_MeshNode * n2,
638                                                const SMDS_MeshNode * n3,
639                                                const SMDS_MeshNode * n4,
640                                                const SMDS_MeshNode * n5,
641                                                const SMDS_MeshNode * n6,
642                                                const SMDS_MeshNode * n7,
643                                                const SMDS_MeshNode * n8, 
644                                                const SMDS_MeshNode * n9, 
645                                                const SMDS_MeshNode * n10, 
646                                                const SMDS_MeshNode * n11, 
647                                                const SMDS_MeshNode * n12, 
648                                                int ID)
649 {
650   return AddVolumeWithID(n1->GetID(), 
651                          n2->GetID(),
652                          n3->GetID(),
653                          n4->GetID(),
654                          n5->GetID(),
655                          n6->GetID(),
656                          n7->GetID(),
657                          n8->GetID(),
658                          n9->GetID(),
659                          n10->GetID(),
660                          n11->GetID(),
661                          n12->GetID(),
662                          ID);
663 }
664
665 SMDS_MeshVolume* SMESHDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
666                                          const SMDS_MeshNode * n2,
667                                          const SMDS_MeshNode * n3,
668                                          const SMDS_MeshNode * n4,
669                                          const SMDS_MeshNode * n5,
670                                          const SMDS_MeshNode * n6,
671                                          const SMDS_MeshNode * n7,
672                                          const SMDS_MeshNode * n8, 
673                                          const SMDS_MeshNode * n9, 
674                                          const SMDS_MeshNode * n10, 
675                                          const SMDS_MeshNode * n11, 
676                                          const SMDS_MeshNode * n12)
677 {
678   SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolume(n1, n2, n3, n4, n5, n6, n7, n8, n9, n10, n11, n12);
679   if(anElem) myScript->AddVolume(anElem->GetID(), 
680                                  n1->GetID(),
681                                  n2->GetID(),
682                                  n3->GetID(),
683                                  n4->GetID(),
684                                  n5->GetID(),
685                                  n6->GetID(),
686                                  n7->GetID(),
687                                  n8->GetID(),
688                                  n9->GetID(),
689                                  n10->GetID(),
690                                  n11->GetID(),
691                                  n12->GetID());
692   return anElem;
693 }
694
695
696 //=======================================================================
697 //function : AddPolygonalFace
698 //purpose  : 
699 //=======================================================================
700 SMDS_MeshFace* SMESHDS_Mesh::AddPolygonalFaceWithID (const std::vector<int>& nodes_ids,
701                                                      const int               ID)
702 {
703   SMDS_MeshFace *anElem = SMDS_Mesh::AddPolygonalFaceWithID(nodes_ids, ID);
704   if (anElem) {
705     myScript->AddPolygonalFace(ID, nodes_ids);
706   }
707   return anElem;
708 }
709
710 SMDS_MeshFace*
711 SMESHDS_Mesh::AddPolygonalFaceWithID (const std::vector<const SMDS_MeshNode*>& nodes,
712                                       const int                                ID)
713 {
714   SMDS_MeshFace *anElem = SMDS_Mesh::AddPolygonalFaceWithID(nodes, ID);
715   if (anElem) {
716     int i, len = nodes.size();
717     std::vector<int> nodes_ids (len);
718     for (i = 0; i < len; i++) {
719       nodes_ids[i] = nodes[i]->GetID();
720     }
721     myScript->AddPolygonalFace(ID, nodes_ids);
722   }
723   return anElem;
724 }
725
726 SMDS_MeshFace*
727 SMESHDS_Mesh::AddPolygonalFace (const std::vector<const SMDS_MeshNode*>& nodes)
728 {
729   SMDS_MeshFace *anElem = SMDS_Mesh::AddPolygonalFace(nodes);
730   if (anElem) {
731     int i, len = nodes.size();
732     std::vector<int> nodes_ids (len);
733     for (i = 0; i < len; i++) {
734       nodes_ids[i] = nodes[i]->GetID();
735     }
736     myScript->AddPolygonalFace(anElem->GetID(), nodes_ids);
737   }
738   return anElem;
739 }
740
741
742 //=======================================================================
743 //function : AddQuadPolygonalFace
744 //purpose  : 
745 //=======================================================================
746 SMDS_MeshFace* SMESHDS_Mesh::AddQuadPolygonalFaceWithID (const std::vector<int>& nodes_ids,
747                                                          const int               ID)
748 {
749   SMDS_MeshFace *anElem = SMDS_Mesh::AddQuadPolygonalFaceWithID(nodes_ids, ID);
750   if (anElem) {
751     myScript->AddQuadPolygonalFace(ID, nodes_ids);
752   }
753   return anElem;
754 }
755
756 SMDS_MeshFace*
757 SMESHDS_Mesh::AddQuadPolygonalFaceWithID (const std::vector<const SMDS_MeshNode*>& nodes,
758                                           const int                                ID)
759 {
760   SMDS_MeshFace *anElem = SMDS_Mesh::AddQuadPolygonalFaceWithID(nodes, ID);
761   if (anElem) {
762     int i, len = nodes.size();
763     std::vector<int> nodes_ids (len);
764     for (i = 0; i < len; i++) {
765       nodes_ids[i] = nodes[i]->GetID();
766     }
767     myScript->AddQuadPolygonalFace(ID, nodes_ids);
768   }
769   return anElem;
770 }
771
772 SMDS_MeshFace*
773 SMESHDS_Mesh::AddQuadPolygonalFace (const std::vector<const SMDS_MeshNode*>& nodes)
774 {
775   SMDS_MeshFace *anElem = SMDS_Mesh::AddQuadPolygonalFace(nodes);
776   if (anElem) {
777     int i, len = nodes.size();
778     std::vector<int> nodes_ids (len);
779     for (i = 0; i < len; i++) {
780       nodes_ids[i] = nodes[i]->GetID();
781     }
782     myScript->AddQuadPolygonalFace(anElem->GetID(), nodes_ids);
783   }
784   return anElem;
785 }
786
787
788 //=======================================================================
789 //function : AddPolyhedralVolume
790 //purpose  : 
791 //=======================================================================
792 SMDS_MeshVolume* SMESHDS_Mesh::AddPolyhedralVolumeWithID (const std::vector<int>& nodes_ids,
793                                                           const std::vector<int>& quantities,
794                                                           const int               ID)
795 {
796   SMDS_MeshVolume *anElem = SMDS_Mesh::AddPolyhedralVolumeWithID(nodes_ids, quantities, ID);
797   if (anElem) {
798     myScript->AddPolyhedralVolume(ID, nodes_ids, quantities);
799   }
800   return anElem;
801 }
802
803 SMDS_MeshVolume* SMESHDS_Mesh::AddPolyhedralVolumeWithID
804 (const std::vector<const SMDS_MeshNode*>& nodes,
805  const std::vector<int>&                  quantities,
806  const int                                ID)
807 {
808   SMDS_MeshVolume *anElem = SMDS_Mesh::AddPolyhedralVolumeWithID(nodes, quantities, ID);
809   if (anElem) {
810     int i, len = nodes.size();
811     std::vector<int> nodes_ids (len);
812     for (i = 0; i < len; i++) {
813       nodes_ids[i] = nodes[i]->GetID();
814     }
815     myScript->AddPolyhedralVolume(ID, nodes_ids, quantities);
816   }
817   return anElem;
818 }
819
820 SMDS_MeshVolume* SMESHDS_Mesh::AddPolyhedralVolume
821 (const std::vector<const SMDS_MeshNode*>& nodes,
822  const std::vector<int>&                  quantities)
823 {
824   SMDS_MeshVolume *anElem = SMDS_Mesh::AddPolyhedralVolume(nodes, quantities);
825   if (anElem) {
826     int i, len = nodes.size();
827     std::vector<int> nodes_ids (len);
828     for (i = 0; i < len; i++) {
829       nodes_ids[i] = nodes[i]->GetID();
830     }
831     myScript->AddPolyhedralVolume(anElem->GetID(), nodes_ids, quantities);
832   }
833   return anElem;
834 }
835
836 //=======================================================================
837 //function : removeFromContainers
838 //purpose  : 
839 //=======================================================================
840
841 static void removeFromContainers (SMESHDS_Mesh*                         /*theMesh*/,
842                                   std::set<SMESHDS_GroupBase*>&         theGroups,
843                                   std::vector<const SMDS_MeshElement*>& theElems)
844 {
845   if ( theElems.empty() )
846     return;
847
848   // Rm from group
849   // Element can belong to several groups
850   if ( !theGroups.empty() )
851   {
852     std::set<SMESHDS_GroupBase*>::iterator GrIt = theGroups.begin();
853     for ( ; GrIt != theGroups.end(); GrIt++ )
854     {
855       SMESHDS_Group* group = dynamic_cast<SMESHDS_Group*>( *GrIt );
856       if ( !group || group->IsEmpty() ) continue;
857
858       std::vector<const SMDS_MeshElement *>::iterator elIt = theElems.begin();
859       for ( ; elIt != theElems.end(); elIt++ )
860       {
861         group->SMDSGroup().Remove( *elIt );
862         if ( group->IsEmpty() ) break;
863       }
864     }
865   }
866
867   //const bool deleted=true;
868
869   // Rm from sub-meshes
870   // Element should belong to only one sub-mesh
871   // if ( theMesh->SubMeshes()->more() )
872   // {
873   //   std::list<const SMDS_MeshElement *>::iterator elIt = theElems.begin();
874   //   if ( isNode ) {
875   //     for ( ; elIt != theElems.end(); ++elIt )
876   //       if ( SMESHDS_SubMesh* sm = theMesh->MeshElements( (*elIt)->getshapeId() ))
877   //         sm->RemoveNode( static_cast<const SMDS_MeshNode*> (*elIt), deleted );
878   //   }
879   //   else {
880   //     for ( ; elIt != theElems.end(); ++elIt )
881   //       if ( SMESHDS_SubMesh* sm = theMesh->MeshElements( (*elIt)->getshapeId() ))
882   //         sm->RemoveElement( *elIt, deleted );
883   //   }
884   // }
885 }
886
887 //=======================================================================
888 //function : RemoveNode
889 //purpose  :
890 //=======================================================================
891 void SMESHDS_Mesh::RemoveNode(const SMDS_MeshNode * n)
892 {
893   if ( RemoveFreeNode( n, 0, true ))
894     return;
895
896   myScript->RemoveNode(n->GetID());
897
898   // remove inverse elements from the sub-meshes
899   for ( SMDS_ElemIteratorPtr eIt = n->GetInverseElementIterator(); eIt->more() ; )
900   {
901     const SMDS_MeshElement* e = eIt->next();
902     if ( SMESHDS_SubMesh * sm = MeshElements( e->getshapeId() ))
903       sm->RemoveElement( e );
904   }
905   if ( SMESHDS_SubMesh * sm = MeshElements( n->getshapeId() ))
906     sm->RemoveNode( n );
907     
908   
909   std::vector<const SMDS_MeshElement *> removedElems;
910   std::vector<const SMDS_MeshElement *> removedNodes;
911
912   SMDS_Mesh::RemoveElement( n, removedElems, removedNodes, true );
913
914   removeFromContainers( this, myGroups, removedElems );
915   removeFromContainers( this, myGroups, removedNodes );
916 }
917
918 //=======================================================================
919 //function : RemoveFreeNode
920 //purpose  : 
921 //=======================================================================
922 bool SMESHDS_Mesh::RemoveFreeNode(const SMDS_MeshNode * n,
923                                   SMESHDS_SubMesh *     subMesh,
924                                   bool                  fromGroups)
925 {
926   if ( n->NbInverseElements() > 0 )
927     return false;
928
929   myScript->RemoveNode(n->GetID());
930
931   // Rm from group
932   // Node can belong to several groups
933   if ( fromGroups && !myGroups.empty() ) {
934     std::set<SMESHDS_GroupBase*>::iterator GrIt = myGroups.begin();
935     for (; GrIt != myGroups.end(); GrIt++) {
936       SMESHDS_Group* group = dynamic_cast<SMESHDS_Group*>(*GrIt);
937       if (group && group->GetType() == SMDSAbs_Node )
938         group->SMDSGroup().Remove(n);
939     }
940   }
941
942   // Rm from sub-mesh
943   // Node should belong to only one sub-mesh
944   if ( !subMesh || !subMesh->RemoveNode( n ))
945     if (( subMesh = MeshElements( n->getshapeId() )))
946       subMesh->RemoveNode(n);
947
948   SMDS_Mesh::RemoveFreeElement(n);
949
950   return true;
951 }
952
953 //=======================================================================
954 //function : RemoveElement
955 //purpose  :
956 //========================================================================
957 void SMESHDS_Mesh::RemoveElement(const SMDS_MeshElement * elt)
958 {
959   if (elt->GetType() == SMDSAbs_Node)
960   {
961     RemoveNode( static_cast<const SMDS_MeshNode*>( elt ));
962     return;
963   }
964   //if (!hasConstructionEdges() && !hasConstructionFaces())
965   {
966     SMESHDS_SubMesh* subMesh=0;
967     if ( elt->getshapeId() > 0 )
968       subMesh = MeshElements( elt->getshapeId() );
969
970     RemoveFreeElement( elt, subMesh, true );
971     return;
972   }
973  
974   myScript->RemoveElement(elt->GetID());
975
976   std::vector<const SMDS_MeshElement *> removedElems;
977   std::vector<const SMDS_MeshElement *> removedNodes;
978
979   SMDS_Mesh::RemoveElement(elt, removedElems, removedNodes );
980   
981   removeFromContainers( this, myGroups, removedElems );
982 }
983
984 //=======================================================================
985 //function : RemoveFreeElement
986 //purpose  : 
987 //========================================================================
988 void SMESHDS_Mesh::RemoveFreeElement(const SMDS_MeshElement * elt,
989                                      SMESHDS_SubMesh *        subMesh,
990                                      bool                     fromGroups)
991 {
992   if (elt->GetType() == SMDSAbs_Node) {
993     RemoveFreeNode( static_cast<const SMDS_MeshNode*>(elt), subMesh, fromGroups);
994     return;
995   }
996
997   // if (hasConstructionEdges() || hasConstructionFaces())
998   //   // this methods is only for meshes without descendants
999   //   return;
1000
1001   myScript->RemoveElement(elt->GetID());
1002
1003   // Rm from group
1004   // Element can belong to several groups
1005   if ( fromGroups && !myGroups.empty() ) {
1006     std::set<SMESHDS_GroupBase*>::iterator GrIt = myGroups.begin();
1007     for (; GrIt != myGroups.end(); GrIt++) {
1008       SMESHDS_Group* group = dynamic_cast<SMESHDS_Group*>(*GrIt);
1009       if (group && !group->IsEmpty())
1010         group->SMDSGroup().Remove(elt);
1011     }
1012   }
1013
1014   // Rm from sub-mesh
1015   // Element should belong to only one sub-mesh
1016   if ( !subMesh && elt->getshapeId() > 0 )
1017     subMesh = MeshElements( elt->getshapeId() );
1018   if ( subMesh )
1019     subMesh->RemoveElement( elt );
1020
1021   SMDS_Mesh::RemoveFreeElement( elt );
1022 }
1023
1024 //================================================================================
1025 /*!
1026  * \brief Remove all data from the mesh
1027  */
1028 //================================================================================
1029
1030 void SMESHDS_Mesh::ClearMesh()
1031 {
1032   myScript->ClearMesh();
1033   SMDS_Mesh::Clear();
1034
1035   // clear submeshes
1036   SMESHDS_SubMeshIteratorPtr smIt = SubMeshes();
1037   while ( SMESHDS_SubMesh* sm = const_cast< SMESHDS_SubMesh* >( smIt->next() ))
1038     sm->Clear();
1039
1040   // clear groups
1041   TGroups::iterator group, groupEnd = myGroups.end();
1042   for ( group = myGroups.begin(); group != groupEnd; ++group ) {
1043     if ( SMESHDS_Group* g = dynamic_cast<SMESHDS_Group*>(*group)) {
1044       SMDSAbs_ElementType groupType = g->GetType();
1045       g->Clear();
1046       g->SetType( groupType );
1047     }
1048     else
1049     {
1050       (*group)->Extent(); // to free cached elements in GroupOnFilter's
1051     }
1052   }
1053 }
1054
1055 //================================================================================
1056 /*!
1057  * \brief return submesh by shape
1058  * \param shape - the sub-shape
1059  * \retval SMESHDS_SubMesh* - the found submesh
1060  */
1061 //================================================================================
1062
1063 SMESHDS_SubMesh* SMESHDS_Mesh::getSubmesh( const TopoDS_Shape & shape )
1064 {
1065   if ( shape.IsNull() )
1066     return 0;
1067
1068   return NewSubMesh( ShapeToIndex( shape ));
1069 }
1070
1071 //================================================================================
1072 /*!
1073  * \brief Add element or node to submesh
1074  * \param elem - element to add
1075  * \param subMesh - submesh to be filled in
1076  */
1077 //================================================================================
1078
1079 int SMESHDS_Mesh::add(const SMDS_MeshElement* elem, SMESHDS_SubMesh* subMesh )
1080 {
1081   if ( elem && subMesh ) {
1082     subMesh->AddElement( elem );
1083     return subMesh->GetID();
1084   }
1085   return 0;
1086 }
1087
1088 //=======================================================================
1089 //function : SetNodeOnVolume
1090 //purpose  :
1091 //=======================================================================
1092 void SMESHDS_Mesh::SetNodeInVolume(const SMDS_MeshNode* aNode,
1093                                    const TopoDS_Shell & S)
1094 {
1095   if ( int shapeID = add( aNode, getSubmesh( S )))
1096     const_cast< SMDS_MeshNode* >
1097       ( aNode )->SetPosition( SMDS_SpacePosition::originSpacePosition(), shapeID );
1098 }
1099
1100 //=======================================================================
1101 //function : SetNodeOnVolume
1102 //purpose  :
1103 //=======================================================================
1104 void SMESHDS_Mesh::SetNodeInVolume(const SMDS_MeshNode *      aNode,
1105                                    const TopoDS_Solid & S)
1106 {
1107   if ( int shapeID = add( aNode, getSubmesh( S )))
1108     const_cast< SMDS_MeshNode* >
1109       ( aNode )->SetPosition( SMDS_SpacePosition::originSpacePosition(), shapeID );
1110 }
1111
1112 //=======================================================================
1113 //function : SetNodeOnFace
1114 //purpose  :
1115 //=======================================================================
1116 void SMESHDS_Mesh::SetNodeOnFace(const SMDS_MeshNode * aNode,
1117                                  const TopoDS_Face &   S,
1118                                  double                u,
1119                                  double                v)
1120 {
1121   if ( int shapeID = add( aNode, getSubmesh( S )))
1122     const_cast< SMDS_MeshNode* >
1123       ( aNode )->SetPosition(SMDS_PositionPtr( new SMDS_FacePosition( u, v )), shapeID );
1124 }
1125
1126 //=======================================================================
1127 //function : SetNodeOnEdge
1128 //purpose  :
1129 //=======================================================================
1130 void SMESHDS_Mesh::SetNodeOnEdge(const SMDS_MeshNode * aNode,
1131                                  const TopoDS_Edge &   S,
1132                                  double                u)
1133 {
1134   if ( int shapeID = add( aNode, getSubmesh( S )))
1135     const_cast< SMDS_MeshNode* >
1136       ( aNode )->SetPosition(SMDS_PositionPtr( new SMDS_EdgePosition( u )), shapeID );
1137 }
1138
1139 //=======================================================================
1140 //function : SetNodeOnVertex
1141 //purpose  :
1142 //=======================================================================
1143 void SMESHDS_Mesh::SetNodeOnVertex(const SMDS_MeshNode * aNode,
1144                                    const TopoDS_Vertex & S)
1145 {
1146   if ( int shapeID = add( aNode, getSubmesh( S )))
1147     const_cast< SMDS_MeshNode* >
1148       ( aNode )->SetPosition(SMDS_PositionPtr( new SMDS_VertexPosition()), shapeID );
1149 }
1150
1151 //=======================================================================
1152 //function : UnSetNodeOnShape
1153 //purpose  : 
1154 //=======================================================================
1155 void SMESHDS_Mesh::UnSetNodeOnShape(const SMDS_MeshNode* aNode)
1156 {
1157   int shapeId = aNode->getshapeId();
1158   if (shapeId > 0)
1159     if ( SMESHDS_SubMesh* sm = MeshElements( shapeId ))
1160       sm->RemoveNode(aNode);
1161 }
1162
1163 //=======================================================================
1164 //function : SetMeshElementOnShape
1165 //purpose  :
1166 //=======================================================================
1167 void SMESHDS_Mesh::SetMeshElementOnShape(const SMDS_MeshElement * anElement,
1168                                          const TopoDS_Shape &     S)
1169 {
1170   add( anElement, getSubmesh(S) );
1171 }
1172
1173 //=======================================================================
1174 //function : UnSetMeshElementOnShape
1175 //purpose  : 
1176 //=======================================================================
1177 void SMESHDS_Mesh::UnSetMeshElementOnShape(const SMDS_MeshElement * elem,
1178                                            const TopoDS_Shape &     S)
1179 {
1180   if ( SMESHDS_SubMesh* sm = MeshElements( S ))
1181     sm->RemoveElement(elem);
1182 }
1183
1184 //=======================================================================
1185 //function : ShapeToMesh
1186 //purpose  : 
1187 //=======================================================================
1188 TopoDS_Shape SMESHDS_Mesh::ShapeToMesh() const
1189 {
1190   return myShape;
1191 }
1192
1193 //=======================================================================
1194 //function : IsGroupOfSubShapes
1195 //purpose  : return true if at least one sub-shape of theShape is a sub-shape
1196 //           of myShape or theShape == myShape
1197 //=======================================================================
1198
1199 bool SMESHDS_Mesh::IsGroupOfSubShapes (const TopoDS_Shape& theShape) const
1200 {
1201   if ( myIndexToShape.Contains(theShape) )
1202     return true;
1203
1204   for ( TopoDS_Iterator it( theShape ); it.More(); it.Next() )
1205     if ( IsGroupOfSubShapes( it.Value() ))
1206       return true;
1207
1208   return false;
1209 }
1210
1211 ///////////////////////////////////////////////////////////////////////////////
1212 /// Return the sub mesh linked to the a given TopoDS_Shape or NULL if the given
1213 /// TopoDS_Shape is unknown
1214 ///////////////////////////////////////////////////////////////////////////////
1215 SMESHDS_SubMesh * SMESHDS_Mesh::MeshElements(const TopoDS_Shape & S) const
1216 {
1217   int Index = ShapeToIndex(S);
1218   return (SMESHDS_SubMesh *) ( Index ? mySubMeshHolder->Get( Index ) : 0 );
1219 }
1220
1221 ///////////////////////////////////////////////////////////////////////////////
1222 /// Return the sub mesh by Id of shape it is linked to
1223 ///////////////////////////////////////////////////////////////////////////////
1224 SMESHDS_SubMesh * SMESHDS_Mesh::MeshElements(const int Index) const
1225 {
1226   return const_cast< SMESHDS_SubMesh* >( mySubMeshHolder->Get( Index ));
1227 }
1228
1229 //=======================================================================
1230 //function : SubMeshIndices
1231 //purpose  : 
1232 //=======================================================================
1233 std::list<int> SMESHDS_Mesh::SubMeshIndices() const
1234 {
1235   std::list<int> anIndices;
1236   SMESHDS_SubMeshIteratorPtr smIt = SubMeshes();
1237   while ( const SMESHDS_SubMesh* sm = smIt->next() )
1238     anIndices.push_back( sm->GetID() );
1239
1240   return anIndices;
1241 }
1242
1243 //=======================================================================
1244 //function : SubMeshes
1245 //purpose  : 
1246 //=======================================================================
1247
1248 SMESHDS_SubMeshIteratorPtr SMESHDS_Mesh::SubMeshes() const
1249 {
1250   return SMESHDS_SubMeshIteratorPtr( mySubMeshHolder->GetIterator() );
1251 }
1252
1253 //=======================================================================
1254 //function : GetHypothesis
1255 //purpose  : 
1256 //=======================================================================
1257
1258 const std::list<const SMESHDS_Hypothesis*>&
1259 SMESHDS_Mesh::GetHypothesis(const TopoDS_Shape & S) const
1260 {
1261   if ( myShapeToHypothesis.IsBound( S/*.Oriented(TopAbs_FORWARD)*/ ) ) // ignore orientation of S
1262     return myShapeToHypothesis.Find( S/*.Oriented(TopAbs_FORWARD)*/ );
1263
1264   static std::list<const SMESHDS_Hypothesis*> empty;
1265   return empty;
1266 }
1267
1268 //================================================================================
1269 /*!
1270  * \brief returns true if the hypothesis is assigned to any sub-shape
1271  */
1272 //================================================================================
1273
1274 bool SMESHDS_Mesh::IsUsedHypothesis(const SMESHDS_Hypothesis * H) const
1275 {
1276   ShapeToHypothesis::Iterator s2h( myShapeToHypothesis );
1277   for ( ; s2h.More(); s2h.Next() )
1278     if ( std::find( s2h.Value().begin(), s2h.Value().end(), H ) != s2h.Value().end() )
1279       return true;
1280   return false;
1281 }
1282
1283 //=======================================================================
1284 //function : GetScript
1285 //purpose  : 
1286 //=======================================================================
1287 SMESHDS_Script* SMESHDS_Mesh::GetScript()
1288 {
1289   return myScript;
1290 }
1291
1292 //=======================================================================
1293 //function : ClearScript
1294 //purpose  : 
1295 //=======================================================================
1296 void SMESHDS_Mesh::ClearScript()
1297 {
1298   myScript->Clear();
1299 }
1300
1301 //=======================================================================
1302 //function : HasMeshElements
1303 //purpose  : 
1304 //=======================================================================
1305 bool SMESHDS_Mesh::HasMeshElements(const TopoDS_Shape & S) const
1306 {
1307   int Index = myIndexToShape.FindIndex(S);
1308   return mySubMeshHolder->Get( Index );
1309 }
1310
1311 //=======================================================================
1312 //function : HasHypothesis
1313 //purpose  : 
1314 //=======================================================================
1315 bool SMESHDS_Mesh::HasHypothesis(const TopoDS_Shape & S)
1316 {
1317   return myShapeToHypothesis.IsBound(S/*.Oriented(TopAbs_FORWARD)*/);
1318 }
1319
1320 //=======================================================================
1321 //function : NewSubMesh 
1322 //purpose  : 
1323 //=======================================================================
1324 SMESHDS_SubMesh * SMESHDS_Mesh::NewSubMesh(int Index)
1325 {
1326   SMESHDS_SubMesh* SM = MeshElements( Index );
1327   if ( !SM )
1328   {
1329     SM = new SMESHDS_SubMesh(this, Index);
1330     mySubMeshHolder->Add( Index, SM );
1331   }
1332   return SM;
1333 }
1334
1335 //=======================================================================
1336 //function : AddCompoundSubmesh
1337 //purpose  : 
1338 //=======================================================================
1339
1340 int SMESHDS_Mesh::AddCompoundSubmesh(const TopoDS_Shape& S,
1341                                      TopAbs_ShapeEnum    type)
1342 {
1343   int aMainIndex = 0;
1344   if ( IsGroupOfSubShapes( S ))
1345   {
1346     aMainIndex = myIndexToShape.Add( S );
1347     bool all = ( type == TopAbs_SHAPE );
1348     if ( all ) // corresponding simple submesh may exist
1349       aMainIndex = -aMainIndex;
1350     SMESHDS_SubMesh * aNewSub = NewSubMesh( aMainIndex );
1351     if ( !aNewSub->IsComplexSubmesh() ) // is empty
1352     {
1353       int shapeType = Max( TopAbs_SOLID, all ? myShape.ShapeType() : type );
1354       int typeLimit = all ? TopAbs_VERTEX : type;
1355       for ( ; shapeType <= typeLimit; shapeType++ )
1356       {
1357         TopExp_Explorer exp( S, TopAbs_ShapeEnum( shapeType ));
1358         for ( ; exp.More(); exp.Next() )
1359         {
1360           int index = myIndexToShape.FindIndex( exp.Current() );
1361           if ( index )
1362             aNewSub->AddSubMesh( NewSubMesh( index ));
1363         }
1364       }
1365     }
1366   }
1367   return aMainIndex;
1368 }
1369
1370 //=======================================================================
1371 //function : IndexToShape
1372 //purpose  : 
1373 //=======================================================================
1374 const TopoDS_Shape& SMESHDS_Mesh::IndexToShape(int ShapeIndex) const
1375 {
1376   try
1377   {
1378     if ( ShapeIndex > 0 )
1379       return myIndexToShape.FindKey(ShapeIndex);
1380   }
1381   catch ( ... )
1382   {
1383   }
1384   static TopoDS_Shape nullShape;
1385   return nullShape;
1386 }
1387
1388 //================================================================================
1389 /*!
1390  * \brief Return max index of sub-mesh
1391  */
1392 //================================================================================
1393
1394 int SMESHDS_Mesh::MaxSubMeshIndex() const
1395 {
1396   return mySubMeshHolder->GetMaxID();
1397 }
1398
1399 //=======================================================================
1400 //function : ShapeToIndex
1401 //purpose  : 
1402 //=======================================================================
1403 int SMESHDS_Mesh::ShapeToIndex(const TopoDS_Shape & S) const
1404 {
1405   int index = myIndexToShape.FindIndex(S);
1406   return index;
1407 }
1408
1409 //=======================================================================
1410 //function : SetNodeOnVolume
1411 //purpose  : 
1412 //=======================================================================
1413 void SMESHDS_Mesh::SetNodeInVolume(const SMDS_MeshNode* aNode, int Index)
1414 {
1415   if ( int shapeID = add( aNode, NewSubMesh( Index )))
1416     ((SMDS_MeshNode*) aNode)->SetPosition( SMDS_SpacePosition::originSpacePosition(), shapeID );
1417 }
1418
1419 //=======================================================================
1420 //function : SetNodeOnFace
1421 //purpose  :
1422 //=======================================================================
1423 void SMESHDS_Mesh::SetNodeOnFace(const SMDS_MeshNode* aNode, int Index, double u, double v)
1424 {
1425   //Set Position on Node
1426   if ( int shapeID = add( aNode, NewSubMesh( Index )))
1427     const_cast< SMDS_MeshNode* >
1428       ( aNode )->SetPosition(SMDS_PositionPtr(new SMDS_FacePosition( u, v )), shapeID );
1429 }
1430
1431 //=======================================================================
1432 //function : SetNodeOnEdge
1433 //purpose  :
1434 //=======================================================================
1435 void SMESHDS_Mesh::SetNodeOnEdge(const SMDS_MeshNode* aNode,
1436                                  int                  Index,
1437                                  double               u)
1438 {
1439   //Set Position on Node
1440   if (  int shapeID = add( aNode, NewSubMesh( Index )))
1441     const_cast< SMDS_MeshNode* >
1442       ( aNode )->SetPosition(SMDS_PositionPtr(new SMDS_EdgePosition( u )), shapeID );
1443 }
1444
1445 //=======================================================================
1446 //function : SetNodeOnVertex
1447 //purpose  :
1448 //=======================================================================
1449 void SMESHDS_Mesh::SetNodeOnVertex(const SMDS_MeshNode* aNode, int Index)
1450 {
1451   //Set Position on Node
1452   if (  int shapeID = add( aNode, NewSubMesh( Index )))
1453     const_cast< SMDS_MeshNode* >
1454       ( aNode )->SetPosition(SMDS_PositionPtr(new SMDS_VertexPosition()), shapeID );
1455 }
1456
1457 //=======================================================================
1458 //function : SetMeshElementOnShape
1459 //purpose  : 
1460 //=======================================================================
1461 void SMESHDS_Mesh::SetMeshElementOnShape(const SMDS_MeshElement* anElement,
1462                                          int                     Index)
1463 {
1464   add( anElement, NewSubMesh( Index ));
1465 }
1466
1467 //=======================================================================
1468 //function : ~SMESHDS_Mesh
1469 //purpose  : 
1470 //=======================================================================
1471 SMESHDS_Mesh::~SMESHDS_Mesh()
1472 {
1473   // myScript
1474   delete myScript;
1475   // submeshes
1476   delete mySubMeshHolder;
1477 }
1478
1479
1480 //********************************************************************
1481 //********************************************************************
1482 //********                                                   *********
1483 //*****       Methods for addition of quadratic elements        ******
1484 //********                                                   *********
1485 //********************************************************************
1486 //********************************************************************
1487
1488 //=======================================================================
1489 //function : AddEdgeWithID
1490 //purpose  : 
1491 //=======================================================================
1492 SMDS_MeshEdge* SMESHDS_Mesh::AddEdgeWithID(int n1, int n2, int n12, int ID) 
1493 {
1494   SMDS_MeshEdge* anElem = SMDS_Mesh::AddEdgeWithID(n1,n2,n12,ID);
1495   if(anElem) myScript->AddEdge(ID,n1,n2,n12);
1496   return anElem;
1497 }
1498
1499 //=======================================================================
1500 //function : AddEdge
1501 //purpose  : 
1502 //=======================================================================
1503 SMDS_MeshEdge* SMESHDS_Mesh::AddEdge(const SMDS_MeshNode* n1,
1504                                      const SMDS_MeshNode* n2,
1505                                      const SMDS_MeshNode* n12)
1506 {
1507   SMDS_MeshEdge* anElem = SMDS_Mesh::AddEdge(n1,n2,n12);
1508   if(anElem) myScript->AddEdge(anElem->GetID(), 
1509                                n1->GetID(), 
1510                                n2->GetID(),
1511                                n12->GetID());
1512   return anElem;
1513 }
1514
1515 //=======================================================================
1516 //function : AddEdgeWithID
1517 //purpose  : 
1518 //=======================================================================
1519 SMDS_MeshEdge* SMESHDS_Mesh::AddEdgeWithID(const SMDS_MeshNode * n1,
1520                                            const SMDS_MeshNode * n2, 
1521                                            const SMDS_MeshNode * n12, 
1522                                            int ID)
1523 {
1524   return AddEdgeWithID(n1->GetID(),
1525                        n2->GetID(),
1526                        n12->GetID(),
1527                        ID);
1528 }
1529
1530
1531 //=======================================================================
1532 //function : AddFace
1533 //purpose  : 
1534 //=======================================================================
1535 SMDS_MeshFace* SMESHDS_Mesh::AddFace(const SMDS_MeshNode * n1,
1536                                      const SMDS_MeshNode * n2,
1537                                      const SMDS_MeshNode * n3,
1538                                      const SMDS_MeshNode * n12,
1539                                      const SMDS_MeshNode * n23,
1540                                      const SMDS_MeshNode * n31)
1541 {
1542   SMDS_MeshFace *anElem = SMDS_Mesh::AddFace(n1,n2,n3,n12,n23,n31);
1543   if(anElem) myScript->AddFace(anElem->GetID(), 
1544                                n1->GetID(), n2->GetID(), n3->GetID(),
1545                                n12->GetID(), n23->GetID(), n31->GetID());
1546   return anElem;
1547 }
1548
1549 //=======================================================================
1550 //function : AddFaceWithID
1551 //purpose  : 
1552 //=======================================================================
1553 SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(int n1, int n2, int n3,
1554                                            int n12,int n23,int n31, int ID)
1555 {
1556   SMDS_MeshFace *anElem = SMDS_Mesh::AddFaceWithID(n1,n2,n3,n12,n23,n31,ID);
1557   if(anElem) myScript->AddFace(ID,n1,n2,n3,n12,n23,n31);
1558   return anElem;
1559 }
1560
1561 //=======================================================================
1562 //function : AddFaceWithID
1563 //purpose  : 
1564 //=======================================================================
1565 SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
1566                                            const SMDS_MeshNode * n2,
1567                                            const SMDS_MeshNode * n3,
1568                                            const SMDS_MeshNode * n12,
1569                                            const SMDS_MeshNode * n23,
1570                                            const SMDS_MeshNode * n31, 
1571                                            int ID)
1572 {
1573   return AddFaceWithID(n1->GetID(), n2->GetID(), n3->GetID(),
1574                        n12->GetID(), n23->GetID(), n31->GetID(),
1575                        ID);
1576 }
1577
1578 //=======================================================================
1579 //function : AddFace
1580 //purpose  : 
1581 //=======================================================================
1582 SMDS_MeshFace* SMESHDS_Mesh::AddFace(const SMDS_MeshNode * n1,
1583                                      const SMDS_MeshNode * n2,
1584                                      const SMDS_MeshNode * n3,
1585                                      const SMDS_MeshNode * n12,
1586                                      const SMDS_MeshNode * n23,
1587                                      const SMDS_MeshNode * n31,
1588                                      const SMDS_MeshNode * nCenter)
1589 {
1590   SMDS_MeshFace *anElem = SMDS_Mesh::AddFace(n1,n2,n3,n12,n23,n31,nCenter);
1591   if(anElem) myScript->AddFace(anElem->GetID(), 
1592                                n1->GetID(), n2->GetID(), n3->GetID(),
1593                                n12->GetID(), n23->GetID(), n31->GetID(),
1594                                nCenter->GetID());
1595   return anElem;
1596 }
1597
1598 //=======================================================================
1599 //function : AddFaceWithID
1600 //purpose  : 
1601 //=======================================================================
1602 SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(int n1, int n2, int n3,
1603                                            int n12,int n23,int n31, int nCenter, int ID)
1604 {
1605   SMDS_MeshFace *anElem = SMDS_Mesh::AddFaceWithID(n1,n2,n3,n12,n23,n31,nCenter,ID);
1606   if(anElem) myScript->AddFace(ID,n1,n2,n3,n12,n23,n31,nCenter);
1607   return anElem;
1608 }
1609
1610 //=======================================================================
1611 //function : AddFaceWithID
1612 //purpose  : 
1613 //=======================================================================
1614 SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
1615                                            const SMDS_MeshNode * n2,
1616                                            const SMDS_MeshNode * n3,
1617                                            const SMDS_MeshNode * n12,
1618                                            const SMDS_MeshNode * n23,
1619                                            const SMDS_MeshNode * n31, 
1620                                            const SMDS_MeshNode * nCenter, 
1621                                            int ID)
1622 {
1623   return AddFaceWithID(n1->GetID(), n2->GetID(), n3->GetID(),
1624                        n12->GetID(), n23->GetID(), n31->GetID(),
1625                        nCenter->GetID(), ID);
1626 }
1627
1628
1629 //=======================================================================
1630 //function : AddFace
1631 //purpose  : 
1632 //=======================================================================
1633 SMDS_MeshFace* SMESHDS_Mesh::AddFace(const SMDS_MeshNode * n1,
1634                                      const SMDS_MeshNode * n2,
1635                                      const SMDS_MeshNode * n3,
1636                                      const SMDS_MeshNode * n4,
1637                                      const SMDS_MeshNode * n12,
1638                                      const SMDS_MeshNode * n23,
1639                                      const SMDS_MeshNode * n34,
1640                                      const SMDS_MeshNode * n41)
1641 {
1642   SMDS_MeshFace *anElem = SMDS_Mesh::AddFace(n1,n2,n3,n4,n12,n23,n34,n41);
1643   if(anElem) myScript->AddFace(anElem->GetID(), 
1644                                n1->GetID(), n2->GetID(), n3->GetID(), n4->GetID(),
1645                                n12->GetID(), n23->GetID(), n34->GetID(), n41->GetID());
1646   return anElem;
1647 }
1648
1649 //=======================================================================
1650 //function : AddFaceWithID
1651 //purpose  : 
1652 //=======================================================================
1653 SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(int n1, int n2, int n3, int n4,
1654                                            int n12,int n23,int n34,int n41, int ID)
1655 {
1656   SMDS_MeshFace *anElem = SMDS_Mesh::AddFaceWithID(n1,n2,n3,n4,n12,n23,n34,n41,ID);
1657   if(anElem) myScript->AddFace(ID,n1,n2,n3,n4,n12,n23,n34,n41);
1658   return anElem;
1659 }
1660
1661 //=======================================================================
1662 //function : AddFaceWithID
1663 //purpose  : 
1664 //=======================================================================
1665 SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
1666                                            const SMDS_MeshNode * n2,
1667                                            const SMDS_MeshNode * n3,
1668                                            const SMDS_MeshNode * n4,
1669                                            const SMDS_MeshNode * n12,
1670                                            const SMDS_MeshNode * n23,
1671                                            const SMDS_MeshNode * n34, 
1672                                            const SMDS_MeshNode * n41, 
1673                                            int ID)
1674 {
1675   return AddFaceWithID(n1->GetID(), n2->GetID(), n3->GetID(), n4->GetID(),
1676                        n12->GetID(), n23->GetID(), n34->GetID(), n41->GetID(),
1677                        ID);
1678 }
1679
1680
1681 //=======================================================================
1682 //function : AddFace
1683 //purpose  : 
1684 //=======================================================================
1685 SMDS_MeshFace* SMESHDS_Mesh::AddFace(const SMDS_MeshNode * n1,
1686                                      const SMDS_MeshNode * n2,
1687                                      const SMDS_MeshNode * n3,
1688                                      const SMDS_MeshNode * n4,
1689                                      const SMDS_MeshNode * n12,
1690                                      const SMDS_MeshNode * n23,
1691                                      const SMDS_MeshNode * n34,
1692                                      const SMDS_MeshNode * n41, 
1693                                      const SMDS_MeshNode * nCenter)
1694 {
1695   SMDS_MeshFace *anElem = SMDS_Mesh::AddFace(n1,n2,n3,n4,n12,n23,n34,n41,nCenter);
1696   if(anElem) myScript->AddFace(anElem->GetID(), 
1697                                n1->GetID(), n2->GetID(), n3->GetID(), n4->GetID(),
1698                                n12->GetID(), n23->GetID(), n34->GetID(), n41->GetID(),
1699                                nCenter->GetID());
1700   return anElem;
1701 }
1702
1703 //=======================================================================
1704 //function : AddFaceWithID
1705 //purpose  : 
1706 //=======================================================================
1707 SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(int n1, int n2, int n3, int n4,
1708                                            int n12,int n23,int n34,int n41,
1709                                            int nCenter, int ID)
1710 {
1711   SMDS_MeshFace *anElem = SMDS_Mesh::AddFaceWithID(n1,n2,n3,n4,n12,n23,n34,n41,nCenter,ID);
1712   if(anElem) myScript->AddFace(ID,n1,n2,n3,n4,n12,n23,n34,n41,nCenter);
1713   return anElem;
1714 }
1715
1716 //=======================================================================
1717 //function : AddFaceWithID
1718 //purpose  : 
1719 //=======================================================================
1720 SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
1721                                            const SMDS_MeshNode * n2,
1722                                            const SMDS_MeshNode * n3,
1723                                            const SMDS_MeshNode * n4,
1724                                            const SMDS_MeshNode * n12,
1725                                            const SMDS_MeshNode * n23,
1726                                            const SMDS_MeshNode * n34, 
1727                                            const SMDS_MeshNode * n41, 
1728                                            const SMDS_MeshNode * nCenter, 
1729                                            int ID)
1730 {
1731   return AddFaceWithID(n1->GetID(), n2->GetID(), n3->GetID(), n4->GetID(),
1732                        n12->GetID(), n23->GetID(), n34->GetID(), n41->GetID(),
1733                        nCenter->GetID(), ID);
1734 }
1735
1736
1737 //=======================================================================
1738 //function : AddVolume
1739 //purpose  : 
1740 //=======================================================================
1741 SMDS_MeshVolume* SMESHDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
1742                                          const SMDS_MeshNode * n2, 
1743                                          const SMDS_MeshNode * n3,
1744                                          const SMDS_MeshNode * n4,
1745                                          const SMDS_MeshNode * n12,
1746                                          const SMDS_MeshNode * n23,
1747                                          const SMDS_MeshNode * n31,
1748                                          const SMDS_MeshNode * n14, 
1749                                          const SMDS_MeshNode * n24,
1750                                          const SMDS_MeshNode * n34)
1751 {
1752   SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolume(n1,n2,n3,n4,n12,n23,n31,n14,n24,n34);
1753   if(anElem) myScript->AddVolume(anElem->GetID(), 
1754                                  n1->GetID(), n2->GetID(), n3->GetID(), n4->GetID(),
1755                                  n12->GetID(), n23->GetID(), n31->GetID(),
1756                                  n14->GetID(), n24->GetID(), n34->GetID());
1757   return anElem;
1758 }
1759
1760 //=======================================================================
1761 //function : AddVolumeWithID
1762 //purpose  : 
1763 //=======================================================================
1764 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4,
1765                                                int n12,int n23,int n31,
1766                                                int n14,int n24,int n34, int ID)
1767 {
1768   SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolumeWithID(n1,n2,n3,n4,n12,n23,
1769                                                        n31,n14,n24,n34,ID);
1770   if(anElem) myScript->AddVolume(ID,n1,n2,n3,n4,n12,n23,n31,n14,n24,n34);
1771   return anElem;
1772 }
1773         
1774 //=======================================================================
1775 //function : AddVolumeWithID
1776 //purpose  : 2d order tetrahedron of 10 nodes
1777 //=======================================================================
1778 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
1779                                                const SMDS_MeshNode * n2,
1780                                                const SMDS_MeshNode * n3,
1781                                                const SMDS_MeshNode * n4,
1782                                                const SMDS_MeshNode * n12,
1783                                                const SMDS_MeshNode * n23,
1784                                                const SMDS_MeshNode * n31,
1785                                                const SMDS_MeshNode * n14, 
1786                                                const SMDS_MeshNode * n24,
1787                                                const SMDS_MeshNode * n34,
1788                                                int ID)
1789 {
1790   return AddVolumeWithID(n1->GetID(), n2->GetID(), n3->GetID(), n4->GetID(),
1791                          n12->GetID(), n23->GetID(), n31->GetID(),
1792                          n14->GetID(), n24->GetID(), n34->GetID(), ID);
1793 }
1794
1795
1796 //=======================================================================
1797 //function : AddVolume
1798 //purpose  : 
1799 //=======================================================================
1800 SMDS_MeshVolume* SMESHDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
1801                                          const SMDS_MeshNode * n2, 
1802                                          const SMDS_MeshNode * n3,
1803                                          const SMDS_MeshNode * n4,
1804                                          const SMDS_MeshNode * n5, 
1805                                          const SMDS_MeshNode * n12,
1806                                          const SMDS_MeshNode * n23,
1807                                          const SMDS_MeshNode * n34,
1808                                          const SMDS_MeshNode * n41,
1809                                          const SMDS_MeshNode * n15, 
1810                                          const SMDS_MeshNode * n25,
1811                                          const SMDS_MeshNode * n35,
1812                                          const SMDS_MeshNode * n45)
1813 {
1814   SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolume(n1,n2,n3,n4,n5,n12,n23,n34,n41,
1815                                                  n15,n25,n35,n45);
1816   if(anElem)
1817     myScript->AddVolume(anElem->GetID(), n1->GetID(), n2->GetID(),
1818                         n3->GetID(), n4->GetID(), n5->GetID(),
1819                         n12->GetID(), n23->GetID(), n34->GetID(), n41->GetID(),
1820                         n15->GetID(), n25->GetID(), n35->GetID(), n45->GetID());
1821   return anElem;
1822 }
1823
1824 //=======================================================================
1825 //function : AddVolumeWithID
1826 //purpose  : 
1827 //=======================================================================
1828 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4, int n5,
1829                                                int n12,int n23,int n34,int n41,
1830                                                int n15,int n25,int n35,int n45, int ID)
1831 {
1832   SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolumeWithID(n1,n2,n3,n4,n5,
1833                                                        n12,n23,n34,n41,
1834                                                        n15,n25,n35,n45,ID);
1835   if(anElem) myScript->AddVolume(ID,n1,n2,n3,n4,n5,n12,n23,n34,n41,
1836                                  n15,n25,n35,n45);
1837   return anElem;
1838 }
1839         
1840 //=======================================================================
1841 //function : AddVolumeWithID
1842 //purpose  : 2d order pyramid of 13 nodes
1843 //=======================================================================
1844 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
1845                                                const SMDS_MeshNode * n2,
1846                                                const SMDS_MeshNode * n3,
1847                                                const SMDS_MeshNode * n4,
1848                                                const SMDS_MeshNode * n5, 
1849                                                const SMDS_MeshNode * n12,
1850                                                const SMDS_MeshNode * n23,
1851                                                const SMDS_MeshNode * n34,
1852                                                const SMDS_MeshNode * n41,
1853                                                const SMDS_MeshNode * n15, 
1854                                                const SMDS_MeshNode * n25,
1855                                                const SMDS_MeshNode * n35,
1856                                                const SMDS_MeshNode * n45,
1857                                                int ID)
1858 {
1859   return AddVolumeWithID(n1->GetID(), n2->GetID(), n3->GetID(),
1860                          n4->GetID(), n5->GetID(),
1861                          n12->GetID(), n23->GetID(), n34->GetID(), n41->GetID(),
1862                          n15->GetID(), n25->GetID(), n35->GetID(), n45->GetID(),
1863                          ID);
1864 }
1865
1866
1867 //=======================================================================
1868 //function : AddVolume
1869 //purpose  : 2nd order pentahedron (prism) with 15 nodes
1870 //=======================================================================
1871 SMDS_MeshVolume* SMESHDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
1872                                          const SMDS_MeshNode * n2, 
1873                                          const SMDS_MeshNode * n3,
1874                                          const SMDS_MeshNode * n4,
1875                                          const SMDS_MeshNode * n5, 
1876                                          const SMDS_MeshNode * n6, 
1877                                          const SMDS_MeshNode * n12,
1878                                          const SMDS_MeshNode * n23,
1879                                          const SMDS_MeshNode * n31, 
1880                                          const SMDS_MeshNode * n45,
1881                                          const SMDS_MeshNode * n56,
1882                                          const SMDS_MeshNode * n64, 
1883                                          const SMDS_MeshNode * n14,
1884                                          const SMDS_MeshNode * n25,
1885                                          const SMDS_MeshNode * n36)
1886 {
1887   SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolume(n1,n2,n3,n4,n5,n6,n12,n23,n31,
1888                                                  n45,n56,n64,n14,n25,n36);
1889   if(anElem)
1890     myScript->AddVolume(anElem->GetID(), n1->GetID(), n2->GetID(),
1891                         n3->GetID(), n4->GetID(), n5->GetID(), n6->GetID(),
1892                         n12->GetID(), n23->GetID(), n31->GetID(),
1893                         n45->GetID(), n56->GetID(), n64->GetID(),
1894                         n14->GetID(), n25->GetID(), n36->GetID());
1895   return anElem;
1896 }
1897
1898 //=======================================================================
1899 //function : AddVolumeWithID
1900 //purpose  : 2nd order pentahedron (prism) with 15 nodes
1901 //=======================================================================
1902 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(int n1, int n2, int n3,
1903                                                int n4, int n5, int n6,
1904                                                int n12,int n23,int n31,
1905                                                int n45,int n56,int n64,
1906                                                int n14,int n25,int n36, int ID)
1907 {
1908   SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolumeWithID(n1,n2,n3,n4,n5,n6,
1909                                                        n12,n23,n31,
1910                                                        n45,n56,n64,
1911                                                        n14,n25,n36,ID);
1912   if(anElem) myScript->AddVolume(ID,n1,n2,n3,n4,n5,n6,n12,n23,n31,
1913                                  n45,n56,n64,n14,n25,n36);
1914   return anElem;
1915 }
1916
1917 //=======================================================================
1918 //function : AddVolumeWithID
1919 //purpose  : 2d order Pentahedron (prism) with 15 nodes
1920 //=======================================================================
1921 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
1922                                                const SMDS_MeshNode * n2,
1923                                                const SMDS_MeshNode * n3,
1924                                                const SMDS_MeshNode * n4,
1925                                                const SMDS_MeshNode * n5,
1926                                                const SMDS_MeshNode * n6,
1927                                                const SMDS_MeshNode * n12,
1928                                                const SMDS_MeshNode * n23,
1929                                                const SMDS_MeshNode * n31,
1930                                                const SMDS_MeshNode * n45,
1931                                                const SMDS_MeshNode * n56,
1932                                                const SMDS_MeshNode * n64,
1933                                                const SMDS_MeshNode * n14,
1934                                                const SMDS_MeshNode * n25,
1935                                                const SMDS_MeshNode * n36,
1936                                                int ID)
1937 {
1938   return AddVolumeWithID(n1->GetID(), n2->GetID(), n3->GetID(),
1939                          n4->GetID(), n5->GetID(), n6->GetID(),
1940                          n12->GetID(), n23->GetID(), n31->GetID(),
1941                          n45->GetID(), n56->GetID(), n64->GetID(),
1942                          n14->GetID(), n25->GetID(), n36->GetID(),
1943                          ID);
1944 }
1945 //=======================================================================
1946 //function : AddVolume
1947 //purpose  : 2nd order pentahedron (prism) with 18 nodes
1948 //=======================================================================
1949 SMDS_MeshVolume* SMESHDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
1950                                          const SMDS_MeshNode * n2,
1951                                          const SMDS_MeshNode * n3,
1952                                          const SMDS_MeshNode * n4,
1953                                          const SMDS_MeshNode * n5,
1954                                          const SMDS_MeshNode * n6,
1955                                          const SMDS_MeshNode * n12,
1956                                          const SMDS_MeshNode * n23,
1957                                          const SMDS_MeshNode * n31,
1958                                          const SMDS_MeshNode * n45,
1959                                          const SMDS_MeshNode * n56,
1960                                          const SMDS_MeshNode * n64,
1961                                          const SMDS_MeshNode * n14,
1962                                          const SMDS_MeshNode * n25,
1963                                          const SMDS_MeshNode * n36,
1964                                          const SMDS_MeshNode * n1245,
1965                                          const SMDS_MeshNode * n2356,
1966                                          const SMDS_MeshNode * n1346)
1967 {
1968   SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolume(n1,n2,n3,n4,n5,n6,n12,n23,n31,
1969                                                  n45,n56,n64,n14,n25,n36,
1970                                                  n1245, n2356, n1346);
1971   if(anElem)
1972     myScript->AddVolume(anElem->GetID(), n1->GetID(), n2->GetID(),
1973                         n3->GetID(), n4->GetID(), n5->GetID(), n6->GetID(),
1974                         n12->GetID(), n23->GetID(), n31->GetID(),
1975                         n45->GetID(), n56->GetID(), n64->GetID(),
1976                         n14->GetID(), n25->GetID(), n36->GetID(),
1977                         n1245->GetID(), n2356->GetID(), n1346->GetID());
1978   return anElem;
1979 }
1980
1981 //=======================================================================
1982 //function : AddVolumeWithID
1983 //purpose  : 2nd order pentahedron (prism) with 18 nodes
1984 //=======================================================================
1985 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(int n1, int n2, int n3,
1986                                                int n4, int n5, int n6,
1987                                                int n12,int n23,int n31,
1988                                                int n45,int n56,int n64,
1989                                                int n14,int n25,int n36,
1990                                                int n1245, int n2356, int n1346,
1991                                                int ID)
1992 {
1993   SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolumeWithID(n1,n2,n3,n4,n5,n6,
1994                                                        n12,n23,n31,
1995                                                        n45,n56,n64,
1996                                                        n14,n25,n36,
1997                                                        n1245, n2356, n1346, ID);
1998   if(anElem) myScript->AddVolume(ID,n1,n2,n3,n4,n5,n6,n12,n23,n31,
1999                                  n45,n56,n64,n14,n25,n36, n1245, n2356, n1346);
2000   return anElem;
2001 }
2002         
2003 //=======================================================================
2004 //function : AddVolumeWithID
2005 //purpose  : 2d order Pentahedron with 18 nodes
2006 //=======================================================================
2007 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
2008                                                const SMDS_MeshNode * n2,
2009                                                const SMDS_MeshNode * n3,
2010                                                const SMDS_MeshNode * n4,
2011                                                const SMDS_MeshNode * n5, 
2012                                                const SMDS_MeshNode * n6, 
2013                                                const SMDS_MeshNode * n12,
2014                                                const SMDS_MeshNode * n23,
2015                                                const SMDS_MeshNode * n31, 
2016                                                const SMDS_MeshNode * n45,
2017                                                const SMDS_MeshNode * n56,
2018                                                const SMDS_MeshNode * n64, 
2019                                                const SMDS_MeshNode * n14,
2020                                                const SMDS_MeshNode * n25,
2021                                                const SMDS_MeshNode * n36,
2022                                                const SMDS_MeshNode * n1245,
2023                                                const SMDS_MeshNode * n2356,
2024                                                const SMDS_MeshNode * n1346,
2025                                                int ID)
2026 {
2027   return AddVolumeWithID(n1->GetID(), n2->GetID(), n3->GetID(),
2028                          n4->GetID(), n5->GetID(), n6->GetID(),
2029                          n12->GetID(), n23->GetID(), n31->GetID(),
2030                          n45->GetID(), n56->GetID(), n64->GetID(),
2031                          n14->GetID(), n25->GetID(), n36->GetID(),
2032                          n1245->GetID(), n2356->GetID(), n1346->GetID(), ID);
2033 }
2034
2035
2036 //=======================================================================
2037 //function : AddVolume
2038 //purpose  : add quadratic hexahedron
2039 //=======================================================================
2040 SMDS_MeshVolume* SMESHDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
2041                                          const SMDS_MeshNode * n2, 
2042                                          const SMDS_MeshNode * n3,
2043                                          const SMDS_MeshNode * n4,
2044                                          const SMDS_MeshNode * n5, 
2045                                          const SMDS_MeshNode * n6, 
2046                                          const SMDS_MeshNode * n7,
2047                                          const SMDS_MeshNode * n8, 
2048                                          const SMDS_MeshNode * n12,
2049                                          const SMDS_MeshNode * n23,
2050                                          const SMDS_MeshNode * n34,
2051                                          const SMDS_MeshNode * n41, 
2052                                          const SMDS_MeshNode * n56,
2053                                          const SMDS_MeshNode * n67,
2054                                          const SMDS_MeshNode * n78,
2055                                          const SMDS_MeshNode * n85, 
2056                                          const SMDS_MeshNode * n15,
2057                                          const SMDS_MeshNode * n26,
2058                                          const SMDS_MeshNode * n37,
2059                                          const SMDS_MeshNode * n48)
2060 {
2061   SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolume(n1,n2,n3,n4,n5,n6,n7,n8,
2062                                                  n12,n23,n34,n41,
2063                                                  n56,n67,n78,n85,
2064                                                  n15,n26,n37,n48);
2065   if(anElem)
2066     myScript->AddVolume(anElem->GetID(), n1->GetID(), n2->GetID(),
2067                         n3->GetID(), n4->GetID(), n5->GetID(),
2068                         n6->GetID(), n7->GetID(), n8->GetID(),
2069                         n12->GetID(), n23->GetID(), n34->GetID(), n41->GetID(),
2070                         n56->GetID(), n67->GetID(), n78->GetID(), n85->GetID(),
2071                         n15->GetID(), n26->GetID(), n37->GetID(), n48->GetID());
2072   return anElem;
2073 }
2074
2075 //=======================================================================
2076 //function : AddVolumeWithID
2077 //purpose  : 
2078 //=======================================================================
2079 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4,
2080                                                int n5, int n6, int n7, int n8,
2081                                                int n12,int n23,int n34,int n41,
2082                                                int n56,int n67,int n78,int n85,
2083                                                int n15,int n26,int n37,int n48, int ID)
2084 {
2085   SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolumeWithID(n1,n2,n3,n4,n5,n6,n7,n8,
2086                                                        n12,n23,n34,n41,
2087                                                        n56,n67,n78,n85,
2088                                                        n15,n26,n37,n48,ID);
2089   if(anElem) myScript->AddVolume(ID,n1,n2,n3,n4,n5,n6,n7,n8,n12,n23,n34,n41,
2090                                  n56,n67,n78,n85,n15,n26,n37,n48);
2091   return anElem;
2092 }
2093         
2094 //=======================================================================
2095 //function : AddVolumeWithID
2096 //purpose  : 2d order Hexahedrons with 20 nodes
2097 //=======================================================================
2098 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
2099                                                const SMDS_MeshNode * n2,
2100                                                const SMDS_MeshNode * n3,
2101                                                const SMDS_MeshNode * n4,
2102                                                const SMDS_MeshNode * n5, 
2103                                                const SMDS_MeshNode * n6, 
2104                                                const SMDS_MeshNode * n7,
2105                                                const SMDS_MeshNode * n8, 
2106                                                const SMDS_MeshNode * n12,
2107                                                const SMDS_MeshNode * n23,
2108                                                const SMDS_MeshNode * n34,
2109                                                const SMDS_MeshNode * n41, 
2110                                                const SMDS_MeshNode * n56,
2111                                                const SMDS_MeshNode * n67,
2112                                                const SMDS_MeshNode * n78,
2113                                                const SMDS_MeshNode * n85, 
2114                                                const SMDS_MeshNode * n15,
2115                                                const SMDS_MeshNode * n26,
2116                                                const SMDS_MeshNode * n37,
2117                                                const SMDS_MeshNode * n48,
2118                                                int ID)
2119 {
2120   return AddVolumeWithID(n1->GetID(), n2->GetID(), n3->GetID(), n4->GetID(),
2121                          n5->GetID(), n6->GetID(), n7->GetID(), n8->GetID(),
2122                          n12->GetID(), n23->GetID(), n34->GetID(), n41->GetID(),
2123                          n56->GetID(), n67->GetID(), n78->GetID(), n85->GetID(),
2124                          n15->GetID(), n26->GetID(), n37->GetID(), n48->GetID(),
2125                          ID);
2126 }
2127
2128 //=======================================================================
2129 //function : AddVolume
2130 //purpose  : add tri-quadratic hexahedron of 27 nodes
2131 //=======================================================================
2132
2133 SMDS_MeshVolume* SMESHDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
2134                                          const SMDS_MeshNode * n2, 
2135                                          const SMDS_MeshNode * n3,
2136                                          const SMDS_MeshNode * n4,
2137                                          const SMDS_MeshNode * n5, 
2138                                          const SMDS_MeshNode * n6, 
2139                                          const SMDS_MeshNode * n7,
2140                                          const SMDS_MeshNode * n8, 
2141                                          const SMDS_MeshNode * n12,
2142                                          const SMDS_MeshNode * n23,
2143                                          const SMDS_MeshNode * n34,
2144                                          const SMDS_MeshNode * n41, 
2145                                          const SMDS_MeshNode * n56,
2146                                          const SMDS_MeshNode * n67,
2147                                          const SMDS_MeshNode * n78,
2148                                          const SMDS_MeshNode * n85, 
2149                                          const SMDS_MeshNode * n15,
2150                                          const SMDS_MeshNode * n26,
2151                                          const SMDS_MeshNode * n37,
2152                                          const SMDS_MeshNode * n48, 
2153                                          const SMDS_MeshNode * n1234,
2154                                          const SMDS_MeshNode * n1256,
2155                                          const SMDS_MeshNode * n2367,
2156                                          const SMDS_MeshNode * n3478,
2157                                          const SMDS_MeshNode * n1458,
2158                                          const SMDS_MeshNode * n5678,
2159                                          const SMDS_MeshNode * nCenter)
2160 {
2161   SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolume(n1,n2,n3,n4,n5,n6,n7,n8,
2162                                                  n12,n23,n34,n41,
2163                                                  n56,n67,n78,n85,
2164                                                  n15,n26,n37,n48,
2165                                                  n1234,n1256,n2367,n3478,n1458,n5678,nCenter);
2166   if(anElem)
2167     myScript->AddVolume(anElem->GetID(), n1->GetID(), n2->GetID(),
2168                         n3->GetID(), n4->GetID(), n5->GetID(),
2169                         n6->GetID(), n7->GetID(), n8->GetID(),
2170                         n12->GetID(), n23->GetID(), n34->GetID(), n41->GetID(),
2171                         n56->GetID(), n67->GetID(), n78->GetID(), n85->GetID(),
2172                         n15->GetID(), n26->GetID(), n37->GetID(), n48->GetID(),
2173                         n1234->GetID(),n1256->GetID(),n2367->GetID(),n3478->GetID(),
2174                         n1458->GetID(),n5678->GetID(),nCenter->GetID());
2175   return anElem;
2176 }
2177
2178 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4,
2179                                                int n5, int n6, int n7, int n8,
2180                                                int n12,int n23,int n34,int n41,
2181                                                int n56,int n67,int n78,int n85,
2182                                                int n15,int n26,int n37,int n48,
2183                                                int n1234,int n1256,int n2367,int n3478,
2184                                                int n1458,int n5678,int nCenter,
2185                                                int ID)
2186 {
2187   SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolumeWithID(n1,n2,n3,n4,n5,n6,n7,n8,
2188                                                        n12,n23,n34,n41,
2189                                                        n56,n67,n78,n85,
2190                                                        n15,n26,n37,n48,
2191                                                        n1234, n1256, n2367, n3478,
2192                                                        n1458, n5678, nCenter,
2193                                                        ID);
2194   if(anElem) myScript->AddVolume(ID,n1,n2,n3,n4,n5,n6,n7,n8,n12,n23,n34,n41,
2195                                  n56,n67,n78,n85,n15,n26,n37,n48,
2196                                  n1234, n1256, n2367, n3478,
2197                                  n1458, n5678, nCenter);
2198   return anElem;
2199 }
2200
2201 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
2202                                                const SMDS_MeshNode * n2,
2203                                                const SMDS_MeshNode * n3,
2204                                                const SMDS_MeshNode * n4,
2205                                                const SMDS_MeshNode * n5,
2206                                                const SMDS_MeshNode * n6,
2207                                                const SMDS_MeshNode * n7,
2208                                                const SMDS_MeshNode * n8,
2209                                                const SMDS_MeshNode * n12,
2210                                                const SMDS_MeshNode * n23,
2211                                                const SMDS_MeshNode * n34,
2212                                                const SMDS_MeshNode * n41,
2213                                                const SMDS_MeshNode * n56,
2214                                                const SMDS_MeshNode * n67,
2215                                                const SMDS_MeshNode * n78,
2216                                                const SMDS_MeshNode * n85,
2217                                                const SMDS_MeshNode * n15,
2218                                                const SMDS_MeshNode * n26,
2219                                                const SMDS_MeshNode * n37,
2220                                                const SMDS_MeshNode * n48,
2221                                                const SMDS_MeshNode * n1234,
2222                                                const SMDS_MeshNode * n1256,
2223                                                const SMDS_MeshNode * n2367,
2224                                                const SMDS_MeshNode * n3478,
2225                                                const SMDS_MeshNode * n1458,
2226                                                const SMDS_MeshNode * n5678,
2227                                                const SMDS_MeshNode * nCenter,
2228                                                int ID)
2229 {
2230   return AddVolumeWithID(n1->GetID(), n2->GetID(), n3->GetID(), n4->GetID(),
2231                          n5->GetID(), n6->GetID(), n7->GetID(), n8->GetID(),
2232                          n12->GetID(), n23->GetID(), n34->GetID(), n41->GetID(),
2233                          n56->GetID(), n67->GetID(), n78->GetID(), n85->GetID(),
2234                          n15->GetID(), n26->GetID(), n37->GetID(), n48->GetID(),
2235                          n1234->GetID(),n1256->GetID(),n2367->GetID(),n3478->GetID(),
2236                          n1458->GetID(),n5678->GetID(),nCenter->GetID(), ID);
2237 }
2238
2239 void SMESHDS_Mesh::CompactMesh()
2240 {
2241   if ( IsCompacted() )
2242     return;
2243
2244   SMDS_Mesh::CompactMesh();
2245
2246   this->myScript->SetModified(true); // notify GUI client for buildPrs when update
2247 }
2248
2249 void SMESHDS_Mesh::CleanDownWardConnectivity()
2250 {
2251   myGrid->CleanDownwardConnectivity();
2252 }
2253
2254 void SMESHDS_Mesh::BuildDownWardConnectivity(bool withEdges)
2255 {
2256   myGrid->BuildDownwardConnectivity(withEdges);
2257 }
2258
2259 /*! change some nodes in cell without modifying type or internal connectivity.
2260  * Nodes inverse connectivity is maintained up to date.
2261  * @param vtkVolId vtk id of the cell.
2262  * @param localClonedNodeIds map old node id to new node id.
2263  * @return ok if success.
2264  */
2265 bool SMESHDS_Mesh::ModifyCellNodes(int vtkVolId, std::map<int,int> localClonedNodeIds)
2266 {
2267   myGrid->ModifyCellNodes(vtkVolId, localClonedNodeIds);
2268   return true;
2269 }