-// Copyright (C) 2007-2013 CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015 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.
+// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
#include <BRep_Builder.hxx>
#include <BRep_Tool.hxx>
#include <TopExp.hxx>
+#include <TopExp_Explorer.hxx>
#include <TopTools_IndexedMapOfShape.hxx>
#include <TopTools_ListIteratorOfListOfShape.hxx>
+#include <TopTools_ListOfShape.hxx>
#include <TopoDS.hxx>
#include <TopoDS_Compound.hxx>
-#include <gp_Pnt.hxx>
-#include <TopExp_Explorer.hxx>
#include <TopoDS_Iterator.hxx>
+#include <gp_Pnt.hxx>
#include <Standard_OutOfMemory.hxx>
#include <Standard_ErrorHandler.hxx>
SMESH_subMesh::~SMESH_subMesh()
{
- MESSAGE("SMESH_subMesh::~SMESH_subMesh");
- // ****
deleteOwnListeners();
}
SMESH_Algo* SMESH_subMesh::GetAlgo() const
{
if ( !_algo )
- ((SMESH_subMesh*)this)->_algo = _father->GetGen()->GetAlgo(*_father, _subShape);
+ {
+ SMESH_subMesh* me = const_cast< SMESH_subMesh* >( this );
+ me->_algo = _father->GetGen()->GetAlgo( me );
+ }
return _algo;
}
int computeCost;
switch ( _subShape.ShapeType() ) {
case TopAbs_SOLID:
- case TopAbs_SHELL: computeCost = 1000; break;
- case TopAbs_FACE: computeCost = 100; break;
- case TopAbs_EDGE: computeCost = 10; break;
+ case TopAbs_SHELL: computeCost = 5000; break;
+ case TopAbs_FACE: computeCost = 500; break;
+ case TopAbs_EDGE: computeCost = 2; break;
default: computeCost = 1;
}
SMESH_subMeshIteratorPtr childIt = getDependsOnIterator(/*includeSelf=*/false);
//=============================================================================
/*!
- *
- */
-//=============================================================================
-
-// bool SMESH_subMesh::SubMeshesReady()
-// {
-// bool subMeshesReady = true;
-// SMESH_subMeshIteratorPtr smIt = getDependsOnIterator(false,true);
-// while ( smIt->more() ) {
-// SMESH_subMesh *sm = smIt->next();
-// bool computeOk = (sm->GetComputeState() == COMPUTE_OK ||
-// sm->GetComputeState() == READY_TO_COMPUTE);
-// if (!computeOk)
-// {
-// subMeshesReady = false;
-// SCRUTE(sm->GetId());
-// break;
-// }
-// }
-// return subMeshesReady;
-// }
-
-//=============================================================================
-/*!
- * Construct dependence on first level subMeshes. complex shapes (compsolid,
- * shell, wire) are not analysed the same way as simple shapes (solid, face,
- * edge).
- * For collection shapes (compsolid, shell, wire) prepare a list of submeshes
- * with possible multiples occurences. Multiples occurences corresponds to
- * internal frontiers within shapes of the collection and must not be keeped.
- * See FinalizeDependence.
+ * Returns all sub-meshes this one depend on
*/
//=============================================================================
const map < int, SMESH_subMesh * >& SMESH_subMesh::DependsOn()
{
- if (_dependenceAnalysed)
+ if ( _dependenceAnalysed || !_father->HasShapeToMesh() )
return _mapDepend;
- //MESSAGE("SMESH_subMesh::DependsOn");
-
int type = _subShape.ShapeType();
- //SCRUTE(type);
switch (type)
{
case TopAbs_COMPOUND:
+ {
+ list< TopoDS_Shape > compounds( 1, _subShape );
+ list< TopoDS_Shape >::iterator comp = compounds.begin();
+ for ( ; comp != compounds.end(); ++comp )
{
- //MESSAGE("compound");
- for (TopExp_Explorer exp(_subShape, TopAbs_SOLID); exp.More();exp.Next())
- {
- insertDependence(exp.Current());
- }
- for (TopExp_Explorer exp(_subShape, TopAbs_SHELL, TopAbs_SOLID); exp.More(); exp.Next())
- {
- if ( BRep_Tool::IsClosed(exp.Current() ))
- insertDependence(exp.Current()); //only shell not in solid
- else
- for (TopExp_Explorer expF(exp.Current(), TopAbs_FACE); expF.More();expF.Next())
- insertDependence(expF.Current()); // issue 0020959: HEXA_3D fails on shell
-
- }
- for (TopExp_Explorer exp(_subShape, TopAbs_FACE, TopAbs_SHELL); exp.More();exp.Next())
- {
- insertDependence(exp.Current());
- }
- for (TopExp_Explorer exp(_subShape, TopAbs_EDGE, TopAbs_FACE); exp.More();exp.Next())
- {
- insertDependence(exp.Current());
- }
- for (TopExp_Explorer exp(_subShape, TopAbs_VERTEX, TopAbs_EDGE); exp.More();exp.Next())
- {
- insertDependence(exp.Current());
- }
- break;
- }
- case TopAbs_COMPSOLID:
- {
- //MESSAGE("compsolid");
- for (TopExp_Explorer exp(_subShape, TopAbs_SOLID); exp.More(); exp.Next())
- {
- insertDependence(exp.Current());
- }
- break;
- }
- case TopAbs_SHELL:
- {
- //MESSAGE("shell");
- for (TopExp_Explorer exp(_subShape, TopAbs_FACE); exp.More(); exp.Next())
- {
- insertDependence(exp.Current());
- }
- break;
- }
- case TopAbs_WIRE:
- {
- //MESSAGE("wire");
- for (TopExp_Explorer exp(_subShape, TopAbs_EDGE); exp.More(); exp.Next())
- {
- insertDependence(exp.Current());
- }
- break;
- }
- case TopAbs_SOLID:
- {
- //MESSAGE("solid");
- if(_father->HasShapeToMesh()) {
- for (TopExp_Explorer exp(_subShape, TopAbs_FACE); exp.More();exp.Next())
+ for ( TopoDS_Iterator sub( *comp ); sub.More(); sub.Next() )
+ switch ( sub.Value().ShapeType() )
{
- insertDependence(exp.Current());
+ case TopAbs_COMPOUND: compounds.push_back( sub.Value() ); break;
+ case TopAbs_COMPSOLID: insertDependence( sub.Value(), TopAbs_SOLID ); break;
+ case TopAbs_SOLID: insertDependence( sub.Value(), TopAbs_SOLID ); break;
+ case TopAbs_SHELL: insertDependence( sub.Value(), TopAbs_FACE ); break;
+ case TopAbs_FACE: insertDependence( sub.Value(), TopAbs_FACE ); break;
+ case TopAbs_WIRE: insertDependence( sub.Value(), TopAbs_EDGE ); break;
+ case TopAbs_EDGE: insertDependence( sub.Value(), TopAbs_EDGE ); break;
+ case TopAbs_VERTEX: insertDependence( sub.Value(), TopAbs_VERTEX ); break;
+ default:;
}
- }
- break;
- }
- case TopAbs_FACE:
- {
- //MESSAGE("face");
- for (TopExp_Explorer exp(_subShape, TopAbs_EDGE); exp.More();exp.Next())
- {
- insertDependence(exp.Current());
- }
- break;
- }
- case TopAbs_EDGE:
- {
- //MESSAGE("edge");
- for (TopExp_Explorer exp(_subShape, TopAbs_VERTEX); exp.More(); exp.Next())
- {
- insertDependence(exp.Current());
- }
- break;
- }
- case TopAbs_VERTEX:
- {
- break;
- }
- default:
- {
- break;
}
}
+ break;
+ case TopAbs_COMPSOLID: insertDependence( _subShape, TopAbs_SOLID ); break;
+ case TopAbs_SOLID: insertDependence( _subShape, TopAbs_FACE ); break;
+ case TopAbs_SHELL: insertDependence( _subShape, TopAbs_FACE ); break;
+ case TopAbs_FACE: insertDependence( _subShape, TopAbs_EDGE ); break;
+ case TopAbs_WIRE: insertDependence( _subShape, TopAbs_EDGE ); break;
+ case TopAbs_EDGE: insertDependence( _subShape, TopAbs_VERTEX ); break;
+ default:;
+ }
_dependenceAnalysed = true;
return _mapDepend;
}
*/
//================================================================================
-namespace {
+namespace
+{
int dependsOnMapKey( const SMESH_subMesh* sm )
{
int type = sm->GetSubShape().ShapeType();
//=============================================================================
/*!
- * For simple Shapes (solid, face, edge): add subMesh into dependence list.
+ * Add sub-meshes on sub-shapes of a given type into the dependence map.
*/
//=============================================================================
-void SMESH_subMesh::insertDependence(const TopoDS_Shape aSubShape)
+void SMESH_subMesh::insertDependence(const TopoDS_Shape aShape,
+ TopAbs_ShapeEnum aSubType)
{
- SMESH_subMesh *aSubMesh = _father->GetSubMesh(aSubShape);
- int cle = dependsOnMapKey( aSubMesh );
- if ( _mapDepend.find( cle ) == _mapDepend.end())
+ TopExp_Explorer sub( aShape, aSubType );
+ for ( ; sub.More(); sub.Next() )
{
- _mapDepend[cle] = aSubMesh;
- const map < int, SMESH_subMesh * > & subMap = aSubMesh->DependsOn();
- _mapDepend.insert( subMap.begin(), subMap.end() );
+ SMESH_subMesh *aSubMesh = _father->GetSubMesh( sub.Current() );
+ if ( aSubMesh->GetId() == 0 )
+ continue; // not a sub-shape of the shape to mesh
+ int cle = dependsOnMapKey( aSubMesh );
+ if ( _mapDepend.find( cle ) == _mapDepend.end())
+ {
+ _mapDepend[cle] = aSubMesh;
+ const map < int, SMESH_subMesh * > & subMap = aSubMesh->DependsOn();
+ _mapDepend.insert( subMap.begin(), subMap.end() );
+ }
}
}
return false;
}
-//=============================================================================
+//================================================================================
/*!
- *
+ * \brief Treats modification of hypotheses definition
+ * \param [in] event - what happens
+ * \param [in] anHyp - a hypothesis
+ * \return SMESH_Hypothesis::Hypothesis_Status - a treatment result.
+ *
+ * Optional description of a problematic situation (if any) can be retrieved
+ * via GetComputeError().
*/
-//=============================================================================
+//================================================================================
SMESH_Hypothesis::Hypothesis_Status
SMESH_subMesh::AlgoStateEngine(int event, SMESH_Hypothesis * anHyp)
// le retour des evenement father n'indiquent pas que add ou remove fait
SMESH_Hypothesis::Hypothesis_Status aux_ret, ret = SMESH_Hypothesis::HYP_OK;
+ if ( _Id == 0 ) return ret; // not a sub-shape of the shape to mesh
SMESHDS_Mesh* meshDS =_father->GetMeshDS();
SMESH_Algo* algo = 0;
SMESH_HypoFilter filter( SMESH_HypoFilter::HasType( algo->GetType() ));
filter.Or( SMESH_HypoFilter::HasType( algo->GetType()+1 ));
filter.Or( SMESH_HypoFilter::HasType( algo->GetType()+2 ));
- if ( SMESH_Algo * curAlgo = (SMESH_Algo*)_father->GetHypothesis(_subShape, filter, true ))
+ if ( SMESH_Algo * curAlgo = (SMESH_Algo*)_father->GetHypothesis( this, filter, true ))
if ( !curAlgo->NeedDiscreteBoundary() )
algoRequiringCleaning = curAlgo;
}
if ( ! CanAddHypothesis( anHyp )) // check dimension
return SMESH_Hypothesis::HYP_BAD_DIM;
- if ( /*!anHyp->IsAuxiliary() &&*/ getSimilarAttached( _subShape, anHyp ) )
+ if ( !anHyp->IsAuxiliary() && getSimilarAttached( _subShape, anHyp ) )
return SMESH_Hypothesis::HYP_ALREADY_EXIST;
if ( !meshDS->AddHypothesis(_subShape, anHyp))
if (!isApplicableHyp)
return ret; // not applicable hypotheses do not change algo state
+ if (( algo = GetAlgo()))
+ algo->InitComputeError();
+
switch (_algoState)
{
// ret should be fatal: anHyp was not added
ret = SMESH_Hypothesis::HYP_INCOMPATIBLE;
}
- else if (!_father->IsUsedHypothesis( anHyp, this ))
+ else if (!_father->IsUsedHypothesis( anHyp, this ))
ret = SMESH_Hypothesis::HYP_INCOMPATIBLE;
if (SMESH_Hypothesis::IsStatusFatal( ret ))
f.Init( SMESH_HypoFilter::IsAlgo() );
f.And( SMESH_HypoFilter::IsApplicableTo( _subShape ));
f.AndNot( SMESH_HypoFilter::Is( algo ));
- const SMESH_Hypothesis * prevAlgo = _father->GetHypothesis( _subShape, f, true );
+ const SMESH_Hypothesis * prevAlgo = _father->GetHypothesis( this, f, true );
if (prevAlgo &&
- string(algo->GetName()) != string(prevAlgo->GetName()) )
+ string( algo->GetName()) != prevAlgo->GetName())
modifiedHyp = true;
}
else
f.Init( SMESH_HypoFilter::IsAlgo() );
f.And( SMESH_HypoFilter::IsApplicableTo( _subShape ));
f.AndNot( SMESH_HypoFilter::Is( algo ));
- const SMESH_Hypothesis* prevAlgo = _father->GetHypothesis( _subShape, f, true );
+ const SMESH_Hypothesis* prevAlgo = _father->GetHypothesis( this, f, true );
if (prevAlgo &&
string(algo->GetName()) != string(prevAlgo->GetName()) )
modifiedHyp = true;
// detect algorithm hiding
//
- if ( ret == SMESH_Hypothesis::HYP_OK &&
- ( event == ADD_ALGO || event == ADD_FATHER_ALGO ) &&
+ if ( ret == SMESH_Hypothesis::HYP_OK &&
+ ( event == ADD_ALGO || event == ADD_FATHER_ALGO ) && algo &&
algo->GetName() == anHyp->GetName() )
{
// is algo hidden?
SMESH_Gen* gen = _father->GetGen();
- TopTools_ListIteratorOfListOfShape it( _father->GetAncestors( _subShape ));
- for ( ; ( ret == SMESH_Hypothesis::HYP_OK && it.More()); it.Next() ) {
- if ( SMESH_Algo* upperAlgo = gen->GetAlgo( *_father, it.Value() ))
+ const std::vector< SMESH_subMesh * > & ancestors = GetAncestors();
+ for ( size_t iA = 0; ( ret == SMESH_Hypothesis::HYP_OK && iA < ancestors.size()); ++iA ) {
+ if ( SMESH_Algo* upperAlgo = ancestors[ iA ]->GetAlgo() )
if ( !upperAlgo->NeedDiscreteBoundary() && !upperAlgo->SupportSubmeshes())
ret = SMESH_Hypothesis::HYP_HIDDEN_ALGO;
}
// is algo hiding?
if ( ret == SMESH_Hypothesis::HYP_OK &&
!algo->NeedDiscreteBoundary() &&
- !algo->SupportSubmeshes()) {
+ !algo->SupportSubmeshes())
+ {
TopoDS_Shape algoAssignedTo, otherAssignedTo;
- gen->GetAlgo( *_father, _subShape, &algoAssignedTo );
+ gen->GetAlgo( this, &algoAssignedTo );
map<int, SMESH_subMesh*>::reverse_iterator i_sm = _mapDepend.rbegin();
for ( ; ( ret == SMESH_Hypothesis::HYP_OK && i_sm != _mapDepend.rend()) ; ++i_sm )
- if ( gen->GetAlgo( *_father, i_sm->second->_subShape, &otherAssignedTo ) &&
+ if ( gen->GetAlgo( i_sm->second, &otherAssignedTo ) &&
SMESH_MesherHelper::IsSubShape( /*sub=*/otherAssignedTo, /*main=*/algoAssignedTo ))
ret = SMESH_Hypothesis::HYP_HIDING_ALGO;
}
}
+ if ( _algo ) { // get an error description set by _algo->CheckHypothesis()
+ _computeError = _algo->GetComputeError();
+ _algo->InitComputeError();
+ }
+
bool stateChange = ( _algoState != oldAlgoState );
if ( stateChange && _algoState == HYP_OK ) // hyp becomes OK
ComputeSubMeshStateEngine( CHECK_COMPUTE_STATE );
}
- if (stateChange || modifiedHyp)
- ComputeStateEngine(MODIF_ALGO_STATE);
+ if ( stateChange || modifiedHyp )
+ ComputeStateEngine( MODIF_ALGO_STATE );
_realComputeCost = ( _algoState == HYP_OK ) ? computeCost() : 0;
for (; itsub.More(); itsub.Next())
{
// loop on adjacent subShapes
- TopTools_ListIteratorOfListOfShape it( _father->GetAncestors( itsub.Value() ));
- for (; it.More(); it.Next())
+ const std::vector< SMESH_subMesh * > & ancestors = GetAncestors();
+ for ( size_t iA = 0; iA < ancestors.size(); ++iA )
{
- const TopoDS_Shape& adjacent = it.Value();
+ const TopoDS_Shape& adjacent = ancestors[ iA ]->GetSubShape();
if ( _subShape.IsSame( adjacent )) continue;
if ( adjacent.ShapeType() != _subShape.ShapeType())
break;
// check algo attached to smAdjacent
- SMESH_Algo * algo = gen->GetAlgo((*_father), adjacent);
+ SMESH_Algo * algo = ancestors[ iA ]->GetAlgo();
if (algo &&
!algo->NeedDiscreteBoundary() &&
algo->OnlyUnaryInput())
_algoState = state;
}
-//=============================================================================
+//================================================================================
/*!
+ * \brief Send an event to sub-meshes
+ * \param [in] event - the event
+ * \param [in] anHyp - an hypothesis
+ * \param [in] exitOnFatal - to stop iteration on sub-meshes if a sub-mesh
+ * reports a fatal result
+ * \return SMESH_Hypothesis::Hypothesis_Status - the worst result
*
+ * Optional description of a problematic situation (if any) can be retrieved
+ * via GetComputeError().
*/
-//=============================================================================
+//================================================================================
+
SMESH_Hypothesis::Hypothesis_Status
- SMESH_subMesh::SubMeshesAlgoStateEngine(int event,
- SMESH_Hypothesis * anHyp)
+ SMESH_subMesh::SubMeshesAlgoStateEngine(int event,
+ SMESH_Hypothesis * anHyp,
+ bool exitOnFatal)
{
SMESH_Hypothesis::Hypothesis_Status ret = SMESH_Hypothesis::HYP_OK;
//EAP: a wire (dim==1) should notify edges (dim==1)
{
SMESH_subMeshIteratorPtr smIt = getDependsOnIterator(false,false);
while ( smIt->more() ) {
- SMESH_Hypothesis::Hypothesis_Status ret2 =
- smIt->next()->AlgoStateEngine(event, anHyp);
+ SMESH_subMesh* sm = smIt->next();
+ SMESH_Hypothesis::Hypothesis_Status ret2 = sm->AlgoStateEngine(event, anHyp);
if ( ret2 > ret )
+ {
ret = ret2;
+ _computeError = sm->_computeError;
+ sm->_computeError.reset();
+ if ( exitOnFatal && SMESH_Hypothesis::IsStatusFatal( ret ))
+ break;
+ }
}
}
return ret;
if ( !sm->IsEmpty() )
{
const bool sameShapeType = ( prevShapeType == sm->GetSubShape().ShapeType() );
- bool keepSubMeshes = ( sameShapeType && toKeepPrevShapeType );
+ bool keepSubMeshes = ( sameShapeType && toKeepPrevShapeType );
if ( !sameShapeType )
{
// check if the algo allows presence of global algos of dimension the algo
// remember all sub-meshes of sm
if ( keepSubMeshes )
{
- SMESH_subMeshIteratorPtr smIt2 = getDependsOnIterator(false,true);
+ SMESH_subMeshIteratorPtr smIt2 = getDependsOnIterator(false);
while ( smIt2->more() )
smToKeep.insert( smIt2->next() );
}
void SMESH_subMesh::DumpAlgoState(bool isMain)
{
- // if (dim < 1) return;
- if (isMain)
- {
- const map < int, SMESH_subMesh * >&subMeshes = DependsOn();
-
- map < int, SMESH_subMesh * >::const_iterator itsub;
- for (itsub = subMeshes.begin(); itsub != subMeshes.end(); itsub++)
- {
- SMESH_subMesh *sm = (*itsub).second;
- sm->DumpAlgoState(false);
- }
- }
- //int type = _subShape.ShapeType();
- MESSAGE("dim = " << SMESH_Gen::GetShapeDim(_subShape) <<
- " type of shape " << _subShape.ShapeType());
- switch (_algoState)
- {
- case NO_ALGO:
- MESSAGE(" AlgoState = NO_ALGO");
- break;
- case MISSING_HYP:
- MESSAGE(" AlgoState = MISSING_HYP");
- break;
- case HYP_OK:
- MESSAGE(" AlgoState = HYP_OK");
- break;
- }
- switch (_computeState)
- {
- case NOT_READY:
- MESSAGE(" ComputeState = NOT_READY");
- break;
- case READY_TO_COMPUTE:
- MESSAGE(" ComputeState = READY_TO_COMPUTE");
- break;
- case COMPUTE_OK:
- MESSAGE(" ComputeState = COMPUTE_OK");
- break;
- case FAILED_TO_COMPUTE:
- MESSAGE(" ComputeState = FAILED_TO_COMPUTE");
- break;
- }
+ if (isMain)
+ {
+ const map < int, SMESH_subMesh * >&subMeshes = DependsOn();
+
+ map < int, SMESH_subMesh * >::const_iterator itsub;
+ for (itsub = subMeshes.begin(); itsub != subMeshes.end(); itsub++)
+ {
+ SMESH_subMesh *sm = (*itsub).second;
+ sm->DumpAlgoState(false);
+ }
+ }
+ MESSAGE("dim = " << SMESH_Gen::GetShapeDim(_subShape) <<
+ " type of shape " << _subShape.ShapeType());
+ switch (_algoState)
+ {
+ case NO_ALGO : MESSAGE(" AlgoState = NO_ALGO"); break;
+ case MISSING_HYP : MESSAGE(" AlgoState = MISSING_HYP"); break;
+ case HYP_OK : MESSAGE(" AlgoState = HYP_OK");break;
+ }
+ switch (_computeState)
+ {
+ case NOT_READY : MESSAGE(" ComputeState = NOT_READY");break;
+ case READY_TO_COMPUTE : MESSAGE(" ComputeState = READY_TO_COMPUTE");break;
+ case COMPUTE_OK : MESSAGE(" ComputeState = COMPUTE_OK");break;
+ case FAILED_TO_COMPUTE: MESSAGE(" ComputeState = FAILED_TO_COMPUTE");break;
+ }
}
//================================================================================
if ( !algo->NeedDiscreteBoundary() && !subFailed )
_computeError =
SMESH_ComputeError::New(COMPERR_BAD_INPUT_MESH,
- "Unexpected computed submesh",algo);
+ "Unexpected computed sub-mesh",algo);
break; // goto exit
}
}
// Compute
+ // to restore cout that may be redirected by algo
+ std::streambuf* coutBuffer = std::cout.rdbuf();
+
//cleanDependants(); for "UseExisting_*D" algos
//removeSubMeshElementsAndNodes();
loadDependentMeshes();
_computeState = FAILED_TO_COMPUTE;
_computeError = SMESH_ComputeError::New(COMPERR_OK,"",algo);
try {
-#if OCC_VERSION_LARGE > 0x06010000
OCC_CATCH_SIGNALS;
-#endif
+
algo->InitComputeError();
MemoryReserve aMemoryReserve;
{
ret = algo->Compute((*_father), shape);
}
- if ( !_computeError || (/* !ret && */_computeError->IsOK() ) ) // algo can set _computeError of submesh
- _computeError = algo->GetComputeError();
+ // algo can set _computeError of submesh
+ _computeError = SMESH_ComputeError::Worst( _computeError, algo->GetComputeError() );
}
catch ( ::SMESH_ComputeError& comperr ) {
cout << " SMESH_ComputeError caught" << endl;
else
ret = false;
}
+ std::cout.rdbuf( coutBuffer ); // restore cout that could be redirected by algo
+
// check if an error reported on any sub-shape
bool isComputeErrorSet = !checkComputeError( algo, ret, shape );
if ( isComputeErrorSet )
if (ret)
{
for (; ret && subS.More(); subS.Next())
- ret = _father->GetSubMesh( subS.Current() )->IsMeshComputed();
+ if ( !_father->GetSubMesh( subS.Current() )->IsMeshComputed() &&
+ ( _subShape.ShapeType() != TopAbs_EDGE ||
+ !algo->isDegenerated( TopoDS::Edge( subS.Current() ))))
+ ret = false;
}
// Set _computeError
if (!ret && !isComputeErrorSet)
case CHECK_COMPUTE_STATE:
if ( IsMeshComputed() )
_computeState = COMPUTE_OK;
+ else if ( _computeError && _computeError->IsKO() )
+ _computeState = FAILED_TO_COMPUTE;
break;
default:
ASSERT(0);
removeSubMeshElementsAndNodes();
break;
case SUBMESH_COMPUTED: // allow retry compute
- if (_algoState == HYP_OK)
- _computeState = READY_TO_COMPUTE;
- else
- _computeState = NOT_READY;
+ if ( IsEmpty() ) // 23061
+ {
+ if (_algoState == HYP_OK)
+ _computeState = READY_TO_COMPUTE;
+ else
+ _computeState = NOT_READY;
+ }
break;
case SUBMESH_RESTORED:
ComputeSubMeshStateEngine( SUBMESH_RESTORED );
SMESH_Hypothesis::Hypothesis_Status hyp_status;
algo = GetAlgo();
- if(algo && !aResMap.count(this) )
+ if( algo && !aResMap.count( this ))
{
ret = algo->CheckHypothesis((*_father), _subShape, hyp_status);
if (!ret) return false;
- if (_father->HasShapeToMesh() && algo->NeedDiscreteBoundary())
+ if (_father->HasShapeToMesh() && algo->NeedDiscreteBoundary() )
{
// check submeshes needed
bool subMeshEvaluated = true;
return false;
}
_computeError = SMESH_ComputeError::New(COMPERR_OK,"",algo);
- ret = algo->Evaluate((*_father), _subShape, aResMap);
+ if ( IsMeshComputed() )
+ {
+ vector<int> & nbEntities = aResMap[ this ];
+ nbEntities.resize( SMDSEntity_Last, 0 );
+ if ( SMESHDS_SubMesh* sm = GetSubMeshDS() )
+ {
+ nbEntities[ SMDSEntity_Node ] = sm->NbNodes();
+ SMDS_ElemIteratorPtr elemIt = sm->GetElements();
+ while ( elemIt->more() )
+ nbEntities[ elemIt->next()->GetEntityType() ]++;
+ }
+ }
+ else
+ {
+ ret = algo->Evaluate((*_father), _subShape, aResMap);
+ }
aResMap.insert( make_pair( this,vector<int>(0)));
}
if ( _computeState != COMPUTE_OK )
{
if ( _subShape.ShapeType() == TopAbs_EDGE &&
- BRep_Tool::Degenerated( TopoDS::Edge( _subShape )) )
+ SMESH_Algo::isDegenerated( TopoDS::Edge( _subShape )) )
_computeState = COMPUTE_OK;
else if ( theComputeOK )
_computeError = SMESH_ComputeError::New(COMPERR_NO_MESH_ON_SHAPE,"",theAlgo);
void SMESH_subMesh::updateDependantsState(const compute_event theEvent)
{
- TopTools_ListIteratorOfListOfShape it( _father->GetAncestors( _subShape ));
- for (; it.More(); it.Next())
+ const std::vector< SMESH_subMesh * > & ancestors = GetAncestors();
+ for ( size_t iA = 0; iA < ancestors.size(); ++iA )
{
- const TopoDS_Shape& ancestor = it.Value();
- if ( SMESH_subMesh *aSubMesh = _father->GetSubMeshContaining(ancestor))
- aSubMesh->ComputeStateEngine( theEvent );
+ ancestors[ iA ]->ComputeStateEngine( theEvent );
}
}
-//=============================================================================
-/*!
- *
- */
-//=============================================================================
+//=======================================================================
+//function : cleanDependants
+//purpose :
+//=======================================================================
void SMESH_subMesh::cleanDependants()
{
int dimToClean = SMESH_Gen::GetShapeDim( _subShape ) + 1;
- TopTools_ListIteratorOfListOfShape it( _father->GetAncestors( _subShape ));
- for (; it.More(); it.Next())
+ const std::vector< SMESH_subMesh * > & ancestors = GetAncestors();
+ for ( size_t iA = 0; iA < ancestors.size(); ++iA )
{
- const TopoDS_Shape& ancestor = it.Value();
- if ( SMESH_Gen::GetShapeDim( ancestor ) == dimToClean ) {
+ const TopoDS_Shape& ancestor = ancestors[ iA ]->GetSubShape();
+ if ( SMESH_Gen::GetShapeDim( ancestor ) == dimToClean )
+ {
// PAL8021. do not go upper than SOLID, else ComputeStateEngine(CLEAN)
// will erase mesh on other shapes in a compound
- if ( ancestor.ShapeType() >= TopAbs_SOLID ) {
- SMESH_subMesh *aSubMesh = _father->GetSubMeshContaining(ancestor);
- if (aSubMesh &&
- !aSubMesh->IsEmpty() ) // prevent infinite CLEAN via event lesteners
- aSubMesh->ComputeStateEngine(CLEAN);
- }
+ if ( ancestor.ShapeType() >= TopAbs_SOLID &&
+ !ancestors[ iA ]->IsEmpty() ) // prevent infinite CLEAN via event lesteners
+ ancestors[ iA ]->ComputeStateEngine(CLEAN);
}
}
}
-//=============================================================================
-/*!
- *
- */
-//=============================================================================
+//=======================================================================
+//function : removeSubMeshElementsAndNodes
+//purpose :
+//=======================================================================
void SMESH_subMesh::removeSubMeshElementsAndNodes()
{
if ( mainShape.IsSame( _subShape ))
return _subShape;
- const bool ignoreAuxiliaryHyps = false;
+ const bool skipAuxHyps = false;
list<const SMESHDS_Hypothesis*> aUsedHyp =
- theAlgo->GetUsedHypothesis( *_father, _subShape, ignoreAuxiliaryHyps ); // copy
+ theAlgo->GetUsedHypothesis( *_father, _subShape, skipAuxHyps ); // copy
// put in a compound all shapes with the same hypothesis assigned
- // and a good ComputState
+ // and a good ComputeState
TopoDS_Compound aCompound;
BRep_Builder aBuilder;
theSubs.clear();
- TopExp_Explorer anExplorer( mainShape, _subShape.ShapeType() );
- for ( ; anExplorer.More(); anExplorer.Next() )
+ SMESH_subMeshIteratorPtr smIt = _father->GetSubMesh( mainShape )->getDependsOnIterator(false);
+ while ( smIt->more() )
{
- const TopoDS_Shape& S = anExplorer.Current();
- SMESH_subMesh* subMesh = _father->GetSubMesh( S );
+ SMESH_subMesh* subMesh = smIt->next();
+ const TopoDS_Shape& S = subMesh->_subShape;
+ if ( S.ShapeType() != this->_subShape.ShapeType() )
+ continue;
theSubs.push_back( subMesh );
if ( subMesh == this )
{
}
else if ( subMesh->GetComputeState() == READY_TO_COMPUTE )
{
- SMESH_Algo* anAlgo = theGen->GetAlgo( *_father, S );
- if (strcmp( anAlgo->GetName(), theAlgo->GetName()) == 0 && // same algo
- anAlgo->GetUsedHypothesis( *_father, S, ignoreAuxiliaryHyps ) == aUsedHyp) // same hyps
+ SMESH_Algo* anAlgo = subMesh->GetAlgo();
+ if (( anAlgo->IsSameName( *theAlgo )) && // same algo
+ ( anAlgo->GetUsedHypothesis( *_father, S, skipAuxHyps ) == aUsedHyp )) // same hyps
+ {
aBuilder.Add( aCompound, S );
- if ( !subMesh->SubMeshesComputed() )
- theSubComputed = false;
+ if ( !subMesh->SubMeshesComputed() )
+ theSubComputed = false;
+ }
}
}
EventListenerData* curData = l_d->second;
if ( curData && curData != data && curData->IsDeletable() )
delete curData;
- if ( l_d->first->IsDeletable() )
+ if ( l_d->first != listener && l_d->first->IsDeletable() )
delete l_d->first;
_eventListeners.erase( l_d );
break;
/*!
* \brief Return an event listener data
* \param listener - the listener whose data is
+ * \param myOwn - if \c true, returns a listener set by this sub-mesh,
+ * else returns a listener listening to events of this sub-mesh
* \retval EventListenerData* - found data, maybe NULL
*/
//================================================================================
-EventListenerData* SMESH_subMesh::GetEventListenerData(EventListener* listener) const
+EventListenerData* SMESH_subMesh::GetEventListenerData(EventListener* listener,
+ const bool myOwn) const
{
- map< EventListener*, EventListenerData* >::const_iterator l_d =
- _eventListeners.find( listener );
- if ( l_d != _eventListeners.end() )
- return l_d->second;
+ if ( myOwn )
+ {
+ list< OwnListenerData >::const_iterator d;
+ for ( d = _ownListeners.begin(); d != _ownListeners.end(); ++d )
+ {
+ if ( d->myListener == listener && _father->MeshExists( d->myMeshID ))
+ return d->mySubMesh->GetEventListenerData( listener, !myOwn );
+ }
+ }
+ else
+ {
+ map< EventListener*, EventListenerData* >::const_iterator l_d =
+ _eventListeners.find( listener );
+ if ( l_d != _eventListeners.end() )
+ return l_d->second;
+ }
return 0;
}
/*!
* \brief Return an event listener data
* \param listenerName - the listener name
+ * \param myOwn - if \c true, returns a listener set by this sub-mesh,
+ * else returns a listener listening to events of this sub-mesh
* \retval EventListenerData* - found data, maybe NULL
*/
//================================================================================
-EventListenerData* SMESH_subMesh::GetEventListenerData(const string& listenerName) const
+EventListenerData* SMESH_subMesh::GetEventListenerData(const string& listenerName,
+ const bool myOwn) const
{
- map< EventListener*, EventListenerData* >::const_iterator l_d = _eventListeners.begin();
- for ( ; l_d != _eventListeners.end(); ++l_d )
- if ( listenerName == l_d->first->GetName() )
- return l_d->second;
+ if ( myOwn )
+ {
+ list< OwnListenerData >::const_iterator d;
+ for ( d = _ownListeners.begin(); d != _ownListeners.end(); ++d )
+ {
+ if ( _father->MeshExists( d->myMeshID ) && listenerName == d->myListener->GetName())
+ return d->mySubMesh->GetEventListenerData( listenerName, !myOwn );
+ }
+ }
+ else
+ {
+ map< EventListener*, EventListenerData* >::const_iterator l_d = _eventListeners.begin();
+ for ( ; l_d != _eventListeners.end(); ++l_d )
+ if ( listenerName == l_d->first->GetName() )
+ return l_d->second;
+ }
return 0;
}
list< OwnListenerData >::iterator d;
for ( d = _ownListeners.begin(); d != _ownListeners.end(); ++d )
{
- if ( !_father->MeshExists( d->myMeshID ))
- continue;
- if ( _father->GetId() == d->myMeshID && !_father->GetSubMeshContaining( d->mySubMeshID ))
+ SMESH_Mesh* mesh = _father->FindMesh( d->myMeshID );
+ if ( !mesh || !mesh->GetSubMeshContaining( d->mySubMeshID ))
continue;
d->mySubMesh->DeleteEventListener( d->myListener );
}
}
}
+//================================================================================
+/*!
+ * \brief Returns ancestor sub-meshes. Finds them if not yet found.
+ */
+//================================================================================
+
+const std::vector< SMESH_subMesh * > & SMESH_subMesh::GetAncestors() const
+{
+ if ( _ancestors.empty() &&
+ !_subShape.IsSame( _father->GetShapeToMesh() ))
+ {
+ const TopTools_ListOfShape& ancShapes = _father->GetAncestors( _subShape );
+
+ SMESH_subMesh* me = const_cast< SMESH_subMesh* >( this );
+ me->_ancestors.reserve( ancShapes.Extent() );
+
+ TopTools_MapOfShape map;
+
+ for ( TopTools_ListIteratorOfListOfShape it( ancShapes ); it.More(); it.Next() )
+ if ( SMESH_subMesh* sm = _father->GetSubMeshContaining( it.Value() ))
+ if ( map.Add( it.Value() ))
+ me->_ancestors.push_back( sm );
+ }
+
+ return _ancestors;
+}
+
+//================================================================================
+/*!
+ * \brief Clears the vector of ancestor sub-meshes
+ */
+//================================================================================
+
+void SMESH_subMesh::ClearAncestors()
+{
+ _ancestors.clear();
+}
+
//================================================================================
/*!
* \brief Find common submeshes (based on shared sub-shapes with other
*/
//================================================================================
-bool SMESH_subMesh::FindIntersection(const SMESH_subMesh* theOther,
+bool SMESH_subMesh::FindIntersection(const SMESH_subMesh* theOther,
std::set<const SMESH_subMesh*>& theSetOfCommon ) const
{
int oldNb = theSetOfCommon.size();
+
// check main submeshes
const map <int, SMESH_subMesh*>::const_iterator otherEnd = theOther->_mapDepend.end();
if ( theOther->_mapDepend.find(this->GetId()) != otherEnd )
theSetOfCommon.insert( this );
if ( _mapDepend.find(theOther->GetId()) != _mapDepend.end() )
theSetOfCommon.insert( theOther );
+
// check common submeshes
map <int, SMESH_subMesh*>::const_iterator mapIt = _mapDepend.begin();
for( ; mapIt != _mapDepend.end(); mapIt++ )