Salome HOME
Mesh redesine. New fields added to specify whether hypothesis is main or additional...
[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   //ASSERT( nbnodes < 9 );
175   //int i, IDs[ 8 ];
176   int i, IDs[ nbnodes ];
177   for ( i = 0; i < nbnodes; i++ )
178     IDs [ i ] = nodes[ i ]->GetID();
179   myScript->ChangeElementNodes( elem->GetID(), IDs, nbnodes);
180
181   return true;
182 }
183
184 //=======================================================================
185 //function : ChangePolygonNodes
186 //purpose  : 
187 //=======================================================================
188 bool SMESHDS_Mesh::ChangePolygonNodes
189                    (const SMDS_MeshElement * elem,
190                     std::vector<const SMDS_MeshNode*> nodes)
191 {
192   ASSERT(nodes.size() > 3);
193
194   int nb = nodes.size();
195   const SMDS_MeshNode* nodes_array [nb];
196   for (int inode = 0; inode < nb; inode++) {
197     nodes_array[inode] = nodes[inode];
198   }
199
200   return ChangeElementNodes(elem, nodes_array, nb);
201 }
202
203 //=======================================================================
204 //function : ChangePolyhedronNodes
205 //purpose  : 
206 //=======================================================================
207 bool SMESHDS_Mesh::ChangePolyhedronNodes
208                    (const SMDS_MeshElement * elem,
209                     std::vector<const SMDS_MeshNode*> nodes,
210                     std::vector<int>                  quantities)
211 {
212   ASSERT(nodes.size() > 3);
213
214   if (!SMDS_Mesh::ChangePolyhedronNodes(elem, nodes, quantities))
215     return false;
216
217   int i, len = nodes.size();
218   std::vector<int> nodes_ids (len);
219   for (i = 0; i < len; i++) {
220     nodes_ids[i] = nodes[i]->GetID();
221   }
222   myScript->ChangePolyhedronNodes(elem->GetID(), nodes_ids, quantities);
223
224   return true;
225 }
226
227 //=======================================================================
228 //function : Renumber
229 //purpose  : 
230 //=======================================================================
231
232 void SMESHDS_Mesh::Renumber (const bool isNodes, const int startID, const int deltaID)
233 {
234   SMDS_Mesh::Renumber( isNodes, startID, deltaID );
235   myScript->Renumber( isNodes, startID, deltaID );
236 }
237
238 //=======================================================================
239 //function :AddEdgeWithID
240 //purpose  : 
241 //=======================================================================
242 SMDS_MeshEdge* SMESHDS_Mesh::AddEdgeWithID(int n1, int n2, int ID)
243 {
244   SMDS_MeshEdge* anElem = SMDS_Mesh::AddEdgeWithID(n1,n2,ID);
245   if(anElem) myScript->AddEdge(ID,n1,n2);
246   return anElem;
247 }
248
249 SMDS_MeshEdge* SMESHDS_Mesh::AddEdgeWithID(const SMDS_MeshNode * n1,
250                                            const SMDS_MeshNode * n2, 
251                                            int ID)
252 {
253   return AddEdgeWithID(n1->GetID(),
254                        n2->GetID(),
255                        ID);
256 }
257
258 SMDS_MeshEdge* SMESHDS_Mesh::AddEdge(const SMDS_MeshNode * n1,
259                                      const SMDS_MeshNode * n2)
260 {
261   SMDS_MeshEdge* anElem = SMDS_Mesh::AddEdge(n1,n2);
262   if(anElem) myScript->AddEdge(anElem->GetID(), 
263                                n1->GetID(), 
264                                n2->GetID());
265   return anElem;
266 }
267
268 //=======================================================================
269 //function :AddFace
270 //purpose  : 
271 //=======================================================================
272 SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(int n1, int n2, int n3, int ID)
273 {
274   SMDS_MeshFace *anElem = SMDS_Mesh::AddFaceWithID(n1, n2, n3, ID);
275   if(anElem) myScript->AddFace(ID,n1,n2,n3);
276   return anElem;
277 }
278
279 SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
280                                            const SMDS_MeshNode * n2,
281                                            const SMDS_MeshNode * n3, 
282                                            int ID)
283 {
284   return AddFaceWithID(n1->GetID(),
285                        n2->GetID(),
286                        n3->GetID(),
287                        ID);
288 }
289
290 SMDS_MeshFace* SMESHDS_Mesh::AddFace( const SMDS_MeshNode * n1,
291                                       const SMDS_MeshNode * n2,
292                                       const SMDS_MeshNode * n3)
293 {
294   SMDS_MeshFace *anElem = SMDS_Mesh::AddFace(n1, n2, n3);
295   if(anElem) myScript->AddFace(anElem->GetID(), 
296                                n1->GetID(), 
297                                n2->GetID(),
298                                n3->GetID());
299   return anElem;
300 }
301
302 //=======================================================================
303 //function :AddFace
304 //purpose  : 
305 //=======================================================================
306 SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(int n1, int n2, int n3, int n4, int ID)
307 {
308   SMDS_MeshFace *anElem = SMDS_Mesh::AddFaceWithID(n1, n2, n3, n4, ID);
309   if(anElem) myScript->AddFace(ID, n1, n2, n3, n4);
310   return anElem;
311 }
312
313 SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
314                                            const SMDS_MeshNode * n2,
315                                            const SMDS_MeshNode * n3,
316                                            const SMDS_MeshNode * n4, 
317                                            int ID)
318 {
319   return AddFaceWithID(n1->GetID(),
320                        n2->GetID(),
321                        n3->GetID(),
322                        n4->GetID(),
323                        ID);
324 }
325
326 SMDS_MeshFace* SMESHDS_Mesh::AddFace(const SMDS_MeshNode * n1,
327                                      const SMDS_MeshNode * n2,
328                                      const SMDS_MeshNode * n3,
329                                      const SMDS_MeshNode * n4)
330 {
331   SMDS_MeshFace *anElem = SMDS_Mesh::AddFace(n1, n2, n3, n4);
332   if(anElem) myScript->AddFace(anElem->GetID(), 
333                                n1->GetID(), 
334                                n2->GetID(), 
335                                n3->GetID(),
336                                n4->GetID());
337   return anElem;
338 }
339
340 //=======================================================================
341 //function :AddVolume
342 //purpose  : 
343 //=======================================================================
344 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4, int ID)
345 {
346   SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, ID);
347   if(anElem) myScript->AddVolume(ID, n1, n2, n3, n4);
348   return anElem;
349 }
350
351 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
352                                                const SMDS_MeshNode * n2,
353                                                const SMDS_MeshNode * n3,
354                                                const SMDS_MeshNode * n4, 
355                                                int ID)
356 {
357   return AddVolumeWithID(n1->GetID(), 
358                          n2->GetID(), 
359                          n3->GetID(),
360                          n4->GetID(),
361                          ID);
362 }
363
364 SMDS_MeshVolume* SMESHDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
365                                          const SMDS_MeshNode * n2,
366                                          const SMDS_MeshNode * n3,
367                                          const SMDS_MeshNode * n4)
368 {
369   SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolume(n1, n2, n3, n4);
370   if(anElem) myScript->AddVolume(anElem->GetID(), 
371                                  n1->GetID(), 
372                                  n2->GetID(), 
373                                  n3->GetID(),
374                                  n4->GetID());
375   return anElem;
376 }
377
378 //=======================================================================
379 //function :AddVolume
380 //purpose  : 
381 //=======================================================================
382 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4, int n5, int ID)
383 {
384   SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, ID);
385   if(anElem) myScript->AddVolume(ID, n1, n2, n3, n4, n5);
386   return anElem;
387 }
388
389 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
390                                                const SMDS_MeshNode * n2,
391                                                const SMDS_MeshNode * n3,
392                                                const SMDS_MeshNode * n4,
393                                                const SMDS_MeshNode * n5, 
394                                                int ID)
395 {
396   return AddVolumeWithID(n1->GetID(), 
397                          n2->GetID(), 
398                          n3->GetID(),
399                          n4->GetID(), 
400                          n5->GetID(),
401                          ID);
402 }
403
404 SMDS_MeshVolume* SMESHDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
405                                          const SMDS_MeshNode * n2,
406                                          const SMDS_MeshNode * n3,
407                                          const SMDS_MeshNode * n4,
408                                          const SMDS_MeshNode * n5)
409 {
410   SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolume(n1, n2, n3, n4, n5);
411   if(anElem) myScript->AddVolume(anElem->GetID(), 
412                                  n1->GetID(), 
413                                  n2->GetID(), 
414                                  n3->GetID(),
415                                  n4->GetID(), 
416                                  n5->GetID());
417   return anElem;
418 }
419
420 //=======================================================================
421 //function :AddVolume
422 //purpose  : 
423 //=======================================================================
424 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4, int n5, int n6, int ID)
425 {
426   SMDS_MeshVolume *anElem= SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, ID);
427   if(anElem) myScript->AddVolume(ID, n1, n2, n3, n4, n5, n6);
428   return anElem;
429 }
430
431 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
432                                                const SMDS_MeshNode * n2,
433                                                const SMDS_MeshNode * n3,
434                                                const SMDS_MeshNode * n4,
435                                                const SMDS_MeshNode * n5,
436                                                const SMDS_MeshNode * n6, 
437                                                int ID)
438 {
439   return AddVolumeWithID(n1->GetID(), 
440                          n2->GetID(), 
441                          n3->GetID(),
442                          n4->GetID(), 
443                          n5->GetID(), 
444                          n6->GetID(),
445                          ID);
446 }
447
448 SMDS_MeshVolume* SMESHDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
449                                          const SMDS_MeshNode * n2,
450                                          const SMDS_MeshNode * n3,
451                                          const SMDS_MeshNode * n4,
452                                          const SMDS_MeshNode * n5,
453                                          const SMDS_MeshNode * n6)
454 {
455   SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolume(n1, n2, n3, n4, n5, n6);
456   if(anElem) myScript->AddVolume(anElem->GetID(), 
457                                  n1->GetID(), 
458                                  n2->GetID(), 
459                                  n3->GetID(),
460                                  n4->GetID(), 
461                                  n5->GetID(), 
462                                  n6->GetID());
463   return anElem;
464 }
465
466 //=======================================================================
467 //function :AddVolume
468 //purpose  : 
469 //=======================================================================
470 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4, int n5, int n6, int n7, int n8, int ID)
471 {
472   SMDS_MeshVolume *anElem= SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, n7, n8, ID);
473   if(anElem) myScript->AddVolume(ID, n1, n2, n3, n4, n5, n6, n7, n8);
474   return anElem;
475 }
476
477 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
478                                                const SMDS_MeshNode * n2,
479                                                const SMDS_MeshNode * n3,
480                                                const SMDS_MeshNode * n4,
481                                                const SMDS_MeshNode * n5,
482                                                const SMDS_MeshNode * n6,
483                                                const SMDS_MeshNode * n7,
484                                                const SMDS_MeshNode * n8, 
485                                                int ID)
486 {
487   return AddVolumeWithID(n1->GetID(), 
488                          n2->GetID(), 
489                          n3->GetID(),
490                          n4->GetID(), 
491                          n5->GetID(), 
492                          n6->GetID(), 
493                          n7->GetID(), 
494                          n8->GetID(),
495                          ID);
496 }
497
498 SMDS_MeshVolume* SMESHDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
499                                          const SMDS_MeshNode * n2,
500                                          const SMDS_MeshNode * n3,
501                                          const SMDS_MeshNode * n4,
502                                          const SMDS_MeshNode * n5,
503                                          const SMDS_MeshNode * n6,
504                                          const SMDS_MeshNode * n7,
505                                          const SMDS_MeshNode * n8)
506 {
507   SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolume(n1, n2, n3, n4, n5, n6, n7, n8);
508   if(anElem) myScript->AddVolume(anElem->GetID(), 
509                                  n1->GetID(), 
510                                  n2->GetID(), 
511                                  n3->GetID(),
512                                  n4->GetID(), 
513                                  n5->GetID(), 
514                                  n6->GetID(), 
515                                  n7->GetID(), 
516                                  n8->GetID());
517   return anElem;
518 }
519
520 //=======================================================================
521 //function : AddPolygonalFace
522 //purpose  : 
523 //=======================================================================
524 SMDS_MeshFace* SMESHDS_Mesh::AddPolygonalFaceWithID (std::vector<int> nodes_ids,
525                                                      const int        ID)
526 {
527   SMDS_MeshFace *anElem = SMDS_Mesh::AddPolygonalFaceWithID(nodes_ids, ID);
528   if (anElem) {
529     myScript->AddPolygonalFace(ID, nodes_ids);
530   }
531   return anElem;
532 }
533
534 SMDS_MeshFace* SMESHDS_Mesh::AddPolygonalFaceWithID
535                              (std::vector<const SMDS_MeshNode*> nodes,
536                               const int                         ID)
537 {
538   SMDS_MeshFace *anElem = SMDS_Mesh::AddPolygonalFaceWithID(nodes, ID);
539   if (anElem) {
540     int i, len = nodes.size();
541     std::vector<int> nodes_ids (len);
542     for (i = 0; i < len; i++) {
543       nodes_ids[i] = nodes[i]->GetID();
544     }
545     myScript->AddPolygonalFace(ID, nodes_ids);
546   }
547   return anElem;
548 }
549
550 SMDS_MeshFace* SMESHDS_Mesh::AddPolygonalFace
551                              (std::vector<const SMDS_MeshNode*> nodes)
552 {
553   SMDS_MeshFace *anElem = SMDS_Mesh::AddPolygonalFace(nodes);
554   if (anElem) {
555     int i, len = nodes.size();
556     std::vector<int> nodes_ids (len);
557     for (i = 0; i < len; i++) {
558       nodes_ids[i] = nodes[i]->GetID();
559     }
560     myScript->AddPolygonalFace(anElem->GetID(), nodes_ids);
561   }
562   return anElem;
563 }
564
565 //=======================================================================
566 //function : AddPolyhedralVolume
567 //purpose  : 
568 //=======================================================================
569 SMDS_MeshVolume* SMESHDS_Mesh::AddPolyhedralVolumeWithID (std::vector<int> nodes_ids,
570                                                           std::vector<int> quantities,
571                                                           const int        ID)
572 {
573   SMDS_MeshVolume *anElem = SMDS_Mesh::AddPolyhedralVolumeWithID(nodes_ids, quantities, ID);
574   if (anElem) {
575     myScript->AddPolyhedralVolume(ID, nodes_ids, quantities);
576   }
577   return anElem;
578 }
579
580 SMDS_MeshVolume* SMESHDS_Mesh::AddPolyhedralVolumeWithID
581                                (std::vector<const SMDS_MeshNode*> nodes,
582                                 std::vector<int>                  quantities,
583                                 const int                         ID)
584 {
585   SMDS_MeshVolume *anElem = SMDS_Mesh::AddPolyhedralVolumeWithID(nodes, quantities, ID);
586   if (anElem) {
587     int i, len = nodes.size();
588     std::vector<int> nodes_ids (len);
589     for (i = 0; i < len; i++) {
590       nodes_ids[i] = nodes[i]->GetID();
591     }
592     myScript->AddPolyhedralVolume(ID, nodes_ids, quantities);
593   }
594   return anElem;
595 }
596
597 SMDS_MeshVolume* SMESHDS_Mesh::AddPolyhedralVolume
598                                (std::vector<const SMDS_MeshNode*> nodes,
599                                 std::vector<int>                  quantities)
600 {
601   SMDS_MeshVolume *anElem = SMDS_Mesh::AddPolyhedralVolume(nodes, quantities);
602   if (anElem) {
603     int i, len = nodes.size();
604     std::vector<int> nodes_ids (len);
605     for (i = 0; i < len; i++) {
606       nodes_ids[i] = nodes[i]->GetID();
607     }
608     myScript->AddPolyhedralVolume(anElem->GetID(), nodes_ids, quantities);
609   }
610   return anElem;
611 }
612
613 //=======================================================================
614 //function : removeFromContainers
615 //purpose  : 
616 //=======================================================================
617
618 static void removeFromContainers (map<int,SMESHDS_SubMesh*> &      theSubMeshes,
619                                   set<SMESHDS_GroupBase*>&             theGroups,
620                                   list<const SMDS_MeshElement *> & theElems,
621                                   const bool                       isNode)
622 {
623   if ( theElems.empty() )
624     return;
625
626   // Rm from group
627   // Element can belong to several groups
628   if ( !theGroups.empty() )
629   {
630     set<SMESHDS_GroupBase*>::iterator GrIt = theGroups.begin();
631     for ( ; GrIt != theGroups.end(); GrIt++ )
632     {
633       SMESHDS_Group* group = dynamic_cast<SMESHDS_Group*>( *GrIt );
634       if ( !group || group->IsEmpty() ) continue;
635
636       list<const SMDS_MeshElement *>::iterator elIt = theElems.begin();
637       for ( ; elIt != theElems.end(); elIt++ )
638       {
639         group->SMDSGroup().Remove( *elIt );
640         if ( group->IsEmpty() ) break;
641       }
642     }
643   }
644
645   // Rm from sub-meshes
646   // Element should belong to only one sub-mesh
647   map<int,SMESHDS_SubMesh*>::iterator SubIt = theSubMeshes.begin();
648   for ( ; SubIt != theSubMeshes.end(); SubIt++ )
649   {
650     int size = isNode ? (*SubIt).second->NbNodes() : (*SubIt).second->NbElements();
651     if ( size == 0 ) continue;
652
653     list<const SMDS_MeshElement *>::iterator elIt = theElems.begin();
654     while ( elIt != theElems.end() )
655     {
656       bool removed = false;
657       if ( isNode )
658         removed = (*SubIt).second->RemoveNode( static_cast<const SMDS_MeshNode*> (*elIt) );
659       else
660         removed = (*SubIt).second->RemoveElement( *elIt );
661
662       if (removed)
663       {
664         elIt = theElems.erase( elIt );
665         if ( theElems.empty() )
666           return; // all elements are found and removed
667       }
668       else
669       {
670         elIt++ ;
671       }
672     }
673   }
674 }
675   
676 //=======================================================================
677 //function : RemoveNode
678 //purpose  : 
679 //=======================================================================
680 void SMESHDS_Mesh::RemoveNode(const SMDS_MeshNode * n)
681 {
682   myScript->RemoveNode(n->GetID());
683   
684   list<const SMDS_MeshElement *> removedElems;
685   list<const SMDS_MeshElement *> removedNodes;
686
687   SMDS_Mesh::RemoveElement( n, removedElems, removedNodes, true );
688
689   removeFromContainers( myShapeIndexToSubMesh, myGroups, removedElems, false );
690   removeFromContainers( myShapeIndexToSubMesh, myGroups, removedNodes, true );
691 }
692
693 //=======================================================================
694 //function : RemoveElement
695 //purpose  : 
696 //========================================================================
697 void SMESHDS_Mesh::RemoveElement(const SMDS_MeshElement * elt)
698 {
699   if (elt->GetType() == SMDSAbs_Node)
700   {
701     RemoveNode( static_cast<const SMDS_MeshNode*>( elt ));
702     return;
703   }
704
705   myScript->RemoveElement(elt->GetID());
706
707   list<const SMDS_MeshElement *> removedElems;
708   list<const SMDS_MeshElement *> removedNodes;
709
710   SMDS_Mesh::RemoveElement(elt, removedElems, removedNodes, false);
711   
712   removeFromContainers( myShapeIndexToSubMesh, myGroups, removedElems, false );
713 }
714
715 //=======================================================================
716 //function : SetNodeOnVolume
717 //purpose  : 
718 //=======================================================================
719 void SMESHDS_Mesh::SetNodeInVolume(SMDS_MeshNode * aNode,
720         const TopoDS_Shell & S)
721 {
722         if (myShape.IsNull()) MESSAGE("myShape is NULL");
723
724         int Index = myIndexToShape.FindIndex(S);
725
726         //Set Position on Node
727         //Handle (SMDS_FacePosition) aPos = new SMDS_FacePosition (myFaceToId(S),0.,0.);;
728         //aNode->SetPosition(aPos);
729
730         //Update or build submesh
731         map<int,SMESHDS_SubMesh*>::iterator it=myShapeIndexToSubMesh.find(Index);
732         if (it==myShapeIndexToSubMesh.end())
733                 myShapeIndexToSubMesh[Index]= new SMESHDS_SubMesh();
734
735         myShapeIndexToSubMesh[Index]->AddNode(aNode);
736 }
737
738 //=======================================================================
739 //function : SetNodeOnFace
740 //purpose  : 
741 //=======================================================================
742 void SMESHDS_Mesh::SetNodeOnFace(SMDS_MeshNode * aNode,
743         const TopoDS_Face & S)
744 {
745         if (myShape.IsNull()) MESSAGE("myShape is NULL");
746
747         int Index = myIndexToShape.FindIndex(S);
748
749         //Set Position on Node
750         aNode->SetPosition(SMDS_PositionPtr(new SMDS_FacePosition(Index, 0., 0.)));
751
752         //Update or build submesh
753         map<int,SMESHDS_SubMesh*>::iterator it=myShapeIndexToSubMesh.find(Index);
754         if (it==myShapeIndexToSubMesh.end())
755                 myShapeIndexToSubMesh[Index]= new SMESHDS_SubMesh();
756
757         myShapeIndexToSubMesh[Index]->AddNode(aNode);
758 }
759
760 //=======================================================================
761 //function : SetNodeOnEdge
762 //purpose  : 
763 //=======================================================================
764 void SMESHDS_Mesh::SetNodeOnEdge(SMDS_MeshNode * aNode,
765         const TopoDS_Edge & S)
766 {
767         if (myShape.IsNull()) MESSAGE("myShape is NULL");
768
769         int Index = myIndexToShape.FindIndex(S);
770
771         //Set Position on Node
772         aNode->SetPosition(SMDS_PositionPtr(new SMDS_EdgePosition(Index, 0.)));
773
774         //Update or build submesh
775         map<int,SMESHDS_SubMesh*>::iterator it=myShapeIndexToSubMesh.find(Index);
776         if (it==myShapeIndexToSubMesh.end())
777                 myShapeIndexToSubMesh[Index]= new SMESHDS_SubMesh();
778
779         myShapeIndexToSubMesh[Index]->AddNode(aNode);
780 }
781
782 //=======================================================================
783 //function : SetNodeOnVertex
784 //purpose  : 
785 //=======================================================================
786 void SMESHDS_Mesh::SetNodeOnVertex(SMDS_MeshNode * aNode,
787         const TopoDS_Vertex & S)
788 {
789         if (myShape.IsNull()) MESSAGE("myShape is NULL");
790
791         int Index = myIndexToShape.FindIndex(S);
792
793         //Set Position on Node
794         aNode->SetPosition(SMDS_PositionPtr(new SMDS_VertexPosition(Index)));
795
796         //Update or build submesh
797         map<int,SMESHDS_SubMesh*>::iterator it=myShapeIndexToSubMesh.find(Index);
798         if (it==myShapeIndexToSubMesh.end())
799                 myShapeIndexToSubMesh[Index]= new SMESHDS_SubMesh();
800
801         myShapeIndexToSubMesh[Index]->AddNode(aNode);
802 }
803
804 //=======================================================================
805 //function : UnSetNodeOnShape
806 //purpose  : 
807 //=======================================================================
808 void SMESHDS_Mesh::UnSetNodeOnShape(const SMDS_MeshNode* aNode)
809 {
810         MESSAGE("not implemented");
811 }
812
813 //=======================================================================
814 //function : SetMeshElementOnShape
815 //purpose  : 
816 //=======================================================================
817 void SMESHDS_Mesh::SetMeshElementOnShape(const SMDS_MeshElement * anElement,
818         const TopoDS_Shape & S)
819 {
820         if (myShape.IsNull()) MESSAGE("myShape is NULL");
821
822         int Index = myIndexToShape.FindIndex(S);
823
824         if (myShapeIndexToSubMesh.find(Index)==myShapeIndexToSubMesh.end())
825                 myShapeIndexToSubMesh[Index]=new SMESHDS_SubMesh();
826
827         myShapeIndexToSubMesh[Index]->AddElement(anElement);
828 }
829
830 //=======================================================================
831 //function : UnSetMeshElementOnShape
832 //purpose  : 
833 //=======================================================================
834 void SMESHDS_Mesh::
835 UnSetMeshElementOnShape(const SMDS_MeshElement * anElement,
836         const TopoDS_Shape & S)
837 {
838         if (myShape.IsNull()) MESSAGE("myShape is NULL");
839
840         int Index = myIndexToShape.FindIndex(S);
841
842         if (myShapeIndexToSubMesh.find(Index)!=myShapeIndexToSubMesh.end())
843                 myShapeIndexToSubMesh[Index]->RemoveElement(anElement);
844 }
845
846 //=======================================================================
847 //function : ShapeToMesh
848 //purpose  : 
849 //=======================================================================
850 TopoDS_Shape SMESHDS_Mesh::ShapeToMesh() const
851 {
852         return myShape;
853 }
854
855 //=======================================================================
856 //function : IsGroupOfSubShapes
857 //purpose  : return true if at least one subshape of theShape is a subshape
858 //           of myShape or theShape == myShape
859 //=======================================================================
860
861 bool SMESHDS_Mesh::IsGroupOfSubShapes (const TopoDS_Shape& theShape) const
862 {
863   if ( myShape.IsSame( theShape ))
864     return true;
865
866   for ( TopoDS_Iterator it( theShape ); it.More(); it.Next() ) {
867     if (myIndexToShape.Contains( it.Value() ) ||
868         IsGroupOfSubShapes( it.Value() ))
869       return true;
870   }
871   
872   return false;
873 }
874
875 ///////////////////////////////////////////////////////////////////////////////
876 /// Return the sub mesh linked to the a given TopoDS_Shape or NULL if the given
877 /// TopoDS_Shape is unknown
878 ///////////////////////////////////////////////////////////////////////////////
879 SMESHDS_SubMesh * SMESHDS_Mesh::MeshElements(const TopoDS_Shape & S) const
880 {
881   if (myShape.IsNull()) MESSAGE("myShape is NULL");
882
883   int Index = ShapeToIndex(S);
884   TShapeIndexToSubMesh::const_iterator anIter = myShapeIndexToSubMesh.find(Index);
885   if (anIter != myShapeIndexToSubMesh.end())
886     return anIter->second;
887   else
888     return NULL;
889 }
890
891 ///////////////////////////////////////////////////////////////////////////////
892 /// Return the sub mesh by Id of shape it is linked to
893 ///////////////////////////////////////////////////////////////////////////////
894 SMESHDS_SubMesh * SMESHDS_Mesh::MeshElements(const int Index)
895 {
896   if (myShape.IsNull()) MESSAGE("myShape is NULL");
897
898   if (myShapeIndexToSubMesh.find(Index)!=myShapeIndexToSubMesh.end())
899     return myShapeIndexToSubMesh[Index];
900   else
901     return NULL;
902 }
903
904 //=======================================================================
905 //function : SubMeshIndices
906 //purpose  : 
907 //=======================================================================
908 list<int> SMESHDS_Mesh::SubMeshIndices()
909 {
910   list<int> anIndices;
911   std::map<int,SMESHDS_SubMesh*>::iterator anIter = myShapeIndexToSubMesh.begin();
912   for (; anIter != myShapeIndexToSubMesh.end(); anIter++) {
913     anIndices.push_back((*anIter).first);
914   }
915   return anIndices;
916 }
917
918 //=======================================================================
919 //function : GetHypothesis
920 //purpose  : 
921 //=======================================================================
922
923 const list<const SMESHDS_Hypothesis*>& SMESHDS_Mesh::GetHypothesis(
924         const TopoDS_Shape & S) const
925 {
926         if (myShapeToHypothesis.find(S)!=myShapeToHypothesis.end())
927                 return myShapeToHypothesis.find(S)->second;
928
929         static list<const SMESHDS_Hypothesis*> empty;
930         return empty;
931 }
932
933 //=======================================================================
934 //function : GetScript
935 //purpose  : 
936 //=======================================================================
937 SMESHDS_Script* SMESHDS_Mesh::GetScript()
938 {
939         return myScript;
940 }
941
942 //=======================================================================
943 //function : ClearScript
944 //purpose  : 
945 //=======================================================================
946 void SMESHDS_Mesh::ClearScript()
947 {
948         myScript->Clear();
949 }
950
951 //=======================================================================
952 //function : HasMeshElements
953 //purpose  : 
954 //=======================================================================
955 bool SMESHDS_Mesh::HasMeshElements(const TopoDS_Shape & S)
956 {
957         if (myShape.IsNull()) MESSAGE("myShape is NULL");
958         int Index = myIndexToShape.FindIndex(S);
959         return myShapeIndexToSubMesh.find(Index)!=myShapeIndexToSubMesh.end();
960 }
961
962 //=======================================================================
963 //function : HasHypothesis
964 //purpose  : 
965 //=======================================================================
966 bool SMESHDS_Mesh::HasHypothesis(const TopoDS_Shape & S)
967 {
968         return myShapeToHypothesis.find(S)!=myShapeToHypothesis.end();
969 }
970
971 //=======================================================================
972 //function : NewSubMesh 
973 //purpose  : 
974 //=======================================================================
975 SMESHDS_SubMesh * SMESHDS_Mesh::NewSubMesh(int Index)
976 {
977   SMESHDS_SubMesh* SM = 0;
978   if (myShapeIndexToSubMesh.find(Index)==myShapeIndexToSubMesh.end())
979   {
980     SM = new SMESHDS_SubMesh();
981     myShapeIndexToSubMesh[Index]=SM;
982   }
983   else
984     SM = myShapeIndexToSubMesh[Index];
985   return SM;
986 }
987
988 //=======================================================================
989 //function : AddCompoundSubmesh
990 //purpose  : 
991 //=======================================================================
992
993 int SMESHDS_Mesh::AddCompoundSubmesh(const TopoDS_Shape& S,
994                                      TopAbs_ShapeEnum    type)
995 {
996   int aMainIndex = 0;
997   if ( IsGroupOfSubShapes( S ) || (S.ShapeType() == TopAbs_VERTEX && myIndexToShape.Contains(S)) )
998   {
999     aMainIndex = myIndexToShape.Add( S );
1000     bool all = ( type == TopAbs_SHAPE );
1001     if ( all ) // corresponding simple submesh may exist
1002       aMainIndex = -aMainIndex;
1003     //MESSAGE("AddCompoundSubmesh index = " << aMainIndex );
1004     SMESHDS_SubMesh * aNewSub = NewSubMesh( aMainIndex );
1005     if ( !aNewSub->IsComplexSubmesh() ) // is empty
1006     {
1007       int shapeType = all ? myShape.ShapeType() : type;
1008       int typeLimit = all ? TopAbs_VERTEX : type;
1009       for ( ; shapeType <= typeLimit; shapeType++ )
1010       {
1011         TopExp_Explorer exp( S, TopAbs_ShapeEnum( shapeType ));
1012         for ( ; exp.More(); exp.Next() )
1013         {
1014           int index = myIndexToShape.FindIndex( exp.Current() );
1015           if ( index )
1016             aNewSub->AddSubMesh( NewSubMesh( index ));
1017         }
1018       }
1019     }
1020   }
1021   return aMainIndex;
1022 }
1023
1024 //=======================================================================
1025 //function : IndexToShape
1026 //purpose  : 
1027 //=======================================================================
1028 TopoDS_Shape SMESHDS_Mesh::IndexToShape(int ShapeIndex)
1029 {
1030         return myIndexToShape.FindKey(ShapeIndex);
1031 }
1032
1033 //=======================================================================
1034 //function : ShapeToIndex
1035 //purpose  : 
1036 //=======================================================================
1037 int SMESHDS_Mesh::ShapeToIndex(const TopoDS_Shape & S) const
1038 {
1039   if (myShape.IsNull())
1040     MESSAGE("myShape is NULL");
1041
1042   int index = myIndexToShape.FindIndex(S);
1043   
1044   return index;
1045 }
1046
1047 //=======================================================================
1048 //function : SetNodeOnVolume
1049 //purpose  : 
1050 //=======================================================================
1051 void SMESHDS_Mesh::SetNodeInVolume(const SMDS_MeshNode* aNode, int Index)
1052 {
1053         //Set Position on Node
1054         //Handle (SMDS_FacePosition) aPos = new SMDS_FacePosition (myFaceToId(S),0.,0.);;
1055         //aNode->SetPosition(aPos);
1056
1057         //Update or build submesh
1058         if (myShapeIndexToSubMesh.find(Index)==myShapeIndexToSubMesh.end())
1059                 myShapeIndexToSubMesh[Index]=new SMESHDS_SubMesh();
1060
1061         myShapeIndexToSubMesh[Index]->AddNode(aNode);
1062 }
1063
1064 //=======================================================================
1065 //function : SetNodeOnFace
1066 //purpose  : 
1067 //=======================================================================
1068 void SMESHDS_Mesh::SetNodeOnFace(SMDS_MeshNode* aNode, int Index)
1069 {
1070         //Set Position on Node
1071         aNode->SetPosition(SMDS_PositionPtr(new SMDS_FacePosition(Index, 0., 0.)));
1072
1073         //Update or build submesh
1074         if (myShapeIndexToSubMesh.find(Index)==myShapeIndexToSubMesh.end())
1075                 myShapeIndexToSubMesh[Index]=new SMESHDS_SubMesh();
1076
1077         myShapeIndexToSubMesh[Index]->AddNode(aNode);
1078 }
1079
1080 //=======================================================================
1081 //function : SetNodeOnEdge
1082 //purpose  : 
1083 //=======================================================================
1084 void SMESHDS_Mesh::SetNodeOnEdge(SMDS_MeshNode* aNode, int Index)
1085 {
1086         //Set Position on Node
1087         aNode->SetPosition(SMDS_PositionPtr(new SMDS_EdgePosition(Index, 0.)));
1088
1089         //Update or build submesh
1090         if (myShapeIndexToSubMesh.find(Index)==myShapeIndexToSubMesh.end())
1091                 myShapeIndexToSubMesh[Index]=new SMESHDS_SubMesh();
1092
1093         myShapeIndexToSubMesh[Index]->AddNode(aNode);
1094 }
1095
1096 //=======================================================================
1097 //function : SetNodeOnVertex
1098 //purpose  : 
1099 //=======================================================================
1100 void SMESHDS_Mesh::SetNodeOnVertex(SMDS_MeshNode* aNode, int Index)
1101 {
1102         //Set Position on Node
1103         aNode->SetPosition(SMDS_PositionPtr(new SMDS_VertexPosition(Index)));
1104
1105         //Update or build submesh
1106         if (myShapeIndexToSubMesh.find(Index)==myShapeIndexToSubMesh.end())
1107                 myShapeIndexToSubMesh[Index]=new SMESHDS_SubMesh();
1108
1109         myShapeIndexToSubMesh[Index]->AddNode(aNode);
1110 }
1111
1112 //=======================================================================
1113 //function : SetMeshElementOnShape
1114 //purpose  : 
1115 //=======================================================================
1116 void SMESHDS_Mesh::SetMeshElementOnShape(const SMDS_MeshElement* anElement,
1117         int Index)
1118 {
1119         if (myShapeIndexToSubMesh.find(Index)==myShapeIndexToSubMesh.end())
1120                 myShapeIndexToSubMesh[Index]=new SMESHDS_SubMesh();
1121
1122         myShapeIndexToSubMesh[Index]->AddElement(anElement);
1123 }
1124
1125 SMESHDS_Mesh::~SMESHDS_Mesh()
1126 {
1127 }