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