-// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2013 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
SMESHDS_Mesh * meshDS,
const TopoDS_Shape & aSubShape)
{
- _subShape = aSubShape;
- _subMeshDS = meshDS->MeshElements(_subShape); // may be null ...
- _father = father;
- _Id = Id;
- _dependenceAnalysed = _alwaysComputed = false;
-
- if (_subShape.ShapeType() == TopAbs_VERTEX)
- {
- _algoState = HYP_OK;
- _computeState = READY_TO_COMPUTE;
- }
- else
- {
- _algoState = NO_ALGO;
- _computeState = NOT_READY;
- }
+ _subShape = aSubShape;
+ _subMeshDS = meshDS->MeshElements(_subShape); // may be null ...
+ _father = father;
+ _Id = Id;
+ _dependenceAnalysed = _alwaysComputed = false;
+ _algo = 0;
+ if (_subShape.ShapeType() == TopAbs_VERTEX)
+ {
+ _algoState = HYP_OK;
+ _computeState = READY_TO_COMPUTE;
+ }
+ else
+ {
+ _algoState = NO_ALGO;
+ _computeState = NOT_READY;
+ }
+ _computeCost = 0; // how costly is to compute this sub-mesh
+ _realComputeCost = 0;
}
//=============================================================================
SMESH_Algo* SMESH_subMesh::GetAlgo() const
{
- return _father->GetGen()->GetAlgo(*_father, _subShape);
+ if ( !_algo )
+ ((SMESH_subMesh*)this)->_algo = _father->GetGen()->GetAlgo(*_father, _subShape);
+ return _algo;
}
//================================================================================
//=============================================================================
/*!
- *
+ * Return true if all sub-meshes have been meshed
*/
//=============================================================================
-bool SMESH_subMesh::subMeshesComputed()
+bool SMESH_subMesh::SubMeshesComputed(bool * isFailedToCompute/*=0*/) const
{
int myDim = SMESH_Gen::GetShapeDim( _subShape );
int dimToCheck = myDim - 1;
bool subMeshesComputed = true;
+ if ( isFailedToCompute ) *isFailedToCompute = false;
// check subMeshes with upper dimension => reverse iteration
SMESH_subMeshIteratorPtr smIt = getDependsOnIterator(false,true);
while ( smIt->more() )
if ( sm->_alwaysComputed )
continue;
const TopoDS_Shape & ss = sm->GetSubShape();
+
// MSV 07.04.2006: restrict checking to myDim-1 only. Ex., there is no sense
// in checking of existence of edges if the algo needs only faces. Moreover,
// degenerated edges may have no submesh, as after computing NETGEN_2D.
- int dim = SMESH_Gen::GetShapeDim( ss );
- if (dim < dimToCheck)
- break; // the rest subMeshes are all of less dimension
+ if ( !_algo || _algo->NeedDiscreteBoundary() ) {
+ int dim = SMESH_Gen::GetShapeDim( ss );
+ if (dim < dimToCheck)
+ break; // the rest subMeshes are all of less dimension
+ }
SMESHDS_SubMesh * ds = sm->GetSubMeshDS();
bool computeOk = (sm->GetComputeState() == COMPUTE_OK ||
(ds && ( dimToCheck ? ds->NbElements() : ds->NbNodes() )));
if (!computeOk)
{
- int type = ss.ShapeType();
-
subMeshesComputed = false;
-
- switch (type)
- {
- case TopAbs_COMPOUND:
- {
- MESSAGE("The not computed sub mesh is a COMPOUND");
- break;
- }
- case TopAbs_COMPSOLID:
- {
- MESSAGE("The not computed sub mesh is a COMPSOLID");
- break;
- }
- case TopAbs_SHELL:
- {
- MESSAGE("The not computed sub mesh is a SHEL");
- break;
- }
- case TopAbs_WIRE:
- {
- MESSAGE("The not computed sub mesh is a WIRE");
- break;
- }
- case TopAbs_SOLID:
- {
- MESSAGE("The not computed sub mesh is a SOLID");
- break;
- }
- case TopAbs_FACE:
- {
- MESSAGE("The not computed sub mesh is a FACE");
- break;
- }
- case TopAbs_EDGE:
- {
- MESSAGE("The not computed sub mesh is a EDGE");
- break;
- }
- default:
- {
- MESSAGE("The not computed sub mesh is of unknown type");
- break;
- }
- }
-
- break;
+ if ( isFailedToCompute && !(*isFailedToCompute) )
+ *isFailedToCompute = ( sm->GetComputeState() == FAILED_TO_COMPUTE );
+
+ // int type = ss.ShapeType();
+
+ // switch (type)
+ // {
+ // case TopAbs_COMPOUND:
+ // {
+ // MESSAGE("The not computed sub mesh is a COMPOUND");
+ // break;
+ // }
+ // case TopAbs_COMPSOLID:
+ // {
+ // MESSAGE("The not computed sub mesh is a COMPSOLID");
+ // break;
+ // }
+ // case TopAbs_SHELL:
+ // {
+ // MESSAGE("The not computed sub mesh is a SHEL");
+ // break;
+ // }
+ // case TopAbs_WIRE:
+ // {
+ // MESSAGE("The not computed sub mesh is a WIRE");
+ // break;
+ // }
+ // case TopAbs_SOLID:
+ // {
+ // MESSAGE("The not computed sub mesh is a SOLID");
+ // break;
+ // }
+ // case TopAbs_FACE:
+ // {
+ // MESSAGE("The not computed sub mesh is a FACE");
+ // break;
+ // }
+ // case TopAbs_EDGE:
+ // {
+ // MESSAGE("The not computed sub mesh is a EDGE");
+ // break;
+ // }
+ // default:
+ // {
+ // MESSAGE("The not computed sub mesh is of unknown type");
+ // break;
+ // }
+ // }
+
+ if ( !isFailedToCompute )
+ break;
}
}
return subMeshesComputed;
}
+//================================================================================
+/*!
+ * \brief Return cost of computing this sub-mesh. If hypotheses are not well defined,
+ * zero is returned
+ * \return int - the computation cost in abstract units.
+ */
+//================================================================================
+
+int SMESH_subMesh::GetComputeCost() const
+{
+ return _realComputeCost;
+}
+
+//================================================================================
+/*!
+ * \brief Return cost of computing this sub-mesh. The cost depends on the shape type
+ * and number of sub-meshes this one DependsOn().
+ * \return int - the computation cost in abstract units.
+ */
+//================================================================================
+
+int SMESH_subMesh::computeCost() const
+{
+ if ( !_computeCost )
+ {
+ int computeCost;
+ switch ( _subShape.ShapeType() ) {
+ case TopAbs_SOLID:
+ 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);
+ while ( childIt->more() )
+ computeCost += childIt->next()->computeCost();
+
+ ((SMESH_subMesh*)this)->_computeCost = computeCost;
+ }
+ return _computeCost;
+}
+
//=============================================================================
/*!
*
return _mapDepend;
}
+//================================================================================
+/*!
+ * \brief Return a key for SMESH_subMesh::_mapDepend map
+ */
+//================================================================================
+
+namespace {
+ int dependsOnMapKey( const SMESH_subMesh* sm )
+ {
+ int type = sm->GetSubShape().ShapeType();
+ int ordType = 9 - type; // 2 = Vertex, 8 = CompSolid
+ int cle = sm->GetId();
+ cle += 10000000 * ordType; // sort map by ordType then index
+ return cle;
+ }
+}
+
//=============================================================================
/*!
* For simple Shapes (solid, face, edge): add subMesh into dependence list.
void SMESH_subMesh::insertDependence(const TopoDS_Shape aSubShape)
{
SMESH_subMesh *aSubMesh = _father->GetSubMesh(aSubShape);
- int type = aSubShape.ShapeType();
- int ordType = 9 - type; // 2 = Vertex, 8 = CompSolid
- int cle = aSubMesh->GetId();
- cle += 10000000 * ordType; // sort map by ordType then index
+ int cle = dependsOnMapKey( aSubMesh );
if ( _mapDepend.find( cle ) == _mapDepend.end())
{
_mapDepend[cle] = aSubMesh;
}
}
+//================================================================================
+/*!
+ * \brief Return \c true if \a this sub-mesh depends on \a other
+ */
+//================================================================================
+
+bool SMESH_subMesh::DependsOn( const SMESH_subMesh* other ) const
+{
+ return other ? _mapDepend.count( dependsOnMapKey( other )) : false;
+}
+
//=============================================================================
/*!
- *
+ * Return a shape of \a this sub-mesh
*/
//=============================================================================
const TopoDS_Shape & SMESH_subMesh::GetSubShape() const
{
- //MESSAGE("SMESH_subMesh::GetSubShape");
- return _subShape;
+ return _subShape;
}
-
//=======================================================================
//function : CanAddHypothesis
//purpose : return true if theHypothesis can be attached to me:
SMESH_Hypothesis::Hypothesis_Status
SMESH_subMesh::AlgoStateEngine(int event, SMESH_Hypothesis * anHyp)
{
- // MESSAGE("SMESH_subMesh::AlgoStateEngine");
- //SCRUTE(_algoState);
- //SCRUTE(event);
-
// **** les retour des evenement shape sont significatifs
// (add ou remove fait ou non)
// le retour des evenement father n'indiquent pas que add ou remove fait
SMESH_Hypothesis::Hypothesis_Status aux_ret, ret = SMESH_Hypothesis::HYP_OK;
SMESHDS_Mesh* meshDS =_father->GetMeshDS();
- //SMESH_Gen* gen =_father->GetGen();
SMESH_Algo* algo = 0;
+ _algo = 0;
if (_subShape.ShapeType() == TopAbs_VERTEX )
{
int oldAlgoState = _algoState;
bool modifiedHyp = (event == MODIF_HYP); // if set to true, force event MODIF_ALGO_STATE
- bool needFullClean = false;
+ SMESH_Algo* algoRequiringCleaning = 0;
bool isApplicableHyp = IsApplicableHypotesis( anHyp );
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 ))
- needFullClean = ( !curAlgo->NeedDiscreteBoundary() );
+ if ( SMESH_Algo * curAlgo = (SMESH_Algo*)_father->GetHypothesis(_subShape, filter, true ))
+ if ( !curAlgo->NeedDiscreteBoundary() )
+ algoRequiringCleaning = curAlgo;
}
}
{
algo = dynamic_cast<SMESH_Algo*> (anHyp);
if (!algo->NeedDiscreteBoundary())
- {
- // clean all mesh in the tree of the current submesh;
- // we must perform it now because later
- // we will have no information about the type of the removed algo
- needFullClean = true;
- }
+ algoRequiringCleaning = algo;
}
}
// CLEAN was not called at event REMOVE_ALGO because the algo is not applicable to SOLID.
algo = dynamic_cast<SMESH_Algo*> (anHyp);
if (!algo->NeedDiscreteBoundary())
- needFullClean = true;
-
+ algoRequiringCleaning = algo;
algo = GetAlgo();
if (algo == NULL) // no more applying algo on father
{
if ( stateChange && _algoState == HYP_OK ) // hyp becomes OK
algo->SetEventListener( this );
+ if ( event == REMOVE_ALGO || event == REMOVE_FATHER_ALGO )
+ _algo = 0;
+
notifyListenersOnEvent( event, ALGO_EVENT, anHyp );
if ( stateChange && oldAlgoState == HYP_OK ) { // hyp becomes KO
}
}
- if ( needFullClean ) {
+ if ( algoRequiringCleaning ) {
// added or removed algo is all-dimensional
ComputeStateEngine( CLEAN );
- cleanDependsOn();
+ cleanDependsOn( algoRequiringCleaning );
ComputeSubMeshStateEngine( CHECK_COMPUTE_STATE );
}
if (stateChange || modifiedHyp)
ComputeStateEngine(MODIF_ALGO_STATE);
+ _realComputeCost = ( _algoState == HYP_OK ) ? computeCost() : 0;
+
return ret;
}
return ret;
}
-//=============================================================================
+//================================================================================
/*!
- *
+ * \brief Remove elements from sub-meshes.
+ * \param algoRequiringCleaning - an all-dimensional algorithm whose presence
+ * causes the cleaning.
*/
-//=============================================================================
+//================================================================================
-void SMESH_subMesh::cleanDependsOn()
+void SMESH_subMesh::cleanDependsOn( SMESH_Algo* algoRequiringCleaning/*=0*/ )
{
- SMESH_subMeshIteratorPtr smIt = getDependsOnIterator(false,false);
- while ( smIt->more() )
- smIt->next()->ComputeStateEngine(CLEAN);
+ SMESH_subMeshIteratorPtr smIt = getDependsOnIterator(false,
+ /*complexShapeFirst=*/true);
+ if ( _father->NbNodes() == 0 )
+ {
+ while ( smIt->more() )
+ smIt->next()->ComputeStateEngine(CHECK_COMPUTE_STATE);
+ }
+ else if ( !algoRequiringCleaning || !algoRequiringCleaning->SupportSubmeshes() )
+ {
+ while ( smIt->more() )
+ smIt->next()->ComputeStateEngine(CLEAN);
+ }
+ else if ( algoRequiringCleaning && algoRequiringCleaning->SupportSubmeshes() )
+ {
+ SMESHDS_Mesh* meshDS = _father->GetMeshDS();
+
+ // find sub-meshes to keep elements on
+ set< SMESH_subMesh* > smToKeep;
+ TopAbs_ShapeEnum prevShapeType = TopAbs_SHAPE;
+ bool toKeepPrevShapeType = false;
+ while ( smIt->more() )
+ {
+ SMESH_subMesh* sm = smIt->next();
+ sm->ComputeStateEngine(CHECK_COMPUTE_STATE);
+ if ( !sm->IsEmpty() )
+ {
+ const bool sameShapeType = ( prevShapeType == sm->GetSubShape().ShapeType() );
+ bool keepSubMeshes = ( sameShapeType && toKeepPrevShapeType );
+ if ( !sameShapeType )
+ {
+ // check if the algo allows presence of global algos of dimension the algo
+ // can generate it-self
+ int shapeDim = SMESH_Gen::GetShapeDim( sm->GetSubShape() );
+ keepSubMeshes = algoRequiringCleaning->NeedLowerHyps( shapeDim );
+ prevShapeType = sm->GetSubShape().ShapeType();
+ toKeepPrevShapeType = keepSubMeshes;
+ }
+ if ( !keepSubMeshes )
+ {
+ // look for an algo assigned to sm
+ bool algoFound = false;
+ const list<const SMESHDS_Hypothesis*>& hyps = meshDS->GetHypothesis( sm->_subShape );
+ list<const SMESHDS_Hypothesis*>::const_iterator h = hyps.begin();
+ for ( ; ( !algoFound && h != hyps.end() ); ++h )
+ algoFound = ((*h)->GetType() != SMESHDS_Hypothesis::PARAM_ALGO );
+ keepSubMeshes = algoFound;
+ }
+ // remember all sub-meshes of sm
+ if ( keepSubMeshes )
+ {
+ SMESH_subMeshIteratorPtr smIt2 = getDependsOnIterator(false,true);
+ while ( smIt2->more() )
+ smToKeep.insert( smIt2->next() );
+ }
+ }
+ }
+ // remove elements
+ SMESH_subMeshIteratorPtr smIt = getDependsOnIterator(false,true);
+ while ( smIt->more() )
+ {
+ SMESH_subMesh* sm = smIt->next();
+ if ( !smToKeep.count( sm ))
+ sm->ComputeStateEngine(CLEAN);
+ }
+ }
}
//=============================================================================
void SMESH_subMesh::DumpAlgoState(bool isMain)
{
- int dim = SMESH_Gen::GetShapeDim(_subShape);
-// if (dim < 1) return;
+ // if (dim < 1) return;
if (isMain)
{
const map < int, SMESH_subMesh * >&subMeshes = DependsOn();
sm->DumpAlgoState(false);
}
}
- int type = _subShape.ShapeType();
- MESSAGE("dim = " << dim << " type of shape " << type);
+ //int type = _subShape.ShapeType();
+ MESSAGE("dim = " << SMESH_Gen::GetShapeDim(_subShape) <<
+ " type of shape " << _subShape.ShapeType());
switch (_algoState)
{
case NO_ALGO:
const SMDS_MeshElement * elt = ite->next();
//MESSAGE( " RM elt: "<<elt->GetID()<<" ( "<<elt->NbNodes()<<" )" );
//meshDS->RemoveElement(elt);
- meshDS->RemoveFreeElement(elt, subMeshDS);
+ meshDS->RemoveFreeElement(elt, 0);
}
SMDS_NodeIteratorPtr itn = subMeshDS->GetNodes();
const SMDS_MeshNode * node = itn->next();
//MESSAGE( " RM node: "<<node->GetID());
if ( node->NbInverseElements() == 0 )
- meshDS->RemoveFreeNode(node, subMeshDS);
+ meshDS->RemoveFreeNode(node, 0);
else // for StdMeshers_CompositeSegment_1D: node in one submesh, edge in another
meshDS->RemoveNode(node);
}
+ subMeshDS->Clear();
}
}
}
switch ( event ) {
case MODIF_ALGO_STATE:
case COMPUTE:
+ case COMPUTE_SUBMESH:
//case COMPUTE_CANCELED:
case CLEAN:
//case SUBMESH_COMPUTED:
default:;
}
- //MESSAGE("SMESH_subMesh::ComputeStateEngine");
- //SCRUTE(_computeState);
- //SCRUTE(event);
+ if ( event == CLEAN )
+ _alwaysComputed = false; // Unset 'true' set by MergeNodes() (issue 0022182)
if (_subShape.ShapeType() == TopAbs_VERTEX)
{
_computeState = READY_TO_COMPUTE;
SMESHDS_SubMesh* smDS = GetSubMeshDS();
- if ( smDS && smDS->NbNodes() ) {
+ if ( smDS && smDS->NbNodes() )
+ {
if ( event == CLEAN ) {
cleanDependants();
cleanSubMesh( this );
else
_computeState = COMPUTE_OK;
}
- else if ( event == COMPUTE && !_alwaysComputed ) {
+ else if (( event == COMPUTE || event == COMPUTE_SUBMESH )
+ && !_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()) ) {
case MODIF_ALGO_STATE:
algo = GetAlgo();
if (algo && !algo->NeedDiscreteBoundary())
- cleanDependsOn(); // clean sub-meshes with event CLEAN
+ cleanDependsOn( algo ); // clean sub-meshes with event CLEAN
if ( _algoState == HYP_OK )
_computeState = READY_TO_COMPUTE;
break;
case COMPUTE: // nothing to do
+ case COMPUTE_SUBMESH:
break;
-#ifdef WITH_SMESH_CANCEL_COMPUTE
- case COMPUTE_CANCELED: // nothing to do
+ case COMPUTE_CANCELED: // nothing to do
break;
-#endif
case CLEAN:
cleanDependants();
removeSubMeshElementsAndNodes();
if (algo)
{
if (!algo->NeedDiscreteBoundary())
- cleanDependsOn(); // clean sub-meshes with event CLEAN
+ cleanDependsOn( algo ); // clean sub-meshes with event CLEAN
if ( _algoState == HYP_OK )
_computeState = READY_TO_COMPUTE;
}
break;
case COMPUTE:
+ case COMPUTE_SUBMESH:
{
algo = GetAlgo();
ASSERT(algo);
break;
}
TopoDS_Shape shape = _subShape;
+ algo->SubMeshesToCompute().assign( 1, this );
// check submeshes needed
if (_father->HasShapeToMesh() ) {
- bool subComputed = false;
- if (!algo->OnlyUnaryInput())
- shape = getCollection( gen, algo, subComputed );
- else
- subComputed = subMeshesComputed();
+ bool subComputed = false, subFailed = false;
+ if (!algo->OnlyUnaryInput()) {
+ if ( event == COMPUTE /*&&
+ ( algo->NeedDiscreteBoundary() || algo->SupportSubmeshes() )*/)
+ shape = getCollection( gen, algo, subComputed, subFailed, algo->SubMeshesToCompute());
+ else
+ subComputed = SubMeshesComputed( & subFailed );
+ }
+ else {
+ subComputed = SubMeshesComputed();
+ }
ret = ( algo->NeedDiscreteBoundary() ? subComputed :
- algo->SupportSubmeshes() ? true :
+ algo->SupportSubmeshes() ? !subFailed :
( !subComputed || _father->IsNotConformAllowed() ));
- if (!ret) {
+ if (!ret)
+ {
_computeState = FAILED_TO_COMPUTE;
- if ( !algo->NeedDiscreteBoundary() )
+ if ( !algo->NeedDiscreteBoundary() && !subFailed )
_computeError =
SMESH_ComputeError::New(COMPERR_BAD_INPUT_MESH,
"Unexpected computed submesh",algo);
- break;
+ 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;
SMDS_Mesh::CheckMemory();
Kernel_Utils::Localizer loc;
{
ret = algo->Compute((*_father), shape);
}
- if ( !_computeError || ( !ret && _computeError->IsOK() ) ) // algo can set _computeError of submesh
+ if ( !_computeError || (/* !ret && */_computeError->IsOK() ) ) // algo can set _computeError of submesh
_computeError = algo->GetComputeError();
}
catch ( ::SMESH_ComputeError& comperr ) {
}
}
catch ( SALOME_Exception& S_ex ) {
+ const int skipSalomeShift = 7; /* to skip "Salome " of
+ "Salome Exception" prefix returned
+ by SALOME_Exception::what() */
if ( !_computeError ) _computeError = SMESH_ComputeError::New();
_computeError->myName = COMPERR_SLM_EXCEPTION;
- _computeError->myComment = S_ex.what();
+ _computeError->myComment = S_ex.what() + skipSalomeShift;
}
catch ( std::exception& exc ) {
if ( !_computeError ) _computeError = SMESH_ComputeError::New();
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 )
+ ret = false;
// check if anything was built
TopExp_Explorer subS(shape, _subShape.ShapeType());
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)
{
_computeError.reset();
}
- updateDependantsState( SUBMESH_COMPUTED ); // send event SUBMESH_COMPUTED
+
+ // send event SUBMESH_COMPUTED
+ if ( ret ) {
+ if ( !algo->NeedDiscreteBoundary() )
+ // send SUBMESH_COMPUTED to dependants of all sub-meshes of shape
+ for (subS.ReInit(); subS.More(); subS.Next())
+ {
+ SMESH_subMesh* sm = _father->GetSubMesh( subS.Current() );
+ SMESH_subMeshIteratorPtr smIt = sm->getDependsOnIterator(false,false);
+ while ( smIt->more() ) {
+ sm = smIt->next();
+ if ( sm->GetSubShape().ShapeType() == TopAbs_VERTEX )
+ sm->updateDependantsState( SUBMESH_COMPUTED );
+ else
+ break;
+ }
+ }
+ else
+ updateDependantsState( SUBMESH_COMPUTED );
+ }
}
break;
-#ifdef WITH_SMESH_CANCEL_COMPUTE
case COMPUTE_CANCELED: // nothing to do
break;
-#endif
case CLEAN:
cleanDependants();
removeSubMeshElementsAndNodes();
ComputeStateEngine( CLEAN );
algo = GetAlgo();
if (algo && !algo->NeedDiscreteBoundary())
- cleanDependsOn(); // clean sub-meshes with event CLEAN
+ cleanDependsOn( algo ); // clean sub-meshes with event CLEAN
break;
case COMPUTE: // nothing to do
break;
-#ifdef WITH_SMESH_CANCEL_COMPUTE
- case COMPUTE_CANCELED: // nothing to do
+ case COMPUTE_CANCELED: // nothing to do
break;
-#endif
case CLEAN:
cleanDependants(); // clean sub-meshes, dependant on this one, with event CLEAN
removeSubMeshElementsAndNodes();
ComputeStateEngine( CLEAN );
algo = GetAlgo();
if (algo && !algo->NeedDiscreteBoundary())
- cleanDependsOn(); // clean sub-meshes with event CLEAN
+ cleanDependsOn( algo ); // clean sub-meshes with event CLEAN
if (_algoState == HYP_OK)
_computeState = READY_TO_COMPUTE;
else
_computeState = NOT_READY;
break;
- case COMPUTE: // nothing to do
+ case COMPUTE: // nothing to do
+ case COMPUTE_SUBMESH:
break;
case COMPUTE_CANCELED:
{
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);
for (; it.More(); it.Next())
{
const TopoDS_Shape& ancestor = it.Value();
- SMESH_subMesh *aSubMesh =
- _father->GetSubMeshContaining(ancestor);
- if (aSubMesh)
+ if ( SMESH_subMesh *aSubMesh = _father->GetSubMeshContaining(ancestor))
aSubMesh->ComputeStateEngine( theEvent );
}
}
TopoDS_Shape SMESH_subMesh::getCollection(SMESH_Gen * theGen,
SMESH_Algo* theAlgo,
- bool & theSubComputed)
+ bool & theSubComputed,
+ bool & theSubFailed,
+ std::vector<SMESH_subMesh*>& theSubs)
{
- theSubComputed = subMeshesComputed();
+ theSubComputed = SubMeshesComputed( & theSubFailed );
TopoDS_Shape mainShape = _father->GetMeshDS()->ShapeToMesh();
BRep_Builder aBuilder;
aBuilder.MakeCompound( aCompound );
+ theSubs.clear();
+
TopExp_Explorer anExplorer( mainShape, _subShape.ShapeType() );
for ( ; anExplorer.More(); anExplorer.Next() )
{
const TopoDS_Shape& S = anExplorer.Current();
SMESH_subMesh* subMesh = _father->GetSubMesh( S );
+ theSubs.push_back( subMesh );
if ( subMesh == this )
{
aBuilder.Add( aCompound, S );
if (strcmp( anAlgo->GetName(), theAlgo->GetName()) == 0 && // same algo
anAlgo->GetUsedHypothesis( *_father, S, ignoreAuxiliaryHyps ) == aUsedHyp) // same hyps
aBuilder.Add( aCompound, S );
- if ( !subMesh->subMeshesComputed() )
+ if ( !subMesh->SubMeshesComputed() )
theSubComputed = false;
}
}
const event_type eventType,
SMESH_Hypothesis* hyp)
{
- map< EventListener*, EventListenerData* >::iterator l_d = _eventListeners.begin();
- for ( ; l_d != _eventListeners.end(); )
+ list< pair< EventListener*, EventListenerData* > > eventListeners( _eventListeners.begin(),
+ _eventListeners.end());
+ list< pair< EventListener*, EventListenerData* > >::iterator l_d = eventListeners.begin();
+ for ( ; l_d != eventListeners.end(); ++l_d )
{
- std::pair< EventListener*, EventListenerData* > li_da = *l_d++; /* copy to enable removal
- of a listener from
- _eventListeners by
- its ProcessEvent() */
+ std::pair< EventListener*, EventListenerData* > li_da = *l_d;
+ if ( !_eventListeners.count( li_da.first )) continue;
+
if ( li_da.first->myBusySM.insert( this ).second )
{
- const size_t nbListenersBefore = _eventListeners.size();
+ const bool isDeletable = li_da.first->IsDeletable();
+
li_da.first->ProcessEvent( event, eventType, this, li_da.second, hyp );
- if ( nbListenersBefore == _eventListeners.size() )
- li_da.first->myBusySM.erase( this ); // a listener hopefully not removed
+
+ if ( !isDeletable || _eventListeners.count( li_da.first ))
+ li_da.first->myBusySM.erase( this ); // a listener is hopefully not dead
}
}
}
{
map< EventListener*, EventListenerData* >::iterator l_d =
_eventListeners.find( listener );
- if ( l_d != _eventListeners.end() ) {
- if ( l_d->first && l_d->first->IsDeletable() )
- {
- l_d->first->BeforeDelete( this, l_d->second );
- delete l_d->first;
- }
+ if ( l_d != _eventListeners.end() && l_d->first )
+ {
if ( l_d->second && l_d->second->IsDeletable() )
{
delete l_d->second;
}
+ l_d->first->myBusySM.erase( this );
+ if ( l_d->first->IsDeletable() )
+ {
+ l_d->first->BeforeDelete( this, l_d->second );
+ delete l_d->first;
+ }
_eventListeners.erase( l_d );
-
- if ( l_d->first && !l_d->first->IsDeletable() )
- l_d->first->myBusySM.erase( this );
}
}
(*smIt)->ComputeStateEngine( event );
break;
case SMESH_subMesh::COMPUTE:
+ case SMESH_subMesh::COMPUTE_SUBMESH:
if ( subMesh->GetComputeState() == SMESH_subMesh::COMPUTE_OK )
for ( ; smIt != smEnd; ++ smIt)
(*smIt)->ComputeStateEngine( SMESH_subMesh::SUBMESH_COMPUTED );
//================================================================================
SMESH_subMeshIteratorPtr SMESH_subMesh::getDependsOnIterator(const bool includeSelf,
- const bool reverse)
+ const bool reverse) const
{
+ SMESH_subMesh *me = (SMESH_subMesh*) this;
SMESH_subMesh *prepend=0, *append=0;
if ( includeSelf ) {
- if ( reverse ) prepend = this;
- else append = this;
+ if ( reverse ) prepend = me;
+ else append = me;
}
typedef map < int, SMESH_subMesh * > TMap;
if ( reverse )
{
return SMESH_subMeshIteratorPtr
- ( new _Iterator( new SMDS_mapReverseIterator<TMap>( DependsOn() ), prepend, append ));
+ ( new _Iterator( new SMDS_mapReverseIterator<TMap>( me->DependsOn() ), prepend, append ));
}
{
return SMESH_subMeshIteratorPtr
- ( new _Iterator( new SMDS_mapIterator<TMap>( DependsOn() ), prepend, append ));
+ ( new _Iterator( new SMDS_mapIterator<TMap>( me->DependsOn() ), prepend, append ));
}
}