Salome HOME
0020206: EDF SMESH 987: Netgen1D2D3D +submesh
[modules/smesh.git] / src / SMESHDS / SMESHDS_SubMesh.cxx
1 //  Copyright (C) 2007-2008  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 //  SMESH SMESHDS : management of mesh data and SMESH document
23 //  File   : SMESH_SubMesh.cxx
24 //  Author : Yves FRICAUD, OCC
25 //  Module : SMESH
26 //  $Header: 
27 //
28 #include "SMESHDS_SubMesh.hxx"
29
30 #include "utilities.h"
31 #include "SMDS_SetIterator.hxx"
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*>::const_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*>::const_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 TSet> class MySetIterator: public SMDS_SetIterator<typename TSet::key_type,
120                                                                      typename TSet::const_iterator >
121 {
122   typedef SMDS_SetIterator<typename TSet::key_type, typename TSet::const_iterator > TFather;
123   public:
124         MySetIterator(const TSet& s):TFather(s.begin(),s.end())
125         {
126         }
127 };
128
129 // =====================
130 // class MyIterator
131 // =====================
132
133 template<typename VALUE> class MyIterator : public SMDS_Iterator<VALUE>
134 {
135  public:
136   MyIterator (const set<const SMESHDS_SubMesh*>& theSubMeshes)
137     : mySubMeshes( theSubMeshes ), mySubIt( theSubMeshes.begin() ), myMore(false)
138     {}
139   bool more()
140   {
141     while (( !myElemIt.get() || !myElemIt->more() ) &&
142            mySubIt != mySubMeshes.end())
143     {
144       myElemIt = getElements(*mySubIt);
145       mySubIt++;
146     }
147     myMore = myElemIt.get() && myElemIt->more();
148     return myMore;
149   }
150   VALUE next()
151   {
152     VALUE elem = 0;
153     if ( myMore )
154       elem = myElemIt->next();
155     return elem;
156   }
157  protected:
158   virtual boost::shared_ptr< SMDS_Iterator<VALUE> >
159     getElements(const SMESHDS_SubMesh*) const = 0;
160
161  private:
162   bool                                        myMore;
163   const set<const SMESHDS_SubMesh*>&          mySubMeshes;
164   set<const SMESHDS_SubMesh*>::const_iterator mySubIt;
165   boost::shared_ptr< SMDS_Iterator<VALUE> >   myElemIt;
166 };
167
168 // =====================
169 // class MyElemIterator
170 // =====================
171
172 class MyElemIterator: public MyIterator<const SMDS_MeshElement*>
173 {
174  public:
175   MyElemIterator (const set<const SMESHDS_SubMesh*>& theSubMeshes)
176     :MyIterator<const SMDS_MeshElement*>( theSubMeshes ) {}
177   SMDS_ElemIteratorPtr getElements(const SMESHDS_SubMesh* theSubMesh) const
178   { return theSubMesh->GetElements(); }
179 };
180
181 // =====================
182 // class MyNodeIterator
183 // =====================
184
185 class MyNodeIterator: public MyIterator<const SMDS_MeshNode*>
186 {
187  public:
188   MyNodeIterator (const set<const SMESHDS_SubMesh*>& theSubMeshes)
189     :MyIterator<const SMDS_MeshNode*>( theSubMeshes ) {}
190   SMDS_NodeIteratorPtr getElements(const SMESHDS_SubMesh* theSubMesh) const
191   { return theSubMesh->GetNodes(); }
192 };
193   
194 //=======================================================================
195 //function : GetElements
196 //purpose  : 
197 //=======================================================================
198
199 SMDS_ElemIteratorPtr SMESHDS_SubMesh::GetElements() const
200 {
201   if ( IsComplexSubmesh() )
202     return SMDS_ElemIteratorPtr( new MyElemIterator( mySubMeshes ));
203
204   return SMDS_ElemIteratorPtr(new MySetIterator<TElemSet>(myElements));
205 }
206
207 //=======================================================================
208 //function : GetNodes
209 //purpose  : 
210 //=======================================================================
211
212 SMDS_NodeIteratorPtr SMESHDS_SubMesh::GetNodes() const
213 {
214   if ( IsComplexSubmesh() )
215     return SMDS_NodeIteratorPtr( new MyNodeIterator( mySubMeshes ));
216
217   return SMDS_NodeIteratorPtr(new MySetIterator<TNodeSet>(myNodes));
218 }
219
220 //=======================================================================
221 //function : Contains
222 //purpose  : check if elem or node is in
223 //=======================================================================
224
225 bool SMESHDS_SubMesh::Contains(const SMDS_MeshElement * ME) const
226 {
227   // DO NOT TRY TO FIND A REMOVED ELEMENT !!
228   if ( !ME )
229     return false;
230
231   if ( IsComplexSubmesh() )
232   {
233     set<const SMESHDS_SubMesh*>::const_iterator aSubIt = mySubMeshes.begin();
234     for ( ; aSubIt != mySubMeshes.end(); aSubIt++ )
235       if ( (*aSubIt)->Contains( ME ))
236         return true;
237     return false;
238   }
239
240   if ( ME->GetType() == SMDSAbs_Node )
241   {
242     const SMDS_MeshNode* n = static_cast<const SMDS_MeshNode*>( ME );
243     return ( myNodes.find( n ) != myNodes.end() );
244   }
245
246   return ( myElements.find( ME ) != myElements.end() );
247 }
248
249 //=======================================================================
250 //function : AddSubMesh
251 //purpose  : 
252 //=======================================================================
253
254 void SMESHDS_SubMesh::AddSubMesh( const SMESHDS_SubMesh* theSubMesh )
255 {
256   ASSERT( theSubMesh );
257   mySubMeshes.insert( theSubMesh );
258 }
259
260 //=======================================================================
261 //function : RemoveSubMesh
262 //purpose  : 
263 //=======================================================================
264
265 bool SMESHDS_SubMesh::RemoveSubMesh( const SMESHDS_SubMesh* theSubMesh )
266 {
267   return mySubMeshes.erase( theSubMesh );
268 }
269
270 //=======================================================================
271 //function : ContainsSubMesh
272 //purpose  : 
273 //=======================================================================
274
275 bool SMESHDS_SubMesh::ContainsSubMesh( const SMESHDS_SubMesh* theSubMesh ) const
276 {
277   return mySubMeshes.find( theSubMesh ) != mySubMeshes.end();
278 }
279
280 //=======================================================================
281 //function : GetSubMeshIterator
282 //purpose  : 
283 //=======================================================================
284
285 SMESHDS_SubMeshIteratorPtr SMESHDS_SubMesh::GetSubMeshIterator() const
286 {
287   typedef set<const SMESHDS_SubMesh*>::const_iterator TIterator;
288   return SMESHDS_SubMeshIteratorPtr
289     ( new SMDS_SetIterator< const SMESHDS_SubMesh*, TIterator >( mySubMeshes.begin(),
290                                                                  mySubMeshes.end()));
291 }
292
293 //=======================================================================
294 //function : Clear
295 //purpose  : remove the contents
296 //=======================================================================
297
298 void SMESHDS_SubMesh::Clear()
299 {
300   myElements.clear();
301   myNodes.clear();
302   SMESHDS_SubMeshIteratorPtr sub = GetSubMeshIterator();
303   while ( sub->more() ) {
304     if ( SMESHDS_SubMesh* sm = (SMESHDS_SubMesh*) sub->next())
305       sm->Clear();
306   }
307 }