mirror of
https://git.salome-platform.org/gitpub/modules/smesh.git
synced 2025-04-15 14:01:22 +05:00
424 lines
12 KiB
C++
424 lines
12 KiB
C++
// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE
|
|
//
|
|
// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
|
|
// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
|
|
//
|
|
// This library is free software; you can redistribute it and/or
|
|
// modify it under the terms of the GNU Lesser General Public
|
|
// License as published by the Free Software Foundation; either
|
|
// version 2.1 of the License.
|
|
//
|
|
// This library is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
// Lesser General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU Lesser General Public
|
|
// License along with this library; if not, write to the Free Software
|
|
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
//
|
|
// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
|
|
//
|
|
// SMESH SMESHDS : management of mesh data and SMESH document
|
|
// File : SMESH_SubMesh.cxx
|
|
// Author : Yves FRICAUD, OCC
|
|
// Module : SMESH
|
|
// $Header:
|
|
//
|
|
#include "SMESHDS_SubMesh.hxx"
|
|
|
|
#include "utilities.h"
|
|
#include "SMDS_SetIterator.hxx"
|
|
#include <iostream>
|
|
#include <cassert>
|
|
|
|
using namespace std;
|
|
|
|
SMESHDS_SubMesh::SMESHDS_SubMesh()
|
|
{
|
|
myElements.clear();
|
|
myNodes.clear();
|
|
myUnusedIdNodes = 0;
|
|
myUnusedIdElements = 0;
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : AddElement
|
|
//purpose :
|
|
//=======================================================================
|
|
void SMESHDS_SubMesh::AddElement(const SMDS_MeshElement * ME)
|
|
{
|
|
if ( !IsComplexSubmesh() )
|
|
{
|
|
int idInSubShape = ME->getIdInShape();
|
|
assert(idInSubShape == -1);
|
|
SMDS_MeshElement* elem = (SMDS_MeshElement*)(ME);
|
|
elem->setIdInShape(myElements.size());
|
|
myElements.push_back(ME);
|
|
}
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : RemoveElement
|
|
//purpose :
|
|
//=======================================================================
|
|
bool SMESHDS_SubMesh::RemoveElement(const SMDS_MeshElement * ME, bool isElemDeleted)
|
|
{
|
|
// MESSAGE("--------------------------------------> RemoveElement " << isElemDeleted);
|
|
// if ( !IsComplexSubmesh() && NbElements() ) {
|
|
|
|
if (!isElemDeleted) // alive element has valid ID and can be found
|
|
{
|
|
int idInSubShape = ME->getIdInShape();
|
|
//MESSAGE("SMESHDS_SubMesh::RemoveElement " << idInSubShape << " " << ME->GetID());
|
|
assert(idInSubShape >= 0);
|
|
assert(idInSubShape < myElements.size());
|
|
myElements[idInSubShape] = 0; // this vector entry is no more used
|
|
myUnusedIdElements++;
|
|
return true;
|
|
}
|
|
|
|
|
|
// --- strange ?
|
|
// TElemSet::iterator e = myElements.begin(), eEnd = myElements.end();
|
|
// for ( ; e != eEnd; ++e )
|
|
// if ( ME == *e ) {
|
|
// myElements.erase( e );
|
|
// return true;
|
|
// }
|
|
// }
|
|
|
|
return false;
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : AddNode
|
|
//purpose :
|
|
//=======================================================================
|
|
void SMESHDS_SubMesh::AddNode(const SMDS_MeshNode * N)
|
|
{
|
|
if ( !IsComplexSubmesh() )
|
|
{
|
|
int idInSubShape = N->getIdInShape();
|
|
assert(idInSubShape == -1);
|
|
SMDS_MeshNode* node = (SMDS_MeshNode*)(N);
|
|
node->setIdInShape(myNodes.size());
|
|
myNodes.push_back(N);
|
|
}
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : RemoveNode
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
bool SMESHDS_SubMesh::RemoveNode(const SMDS_MeshNode * N, bool isNodeDeleted)
|
|
{
|
|
// if ( !IsComplexSubmesh() && NbNodes() ) {
|
|
|
|
if (!isNodeDeleted) // alive node has valid ID and can be found
|
|
{
|
|
int idInSubShape = N->getIdInShape();
|
|
//MESSAGE("SMESHDS_SubMesh::RemoveNode " << idInSubShape << " " << N->GetID());
|
|
assert(idInSubShape >= 0);
|
|
assert(idInSubShape < myNodes.size());
|
|
myNodes[idInSubShape] = 0; // this vector entry is no more used
|
|
myUnusedIdNodes++;
|
|
return true;
|
|
}
|
|
|
|
// --- strange ?
|
|
// TElemSet::iterator e = myNodes.begin(), eEnd = myNodes.end();
|
|
// for ( ; e != eEnd; ++e )
|
|
// if ( N == *e ) {
|
|
// myNodes.erase( e );
|
|
// return true;
|
|
// }
|
|
// }
|
|
|
|
return false;
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : NbElements
|
|
//purpose :
|
|
//=======================================================================
|
|
int SMESHDS_SubMesh::NbElements() const
|
|
{
|
|
if ( !IsComplexSubmesh() )
|
|
return myElements.size() - myUnusedIdElements;
|
|
|
|
int nbElems = 0;
|
|
set<const SMESHDS_SubMesh*>::const_iterator it = mySubMeshes.begin();
|
|
for ( ; it != mySubMeshes.end(); it++ )
|
|
nbElems += (*it)->NbElements();
|
|
|
|
return nbElems;
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : NbNodes
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
int SMESHDS_SubMesh::NbNodes() const
|
|
{
|
|
if ( !IsComplexSubmesh() )
|
|
return myNodes.size() - myUnusedIdNodes;
|
|
|
|
int nbElems = 0;
|
|
set<const SMESHDS_SubMesh*>::const_iterator it = mySubMeshes.begin();
|
|
for ( ; it != mySubMeshes.end(); it++ )
|
|
nbElems += (*it)->NbNodes();
|
|
|
|
return nbElems;
|
|
}
|
|
|
|
/*!
|
|
* template class used for iteration on submesh elements. Interface of iterator remains
|
|
* unchanged after redesign of SMDS to avoid modification everywhere in SMESH.
|
|
* instances are stored in shared_ptr for automatic destruction.
|
|
* Container is copied for iteration, because original can be modified
|
|
* by addition of elements, for instance, and then reallocated (vector)
|
|
*/
|
|
template <class ELEM, typename TSET> class MySetIterator : public SMDS_Iterator<ELEM>
|
|
{
|
|
protected:
|
|
typename TSET::const_iterator _it, _end;
|
|
TSET _table;
|
|
// int _ind;
|
|
public:
|
|
MySetIterator(const TSET& table)
|
|
// : _it(table.begin()), _end(table.end())
|
|
{
|
|
// MESSAGE("table.size()="<< table.size());
|
|
_table = table;
|
|
_it = _table.begin();
|
|
_end = _table.end();
|
|
// for (int i=0; i< _table.size(); i++)
|
|
// if (_table[i]) { MESSAGE("_table["<< i << "]="<< _table[i]);}
|
|
// else
|
|
// { MESSAGE("_table["<< i << "]=NULL"); }
|
|
// _ind = 0;
|
|
}
|
|
|
|
virtual bool more()
|
|
{
|
|
while((_it != _end) && (*_it == 0))
|
|
{
|
|
_it++;
|
|
// _ind++;
|
|
}
|
|
// MESSAGE("more _ind=" << _ind);
|
|
return (_it != _end);
|
|
}
|
|
|
|
virtual ELEM next()
|
|
{
|
|
ELEM e=*_it;
|
|
// if (e) { MESSAGE("next _ind=" << _ind << " *_it=" << *_it);}
|
|
// else { MESSAGE("next _ind=" << _ind << " *_it=NULL");}
|
|
// _ind++;
|
|
_it++;
|
|
return e;
|
|
}
|
|
};
|
|
|
|
// =====================
|
|
// class MyIterator
|
|
// =====================
|
|
|
|
template<typename VALUE> class MyIterator : public SMDS_Iterator<VALUE>
|
|
{
|
|
public:
|
|
MyIterator (const set<const SMESHDS_SubMesh*>& theSubMeshes)
|
|
: mySubIt( theSubMeshes.begin() ), mySubEnd( theSubMeshes.end() ), myMore(false)
|
|
{}
|
|
bool more()
|
|
{
|
|
while (( !myElemIt.get() || !myElemIt->more() ) && mySubIt != mySubEnd)
|
|
{
|
|
myElemIt = getElements(*mySubIt);
|
|
mySubIt++;
|
|
}
|
|
myMore = myElemIt.get() && myElemIt->more();
|
|
return myMore;
|
|
}
|
|
VALUE next()
|
|
{
|
|
VALUE elem = 0;
|
|
if ( myMore )
|
|
elem = myElemIt->next();
|
|
return elem;
|
|
}
|
|
protected:
|
|
virtual boost::shared_ptr< SMDS_Iterator<VALUE> >
|
|
getElements(const SMESHDS_SubMesh*) const = 0;
|
|
|
|
private:
|
|
bool myMore;
|
|
set<const SMESHDS_SubMesh*>::const_iterator mySubIt, mySubEnd;
|
|
boost::shared_ptr< SMDS_Iterator<VALUE> > myElemIt;
|
|
};
|
|
|
|
// =====================
|
|
// class MyElemIterator
|
|
// =====================
|
|
|
|
class MyElemIterator: public MyIterator<const SMDS_MeshElement*>
|
|
{
|
|
public:
|
|
MyElemIterator (const set<const SMESHDS_SubMesh*>& theSubMeshes)
|
|
:MyIterator<const SMDS_MeshElement*>( theSubMeshes ) {}
|
|
SMDS_ElemIteratorPtr getElements(const SMESHDS_SubMesh* theSubMesh) const
|
|
{ return theSubMesh->GetElements(); }
|
|
};
|
|
|
|
// =====================
|
|
// class MyNodeIterator
|
|
// =====================
|
|
|
|
class MyNodeIterator: public MyIterator<const SMDS_MeshNode*>
|
|
{
|
|
public:
|
|
MyNodeIterator (const set<const SMESHDS_SubMesh*>& theSubMeshes)
|
|
:MyIterator<const SMDS_MeshNode*>( theSubMeshes ) {}
|
|
SMDS_NodeIteratorPtr getElements(const SMESHDS_SubMesh* theSubMesh) const
|
|
{ return theSubMesh->GetNodes(); }
|
|
};
|
|
|
|
//=======================================================================
|
|
//function : GetElements
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
SMDS_ElemIteratorPtr SMESHDS_SubMesh::GetElements() const
|
|
{
|
|
if ( IsComplexSubmesh() )
|
|
return SMDS_ElemIteratorPtr( new MyElemIterator( mySubMeshes ));
|
|
return SMDS_ElemIteratorPtr(new MySetIterator<const SMDS_MeshElement*, std::vector<const SMDS_MeshElement*> >(myElements));
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : GetNodes
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
SMDS_NodeIteratorPtr SMESHDS_SubMesh::GetNodes() const
|
|
{
|
|
if ( IsComplexSubmesh() )
|
|
return SMDS_NodeIteratorPtr( new MyNodeIterator( mySubMeshes ));
|
|
|
|
return SMDS_NodeIteratorPtr(new MySetIterator<const SMDS_MeshNode*, std::vector<const SMDS_MeshNode*> >(myNodes));
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : Contains
|
|
//purpose : check if elem or node is in
|
|
//=======================================================================
|
|
|
|
bool SMESHDS_SubMesh::Contains(const SMDS_MeshElement * ME) const
|
|
{
|
|
// DO NOT TRY TO FIND A REMOVED ELEMENT !!
|
|
//if ( IsComplexSubmesh() || !ME )
|
|
if (!ME )
|
|
return false;
|
|
|
|
if ( IsComplexSubmesh() )
|
|
{
|
|
set<const SMESHDS_SubMesh*>::const_iterator aSubIt = mySubMeshes.begin();
|
|
for ( ; aSubIt != mySubMeshes.end(); aSubIt++ )
|
|
if ( (*aSubIt)->Contains( ME ))
|
|
return true;
|
|
return false;
|
|
}
|
|
|
|
if ( ME->GetType() == SMDSAbs_Node )
|
|
{
|
|
int idInShape = ME->getIdInShape();
|
|
if ((idInShape >= 0) && (idInShape < myNodes.size()))
|
|
if (myNodes[idInShape] == ME) return true;
|
|
}
|
|
else
|
|
{
|
|
int idInShape = ME->getIdInShape();
|
|
if ((idInShape >= 0) && (idInShape < myElements.size()))
|
|
if (myElements[idInShape] == ME) return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : AddSubMesh
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
void SMESHDS_SubMesh::AddSubMesh( const SMESHDS_SubMesh* theSubMesh )
|
|
{
|
|
ASSERT( theSubMesh );
|
|
mySubMeshes.insert( theSubMesh );
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : RemoveSubMesh
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
bool SMESHDS_SubMesh::RemoveSubMesh( const SMESHDS_SubMesh* theSubMesh )
|
|
{
|
|
return mySubMeshes.erase( theSubMesh );
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : ContainsSubMesh
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
bool SMESHDS_SubMesh::ContainsSubMesh( const SMESHDS_SubMesh* theSubMesh ) const
|
|
{
|
|
return mySubMeshes.find( theSubMesh ) != mySubMeshes.end();
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : GetSubMeshIterator
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
SMESHDS_SubMeshIteratorPtr SMESHDS_SubMesh::GetSubMeshIterator() const
|
|
{
|
|
typedef set<const SMESHDS_SubMesh*>::const_iterator TIterator;
|
|
return SMESHDS_SubMeshIteratorPtr
|
|
( new SMDS_SetIterator< const SMESHDS_SubMesh*, TIterator >( mySubMeshes.begin(),
|
|
mySubMeshes.end()));
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : Clear
|
|
//purpose : remove the contents
|
|
//=======================================================================
|
|
|
|
void SMESHDS_SubMesh::Clear()
|
|
{
|
|
myElements.clear();
|
|
myNodes.clear();
|
|
SMESHDS_SubMeshIteratorPtr sub = GetSubMeshIterator();
|
|
while ( sub->more() ) {
|
|
if ( SMESHDS_SubMesh* sm = (SMESHDS_SubMesh*) sub->next())
|
|
sm->Clear();
|
|
}
|
|
}
|
|
|
|
int SMESHDS_SubMesh::getSize()
|
|
{
|
|
int c = NbNodes();
|
|
int d = NbElements();
|
|
//cerr << "SMESHDS_SubMesh::NbNodes " << c << endl;
|
|
//cerr << "SMESHDS_SubMesh::NbElements " << d << endl;
|
|
return c+d;
|
|
}
|
|
|
|
void SMESHDS_SubMesh::compactList()
|
|
{
|
|
// todo : compact vector of nodes and elements
|
|
}
|