Salome HOME
Advanced feature for sewing - polygons creation instead of splitting.
[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)
880 {
881   if (myShape.IsNull()) MESSAGE("myShape is NULL");
882
883   int Index = ShapeToIndex(S);
884   if (myShapeIndexToSubMesh.find(Index)!=myShapeIndexToSubMesh.end())
885     return myShapeIndexToSubMesh[Index];
886   else
887     return NULL;
888 }
889
890 ///////////////////////////////////////////////////////////////////////////////
891 /// Return the sub mesh by Id of shape it is linked to
892 ///////////////////////////////////////////////////////////////////////////////
893 SMESHDS_SubMesh * SMESHDS_Mesh::MeshElements(const int Index)
894 {
895   if (myShape.IsNull()) MESSAGE("myShape is NULL");
896
897   if (myShapeIndexToSubMesh.find(Index)!=myShapeIndexToSubMesh.end())
898     return myShapeIndexToSubMesh[Index];
899   else
900     return NULL;
901 }
902
903 //=======================================================================
904 //function : SubMeshIndices
905 //purpose  : 
906 //=======================================================================
907 list<int> SMESHDS_Mesh::SubMeshIndices()
908 {
909   list<int> anIndices;
910   std::map<int,SMESHDS_SubMesh*>::iterator anIter = myShapeIndexToSubMesh.begin();
911   for (; anIter != myShapeIndexToSubMesh.end(); anIter++) {
912     anIndices.push_back((*anIter).first);
913   }
914   return anIndices;
915 }
916
917 //=======================================================================
918 //function : GetHypothesis
919 //purpose  : 
920 //=======================================================================
921
922 const list<const SMESHDS_Hypothesis*>& SMESHDS_Mesh::GetHypothesis(
923         const TopoDS_Shape & S) const
924 {
925         if (myShapeToHypothesis.find(S)!=myShapeToHypothesis.end())
926                 return myShapeToHypothesis.find(S)->second;
927
928         static list<const SMESHDS_Hypothesis*> empty;
929         return empty;
930 }
931
932 //=======================================================================
933 //function : GetScript
934 //purpose  : 
935 //=======================================================================
936 SMESHDS_Script* SMESHDS_Mesh::GetScript()
937 {
938         return myScript;
939 }
940
941 //=======================================================================
942 //function : ClearScript
943 //purpose  : 
944 //=======================================================================
945 void SMESHDS_Mesh::ClearScript()
946 {
947         myScript->Clear();
948 }
949
950 //=======================================================================
951 //function : HasMeshElements
952 //purpose  : 
953 //=======================================================================
954 bool SMESHDS_Mesh::HasMeshElements(const TopoDS_Shape & S)
955 {
956         if (myShape.IsNull()) MESSAGE("myShape is NULL");
957         int Index = myIndexToShape.FindIndex(S);
958         return myShapeIndexToSubMesh.find(Index)!=myShapeIndexToSubMesh.end();
959 }
960
961 //=======================================================================
962 //function : HasHypothesis
963 //purpose  : 
964 //=======================================================================
965 bool SMESHDS_Mesh::HasHypothesis(const TopoDS_Shape & S)
966 {
967         return myShapeToHypothesis.find(S)!=myShapeToHypothesis.end();
968 }
969
970 //=======================================================================
971 //function : NewSubMesh 
972 //purpose  : 
973 //=======================================================================
974 SMESHDS_SubMesh * SMESHDS_Mesh::NewSubMesh(int Index)
975 {
976   SMESHDS_SubMesh* SM = 0;
977   if (myShapeIndexToSubMesh.find(Index)==myShapeIndexToSubMesh.end())
978   {
979     SM = new SMESHDS_SubMesh();
980     myShapeIndexToSubMesh[Index]=SM;
981   }
982   else
983     SM = myShapeIndexToSubMesh[Index];
984   return SM;
985 }
986
987 //=======================================================================
988 //function : AddCompoundSubmesh
989 //purpose  : 
990 //=======================================================================
991
992 int SMESHDS_Mesh::AddCompoundSubmesh(const TopoDS_Shape& S,
993                                      TopAbs_ShapeEnum    type)
994 {
995   int aMainIndex = 0;
996   if ( IsGroupOfSubShapes( S ))
997   {
998     aMainIndex = myIndexToShape.Add( S );
999     bool all = ( type == TopAbs_SHAPE );
1000     if ( all ) // corresponding simple submesh may exist
1001       aMainIndex = -aMainIndex;
1002     //MESSAGE("AddCompoundSubmesh index = " << aMainIndex );
1003     SMESHDS_SubMesh * aNewSub = NewSubMesh( aMainIndex );
1004     if ( !aNewSub->IsComplexSubmesh() ) // is empty
1005     {
1006       int shapeType = all ? myShape.ShapeType() : type;
1007       int typeLimit = all ? TopAbs_VERTEX : type;
1008       for ( ; shapeType <= typeLimit; shapeType++ )
1009       {
1010         TopExp_Explorer exp( S, TopAbs_ShapeEnum( shapeType ));
1011         for ( ; exp.More(); exp.Next() )
1012         {
1013           int index = myIndexToShape.FindIndex( exp.Current() );
1014           if ( index )
1015             aNewSub->AddSubMesh( NewSubMesh( index ));
1016         }
1017       }
1018     }
1019   }
1020   return aMainIndex;
1021 }
1022
1023 //=======================================================================
1024 //function : IndexToShape
1025 //purpose  : 
1026 //=======================================================================
1027 TopoDS_Shape SMESHDS_Mesh::IndexToShape(int ShapeIndex)
1028 {
1029         return myIndexToShape.FindKey(ShapeIndex);
1030 }
1031
1032 //=======================================================================
1033 //function : ShapeToIndex
1034 //purpose  : 
1035 //=======================================================================
1036 int SMESHDS_Mesh::ShapeToIndex(const TopoDS_Shape & S)
1037 {
1038   if (myShape.IsNull())
1039     MESSAGE("myShape is NULL");
1040
1041   int index = myIndexToShape.FindIndex(S);
1042   
1043   return index;
1044 }
1045
1046 //=======================================================================
1047 //function : SetNodeOnVolume
1048 //purpose  : 
1049 //=======================================================================
1050 void SMESHDS_Mesh::SetNodeInVolume(const SMDS_MeshNode* aNode, int Index)
1051 {
1052         //Set Position on Node
1053         //Handle (SMDS_FacePosition) aPos = new SMDS_FacePosition (myFaceToId(S),0.,0.);;
1054         //aNode->SetPosition(aPos);
1055
1056         //Update or build submesh
1057         if (myShapeIndexToSubMesh.find(Index)==myShapeIndexToSubMesh.end())
1058                 myShapeIndexToSubMesh[Index]=new SMESHDS_SubMesh();
1059
1060         myShapeIndexToSubMesh[Index]->AddNode(aNode);
1061 }
1062
1063 //=======================================================================
1064 //function : SetNodeOnFace
1065 //purpose  : 
1066 //=======================================================================
1067 void SMESHDS_Mesh::SetNodeOnFace(SMDS_MeshNode* aNode, int Index)
1068 {
1069         //Set Position on Node
1070         aNode->SetPosition(SMDS_PositionPtr(new SMDS_FacePosition(Index, 0., 0.)));
1071
1072         //Update or build submesh
1073         if (myShapeIndexToSubMesh.find(Index)==myShapeIndexToSubMesh.end())
1074                 myShapeIndexToSubMesh[Index]=new SMESHDS_SubMesh();
1075
1076         myShapeIndexToSubMesh[Index]->AddNode(aNode);
1077 }
1078
1079 //=======================================================================
1080 //function : SetNodeOnEdge
1081 //purpose  : 
1082 //=======================================================================
1083 void SMESHDS_Mesh::SetNodeOnEdge(SMDS_MeshNode* aNode, int Index)
1084 {
1085         //Set Position on Node
1086         aNode->SetPosition(SMDS_PositionPtr(new SMDS_EdgePosition(Index, 0.)));
1087
1088         //Update or build submesh
1089         if (myShapeIndexToSubMesh.find(Index)==myShapeIndexToSubMesh.end())
1090                 myShapeIndexToSubMesh[Index]=new SMESHDS_SubMesh();
1091
1092         myShapeIndexToSubMesh[Index]->AddNode(aNode);
1093 }
1094
1095 //=======================================================================
1096 //function : SetNodeOnVertex
1097 //purpose  : 
1098 //=======================================================================
1099 void SMESHDS_Mesh::SetNodeOnVertex(SMDS_MeshNode* aNode, int Index)
1100 {
1101         //Set Position on Node
1102         aNode->SetPosition(SMDS_PositionPtr(new SMDS_VertexPosition(Index)));
1103
1104         //Update or build submesh
1105         if (myShapeIndexToSubMesh.find(Index)==myShapeIndexToSubMesh.end())
1106                 myShapeIndexToSubMesh[Index]=new SMESHDS_SubMesh();
1107
1108         myShapeIndexToSubMesh[Index]->AddNode(aNode);
1109 }
1110
1111 //=======================================================================
1112 //function : SetMeshElementOnShape
1113 //purpose  : 
1114 //=======================================================================
1115 void SMESHDS_Mesh::SetMeshElementOnShape(const SMDS_MeshElement* anElement,
1116         int Index)
1117 {
1118         if (myShapeIndexToSubMesh.find(Index)==myShapeIndexToSubMesh.end())
1119                 myShapeIndexToSubMesh[Index]=new SMESHDS_SubMesh();
1120
1121         myShapeIndexToSubMesh[Index]->AddElement(anElement);
1122 }
1123
1124 SMESHDS_Mesh::~SMESHDS_Mesh()
1125 {
1126 }