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