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