0021559: EDF 2175 SMESH: Hexa/Tetra mixed meshes

Return newly detected concurrent sub-meshes in the order they are
  computed w/o imposed order of sub-meshes
This commit is contained in:
eap 2012-09-06 14:13:38 +00:00
parent a438b8cfa9
commit ab9945d2b0

View File

@ -4352,12 +4352,14 @@ void SMESH_Mesh_i::CollectMeshInfo(const SMDS_ElemIteratorPtr theItr,
} }
//============================================================================= //=============================================================================
namespace // Finding concurrent hypotheses
//=============================================================================
{
/*! /*!
* \brief mapping of mesh dimension into shape type * \brief mapping of mesh dimension into shape type
*/ */
//============================================================================= TopAbs_ShapeEnum shapeTypeByDim(const int theDim)
static TopAbs_ShapeEnum shapeTypeByDim(const int theDim)
{ {
TopAbs_ShapeEnum aType = TopAbs_SOLID; TopAbs_ShapeEnum aType = TopAbs_SOLID;
switch ( theDim ) { switch ( theDim ) {
@ -4370,7 +4372,7 @@ static TopAbs_ShapeEnum shapeTypeByDim(const int theDim)
return aType; return aType;
} }
//============================================================================= //-----------------------------------------------------------------------------
/*! /*!
* \brief Internal structure used to find concurent submeshes * \brief Internal structure used to find concurent submeshes
* *
@ -4379,8 +4381,6 @@ static TopAbs_ShapeEnum shapeTypeByDim(const int theDim)
* with another submesh. In other words, it is dimension of a hypothesis assigned * with another submesh. In other words, it is dimension of a hypothesis assigned
* to submesh. * to submesh.
*/ */
//=============================================================================
class SMESH_DimHyp class SMESH_DimHyp
{ {
public: public:
@ -4389,8 +4389,14 @@ class SMESH_DimHyp
int _ownDim; //!< dimension of shape of _subMesh (>=_dim) int _ownDim; //!< dimension of shape of _subMesh (>=_dim)
TopTools_MapOfShape _shapeMap; TopTools_MapOfShape _shapeMap;
SMESH_subMesh* _subMesh; SMESH_subMesh* _subMesh;
list<const SMESHDS_Hypothesis*> _hypothesises; //!< algo is first, then its parameters list<const SMESHDS_Hypothesis*> _hypotheses; //!< algo is first, then its parameters
//-----------------------------------------------------------------------------
// Return the algorithm
const SMESH_Algo* GetAlgo() const
{ return _hypotheses.empty() ? 0 : dynamic_cast<const SMESH_Algo*>( _hypotheses.front() ); }
//-----------------------------------------------------------------------------
//! Constructors //! Constructors
SMESH_DimHyp(const SMESH_subMesh* theSubMesh, SMESH_DimHyp(const SMESH_subMesh* theSubMesh,
const int theDim, const int theDim,
@ -4400,6 +4406,7 @@ class SMESH_DimHyp
SetShape( theDim, theShape ); SetShape( theDim, theShape );
} }
//-----------------------------------------------------------------------------
//! set shape //! set shape
void SetShape(const int theDim, void SetShape(const int theDim,
const TopoDS_Shape& theShape) const TopoDS_Shape& theShape)
@ -4415,6 +4422,7 @@ class SMESH_DimHyp
} }
} }
//-----------------------------------------------------------------------------
//! Check sharing of sub-shapes //! Check sharing of sub-shapes
static bool isShareSubShapes(const TopTools_MapOfShape& theToCheck, static bool isShareSubShapes(const TopTools_MapOfShape& theToCheck,
const TopTools_MapOfShape& theToFind, const TopTools_MapOfShape& theToFind,
@ -4435,11 +4443,13 @@ class SMESH_DimHyp
return isShared; return isShared;
} }
//-----------------------------------------------------------------------------
//! check algorithms //! check algorithms
static bool checkAlgo(const SMESHDS_Hypothesis* theA1, static bool checkAlgo(const SMESHDS_Hypothesis* theA1,
const SMESHDS_Hypothesis* theA2) const SMESHDS_Hypothesis* theA2)
{ {
if ( theA1->GetType() == SMESHDS_Hypothesis::PARAM_ALGO || if ( !theA1 || !theA2 ||
theA1->GetType() == SMESHDS_Hypothesis::PARAM_ALGO ||
theA2->GetType() == SMESHDS_Hypothesis::PARAM_ALGO ) theA2->GetType() == SMESHDS_Hypothesis::PARAM_ALGO )
return false; // one of the hypothesis is not algorithm return false; // one of the hypothesis is not algorithm
// check algorithm names (should be equal) // check algorithm names (should be equal)
@ -4447,6 +4457,7 @@ class SMESH_DimHyp
} }
//-----------------------------------------------------------------------------
//! Check if sub-shape hypotheses are concurrent //! Check if sub-shape hypotheses are concurrent
bool IsConcurrent(const SMESH_DimHyp* theOther) const bool IsConcurrent(const SMESH_DimHyp* theOther) const
{ {
@ -4456,8 +4467,10 @@ class SMESH_DimHyp
// if ( <own dim of either of submeshes> == <concurrent dim> && // if ( <own dim of either of submeshes> == <concurrent dim> &&
// any of the two submeshes is not on COMPOUND shape ) // any of the two submeshes is not on COMPOUND shape )
// -> no concurrency // -> no concurrency
bool meIsCompound = (_subMesh->GetSubMeshDS() && _subMesh->GetSubMeshDS()->IsComplexSubmesh()); bool meIsCompound = (_subMesh->GetSubMeshDS() &&
bool otherIsCompound = (theOther->_subMesh->GetSubMeshDS() && theOther->_subMesh->GetSubMeshDS()->IsComplexSubmesh()); _subMesh->GetSubMeshDS()->IsComplexSubmesh());
bool otherIsCompound = (theOther->_subMesh->GetSubMeshDS() &&
theOther->_subMesh->GetSubMeshDS()->IsComplexSubmesh());
if ( (_ownDim == _dim || theOther->_ownDim == _dim ) && (!meIsCompound || !otherIsCompound)) if ( (_ownDim == _dim || theOther->_ownDim == _dim ) && (!meIsCompound || !otherIsCompound))
return false; return false;
@ -4469,65 +4482,102 @@ class SMESH_DimHyp
return false; return false;
// check algorithms to be same // check algorithms to be same
if (!checkAlgo( _hypothesises.front(), theOther->_hypothesises.front() )) if ( !checkAlgo( this->GetAlgo(), theOther->GetAlgo() ))
return true; // different algorithms return true; // different algorithms -> concurrency !
// check hypothesises for concurrence (skip first as algorithm) // check hypothesises for concurrence (skip first as algorithm)
int nbSame = 0; int nbSame = 0;
// pointers should be same, becase it is referenes from mesh hypothesis partition // pointers should be same, because it is referened from mesh hypothesis partition
list <const SMESHDS_Hypothesis*>::const_iterator hypIt = _hypothesises.begin(); list <const SMESHDS_Hypothesis*>::const_iterator hypIt = _hypotheses.begin();
list <const SMESHDS_Hypothesis*>::const_iterator otheEndIt = theOther->_hypothesises.end(); list <const SMESHDS_Hypothesis*>::const_iterator otheEndIt = theOther->_hypotheses.end();
for ( hypIt++ /*skip first as algo*/; hypIt != _hypothesises.end(); hypIt++ ) for ( hypIt++ /*skip first as algo*/; hypIt != _hypotheses.end(); hypIt++ )
if ( find( theOther->_hypothesises.begin(), otheEndIt, *hypIt ) != otheEndIt ) if ( find( theOther->_hypotheses.begin(), otheEndIt, *hypIt ) != otheEndIt )
nbSame++; nbSame++;
// the submeshes are concurrent if their algorithms has different parameters // the submeshes are concurrent if their algorithms has different parameters
return nbSame != theOther->_hypothesises.size() - 1; return nbSame != theOther->_hypotheses.size() - 1;
}
// Return true if algorithm of this SMESH_DimHyp is used if no
// sub-mesh order is imposed by the user
bool IsHigherPriorityThan( const SMESH_DimHyp* theOther ) const
{
// NeedDiscreteBoundary() algo has a higher priority
if ( this ->GetAlgo()->NeedDiscreteBoundary() !=
theOther->GetAlgo()->NeedDiscreteBoundary() )
return !this->GetAlgo()->NeedDiscreteBoundary();
return ( this->_subMesh->GetId() < theOther->_subMesh->GetId() );
} }
}; // end of SMESH_DimHyp }; // end of SMESH_DimHyp
//-----------------------------------------------------------------------------
typedef list<SMESH_DimHyp*> TDimHypList; typedef list<const SMESH_DimHyp*> TDimHypList;
static void addDimHypInstance(const int theDim, //-----------------------------------------------------------------------------
const TopoDS_Shape& theShape,
const SMESH_Algo* theAlgo, void addDimHypInstance(const int theDim,
const SMESH_subMesh* theSubMesh, const TopoDS_Shape& theShape,
const list <const SMESHDS_Hypothesis*>& theHypList, const SMESH_Algo* theAlgo,
TDimHypList* theDimHypListArr ) const SMESH_subMesh* theSubMesh,
const list <const SMESHDS_Hypothesis*>& theHypList,
TDimHypList* theDimHypListArr )
{ {
TDimHypList& listOfdimHyp = theDimHypListArr[theDim]; TDimHypList& listOfdimHyp = theDimHypListArr[theDim];
if ( listOfdimHyp.empty() || listOfdimHyp.back()->_subMesh != theSubMesh ) { if ( listOfdimHyp.empty() || listOfdimHyp.back()->_subMesh != theSubMesh ) {
SMESH_DimHyp* dimHyp = new SMESH_DimHyp( theSubMesh, theDim, theShape ); SMESH_DimHyp* dimHyp = new SMESH_DimHyp( theSubMesh, theDim, theShape );
dimHyp->_hypotheses.push_front(theAlgo);
listOfdimHyp.push_back( dimHyp ); listOfdimHyp.push_back( dimHyp );
} }
SMESH_DimHyp* dimHyp = listOfdimHyp.back(); SMESH_DimHyp* dimHyp = const_cast<SMESH_DimHyp*>( listOfdimHyp.back() );
dimHyp->_hypothesises.push_front(theAlgo); dimHyp->_hypotheses.insert( dimHyp->_hypotheses.end(),
list <const SMESHDS_Hypothesis*>::const_iterator hypIt = theHypList.begin(); theHypList.begin(), theHypList.end() );
for( ; hypIt != theHypList.end(); hypIt++ )
dimHyp->_hypothesises.push_back( *hypIt );
} }
static void findConcurrents(const SMESH_DimHyp* theDimHyp, //-----------------------------------------------------------------------------
const TDimHypList& theListOfDimHyp, void addInOrderOfPriority( const SMESH_DimHyp* theDimHyp,
TListOfInt& theListOfConcurr ) TDimHypList& theListOfConcurr)
{ {
TDimHypList::const_reverse_iterator rIt = theListOfDimHyp.rbegin(); if ( theListOfConcurr.empty() )
for ( ; rIt != theListOfDimHyp.rend(); rIt++ ) { {
const SMESH_DimHyp* curDimHyp = *rIt; theListOfConcurr.push_back( theDimHyp );
if ( curDimHyp == theDimHyp ) }
break; // meet own dimHyp pointer in same dimension else
else if ( theDimHyp->IsConcurrent( curDimHyp ) ) {
if ( find( theListOfConcurr.begin(), TDimHypList::iterator hypIt = theListOfConcurr.begin();
theListOfConcurr.end(), while ( hypIt != theListOfConcurr.end() &&
curDimHyp->_subMesh->GetId() ) == theListOfConcurr.end() ) !theDimHyp->IsHigherPriorityThan( *hypIt ))
theListOfConcurr.push_back( curDimHyp->_subMesh->GetId() ); ++hypIt;
theListOfConcurr.insert( hypIt, theDimHyp );
} }
} }
static void unionLists(TListOfInt& theListOfId, //-----------------------------------------------------------------------------
TListOfListOfInt& theListOfListOfId, void findConcurrents(const SMESH_DimHyp* theDimHyp,
const int theIndx ) const TDimHypList& theListOfDimHyp,
TDimHypList& theListOfConcurrHyp,
set<int>& theSetOfConcurrId )
{
TDimHypList::const_reverse_iterator rIt = theListOfDimHyp.rbegin();
for ( ; rIt != theListOfDimHyp.rend(); rIt++ )
{
const SMESH_DimHyp* curDimHyp = *rIt;
if ( curDimHyp == theDimHyp )
break; // meet own dimHyp pointer in same dimension
if ( theDimHyp->IsConcurrent( curDimHyp ) &&
theSetOfConcurrId.insert( curDimHyp->_subMesh->GetId() ).second )
{
addInOrderOfPriority( curDimHyp, theListOfConcurrHyp );
}
}
}
//-----------------------------------------------------------------------------
void unionLists(TListOfInt& theListOfId,
TListOfListOfInt& theListOfListOfId,
const int theIndx )
{ {
TListOfListOfInt::iterator it = theListOfListOfId.begin(); TListOfListOfInt::iterator it = theListOfListOfId.begin();
for ( int i = 0; it != theListOfListOfId.end(); it++, i++ ) { for ( int i = 0; it != theListOfListOfId.end(); it++, i++ ) {
@ -4549,9 +4599,10 @@ static void unionLists(TListOfInt& theListOfId,
otherListOfId.clear(); otherListOfId.clear();
} }
} }
//-----------------------------------------------------------------------------
//! free memory allocated for dimension-hypothesis objects //! free memory allocated for dimension-hypothesis objects
static void removeDimHyps( TDimHypList* theArrOfList ) void removeDimHyps( TDimHypList* theArrOfList )
{ {
for (int i = 0; i < 4; i++ ) { for (int i = 0; i < 4; i++ ) {
TDimHypList& listOfdimHyp = theArrOfList[i]; TDimHypList& listOfdimHyp = theArrOfList[i];
@ -4561,6 +4612,28 @@ static void removeDimHyps( TDimHypList* theArrOfList )
} }
} }
//-----------------------------------------------------------------------------
/*!
* \brief find common submeshes with given submesh
* \param theSubMeshList list of already collected submesh to check
* \param theSubMesh given submesh to intersect with other
* \param theCommonSubMeshes collected common submeshes
*/
void findCommonSubMesh (list<const SMESH_subMesh*>& theSubMeshList,
const SMESH_subMesh* theSubMesh,
set<const SMESH_subMesh*>& theCommon )
{
if ( !theSubMesh )
return;
list<const SMESH_subMesh*>::const_iterator it = theSubMeshList.begin();
for ( ; it != theSubMeshList.end(); it++ )
theSubMesh->FindIntersection( *it, theCommon );
theSubMeshList.push_back( theSubMesh );
//theCommon.insert( theSubMesh );
}
} // namespace
//============================================================================= //=============================================================================
/*! /*!
* \brief Return submesh objects list in meshing order * \brief Return submesh objects list in meshing order
@ -4579,7 +4652,7 @@ SMESH::submesh_array_array* SMESH_Mesh_i::GetMeshOrder()
TListOfListOfInt anOrder = mesh.GetMeshOrder(); // is there already defined order? TListOfListOfInt anOrder = mesh.GetMeshOrder(); // is there already defined order?
if ( !anOrder.size() ) { if ( !anOrder.size() ) {
// collect submeshes detecting concurrent algorithms and hypothesises // collect submeshes and detect concurrent algorithms and hypothesises
TDimHypList dimHypListArr[4]; // dimHyp list for each shape dimension TDimHypList dimHypListArr[4]; // dimHyp list for each shape dimension
map<int, ::SMESH_subMesh*>::iterator i_sm = _mapSubMesh.begin(); map<int, ::SMESH_subMesh*>::iterator i_sm = _mapSubMesh.begin();
@ -4587,7 +4660,7 @@ SMESH::submesh_array_array* SMESH_Mesh_i::GetMeshOrder()
::SMESH_subMesh* sm = (*i_sm).second; ::SMESH_subMesh* sm = (*i_sm).second;
// shape of submesh // shape of submesh
const TopoDS_Shape& aSubMeshShape = sm->GetSubShape(); const TopoDS_Shape& aSubMeshShape = sm->GetSubShape();
// list of assigned hypothesises // list of assigned hypothesises
const list <const SMESHDS_Hypothesis*>& hypList = mesh.GetHypothesisList(aSubMeshShape); const list <const SMESHDS_Hypothesis*>& hypList = mesh.GetHypothesisList(aSubMeshShape);
// Find out dimensions where the submesh can be concurrent. // Find out dimensions where the submesh can be concurrent.
@ -4606,7 +4679,7 @@ SMESH::submesh_array_array* SMESH_Mesh_i::GetMeshOrder()
anAlgo = mesh.GetGen()->GetAlgo( mesh, anExp.Current() ); anAlgo = mesh.GetGen()->GetAlgo( mesh, anExp.Current() );
} }
if (!anAlgo) if (!anAlgo)
continue; // no assigned algorithm to current submesh continue; // no algorithm assigned to a current submesh
int dim = anAlgo->GetDim(); // top concurrent dimension (see comment to SMESH_DimHyp) int dim = anAlgo->GetDim(); // top concurrent dimension (see comment to SMESH_DimHyp)
// the submesh can concurrent at <dim> (or lower dims if !anAlgo->NeedDiscreteBoundary()) // the submesh can concurrent at <dim> (or lower dims if !anAlgo->NeedDiscreteBoundary())
@ -4619,20 +4692,25 @@ SMESH::submesh_array_array* SMESH_Mesh_i::GetMeshOrder()
// iterate on created dimension-hypotheses and check for concurrents // iterate on created dimension-hypotheses and check for concurrents
for ( int i = 0; i < 4; i++ ) { for ( int i = 0; i < 4; i++ ) {
const list<SMESH_DimHyp*>& listOfDimHyp = dimHypListArr[i]; const TDimHypList& listOfDimHyp = dimHypListArr[i];
// check for concurrents in own and other dimensions (step-by-step) // check for concurrents in own and other dimensions (step-by-step)
TDimHypList::const_iterator dhIt = listOfDimHyp.begin(); TDimHypList::const_iterator dhIt = listOfDimHyp.begin();
for ( ; dhIt != listOfDimHyp.end(); dhIt++ ) { for ( ; dhIt != listOfDimHyp.end(); dhIt++ ) {
const SMESH_DimHyp* dimHyp = *dhIt; const SMESH_DimHyp* dimHyp = *dhIt;
TListOfInt listOfConcurr; TDimHypList listOfConcurr;
set<int> setOfConcurrIds;
// looking for concurrents and collect into own list // looking for concurrents and collect into own list
for ( int j = i; j < 4; j++ ) for ( int j = i; j < 4; j++ )
findConcurrents( dimHyp, dimHypListArr[j], listOfConcurr ); findConcurrents( dimHyp, dimHypListArr[j], listOfConcurr, setOfConcurrIds );
// check if any concurrents found // check if any concurrents found
if ( listOfConcurr.size() > 0 ) { if ( listOfConcurr.size() > 0 ) {
// add own submesh to list of concurrent // add own submesh to list of concurrent
listOfConcurr.push_front( dimHyp->_subMesh->GetId() ); addInOrderOfPriority( dimHyp, listOfConcurr );
anOrder.push_back( listOfConcurr ); list<int> listOfConcurrIds;
TDimHypList::iterator hypIt = listOfConcurr.begin();
for ( ; hypIt != listOfConcurr.end(); ++hypIt )
listOfConcurrIds.push_back( (*hypIt)->_subMesh->GetId() );
anOrder.push_back( listOfConcurrIds );
} }
} }
} }
@ -4655,28 +4733,6 @@ SMESH::submesh_array_array* SMESH_Mesh_i::GetMeshOrder()
return aResult._retn(); return aResult._retn();
} }
//=============================================================================
/*!
* \brief find common submeshes with given submesh
* \param theSubMeshList list of already collected submesh to check
* \param theSubMesh given submesh to intersect with other
* \param theCommonSubMeshes collected common submeshes
*/
//=============================================================================
static void findCommonSubMesh (list<const SMESH_subMesh*>& theSubMeshList,
const SMESH_subMesh* theSubMesh,
set<const SMESH_subMesh*>& theCommon )
{
if ( !theSubMesh )
return;
list<const SMESH_subMesh*>::const_iterator it = theSubMeshList.begin();
for ( ; it != theSubMeshList.end(); it++ )
theSubMesh->FindIntersection( *it, theCommon );
theSubMeshList.push_back( theSubMesh );
//theCommon.insert( theSubMesh );
}
//============================================================================= //=============================================================================
/*! /*!
* \brief Set submesh object order * \brief Set submesh object order