0022098: EDF 2036 SMESH: Create groups from none conected parts of a mesh

+#include "SMESH_MeshAlgos.hxx"

+    class SMESHCONTROLS_EXPORT ConnectedElements: public virtual Predicate
This commit is contained in:
eap 2013-05-16 16:36:26 +00:00
parent b73a05d5ec
commit 101919845f
2 changed files with 180 additions and 4 deletions

View File

@ -33,6 +33,7 @@
#include "SMESHDS_GroupBase.hxx"
#include "SMESHDS_Mesh.hxx"
#include "SMESH_OctreeNode.hxx"
#include "SMESH_MeshAlgos.hxx"
#include <BRepAdaptor_Surface.hxx>
#include <BRepClass_FaceClassifier.hxx>
@ -2793,6 +2794,148 @@ SMDSAbs_EntityType ElemEntityType::GetElemEntityType() const
return myEntityType;
}
//================================================================================
/*!
* \brief Class ConnectedElements
*/
//================================================================================
ConnectedElements::ConnectedElements():
myNodeID(0), myType( SMDSAbs_All ), myOkIDsReady( false ) {}
SMDSAbs_ElementType ConnectedElements::GetType() const
{ return myType; }
int ConnectedElements::GetNode() const
{ return myXYZ.empty() ? myNodeID : 0; } // myNodeID can be found by myXYZ
std::vector<double> ConnectedElements::GetPoint() const
{ return myXYZ; }
void ConnectedElements::clearOkIDs()
{ myOkIDsReady = false; myOkIDs.clear(); }
void ConnectedElements::SetType( SMDSAbs_ElementType theType )
{
if ( myType != theType || myMeshModifTracer.IsMeshModified() )
clearOkIDs();
myType = theType;
}
void ConnectedElements::SetMesh( const SMDS_Mesh* theMesh )
{
myMeshModifTracer.SetMesh( theMesh );
if ( myMeshModifTracer.IsMeshModified() )
{
clearOkIDs();
if ( !myXYZ.empty() )
SetPoint( myXYZ[0], myXYZ[1], myXYZ[2] ); // find a node near myXYZ it in a new mesh
}
}
void ConnectedElements::SetNode( int nodeID )
{
myNodeID = nodeID;
myXYZ.clear();
bool isSameDomain = false;
if ( myOkIDsReady && myMeshModifTracer.GetMesh() && !myMeshModifTracer.IsMeshModified() )
if ( const SMDS_MeshNode* n = myMeshModifTracer.GetMesh()->FindNode( myNodeID ))
{
SMDS_ElemIteratorPtr eIt = n->GetInverseElementIterator( myType );
while ( !isSameDomain && eIt->more() )
isSameDomain = IsSatisfy( eIt->next()->GetID() );
}
if ( !isSameDomain )
clearOkIDs();
}
void ConnectedElements::SetPoint( double x, double y, double z )
{
myXYZ.resize(3);
myXYZ[0] = x;
myXYZ[1] = y;
myXYZ[2] = z;
myNodeID = 0;
bool isSameDomain = false;
// find myNodeID by myXYZ if possible
if ( myMeshModifTracer.GetMesh() )
{
auto_ptr<SMESH_ElementSearcher> searcher
( SMESH_MeshAlgos::GetElementSearcher( (SMDS_Mesh&) *myMeshModifTracer.GetMesh() ));
vector< const SMDS_MeshElement* > foundElems;
searcher->FindElementsByPoint( gp_Pnt(x,y,z), SMDSAbs_All, foundElems );
if ( !foundElems.empty() )
{
myNodeID = foundElems[0]->GetNode(0)->GetID();
if ( myOkIDsReady && !myMeshModifTracer.IsMeshModified() )
isSameDomain = IsSatisfy( foundElems[0]->GetID() );
}
}
if ( !isSameDomain )
clearOkIDs();
}
bool ConnectedElements::IsSatisfy( long theElementId )
{
// Here we do NOT check if the mesh has changed, we do it in Set...() only!!!
if ( !myOkIDsReady )
{
if ( !myMeshModifTracer.GetMesh() )
return false;
const SMDS_MeshNode* node0 = myMeshModifTracer.GetMesh()->FindNode( myNodeID );
if ( !node0 )
return false;
list< const SMDS_MeshNode* > nodeQueue( 1, node0 );
std::set< int > checkedNodeIDs;
// algo:
// foreach node in nodeQueue:
// foreach element sharing a node:
// add ID of an element of myType to myOkIDs;
// push all element nodes absent from checkedNodeIDs to nodeQueue;
while ( !nodeQueue.empty() )
{
const SMDS_MeshNode* node = nodeQueue.front();
nodeQueue.pop_front();
// loop on elements sharing the node
SMDS_ElemIteratorPtr eIt = node->GetInverseElementIterator();
while ( eIt->more() )
{
// keep elements of myType
const SMDS_MeshElement* element = eIt->next();
if ( element->GetType() == myType )
myOkIDs.insert( myOkIDs.end(), element->GetID() );
// enqueue nodes of the element
SMDS_ElemIteratorPtr nIt = element->nodesIterator();
while ( nIt->more() )
{
const SMDS_MeshNode* n = static_cast< const SMDS_MeshNode* >( nIt->next() );
if ( checkedNodeIDs.insert( n->GetID() ).second )
nodeQueue.push_back( n );
}
}
}
if ( myType == SMDSAbs_Node )
std::swap( myOkIDs, checkedNodeIDs );
size_t totalNbElems = myMeshModifTracer.GetMesh()->GetMeshInfo().NbElements( myType );
if ( myOkIDs.size() == totalNbElems )
myOkIDs.clear();
myOkIDsReady = true;
}
return myOkIDs.empty() ? true : myOkIDs.count( theElementId );
}
//================================================================================
/*!
* \brief Class CoplanarFaces

View File

@ -302,7 +302,7 @@ namespace SMESH{
/*
Class : MultiConnection
Description : Functor for calculating number of faces conneted to the edge
Description : Functor for calculating number of faces connected to the edge
*/
class SMESHCONTROLS_EXPORT MultiConnection: public virtual NumericalFunctor{
public:
@ -314,7 +314,7 @@ namespace SMESH{
/*
Class : MultiConnection2D
Description : Functor for calculating number of faces conneted to the edge
Description : Functor for calculating number of faces connected to the edge
*/
class SMESHCONTROLS_EXPORT MultiConnection2D: public virtual NumericalFunctor{
public:
@ -945,7 +945,7 @@ namespace SMESH{
void SetType( SMDSAbs_ElementType theType );
virtual SMDSAbs_ElementType GetType() const;
void SetGeomType( SMDSAbs_GeometryType theType );
virtual SMDSAbs_GeometryType GetGeomType() const;
SMDSAbs_GeometryType GetGeomType() const;
private:
const SMDS_Mesh* myMesh;
@ -979,10 +979,43 @@ namespace SMESH{
};
typedef boost::shared_ptr<CoplanarFaces> CoplanarFacesPtr;
/*
Class : ConnectedElements
Description : Predicate to get elements of one domain
*/
class SMESHCONTROLS_EXPORT ConnectedElements: public virtual Predicate
{
public:
ConnectedElements();
void SetNode( int nodeID );
void SetPoint( double x, double y, double z );
int GetNode() const;
std::vector<double> GetPoint() const;
void SetType( SMDSAbs_ElementType theType );
virtual SMDSAbs_ElementType GetType() const;
virtual void SetMesh( const SMDS_Mesh* theMesh );
virtual bool IsSatisfy( long theElementId );
//const std::set<long>& GetDomainIDs() const { return myOkIDs; }
private:
int myNodeID;
std::vector<double> myXYZ;
SMDSAbs_ElementType myType;
TMeshModifTracer myMeshModifTracer;
void clearOkIDs();
bool myOkIDsReady;
std::set< int > myOkIDs; // empty means that there is one domain
};
typedef boost::shared_ptr<ConnectedElements> ConnectedElementsPtr;
/*
FILTER
*/
class SMESHCONTROLS_EXPORT Filter{
class SMESHCONTROLS_EXPORT Filter {
public:
Filter();
virtual ~Filter();