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