1 // Copyright (C) 2007-2016 CEA/DEN, EDF R&D, OPEN CASCADE
3 // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
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, or (at your option) any later version.
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.
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
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
23 // SMESH SMESHDS : management of mesh data and SMESH document
24 // File : SMESH_SubMesh.cxx
25 // Author : Yves FRICAUD, OCC
29 #include "SMESHDS_SubMesh.hxx"
31 #include "SMESHDS_Mesh.hxx"
32 #include "SMDS_SetIterator.hxx"
33 #include "SMDS_ElementFactory.hxx"
35 #include <utilities.h>
37 //================================================================================
41 //================================================================================
43 SMESHDS_SubMesh::SMESHDS_SubMesh(SMESHDS_Mesh *parent, int index)
51 //================================================================================
55 //================================================================================
57 SMESHDS_SubMesh::~SMESHDS_SubMesh()
61 //=======================================================================
62 //function : AddElement
64 //=======================================================================
66 void SMESHDS_SubMesh::AddElement(const SMDS_MeshElement * elem)
68 if (!IsComplexSubmesh())
70 if ( elem->GetType() == SMDSAbs_Node )
72 AddNode( static_cast< const SMDS_MeshNode* >( elem ));
75 int oldShapeId = elem->GetShapeID();
78 if (oldShapeId != myIndex)
80 throw SALOME_Exception
81 (LOCALIZED("add element in subshape already belonging to a subshape"));
85 elem->setShapeID( myIndex );
90 //=======================================================================
91 //function : RemoveElement
93 //=======================================================================
95 bool SMESHDS_SubMesh::RemoveElement(const SMDS_MeshElement * elem )
97 if ( !elem || elem->IsNull() || elem->getshapeId() != myIndex )
101 if ( !IsComplexSubmesh() )
103 elem->setShapeID( 0 );
110 //=======================================================================
113 //=======================================================================
115 void SMESHDS_SubMesh::AddNode(const SMDS_MeshNode * N)
117 if ( !IsComplexSubmesh() )
119 const int shapeId = N->getshapeId();
122 if ( shapeId != myIndex )
123 throw SALOME_Exception
124 (LOCALIZED("a node being in sub-mesh is added to another sub-mesh"));
125 return; // already in
127 N->setShapeID( myIndex );
132 //=======================================================================
133 //function : RemoveNode
135 //=======================================================================
137 bool SMESHDS_SubMesh::RemoveNode(const SMDS_MeshNode * N)
139 if ( !N || N->getshapeId() != myIndex )
143 if ( !IsComplexSubmesh() )
152 //=======================================================================
153 //function : NbElements
155 //=======================================================================
157 int SMESHDS_SubMesh::NbElements() const
159 if ( !IsComplexSubmesh() )
163 TSubMeshSet::const_iterator it = mySubMeshes.begin();
164 for ( ; it != mySubMeshes.end(); it++ )
165 nbElems += (*it)->NbElements();
170 //=======================================================================
173 //=======================================================================
175 int SMESHDS_SubMesh::NbNodes() const
177 if ( !IsComplexSubmesh() )
181 TSubMeshSet::const_iterator it = mySubMeshes.begin();
182 for ( ; it != mySubMeshes.end(); it++ )
183 nbElems += (*it)->NbNodes();
189 * Template class used for iteration on vector of elements which can resize
190 * during iteration. The iterator returns only elements present upon its creation.
192 template <class ELEM, typename TSET> class MySetIterator : public SMDS_Iterator<ELEM>
195 int _iCur, _iEnd, _iDelta;
198 MySetIterator(const TSET& table, bool reverse): _table( table )
202 _iCur = _table.size()-1;
209 _iEnd = _table.size();
212 if ( more() && !_table[ _iCur ])
218 return ( _iEnd - _iCur ) * _iDelta > 0;
223 ELEM e = more() ? _table[ _iCur ] : 0;
225 while ( more() && !_table[ _iCur ])
231 // =====================
233 // =====================
235 template<typename VALUE> class MyIterator : public SMDS_Iterator<VALUE>
238 MyIterator (const TSubMeshSet& theSubMeshes)
239 : myMore(false), mySubIt( theSubMeshes.begin() ), mySubEnd( theSubMeshes.end() )
243 while (( !myElemIt.get() || !myElemIt->more() ) && mySubIt != mySubEnd)
245 myElemIt = getElements(*mySubIt);
248 myMore = myElemIt.get() && myElemIt->more();
255 elem = myElemIt->next();
259 virtual boost::shared_ptr< SMDS_Iterator<VALUE> >
260 getElements(const SMESHDS_SubMesh*) const = 0;
264 TSubMeshSet::const_iterator mySubIt, mySubEnd;
265 boost::shared_ptr< SMDS_Iterator<VALUE> > myElemIt;
268 // =====================
269 // class MyElemIterator
270 // =====================
272 class MyElemIterator: public MyIterator<const SMDS_MeshElement*>
275 MyElemIterator (const TSubMeshSet& theSubMeshes)
276 :MyIterator<const SMDS_MeshElement*>( theSubMeshes ) {}
277 SMDS_ElemIteratorPtr getElements(const SMESHDS_SubMesh* theSubMesh) const
278 { return theSubMesh->GetElements(); }
281 // =====================
282 // class MyNodeIterator
283 // =====================
285 class MyNodeIterator: public MyIterator<const SMDS_MeshNode*>
288 MyNodeIterator (const TSubMeshSet& theSubMeshes)
289 :MyIterator<const SMDS_MeshNode*>( theSubMeshes ) {}
290 SMDS_NodeIteratorPtr getElements(const SMESHDS_SubMesh* theSubMesh) const
291 { return theSubMesh->GetNodes(); }
294 //=======================================================================
295 //function : GetElements
297 //=======================================================================
299 SMDS_ElemIteratorPtr SMESHDS_SubMesh::GetElements() const
301 if ( IsComplexSubmesh() )
302 return SMDS_ElemIteratorPtr( new MyElemIterator( mySubMeshes ));
304 return myParent->shapeElementsIterator( myIndex, myNbElements );
307 //=======================================================================
308 //function : GetNodes
310 //=======================================================================
312 SMDS_NodeIteratorPtr SMESHDS_SubMesh::GetNodes() const
314 if ( IsComplexSubmesh() )
315 return SMDS_NodeIteratorPtr( new MyNodeIterator( mySubMeshes ));
317 return myParent->shapeNodesIterator( myIndex, myNbNodes );
320 //=======================================================================
321 //function : Contains
322 //purpose : check if elem or node is in
323 //=======================================================================
325 bool SMESHDS_SubMesh::Contains(const SMDS_MeshElement * ME) const
327 if ( !ME || ME->IsNull() )
330 if ( IsComplexSubmesh() )
332 TSubMeshSet::const_iterator aSubIt = mySubMeshes.begin();
333 for (; aSubIt != mySubMeshes.end(); aSubIt++)
334 if ((*aSubIt)->Contains(ME))
338 return ME->getshapeId() == myIndex;
341 //=======================================================================
342 //function : IsQuadratic
343 //purpose : Return true if my 1st element is quadratic
344 //=======================================================================
346 bool SMESHDS_SubMesh::IsQuadratic() const
348 if ( IsComplexSubmesh() )
350 TSubMeshSet::const_iterator aSubIt = mySubMeshes.begin();
351 for (; aSubIt != mySubMeshes.end(); aSubIt++)
352 if ((*aSubIt)->IsQuadratic())
357 if ( myNbElements == 0 )
360 SMDS_ElemIteratorPtr it = GetElements();
361 return it->more() && it->next()->IsQuadratic();
364 //=======================================================================
365 //function : AddSubMesh
367 //=======================================================================
369 void SMESHDS_SubMesh::AddSubMesh( const SMESHDS_SubMesh* theSubMesh )
371 ASSERT( theSubMesh );
372 mySubMeshes.insert( theSubMesh );
375 //=======================================================================
376 //function : RemoveSubMesh
378 //=======================================================================
380 bool SMESHDS_SubMesh::RemoveSubMesh( const SMESHDS_SubMesh* theSubMesh )
382 return mySubMeshes.erase( theSubMesh );
385 //=======================================================================
386 //function : RemoveAllSubmeshes
388 //=======================================================================
390 void SMESHDS_SubMesh::RemoveAllSubmeshes()
395 //=======================================================================
396 //function : ContainsSubMesh
398 //=======================================================================
400 bool SMESHDS_SubMesh::ContainsSubMesh( const SMESHDS_SubMesh* theSubMesh ) const
402 return mySubMeshes.find( theSubMesh ) != mySubMeshes.end();
405 //=======================================================================
406 //function : GetSubMeshIterator
408 //=======================================================================
410 SMESHDS_SubMeshIteratorPtr SMESHDS_SubMesh::GetSubMeshIterator() const
412 typedef SMDS_SetIterator< const SMESHDS_SubMesh*, TSubMeshSet::const_iterator > TIterator;
413 return boost::make_shared< TIterator >( mySubMeshes.begin(), mySubMeshes.end());
416 //=======================================================================
418 //purpose : remove the contents
419 //=======================================================================
421 void SMESHDS_SubMesh::Clear()
423 if ( myParent && myParent->NbNodes() > 0 )
425 if ( myNbElements > 0 )
426 for ( SMDS_ElemIteratorPtr it = GetElements(); it->more(); )
428 const SMDS_MeshElement * elem = it->next();
429 elem->setShapeID( 0 );
432 for ( SMDS_NodeIteratorPtr it = GetNodes(); it->more(); )
434 const SMDS_MeshNode * elem = it->next();
435 elem->setShapeID( 0 );
441 if ( NbSubMeshes() > 0 )
443 SMESHDS_SubMeshIteratorPtr sub = GetSubMeshIterator();
444 while ( sub->more() ) {
445 if ( SMESHDS_SubMesh* sm = (SMESHDS_SubMesh*) sub->next())