Back to index

salome-smesh  6.5.0
SMESH_ProxyMesh.cxx
Go to the documentation of this file.
00001 // Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
00002 //
00003 // This library is free software; you can redistribute it and/or
00004 // modify it under the terms of the GNU Lesser General Public
00005 // License as published by the Free Software Foundation; either
00006 // version 2.1 of the License.
00007 //
00008 // This library is distributed in the hope that it will be useful,
00009 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00010 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00011 // Lesser General Public License for more details.
00012 //
00013 // You should have received a copy of the GNU Lesser General Public
00014 // License along with this library; if not, write to the Free Software
00015 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
00016 //
00017 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
00018 //
00019 // File      : SMESH_ProxyMesh.cxx
00020 // Created   : Thu Dec  2 12:32:53 2010
00021 // Author    : Edward AGAPOV (eap)
00022 
00023 #include "SMESH_ProxyMesh.hxx"
00024 
00025 #include "SMDS_IteratorOnIterators.hxx"
00026 #include "SMDS_SetIterator.hxx"
00027 #include "SMESH_MesherHelper.hxx"
00028 
00029 #include <TopTools_ListIteratorOfListOfShape.hxx>
00030 #include <TopExp.hxx>
00031 #include <TopTools_IndexedMapOfShape.hxx>
00032 
00033 //================================================================================
00037 //================================================================================
00038 
00039 SMESH_ProxyMesh::SMESH_ProxyMesh():_mesh(0)
00040 {
00041 }
00042 //================================================================================
00046 //================================================================================
00047 
00048 SMESH_ProxyMesh::SMESH_ProxyMesh(vector<SMESH_ProxyMesh::Ptr>& components):
00049   _mesh(0)
00050 {
00051   if ( components.empty() ) return;
00052 
00053   for ( unsigned i = 0; i < components.size(); ++i )
00054   {
00055     SMESH_ProxyMesh* m = components[i].get();
00056     if ( !m ) continue;
00057 
00058     takeTmpElemsInMesh( m );
00059 
00060     if ( !_mesh ) _mesh = m->_mesh;
00061     if ( _allowedTypes.empty() ) _allowedTypes = m->_allowedTypes;
00062 
00063     if ( _subMeshes.size() < m->_subMeshes.size() )
00064       _subMeshes.resize( m->_subMeshes.size(), 0 );
00065     for ( unsigned j = 0; j < m->_subMeshes.size(); ++j )
00066     {
00067       if ( !m->_subMeshes[j] ) continue;
00068       if ( _subMeshes[j] )
00069       {
00070         // unite 2 sub-meshes
00071         set< const SMDS_MeshElement * > elems( _subMeshes[j]->_elements.begin(),
00072                                                _subMeshes[j]->_elements.end());
00073         elems.insert( m->_subMeshes[j]->_elements.begin(),
00074                       m->_subMeshes[j]->_elements.end());
00075         _subMeshes[j]->_elements.assign( elems.begin(), elems.end() );
00076         m->_subMeshes[j]->_elements.clear();
00077 
00078         if ( !_subMeshes[j]->_n2n )
00079           _subMeshes[j]->_n2n = m->_subMeshes[j]->_n2n, m->_subMeshes[j]->_n2n = 0;
00080 
00081         else if ( _subMeshes[j]->_n2n && m->_subMeshes[j]->_n2n )
00082           _subMeshes[j]->_n2n->insert( m->_subMeshes[j]->_n2n->begin(),
00083                                        m->_subMeshes[j]->_n2n->end());
00084       }
00085       else
00086       {
00087         _subMeshes[j] = m->_subMeshes[j];
00088         m->_subMeshes[j] = 0;
00089       }
00090     }
00091   }
00092 }
00093 
00094 //================================================================================
00098 //================================================================================
00099 
00100 SMESH_ProxyMesh::~SMESH_ProxyMesh()
00101 {
00102   for ( unsigned i = 0; i < _subMeshes.size(); ++i )
00103     delete _subMeshes[i];
00104   _subMeshes.clear();
00105 
00106   set< const SMDS_MeshElement* >::iterator i = _elemsInMesh.begin();
00107   for ( ; i != _elemsInMesh.end(); ++i )
00108     GetMeshDS()->RemoveFreeElement( *i, 0 );
00109   _elemsInMesh.clear();
00110 }
00111 
00112 //================================================================================
00116 //================================================================================
00117 
00118 int SMESH_ProxyMesh::shapeIndex(const TopoDS_Shape& shape) const
00119 {
00120   return ( shape.IsNull() || !_mesh->HasShapeToMesh() ? 0 : GetMeshDS()->ShapeToIndex(shape));
00121 }
00122 
00123 //================================================================================
00127 //================================================================================
00128 
00129 const SMESHDS_SubMesh* SMESH_ProxyMesh::GetSubMesh(const TopoDS_Shape& shape) const
00130 {
00131   const SMESHDS_SubMesh* sm = 0;
00132 
00133   int i = shapeIndex(shape);
00134   if ( i < _subMeshes.size() )
00135     sm = _subMeshes[i];
00136   if ( !sm )
00137     sm = GetMeshDS()->MeshElements( i );
00138 
00139   return sm;
00140 }
00141 
00142 //================================================================================
00146 //================================================================================
00147 
00148 const SMESH_ProxyMesh::SubMesh*
00149 SMESH_ProxyMesh::GetProxySubMesh(const TopoDS_Shape& shape) const
00150 {
00151   int i = shapeIndex(shape);
00152   return i < _subMeshes.size() ? _subMeshes[i] : 0;
00153 }
00154 
00155 //================================================================================
00159 //================================================================================
00160 
00161 const SMDS_MeshNode* SMESH_ProxyMesh::GetProxyNode( const SMDS_MeshNode* node ) const
00162 {
00163   const SMDS_MeshNode* proxy = node;
00164   if ( node->GetPosition()->GetTypeOfPosition() == SMDS_TOP_FACE )
00165   {
00166     if ( const SubMesh* proxySM = findProxySubMesh( node->getshapeId() ))
00167       proxy = proxySM->GetProxyNode( node );
00168   }
00169   else
00170   {
00171     TopoDS_Shape shape = SMESH_MesherHelper::GetSubShapeByNode( node, GetMeshDS());
00172     TopTools_ListIteratorOfListOfShape ancIt;
00173     if ( !shape.IsNull() ) ancIt.Initialize( _mesh->GetAncestors( shape ));
00174     for ( ; ancIt.More() && proxy == node; ancIt.Next() )
00175       if ( const SubMesh* proxySM = findProxySubMesh( shapeIndex(ancIt.Value())))
00176         proxy = proxySM->GetProxyNode( node );
00177   }
00178   return proxy;
00179 }
00180 
00181 namespace
00182 {
00183   //================================================================================
00187   //================================================================================
00188 
00189   class TFilteringIterator : public SMDS_ElemIterator
00190   {
00191     SMDS_ElemIteratorPtr        _iter;
00192     const SMDS_MeshElement *    _curElem;
00193     vector< SMDSAbs_EntityType> _okTypes;
00194   public:
00195     TFilteringIterator( const vector< SMDSAbs_EntityType>& okTypes,
00196                         const SMDS_ElemIteratorPtr&        elemIterator)
00197       :_iter(elemIterator), _curElem(0), _okTypes(okTypes)
00198     {
00199       next();
00200     }
00201     virtual bool more()
00202     {
00203       return _curElem;
00204     }
00205     virtual const SMDS_MeshElement* next()
00206     {
00207       const SMDS_MeshElement* res = _curElem;
00208       _curElem = 0;
00209       while ( _iter->more() && !_curElem )
00210       {
00211         _curElem = _iter->next();
00212         if ( find( _okTypes.begin(), _okTypes.end(), _curElem->GetEntityType()) == _okTypes.end())
00213           _curElem = 0;
00214       }
00215       return res;
00216     }
00217   };
00218 }
00219 
00220 //================================================================================
00224 //================================================================================
00225 
00226 SMDS_ElemIteratorPtr SMESH_ProxyMesh::GetFaces(const TopoDS_Shape& shape) const
00227 {
00228   if ( !_mesh->HasShapeToMesh() )
00229     return SMDS_ElemIteratorPtr();
00230 
00231   _subContainer.RemoveAllSubmeshes();
00232 
00233   TopTools_IndexedMapOfShape FF;
00234   TopExp::MapShapes( shape, TopAbs_FACE, FF );
00235   for ( int i = 1; i <= FF.Extent(); ++i )
00236     if ( const SMESHDS_SubMesh* sm = GetSubMesh( FF(i)))
00237       _subContainer.AddSubMesh( sm );
00238 
00239   return _subContainer.SMESHDS_SubMesh::GetElements();
00240 }
00241 
00242 //================================================================================
00247 //================================================================================
00248 
00249 SMDS_ElemIteratorPtr SMESH_ProxyMesh::GetFaces() const
00250 {
00251   if ( _mesh->HasShapeToMesh() )
00252     return SMDS_ElemIteratorPtr();
00253 
00254   _subContainer.RemoveAllSubmeshes();
00255   for ( unsigned i = 0; i < _subMeshes.size(); ++i )
00256     if ( _subMeshes[i] )
00257       _subContainer.AddSubMesh( _subMeshes[i] );
00258 
00259   if ( _subContainer.NbSubMeshes() == 0 ) // no elements substituted
00260     return GetMeshDS()->elementsIterator(SMDSAbs_Face);
00261 
00262   // if _allowedTypes is empty, only elements from _subMeshes are returned,...
00263   SMDS_ElemIteratorPtr proxyIter = _subContainer.SMESHDS_SubMesh::GetElements();
00264   if ( _allowedTypes.empty() || NbFaces() == _mesh->NbFaces() )
00265     return proxyIter;
00266 
00267   // ... else elements filtered using allowedTypes are additionally returned
00268   SMDS_ElemIteratorPtr facesIter = GetMeshDS()->elementsIterator(SMDSAbs_Face);
00269   SMDS_ElemIteratorPtr filterIter( new TFilteringIterator( _allowedTypes, facesIter ));
00270   vector< SMDS_ElemIteratorPtr > iters(2);
00271   iters[0] = proxyIter;
00272   iters[1] = filterIter;
00273     
00274   typedef vector< SMDS_ElemIteratorPtr > TElemIterVector;
00275   typedef SMDS_IteratorOnIterators<const SMDS_MeshElement *, TElemIterVector> TItersIter;
00276   return SMDS_ElemIteratorPtr( new TItersIter( iters ));
00277 }
00278 
00279 //================================================================================
00283 //================================================================================
00284 
00285 int SMESH_ProxyMesh::NbFaces() const
00286 {
00287   int nb = 0;
00288   if ( _mesh->HasShapeToMesh() )
00289   {
00290     TopTools_IndexedMapOfShape FF;
00291     TopExp::MapShapes( _mesh->GetShapeToMesh(), TopAbs_FACE, FF );
00292     for ( int i = 1; i <= FF.Extent(); ++i )
00293       if ( const SMESHDS_SubMesh* sm = GetSubMesh( FF(i)))
00294         nb += sm->NbElements();
00295   }
00296   else
00297   {
00298     if ( _subMeshes.empty() )
00299       return GetMeshDS()->NbFaces();
00300 
00301     for ( unsigned i = 0; i < _subMeshes.size(); ++i )
00302       if ( _subMeshes[i] )
00303         nb += _subMeshes[i]->NbElements();
00304 
00305     // if _allowedTypes is empty, only elements from _subMeshes are returned,
00306     // else elements filtered using allowedTypes are additionally returned
00307     if ( !_allowedTypes.empty() )
00308     {
00309       for ( int t = SMDSEntity_Triangle; t <= SMDSEntity_Quad_Quadrangle; ++t )
00310       {
00311         bool allowed =
00312           ( find( _allowedTypes.begin(), _allowedTypes.end(), t ) != _allowedTypes.end() );
00313         if ( allowed )
00314           nb += GetMeshDS()->GetMeshInfo().NbEntities( SMDSAbs_EntityType( t ));
00315       }
00316     }
00317   }
00318   return nb;
00319 }
00320 
00321 //================================================================================
00325 //================================================================================
00326 
00327 SMESH_ProxyMesh::SubMesh* SMESH_ProxyMesh::getProxySubMesh(int index)
00328 {
00329   if ( int(_subMeshes.size()) <= index )
00330     _subMeshes.resize( index+1, 0 );
00331   if ( !_subMeshes[index] )
00332     _subMeshes[index] = new SubMesh( index );
00333   return _subMeshes[index];
00334 }
00335 
00336 //================================================================================
00340 //================================================================================
00341 
00342 SMESH_ProxyMesh::SubMesh* SMESH_ProxyMesh::getProxySubMesh(const TopoDS_Shape& shape)
00343 {
00344   return getProxySubMesh( shapeIndex( shape ));
00345 }
00346 
00347 //================================================================================
00351 //================================================================================
00352 
00353 SMESH_ProxyMesh::SubMesh* SMESH_ProxyMesh::findProxySubMesh(int shapeIndex) const
00354 {
00355   return shapeIndex < int(_subMeshes.size()) ? _subMeshes[shapeIndex] : 0;
00356 }
00357 
00358 //================================================================================
00362 //================================================================================
00363 
00364 SMESHDS_Mesh* SMESH_ProxyMesh::GetMeshDS() const
00365 {
00366   return (SMESHDS_Mesh*)( _mesh ? _mesh->GetMeshDS() : 0 );
00367 }
00368 
00369 //================================================================================
00373 //================================================================================
00374 
00375 bool SMESH_ProxyMesh::takeProxySubMesh( const TopoDS_Shape&   shape,
00376                                              SMESH_ProxyMesh* proxyMesh )
00377 {
00378   if ( proxyMesh && proxyMesh->_mesh == _mesh )
00379   {
00380     int iS = shapeIndex( shape );
00381     if ( SubMesh* sm = proxyMesh->findProxySubMesh( iS ))
00382     {
00383       if ( iS >= int(_subMeshes.size()) )
00384         _subMeshes.resize( iS + 1, 0 );
00385       _subMeshes[iS] = sm;
00386       proxyMesh->_subMeshes[iS] = 0;
00387       return true;
00388     }
00389   }
00390   return false;
00391 }
00392 
00393 //================================================================================
00397 //================================================================================
00398 
00399 void SMESH_ProxyMesh::takeTmpElemsInMesh( SMESH_ProxyMesh* proxyMesh )
00400 {
00401   if ( proxyMesh )
00402   {
00403     _elemsInMesh.insert( proxyMesh->_elemsInMesh.begin(),
00404                          proxyMesh->_elemsInMesh.end());
00405     proxyMesh->_elemsInMesh.clear();
00406   }
00407 }
00408 
00409 //================================================================================
00413 //================================================================================
00414 
00415 void SMESH_ProxyMesh::removeTmpElement( const SMDS_MeshElement* face )
00416 {
00417   if ( face && face->GetID() > 0 )
00418   {
00419     set< const SMDS_MeshElement* >::iterator i =  _elemsInMesh.find( face );
00420     if ( i != _elemsInMesh.end() )
00421     {
00422       GetMeshDS()->RemoveFreeElement( face, 0 );
00423       _elemsInMesh.erase( i );
00424     }
00425   }
00426   else
00427   {
00428     delete face;
00429   }
00430 }
00431 
00432 //================================================================================
00436 //================================================================================
00437 
00438 void SMESH_ProxyMesh::storeTmpElement( const SMDS_MeshElement* face )
00439 {
00440   _elemsInMesh.insert( face );
00441 }
00442 
00443 //================================================================================
00447 //================================================================================
00448 
00449 void SMESH_ProxyMesh::setNode2Node(const SMDS_MeshNode* srcNode,
00450                                    const SMDS_MeshNode* proxyNode,
00451                                    const SubMesh*       subMesh)
00452 {
00453   SubMesh* sm = const_cast<SubMesh*>( subMesh );
00454   if ( !subMesh->_n2n )
00455     sm->_n2n = new TN2NMap;
00456   sm->_n2n->insert( make_pair( srcNode, proxyNode ));
00457 }
00458 
00459 //================================================================================
00463 //================================================================================
00464 
00465 bool SMESH_ProxyMesh::IsTemporary(const SMDS_MeshElement* elem ) const
00466 {
00467   return ( elem->GetID() < 1 ) || _elemsInMesh.count( elem );
00468 }
00469 
00470 //================================================================================
00474 //================================================================================
00475 
00476 const SMDS_MeshNode* SMESH_ProxyMesh::SubMesh::GetProxyNode( const SMDS_MeshNode* n ) const
00477 {
00478   TN2NMap::iterator n2n;
00479   if ( _n2n && ( n2n = _n2n->find( n )) != _n2n->end())
00480     return n2n->second;
00481   return n;
00482 }
00483 
00484 //================================================================================
00488 //================================================================================
00489 
00490 void SMESH_ProxyMesh::SubMesh::Clear()
00491 {
00492   for ( unsigned i = 0; i < _elements.size(); ++i )
00493     if ( _elements[i]->GetID() < 0 )
00494       delete _elements[i];
00495   _elements.clear();
00496   if ( _n2n )
00497     delete _n2n, _n2n = 0;
00498 }
00499 
00500 //================================================================================
00504 //================================================================================
00505 
00506 int SMESH_ProxyMesh::SubMesh::NbElements() const
00507 {
00508   return _elements.size();
00509 }
00510 
00511 //================================================================================
00515 //================================================================================
00516 
00517 SMDS_ElemIteratorPtr SMESH_ProxyMesh::SubMesh::GetElements() const
00518 {
00519   return SMDS_ElemIteratorPtr
00520     ( new SMDS_ElementVectorIterator( _elements.begin(), _elements.end() ));
00521 }
00522 
00523 //================================================================================
00527 //================================================================================
00528 
00529 void SMESH_ProxyMesh::SubMesh::AddElement(const SMDS_MeshElement * e)
00530 {
00531   _elements.push_back( e );
00532 }
00533 
00534 //================================================================================
00538 //================================================================================
00539 
00540 bool SMESH_ProxyMesh::SubMesh::Contains(const SMDS_MeshElement * ME) const
00541 {
00542   if ( ME->GetType() != SMDSAbs_Node )
00543     return find( _elements.begin(), _elements.end(), ME ) != _elements.end();
00544   return false;
00545 }