Salome HOME
Merge with version on tag OCC-V2_1_0d
[modules/smesh.git] / src / SMESHDS / SMESHDS_Mesh.cxx
1 //  SMESH SMESHDS : management of mesh data and SMESH document
2 //
3 //  Copyright (C) 2003  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 //  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS 
5 // 
6 //  This library is free software; you can redistribute it and/or 
7 //  modify it under the terms of the GNU Lesser General Public 
8 //  License as published by the Free Software Foundation; either 
9 //  version 2.1 of the License. 
10 // 
11 //  This library is distributed in the hope that it will be useful, 
12 //  but WITHOUT ANY WARRANTY; without even the implied warranty of 
13 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
14 //  Lesser General Public License for more details. 
15 // 
16 //  You should have received a copy of the GNU Lesser General Public 
17 //  License along with this library; if not, write to the Free Software 
18 //  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA 
19 // 
20 //  See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org 
21 //
22 //
23 //
24 //  File   : SMESH_Mesh.cxx
25 //  Author : Yves FRICAUD, OCC
26 //  Module : SMESH
27 //  $Header: 
28
29 #include "SMESHDS_Mesh.hxx"
30
31 #include "SMESHDS_Group.hxx"
32 #include "SMDS_VertexPosition.hxx"
33 #include "SMDS_EdgePosition.hxx"
34 #include "SMDS_FacePosition.hxx"
35 #include <TopExp_Explorer.hxx>
36 #include <TopExp.hxx>
37 #include <TopoDS_Iterator.hxx>
38
39 #include "utilities.h"
40
41 using namespace std;
42
43 //=======================================================================
44 //function : Create
45 //purpose  : 
46 //=======================================================================
47 SMESHDS_Mesh::SMESHDS_Mesh(int MeshID):myMeshID(MeshID)
48 {
49         myScript = new SMESHDS_Script();
50 }
51
52 //=======================================================================
53 //function : ShapeToMesh
54 //purpose  : 
55 //=======================================================================
56 void SMESHDS_Mesh::ShapeToMesh(const TopoDS_Shape & S)
57 {
58         myShape = S;
59         TopExp::MapShapes(myShape, myIndexToShape);
60 }
61
62 //=======================================================================
63 //function : AddHypothesis
64 //purpose  : 
65 //=======================================================================
66
67 bool SMESHDS_Mesh::AddHypothesis(const TopoDS_Shape & SS,
68         const SMESHDS_Hypothesis * H)
69 {
70         list<const SMESHDS_Hypothesis *>& alist=myShapeToHypothesis[SS];
71
72         //Check if the Hypothesis is still present
73         list<const SMESHDS_Hypothesis*>::iterator ith=alist.begin();
74
75         for (; ith!=alist.end(); ith++)
76                 if (H == *ith) return false;
77
78         alist.push_back(H);
79         return true;
80 }
81
82 //=======================================================================
83 //function : RemoveHypothesis
84 //purpose  : 
85 //=======================================================================
86
87 bool SMESHDS_Mesh::RemoveHypothesis(const TopoDS_Shape & S,
88         const SMESHDS_Hypothesis * H)
89 {
90         ShapeToHypothesis::iterator its=myShapeToHypothesis.find(S);
91         if(its!=myShapeToHypothesis.end())
92         {
93                 list<const SMESHDS_Hypothesis*>::iterator ith=(*its).second.begin();
94
95                 for (; ith!=(*its).second.end(); ith++)
96                         if (H == *ith)
97                         {
98                                 (*its).second.erase(ith);
99                                 return true;
100                         }
101         }
102         return false;
103 }
104
105 //=======================================================================
106 //function : AddNode
107 //purpose  : 
108 //=======================================================================
109 SMDS_MeshNode* SMESHDS_Mesh::AddNode(double x, double y, double z){
110   SMDS_MeshNode* node = SMDS_Mesh::AddNode(x, y, z);
111   if(node!=NULL) myScript->AddNode(node->GetID(), x, y, z);
112   return node;
113 }
114
115 SMDS_MeshNode* SMESHDS_Mesh::AddNodeWithID(double x, double y, double z, int ID){
116   SMDS_MeshNode* node = SMDS_Mesh::AddNodeWithID(x,y,z,ID);
117   if(node!=NULL) myScript->AddNode(node->GetID(), x, y, z);
118   return node;
119 }
120
121 //=======================================================================
122 //function : MoveNode
123 //purpose  : 
124 //=======================================================================
125 void SMESHDS_Mesh::MoveNode(const SMDS_MeshNode *n, double x, double y, double z)
126 {
127   SMDS_MeshNode * node=const_cast<SMDS_MeshNode*>(n);
128   node->setXYZ(x,y,z);
129   myScript->MoveNode(n->GetID(), x, y, z);
130 }
131
132 //=======================================================================
133 //function : ChangeElementNodes
134 //purpose  : 
135 //=======================================================================
136
137 bool SMESHDS_Mesh::ChangeElementNodes(const SMDS_MeshElement * elem,
138                                       const SMDS_MeshNode    * nodes[],
139                                       const int                nbnodes)
140 {
141   if ( ! SMDS_Mesh::ChangeElementNodes( elem, nodes, nbnodes ))
142     return false;
143
144   ASSERT( nbnodes < 9 );
145   int i, IDs[ 8 ];
146   for ( i = 0; i < nbnodes; i++ )
147     IDs [ i ] = nodes[ i ]->GetID();
148   myScript->ChangeElementNodes( elem->GetID(), IDs, nbnodes);
149
150   return true;
151 }
152
153 //=======================================================================
154 //function : Renumber
155 //purpose  : 
156 //=======================================================================
157
158 void SMESHDS_Mesh::Renumber (const bool isNodes, const int startID, const int deltaID)
159 {
160   SMDS_Mesh::Renumber( isNodes, startID, deltaID );
161   myScript->Renumber( isNodes, startID, deltaID );
162 }
163
164 //=======================================================================
165 //function :AddEdgeWithID
166 //purpose  : 
167 //=======================================================================
168 SMDS_MeshEdge* SMESHDS_Mesh::AddEdgeWithID(int n1, int n2, int ID)
169 {
170   SMDS_MeshEdge* anElem = SMDS_Mesh::AddEdgeWithID(n1,n2,ID);
171   if(anElem) myScript->AddEdge(ID,n1,n2);
172   return anElem;
173 }
174
175 SMDS_MeshEdge* SMESHDS_Mesh::AddEdgeWithID(const SMDS_MeshNode * n1,
176                                            const SMDS_MeshNode * n2, 
177                                            int ID)
178 {
179   return AddEdgeWithID(n1->GetID(),
180                        n2->GetID(),
181                        ID);
182 }
183
184 SMDS_MeshEdge* SMESHDS_Mesh::AddEdge(const SMDS_MeshNode * n1,
185                                      const SMDS_MeshNode * n2)
186 {
187   SMDS_MeshEdge* anElem = SMDS_Mesh::AddEdge(n1,n2);
188   if(anElem) myScript->AddEdge(anElem->GetID(), 
189                                n1->GetID(), 
190                                n2->GetID());
191   return anElem;
192 }
193
194 //=======================================================================
195 //function :AddFace
196 //purpose  : 
197 //=======================================================================
198 SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(int n1, int n2, int n3, int ID)
199 {
200   SMDS_MeshFace *anElem = SMDS_Mesh::AddFaceWithID(n1, n2, n3, ID);
201   if(anElem) myScript->AddFace(ID,n1,n2,n3);
202   return anElem;
203 }
204
205 SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
206                                            const SMDS_MeshNode * n2,
207                                            const SMDS_MeshNode * n3, 
208                                            int ID)
209 {
210   return AddFaceWithID(n1->GetID(),
211                        n2->GetID(),
212                        n3->GetID(),
213                        ID);
214 }
215
216 SMDS_MeshFace* SMESHDS_Mesh::AddFace( const SMDS_MeshNode * n1,
217                                       const SMDS_MeshNode * n2,
218                                       const SMDS_MeshNode * n3)
219 {
220   SMDS_MeshFace *anElem = SMDS_Mesh::AddFace(n1, n2, n3);
221   if(anElem) myScript->AddFace(anElem->GetID(), 
222                                n1->GetID(), 
223                                n2->GetID(),
224                                n3->GetID());
225   return anElem;
226 }
227
228 //=======================================================================
229 //function :AddFace
230 //purpose  : 
231 //=======================================================================
232 SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(int n1, int n2, int n3, int n4, int ID)
233 {
234   SMDS_MeshFace *anElem = SMDS_Mesh::AddFaceWithID(n1, n2, n3, n4, ID);
235   if(anElem) myScript->AddFace(ID, n1, n2, n3, n4);
236   return anElem;
237 }
238
239 SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
240                                            const SMDS_MeshNode * n2,
241                                            const SMDS_MeshNode * n3,
242                                            const SMDS_MeshNode * n4, 
243                                            int ID)
244 {
245   return AddFaceWithID(n1->GetID(),
246                        n2->GetID(),
247                        n3->GetID(),
248                        n4->GetID(),
249                        ID);
250 }
251
252 SMDS_MeshFace* SMESHDS_Mesh::AddFace(const SMDS_MeshNode * n1,
253                                      const SMDS_MeshNode * n2,
254                                      const SMDS_MeshNode * n3,
255                                      const SMDS_MeshNode * n4)
256 {
257   SMDS_MeshFace *anElem = SMDS_Mesh::AddFace(n1, n2, n3, n4);
258   if(anElem) myScript->AddFace(anElem->GetID(), 
259                                n1->GetID(), 
260                                n2->GetID(), 
261                                n3->GetID(),
262                                n4->GetID());
263   return anElem;
264 }
265
266 //=======================================================================
267 //function :AddVolume
268 //purpose  : 
269 //=======================================================================
270 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4, int ID)
271 {
272   SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, ID);
273   if(anElem) myScript->AddVolume(ID, n1, n2, n3, n4);
274   return anElem;
275 }
276
277 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
278                                                const SMDS_MeshNode * n2,
279                                                const SMDS_MeshNode * n3,
280                                                const SMDS_MeshNode * n4, 
281                                                int ID)
282 {
283   return AddVolumeWithID(n1->GetID(), 
284                          n2->GetID(), 
285                          n3->GetID(),
286                          n4->GetID(),
287                          ID);
288 }
289
290 SMDS_MeshVolume* SMESHDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
291                                          const SMDS_MeshNode * n2,
292                                          const SMDS_MeshNode * n3,
293                                          const SMDS_MeshNode * n4)
294 {
295   SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolume(n1, n2, n3, n4);
296   if(anElem) myScript->AddVolume(anElem->GetID(), 
297                                  n1->GetID(), 
298                                  n2->GetID(), 
299                                  n3->GetID(),
300                                  n4->GetID());
301   return anElem;
302 }
303
304 //=======================================================================
305 //function :AddVolume
306 //purpose  : 
307 //=======================================================================
308 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4, int n5, int ID)
309 {
310   SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, ID);
311   if(anElem) myScript->AddVolume(ID, n1, n2, n3, n4, n5);
312   return anElem;
313 }
314
315 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
316                                                const SMDS_MeshNode * n2,
317                                                const SMDS_MeshNode * n3,
318                                                const SMDS_MeshNode * n4,
319                                                const SMDS_MeshNode * n5, 
320                                                int ID)
321 {
322   return AddVolumeWithID(n1->GetID(), 
323                          n2->GetID(), 
324                          n3->GetID(),
325                          n4->GetID(), 
326                          n5->GetID(),
327                          ID);
328 }
329
330 SMDS_MeshVolume* SMESHDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
331                                          const SMDS_MeshNode * n2,
332                                          const SMDS_MeshNode * n3,
333                                          const SMDS_MeshNode * n4,
334                                          const SMDS_MeshNode * n5)
335 {
336   SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolume(n1, n2, n3, n4, n5);
337   if(anElem) myScript->AddVolume(anElem->GetID(), 
338                                  n1->GetID(), 
339                                  n2->GetID(), 
340                                  n3->GetID(),
341                                  n4->GetID(), 
342                                  n5->GetID());
343   return anElem;
344 }
345
346 //=======================================================================
347 //function :AddVolume
348 //purpose  : 
349 //=======================================================================
350 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4, int n5, int n6, int ID)
351 {
352   SMDS_MeshVolume *anElem= SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, ID);
353   if(anElem) myScript->AddVolume(ID, n1, n2, n3, n4, n5, n6);
354   return anElem;
355 }
356
357 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
358                                                const SMDS_MeshNode * n2,
359                                                const SMDS_MeshNode * n3,
360                                                const SMDS_MeshNode * n4,
361                                                const SMDS_MeshNode * n5,
362                                                const SMDS_MeshNode * n6, 
363                                                int ID)
364 {
365   return AddVolumeWithID(n1->GetID(), 
366                          n2->GetID(), 
367                          n3->GetID(),
368                          n4->GetID(), 
369                          n5->GetID(), 
370                          n6->GetID(),
371                          ID);
372 }
373
374 SMDS_MeshVolume* SMESHDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
375                                          const SMDS_MeshNode * n2,
376                                          const SMDS_MeshNode * n3,
377                                          const SMDS_MeshNode * n4,
378                                          const SMDS_MeshNode * n5,
379                                          const SMDS_MeshNode * n6)
380 {
381   SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolume(n1, n2, n3, n4, n5, n6);
382   if(anElem) myScript->AddVolume(anElem->GetID(), 
383                                  n1->GetID(), 
384                                  n2->GetID(), 
385                                  n3->GetID(),
386                                  n4->GetID(), 
387                                  n5->GetID(), 
388                                  n6->GetID());
389   return anElem;
390 }
391
392 //=======================================================================
393 //function :AddVolume
394 //purpose  : 
395 //=======================================================================
396 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4, int n5, int n6, int n7, int n8, int ID)
397 {
398   SMDS_MeshVolume *anElem= SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, n7, n8, ID);
399   if(anElem) myScript->AddVolume(ID, n1, n2, n3, n4, n5, n6, n7, n8);
400   return anElem;
401 }
402
403 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
404                                                const SMDS_MeshNode * n2,
405                                                const SMDS_MeshNode * n3,
406                                                const SMDS_MeshNode * n4,
407                                                const SMDS_MeshNode * n5,
408                                                const SMDS_MeshNode * n6,
409                                                const SMDS_MeshNode * n7,
410                                                const SMDS_MeshNode * n8, 
411                                                int ID)
412 {
413   return AddVolumeWithID(n1->GetID(), 
414                          n2->GetID(), 
415                          n3->GetID(),
416                          n4->GetID(), 
417                          n5->GetID(), 
418                          n6->GetID(), 
419                          n7->GetID(), 
420                          n8->GetID(),
421                          ID);
422 }
423
424 SMDS_MeshVolume* SMESHDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
425                                          const SMDS_MeshNode * n2,
426                                          const SMDS_MeshNode * n3,
427                                          const SMDS_MeshNode * n4,
428                                          const SMDS_MeshNode * n5,
429                                          const SMDS_MeshNode * n6,
430                                          const SMDS_MeshNode * n7,
431                                          const SMDS_MeshNode * n8)
432 {
433   SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolume(n1, n2, n3, n4, n5, n6, n7, n8);
434   if(anElem) myScript->AddVolume(anElem->GetID(), 
435                                  n1->GetID(), 
436                                  n2->GetID(), 
437                                  n3->GetID(),
438                                  n4->GetID(), 
439                                  n5->GetID(), 
440                                  n6->GetID(), 
441                                  n7->GetID(), 
442                                  n8->GetID());
443   return anElem;
444 }
445 //=======================================================================
446 //function : removeFromContainers
447 //purpose  : 
448 //=======================================================================
449
450 static void removeFromContainers (map<int,SMESHDS_SubMesh*> &      theSubMeshes,
451                                   set<SMESHDS_GroupBase*>&             theGroups,
452                                   list<const SMDS_MeshElement *> & theElems,
453                                   const bool                       isNode)
454 {
455   if ( theElems.empty() )
456     return;
457
458   // Rm from group
459   // Element can belong to several groups
460   if ( !theGroups.empty() )
461   {
462     set<SMESHDS_GroupBase*>::iterator GrIt = theGroups.begin();
463     for ( ; GrIt != theGroups.end(); GrIt++ )
464     {
465       SMESHDS_Group* group = dynamic_cast<SMESHDS_Group*>( *GrIt );
466       if ( !group || group->IsEmpty() ) continue;
467
468       list<const SMDS_MeshElement *>::iterator elIt = theElems.begin();
469       for ( ; elIt != theElems.end(); elIt++ )
470       {
471         group->SMDSGroup().Remove( *elIt );
472         if ( group->IsEmpty() ) break;
473       }
474     }
475   }
476
477   // Rm from sub-meshes
478   // Element should belong to only one sub-mesh
479   map<int,SMESHDS_SubMesh*>::iterator SubIt = theSubMeshes.begin();
480   for ( ; SubIt != theSubMeshes.end(); SubIt++ )
481   {
482     int size = isNode ? (*SubIt).second->NbNodes() : (*SubIt).second->NbElements();
483     if ( size == 0 ) continue;
484
485     list<const SMDS_MeshElement *>::iterator elIt = theElems.begin();
486     while ( elIt != theElems.end() )
487     {
488       bool removed = false;
489       if ( isNode )
490         removed = (*SubIt).second->RemoveNode( static_cast<const SMDS_MeshNode*> (*elIt) );
491       else
492         removed = (*SubIt).second->RemoveElement( *elIt );
493
494       if (removed)
495       {
496         elIt = theElems.erase( elIt );
497         if ( theElems.empty() )
498           return; // all elements are found and removed
499       }
500       else
501       {
502         elIt++ ;
503       }
504     }
505   }
506 }
507   
508 //=======================================================================
509 //function : RemoveNode
510 //purpose  : 
511 //=======================================================================
512 void SMESHDS_Mesh::RemoveNode(const SMDS_MeshNode * n)
513 {
514   myScript->RemoveNode(n->GetID());
515   
516   list<const SMDS_MeshElement *> removedElems;
517   list<const SMDS_MeshElement *> removedNodes;
518
519   SMDS_Mesh::RemoveElement( n, removedElems, removedNodes, true );
520
521   removeFromContainers( myShapeIndexToSubMesh, myGroups, removedElems, false );
522   removeFromContainers( myShapeIndexToSubMesh, myGroups, removedNodes, true );
523 }
524
525 //=======================================================================
526 //function : RemoveElement
527 //purpose  : 
528 //========================================================================
529 void SMESHDS_Mesh::RemoveElement(const SMDS_MeshElement * elt)
530 {
531   if (elt->GetType() == SMDSAbs_Node)
532   {
533     RemoveNode( static_cast<const SMDS_MeshNode*>( elt ));
534     return;
535   }
536
537   myScript->RemoveElement(elt->GetID());
538
539   list<const SMDS_MeshElement *> removedElems;
540   list<const SMDS_MeshElement *> removedNodes;
541
542   SMDS_Mesh::RemoveElement(elt, removedElems, removedNodes, false);
543   
544   removeFromContainers( myShapeIndexToSubMesh, myGroups, removedElems, false );
545 }
546
547 //=======================================================================
548 //function : SetNodeOnVolume
549 //purpose  : 
550 //=======================================================================
551 void SMESHDS_Mesh::SetNodeInVolume(SMDS_MeshNode * aNode,
552         const TopoDS_Shell & S)
553 {
554         if (myShape.IsNull()) MESSAGE("myShape is NULL");
555
556         int Index = myIndexToShape.FindIndex(S);
557
558         //Set Position on Node
559         //Handle (SMDS_FacePosition) aPos = new SMDS_FacePosition (myFaceToId(S),0.,0.);;
560         //aNode->SetPosition(aPos);
561
562         //Update or build submesh
563         map<int,SMESHDS_SubMesh*>::iterator it=myShapeIndexToSubMesh.find(Index);
564         if (it==myShapeIndexToSubMesh.end())
565                 myShapeIndexToSubMesh[Index]= new SMESHDS_SubMesh();
566
567         myShapeIndexToSubMesh[Index]->AddNode(aNode);
568 }
569
570 //=======================================================================
571 //function : SetNodeOnFace
572 //purpose  : 
573 //=======================================================================
574 void SMESHDS_Mesh::SetNodeOnFace(SMDS_MeshNode * aNode,
575         const TopoDS_Face & S)
576 {
577         if (myShape.IsNull()) MESSAGE("myShape is NULL");
578
579         int Index = myIndexToShape.FindIndex(S);
580
581         //Set Position on Node
582         aNode->SetPosition(SMDS_PositionPtr(new SMDS_FacePosition(Index, 0., 0.)));
583
584         //Update or build submesh
585         map<int,SMESHDS_SubMesh*>::iterator it=myShapeIndexToSubMesh.find(Index);
586         if (it==myShapeIndexToSubMesh.end())
587                 myShapeIndexToSubMesh[Index]= new SMESHDS_SubMesh();
588
589         myShapeIndexToSubMesh[Index]->AddNode(aNode);
590 }
591
592 //=======================================================================
593 //function : SetNodeOnEdge
594 //purpose  : 
595 //=======================================================================
596 void SMESHDS_Mesh::SetNodeOnEdge(SMDS_MeshNode * aNode,
597         const TopoDS_Edge & S)
598 {
599         if (myShape.IsNull()) MESSAGE("myShape is NULL");
600
601         int Index = myIndexToShape.FindIndex(S);
602
603         //Set Position on Node
604         aNode->SetPosition(SMDS_PositionPtr(new SMDS_EdgePosition(Index, 0.)));
605
606         //Update or build submesh
607         map<int,SMESHDS_SubMesh*>::iterator it=myShapeIndexToSubMesh.find(Index);
608         if (it==myShapeIndexToSubMesh.end())
609                 myShapeIndexToSubMesh[Index]= new SMESHDS_SubMesh();
610
611         myShapeIndexToSubMesh[Index]->AddNode(aNode);
612 }
613
614 //=======================================================================
615 //function : SetNodeOnVertex
616 //purpose  : 
617 //=======================================================================
618 void SMESHDS_Mesh::SetNodeOnVertex(SMDS_MeshNode * aNode,
619         const TopoDS_Vertex & S)
620 {
621         if (myShape.IsNull()) MESSAGE("myShape is NULL");
622
623         int Index = myIndexToShape.FindIndex(S);
624
625         //Set Position on Node
626         aNode->SetPosition(SMDS_PositionPtr(new SMDS_VertexPosition(Index)));
627
628         //Update or build submesh
629         map<int,SMESHDS_SubMesh*>::iterator it=myShapeIndexToSubMesh.find(Index);
630         if (it==myShapeIndexToSubMesh.end())
631                 myShapeIndexToSubMesh[Index]= new SMESHDS_SubMesh();
632
633         myShapeIndexToSubMesh[Index]->AddNode(aNode);
634 }
635
636 //=======================================================================
637 //function : UnSetNodeOnShape
638 //purpose  : 
639 //=======================================================================
640 void SMESHDS_Mesh::UnSetNodeOnShape(const SMDS_MeshNode* aNode)
641 {
642         MESSAGE("not implemented");
643 }
644
645 //=======================================================================
646 //function : SetMeshElementOnShape
647 //purpose  : 
648 //=======================================================================
649 void SMESHDS_Mesh::SetMeshElementOnShape(const SMDS_MeshElement * anElement,
650         const TopoDS_Shape & S)
651 {
652         if (myShape.IsNull()) MESSAGE("myShape is NULL");
653
654         int Index = myIndexToShape.FindIndex(S);
655
656         if (myShapeIndexToSubMesh.find(Index)==myShapeIndexToSubMesh.end())
657                 myShapeIndexToSubMesh[Index]=new SMESHDS_SubMesh();
658
659         myShapeIndexToSubMesh[Index]->AddElement(anElement);
660 }
661
662 //=======================================================================
663 //function : UnSetMeshElementOnShape
664 //purpose  : 
665 //=======================================================================
666 void SMESHDS_Mesh::
667 UnSetMeshElementOnShape(const SMDS_MeshElement * anElement,
668         const TopoDS_Shape & S)
669 {
670         if (myShape.IsNull()) MESSAGE("myShape is NULL");
671
672         int Index = myIndexToShape.FindIndex(S);
673
674         if (myShapeIndexToSubMesh.find(Index)!=myShapeIndexToSubMesh.end())
675                 myShapeIndexToSubMesh[Index]->RemoveElement(anElement);
676 }
677
678 //=======================================================================
679 //function : ShapeToMesh
680 //purpose  : 
681 //=======================================================================
682 TopoDS_Shape SMESHDS_Mesh::ShapeToMesh() const
683 {
684         return myShape;
685 }
686
687 //=======================================================================
688 //function : IsGroupOfSubShapes
689 //purpose  : return true if at least one subshape of theShape is a subshape
690 //           of myShape or theShape == myShape
691 //=======================================================================
692
693 bool SMESHDS_Mesh::IsGroupOfSubShapes (const TopoDS_Shape& theShape) const
694 {
695   if ( myShape.IsSame( theShape ))
696     return true;
697
698   for ( TopoDS_Iterator it( theShape ); it.More(); it.Next() ) {
699     if (myIndexToShape.Contains( it.Value() ) ||
700         IsGroupOfSubShapes( it.Value() ))
701       return true;
702   }
703   
704   return false;
705 }
706
707 ///////////////////////////////////////////////////////////////////////////////
708 /// Return the sub mesh linked to the a given TopoDS_Shape or NULL if the given
709 /// TopoDS_Shape is unknown
710 ///////////////////////////////////////////////////////////////////////////////
711 SMESHDS_SubMesh * SMESHDS_Mesh::MeshElements(const TopoDS_Shape & S)
712 {
713   if (myShape.IsNull()) MESSAGE("myShape is NULL");
714
715   int Index = ShapeToIndex(S);
716   if (myShapeIndexToSubMesh.find(Index)!=myShapeIndexToSubMesh.end())
717     return myShapeIndexToSubMesh[Index];
718   else
719     return NULL;
720 }
721
722 ///////////////////////////////////////////////////////////////////////////////
723 /// Return the sub mesh by Id of shape it is linked to
724 ///////////////////////////////////////////////////////////////////////////////
725 SMESHDS_SubMesh * SMESHDS_Mesh::MeshElements(const int Index)
726 {
727   if (myShape.IsNull()) MESSAGE("myShape is NULL");
728
729   if (myShapeIndexToSubMesh.find(Index)!=myShapeIndexToSubMesh.end())
730     return myShapeIndexToSubMesh[Index];
731   else
732     return NULL;
733 }
734
735 //=======================================================================
736 //function : SubMeshIndices
737 //purpose  : 
738 //=======================================================================
739 list<int> SMESHDS_Mesh::SubMeshIndices()
740 {
741   list<int> anIndices;
742   std::map<int,SMESHDS_SubMesh*>::iterator anIter = myShapeIndexToSubMesh.begin();
743   for (; anIter != myShapeIndexToSubMesh.end(); anIter++) {
744     anIndices.push_back((*anIter).first);
745   }
746   return anIndices;
747 }
748
749 //=======================================================================
750 //function : GetHypothesis
751 //purpose  : 
752 //=======================================================================
753
754 const list<const SMESHDS_Hypothesis*>& SMESHDS_Mesh::GetHypothesis(
755         const TopoDS_Shape & S) const
756 {
757         if (myShapeToHypothesis.find(S)!=myShapeToHypothesis.end())
758                 return myShapeToHypothesis.find(S)->second;
759
760         static list<const SMESHDS_Hypothesis*> empty;
761         return empty;
762 }
763
764 //=======================================================================
765 //function : GetScript
766 //purpose  : 
767 //=======================================================================
768 SMESHDS_Script* SMESHDS_Mesh::GetScript()
769 {
770         return myScript;
771 }
772
773 //=======================================================================
774 //function : ClearScript
775 //purpose  : 
776 //=======================================================================
777 void SMESHDS_Mesh::ClearScript()
778 {
779         myScript->Clear();
780 }
781
782 //=======================================================================
783 //function : HasMeshElements
784 //purpose  : 
785 //=======================================================================
786 bool SMESHDS_Mesh::HasMeshElements(const TopoDS_Shape & S)
787 {
788         if (myShape.IsNull()) MESSAGE("myShape is NULL");
789         int Index = myIndexToShape.FindIndex(S);
790         return myShapeIndexToSubMesh.find(Index)!=myShapeIndexToSubMesh.end();
791 }
792
793 //=======================================================================
794 //function : HasHypothesis
795 //purpose  : 
796 //=======================================================================
797 bool SMESHDS_Mesh::HasHypothesis(const TopoDS_Shape & S)
798 {
799         return myShapeToHypothesis.find(S)!=myShapeToHypothesis.end();
800 }
801
802 //=======================================================================
803 //function : NewSubMesh 
804 //purpose  : 
805 //=======================================================================
806 SMESHDS_SubMesh * SMESHDS_Mesh::NewSubMesh(int Index)
807 {
808   SMESHDS_SubMesh* SM = 0;
809   if (myShapeIndexToSubMesh.find(Index)==myShapeIndexToSubMesh.end())
810   {
811     SM = new SMESHDS_SubMesh();
812     myShapeIndexToSubMesh[Index]=SM;
813   }
814   else
815     SM = myShapeIndexToSubMesh[Index];
816   return SM;
817 }
818
819 //=======================================================================
820 //function : AddCompoundSubmesh
821 //purpose  : 
822 //=======================================================================
823
824 int SMESHDS_Mesh::AddCompoundSubmesh(const TopoDS_Shape& S,
825                                      TopAbs_ShapeEnum    type)
826 {
827   int aMainIndex = 0;
828   if ( IsGroupOfSubShapes( S ))
829   {
830     aMainIndex = myIndexToShape.Add( S );
831     bool all = ( type == TopAbs_SHAPE );
832     if ( all ) // corresponding simple submesh may exist
833       aMainIndex = -aMainIndex;
834     //MESSAGE("AddCompoundSubmesh index = " << aMainIndex );
835     SMESHDS_SubMesh * aNewSub = NewSubMesh( aMainIndex );
836     if ( !aNewSub->IsComplexSubmesh() ) // is empty
837     {
838       int shapeType = all ? myShape.ShapeType() : type;
839       int typeLimit = all ? TopAbs_VERTEX : type;
840       for ( ; shapeType <= typeLimit; shapeType++ )
841       {
842         TopExp_Explorer exp( S, TopAbs_ShapeEnum( shapeType ));
843         for ( ; exp.More(); exp.Next() )
844         {
845           int index = myIndexToShape.FindIndex( exp.Current() );
846           if ( index )
847             aNewSub->AddSubMesh( NewSubMesh( index ));
848         }
849       }
850     }
851   }
852   return aMainIndex;
853 }
854
855 //=======================================================================
856 //function : IndexToShape
857 //purpose  : 
858 //=======================================================================
859 TopoDS_Shape SMESHDS_Mesh::IndexToShape(int ShapeIndex)
860 {
861         return myIndexToShape.FindKey(ShapeIndex);
862 }
863
864 //=======================================================================
865 //function : ShapeToIndex
866 //purpose  : 
867 //=======================================================================
868 int SMESHDS_Mesh::ShapeToIndex(const TopoDS_Shape & S)
869 {
870   if (myShape.IsNull())
871     MESSAGE("myShape is NULL");
872
873   int index = myIndexToShape.FindIndex(S);
874   
875   return index;
876 }
877
878 //=======================================================================
879 //function : SetNodeOnVolume
880 //purpose  : 
881 //=======================================================================
882 void SMESHDS_Mesh::SetNodeInVolume(const SMDS_MeshNode* aNode, int Index)
883 {
884         //Set Position on Node
885         //Handle (SMDS_FacePosition) aPos = new SMDS_FacePosition (myFaceToId(S),0.,0.);;
886         //aNode->SetPosition(aPos);
887
888         //Update or build submesh
889         if (myShapeIndexToSubMesh.find(Index)==myShapeIndexToSubMesh.end())
890                 myShapeIndexToSubMesh[Index]=new SMESHDS_SubMesh();
891
892         myShapeIndexToSubMesh[Index]->AddNode(aNode);
893 }
894
895 //=======================================================================
896 //function : SetNodeOnFace
897 //purpose  : 
898 //=======================================================================
899 void SMESHDS_Mesh::SetNodeOnFace(SMDS_MeshNode* aNode, int Index)
900 {
901         //Set Position on Node
902         aNode->SetPosition(SMDS_PositionPtr(new SMDS_FacePosition(Index, 0., 0.)));
903
904         //Update or build submesh
905         if (myShapeIndexToSubMesh.find(Index)==myShapeIndexToSubMesh.end())
906                 myShapeIndexToSubMesh[Index]=new SMESHDS_SubMesh();
907
908         myShapeIndexToSubMesh[Index]->AddNode(aNode);
909 }
910
911 //=======================================================================
912 //function : SetNodeOnEdge
913 //purpose  : 
914 //=======================================================================
915 void SMESHDS_Mesh::SetNodeOnEdge(SMDS_MeshNode* aNode, int Index)
916 {
917         //Set Position on Node
918         aNode->SetPosition(SMDS_PositionPtr(new SMDS_EdgePosition(Index, 0.)));
919
920         //Update or build submesh
921         if (myShapeIndexToSubMesh.find(Index)==myShapeIndexToSubMesh.end())
922                 myShapeIndexToSubMesh[Index]=new SMESHDS_SubMesh();
923
924         myShapeIndexToSubMesh[Index]->AddNode(aNode);
925 }
926
927 //=======================================================================
928 //function : SetNodeOnVertex
929 //purpose  : 
930 //=======================================================================
931 void SMESHDS_Mesh::SetNodeOnVertex(SMDS_MeshNode* aNode, int Index)
932 {
933         //Set Position on Node
934         aNode->SetPosition(SMDS_PositionPtr(new SMDS_VertexPosition(Index)));
935
936         //Update or build submesh
937         if (myShapeIndexToSubMesh.find(Index)==myShapeIndexToSubMesh.end())
938                 myShapeIndexToSubMesh[Index]=new SMESHDS_SubMesh();
939
940         myShapeIndexToSubMesh[Index]->AddNode(aNode);
941 }
942
943 //=======================================================================
944 //function : SetMeshElementOnShape
945 //purpose  : 
946 //=======================================================================
947 void SMESHDS_Mesh::SetMeshElementOnShape(const SMDS_MeshElement* anElement,
948         int Index)
949 {
950         if (myShapeIndexToSubMesh.find(Index)==myShapeIndexToSubMesh.end())
951                 myShapeIndexToSubMesh[Index]=new SMESHDS_SubMesh();
952
953         myShapeIndexToSubMesh[Index]->AddElement(anElement);
954 }
955
956 SMESHDS_Mesh::~SMESHDS_Mesh()
957 {
958 }