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