-// Copyright (C) 2007-2010 CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2011 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
+// 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.
+// 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.
//
-// This library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-// Lesser General Public License for more details.
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
//
-// You should have received a copy of the GNU Lesser General Public
-// License along with this library; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-//
-// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
// SMESH SMESH : implementaion of SMESH idl descriptions
// File : SMESH_subMesh.cxx
// Author : Paul RASCLE, EDF
// Module : SMESH
-//
+
#include "SMESH_subMesh.hxx"
#include "SMESH_Algo.hxx"
#include "SMDS_SetIterator.hxx"
#include "SMDSAbs_ElementType.hxx"
+#include <Basics_OCCTVersion.hxx>
+
#include "utilities.h"
#include "OpUtil.hxx"
#include "Basics_Utils.hxx"
//================================================================================
/*!
- * \brief Allow algo->Compute() if a subshape of lower dim is meshed but
+ * \brief Returns a current algorithm
+ */
+//================================================================================
+
+SMESH_Algo* SMESH_subMesh::GetAlgo() const
+{
+ return _father->GetGen()->GetAlgo(*_father, _subShape);
+}
+
+//================================================================================
+/*!
+ * \brief Allow algo->Compute() if a sub-shape of lower dim is meshed but
* none mesh entity is bound to it (PAL13615, 2nd part)
*/
//================================================================================
{
int aHypDim = theHypothesis->GetDim();
int aShapeDim = SMESH_Gen::GetShapeDim(_subShape);
- if (aHypDim == 3 && aShapeDim == 3) {
- // check case of open shell
- //if (_subShape.ShapeType() == TopAbs_SHELL && !_subShape.Closed())
- if (_subShape.ShapeType() == TopAbs_SHELL && !BRep_Tool::IsClosed(_subShape))
- return false;
- }
+ // issue 21106. Forbid 3D mesh on the SHELL
+ // if (aHypDim == 3 && aShapeDim == 3) {
+ // // check case of open shell
+ // //if (_subShape.ShapeType() == TopAbs_SHELL && !_subShape.Closed())
+ // if (_subShape.ShapeType() == TopAbs_SHELL && !BRep_Tool::IsClosed(_subShape))
+ // return false;
+ // }
if ( aHypDim <= aShapeDim )
return true;
const TopAbs_ShapeEnum theShapeType)
{
if ( theHypothesis->GetType() > SMESHDS_Hypothesis::PARAM_ALGO)
+ {
// algorithm
- return ( theHypothesis->GetShapeType() & (1<< theShapeType));
+ if ( theHypothesis->GetShapeType() & (1<< theShapeType))
+ // issue 21106. Forbid 3D mesh on the SHELL
+ return !( theHypothesis->GetDim() == 3 && theShapeType == TopAbs_SHELL );
+ else
+ return false;
+ }
// hypothesis
switch ( theShapeType ) {
SMESH_Hypothesis::Hypothesis_Status aux_ret, ret = SMESH_Hypothesis::HYP_OK;
SMESHDS_Mesh* meshDS =_father->GetMeshDS();
- SMESH_Gen* gen =_father->GetGen();
+ //SMESH_Gen* gen =_father->GetGen();
SMESH_Algo* algo = 0;
if (_subShape.ShapeType() == TopAbs_VERTEX )
if ( event != REMOVE_FATHER_ALGO )
{
_algoState = NO_ALGO;
- algo = gen->GetAlgo(*_father, _subShape);
+ algo = GetAlgo();
if ( algo ) {
_algoState = MISSING_HYP;
if ( event == REMOVE_FATHER_HYP ||
case ADD_HYP:
break;
case ADD_ALGO: {
- algo = gen->GetAlgo((*_father), _subShape);
+ algo = GetAlgo();
ASSERT(algo);
if (algo->CheckHypothesis((*_father),_subShape, aux_ret))
SetAlgoState(HYP_OK);
case ADD_FATHER_HYP:
break;
case ADD_FATHER_ALGO: { // Algo just added in father
- algo = gen->GetAlgo((*_father), _subShape);
+ algo = GetAlgo();
ASSERT(algo);
if ( algo == anHyp ) {
if ( algo->CheckHypothesis((*_father),_subShape, aux_ret))
case REMOVE_FATHER_HYP:
break;
case REMOVE_FATHER_ALGO: {
- algo = gen->GetAlgo((*_father), _subShape);
+ algo = GetAlgo();
if (algo)
{
if ( algo->CheckHypothesis((*_father),_subShape, aux_ret ))
switch (event)
{
case ADD_HYP: {
- algo = gen->GetAlgo((*_father), _subShape);
+ algo = GetAlgo();
ASSERT(algo);
if ( algo->CheckHypothesis((*_father),_subShape, ret ))
SetAlgoState(HYP_OK);
break;
}
case ADD_ALGO: { //already existing algo : on father ?
- algo = gen->GetAlgo((*_father), _subShape);
+ algo = GetAlgo();
ASSERT(algo);
if ( algo->CheckHypothesis((*_father),_subShape, aux_ret ))// ignore hyp status
SetAlgoState(HYP_OK);
case REMOVE_HYP:
break;
case REMOVE_ALGO: { // perhaps a father algo applies ?
- algo = gen->GetAlgo((*_father), _subShape);
- if (algo == NULL) // no more algo applying on subShape...
+ algo = GetAlgo();
+ if (algo == NULL) // no more algo applying on sub-shape...
{
SetAlgoState(NO_ALGO);
}
}
case MODIF_HYP: // assigned hypothesis value may become good
case ADD_FATHER_HYP: {
- algo = gen->GetAlgo((*_father), _subShape);
+ algo = GetAlgo();
ASSERT(algo);
if ( algo->CheckHypothesis((*_father),_subShape, aux_ret ))
SetAlgoState(HYP_OK);
break;
}
case ADD_FATHER_ALGO: { // new father algo
- algo = gen->GetAlgo((*_father), _subShape);
+ algo = GetAlgo();
ASSERT( algo );
if ( algo == anHyp ) {
if ( algo->CheckHypothesis((*_father),_subShape, aux_ret ))
case REMOVE_FATHER_HYP: // nothing to do
break;
case REMOVE_FATHER_ALGO: {
- algo = gen->GetAlgo((*_father), _subShape);
+ algo = GetAlgo();
if (algo == NULL) // no more applying algo on father
{
SetAlgoState(NO_ALGO);
switch (event)
{
case ADD_HYP: {
- algo = gen->GetAlgo((*_father), _subShape);
+ algo = GetAlgo();
ASSERT(algo);
if (!algo->CheckHypothesis((*_father),_subShape, ret ))
{
break;
}
case ADD_ALGO: { //already existing algo : on father ?
- algo = gen->GetAlgo((*_father), _subShape);
+ algo = GetAlgo();
if ( algo->CheckHypothesis((*_father),_subShape, aux_ret )) {
// check if algo changes
SMESH_HypoFilter f;
break;
}
case REMOVE_HYP: {
- algo = gen->GetAlgo((*_father), _subShape);
+ algo = GetAlgo();
ASSERT(algo);
if ( algo->CheckHypothesis((*_father),_subShape, aux_ret ))
SetAlgoState(HYP_OK);
break;
}
case REMOVE_ALGO: { // perhaps a father algo applies ?
- algo = gen->GetAlgo((*_father), _subShape);
- if (algo == NULL) // no more algo applying on subShape...
+ algo = GetAlgo();
+ if (algo == NULL) // no more algo applying on sub-shape...
{
SetAlgoState(NO_ALGO);
}
}
case MODIF_HYP: // hypothesis value may become bad
case ADD_FATHER_HYP: { // new father hypothesis ?
- algo = gen->GetAlgo((*_father), _subShape);
+ algo = GetAlgo();
ASSERT(algo);
if ( algo->CheckHypothesis((*_father),_subShape, aux_ret ))
{
break;
}
case ADD_FATHER_ALGO: {
- algo = gen->GetAlgo((*_father), _subShape);
+ algo = GetAlgo();
if ( algo == anHyp ) { // a new algo on father
if ( algo->CheckHypothesis((*_father),_subShape, aux_ret )) {
// check if algo changes
break;
}
case REMOVE_FATHER_HYP: {
- algo = gen->GetAlgo((*_father), _subShape);
+ algo = GetAlgo();
ASSERT(algo);
if ( algo->CheckHypothesis((*_father),_subShape, aux_ret )) {
// is there the same local hyp or maybe a new father algo applied?
if (!algo->NeedDescretBoundary())
needFullClean = true;
- algo = gen->GetAlgo((*_father), _subShape);
+ algo = GetAlgo();
if (algo == NULL) // no more applying algo on father
{
SetAlgoState(NO_ALGO);
switch (event)
{
case MODIF_ALGO_STATE:
- algo = gen->GetAlgo((*_father), _subShape);
+ algo = GetAlgo();
if (algo && !algo->NeedDescretBoundary())
CleanDependsOn(); // clean sub-meshes with event CLEAN
if ( _algoState == HYP_OK )
break;
case COMPUTE: // nothing to do
break;
+#ifdef WITH_SMESH_CANCEL_COMPUTE
+ case COMPUTE_CANCELED: // nothing to do
+ break;
+#endif
case CLEAN:
CleanDependants();
RemoveSubMeshElementsAndNodes();
{
case MODIF_ALGO_STATE:
_computeState = NOT_READY;
- algo = gen->GetAlgo((*_father), _subShape);
+ algo = GetAlgo();
if (algo)
{
if (!algo->NeedDescretBoundary())
break;
case COMPUTE:
{
- algo = gen->GetAlgo((*_father), _subShape);
+ algo = GetAlgo();
ASSERT(algo);
ret = algo->CheckHypothesis((*_father), _subShape, hyp_status);
if (!ret)
_computeState = FAILED_TO_COMPUTE;
_computeError = SMESH_ComputeError::New(COMPERR_OK,"",algo);
try {
-#if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
+#if OCC_VERSION_LARGE > 0x06010000
OCC_CATCH_SIGNALS;
#endif
algo->InitComputeError();
if ( !_computeError || ( !ret && _computeError->IsOK() ) ) // algo can set _computeError of submesh
_computeError = algo->GetComputeError();
}
+ catch ( ::SMESH_ComputeError& comperr ) {
+ cout << " SMESH_ComputeError caught" << endl;
+ if ( !_computeError ) _computeError = SMESH_ComputeError::New();
+ *_computeError = comperr;
+ }
catch ( std::bad_alloc& exc ) {
MESSAGE("std::bad_alloc thrown inside algo->Compute()");
if ( _computeError ) {
}
}
}
- if (ret)
+ if (ret && _computeError && _computeError->myName != COMPERR_WARNING )
{
_computeError.reset();
}
UpdateDependantsState( SUBMESH_COMPUTED ); // send event SUBMESH_COMPUTED
}
break;
+#ifdef WITH_SMESH_CANCEL_COMPUTE
+ case COMPUTE_CANCELED: // nothing to do
+ break;
+#endif
case CLEAN:
CleanDependants();
RemoveSubMeshElementsAndNodes();
_computeState = NOT_READY;
- algo = gen->GetAlgo((*_father), _subShape);
+ algo = GetAlgo();
if (algo)
{
ret = algo->CheckHypothesis((*_father), _subShape, hyp_status);
// happen after retrieval from a file
ComputeStateEngine( CHECK_COMPUTE_STATE );
ComputeSubMeshStateEngine( SUBMESH_RESTORED );
- algo = gen->GetAlgo(*_father, _subShape);
+ algo = GetAlgo();
if (algo) algo->SubmeshRestored( this );
break;
case MESH_ENTITY_REMOVED:
{
case MODIF_ALGO_STATE:
ComputeStateEngine( CLEAN );
- algo = gen->GetAlgo((*_father), _subShape);
+ algo = GetAlgo();
if (algo && !algo->NeedDescretBoundary())
CleanDependsOn(); // clean sub-meshes with event CLEAN
break;
case COMPUTE: // nothing to do
break;
+#ifdef WITH_SMESH_CANCEL_COMPUTE
+ case COMPUTE_CANCELED: // nothing to do
+ break;
+#endif
case CLEAN:
CleanDependants(); // clean sub-meshes, dependant on this one, with event CLEAN
RemoveSubMeshElementsAndNodes();
case SUBMESH_RESTORED:
ComputeStateEngine( CHECK_COMPUTE_STATE );
ComputeSubMeshStateEngine( SUBMESH_RESTORED );
- algo = gen->GetAlgo(*_father, _subShape);
+ algo = GetAlgo();
if (algo) algo->SubmeshRestored( this );
break;
case MESH_ENTITY_REMOVED:
case MODIF_ALGO_STATE:
if ( !IsEmpty() )
ComputeStateEngine( CLEAN );
- algo = gen->GetAlgo((*_father), _subShape);
+ algo = GetAlgo();
if (algo && !algo->NeedDescretBoundary())
CleanDependsOn(); // clean sub-meshes with event CLEAN
if (_algoState == HYP_OK)
break;
case COMPUTE: // nothing to do
break;
+#ifdef WITH_SMESH_CANCEL_COMPUTE
+ case COMPUTE_CANCELED:
+ {
+ algo = GetAlgo();
+ algo->CancelCompute();
+ }
+ break;
+#endif
case CLEAN:
CleanDependants(); // submeshes dependent on me should be cleaned as well
RemoveSubMeshElementsAndNodes();
return ret;
}
- SMESH_Gen *gen = _father->GetGen();
+ //SMESH_Gen *gen = _father->GetGen();
SMESH_Algo *algo = 0;
SMESH_Hypothesis::Hypothesis_Status hyp_status;
- algo = gen->GetAlgo((*_father), _subShape);
+ algo = GetAlgo();
if(algo && !aResMap.count(this) )
{
ret = algo->CheckHypothesis((*_father), _subShape, hyp_status);
// Check my state
if ( !_computeError || _computeError->IsOK() )
{
+ // no error description is set to this sub-mesh, check if any mesh is computed
_computeState = IsMeshComputed() ? COMPUTE_OK : FAILED_TO_COMPUTE;
}
else
// Show error
SMESH_Comment text;
- text << theAlgo->GetName() << " failed on subshape #" << _Id << " with error ";
+ text << theAlgo->GetName() << " failed on sub-shape #" << _Id << " with error ";
if (_computeError->IsCommon() )
text << _computeError->CommonName();
else
INFOS( text );
- _computeState = FAILED_TO_COMPUTE;
+ _computeState = _computeError->IsKO() ? FAILED_TO_COMPUTE : COMPUTE_OK;
+
noErrors = false;
}
}
return noErrors;
}
-//=======================================================================
-//function : ApplyToCollection
-//purpose : Apply theAlgo to all subshapes in theCollection
-//=======================================================================
-
-bool SMESH_subMesh::ApplyToCollection (SMESH_Algo* theAlgo,
- const TopoDS_Shape& theCollection)
-{
- MESSAGE("SMESH_subMesh::ApplyToCollection");
- ASSERT ( !theAlgo->NeedDescretBoundary() );
-
- if ( _computeError )
- _computeError->myName = COMPERR_OK;
-
- bool ok = theAlgo->Compute( *_father, theCollection );
-
- // set _computeState of subshapes
- TopExp_Explorer anExplorer( theCollection, _subShape.ShapeType() );
- for ( ; anExplorer.More(); anExplorer.Next() )
- {
- if ( SMESH_subMesh* subMesh = _father->GetSubMeshContaining( anExplorer.Current() ))
- {
- bool localOK = subMesh->CheckComputeError( theAlgo );
- if ( !ok && localOK && !subMesh->IsMeshComputed() )
- {
- subMesh->_computeError = theAlgo->GetComputeError();
- if ( subMesh->_computeError->IsOK() )
- _computeError = SMESH_ComputeError::New(COMPERR_ALGO_FAILED);
- localOK = CheckComputeError( theAlgo );
- }
- if ( localOK )
- subMesh->UpdateDependantsState( SUBMESH_COMPUTED );
- subMesh->UpdateSubMeshState( localOK ? COMPUTE_OK : FAILED_TO_COMPUTE );
- }
- }
-
- return true;
-}
-
-
//=======================================================================
//function : UpdateSubMeshState
//purpose :
// will erase mesh on other shapes in a compound
if ( ancestor.ShapeType() >= TopAbs_SOLID ) {
SMESH_subMesh *aSubMesh = _father->GetSubMeshContaining(ancestor);
- if (aSubMesh)
+ if (aSubMesh &&
+ !aSubMesh->IsEmpty() ) // prevent infinite CLEAN via event lesteners
aSubMesh->ComputeStateEngine(CLEAN);
}
}
{
map< EventListener*, EventListenerData* >::iterator l_d = myEventListeners.begin();
for ( ; l_d != myEventListeners.end(); ++l_d )
- if ( (*l_d).first->myBusySM.insert( this ).second )
+ {
+ std::pair< EventListener*, EventListenerData* > li_da = *l_d; /* copy to enable removal
+ of a listener from
+ myEventListeners by
+ its ProcessEvent() */
+ if ( li_da.first->myBusySM.insert( this ).second )
{
- l_d->first->ProcessEvent( event, eventType, this, l_d->second, hyp );
- l_d->first->myBusySM.erase( this );
+ li_da.first->ProcessEvent( event, eventType, this, li_da.second, hyp );
+ li_da.first->myBusySM.erase( this );
}
+ }
}
//================================================================================
//================================================================================
/*!
- * \brief Find common submeshes (based on shared subshapes with other
+ * \brief Find common submeshes (based on shared sub-shapes with other
* \param theOther submesh to check
* \param theSetOfCommon set of common submesh
*/