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