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