Salome HOME
Adjust to CVS HEAD modifications
[modules/smesh.git] / src / SMESHDS / SMESHDS_Mesh.cxx
1 //  SMESH SMESHDS : management of mesh data and SMESH document
2 //
3 //  Copyright (C) 2003  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 //  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS 
5 // 
6 //  This library is free software; you can redistribute it and/or 
7 //  modify it under the terms of the GNU Lesser General Public 
8 //  License as published by the Free Software Foundation; either 
9 //  version 2.1 of the License. 
10 // 
11 //  This library is distributed in the hope that it will be useful, 
12 //  but WITHOUT ANY WARRANTY; without even the implied warranty of 
13 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
14 //  Lesser General Public License for more details. 
15 // 
16 //  You should have received a copy of the GNU Lesser General Public 
17 //  License along with this library; if not, write to the Free Software 
18 //  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA 
19 // 
20 //  See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org 
21 //
22 //
23 //
24 //  File   : SMESH_Mesh.cxx
25 //  Author : Yves FRICAUD, OCC
26 //  Module : SMESH
27 //  $Header: 
28
29 #include "SMESHDS_Mesh.hxx"
30
31 #include "SMESHDS_Group.hxx"
32 #include "SMDS_VertexPosition.hxx"
33 #include "SMDS_EdgePosition.hxx"
34 #include "SMDS_FacePosition.hxx"
35 #include "SMESHDS_GroupOnGeom.hxx"
36 #include <TopExp_Explorer.hxx>
37 #include <TopExp.hxx>
38 #include <TopoDS_Iterator.hxx>
39
40 #include "utilities.h"
41
42 using namespace std;
43
44 //=======================================================================
45 //function : Create
46 //purpose  : 
47 //=======================================================================
48 SMESHDS_Mesh::SMESHDS_Mesh(int MeshID):myMeshID(MeshID)
49 {
50         myScript = new SMESHDS_Script();
51 }
52
53 //=======================================================================
54 //function : ShapeToMesh
55 //purpose  : 
56 //=======================================================================
57 void SMESHDS_Mesh::ShapeToMesh(const TopoDS_Shape & S)
58 {
59   if ( !myShape.IsNull() && S.IsNull() )
60   {
61     // removal of a shape to mesh, delete ...
62     // - hypotheses
63     myShapeToHypothesis.clear();
64     // - shape indices in SMDS_Position of nodes
65     map<int,SMESHDS_SubMesh*>::iterator i_sub = myShapeIndexToSubMesh.begin();
66     for ( ; i_sub != myShapeIndexToSubMesh.end(); i_sub++ ) {
67       if ( !i_sub->second->IsComplexSubmesh() ) {
68         SMDS_NodeIteratorPtr nIt = i_sub->second->GetNodes();
69         while ( nIt->more() )
70           nIt->next()->GetPosition()->SetShapeId( 0 );
71       }
72     }
73     // - sub-meshes
74     myIndexToShape.Clear();
75     myShapeIndexToSubMesh.clear();
76     // - groups on geometry
77     set<SMESHDS_GroupBase*>::iterator gr = myGroups.begin();
78     while ( gr != myGroups.end() ) {
79       if ( dynamic_cast<SMESHDS_GroupOnGeom*>( *gr ))
80         myGroups.erase( gr++ );
81       else
82         gr++;
83     }
84   }
85   else {
86     myShape = S;
87     if ( !S.IsNull() )
88       TopExp::MapShapes(myShape, myIndexToShape);
89   }
90 }
91
92 //=======================================================================
93 //function : AddHypothesis
94 //purpose  : 
95 //=======================================================================
96
97 bool SMESHDS_Mesh::AddHypothesis(const TopoDS_Shape & SS,
98         const SMESHDS_Hypothesis * H)
99 {
100         list<const SMESHDS_Hypothesis *>& alist=myShapeToHypothesis[SS];
101
102         //Check if the Hypothesis is still present
103         list<const SMESHDS_Hypothesis*>::iterator ith=alist.begin();
104
105         for (; ith!=alist.end(); ith++)
106                 if (H == *ith) return false;
107
108         alist.push_back(H);
109         return true;
110 }
111
112 //=======================================================================
113 //function : RemoveHypothesis
114 //purpose  : 
115 //=======================================================================
116
117 bool SMESHDS_Mesh::RemoveHypothesis(const TopoDS_Shape & S,
118         const SMESHDS_Hypothesis * H)
119 {
120         ShapeToHypothesis::iterator its=myShapeToHypothesis.find(S);
121         if(its!=myShapeToHypothesis.end())
122         {
123                 list<const SMESHDS_Hypothesis*>::iterator ith=(*its).second.begin();
124
125                 for (; ith!=(*its).second.end(); ith++)
126                         if (H == *ith)
127                         {
128                                 (*its).second.erase(ith);
129                                 return true;
130                         }
131         }
132         return false;
133 }
134
135 //=======================================================================
136 //function : AddNode
137 //purpose  : 
138 //=======================================================================
139 SMDS_MeshNode* SMESHDS_Mesh::AddNode(double x, double y, double z){
140   SMDS_MeshNode* node = SMDS_Mesh::AddNode(x, y, z);
141   if(node!=NULL) myScript->AddNode(node->GetID(), x, y, z);
142   return node;
143 }
144
145 SMDS_MeshNode* SMESHDS_Mesh::AddNodeWithID(double x, double y, double z, int ID){
146   SMDS_MeshNode* node = SMDS_Mesh::AddNodeWithID(x,y,z,ID);
147   if(node!=NULL) myScript->AddNode(node->GetID(), x, y, z);
148   return node;
149 }
150
151 //=======================================================================
152 //function : MoveNode
153 //purpose  : 
154 //=======================================================================
155 void SMESHDS_Mesh::MoveNode(const SMDS_MeshNode *n, double x, double y, double z)
156 {
157   SMDS_MeshNode * node=const_cast<SMDS_MeshNode*>(n);
158   node->setXYZ(x,y,z);
159   myScript->MoveNode(n->GetID(), x, y, z);
160 }
161
162 //=======================================================================
163 //function : ChangeElementNodes
164 //purpose  : 
165 //=======================================================================
166
167 bool SMESHDS_Mesh::ChangeElementNodes(const SMDS_MeshElement * elem,
168                                       const SMDS_MeshNode    * nodes[],
169                                       const int                nbnodes)
170 {
171   if ( ! SMDS_Mesh::ChangeElementNodes( elem, nodes, nbnodes ))
172     return false;
173
174   vector<int> IDs( nbnodes );
175   for ( int i = 0; i < nbnodes; i++ )
176     IDs [ i ] = nodes[ i ]->GetID();
177   myScript->ChangeElementNodes( elem->GetID(), &IDs[0], nbnodes);
178
179   return true;
180 }
181
182 //=======================================================================
183 //function : ChangePolygonNodes
184 //purpose  : 
185 //=======================================================================
186 bool SMESHDS_Mesh::ChangePolygonNodes
187                    (const SMDS_MeshElement *     elem,
188                     vector<const SMDS_MeshNode*> nodes)
189 {
190   ASSERT(nodes.size() > 3);
191
192   return ChangeElementNodes(elem, &nodes[0], nodes.size());
193 }
194
195 //=======================================================================
196 //function : ChangePolyhedronNodes
197 //purpose  : 
198 //=======================================================================
199 bool SMESHDS_Mesh::ChangePolyhedronNodes
200                    (const SMDS_MeshElement * elem,
201                     std::vector<const SMDS_MeshNode*> nodes,
202                     std::vector<int>                  quantities)
203 {
204   ASSERT(nodes.size() > 3);
205
206   if (!SMDS_Mesh::ChangePolyhedronNodes(elem, nodes, quantities))
207     return false;
208
209   int i, len = nodes.size();
210   std::vector<int> nodes_ids (len);
211   for (i = 0; i < len; i++) {
212     nodes_ids[i] = nodes[i]->GetID();
213   }
214   myScript->ChangePolyhedronNodes(elem->GetID(), nodes_ids, quantities);
215
216   return true;
217 }
218
219 //=======================================================================
220 //function : Renumber
221 //purpose  : 
222 //=======================================================================
223
224 void SMESHDS_Mesh::Renumber (const bool isNodes, const int startID, const int deltaID)
225 {
226   SMDS_Mesh::Renumber( isNodes, startID, deltaID );
227   myScript->Renumber( isNodes, startID, deltaID );
228 }
229
230 //=======================================================================
231 //function :AddEdgeWithID
232 //purpose  : 
233 //=======================================================================
234 SMDS_MeshEdge* SMESHDS_Mesh::AddEdgeWithID(int n1, int n2, int ID)
235 {
236   SMDS_MeshEdge* anElem = SMDS_Mesh::AddEdgeWithID(n1,n2,ID);
237   if(anElem) myScript->AddEdge(ID,n1,n2);
238   return anElem;
239 }
240
241 SMDS_MeshEdge* SMESHDS_Mesh::AddEdgeWithID(const SMDS_MeshNode * n1,
242                                            const SMDS_MeshNode * n2, 
243                                            int ID)
244 {
245   return AddEdgeWithID(n1->GetID(),
246                        n2->GetID(),
247                        ID);
248 }
249
250 SMDS_MeshEdge* SMESHDS_Mesh::AddEdge(const SMDS_MeshNode * n1,
251                                      const SMDS_MeshNode * n2)
252 {
253   SMDS_MeshEdge* anElem = SMDS_Mesh::AddEdge(n1,n2);
254   if(anElem) myScript->AddEdge(anElem->GetID(), 
255                                n1->GetID(), 
256                                n2->GetID());
257   return anElem;
258 }
259
260 //=======================================================================
261 //function :AddFace
262 //purpose  : 
263 //=======================================================================
264 SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(int n1, int n2, int n3, int ID)
265 {
266   SMDS_MeshFace *anElem = SMDS_Mesh::AddFaceWithID(n1, n2, n3, ID);
267   if(anElem) myScript->AddFace(ID,n1,n2,n3);
268   return anElem;
269 }
270
271 SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
272                                            const SMDS_MeshNode * n2,
273                                            const SMDS_MeshNode * n3, 
274                                            int ID)
275 {
276   return AddFaceWithID(n1->GetID(),
277                        n2->GetID(),
278                        n3->GetID(),
279                        ID);
280 }
281
282 SMDS_MeshFace* SMESHDS_Mesh::AddFace( const SMDS_MeshNode * n1,
283                                       const SMDS_MeshNode * n2,
284                                       const SMDS_MeshNode * n3)
285 {
286   SMDS_MeshFace *anElem = SMDS_Mesh::AddFace(n1, n2, n3);
287   if(anElem) myScript->AddFace(anElem->GetID(), 
288                                n1->GetID(), 
289                                n2->GetID(),
290                                n3->GetID());
291   return anElem;
292 }
293
294 //=======================================================================
295 //function :AddFace
296 //purpose  : 
297 //=======================================================================
298 SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(int n1, int n2, int n3, int n4, int ID)
299 {
300   SMDS_MeshFace *anElem = SMDS_Mesh::AddFaceWithID(n1, n2, n3, n4, ID);
301   if(anElem) myScript->AddFace(ID, n1, n2, n3, n4);
302   return anElem;
303 }
304
305 SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
306                                            const SMDS_MeshNode * n2,
307                                            const SMDS_MeshNode * n3,
308                                            const SMDS_MeshNode * n4, 
309                                            int ID)
310 {
311   return AddFaceWithID(n1->GetID(),
312                        n2->GetID(),
313                        n3->GetID(),
314                        n4->GetID(),
315                        ID);
316 }
317
318 SMDS_MeshFace* SMESHDS_Mesh::AddFace(const SMDS_MeshNode * n1,
319                                      const SMDS_MeshNode * n2,
320                                      const SMDS_MeshNode * n3,
321                                      const SMDS_MeshNode * n4)
322 {
323   SMDS_MeshFace *anElem = SMDS_Mesh::AddFace(n1, n2, n3, n4);
324   if(anElem) myScript->AddFace(anElem->GetID(), 
325                                n1->GetID(), 
326                                n2->GetID(), 
327                                n3->GetID(),
328                                n4->GetID());
329   return anElem;
330 }
331
332 //=======================================================================
333 //function :AddVolume
334 //purpose  : 
335 //=======================================================================
336 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4, int ID)
337 {
338   SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, ID);
339   if(anElem) myScript->AddVolume(ID, n1, n2, n3, n4);
340   return anElem;
341 }
342
343 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
344                                                const SMDS_MeshNode * n2,
345                                                const SMDS_MeshNode * n3,
346                                                const SMDS_MeshNode * n4, 
347                                                int ID)
348 {
349   return AddVolumeWithID(n1->GetID(), 
350                          n2->GetID(), 
351                          n3->GetID(),
352                          n4->GetID(),
353                          ID);
354 }
355
356 SMDS_MeshVolume* SMESHDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
357                                          const SMDS_MeshNode * n2,
358                                          const SMDS_MeshNode * n3,
359                                          const SMDS_MeshNode * n4)
360 {
361   SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolume(n1, n2, n3, n4);
362   if(anElem) myScript->AddVolume(anElem->GetID(), 
363                                  n1->GetID(), 
364                                  n2->GetID(), 
365                                  n3->GetID(),
366                                  n4->GetID());
367   return anElem;
368 }
369
370 //=======================================================================
371 //function :AddVolume
372 //purpose  : 
373 //=======================================================================
374 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4, int n5, int ID)
375 {
376   SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, ID);
377   if(anElem) myScript->AddVolume(ID, n1, n2, n3, n4, n5);
378   return anElem;
379 }
380
381 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
382                                                const SMDS_MeshNode * n2,
383                                                const SMDS_MeshNode * n3,
384                                                const SMDS_MeshNode * n4,
385                                                const SMDS_MeshNode * n5, 
386                                                int ID)
387 {
388   return AddVolumeWithID(n1->GetID(), 
389                          n2->GetID(), 
390                          n3->GetID(),
391                          n4->GetID(), 
392                          n5->GetID(),
393                          ID);
394 }
395
396 SMDS_MeshVolume* SMESHDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
397                                          const SMDS_MeshNode * n2,
398                                          const SMDS_MeshNode * n3,
399                                          const SMDS_MeshNode * n4,
400                                          const SMDS_MeshNode * n5)
401 {
402   SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolume(n1, n2, n3, n4, n5);
403   if(anElem) myScript->AddVolume(anElem->GetID(), 
404                                  n1->GetID(), 
405                                  n2->GetID(), 
406                                  n3->GetID(),
407                                  n4->GetID(), 
408                                  n5->GetID());
409   return anElem;
410 }
411
412 //=======================================================================
413 //function :AddVolume
414 //purpose  : 
415 //=======================================================================
416 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4, int n5, int n6, int ID)
417 {
418   SMDS_MeshVolume *anElem= SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, ID);
419   if(anElem) myScript->AddVolume(ID, n1, n2, n3, n4, n5, n6);
420   return anElem;
421 }
422
423 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
424                                                const SMDS_MeshNode * n2,
425                                                const SMDS_MeshNode * n3,
426                                                const SMDS_MeshNode * n4,
427                                                const SMDS_MeshNode * n5,
428                                                const SMDS_MeshNode * n6, 
429                                                int ID)
430 {
431   return AddVolumeWithID(n1->GetID(), 
432                          n2->GetID(), 
433                          n3->GetID(),
434                          n4->GetID(), 
435                          n5->GetID(), 
436                          n6->GetID(),
437                          ID);
438 }
439
440 SMDS_MeshVolume* SMESHDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
441                                          const SMDS_MeshNode * n2,
442                                          const SMDS_MeshNode * n3,
443                                          const SMDS_MeshNode * n4,
444                                          const SMDS_MeshNode * n5,
445                                          const SMDS_MeshNode * n6)
446 {
447   SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolume(n1, n2, n3, n4, n5, n6);
448   if(anElem) myScript->AddVolume(anElem->GetID(), 
449                                  n1->GetID(), 
450                                  n2->GetID(), 
451                                  n3->GetID(),
452                                  n4->GetID(), 
453                                  n5->GetID(), 
454                                  n6->GetID());
455   return anElem;
456 }
457
458 //=======================================================================
459 //function :AddVolume
460 //purpose  : 
461 //=======================================================================
462 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4, int n5, int n6, int n7, int n8, int ID)
463 {
464   SMDS_MeshVolume *anElem= SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, n7, n8, ID);
465   if(anElem) myScript->AddVolume(ID, n1, n2, n3, n4, n5, n6, n7, n8);
466   return anElem;
467 }
468
469 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
470                                                const SMDS_MeshNode * n2,
471                                                const SMDS_MeshNode * n3,
472                                                const SMDS_MeshNode * n4,
473                                                const SMDS_MeshNode * n5,
474                                                const SMDS_MeshNode * n6,
475                                                const SMDS_MeshNode * n7,
476                                                const SMDS_MeshNode * n8, 
477                                                int ID)
478 {
479   return AddVolumeWithID(n1->GetID(), 
480                          n2->GetID(), 
481                          n3->GetID(),
482                          n4->GetID(), 
483                          n5->GetID(), 
484                          n6->GetID(), 
485                          n7->GetID(), 
486                          n8->GetID(),
487                          ID);
488 }
489
490 SMDS_MeshVolume* SMESHDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
491                                          const SMDS_MeshNode * n2,
492                                          const SMDS_MeshNode * n3,
493                                          const SMDS_MeshNode * n4,
494                                          const SMDS_MeshNode * n5,
495                                          const SMDS_MeshNode * n6,
496                                          const SMDS_MeshNode * n7,
497                                          const SMDS_MeshNode * n8)
498 {
499   SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolume(n1, n2, n3, n4, n5, n6, n7, n8);
500   if(anElem) myScript->AddVolume(anElem->GetID(), 
501                                  n1->GetID(), 
502                                  n2->GetID(), 
503                                  n3->GetID(),
504                                  n4->GetID(), 
505                                  n5->GetID(), 
506                                  n6->GetID(), 
507                                  n7->GetID(), 
508                                  n8->GetID());
509   return anElem;
510 }
511
512 //=======================================================================
513 //function : AddPolygonalFace
514 //purpose  : 
515 //=======================================================================
516 SMDS_MeshFace* SMESHDS_Mesh::AddPolygonalFaceWithID (std::vector<int> nodes_ids,
517                                                      const int        ID)
518 {
519   SMDS_MeshFace *anElem = SMDS_Mesh::AddPolygonalFaceWithID(nodes_ids, ID);
520   if (anElem) {
521     myScript->AddPolygonalFace(ID, nodes_ids);
522   }
523   return anElem;
524 }
525
526 SMDS_MeshFace* SMESHDS_Mesh::AddPolygonalFaceWithID
527                              (std::vector<const SMDS_MeshNode*> nodes,
528                               const int                         ID)
529 {
530   SMDS_MeshFace *anElem = SMDS_Mesh::AddPolygonalFaceWithID(nodes, ID);
531   if (anElem) {
532     int i, len = nodes.size();
533     std::vector<int> nodes_ids (len);
534     for (i = 0; i < len; i++) {
535       nodes_ids[i] = nodes[i]->GetID();
536     }
537     myScript->AddPolygonalFace(ID, nodes_ids);
538   }
539   return anElem;
540 }
541
542 SMDS_MeshFace* SMESHDS_Mesh::AddPolygonalFace
543                              (std::vector<const SMDS_MeshNode*> nodes)
544 {
545   SMDS_MeshFace *anElem = SMDS_Mesh::AddPolygonalFace(nodes);
546   if (anElem) {
547     int i, len = nodes.size();
548     std::vector<int> nodes_ids (len);
549     for (i = 0; i < len; i++) {
550       nodes_ids[i] = nodes[i]->GetID();
551     }
552     myScript->AddPolygonalFace(anElem->GetID(), nodes_ids);
553   }
554   return anElem;
555 }
556
557 //=======================================================================
558 //function : AddPolyhedralVolume
559 //purpose  : 
560 //=======================================================================
561 SMDS_MeshVolume* SMESHDS_Mesh::AddPolyhedralVolumeWithID (std::vector<int> nodes_ids,
562                                                           std::vector<int> quantities,
563                                                           const int        ID)
564 {
565   SMDS_MeshVolume *anElem = SMDS_Mesh::AddPolyhedralVolumeWithID(nodes_ids, quantities, ID);
566   if (anElem) {
567     myScript->AddPolyhedralVolume(ID, nodes_ids, quantities);
568   }
569   return anElem;
570 }
571
572 SMDS_MeshVolume* SMESHDS_Mesh::AddPolyhedralVolumeWithID
573                                (std::vector<const SMDS_MeshNode*> nodes,
574                                 std::vector<int>                  quantities,
575                                 const int                         ID)
576 {
577   SMDS_MeshVolume *anElem = SMDS_Mesh::AddPolyhedralVolumeWithID(nodes, quantities, ID);
578   if (anElem) {
579     int i, len = nodes.size();
580     std::vector<int> nodes_ids (len);
581     for (i = 0; i < len; i++) {
582       nodes_ids[i] = nodes[i]->GetID();
583     }
584     myScript->AddPolyhedralVolume(ID, nodes_ids, quantities);
585   }
586   return anElem;
587 }
588
589 SMDS_MeshVolume* SMESHDS_Mesh::AddPolyhedralVolume
590                                (std::vector<const SMDS_MeshNode*> nodes,
591                                 std::vector<int>                  quantities)
592 {
593   SMDS_MeshVolume *anElem = SMDS_Mesh::AddPolyhedralVolume(nodes, quantities);
594   if (anElem) {
595     int i, len = nodes.size();
596     std::vector<int> nodes_ids (len);
597     for (i = 0; i < len; i++) {
598       nodes_ids[i] = nodes[i]->GetID();
599     }
600     myScript->AddPolyhedralVolume(anElem->GetID(), nodes_ids, quantities);
601   }
602   return anElem;
603 }
604
605 //=======================================================================
606 //function : removeFromContainers
607 //purpose  : 
608 //=======================================================================
609
610 static void removeFromContainers (map<int,SMESHDS_SubMesh*> &      theSubMeshes,
611                                   set<SMESHDS_GroupBase*>&             theGroups,
612                                   list<const SMDS_MeshElement *> & theElems,
613                                   const bool                       isNode)
614 {
615   if ( theElems.empty() )
616     return;
617
618   // Rm from group
619   // Element can belong to several groups
620   if ( !theGroups.empty() )
621   {
622     set<SMESHDS_GroupBase*>::iterator GrIt = theGroups.begin();
623     for ( ; GrIt != theGroups.end(); GrIt++ )
624     {
625       SMESHDS_Group* group = dynamic_cast<SMESHDS_Group*>( *GrIt );
626       if ( !group || group->IsEmpty() ) continue;
627
628       list<const SMDS_MeshElement *>::iterator elIt = theElems.begin();
629       for ( ; elIt != theElems.end(); elIt++ )
630       {
631         group->SMDSGroup().Remove( *elIt );
632         if ( group->IsEmpty() ) break;
633       }
634     }
635   }
636
637   // Rm from sub-meshes
638   // Element should belong to only one sub-mesh
639   map<int,SMESHDS_SubMesh*>::iterator SubIt = theSubMeshes.begin();
640   for ( ; SubIt != theSubMeshes.end(); SubIt++ )
641   {
642     int size = isNode ? (*SubIt).second->NbNodes() : (*SubIt).second->NbElements();
643     if ( size == 0 ) continue;
644
645     list<const SMDS_MeshElement *>::iterator elIt = theElems.begin();
646     while ( elIt != theElems.end() )
647     {
648       bool removed = false;
649       if ( isNode )
650         removed = (*SubIt).second->RemoveNode( static_cast<const SMDS_MeshNode*> (*elIt) );
651       else
652         removed = (*SubIt).second->RemoveElement( *elIt );
653
654       if (removed)
655       {
656         elIt = theElems.erase( elIt );
657         if ( theElems.empty() )
658           return; // all elements are found and removed
659       }
660       else
661       {
662         elIt++ ;
663       }
664     }
665   }
666 }
667   
668 //=======================================================================
669 //function : RemoveNode
670 //purpose  : 
671 //=======================================================================
672 void SMESHDS_Mesh::RemoveNode(const SMDS_MeshNode * n)
673 {
674   myScript->RemoveNode(n->GetID());
675   
676   list<const SMDS_MeshElement *> removedElems;
677   list<const SMDS_MeshElement *> removedNodes;
678
679   SMDS_Mesh::RemoveElement( n, removedElems, removedNodes, true );
680
681   removeFromContainers( myShapeIndexToSubMesh, myGroups, removedElems, false );
682   removeFromContainers( myShapeIndexToSubMesh, myGroups, removedNodes, true );
683 }
684
685 //=======================================================================
686 //function : RemoveElement
687 //purpose  : 
688 //========================================================================
689 void SMESHDS_Mesh::RemoveElement(const SMDS_MeshElement * elt)
690 {
691   if (elt->GetType() == SMDSAbs_Node)
692   {
693     RemoveNode( static_cast<const SMDS_MeshNode*>( elt ));
694     return;
695   }
696
697   myScript->RemoveElement(elt->GetID());
698
699   list<const SMDS_MeshElement *> removedElems;
700   list<const SMDS_MeshElement *> removedNodes;
701
702   SMDS_Mesh::RemoveElement(elt, removedElems, removedNodes, false);
703   
704   removeFromContainers( myShapeIndexToSubMesh, myGroups, removedElems, false );
705 }
706
707 //=======================================================================
708 //function : SetNodeOnVolume
709 //purpose  : 
710 //=======================================================================
711 void SMESHDS_Mesh::SetNodeInVolume(SMDS_MeshNode *      aNode,
712                                    const TopoDS_Shell & S)
713 {
714   SetNodeInVolume( aNode, myIndexToShape.FindIndex(S) );
715 }
716 //=======================================================================
717 //function : SetNodeOnVolume
718 //purpose  : 
719 //=======================================================================
720 void SMESHDS_Mesh::SetNodeInVolume(SMDS_MeshNode *      aNode,
721                                    const TopoDS_Solid & S)
722 {
723   SetNodeInVolume( aNode, myIndexToShape.FindIndex(S) );
724 }
725
726 //=======================================================================
727 //function : SetNodeOnFace
728 //purpose  : 
729 //=======================================================================
730 void SMESHDS_Mesh::SetNodeOnFace(SMDS_MeshNode *     aNode,
731                                  const TopoDS_Face & S,
732                                  double              u,
733                                  double              v)
734 {
735   SetNodeOnFace( aNode, myIndexToShape.FindIndex(S), u, v );
736 }
737
738 //=======================================================================
739 //function : SetNodeOnEdge
740 //purpose  : 
741 //=======================================================================
742 void SMESHDS_Mesh::SetNodeOnEdge(SMDS_MeshNode *     aNode,
743                                  const TopoDS_Edge & S,
744                                  double              u)
745 {
746   SetNodeOnEdge( aNode, myIndexToShape.FindIndex(S), u );
747 }
748
749 //=======================================================================
750 //function : SetNodeOnVertex
751 //purpose  : 
752 //=======================================================================
753 void SMESHDS_Mesh::SetNodeOnVertex(SMDS_MeshNode *       aNode,
754                                    const TopoDS_Vertex & S)
755 {
756   SetNodeOnVertex( aNode, myIndexToShape.FindIndex(S));
757 }
758
759 //=======================================================================
760 //function : UnSetNodeOnShape
761 //purpose  : 
762 //=======================================================================
763 void SMESHDS_Mesh::UnSetNodeOnShape(const SMDS_MeshNode* aNode)
764 {
765         MESSAGE("not implemented");
766 }
767
768 //=======================================================================
769 //function : SetMeshElementOnShape
770 //purpose  : 
771 //=======================================================================
772 void SMESHDS_Mesh::SetMeshElementOnShape(const SMDS_MeshElement * anElement,
773         const TopoDS_Shape & S)
774 {
775         if (myShape.IsNull()) MESSAGE("myShape is NULL");
776
777         int Index = myIndexToShape.FindIndex(S);
778
779         if (myShapeIndexToSubMesh.find(Index)==myShapeIndexToSubMesh.end())
780                 myShapeIndexToSubMesh[Index]=new SMESHDS_SubMesh();
781
782         myShapeIndexToSubMesh[Index]->AddElement(anElement);
783 }
784
785 //=======================================================================
786 //function : UnSetMeshElementOnShape
787 //purpose  : 
788 //=======================================================================
789 void SMESHDS_Mesh::
790 UnSetMeshElementOnShape(const SMDS_MeshElement * anElement,
791         const TopoDS_Shape & S)
792 {
793         if (myShape.IsNull()) MESSAGE("myShape is NULL");
794
795         int Index = myIndexToShape.FindIndex(S);
796
797         if (myShapeIndexToSubMesh.find(Index)!=myShapeIndexToSubMesh.end())
798                 myShapeIndexToSubMesh[Index]->RemoveElement(anElement);
799 }
800
801 //=======================================================================
802 //function : ShapeToMesh
803 //purpose  : 
804 //=======================================================================
805 TopoDS_Shape SMESHDS_Mesh::ShapeToMesh() const
806 {
807         return myShape;
808 }
809
810 //=======================================================================
811 //function : IsGroupOfSubShapes
812 //purpose  : return true if at least one subshape of theShape is a subshape
813 //           of myShape or theShape == myShape
814 //=======================================================================
815
816 bool SMESHDS_Mesh::IsGroupOfSubShapes (const TopoDS_Shape& theShape) const
817 {
818   if ( myShape.IsSame( theShape ))
819     return true;
820
821   for ( TopoDS_Iterator it( theShape ); it.More(); it.Next() ) {
822     if (myIndexToShape.Contains( it.Value() ) ||
823         IsGroupOfSubShapes( it.Value() ))
824       return true;
825   }
826   
827   return false;
828 }
829
830 ///////////////////////////////////////////////////////////////////////////////
831 /// Return the sub mesh linked to the a given TopoDS_Shape or NULL if the given
832 /// TopoDS_Shape is unknown
833 ///////////////////////////////////////////////////////////////////////////////
834 SMESHDS_SubMesh * SMESHDS_Mesh::MeshElements(const TopoDS_Shape & S) const
835 {
836   if (myShape.IsNull()) MESSAGE("myShape is NULL");
837
838   int Index = ShapeToIndex(S);
839   TShapeIndexToSubMesh::const_iterator anIter = myShapeIndexToSubMesh.find(Index);
840   if (anIter != myShapeIndexToSubMesh.end())
841     return anIter->second;
842   else
843     return NULL;
844 }
845
846 ///////////////////////////////////////////////////////////////////////////////
847 /// Return the sub mesh by Id of shape it is linked to
848 ///////////////////////////////////////////////////////////////////////////////
849 SMESHDS_SubMesh * SMESHDS_Mesh::MeshElements(const int Index)
850 {
851   if (myShape.IsNull()) MESSAGE("myShape is NULL");
852
853   if (myShapeIndexToSubMesh.find(Index)!=myShapeIndexToSubMesh.end())
854     return myShapeIndexToSubMesh[Index];
855   else
856     return NULL;
857 }
858
859 //=======================================================================
860 //function : SubMeshIndices
861 //purpose  : 
862 //=======================================================================
863 list<int> SMESHDS_Mesh::SubMeshIndices()
864 {
865   list<int> anIndices;
866   std::map<int,SMESHDS_SubMesh*>::iterator anIter = myShapeIndexToSubMesh.begin();
867   for (; anIter != myShapeIndexToSubMesh.end(); anIter++) {
868     anIndices.push_back((*anIter).first);
869   }
870   return anIndices;
871 }
872
873 //=======================================================================
874 //function : GetHypothesis
875 //purpose  : 
876 //=======================================================================
877
878 const list<const SMESHDS_Hypothesis*>& SMESHDS_Mesh::GetHypothesis(
879         const TopoDS_Shape & S) const
880 {
881         if (myShapeToHypothesis.find(S)!=myShapeToHypothesis.end())
882                 return myShapeToHypothesis.find(S)->second;
883
884         static list<const SMESHDS_Hypothesis*> empty;
885         return empty;
886 }
887
888 //=======================================================================
889 //function : GetScript
890 //purpose  : 
891 //=======================================================================
892 SMESHDS_Script* SMESHDS_Mesh::GetScript()
893 {
894         return myScript;
895 }
896
897 //=======================================================================
898 //function : ClearScript
899 //purpose  : 
900 //=======================================================================
901 void SMESHDS_Mesh::ClearScript()
902 {
903         myScript->Clear();
904 }
905
906 //=======================================================================
907 //function : HasMeshElements
908 //purpose  : 
909 //=======================================================================
910 bool SMESHDS_Mesh::HasMeshElements(const TopoDS_Shape & S)
911 {
912         if (myShape.IsNull()) MESSAGE("myShape is NULL");
913         int Index = myIndexToShape.FindIndex(S);
914         return myShapeIndexToSubMesh.find(Index)!=myShapeIndexToSubMesh.end();
915 }
916
917 //=======================================================================
918 //function : HasHypothesis
919 //purpose  : 
920 //=======================================================================
921 bool SMESHDS_Mesh::HasHypothesis(const TopoDS_Shape & S)
922 {
923         return myShapeToHypothesis.find(S)!=myShapeToHypothesis.end();
924 }
925
926 //=======================================================================
927 //function : NewSubMesh 
928 //purpose  : 
929 //=======================================================================
930 SMESHDS_SubMesh * SMESHDS_Mesh::NewSubMesh(int Index)
931 {
932   SMESHDS_SubMesh* SM = 0;
933   TShapeIndexToSubMesh::iterator anIter = myShapeIndexToSubMesh.find(Index);
934   if (anIter == myShapeIndexToSubMesh.end())
935   {
936     SM = new SMESHDS_SubMesh();
937     myShapeIndexToSubMesh[Index]=SM;
938   }
939   else
940     SM = anIter->second;
941   return SM;
942 }
943
944 //=======================================================================
945 //function : AddCompoundSubmesh
946 //purpose  : 
947 //=======================================================================
948
949 int SMESHDS_Mesh::AddCompoundSubmesh(const TopoDS_Shape& S,
950                                      TopAbs_ShapeEnum    type)
951 {
952   int aMainIndex = 0;
953   if ( IsGroupOfSubShapes( S ) || (S.ShapeType() == TopAbs_VERTEX && myIndexToShape.Contains(S)) )
954   {
955     aMainIndex = myIndexToShape.Add( S );
956     bool all = ( type == TopAbs_SHAPE );
957     if ( all ) // corresponding simple submesh may exist
958       aMainIndex = -aMainIndex;
959     //MESSAGE("AddCompoundSubmesh index = " << aMainIndex );
960     SMESHDS_SubMesh * aNewSub = NewSubMesh( aMainIndex );
961     if ( !aNewSub->IsComplexSubmesh() ) // is empty
962     {
963       int shapeType = all ? myShape.ShapeType() : type;
964       int typeLimit = all ? TopAbs_VERTEX : type;
965       for ( ; shapeType <= typeLimit; shapeType++ )
966       {
967         TopExp_Explorer exp( S, TopAbs_ShapeEnum( shapeType ));
968         for ( ; exp.More(); exp.Next() )
969         {
970           int index = myIndexToShape.FindIndex( exp.Current() );
971           if ( index )
972             aNewSub->AddSubMesh( NewSubMesh( index ));
973         }
974       }
975     }
976   }
977   return aMainIndex;
978 }
979
980 //=======================================================================
981 //function : IndexToShape
982 //purpose  : 
983 //=======================================================================
984 TopoDS_Shape SMESHDS_Mesh::IndexToShape(int ShapeIndex)
985 {
986         return myIndexToShape.FindKey(ShapeIndex);
987 }
988
989 //=======================================================================
990 //function : ShapeToIndex
991 //purpose  : 
992 //=======================================================================
993 int SMESHDS_Mesh::ShapeToIndex(const TopoDS_Shape & S) const
994 {
995   if (myShape.IsNull())
996     MESSAGE("myShape is NULL");
997
998   int index = myIndexToShape.FindIndex(S);
999   
1000   return index;
1001 }
1002
1003 //=======================================================================
1004 //function : SetNodeOnVolume
1005 //purpose  : 
1006 //=======================================================================
1007 void SMESHDS_Mesh::SetNodeInVolume(const SMDS_MeshNode* aNode, int Index)
1008 {
1009   addNodeToSubmesh( aNode, Index );
1010 }
1011
1012 //=======================================================================
1013 //function : SetNodeOnFace
1014 //purpose  : 
1015 //=======================================================================
1016 void SMESHDS_Mesh::SetNodeOnFace(SMDS_MeshNode* aNode, int Index, double u, double v)
1017 {
1018   //Set Position on Node
1019   aNode->SetPosition(SMDS_PositionPtr(new SMDS_FacePosition(Index, u, v)));
1020
1021   addNodeToSubmesh( aNode, Index );
1022 }
1023
1024 //=======================================================================
1025 //function : SetNodeOnEdge
1026 //purpose  : 
1027 //=======================================================================
1028 void SMESHDS_Mesh::SetNodeOnEdge(SMDS_MeshNode* aNode,
1029                                  int            Index,
1030                                  double         u)
1031 {
1032   //Set Position on Node
1033   aNode->SetPosition(SMDS_PositionPtr(new SMDS_EdgePosition(Index, u)));
1034
1035   addNodeToSubmesh( aNode, Index );
1036 }
1037
1038 //=======================================================================
1039 //function : SetNodeOnVertex
1040 //purpose  : 
1041 //=======================================================================
1042 void SMESHDS_Mesh::SetNodeOnVertex(SMDS_MeshNode* aNode, int Index)
1043 {
1044   //Set Position on Node
1045   aNode->SetPosition(SMDS_PositionPtr(new SMDS_VertexPosition(Index)));
1046
1047   addNodeToSubmesh( aNode, Index );
1048 }
1049
1050 //=======================================================================
1051 //function : SetMeshElementOnShape
1052 //purpose  : 
1053 //=======================================================================
1054 void SMESHDS_Mesh::SetMeshElementOnShape(const SMDS_MeshElement* anElement,
1055         int Index)
1056 {
1057         if (myShapeIndexToSubMesh.find(Index)==myShapeIndexToSubMesh.end())
1058                 myShapeIndexToSubMesh[Index]=new SMESHDS_SubMesh();
1059
1060         myShapeIndexToSubMesh[Index]->AddElement(anElement);
1061 }
1062
1063 SMESHDS_Mesh::~SMESHDS_Mesh()
1064 {
1065 }