diff --git a/idl/SMESH_Gen.idl b/idl/SMESH_Gen.idl index 32486e5aa..5757e1075 100644 --- a/idl/SMESH_Gen.idl +++ b/idl/SMESH_Gen.idl @@ -43,6 +43,15 @@ module SMESH interface FilterManager; interface SMESH_Pattern; + enum AlgoStateErrorName { MISSING_ALGO, MISSING_HYPO, NOT_CONFORM_MESH }; + struct AlgoStateError { + AlgoStateErrorName name; + string algoName; + long algoDim; + boolean isGlobalAlgo; + }; + typedef sequence algo_error_array; + interface SMESH_Gen : Engines::Component, SALOMEDS::Driver { @@ -123,6 +132,14 @@ module SMESH in GEOM::GEOM_Object theSubObject ) raises ( SALOME::SALOME_Exception ); + /*! + * Return errors of hypotheses definintion + * algo_error_array is empty if everything is OK + */ + algo_error_array GetAlgoState( in SMESH_Mesh theMesh, + in GEOM::GEOM_Object theSubObject ) + raises ( SALOME::SALOME_Exception ); + /*! * */ diff --git a/src/SMESH/SMESH_Gen.cxx b/src/SMESH/SMESH_Gen.cxx index 7a3c34a50..c5a611a29 100644 --- a/src/SMESH/SMESH_Gen.cxx +++ b/src/SMESH/SMESH_Gen.cxx @@ -259,7 +259,8 @@ static bool checkConformIgnoredAlgos(SMESH_Mesh& aMesh, const SMESH_Algo* aGlobIgnoAlgo, const SMESH_Algo* aLocIgnoAlgo, bool & checkConform, - map& aCheckedMap) + map& aCheckedMap, + list< SMESH_Gen::TAlgoStateError > & theErrors) { ASSERT( aSubMesh ); if ( aSubMesh->GetSubShape().ShapeType() == TopAbs_VERTEX) @@ -308,16 +309,18 @@ static bool checkConformIgnoredAlgos(SMESH_Mesh& aMesh, INFOS( "ERROR: Local <" << algo->GetName() << "> would produce not conform mesh: " " hypotesis is missing"); + theErrors.push_back( SMESH_Gen::TAlgoStateError() ); + theErrors.back().Set( SMESH_Gen::NOT_CONFORM_MESH, algo, false ); } // sub-algos will be hidden by a local const map& smMap = aSubMesh->DependsOn(); map::const_reverse_iterator revItSub; bool checkConform2 = false; - for ( revItSub = smMap.rbegin(); revItSub != smMap.rend(); revItSub++) + for ( revItSub = smMap.rbegin(); revItSub != smMap.rend(); revItSub++) { checkConformIgnoredAlgos (aMesh, (*revItSub).second, aGlobIgnoAlgo, - algo, checkConform2, aCheckedMap); + algo, checkConform2, aCheckedMap, theErrors); int key = (*revItSub).first; SMESH_subMesh* sm = (*revItSub).second; if ( aCheckedMap.find( key ) == aCheckedMap.end() ) @@ -344,7 +347,8 @@ static bool checkMissing(SMESH_Gen* aGen, const int aTopAlgoDim, bool* globalChecked, const bool checkNoAlgo, - map& aCheckedMap) + map& aCheckedMap, + list< SMESH_Gen::TAlgoStateError > & theErrors) { if ( aSubMesh->GetSubShape().ShapeType() == TopAbs_VERTEX) return true; @@ -365,6 +369,8 @@ static bool checkMissing(SMESH_Gen* aGen, { INFOS( "ERROR: " << shapeDim << "D algorithm is missing" ); ret = false; + theErrors.push_back( SMESH_Gen::TAlgoStateError() ); + theErrors.back().Set( SMESH_Gen::MISSING_ALGO, shapeDim, true ); } } return ret; @@ -380,6 +386,8 @@ static bool checkMissing(SMESH_Gen* aGen, << "<" << algo->GetName() << "> misses some hypothesis"); if (IsGlobalHypothesis) globalChecked[ algo->GetDim() ] = true; + theErrors.push_back( SMESH_Gen::TAlgoStateError() ); + theErrors.back().Set( SMESH_Gen::MISSING_HYPO, algo, IsGlobalHypothesis ); } ret = false; break; @@ -414,7 +422,7 @@ static bool checkMissing(SMESH_Gen* aGen, //check algo on sub-meshes int aTopAlgoDim2 = algo->GetDim(); if (!checkMissing (aGen, aMesh, sm, aTopAlgoDim2, - globalChecked, checkNoAlgo2, aCheckedMap)) + globalChecked, checkNoAlgo2, aCheckedMap, theErrors)) { ret = false; if (sm->GetAlgoState() == SMESH_subMesh::NO_ALGO ) @@ -433,14 +441,29 @@ static bool checkMissing(SMESH_Gen* aGen, //======================================================================= bool SMESH_Gen::CheckAlgoState(SMESH_Mesh& aMesh, const TopoDS_Shape& aShape) +{ + list< TAlgoStateError > errors; + return GetAlgoState( aMesh, aShape, errors ); +} + +//======================================================================= +//function : GetAlgoState +//purpose : notify on bad state of attached algos, return false +// if Compute() would fail because of some algo bad state +// theErrors list contains problems description +//======================================================================= + +bool SMESH_Gen::GetAlgoState(SMESH_Mesh& theMesh, + const TopoDS_Shape& theShape, + list< TAlgoStateError > & theErrors) { //MESSAGE("SMESH_Gen::CheckAlgoState"); bool ret = true; bool hasAlgo = false; - SMESH_subMesh* sm = aMesh.GetSubMesh(aShape); - const SMESHDS_Mesh* meshDS = aMesh.GetMeshDS(); + SMESH_subMesh* sm = theMesh.GetSubMesh(theShape); + const SMESHDS_Mesh* meshDS = theMesh.GetMeshDS(); TopoDS_Shape mainShape = meshDS->ShapeToMesh(); // ----------------- @@ -489,19 +512,19 @@ bool SMESH_Gen::CheckAlgoState(SMESH_Mesh& aMesh, const TopoDS_Shape& aShape) const map& smMap = sm->DependsOn(); map::const_reverse_iterator revItSub = smMap.rbegin(); map aCheckedMap; - bool checkConform = ( !aMesh.IsNotConformAllowed() ); + bool checkConform = ( !theMesh.IsNotConformAllowed() ); int aKey = 1; SMESH_subMesh* smToCheck = sm; - // loop on aShape and its sub-shapes + // loop on theShape and its sub-shapes while ( smToCheck ) { if ( smToCheck->GetSubShape().ShapeType() == TopAbs_VERTEX) break; if ( aCheckedMap.find( aKey ) == aCheckedMap.end() ) - if (!checkConformIgnoredAlgos (aMesh, smToCheck, aGlobIgnoAlgo, - 0, checkConform, aCheckedMap)) + if (!checkConformIgnoredAlgos (theMesh, smToCheck, aGlobIgnoAlgo, + 0, checkConform, aCheckedMap, theErrors)) ret = false; if ( smToCheck->GetAlgoState() != SMESH_subMesh::NO_ALGO ) @@ -544,15 +567,15 @@ bool SMESH_Gen::CheckAlgoState(SMESH_Mesh& aMesh, const TopoDS_Shape& aShape) bool checkNoAlgo = (bool) aTopAlgoDim; bool globalChecked[] = { false, false, false, false }; - // loop on aShape and its sub-shapes + // loop on theShape and its sub-shapes while ( smToCheck ) { if ( smToCheck->GetSubShape().ShapeType() == TopAbs_VERTEX) break; if ( aCheckedMap.find( aKey ) == aCheckedMap.end() ) - if (!checkMissing (this, aMesh, smToCheck, aTopAlgoDim, - globalChecked, checkNoAlgo, aCheckedMap)) + if (!checkMissing (this, theMesh, smToCheck, aTopAlgoDim, + globalChecked, checkNoAlgo, aCheckedMap, theErrors)) { ret = false; if (smToCheck->GetAlgoState() == SMESH_subMesh::NO_ALGO ) @@ -570,10 +593,14 @@ bool SMESH_Gen::CheckAlgoState(SMESH_Mesh& aMesh, const TopoDS_Shape& aShape) smToCheck = 0; } - if ( !hasAlgo ) + if ( !hasAlgo ) { + ret = false; INFOS( "None algorithm attached" ); + theErrors.push_back( TAlgoStateError() ); + theErrors.back().Set( MISSING_ALGO, 1, true ); + } - return ( ret && hasAlgo ); + return ret; } //======================================================================= diff --git a/src/SMESH/SMESH_Gen.hxx b/src/SMESH/SMESH_Gen.hxx index 17dbe35e6..5364065ef 100644 --- a/src/SMESH/SMESH_Gen.hxx +++ b/src/SMESH/SMESH_Gen.hxx @@ -68,6 +68,28 @@ class SMESH_Gen // notify on bad state of attached algos, return false // if Compute() would fail because of some algo bad state + + enum TAlgoStateErrorName { NONE=0, MISSING_ALGO, MISSING_HYPO, NOT_CONFORM_MESH }; + struct TAlgoStateError + { + TAlgoStateErrorName _name; + const SMESH_Algo* _algo; + int _algoDim; + bool _isGlobalAlgo; + + TAlgoStateError(): _algoDim(0),_algo(0),_name(NONE) {} + void Set(TAlgoStateErrorName name, const SMESH_Algo* algo, bool isGlobal) + { _name = name; _algo = algo; _algoDim = algo->GetDim(); _isGlobalAlgo = isGlobal; } + void Set(TAlgoStateErrorName name, const int algoDim, bool isGlobal) + { _name = name; _algo = 0; _algoDim = algoDim; _isGlobalAlgo = isGlobal; } + }; + + bool GetAlgoState(SMESH_Mesh& aMesh, const TopoDS_Shape& aShape, + std::list< SMESH_Gen::TAlgoStateError > & theErrors); + // notify on bad state of attached algos, return false + // if Compute() would fail because of some algo bad state + // theErrors list contains problems description + StudyContextStruct *GetStudyContext(int studyId); diff --git a/src/SMESH_I/SMESH_Gen_i.cxx b/src/SMESH_I/SMESH_Gen_i.cxx index fcbf895c0..2806e40eb 100644 --- a/src/SMESH_I/SMESH_Gen_i.cxx +++ b/src/SMESH_I/SMESH_Gen_i.cxx @@ -93,7 +93,7 @@ using namespace std; #define NUM_TMP_FILES 2 #ifdef _DEBUG_ -static int MYDEBUG = 0; +static int MYDEBUG = 1; #else static int MYDEBUG = 0; #endif @@ -729,6 +729,100 @@ CORBA::Boolean SMESH_Gen_i::IsReadyToCompute( SMESH::SMESH_Mesh_ptr theMesh, return false; } +//================================================================================ +/*! + * \brief Returns errors of hypotheses definintion + * \param theMesh - the mesh + * \param theSubObject - the main or sub- shape + * \retval SMESH::algo_error_array* - sequence of errors + */ +//================================================================================ + +SMESH::algo_error_array* SMESH_Gen_i::GetAlgoState( SMESH::SMESH_Mesh_ptr theMesh, + GEOM::GEOM_Object_ptr theSubObject ) + throw ( SALOME::SALOME_Exception ) +{ + Unexpect aCatch(SALOME_SalomeException); + if(MYDEBUG) MESSAGE( "SMESH_Gen_i::GetAlgoState()" ); + + if ( CORBA::is_nil( theSubObject ) ) + THROW_SALOME_CORBA_EXCEPTION( "bad shape object reference", SALOME::BAD_PARAM ); + + if ( CORBA::is_nil( theMesh ) ) + THROW_SALOME_CORBA_EXCEPTION( "bad Mesh reference",SALOME::BAD_PARAM ); + + SMESH::algo_error_array_var error_array = new SMESH::algo_error_array; + try { + SMESH_Mesh_i* meshServant = SMESH::DownCast( theMesh ); + ASSERT( meshServant ); + if ( meshServant ) { + TopoDS_Shape myLocShape = GeomObjectToShape( theSubObject ); + ::SMESH_Mesh& myLocMesh = meshServant->GetImpl(); + list< ::SMESH_Gen::TAlgoStateError > error_list; + list< ::SMESH_Gen::TAlgoStateError >::iterator error; + // call ::SMESH_Gen::GetAlgoState() + myGen.GetAlgoState( myLocMesh, myLocShape, error_list ); + error_array->length( error_list.size() ); + int i = 0; + for ( error = error_list.begin(); error != error_list.end(); ++error ) + { + // error name + SMESH::AlgoStateErrorName errName; + switch ( error->_name ) { + case ::SMESH_Gen::MISSING_ALGO: errName = SMESH::MISSING_ALGO; break; + case ::SMESH_Gen::MISSING_HYPO: errName = SMESH::MISSING_HYPO; break; + case ::SMESH_Gen::NOT_CONFORM_MESH: errName = SMESH::NOT_CONFORM_MESH; break; + default: + THROW_SALOME_CORBA_EXCEPTION( "bad error name",SALOME::BAD_PARAM ); + } + // algo name + CORBA::String_var algoName; + if ( error->_algo ) { + if ( !myCurrentStudy->_is_nil() ) { + // find algo in the study + SALOMEDS::SComponent_var father = SALOMEDS::SComponent::_narrow + ( myCurrentStudy->FindComponent( ComponentDataType() ) ); + if ( !father->_is_nil() ) { + SALOMEDS::ChildIterator_var itBig = myCurrentStudy->NewChildIterator( father ); + for ( ; itBig->More(); itBig->Next() ) { + SALOMEDS::SObject_var gotBranch = itBig->Value(); + if ( gotBranch->Tag() == GetAlgorithmsRootTag() ) { + SALOMEDS::ChildIterator_var algoIt = myCurrentStudy->NewChildIterator( gotBranch ); + for ( ; algoIt->More(); algoIt->Next() ) { + SALOMEDS::SObject_var algoSO = algoIt->Value(); + CORBA::Object_var algoIOR = SObjectToObject( algoSO ); + if ( !CORBA::is_nil( algoIOR )) { + SMESH_Hypothesis_i* myImpl = SMESH::DownCast( algoIOR ); + if ( myImpl && myImpl->GetImpl() == error->_algo ) { + algoName = algoSO->GetName(); + break; + } + } + } // loop on algo SO's + break; + } // if algo tag + } // SMESH component iterator + } + } + if ( algoName.in() == 0 ) + // use algo type name + algoName = CORBA::string_dup( error->_algo->GetName() ); + } + // fill AlgoStateError structure + SMESH::AlgoStateError & errStruct = error_array[ i++ ]; + errStruct.name = errName; + errStruct.algoName = algoName; + errStruct.algoDim = error->_algoDim; + errStruct.isGlobalAlgo = error->_isGlobalAlgo; + } + } + } + catch ( SALOME_Exception& S_ex ) { + INFOS( "catch exception "<< S_ex.what() ); + } + return error_array._retn(); +} + //============================================================================= /*! * SMESH_Gen_i::GetSubShapesId diff --git a/src/SMESH_I/SMESH_Gen_i.hxx b/src/SMESH_I/SMESH_Gen_i.hxx index 152edb6ce..1ffe1993f 100644 --- a/src/SMESH_I/SMESH_Gen_i.hxx +++ b/src/SMESH_I/SMESH_Gen_i.hxx @@ -203,6 +203,11 @@ public: GEOM::GEOM_Object_ptr theShapeObject ) throw ( SALOME::SALOME_Exception ); + // Returns errors of hypotheses definintion + SMESH::algo_error_array* GetAlgoState( SMESH::SMESH_Mesh_ptr theMesh, + GEOM::GEOM_Object_ptr theSubObject ) + throw ( SALOME::SALOME_Exception ); + // Get sub-shapes unique ID's list SMESH::long_array* GetSubShapesId( GEOM::GEOM_Object_ptr theMainShapeObject, const SMESH::object_array& theListOfSubShape )