PAL13330( When mesh generation does not success, trace where )

compute errors management
This commit is contained in:
eap 2007-04-10 14:06:02 +00:00
parent 82e34f1183
commit 8b19a88a83
7 changed files with 371 additions and 314 deletions

View File

@ -122,134 +122,67 @@ SMESH_Mesh* SMESH_Gen::CreateMesh(int theStudyId, bool theIsEmbeddedMode)
return aMesh; return aMesh;
} }
//================================================================================
/*!
* \brief Compute submesh
* \param sm - submesh
* \retval bool - is a success
*/
//================================================================================
bool SMESH_Gen::Compute(::SMESH_subMesh& sm)
{
if ( sm.GetSubShape().ShapeType() == TopAbs_VERTEX )
{
SMESHDS_SubMesh* smDS = sm.GetSubMeshDS();
if ( !smDS || !smDS->NbNodes() ) {
TopoDS_Vertex V = TopoDS::Vertex(sm.GetSubShape());
gp_Pnt P = BRep_Tool::Pnt(V);
SMESHDS_Mesh * meshDS = sm.GetFather()->GetMeshDS();
if ( SMDS_MeshNode * node = meshDS->AddNode(P.X(), P.Y(), P.Z()) )
meshDS->SetNodeOnVertex(node, V);
}
}
return sm.ComputeStateEngine(SMESH_subMesh::COMPUTE);
}
//============================================================================= //=============================================================================
/*! /*!
* * Compute a mesh
*/ */
//============================================================================= //=============================================================================
bool SMESH_Gen::Compute(SMESH_Mesh & aMesh, const TopoDS_Shape & aShape) bool SMESH_Gen::Compute(SMESH_Mesh & aMesh, const TopoDS_Shape & aShape)
{ {
MESSAGE("SMESH_Gen::Compute"); MESSAGE("SMESH_Gen::Compute");
// bool isDone = false;
/*
Algo : s'appuie ou non sur une geometrie
Si geometrie:
Vertex : rien à faire (range le point)
Edge, Wire, collection d'edge et wire : 1D
Face, Shell, collection de Face et Shells : 2D
Solid, Collection de Solid : 3D
*/
// *** corriger commentaires
// check hypothesis associated to the mesh :
// - only one algo : type compatible with the type of the shape
// - hypothesis = compatible with algo
// - check if hypothesis are applicable to this algo
// - check contradictions within hypothesis
// (test if enough hypothesis is done further)
bool ret = true; bool ret = true;
// if ( !CheckAlgoState( aMesh, aShape ))
// {
// INFOS( "ABORT MESHING: some algos or hypothesis are missing");
// return false;
// }
SMESH_subMesh *sm = aMesh.GetSubMesh(aShape); SMESH_subMesh *sm = aMesh.GetSubMesh(aShape);
// if ( sm->GetComputeState() == SMESH_subMesh::COMPUTE_OK )
// return true; // already computed
// ----------------------------------------------------------------- // -----------------------------------------------------------------
// apply algos that do not require descretized boundaries, starting // apply algos that do not require descretized boundaries, starting
// from the most complex shapes // from the most complex shapes
// ----------------------------------------------------------------- // -----------------------------------------------------------------
// map containing all subshapes in the order: vertices, edges, faces... const bool includeSelf = true;
const map<int, SMESH_subMesh*>& smMap = sm->DependsOn(); const bool complexShapeFirst = true;
map<int, SMESH_subMesh*>::const_reverse_iterator revItSub = smMap.rbegin();
SMESH_subMesh* smToCompute = sm; SMESH_subMeshIteratorPtr smIt = sm->getDependsOnIterator(includeSelf,
while ( smToCompute ) complexShapeFirst);
while ( smIt->more() )
{ {
SMESH_subMesh* smToCompute = smIt->next();
const TopoDS_Shape& aSubShape = smToCompute->GetSubShape(); const TopoDS_Shape& aSubShape = smToCompute->GetSubShape();
if ( GetShapeDim( aSubShape ) < 1 ) break; if ( GetShapeDim( aSubShape ) < 1 ) break;
SMESH_Algo* algo = GetAlgo( aMesh, aSubShape ); SMESH_Algo* algo = GetAlgo( aMesh, aSubShape );
if (algo && !algo->NeedDescretBoundary()) { if (algo && !algo->NeedDescretBoundary())
if (smToCompute->GetComputeState() == SMESH_subMesh::READY_TO_COMPUTE) {
ret = smToCompute->ComputeStateEngine( SMESH_subMesh::COMPUTE );
} else if (smToCompute->GetComputeState() == SMESH_subMesh::FAILED_TO_COMPUTE) {
// JFA for PAL6524
ret = false;
} else {
}
}
if (!ret)
return false;
// next subMesh
if (revItSub != smMap.rend())
{ {
smToCompute = (*revItSub).second; if (smToCompute->GetComputeState() == SMESH_subMesh::READY_TO_COMPUTE)
revItSub++; smToCompute->ComputeStateEngine( SMESH_subMesh::COMPUTE );
if (smToCompute->GetComputeState() == SMESH_subMesh::FAILED_TO_COMPUTE)
ret = false;;
} }
else
smToCompute = 0;
} }
// ----------------------------------------------- // -----------------------------------------------
// mesh the rest subshapes starting from vertices // mesh the rest subshapes starting from vertices
// ----------------------------------------------- // -----------------------------------------------
smIt = sm->getDependsOnIterator(includeSelf, !complexShapeFirst);
int i, nbSub = smMap.size(); while ( smIt->more() )
map<int, SMESH_subMesh*>::const_iterator itSub = smMap.begin();
for ( i = 0; i <= nbSub; ++i ) // loop on the whole map plus <sm>
{ {
if ( itSub == smMap.end() ) SMESH_subMesh* smToCompute = smIt->next();
smToCompute = sm;
else
smToCompute = (itSub++)->second;
if (smToCompute->GetComputeState() != SMESH_subMesh::READY_TO_COMPUTE) { if (smToCompute->GetComputeState() == SMESH_subMesh::READY_TO_COMPUTE)
if (smToCompute->GetComputeState() == SMESH_subMesh::FAILED_TO_COMPUTE) smToCompute->ComputeStateEngine( SMESH_subMesh::COMPUTE );
ret = false;
} if (smToCompute->GetComputeState() == SMESH_subMesh::FAILED_TO_COMPUTE)
else if ( !Compute( *smToCompute )) {
ret = false; ret = false;
}
} }
MESSAGE( "VSR - SMESH_Gen::Compute() finished, OK = " << ret); MESSAGE( "VSR - SMESH_Gen::Compute() finished, OK = " << ret);
return ret; return ret;
} }
//======================================================================= //=======================================================================
//function : checkConformIgnoredAlgos //function : checkConformIgnoredAlgos
//purpose : //purpose :
@ -311,7 +244,7 @@ static bool checkConformIgnoredAlgos(SMESH_Mesh& aMesh,
"> would produce not conform mesh: " "> would produce not conform mesh: "
"<Not Conform Mesh Allowed> hypotesis is missing"); "<Not Conform Mesh Allowed> hypotesis is missing");
theErrors.push_back( SMESH_Gen::TAlgoStateError() ); theErrors.push_back( SMESH_Gen::TAlgoStateError() );
theErrors.back().Set( SMESH_Gen::NOT_CONFORM_MESH, algo, false ); theErrors.back().Set( SMESH_Hypothesis::HYP_NOTCONFORM, algo, false );
} }
// sub-algos will be hidden by a local <algo> // sub-algos will be hidden by a local <algo>
@ -371,7 +304,7 @@ static bool checkMissing(SMESH_Gen* aGen,
INFOS( "ERROR: " << shapeDim << "D algorithm is missing" ); INFOS( "ERROR: " << shapeDim << "D algorithm is missing" );
ret = false; ret = false;
theErrors.push_back( SMESH_Gen::TAlgoStateError() ); theErrors.push_back( SMESH_Gen::TAlgoStateError() );
theErrors.back().Set( SMESH_Gen::MISSING_ALGO, shapeDim, true ); theErrors.back().Set( SMESH_Hypothesis::HYP_MISSING, shapeDim, true );
} }
} }
return ret; return ret;
@ -383,13 +316,13 @@ static bool checkMissing(SMESH_Gen* aGen,
bool IsGlobalHypothesis = aGen->IsGlobalHypothesis( algo, aMesh ); bool IsGlobalHypothesis = aGen->IsGlobalHypothesis( algo, aMesh );
if (!IsGlobalHypothesis || !globalChecked[ algo->GetDim() ]) if (!IsGlobalHypothesis || !globalChecked[ algo->GetDim() ])
{ {
SMESH_Gen::TAlgoStateErrorName errName = SMESH_Gen::MISSING_HYPO; TAlgoStateErrorName errName = SMESH_Hypothesis::HYP_MISSING;
SMESH_Hypothesis::Hypothesis_Status status; SMESH_Hypothesis::Hypothesis_Status status;
algo->CheckHypothesis( aMesh, aSubMesh->GetSubShape(), status ); algo->CheckHypothesis( aMesh, aSubMesh->GetSubShape(), status );
if ( status == SMESH_Hypothesis::HYP_BAD_PARAMETER ) { if ( status == SMESH_Hypothesis::HYP_BAD_PARAMETER ) {
INFOS( "ERROR: hypothesis of " << (IsGlobalHypothesis ? "Global " : "Local ") INFOS( "ERROR: hypothesis of " << (IsGlobalHypothesis ? "Global " : "Local ")
<< "<" << algo->GetName() << "> has a bad parameter value"); << "<" << algo->GetName() << "> has a bad parameter value");
errName = SMESH_Gen::BAD_PARAM_VALUE; errName = SMESH_Hypothesis::HYP_BAD_PARAMETER;
} else { } else {
INFOS( "ERROR: " << (IsGlobalHypothesis ? "Global " : "Local ") INFOS( "ERROR: " << (IsGlobalHypothesis ? "Global " : "Local ")
<< "<" << algo->GetName() << "> misses some hypothesis"); << "<" << algo->GetName() << "> misses some hypothesis");
@ -607,7 +540,7 @@ bool SMESH_Gen::GetAlgoState(SMESH_Mesh& theMesh,
ret = false; ret = false;
INFOS( "None algorithm attached" ); INFOS( "None algorithm attached" );
theErrors.push_back( TAlgoStateError() ); theErrors.push_back( TAlgoStateError() );
theErrors.back().Set( MISSING_ALGO, 1, true ); theErrors.back().Set( SMESH_Hypothesis::HYP_MISSING, 1, true );
} }
return ret; return ret;

View File

@ -32,6 +32,7 @@
#include "Utils_SALOME_Exception.hxx" #include "Utils_SALOME_Exception.hxx"
#include "SMESH_Hypothesis.hxx" #include "SMESH_Hypothesis.hxx"
#include "SMESH_ComputeError.hxx"
#include "SMESH_Algo.hxx" #include "SMESH_Algo.hxx"
#include "SMESH_0D_Algo.hxx" #include "SMESH_0D_Algo.hxx"
#include "SMESH_1D_Algo.hxx" #include "SMESH_1D_Algo.hxx"
@ -45,6 +46,7 @@
#include <map> #include <map>
typedef SMESH_Hypothesis::Hypothesis_Status TAlgoStateErrorName;
typedef struct studyContextStruct typedef struct studyContextStruct
{ {
@ -59,23 +61,16 @@ class SMESH_Gen
SMESH_Gen(); SMESH_Gen();
~SMESH_Gen(); ~SMESH_Gen();
// SMESH_Hypothesis *CreateHypothesis(const char *anHyp, int studyId)
// throw(SALOME_Exception);
SMESH_Mesh* CreateMesh(int theStudyId, bool theIsEmbeddedMode) SMESH_Mesh* CreateMesh(int theStudyId, bool theIsEmbeddedMode)
throw(SALOME_Exception); throw(SALOME_Exception);
bool Compute(::SMESH_Mesh & aMesh, const TopoDS_Shape & aShape); bool Compute(::SMESH_Mesh & aMesh, const TopoDS_Shape & aShape);
bool Compute(::SMESH_subMesh& aSubMesh);
bool CheckAlgoState(SMESH_Mesh& aMesh, const TopoDS_Shape& aShape); bool CheckAlgoState(SMESH_Mesh& aMesh, const TopoDS_Shape& aShape);
// notify on bad state of attached algos, return false // notify on bad state of attached algos, return false
// if Compute() would fail because of some algo bad state // if Compute() would fail because of some algo bad state
enum TAlgoStateErrorName { NONE=0,
MISSING_ALGO,
MISSING_HYPO,
NOT_CONFORM_MESH,
BAD_PARAM_VALUE };
struct TAlgoStateError struct TAlgoStateError
{ {
TAlgoStateErrorName _name; TAlgoStateErrorName _name;
@ -83,7 +78,7 @@ class SMESH_Gen
int _algoDim; int _algoDim;
bool _isGlobalAlgo; bool _isGlobalAlgo;
TAlgoStateError(): _algoDim(0),_algo(0),_name(NONE) {} TAlgoStateError(): _algoDim(0),_algo(0),_name(SMESH_Hypothesis::HYP_OK) {}
void Set(TAlgoStateErrorName name, const SMESH_Algo* algo, bool isGlobal) void Set(TAlgoStateErrorName name, const SMESH_Algo* algo, bool isGlobal)
{ _name = name; _algo = algo; _algoDim = algo->GetDim(); _isGlobalAlgo = isGlobal; } { _name = name; _algo = algo; _algoDim = algo->GetDim(); _isGlobalAlgo = isGlobal; }
void Set(TAlgoStateErrorName name, const int algoDim, bool isGlobal) void Set(TAlgoStateErrorName name, const int algoDim, bool isGlobal)
@ -96,7 +91,6 @@ class SMESH_Gen
// if Compute() would fail because of some algo bad state // if Compute() would fail because of some algo bad state
// theErrors list contains problems description // theErrors list contains problems description
StudyContextStruct *GetStudyContext(int studyId); StudyContextStruct *GetStudyContext(int studyId);
static int GetShapeDim(const TopAbs_ShapeEnum & aShapeType); static int GetShapeDim(const TopAbs_ShapeEnum & aShapeType);

View File

@ -40,7 +40,7 @@ class SMESH_Hypothesis: public SMESHDS_Hypothesis
public: public:
enum Hypothesis_Status // in the order of severity enum Hypothesis_Status // in the order of severity
{ {
HYP_OK, HYP_OK = 0,
HYP_MISSING, // algo misses a hypothesis HYP_MISSING, // algo misses a hypothesis
HYP_CONCURENT, // several applicable hypotheses HYP_CONCURENT, // several applicable hypotheses
HYP_BAD_PARAMETER,// hypothesis has a bad parameter value HYP_BAD_PARAMETER,// hypothesis has a bad parameter value

View File

@ -414,11 +414,11 @@ SMESH_Hypothesis::Hypothesis_Status
// check concurent hypotheses on ansestors // check concurent hypotheses on ansestors
if (ret < SMESH_Hypothesis::HYP_CONCURENT && !isGlobalHyp ) if (ret < SMESH_Hypothesis::HYP_CONCURENT && !isGlobalHyp )
{ {
const map < int, SMESH_subMesh * >& smMap = subMesh->DependsOn(); SMESH_subMeshIteratorPtr smIt = subMesh->getDependsOnIterator(false,false);
map < int, SMESH_subMesh * >::const_iterator smIt = smMap.begin(); while ( smIt->more() ) {
for ( ; smIt != smMap.end(); smIt++ ) { SMESH_subMesh* sm = smIt->next();
if ( smIt->second->IsApplicableHypotesis( anHyp )) { if ( sm->IsApplicableHypotesis( anHyp )) {
ret2 = smIt->second->CheckConcurentHypothesis( anHyp->GetType() ); ret2 = sm->CheckConcurentHypothesis( anHyp->GetType() );
if (ret2 > ret) { if (ret2 > ret) {
ret = ret2; ret = ret2;
break; break;
@ -504,11 +504,11 @@ SMESH_Hypothesis::Hypothesis_Status
// check concurent hypotheses on ansestors // check concurent hypotheses on ansestors
if (ret < SMESH_Hypothesis::HYP_CONCURENT && !IsMainShape( aSubShape ) ) if (ret < SMESH_Hypothesis::HYP_CONCURENT && !IsMainShape( aSubShape ) )
{ {
const map < int, SMESH_subMesh * >& smMap = subMesh->DependsOn(); SMESH_subMeshIteratorPtr smIt = subMesh->getDependsOnIterator(false,false);
map < int, SMESH_subMesh * >::const_iterator smIt = smMap.begin(); while ( smIt->more() ) {
for ( ; smIt != smMap.end(); smIt++ ) { SMESH_subMesh* sm = smIt->next();
if ( smIt->second->IsApplicableHypotesis( anHyp )) { if ( sm->IsApplicableHypotesis( anHyp )) {
ret2 = smIt->second->CheckConcurentHypothesis( anHyp->GetType() ); ret2 = sm->CheckConcurentHypothesis( anHyp->GetType() );
if (ret2 > ret) { if (ret2 > ret) {
ret = ret2; ret = ret2;
break; break;
@ -815,12 +815,10 @@ SMESH_Mesh::GetSubMeshUsingHypothesis(SMESHDS_Hypothesis * anHyp)
//purpose : Say all submeshes using theChangedHyp that it has been modified //purpose : Say all submeshes using theChangedHyp that it has been modified
//======================================================================= //=======================================================================
void SMESH_Mesh::NotifySubMeshesHypothesisModification(const SMESH_Hypothesis* theChangedHyp) void SMESH_Mesh::NotifySubMeshesHypothesisModification(const SMESH_Hypothesis* hyp)
{ {
Unexpect aCatch(SalomeException); Unexpect aCatch(SalomeException);
const SMESH_Hypothesis* hyp = cSMESH_Hyp(theChangedHyp);
const SMESH_Algo *foundAlgo = 0; const SMESH_Algo *foundAlgo = 0;
SMESH_HypoFilter algoKind( SMESH_HypoFilter::IsAlgo() ); SMESH_HypoFilter algoKind( SMESH_HypoFilter::IsAlgo() );
SMESH_HypoFilter compatibleHypoKind; SMESH_HypoFilter compatibleHypoKind;

View File

@ -28,13 +28,15 @@
#include "SMESH_subMesh.hxx" #include "SMESH_subMesh.hxx"
#include "SMESH_subMeshEventListener.hxx"
#include "SMESH_Gen.hxx"
#include "SMESH_Mesh.hxx"
#include "SMESH_Hypothesis.hxx"
#include "SMESH_Algo.hxx" #include "SMESH_Algo.hxx"
#include "SMESH_Gen.hxx"
#include "SMESH_HypoFilter.hxx" #include "SMESH_HypoFilter.hxx"
#include "SMESH_Hypothesis.hxx"
#include "SMESH_Mesh.hxx"
#include "SMESH_MesherHelper.hxx" #include "SMESH_MesherHelper.hxx"
#include "SMESH_subMeshEventListener.hxx"
#include "SMESH_Comment.hxx"
#include "SMDS_SetIterator.hxx"
#include "utilities.h" #include "utilities.h"
#include "OpUtil.hxx" #include "OpUtil.hxx"
@ -72,7 +74,6 @@ SMESH_subMesh::SMESH_subMesh(int Id,
const TopoDS_Shape & aSubShape) const TopoDS_Shape & aSubShape)
{ {
_subShape = aSubShape; _subShape = aSubShape;
_meshDS = meshDS;
_subMeshDS = meshDS->MeshElements(_subShape); // may be null ... _subMeshDS = meshDS->MeshElements(_subShape); // may be null ...
_father = father; _father = father;
_Id = Id; _Id = Id;
@ -124,7 +125,7 @@ int SMESH_subMesh::GetId() const
SMESHDS_SubMesh * SMESH_subMesh::GetSubMeshDS() SMESHDS_SubMesh * SMESH_subMesh::GetSubMeshDS()
{ {
// submesh appears in DS only when a mesher set nodes and elements on a shape // submesh appears in DS only when a mesher set nodes and elements on a shape
return _subMeshDS ? _subMeshDS : _subMeshDS = _meshDS->MeshElements(_subShape); // may be null return _subMeshDS ? _subMeshDS : _subMeshDS = _father->GetMeshDS()->MeshElements(_subShape); // may be null
} }
//============================================================================= //=============================================================================
@ -135,9 +136,10 @@ SMESHDS_SubMesh * SMESH_subMesh::GetSubMeshDS()
SMESHDS_SubMesh* SMESH_subMesh::CreateSubMeshDS() SMESHDS_SubMesh* SMESH_subMesh::CreateSubMeshDS()
{ {
if ( !GetSubMeshDS() ) if ( !GetSubMeshDS() ) {
_meshDS->NewSubMesh( _meshDS->ShapeToIndex( _subShape ) ); SMESHDS_Mesh* meshDS = _father->GetMeshDS();
meshDS->NewSubMesh( meshDS->ShapeToIndex( _subShape ) );
}
return GetSubMeshDS(); return GetSubMeshDS();
} }
@ -149,27 +151,11 @@ SMESHDS_SubMesh* SMESH_subMesh::CreateSubMeshDS()
SMESH_subMesh *SMESH_subMesh::GetFirstToCompute() SMESH_subMesh *SMESH_subMesh::GetFirstToCompute()
{ {
const map < int, SMESH_subMesh * >&subMeshes = DependsOn(); SMESH_subMeshIteratorPtr smIt = getDependsOnIterator(true,false);
SMESH_subMesh *firstToCompute = 0; while ( smIt->more() ) {
SMESH_subMesh *sm = smIt->next();
map < int, SMESH_subMesh * >::const_iterator itsub; if ( sm->GetComputeState() == READY_TO_COMPUTE )
for (itsub = subMeshes.begin(); itsub != subMeshes.end(); itsub++) return sm;
{
SMESH_subMesh *sm = (*itsub).second;
bool readyToCompute = (sm->GetComputeState() == READY_TO_COMPUTE);
if (readyToCompute)
{
firstToCompute = sm;
break;
}
}
if (firstToCompute)
{
return firstToCompute; // a subMesh of this
}
if (_computeState == READY_TO_COMPUTE)
{
return this; // this
} }
return 0; // nothing to compute return 0; // nothing to compute
} }
@ -202,6 +188,7 @@ bool SMESH_subMesh::IsMeshComputed() const
// algo may bind a submesh not to _subShape, eg 3D algo // algo may bind a submesh not to _subShape, eg 3D algo
// sets nodes on SHELL while _subShape may be SOLID // sets nodes on SHELL while _subShape may be SOLID
SMESHDS_Mesh* meshDS = _father->GetMeshDS();
int dim = SMESH_Gen::GetShapeDim( _subShape ); int dim = SMESH_Gen::GetShapeDim( _subShape );
int type = _subShape.ShapeType(); int type = _subShape.ShapeType();
for ( ; type <= TopAbs_VERTEX; type++) { for ( ; type <= TopAbs_VERTEX; type++) {
@ -210,9 +197,12 @@ bool SMESH_subMesh::IsMeshComputed() const
TopExp_Explorer exp( _subShape, (TopAbs_ShapeEnum) type ); TopExp_Explorer exp( _subShape, (TopAbs_ShapeEnum) type );
for ( ; exp.More(); exp.Next() ) for ( ; exp.More(); exp.Next() )
{ {
SMESHDS_SubMesh * smDS = _meshDS->MeshElements( exp.Current() ); if ( SMESHDS_SubMesh * smDS = meshDS->MeshElements( exp.Current() ))
if ( smDS && ( smDS->NbElements() || smDS->NbNodes())) {
return true; bool computed = (dim > 0) ? smDS->NbElements() : smDS->NbNodes();
if ( computed )
return true;
}
} }
} }
else else
@ -230,17 +220,14 @@ bool SMESH_subMesh::IsMeshComputed() const
bool SMESH_subMesh::SubMeshesComputed() bool SMESH_subMesh::SubMeshesComputed()
{ {
//MESSAGE("SMESH_subMesh::SubMeshesComputed");
const map < int, SMESH_subMesh * >&subMeshes = DependsOn();
int myDim = SMESH_Gen::GetShapeDim( _subShape ); int myDim = SMESH_Gen::GetShapeDim( _subShape );
int dimToCheck = myDim - 1; int dimToCheck = myDim - 1;
bool subMeshesComputed = true; bool subMeshesComputed = true;
// check subMeshes with upper dimension => reverse iteration // check subMeshes with upper dimension => reverse iteration
map < int, SMESH_subMesh * >::const_reverse_iterator itsub; SMESH_subMeshIteratorPtr smIt = getDependsOnIterator(false,true);
for (itsub = subMeshes.rbegin(); itsub != subMeshes.rend(); itsub++) while ( smIt->more() )
{ {
SMESH_subMesh *sm = (*itsub).second; SMESH_subMesh *sm = smIt->next();
if ( sm->_alwaysComputed ) if ( sm->_alwaysComputed )
continue; continue;
const TopoDS_Shape & ss = sm->GetSubShape(); const TopoDS_Shape & ss = sm->GetSubShape();
@ -317,16 +304,12 @@ bool SMESH_subMesh::SubMeshesComputed()
bool SMESH_subMesh::SubMeshesReady() bool SMESH_subMesh::SubMeshesReady()
{ {
MESSAGE("SMESH_subMesh::SubMeshesReady");
const map < int, SMESH_subMesh * >&subMeshes = DependsOn();
bool subMeshesReady = true; bool subMeshesReady = true;
map < int, SMESH_subMesh * >::const_iterator itsub; SMESH_subMeshIteratorPtr smIt = getDependsOnIterator(false,true);
for (itsub = subMeshes.begin(); itsub != subMeshes.end(); itsub++) while ( smIt->more() ) {
{ SMESH_subMesh *sm = smIt->next();
SMESH_subMesh *sm = (*itsub).second; bool computeOk = (sm->GetComputeState() == COMPUTE_OK ||
bool computeOk = ((sm->GetComputeState() == COMPUTE_OK) sm->GetComputeState() == READY_TO_COMPUTE);
|| (sm->GetComputeState() == READY_TO_COMPUTE));
if (!computeOk) if (!computeOk)
{ {
subMeshesReady = false; subMeshesReady = false;
@ -349,7 +332,7 @@ bool SMESH_subMesh::SubMeshesReady()
*/ */
//============================================================================= //=============================================================================
const map < int, SMESH_subMesh * >&SMESH_subMesh::DependsOn() const map < int, SMESH_subMesh * >& SMESH_subMesh::DependsOn()
{ {
if (_dependenceAnalysed) if (_dependenceAnalysed)
return _mapDepend; return _mapDepend;
@ -567,8 +550,9 @@ SMESH_Hypothesis::Hypothesis_Status
SMESH_Hypothesis::Hypothesis_Status aux_ret, ret = SMESH_Hypothesis::HYP_OK; SMESH_Hypothesis::Hypothesis_Status aux_ret, ret = SMESH_Hypothesis::HYP_OK;
SMESH_Gen* gen =_father->GetGen(); SMESHDS_Mesh* meshDS =_father->GetMeshDS();
SMESH_Algo* algo = 0; SMESH_Gen* gen =_father->GetGen();
SMESH_Algo* algo = 0;
if (_subShape.ShapeType() == TopAbs_VERTEX ) if (_subShape.ShapeType() == TopAbs_VERTEX )
{ {
@ -621,7 +605,7 @@ SMESH_Hypothesis::Hypothesis_Status
if ( /*!anHyp->IsAuxiliary() &&*/ GetSimilarAttached( _subShape, anHyp ) ) if ( /*!anHyp->IsAuxiliary() &&*/ GetSimilarAttached( _subShape, anHyp ) )
return SMESH_Hypothesis::HYP_ALREADY_EXIST; return SMESH_Hypothesis::HYP_ALREADY_EXIST;
if ( !_meshDS->AddHypothesis(_subShape, anHyp)) if ( !meshDS->AddHypothesis(_subShape, anHyp))
return SMESH_Hypothesis::HYP_ALREADY_EXIST; return SMESH_Hypothesis::HYP_ALREADY_EXIST;
// Serve Propagation of 1D hypothesis // Serve Propagation of 1D hypothesis
@ -673,7 +657,7 @@ SMESH_Hypothesis::Hypothesis_Status
// -------------------------- // --------------------------
if (event == REMOVE_HYP || event == REMOVE_ALGO) if (event == REMOVE_HYP || event == REMOVE_ALGO)
{ {
if (!_meshDS->RemoveHypothesis(_subShape, anHyp)) if (!meshDS->RemoveHypothesis(_subShape, anHyp))
return SMESH_Hypothesis::HYP_OK; // nothing changes return SMESH_Hypothesis::HYP_OK; // nothing changes
// Serve Propagation of 1D hypothesis // Serve Propagation of 1D hypothesis
@ -750,7 +734,7 @@ SMESH_Hypothesis::Hypothesis_Status
if (algo->CheckHypothesis((*_father),_subShape, aux_ret)) if (algo->CheckHypothesis((*_father),_subShape, aux_ret))
SetAlgoState(HYP_OK); SetAlgoState(HYP_OK);
else if ( algo->IsStatusFatal( aux_ret )) { else if ( algo->IsStatusFatal( aux_ret )) {
_meshDS->RemoveHypothesis(_subShape, anHyp); meshDS->RemoveHypothesis(_subShape, anHyp);
ret = aux_ret; ret = aux_ret;
} }
else else
@ -803,10 +787,10 @@ SMESH_Hypothesis::Hypothesis_Status
if ( algo->CheckHypothesis((*_father),_subShape, ret )) if ( algo->CheckHypothesis((*_father),_subShape, ret ))
SetAlgoState(HYP_OK); SetAlgoState(HYP_OK);
if (SMESH_Hypothesis::IsStatusFatal( ret )) if (SMESH_Hypothesis::IsStatusFatal( ret ))
_meshDS->RemoveHypothesis(_subShape, anHyp); meshDS->RemoveHypothesis(_subShape, anHyp);
else if (!_father->IsUsedHypothesis( anHyp, this )) else if (!_father->IsUsedHypothesis( anHyp, this ))
{ {
_meshDS->RemoveHypothesis(_subShape, anHyp); meshDS->RemoveHypothesis(_subShape, anHyp);
ret = SMESH_Hypothesis::HYP_INCOMPATIBLE; ret = SMESH_Hypothesis::HYP_INCOMPATIBLE;
} }
break; break;
@ -817,7 +801,7 @@ SMESH_Hypothesis::Hypothesis_Status
if ( algo->CheckHypothesis((*_father),_subShape, aux_ret ))// ignore hyp status if ( algo->CheckHypothesis((*_father),_subShape, aux_ret ))// ignore hyp status
SetAlgoState(HYP_OK); SetAlgoState(HYP_OK);
else if ( algo->IsStatusFatal( aux_ret )) { else if ( algo->IsStatusFatal( aux_ret )) {
_meshDS->RemoveHypothesis(_subShape, anHyp); meshDS->RemoveHypothesis(_subShape, anHyp);
ret = aux_ret; ret = aux_ret;
} }
else else
@ -905,7 +889,7 @@ SMESH_Hypothesis::Hypothesis_Status
if (SMESH_Hypothesis::IsStatusFatal( ret )) if (SMESH_Hypothesis::IsStatusFatal( ret ))
{ {
MESSAGE("do not add extra hypothesis"); MESSAGE("do not add extra hypothesis");
_meshDS->RemoveHypothesis(_subShape, anHyp); meshDS->RemoveHypothesis(_subShape, anHyp);
} }
else else
{ {
@ -1151,20 +1135,15 @@ SMESH_Hypothesis::Hypothesis_Status
SMESH_subMesh::SubMeshesAlgoStateEngine(int event, SMESH_subMesh::SubMeshesAlgoStateEngine(int event,
SMESH_Hypothesis * anHyp) SMESH_Hypothesis * anHyp)
{ {
//MESSAGE("SMESH_subMesh::SubMeshesAlgoStateEngine");
SMESH_Hypothesis::Hypothesis_Status ret = SMESH_Hypothesis::HYP_OK; SMESH_Hypothesis::Hypothesis_Status ret = SMESH_Hypothesis::HYP_OK;
//EAP: a wire (dim==1) should notify edges (dim==1) //EAP: a wire (dim==1) should notify edges (dim==1)
//EAP: int dim = SMESH_Gen::GetShapeDim(_subShape); //EAP: int dim = SMESH_Gen::GetShapeDim(_subShape);
if (_subShape.ShapeType() < TopAbs_EDGE ) // wire,face etc if (_subShape.ShapeType() < TopAbs_EDGE ) // wire,face etc
{ {
const map < int, SMESH_subMesh * >&subMeshes = DependsOn(); SMESH_subMeshIteratorPtr smIt = getDependsOnIterator(false,false);
while ( smIt->more() ) {
map < int, SMESH_subMesh * >::const_iterator itsub;
for (itsub = subMeshes.begin(); itsub != subMeshes.end(); itsub++)
{
SMESH_subMesh *sm = (*itsub).second;
SMESH_Hypothesis::Hypothesis_Status ret2 = SMESH_Hypothesis::Hypothesis_Status ret2 =
sm->AlgoStateEngine(event, anHyp); smIt->next()->AlgoStateEngine(event, anHyp);
if ( ret2 > ret ) if ( ret2 > ret )
ret = ret2; ret = ret2;
} }
@ -1180,15 +1159,9 @@ SMESH_Hypothesis::Hypothesis_Status
void SMESH_subMesh::CleanDependsOn() void SMESH_subMesh::CleanDependsOn()
{ {
//MESSAGE("SMESH_subMesh::CleanDependsOn"); SMESH_subMeshIteratorPtr smIt = getDependsOnIterator(false,false);
while ( smIt->more() )
const map < int, SMESH_subMesh * >&dependson = DependsOn(); smIt->next()->ComputeStateEngine(CLEAN);
map < int, SMESH_subMesh * >::const_iterator its;
for (its = dependson.begin(); its != dependson.end(); its++)
{
SMESH_subMesh *sm = (*its).second;
sm->ComputeStateEngine(CLEAN);
}
} }
//============================================================================= //=============================================================================
@ -1267,8 +1240,10 @@ static void cleanSubMesh( SMESH_subMesh * subMesh )
while (itn->more()) { while (itn->more()) {
const SMDS_MeshNode * node = itn->next(); const SMDS_MeshNode * node = itn->next();
//MESSAGE( " RM node: "<<node->GetID()); //MESSAGE( " RM node: "<<node->GetID());
//meshDS->RemoveNode(node); if ( node->NbInverseNodes() == 0 )
meshDS->RemoveFreeNode(node, subMeshDS); meshDS->RemoveFreeNode(node, subMeshDS);
else // for StdMeshers_CompositeSegment_1D: node in one submesh, edge in another
meshDS->RemoveNode(node);
} }
} }
} }
@ -1282,16 +1257,27 @@ static void cleanSubMesh( SMESH_subMesh * subMesh )
bool SMESH_subMesh::ComputeStateEngine(int event) bool SMESH_subMesh::ComputeStateEngine(int event)
{ {
_computeError.reset();
//MESSAGE("SMESH_subMesh::ComputeStateEngine"); //MESSAGE("SMESH_subMesh::ComputeStateEngine");
//SCRUTE(_computeState); //SCRUTE(_computeState);
//SCRUTE(event); //SCRUTE(event);
if (_subShape.ShapeType() == TopAbs_VERTEX) if (_subShape.ShapeType() == TopAbs_VERTEX)
{ {
if ( IsMeshComputed() ) _computeState = READY_TO_COMPUTE;
SMESHDS_SubMesh* smDS = GetSubMeshDS();
if ( smDS && smDS->NbNodes() ) {
_computeState = COMPUTE_OK; _computeState = COMPUTE_OK;
else }
_computeState = READY_TO_COMPUTE; else if ( event == COMPUTE && !_alwaysComputed ) {
const TopoDS_Vertex & V = TopoDS::Vertex( _subShape );
gp_Pnt P = BRep_Tool::Pnt(V);
if ( SMDS_MeshNode * n = _father->GetMeshDS()->AddNode(P.X(), P.Y(), P.Z()) ) {
_father->GetMeshDS()->SetNodeOnVertex(n,_Id);
_computeState = COMPUTE_OK;
}
}
if ( event == MODIF_ALGO_STATE ) if ( event == MODIF_ALGO_STATE )
CleanDependants(); CleanDependants();
return true; return true;
@ -1369,69 +1355,87 @@ bool SMESH_subMesh::ComputeStateEngine(int event)
break; break;
} }
// check submeshes needed // check submeshes needed
if (_father->HasShapeToMesh() && algo->NeedDescretBoundary()) if (_father->HasShapeToMesh() ) {
ret = SubMeshesComputed(); bool subComputed = SubMeshesComputed();
if (!ret) ret = ( algo->NeedDescretBoundary() ? subComputed :
{ ( _father->IsNotConformAllowed() || !subComputed ));
MESSAGE("Some SubMeshes not computed"); if (!ret) {
_computeState = FAILED_TO_COMPUTE; _computeState = FAILED_TO_COMPUTE;
break; if ( !algo->NeedDescretBoundary() )
_computeError =
SMESH_ComputeError::New(COMPERR_BAD_INPUT_MESH,"Unexpected submesh",algo);
break;
}
} }
// compute // compute
CleanDependants(); CleanDependants();
RemoveSubMeshElementsAndNodes(); RemoveSubMeshElementsAndNodes();
{ ret = false;
try { _computeState = FAILED_TO_COMPUTE;
_computeError = SMESH_ComputeError::New(COMPERR_EXCEPTION,"",algo);
try {
#if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
OCC_CATCH_SIGNALS; OCC_CATCH_SIGNALS;
#endif #endif
if ( !_father->HasShapeToMesh() ) // no shape algo->InitComputeError();
{ if ( !_father->HasShapeToMesh() ) // no shape
SMESH_MesherHelper helper( *_father ); {
helper.SetSubShape( _subShape ); SMESH_MesherHelper helper( *_father );
helper.SetElementsOnShape( true ); helper.SetSubShape( _subShape );
ret = algo->Compute(*_father, &helper ); helper.SetElementsOnShape( true );
} ret = algo->Compute(*_father, &helper );
else {
if (!algo->NeedDescretBoundary() && !algo->OnlyUnaryInput())
ret = ApplyToCollection( algo, GetCollection( gen, algo ) );
else
ret = algo->Compute((*_father), _subShape);
}
} }
catch (Standard_Failure) { else
MESSAGE( "Exception in algo->Compute() "); {
ret = false; if (!algo->NeedDescretBoundary() && !algo->OnlyUnaryInput())
} ret = ApplyToCollection( algo, GetCollection( gen, algo ) );
} else
ret = algo->Compute((*_father), _subShape);
}
_computeError = algo->GetComputeError();
}
catch (Standard_Failure& exc) {
if ( !_computeError ) _computeError = SMESH_ComputeError::New();
_computeError->myName = COMPERR_OCC_EXCEPTION;
_computeError->myComment = exc.GetMessageString();
}
catch ( SALOME_Exception& S_ex ) {
if ( !_computeError ) _computeError = SMESH_ComputeError::New();
_computeError->myName = COMPERR_SLM_EXCEPTION;
_computeError->myComment = S_ex.what();
}
catch ( std::bad_alloc& exc ) {
if ( _computeError ) {
_computeError->myName = COMPERR_MEMORY_PB;
_computeError->myComment = exc.what();
}
throw exc;
}
catch ( std::exception& exc ) {
if ( !_computeError ) _computeError = SMESH_ComputeError::New();
_computeError->myName = COMPERR_STD_EXCEPTION;
_computeError->myComment = exc.what();
}
if ( ret && _computeError && !_computeError->IsOK() ) {
ret = false;
}
if (ret) { // check if anything was built
ret = ( GetSubMeshDS() && ( GetSubMeshDS()->NbElements() || GetSubMeshDS()->NbNodes() ));
}
if (!ret) if (!ret)
{ {
MESSAGE("problem in algo execution: failed to compute"); // Set _computeError
// release ALGO from responsibilty of partially built mesh if ( !_computeError )
RemoveSubMeshElementsAndNodes(); _computeError = SMESH_ComputeError::New();
_computeState = FAILED_TO_COMPUTE; if ( _computeError->IsOK() )
if (!algo->NeedDescretBoundary()) _computeError->myName = COMPERR_ALGO_FAILED;
UpdateSubMeshState( FAILED_TO_COMPUTE );
#ifdef _DEBUG_
// Show vertices location of a failed shape
cout << algo->GetName() << " failed on shape with the following vertices:" << endl;
TopTools_IndexedMapOfShape vMap;
TopExp::MapShapes( _subShape, TopAbs_VERTEX, vMap );
for ( int iv = 1; iv <= vMap.Extent(); ++iv ) {
gp_Pnt P( BRep_Tool::Pnt( TopoDS::Vertex( vMap( iv ) )));
cout << P.X() << " " << P.Y() << " " << P.Z() << " " << endl;
}
#endif
break;
} }
else else
{ {
_computeState = COMPUTE_OK; _computeError.reset();
UpdateDependantsState( SUBMESH_COMPUTED ); // send event SUBMESH_COMPUTED UpdateDependantsState( SUBMESH_COMPUTED ); // send event SUBMESH_COMPUTED
if (!algo->NeedDescretBoundary())
UpdateSubMeshState( COMPUTE_OK );
} }
CheckComputeError( algo );
} }
break; break;
case CLEAN: case CLEAN:
@ -1532,10 +1536,6 @@ bool SMESH_subMesh::ComputeStateEngine(int event)
case CLEAN: case CLEAN:
CleanDependants(); // submeshes dependent on me should be cleaned as well CleanDependants(); // submeshes dependent on me should be cleaned as well
RemoveSubMeshElementsAndNodes(); RemoveSubMeshElementsAndNodes();
if (_algoState == HYP_OK)
_computeState = READY_TO_COMPUTE;
else
_computeState = NOT_READY;
break; break;
case SUBMESH_COMPUTED: // allow retry compute case SUBMESH_COMPUTED: // allow retry compute
if (_algoState == HYP_OK) if (_algoState == HYP_OK)
@ -1574,6 +1574,59 @@ bool SMESH_subMesh::ComputeStateEngine(int event)
return ret; return ret;
} }
//=======================================================================
/*!
* \brief Update compute_state by _computeError
*/
//=======================================================================
bool SMESH_subMesh::CheckComputeError(SMESH_Algo* theAlgo)
{
bool noErrors = ( !_computeError || _computeError->IsOK() );
if ( !noErrors )
{
if ( !_computeError->myAlgo )
_computeError->myAlgo = theAlgo;
// Show error
SMESH_Comment text;
text << theAlgo->GetName() << " failed on subshape " << _Id << " with error ";
if (_computeError->IsCommon() )
text << _computeError->CommonName();
else
text << _computeError->myName;
if ( _computeError->myComment.size() > 0 )
text << " \"" << _computeError->myComment << "\"";
#ifdef _DEBUG_
cout << text << endl;
// Show vertices location of a failed shape
cout << "Subshape vertices (first 10):" << endl;
TopTools_IndexedMapOfShape vMap;
TopExp::MapShapes( _subShape, TopAbs_VERTEX, vMap );
for ( int iv = 1; iv <= vMap.Extent() && iv < 11; ++iv ) {
gp_Pnt P( BRep_Tool::Pnt( TopoDS::Vertex( vMap( iv ) )));
cout << P.X() << " " << P.Y() << " " << P.Z() << " " << endl;
}
#else
INFOS( text );
#endif
_computeState = FAILED_TO_COMPUTE;
}
else
{
_computeState = COMPUTE_OK;
}
// Check state of submeshes
if ( !theAlgo->NeedDescretBoundary() && theAlgo->OnlyUnaryInput() ) {
SMESH_subMeshIteratorPtr smIt = getDependsOnIterator(false,false);
while ( smIt->more() )
if ( !smIt->next()->CheckComputeError( theAlgo ))
noErrors = false;
}
return noErrors;
}
//======================================================================= //=======================================================================
//function : ApplyToCollection //function : ApplyToCollection
//purpose : Apply theAlgo to all subshapes in theCollection //purpose : Apply theAlgo to all subshapes in theCollection
@ -1585,32 +1638,26 @@ bool SMESH_subMesh::ApplyToCollection (SMESH_Algo* theAlgo,
MESSAGE("SMESH_subMesh::ApplyToCollection"); MESSAGE("SMESH_subMesh::ApplyToCollection");
ASSERT ( !theAlgo->NeedDescretBoundary() ); ASSERT ( !theAlgo->NeedDescretBoundary() );
bool ret = false; if ( _computeError )
_computeError->myName = COMPERR_OK;
bool ok = theAlgo->Compute( *_father, theCollection );
ret = theAlgo->Compute( *_father, theCollection );
// set _computeState of subshapes // set _computeState of subshapes
bool localOK = true;
TopExp_Explorer anExplorer( theCollection, _subShape.ShapeType() ); TopExp_Explorer anExplorer( theCollection, _subShape.ShapeType() );
for ( ; anExplorer.More(); anExplorer.Next() ) for ( ; anExplorer.More(); anExplorer.Next() )
{ {
const TopoDS_Shape& aSubShape = anExplorer.Current(); if ( SMESH_subMesh* subMesh = _father->GetSubMeshContaining( anExplorer.Current() ))
SMESH_subMesh* subMesh = _father->GetSubMeshContaining( aSubShape );
if ( subMesh )
{ {
if (ret) if ( !subMesh->CheckComputeError( theAlgo ))
{ localOK = false;
subMesh->_computeState = COMPUTE_OK;
subMesh->UpdateDependantsState( SUBMESH_COMPUTED );
subMesh->UpdateSubMeshState( COMPUTE_OK );
}
else
{
subMesh->_computeState = FAILED_TO_COMPUTE;
}
} }
} }
return ret; if ( !ok && localOK )
return false; // store error in this subMesh
return ( this->_computeState == COMPUTE_OK );
} }
@ -1621,13 +1668,9 @@ bool SMESH_subMesh::ApplyToCollection (SMESH_Algo* theAlgo,
void SMESH_subMesh::UpdateSubMeshState(const compute_state theState) void SMESH_subMesh::UpdateSubMeshState(const compute_state theState)
{ {
const map<int, SMESH_subMesh*>& smMap = DependsOn(); SMESH_subMeshIteratorPtr smIt = getDependsOnIterator(false,false);
map<int, SMESH_subMesh*>::const_iterator itsub; while ( smIt->more() )
for (itsub = smMap.begin(); itsub != smMap.end(); itsub++) smIt->next()->_computeState = theState;
{
SMESH_subMesh* sm = (*itsub).second;
sm->_computeState = theState;
}
} }
//======================================================================= //=======================================================================
@ -1637,13 +1680,9 @@ void SMESH_subMesh::UpdateSubMeshState(const compute_state theState)
void SMESH_subMesh::ComputeSubMeshStateEngine(int event) void SMESH_subMesh::ComputeSubMeshStateEngine(int event)
{ {
const map<int, SMESH_subMesh*>& smMap = DependsOn(); SMESH_subMeshIteratorPtr smIt = getDependsOnIterator(false,false);
map<int, SMESH_subMesh*>::const_iterator itsub; while ( smIt->more() )
for (itsub = smMap.begin(); itsub != smMap.end(); itsub++) smIt->next()->ComputeStateEngine(event);
{
SMESH_subMesh* sm = (*itsub).second;
sm->ComputeStateEngine(event);
}
} }
//======================================================================= //=======================================================================
@ -1752,14 +1791,17 @@ TopoDS_Shape SMESH_subMesh::GetCollection(SMESH_Gen * theGen, SMESH_Algo* theAlg
{ {
const TopoDS_Shape& S = anExplorer.Current(); const TopoDS_Shape& S = anExplorer.Current();
SMESH_subMesh* subMesh = _father->GetSubMesh( S ); SMESH_subMesh* subMesh = _father->GetSubMesh( S );
SMESH_Algo* anAlgo = theGen->GetAlgo( *_father, S ); if ( subMesh == this )
if (subMesh->GetComputeState() == READY_TO_COMPUTE &&
anAlgo == theAlgo &&
anAlgo->GetUsedHypothesis( *_father, S, ignoreAuxiliaryHyps ) == aUsedHyp)
{ {
aBuilder.Add( aCompound, S ); aBuilder.Add( aCompound, S );
} }
else if ( subMesh->GetComputeState() == READY_TO_COMPUTE )
{
SMESH_Algo* anAlgo = theGen->GetAlgo( *_father, S );
if (anAlgo == theAlgo &&
anAlgo->GetUsedHypothesis( *_father, S, ignoreAuxiliaryHyps ) == aUsedHyp)
aBuilder.Add( aCompound, S );
}
} }
return aCompound; return aCompound;
@ -1969,7 +2011,7 @@ void SMESH_subMeshEventListener::ProcessEvent(const int event,
const int eventType, const int eventType,
SMESH_subMesh* subMesh, SMESH_subMesh* subMesh,
EventListenerData* data, EventListenerData* data,
SMESH_Hypothesis* /*hyp*/) const SMESH_Hypothesis* /*hyp*/)
{ {
if ( data && !data->mySubMeshes.empty() && if ( data && !data->mySubMeshes.empty() &&
eventType == SMESH_subMesh::COMPUTE_EVENT) eventType == SMESH_subMesh::COMPUTE_EVENT)
@ -1987,3 +2029,69 @@ void SMESH_subMeshEventListener::ProcessEvent(const int event,
} }
} }
} }
namespace {
//================================================================================
/*!
* \brief Iterator over submeshes and optionally prepended or appended one
*/
//================================================================================
struct _Iterator : public SMDS_Iterator<SMESH_subMesh*>
{
_Iterator(SMDS_Iterator<SMESH_subMesh*>* subIt,
SMESH_subMesh* prepend,
SMESH_subMesh* append): myIt(subIt),myAppend(append)
{
myCur = prepend ? prepend : myIt->more() ? myIt->next() : 0;
}
/// Return true if and only if there are other object in this iterator
virtual bool more()
{
return myCur;
}
/// Return the current object and step to the next one
virtual SMESH_subMesh* next()
{
SMESH_subMesh* res = myCur;
if ( myIt->more() ) { myCur = myIt->next(); }
else { myCur = myAppend; myAppend = 0; }
return res;
}
/// ~
~_Iterator()
{ delete myIt; }
///
SMESH_subMesh *myAppend, *myCur;
SMDS_Iterator<SMESH_subMesh*> *myIt;
};
}
//================================================================================
/*!
* \brief Return iterator on the submeshes this one depends on
* \param includeSelf - this submesh to be returned also
* \param reverse - if true, complex shape submeshes go first
*/
//================================================================================
SMESH_subMeshIteratorPtr SMESH_subMesh::getDependsOnIterator(const bool includeSelf,
const bool reverse)
{
SMESH_subMesh *prepend=0, *append=0;
if ( includeSelf ) {
if ( reverse ) prepend = this;
else append = this;
}
typedef map < int, SMESH_subMesh * > TMap;
if ( reverse )
{
return SMESH_subMeshIteratorPtr
( new _Iterator( new SMDS_mapReverseIterator<TMap>( DependsOn() ), prepend, append ));
}
{
return SMESH_subMeshIteratorPtr
( new _Iterator( new SMDS_mapIterator<TMap>( DependsOn() ), prepend, append ));
}
}

View File

@ -32,12 +32,12 @@
#include "SMESHDS_Mesh.hxx" #include "SMESHDS_Mesh.hxx"
#include "SMESHDS_SubMesh.hxx" #include "SMESHDS_SubMesh.hxx"
#include "SMESH_Hypothesis.hxx" #include "SMESH_Hypothesis.hxx"
#include "Utils_SALOME_Exception.hxx" #include "SMESH_ComputeError.hxx"
#include <TopoDS_Shape.hxx>
#include <TColStd_IndexedMapOfTransient.hxx> #include "Utils_SALOME_Exception.hxx"
#include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
#include <TopoDS_Shape.hxx>
#include <set>
#include <list> #include <list>
#include <map> #include <map>
@ -47,10 +47,14 @@ class SMESH_Algo;
class SMESH_Gen; class SMESH_Gen;
class SMESH_subMeshEventListener; class SMESH_subMeshEventListener;
class SMESH_subMeshEventListenerData; class SMESH_subMeshEventListenerData;
class SMESH_subMesh;
typedef SMESH_subMeshEventListener EventListener; typedef SMESH_subMeshEventListener EventListener;
typedef SMESH_subMeshEventListenerData EventListenerData; typedef SMESH_subMeshEventListenerData EventListenerData;
typedef boost::shared_ptr< SMDS_Iterator<SMESH_subMesh*> > SMESH_subMeshIteratorPtr;
class SMESH_subMesh class SMESH_subMesh
{ {
public: public:
@ -60,9 +64,6 @@ class SMESH_subMesh
int GetId() const; int GetId() const;
// bool Contains(const TopoDS_Shape & aSubShape)
// throw (SALOME_Exception);
SMESH_Mesh* GetFather() { return _father; } SMESH_Mesh* GetFather() { return _father; }
SMESHDS_SubMesh * GetSubMeshDS(); SMESHDS_SubMesh * GetSubMeshDS();
@ -72,8 +73,13 @@ class SMESH_subMesh
SMESH_subMesh *GetFirstToCompute(); SMESH_subMesh *GetFirstToCompute();
const map < int, SMESH_subMesh * >&DependsOn(); const map < int, SMESH_subMesh * >& DependsOn();
//const map < int, SMESH_subMesh * >&Dependants(); //const map < int, SMESH_subMesh * >&Dependants();
/*!
* \brief Return iterator on the submeshes this one depends on
*/
SMESH_subMeshIteratorPtr getDependsOnIterator(const bool includeSelf,
const bool complexShapeFirst);
const TopoDS_Shape & GetSubShape() const; const TopoDS_Shape & GetSubShape() const;
@ -179,6 +185,7 @@ public:
int GetAlgoState() const { return _algoState; } int GetAlgoState() const { return _algoState; }
int GetComputeState() const { return _computeState; }; int GetComputeState() const { return _computeState; };
SMESH_ComputeErrorPtr& GetComputeError() { return _computeError; }
void DumpAlgoState(bool isMain); void DumpAlgoState(bool isMain);
@ -211,6 +218,7 @@ public:
*/ */
void SetIsAlwaysComputed(bool isAlCo); void SetIsAlwaysComputed(bool isAlCo);
protected: protected:
// ================================================================== // ==================================================================
void InsertDependence(const TopoDS_Shape aSubShape); void InsertDependence(const TopoDS_Shape aSubShape);
@ -227,38 +235,54 @@ protected:
void CleanDependsOn(); void CleanDependsOn();
void SetAlgoState(int state); void SetAlgoState(int state);
/*!
* \brief Return a shape containing all sub-shapes of the MainShape that can be
* meshed at once along with _subShape
*/
TopoDS_Shape GetCollection(SMESH_Gen * theGen, SMESH_Algo* theAlgo); TopoDS_Shape GetCollection(SMESH_Gen * theGen, SMESH_Algo* theAlgo);
// return a shape containing all sub-shapes of the MainShape that can be
// meshed at once along with _subShape
/*!
* \brief Apply theAlgo to all subshapes in theCollection
*/
bool ApplyToCollection (SMESH_Algo* theAlgo, bool ApplyToCollection (SMESH_Algo* theAlgo,
const TopoDS_Shape& theCollection); const TopoDS_Shape& theCollection);
// Apply theAlgo to all subshapes in theCollection
/*!
* \brief Update compute_state by _computeError
* \retval bool - false if there are errors
*/
bool CheckComputeError(SMESH_Algo* theAlgo);
/*!
* \brief Return a hypothesis attached to theShape.
*
* If theHyp is provided, similar but not same hypotheses
* is returned; else an applicable ones having theHypType
* is returned
*/
const SMESH_Hypothesis* GetSimilarAttached(const TopoDS_Shape& theShape, const SMESH_Hypothesis* GetSimilarAttached(const TopoDS_Shape& theShape,
const SMESH_Hypothesis * theHyp, const SMESH_Hypothesis * theHyp,
const int theHypType = 0); const int theHypType = 0);
// return a hypothesis attached to theShape. //
// If theHyp is provided, similar but not same hypotheses
// is returned; else an applicable ones having theHypType protected:
// is returned
TopoDS_Shape _subShape;
SMESHDS_SubMesh * _subMeshDS;
SMESH_Mesh * _father;
int _Id;
TopoDS_Shape _subShape;
SMESHDS_Mesh * _meshDS;
SMESHDS_SubMesh * _subMeshDS;
int _Id;
SMESH_Mesh *_father;
map < int, SMESH_subMesh * >_mapDepend; map < int, SMESH_subMesh * >_mapDepend;
bool _dependenceAnalysed; bool _dependenceAnalysed;
int _algoState; int _algoState;
int _computeState; int _computeState;
SMESH_ComputeErrorPtr _computeError;
// allow algo->Compute() if a subshape of lower dim is meshed but // allow algo->Compute() if a subshape of lower dim is meshed but
// none mesh entity is bound to it. Eg StdMeshers_CompositeSegment_1D can // none mesh entity is bound to it. Eg StdMeshers_CompositeSegment_1D can
// mesh several edges as a whole and leave some of them without mesh entities // mesh several edges as a whole and leave some of them without mesh entities
bool _alwaysComputed; bool _alwaysComputed;
}; };

View File

@ -62,7 +62,7 @@ public:
const int eventType, const int eventType,
SMESH_subMesh* subMesh, SMESH_subMesh* subMesh,
SMESH_subMeshEventListenerData* data, SMESH_subMeshEventListenerData* data,
SMESH_Hypothesis* hyp = 0); const SMESH_Hypothesis* hyp = 0);
}; };
// ------------------------------------------------------------------ // ------------------------------------------------------------------