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