Salome HOME
Merge with OCC_development_01
[modules/smesh.git] / src / SMESHDS / SMESHDS_SubMesh.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_SubMesh.cxx
25 //  Author : Yves FRICAUD, OCC
26 //  Module : SMESH
27 //  $Header: 
28
29 #include "SMESHDS_SubMesh.hxx"
30
31 #include "utilities.h"
32
33 using namespace std;
34
35 //=======================================================================
36 //function : AddElement
37 //purpose  : 
38 //=======================================================================
39 void SMESHDS_SubMesh::AddElement(const SMDS_MeshElement * ME)
40 {
41   if ( !IsComplexSubmesh() )
42     myElements.insert(ME);
43 }
44
45 //=======================================================================
46 //function : RemoveElement
47 //purpose  : 
48 //=======================================================================
49 bool SMESHDS_SubMesh::RemoveElement(const SMDS_MeshElement * ME)
50 {
51   if ( !IsComplexSubmesh() && NbElements() )
52     return myElements.erase(ME);
53   
54   return false;
55 }
56
57 //=======================================================================
58 //function : AddNode
59 //purpose  : 
60 //=======================================================================
61 void SMESHDS_SubMesh::AddNode(const SMDS_MeshNode * N)
62 {
63   if ( !IsComplexSubmesh() )
64     myNodes.insert(N);
65 }
66
67 //=======================================================================
68 //function : RemoveNode
69 //purpose  : 
70 //=======================================================================
71
72 bool SMESHDS_SubMesh::RemoveNode(const SMDS_MeshNode * N)
73 {
74   if ( !IsComplexSubmesh() && NbNodes() )
75     return myNodes.erase(N);
76
77   return false;
78 }
79
80 //=======================================================================
81 //function : NbElements
82 //purpose  : 
83 //=======================================================================
84 int SMESHDS_SubMesh::NbElements() const
85 {
86   if ( !IsComplexSubmesh() )
87     return myElements.size();
88
89   int nbElems = 0;
90   set<const SMESHDS_SubMesh*>::iterator it = mySubMeshes.begin();
91   for ( ; it != mySubMeshes.end(); it++ )
92     nbElems += (*it)->NbElements();
93
94   return nbElems;
95 }
96
97 //=======================================================================
98 //function : NbNodes
99 //purpose  : 
100 //=======================================================================
101
102 int SMESHDS_SubMesh::NbNodes() const
103 {
104  if ( !IsComplexSubmesh() )
105    return myNodes.size(); 
106
107   int nbElems = 0;
108   set<const SMESHDS_SubMesh*>::iterator it = mySubMeshes.begin();
109   for ( ; it != mySubMeshes.end(); it++ )
110     nbElems += (*it)->NbNodes();
111
112   return nbElems;
113 }
114
115 // =====================
116 // class MySetIterator
117 // =====================
118
119 template<typename T> class MySetIterator:public SMDS_Iterator<const T*>
120 {
121   typedef const set<const T*> TSet;
122   typename TSet::const_iterator myIt;
123   TSet& mySet;
124
125   public:
126         MySetIterator(const set<const T*>& s):mySet(s), myIt(s.begin())
127         {
128         }
129
130         bool more()
131         {
132                 return myIt!=mySet.end();
133         }
134         const T* next()
135         {
136                 const T* t=*myIt;
137                 myIt++;
138                 return t;                       
139         }
140 };
141
142 // =====================
143 // class MyIterator
144 // =====================
145
146 template<typename VALUE> class MyIterator : public SMDS_Iterator<VALUE>
147 {
148  public:
149   MyIterator (const set<const SMESHDS_SubMesh*>& theSubMeshes)
150     : mySubMeshes( theSubMeshes ), mySubIt( theSubMeshes.begin() ), myMore(false)
151     {}
152   bool more()
153   {
154     while (( !myElemIt.get() || !myElemIt->more() ) &&
155            mySubIt != mySubMeshes.end())
156     {
157       myElemIt = getElements(*mySubIt);
158       mySubIt++;
159     }
160     myMore = myElemIt.get() && myElemIt->more();
161     return myMore;
162   }
163   VALUE next()
164   {
165     VALUE elem = 0;
166     if ( myMore )
167       elem = myElemIt->next();
168     return elem;
169   }
170  protected:
171   virtual boost::shared_ptr< SMDS_Iterator<VALUE> >
172     getElements(const SMESHDS_SubMesh*) const = 0;
173
174  private:
175   bool                                        myMore;
176   const set<const SMESHDS_SubMesh*>&          mySubMeshes;
177   set<const SMESHDS_SubMesh*>::const_iterator mySubIt;
178   boost::shared_ptr< SMDS_Iterator<VALUE> >   myElemIt;
179 };
180
181 // =====================
182 // class MyElemIterator
183 // =====================
184
185 class MyElemIterator: public MyIterator<const SMDS_MeshElement*>
186 {
187  public:
188   MyElemIterator (const set<const SMESHDS_SubMesh*>& theSubMeshes)
189     :MyIterator<const SMDS_MeshElement*>( theSubMeshes ) {}
190   SMDS_ElemIteratorPtr getElements(const SMESHDS_SubMesh* theSubMesh) const
191   { return theSubMesh->GetElements(); }
192 };
193
194 // =====================
195 // class MyNodeIterator
196 // =====================
197
198 class MyNodeIterator: public MyIterator<const SMDS_MeshNode*>
199 {
200  public:
201   MyNodeIterator (const set<const SMESHDS_SubMesh*>& theSubMeshes)
202     :MyIterator<const SMDS_MeshNode*>( theSubMeshes ) {}
203   SMDS_NodeIteratorPtr getElements(const SMESHDS_SubMesh* theSubMesh) const
204   { return theSubMesh->GetNodes(); }
205 };
206   
207 //=======================================================================
208 //function : GetElements
209 //purpose  : 
210 //=======================================================================
211
212 SMDS_ElemIteratorPtr SMESHDS_SubMesh::GetElements() const
213 {
214   if ( IsComplexSubmesh() )
215     return SMDS_ElemIteratorPtr( new MyElemIterator( mySubMeshes ));
216
217   return SMDS_ElemIteratorPtr(new MySetIterator<SMDS_MeshElement>(myElements));
218 }
219
220 //=======================================================================
221 //function : GetNodes
222 //purpose  : 
223 //=======================================================================
224
225 SMDS_NodeIteratorPtr SMESHDS_SubMesh::GetNodes() const
226 {
227   if ( IsComplexSubmesh() )
228     return SMDS_NodeIteratorPtr( new MyNodeIterator( mySubMeshes ));
229
230   return SMDS_NodeIteratorPtr(new MySetIterator<SMDS_MeshNode>(myNodes));
231 }
232
233 //=======================================================================
234 //function : Contains
235 //purpose  : check if elem or node is in
236 //=======================================================================
237
238 bool SMESHDS_SubMesh::Contains(const SMDS_MeshElement * ME) const
239 {
240   // DO NOT TRY TO FIND A REMOVED ELEMENT !!
241   if ( !ME )
242     return false;
243
244   if ( IsComplexSubmesh() )
245   {
246     set<const SMESHDS_SubMesh*>::const_iterator aSubIt = mySubMeshes.begin();
247     for ( ; aSubIt != mySubMeshes.end(); aSubIt++ )
248       if ( (*aSubIt)->Contains( ME ))
249         return true;
250     return false;
251   }
252
253   if ( ME->GetType() == SMDSAbs_Node )
254   {
255     const SMDS_MeshNode* n = static_cast<const SMDS_MeshNode*>( ME );
256     return ( myNodes.find( n ) != myNodes.end() );
257   }
258
259   return ( myElements.find( ME ) != myElements.end() );
260 }
261
262 //=======================================================================
263 //function : AddSubMesh
264 //purpose  : 
265 //=======================================================================
266
267 void SMESHDS_SubMesh::AddSubMesh( const SMESHDS_SubMesh* theSubMesh )
268 {
269   ASSERT( theSubMesh );
270   mySubMeshes.insert( theSubMesh );
271 }
272
273 //=======================================================================
274 //function : RemoveSubMesh
275 //purpose  : 
276 //=======================================================================
277
278 bool SMESHDS_SubMesh::RemoveSubMesh( const SMESHDS_SubMesh* theSubMesh )
279 {
280   return mySubMeshes.erase( theSubMesh );
281 }
282
283 //=======================================================================
284 //function : ContainsSubMesh
285 //purpose  : 
286 //=======================================================================
287
288 bool SMESHDS_SubMesh::ContainsSubMesh( const SMESHDS_SubMesh* theSubMesh ) const
289 {
290   return mySubMeshes.find( theSubMesh ) != mySubMeshes.end();
291 }