From 6aea23b893abc82fbeecf5924d0939370c110271 Mon Sep 17 00:00:00 2001 From: imn Date: Fri, 21 Feb 2014 12:25:11 +0400 Subject: [PATCH] 0022364: EDF SMESH: Create Mesh dialog box improvement: hide inapplicable algorithms/hypotheses 0022365: EDF SMESH: Create Mesh dialog box improvement: hide algorithms depending on a mesh type --- idl/SMESH_Gen.idl | 7 + src/SMESHGUI/SMESHGUI_HypothesesUtils.cxx | 76 ++-- src/SMESHGUI/SMESHGUI_HypothesesUtils.h | 6 +- src/SMESHGUI/SMESHGUI_MeshOp.cxx | 341 ++++++++++++------ src/SMESHGUI/SMESHGUI_MeshOp.h | 3 +- src/SMESH_I/SMESH_Gen_i.cxx | 80 +++- src/SMESH_I/SMESH_Gen_i.hxx | 13 +- src/SMESH_I/SMESH_Hypothesis_i.hxx | 1 + src/StdMeshers/StdMeshers_Hexa_3D.cxx | 31 +- src/StdMeshers/StdMeshers_Hexa_3D.hxx | 1 + src/StdMeshers/StdMeshers_Quadrangle_2D.cxx | 29 ++ src/StdMeshers/StdMeshers_Quadrangle_2D.hxx | 2 + src/StdMeshers/StdMeshers_RadialPrism_3D.cxx | 47 +++ src/StdMeshers/StdMeshers_RadialPrism_3D.hxx | 2 + .../StdMeshers_RadialQuadrangle_1D2D.cxx | 20 + .../StdMeshers_RadialQuadrangle_1D2D.hxx | 2 + src/StdMeshers_I/StdMeshers_Hexa_3D_i.cxx | 13 + src/StdMeshers_I/StdMeshers_Hexa_3D_i.hxx | 3 + src/StdMeshers_I/StdMeshers_Prism_3D_i.cxx | 5 + src/StdMeshers_I/StdMeshers_Prism_3D_i.hxx | 3 + .../StdMeshers_Quadrangle_2D_i.cxx | 13 + .../StdMeshers_Quadrangle_2D_i.hxx | 3 + .../StdMeshers_RadialQuadrangle_1D2D_i.cxx | 6 + .../StdMeshers_RadialQuadrangle_1D2D_i.hxx | 3 + src/StdMeshers_I/StdMeshers_i.cxx | 20 +- 25 files changed, 543 insertions(+), 187 deletions(-) diff --git a/idl/SMESH_Gen.idl b/idl/SMESH_Gen.idl index 3d7683836..052423ae1 100644 --- a/idl/SMESH_Gen.idl +++ b/idl/SMESH_Gen.idl @@ -417,6 +417,13 @@ module SMESH void Move( in sobject_list what, in SALOMEDS::SObject where, in long row ); + /*! + * Return true if algorithm can be applied + */ + boolean IsApplicable( in string theAlgoType, + in string theLibName, + in GEOM::GEOM_Object theShapeObject, + in boolean toCheckAll ); }; }; diff --git a/src/SMESHGUI/SMESHGUI_HypothesesUtils.cxx b/src/SMESHGUI/SMESHGUI_HypothesesUtils.cxx index da461060c..9902e04a8 100644 --- a/src/SMESHGUI/SMESHGUI_HypothesesUtils.cxx +++ b/src/SMESHGUI/SMESHGUI_HypothesesUtils.cxx @@ -84,7 +84,7 @@ namespace SMESH typedef IMap THypothesisDataMap; THypothesisDataMap myHypothesesMap; THypothesisDataMap myAlgorithmsMap; - + // BUG 0020378 //typedef QMap THypCreatorMap; //THypCreatorMap myHypCreatorMap; @@ -220,16 +220,16 @@ namespace SMESH if (ok) { THypothesisDataMap::ConstIterator it1 = aXmlHandler->myHypothesesMap.begin(); - + for( ;it1 != aXmlHandler->myHypothesesMap.end(); it1++) myHypothesesMap.insert( it1.key(), it1.value() ); - + it1 = aXmlHandler->myAlgorithmsMap.begin(); for( ;it1 != aXmlHandler->myAlgorithmsMap.end(); it1++) myAlgorithmsMap.insert( it1.key(), it1.value() ); - + QList::iterator it; - for ( it = aXmlHandler->myListOfHypothesesSets.begin(); + for ( it = aXmlHandler->myListOfHypothesesSets.begin(); it != aXmlHandler->myListOfHypothesesSets.end(); ++it ) { @@ -301,7 +301,7 @@ namespace SMESH } - QStringList GetHypothesesSets(int maxDim, const QString& MeshType) + QStringList GetHypothesesSets(int maxDim) { QStringList aSetNameList; @@ -309,37 +309,14 @@ namespace SMESH InitAvailableHypotheses(); QList::iterator hypoSet; for ( hypoSet = myListOfHypothesesSets.begin(); - hypoSet != myListOfHypothesesSets.end(); - ++hypoSet ) { + hypoSet != myListOfHypothesesSets.end(); + ++hypoSet ) { HypothesesSet* aSet = *hypoSet; - bool isAvailable = false; - if ( !MeshType.isEmpty() ) - { - if ( aSet->maxDim() != maxDim) - continue; - aSet->init( true ); - while ( aSet->next(), aSet->more() ) - { - if ( HypothesisData* hypData = SMESH::GetHypothesisData( aSet->current() ) ) - { - QStringList::const_iterator inElemType = hypData->OutputTypes.begin(); - for ( ; inElemType != hypData->OutputTypes.end(); inElemType++ ) - { - if ( *inElemType == MeshType ){ - isAvailable = true; - break; - } - } - } - if ( isAvailable ) break; - } - } - else if ( aSet && ( aSet->count( true ) || aSet->count( false )) && - aSet->maxDim() <= maxDim) + if ( aSet && ( aSet->count( true ) || aSet->count( false )) && + aSet->maxDim() <= maxDim) { - isAvailable = true; + aSetNameList.append( mangledHypoSetName( aSet )); } - if ( isAvailable ) aSetNameList.append( mangledHypoSetName( aSet )); } aSetNameList.removeDuplicates(); aSetNameList.sort(); @@ -348,7 +325,7 @@ namespace SMESH QStringList reversedNames; for ( int i = 0; i < aSetNameList.count(); ++i ) reversedNames.prepend( aSetNameList[i] ); - + return reversedNames; } @@ -356,7 +333,7 @@ namespace SMESH { QString name = demangledHypoSetName( theSetName ); QList::iterator hypoSet; - for ( hypoSet = myListOfHypothesesSets.begin(); + for ( hypoSet = myListOfHypothesesSets.begin(); hypoSet != myListOfHypothesesSets.end(); ++hypoSet ) { HypothesesSet* aSet = *hypoSet; @@ -433,7 +410,7 @@ namespace SMESH // 2. Get names of plugin libraries HypothesisData* aHypData = GetHypothesisData(aHypType); - if (!aHypData) + if (!aHypData) return aCreator; QString aClientLibName = aHypData->ClientLibName; @@ -450,7 +427,7 @@ namespace SMESH #ifdef WIN32 const char* anError = "Can't load client meshers plugin library"; #else - const char* anError = dlerror(); + const char* anError = dlerror(); #endif INFOS(anError); // always display this kind of error ! } @@ -480,7 +457,7 @@ namespace SMESH //rnv : This dynamic property of the QObject stores the name of the plugin. // It is used to obtain plugin root dir environment variable - // in the SMESHGUI_HypothesisDlg class. Plugin root dir environment + // in the SMESHGUI_HypothesisDlg class. Plugin root dir environment // variable is used to display documentation. aCreator->setProperty(PLUGIN_NAME,aHypData->PluginName); } @@ -500,7 +477,7 @@ namespace SMESH const QString& aHypName, const bool isAlgo) { - if(MYDEBUG) MESSAGE("Create " << aHypType.toLatin1().data() << + if(MYDEBUG) MESSAGE("Create " << aHypType.toLatin1().data() << " with name " << aHypName.toLatin1().data()); HypothesisData* aHypData = GetHypothesisData(aHypType); QString aServLib = aHypData->ServerLibName; @@ -524,6 +501,17 @@ namespace SMESH return SMESH::SMESH_Hypothesis::_nil(); } + bool IsApplicable(const QString& aHypType, + GEOM::GEOM_Object_ptr theGeomObject, + const bool toCheckAll) + { + HypothesisData* aHypData = GetHypothesisData(aHypType); + QString aServLib = aHypData->ServerLibName; + return SMESHGUI::GetSMESHGen()->IsApplicable( aHypType.toLatin1().data(), + aServLib.toLatin1().data(), + theGeomObject, + toCheckAll); + } bool AddHypothesisOnMesh (SMESH::SMESH_Mesh_ptr aMesh, SMESH::SMESH_Hypothesis_ptr aHyp) @@ -653,7 +641,7 @@ namespace SMESH if (!aSubMesh->_is_nil()) aMesh = aSubMesh->GetFather(); - if (!aMesh->_is_nil()) { + if (!aMesh->_is_nil()) { if (aMesh->HasShapeToMesh() && !aShapeObject->_is_nil()) { res = aMesh->RemoveHypothesis(aShapeObject, anHyp); if (res < SMESH::HYP_UNKNOWN_FATAL) { @@ -661,14 +649,14 @@ namespace SMESH if (meshSO) SMESH::ModifiedMesh(meshSO, false, aMesh->NbNodes()==0); } - + } else if(!aMesh->HasShapeToMesh()){ res = aMesh->RemoveHypothesis(aShapeObject, anHyp); if (res < SMESH::HYP_UNKNOWN_FATAL) { _PTR(SObject) meshSO = SMESH::FindSObject(aMesh); if (meshSO) - SMESH::ModifiedMesh(meshSO, false, aMesh->NbNodes()==0); + SMESH::ModifiedMesh(meshSO, false, aMesh->NbNodes()==0); } } if (res > SMESH::HYP_OK) { @@ -730,7 +718,7 @@ namespace SMESH QString msg; if ( !hasAlgo ) msg = QObject::tr( "STATE_ALGO_MISSING" ); - else + else switch( error.state ) { CASE2MESSAGE( HYP_MISSING ); CASE2MESSAGE( HYP_NOTCONFORM ); diff --git a/src/SMESHGUI/SMESHGUI_HypothesesUtils.h b/src/SMESHGUI/SMESHGUI_HypothesesUtils.h index 26206c043..2841b7a7f 100644 --- a/src/SMESHGUI/SMESHGUI_HypothesesUtils.h +++ b/src/SMESHGUI/SMESHGUI_HypothesesUtils.h @@ -72,7 +72,7 @@ namespace SMESH const bool = true, const bool = false); SMESHGUI_EXPORT - QStringList GetHypothesesSets( int, const QString& ); + QStringList GetHypothesesSets( int ); SMESHGUI_EXPORT HypothesesSet* GetHypothesesSet( const QString& ); @@ -96,6 +96,10 @@ namespace SMESH SMESH::SMESH_Hypothesis_ptr CreateHypothesis( const QString&, const QString&, const bool = false ); + SMESHGUI_EXPORT + bool IsApplicable( const QString&, + GEOM::GEOM_Object_ptr, + const bool = false ); SMESHGUI_EXPORT bool AddHypothesisOnMesh( SMESH::SMESH_Mesh_ptr, SMESH::SMESH_Hypothesis_ptr ); diff --git a/src/SMESHGUI/SMESHGUI_MeshOp.cxx b/src/SMESHGUI/SMESHGUI_MeshOp.cxx index 25f2caafc..babfd2f22 100644 --- a/src/SMESHGUI/SMESHGUI_MeshOp.cxx +++ b/src/SMESHGUI/SMESHGUI_MeshOp.cxx @@ -593,7 +593,7 @@ void SMESHGUI_MeshOp::selectionDone() } myDlg->setMaxHypoDim( shapeDim ); myMaxShapeDim = shapeDim; - myDlg->setHypoSets( SMESH::GetHypothesesSets( shapeDim, "" )); + myDlg->setHypoSets( SMESH::GetHypothesesSets( shapeDim )); if (!myToCreate) // edition: read hypotheses { @@ -691,6 +691,7 @@ void SMESHGUI_MeshOp::selectionDone() QStringList TypeMeshList; createMeshTypeList( TypeMeshList ); setAvailableMeshType( TypeMeshList ); + setFilteredAlgoData( myMaxShapeDim, myDlg->currentMeshType( )); } catch ( const SALOME::SALOME_Exception& S_ex ) { @@ -1391,15 +1392,13 @@ void SMESHGUI_MeshOp::onAlgoSelected( const int theIndex, const bool isSubmesh = ( myToCreate ? !myIsMesh : myDlg->isObjectShown( SMESHGUI_MeshDlg::Mesh )); + // if ( aDim >= SMESH::DIM_2D ) myAvailableHypData[ aDim ][ Algo ] = myFilteredAlgoData[aDim]; HypothesisData* algoData = hypData( aDim, Algo, theIndex ); HypothesisData* algoByDim[4]; algoByDim[ aDim ] = algoData; QStringList anAvailable; - if ( !algoData ) { // all algos becomes available - availableHyps( aDim, Algo, anAvailable, myAvailableHypData[ aDim ][ Algo ]); - myDlg->tab( aDim )->setAvailableHyps( Algo, anAvailable ); - } + // check that tab enable, if algorithm building needed algo is one less than dimension if ( algoData && myIsOnGeometry && !algoData->InputTypes.isEmpty() && ( aDim > SMESH::DIM_0D ) && !isAccessibleDim( aDim - 1 ) ){ @@ -1410,12 +1409,27 @@ void SMESHGUI_MeshOp::onAlgoSelected( const int theIndex, ( algoData && myIsOnGeometry && algoData->InputTypes.isEmpty() && ( aDim > SMESH::DIM_0D ) && isAccessibleDim( aDim - 1 ) ) ) ){ for (int i = aDim - 1; i >= SMESH::DIM_0D; i--){ - if ( isAccessibleDim( i ) ) myDlg->disableTab( i ); + if ( isAccessibleDim( i ) ) { + myDlg->disableTab( i ); + setCurrentHyp(i, Algo, -1); + } } } + // check that algorithms of other dimentions are compatible with // the selected one - + if ( !algoData ) { // all algos becomes available + if (myDlg->currentMeshType() == MT_ANY) + availableHyps( aDim, Algo, anAvailable, myAvailableHypData[ aDim ][ Algo ]); + else{ + anAvailable.clear(); + for (int i = 0; i < myFilteredAlgoData[aDim].count(); ++i) { + HypothesisData* aCurAlgo = myFilteredAlgoData[aDim][ i ]; + anAvailable.append( aCurAlgo->Label ); + } + } + myDlg->tab( aDim )->setAvailableHyps( Algo, anAvailable ); + } // 2 loops: backward and forward from algo dimension for ( int forward = false; forward <= true; ++forward ) { @@ -1444,12 +1458,26 @@ void SMESHGUI_MeshOp::onAlgoSelected( const int theIndex, curAlgo = 0; } // set new available algoritms - availableHyps( dim, Algo, anAvailable, myAvailableHypData[dim][Algo], prevAlgo ); + if (myDlg->currentMeshType() == MT_ANY || dim == SMESH::DIM_1D || dim == SMESH::DIM_0D) + availableHyps( dim, Algo, anAvailable, myAvailableHypData[dim][Algo], prevAlgo ); + else{ + anAvailable.clear(); + myAvailableHypData[dim][Algo].clear(); + for (int i = 0; i < myFilteredAlgoData[dim].count(); ++i) { + HypothesisData* aCurAlgo = myFilteredAlgoData[dim][ i ]; + if ( isCompatible ( prevAlgo, aCurAlgo, Algo )) { + anAvailable.append( aCurAlgo->Label ); + myAvailableHypData[dim][Algo].append( aCurAlgo ); + } + } + } HypothesisData* soleCompatible = 0; if ( anAvailable.count() == 1 ) soleCompatible = myAvailableHypData[dim][Algo][0]; - if ( dim == aTopDim && prevAlgo ) // all available algoritms should be selectable any way - availableHyps( dim, Algo, anAvailable, myAvailableHypData[dim][Algo], 0 ); + if ( dim == aTopDim && prevAlgo ) {// all available algoritms should be selectable any way + if (myDlg->currentMeshType() == MT_ANY) + availableHyps( dim, Algo, anAvailable, myAvailableHypData[dim][Algo], 0 ); + } myDlg->tab( dim )->setAvailableHyps( Algo, anAvailable ); noCompatible = anAvailable.isEmpty(); @@ -1458,7 +1486,7 @@ void SMESHGUI_MeshOp::onAlgoSelected( const int theIndex, if ( !isSubmesh && algoIndex < 0 && soleCompatible && !forward && dim != SMESH::DIM_0D) // select the sole compatible algo algoIndex = myAvailableHypData[dim][Algo].indexOf( soleCompatible ); - setCurrentHyp( dim, Algo, algoIndex ); + setCurrentHyp( dim, Algo, algoIndex); // remember current algo prevAlgo = algoByDim[ dim ] = hypData( dim, Algo, algoIndex ); @@ -1490,8 +1518,8 @@ void SMESHGUI_MeshOp::onAlgoSelected( const int theIndex, bool algoDeselectedByUser = ( theDim < 0 && aDim == dim ); CORBA::String_var curHypType = curHyp->GetName(); if ( !algoDeselectedByUser && - myObjHyps[ dim ][ type ].count() > 0 && - !strcmp( curHypType, myObjHyps[ dim ][ type ].first().first->GetName()) ) + myObjHyps[ dim ][ type ].count() > 0 && + !strcmp( curHypType, myObjHyps[ dim ][ type ].first().first->GetName()) ) { HypothesisData* hypData = SMESH::GetHypothesisData( curHyp->GetName() ); for (int i = 0; i < myAvailableHypData[ dim ][ Algo ].count(); ++i) { @@ -1531,8 +1559,8 @@ void SMESHGUI_MeshOp::onAlgoSelected( const int theIndex, CORBA::String_var hypTypeName = myExistingHyps[ dim ][ type ].first().first->GetName(); bool isOptional = true; if ( algoByDim[ dim ] && - SMESH::IsAvailableHypothesis( algoByDim[ dim ], hypTypeName.in(), isOptional ) && - !isOptional ) + SMESH::IsAvailableHypothesis( algoByDim[ dim ], hypTypeName.in(), isOptional ) && + !isOptional ) hypIndex = 0; } setCurrentHyp( dim, type, hypIndex ); @@ -2450,12 +2478,12 @@ void SMESHGUI_MeshOp::createMeshTypeList( QStringList& theTypeMesh) { theTypeMesh.clear(); theTypeMesh.append( tr( "MT_ANY" ) ); - if ( myIsOnGeometry && ( myMaxShapeDim >= 2 || myMaxShapeDim == -1 ) ) + if ( myMaxShapeDim >= 2 || myMaxShapeDim == -1 ) { theTypeMesh.append( tr( "MT_TRIANGULAR" ) ); theTypeMesh.append( tr( "MT_QUADRILATERAL" ) ); } - if ( myIsOnGeometry && ( myMaxShapeDim == 3 || myMaxShapeDim == -1 ) ) + if ( myMaxShapeDim == 3 || myMaxShapeDim == -1 ) { theTypeMesh.append( tr( "MT_TETRAHEDRAL" ) ); theTypeMesh.append( tr( "MT_HEXAHEDRAL" ) ); @@ -2481,126 +2509,183 @@ void SMESHGUI_MeshOp::setAvailableMeshType( const QStringList& theTypeMesh ) */ //================================================================================ void SMESHGUI_MeshOp::onAlgoSetByMeshType( const int theTabIndex, const int theIndex) +{ + setFilteredAlgoData( theTabIndex, theIndex); +} + +//================================================================================ +/*! + * \brief Set a filtered list of available algorithms by mesh type + * \param theTabIndex - Index of current active tab + * \param theIndex - Index of current type of mesh + */ +//================================================================================ +void SMESHGUI_MeshOp::setFilteredAlgoData( const int theTabIndex, const int theIndex) { int aDim; - if ( !myIsOnGeometry ) return; THypDataList anAvailableAlgsData; QStringList anAvailableAlgs; - QString anCompareType = "ANY"; + QString anCompareType = ""; bool isAvailableChoiceAlgo = false; int anCurrentAvailableAlgo = 0; bool isNone = true; switch ( theIndex ) { - case MT_ANY: + case MT_ANY:{ + anCompareType = "ANY"; + aDim = SMESH::DIM_3D; + } + break; + case MT_TRIANGULAR:{ + aDim = SMESH::DIM_2D; + anCompareType = "TRIA"; + } + break; + case MT_QUADRILATERAL:{ + aDim = SMESH::DIM_2D; + anCompareType = "QUAD"; + } + break; + case MT_TETRAHEDRAL:{ + aDim = SMESH::DIM_3D; + anCompareType = "TETRA"; + } + break; + case MT_HEXAHEDRAL:{ + aDim = SMESH::DIM_3D; + anCompareType = "HEXA"; + } + break; + default:; + } + if ( anCompareType == "ANY" ) + { + for ( int dim = SMESH::DIM_2D; dim <= SMESH::DIM_3D; dim++ ) { - for ( int dim = SMESH::DIM_2D; dim <= SMESH::DIM_3D; dim++ ) + isNone = currentHyp( dim, Algo ) < 0; + isAvailableChoiceAlgo = false; + // retrieves a list of available algorithms from resources + availableHyps( dim, Algo, anAvailableAlgs, anAvailableAlgsData ); + //return current algo in current tab and set new algorithm list + HypothesisData* algoCur; + if ( !isNone && !myAvailableHypData[dim][Algo].empty() ){ + algoCur = myAvailableHypData[dim][Algo].at( currentHyp( dim, Algo ) ); + } + myAvailableHypData[dim][Algo].clear(); + anAvailableAlgs.clear(); + for (int i = 0 ; i < anAvailableAlgsData.count(); i++) { - isNone = currentHyp( dim, Algo ) < 0; - isAvailableChoiceAlgo = false; - // retrieves a list of available algorithms from resources - availableHyps( dim, Algo, anAvailableAlgs, anAvailableAlgsData ); - //return current algo in current tab - if ( !isNone && !myAvailableHypData[dim][Algo].empty() ){ - for (int i = 0 ; i < anAvailableAlgsData.count(); i++) - { - HypothesisData* algoAny = anAvailableAlgsData.at(i); - HypothesisData* algoCur = myAvailableHypData[dim][Algo].at( currentHyp( dim, Algo ) ); - QString tem = algoAny->Label; - if ( algoAny->Label == algoCur->Label ){ - isAvailableChoiceAlgo = true; - anCurrentAvailableAlgo = i; - break; - } - } + HypothesisData* curAlgo = anAvailableAlgsData.at(i); + QString anEntry = myDlg->selectedObject( SMESHGUI_MeshDlg::Geom ); + GEOM::GEOM_Object_var aGeomVar = GEOM::GEOM_Object::_nil(); + if ( _PTR(SObject) pGeom = studyDS()->FindObjectID( anEntry.toLatin1().data() )) + { + aGeomVar= GEOM::GEOM_Object::_narrow( _CAST( SObject,pGeom )->GetObject() ); } - else if ( !isNone ){ - isAvailableChoiceAlgo = true; - anCurrentAvailableAlgo = currentHyp( dim, Algo ); + if ( aGeomVar->_is_nil() || + ( !aGeomVar->_is_nil() && SMESH::IsApplicable( curAlgo->TypeName, aGeomVar, !myIsMesh ))){ + anAvailableAlgs.append( curAlgo->Label ); + myAvailableHypData[dim][Algo].append( curAlgo ); } - //set new algorithm list and select the current algorithm - myAvailableHypData[dim][Algo] = anAvailableAlgsData; - myDlg->tab( dim )->setAvailableHyps( Algo, anAvailableAlgs ); - if ( isAvailableChoiceAlgo ) - setCurrentHyp( dim, Algo, anCurrentAvailableAlgo ); } - int aMaxShapeDim = ( myMaxShapeDim == -1 ) ? SMESH::DIM_3D : myMaxShapeDim; - for ( int i = SMESH::DIM_0D; i <= aMaxShapeDim; i++ ) { - myDlg->enableTab( i ); + if ( !isNone && algoCur ){ + for (int i = 0 ; i < myAvailableHypData[dim][Algo].count(); i++) + { + HypothesisData* algoAny = myAvailableHypData[dim][Algo].at(i); + if ( algoAny->Label == algoCur->Label ){ + isAvailableChoiceAlgo = true; + anCurrentAvailableAlgo = i; + break; + } + } } - myDlg->setCurrentTab( theTabIndex ); - myDlg->setHypoSets( SMESH::GetHypothesesSets( aMaxShapeDim, "" ) ); - } - break; - case MT_TRIANGULAR:{ - aDim = SMESH::DIM_2D; - anCompareType = "TRIA"; - } - break; - case MT_QUADRILATERAL:{ - aDim = SMESH::DIM_2D; - anCompareType = "QUAD"; - } - break; - case MT_TETRAHEDRAL:{ - aDim = SMESH::DIM_3D; - anCompareType = "TETRA"; - } - break; - case MT_HEXAHEDRAL:{ - aDim = SMESH::DIM_3D; - anCompareType = "HEXA"; + else if ( !isNone ){ + isAvailableChoiceAlgo = true; + anCurrentAvailableAlgo = currentHyp( dim, Algo ); + } + myDlg->tab( dim )->setAvailableHyps( Algo, anAvailableAlgs ); + if ( isAvailableChoiceAlgo ) + setCurrentHyp( dim, Algo, anCurrentAvailableAlgo ); + } + int aDimNotGeometry = ( myIsOnGeometry ) ? SMESH::DIM_0D : SMESH::DIM_3D; + if ( !myIsOnGeometry ) + for ( int i = SMESH::DIM_0D; i <= SMESH::DIM_3D; i++ ){ + myDlg->disableTab( i ); + } + for ( int i = aDimNotGeometry; i <= myMaxShapeDim; i++ ) { + myDlg->enableTab( i ); } - break; - default:; + myDlg->setCurrentTab( theTabIndex ); } - if ( anCompareType != "ANY" ) + else { QString anCurrentAlgo; bool isReqDisBound = true; + QString anCurrentCompareType = anCompareType; isNone = currentHyp( aDim, Algo ) < 0; - // retrieves a list of available algorithms from resources - availableHyps( aDim, Algo, anAvailableAlgs, anAvailableAlgsData ); - // finding algorithm which is selected if ( !isNone && !myAvailableHypData[aDim][Algo].empty() && - myAvailableHypData[aDim][Algo].count() != anAvailableAlgsData.count() ){ - anCurrentAlgo = myAvailableHypData[aDim][Algo].at( currentHyp( aDim, Algo ) )->Label; + myAvailableHypData[aDim][Algo].count() != anAvailableAlgsData.count() ) isReqDisBound = myAvailableHypData[aDim][Algo].at( currentHyp( aDim, Algo ) )->InputTypes.isEmpty(); - } - else if ( !isNone ){ - anCurrentAlgo = anAvailableAlgsData.at( currentHyp( aDim, Algo ) )->Label; + else if ( !isNone ) isReqDisBound = anAvailableAlgsData.at( currentHyp( aDim, Algo ) )->InputTypes.isEmpty(); - } - anAvailableAlgs.clear(); - myAvailableHypData[aDim][Algo].clear(); - // finding and adding algorithm depending on the type mesh - for ( int i = 0 ; i < anAvailableAlgsData.count(); i++ ) + for ( int dim = aDim; dim >= SMESH::DIM_2D; dim-- ) { - HypothesisData* algoIn = anAvailableAlgsData.at( i ); - bool isAvailableAlgo = ( algoIn->OutputTypes.count() == 0 ); - QStringList::const_iterator inElemType = algoIn->OutputTypes.begin(); - for ( ; inElemType != algoIn->OutputTypes.end(); inElemType++ ) + bool isNoneAlg = currentHyp( dim, Algo ) < 0; + isAvailableChoiceAlgo = false; + // retrieves a list of available algorithms from resources + availableHyps( dim, Algo, anAvailableAlgs, anAvailableAlgsData ); + // finding algorithm which is selected + if ( !isNoneAlg && !myAvailableHypData[dim][Algo].empty() && + myAvailableHypData[dim][Algo].count() != anAvailableAlgsData.count() ) + anCurrentAlgo = myAvailableHypData[dim][Algo].at( currentHyp( dim, Algo ) )->Label; + else if ( !isNoneAlg ) + anCurrentAlgo = anAvailableAlgsData.at( currentHyp( dim, Algo ) )->Label; + anAvailableAlgs.clear(); + myAvailableHypData[dim][Algo].clear(); + myFilteredAlgoData[dim].clear(); + // finding and adding algorithm depending on the type mesh + for ( int i = 0 ; i < anAvailableAlgsData.count(); i++ ) { - if ( *inElemType == anCompareType ){ - isAvailableAlgo = true; - break; + HypothesisData* algoIn = anAvailableAlgsData.at( i ); + bool isAvailableAlgo = ( algoIn->OutputTypes.count() == 0 ); + QStringList::const_iterator inElemType = algoIn->OutputTypes.begin(); + for ( ; inElemType != algoIn->OutputTypes.end(); inElemType++ ) + { + if ( *inElemType == anCurrentCompareType ){ + isAvailableAlgo = true; + break; + } + } + if ( isAvailableAlgo || algoIn->OutputTypes.count()==0 ){ + QString anEntry = myDlg->selectedObject( SMESHGUI_MeshDlg::Geom ); + GEOM::GEOM_Object_var aGeomVar = GEOM::GEOM_Object::_nil(); + if ( _PTR(SObject) pGeom = studyDS()->FindObjectID( anEntry.toLatin1().data() )) + { + aGeomVar= GEOM::GEOM_Object::_narrow( _CAST( SObject,pGeom )->GetObject() ); + } + if ( aGeomVar->_is_nil() || myMaxShapeDim != dim || + ( !aGeomVar->_is_nil() && SMESH::IsApplicable( algoIn->TypeName, aGeomVar, !myIsMesh ))){ + anAvailableAlgs.append( algoIn->Label ); + myAvailableHypData[dim][Algo].append( algoIn ); + myFilteredAlgoData[dim].append( algoIn ); + } + } + //algorithm will be active, if the chosen algorithm available in the current mesh type + if ( !isNoneAlg && isAvailableAlgo && algoIn->Label == anCurrentAlgo ){ + isAvailableChoiceAlgo = true; + anCurrentAvailableAlgo = anAvailableAlgs.count() - 1 ; } } - if ( isAvailableAlgo || algoIn->OutputTypes.count()==0 ){ - anAvailableAlgs.append( algoIn->Label ); - myAvailableHypData[aDim][Algo].append( algoIn ); - } - //algorithm will be active, if the chosen algorithm available in the current mesh type - if ( !isNone && isAvailableAlgo && algoIn->Label == anCurrentAlgo ){ - isAvailableChoiceAlgo = true; - anCurrentAvailableAlgo = anAvailableAlgs.count() - 1 ; - } + //set new algorithm list and select the current algorithm + myDlg->tab( dim )->setAvailableHyps( Algo, anAvailableAlgs ); + anCurrentCompareType = ( anCompareType == "HEXA" ) ? "QUAD" : "TRIA"; + if ( isAvailableChoiceAlgo ) + setCurrentHyp( dim, Algo, anCurrentAvailableAlgo ); + else + setCurrentHyp( dim, Algo, -1 ); } - //set new algorithm list and select the current algorithm - myDlg->tab( aDim )->setAvailableHyps( Algo, anAvailableAlgs ); - if ( isAvailableChoiceAlgo ) - setCurrentHyp( aDim, Algo, anCurrentAvailableAlgo ); - int aMaxShapeDim = ( myMaxShapeDim == -1 ) ? SMESH::DIM_3D : myMaxShapeDim; - if ( isNone || isReqDisBound || !isAvailableChoiceAlgo ) { + + int aMaxShapeDim = ( myMaxShapeDim != aDim) ? aDim : myMaxShapeDim; + if ( isNone || isReqDisBound ) { for ( int i = SMESH::DIM_0D; i <= aMaxShapeDim; i++ ) { if ( aDim != i ) { myDlg->disableTab( i ); @@ -2615,8 +2700,9 @@ void SMESHGUI_MeshOp::onAlgoSetByMeshType( const int theTabIndex, const int theI } for ( int i = aMaxShapeDim; i > SMESH::DIM_0D; i-- ) { - isReqDisBound = ( currentHyp( i, Algo ) < 0 ) ? true : myAvailableHypData[i][Algo].at( currentHyp( i, Algo ) )->InputTypes.isEmpty(); - if ( aMaxShapeDim != i && isReqDisBound) { + isReqDisBound = ( currentHyp( i, Algo ) < 0 ) ? true : + myAvailableHypData[i][Algo].at( currentHyp( i, Algo ) )->InputTypes.isEmpty(); + if ( isReqDisBound ) { for (int j = i - 1; j >= SMESH::DIM_0D; j--){ myDlg->disableTab( j ); setCurrentHyp( j , Algo, -1 ); @@ -2625,8 +2711,39 @@ void SMESHGUI_MeshOp::onAlgoSetByMeshType( const int theTabIndex, const int theI } } } - myDlg->setHypoSets( SMESH::GetHypothesesSets( aDim, anCompareType ) ); myDlg->enableTab( aDim ); myDlg->setCurrentTab( aDim ); } + QStringList aHypothesesSetsList = SMESH::GetHypothesesSets( aDim ); + QStringList aFilteredHypothesesSetsList; + aFilteredHypothesesSetsList.clear(); + QStringList::const_iterator inHypoSetName = aHypothesesSetsList.begin(); + for ( ; inHypoSetName != aHypothesesSetsList.end(); ++inHypoSetName ) + { + HypothesesSet* currentHypoSet = SMESH::GetHypothesesSet( *inHypoSetName ); + bool isAvailable = false; + currentHypoSet->init( true ); + while ( currentHypoSet->next(), currentHypoSet->more() ) + { + isAvailable = false; + if ( HypothesisData* algoDataIn = SMESH::GetHypothesisData( currentHypoSet->current() )) + { + for (int i = SMESH::DIM_0D; i <= SMESH::DIM_3D; i++) + { + for (int j = 0; j < myAvailableHypData[i][Algo].count(); ++j) { + HypothesisData* aCurAlgo = hypData( i, Algo, j ); + if ( aCurAlgo->Label == algoDataIn->Label ){ + isAvailable = true; + break; + } + } + if ( isAvailable ) break; + } + if ( !isAvailable ) break; + } + } + if ( isAvailable ) + aFilteredHypothesesSetsList.append( *inHypoSetName ); + } + myDlg->setHypoSets( aFilteredHypothesesSetsList ); } diff --git a/src/SMESHGUI/SMESHGUI_MeshOp.h b/src/SMESHGUI/SMESHGUI_MeshOp.h index d67049542..fcaedabf3 100644 --- a/src/SMESHGUI/SMESHGUI_MeshOp.h +++ b/src/SMESHGUI/SMESHGUI_MeshOp.h @@ -132,6 +132,7 @@ private: void selectObject( _PTR(SObject) ) const; void createMeshTypeList( QStringList& ); void setAvailableMeshType( const QStringList& ); + void setFilteredAlgoData( const int, const int ); private: SMESHGUI_MeshDlg* myDlg; SMESHGUI_ShapeByMeshOp* myShapeByMeshOp; @@ -145,7 +146,7 @@ private: // edited mesh/sub-mesh // hypdata corresponding to hypotheses present in myDlg THypDataList myAvailableHypData[4][NbHypTypes]; - + THypDataList myFilteredAlgoData[4]; bool myIgnoreAlgoSelection; HypothesesSet* myHypoSet; int myDim, myType, myMaxShapeDim; diff --git a/src/SMESH_I/SMESH_Gen_i.cxx b/src/SMESH_I/SMESH_Gen_i.cxx index 0a935efbe..200fa9034 100644 --- a/src/SMESH_I/SMESH_Gen_i.cxx +++ b/src/SMESH_I/SMESH_Gen_i.cxx @@ -355,20 +355,20 @@ SMESH_Gen_i::~SMESH_Gen_i() if ( myShapeReader ) delete myShapeReader; } - //============================================================================= /*! - * SMESH_Gen_i::createHypothesis + * SMESH_Gen_i::getHypothesisCreator * - * Create hypothesis of given type + * Get hypothesis creator */ //============================================================================= -SMESH::SMESH_Hypothesis_ptr SMESH_Gen_i::createHypothesis(const char* theHypName, - const char* theLibName) +GenericHypothesisCreator_i* SMESH_Gen_i::getHypothesisCreator(const char* theHypName, + const char* theLibName, + std::string& thePlatformLibName) throw (SALOME::SALOME_Exception) { - /* It's Need to tranlate lib name for WIN32 or X platform */ std::string aPlatformLibName; + /* It's Need to tranlate lib name for WIN32 or X platform */ if ( theLibName && theLibName[0] != '\0' ) { int libNameLen = strlen(theLibName); @@ -395,14 +395,13 @@ SMESH::SMESH_Hypothesis_ptr SMESH_Gen_i::createHypothesis(const char* theHypName #endif } } + thePlatformLibName = aPlatformLibName; Unexpect aCatch(SALOME_SalomeException); if(MYDEBUG) MESSAGE( "Create Hypothesis <" << theHypName << "> from " << aPlatformLibName); - // create a new hypothesis object servant - SMESH_Hypothesis_i* myHypothesis_i = 0; - SMESH::SMESH_Hypothesis_var hypothesis_i; - + typedef GenericHypothesisCreator_i* (*GetHypothesisCreator)(const char* ); + GenericHypothesisCreator_i* aCreator; try { // check, if creator for this hypothesis type already exists @@ -424,7 +423,6 @@ SMESH::SMESH_Hypothesis_ptr SMESH_Gen_i::createHypothesis(const char* theHypName // get method, returning hypothesis creator if(MYDEBUG) MESSAGE("Find GetHypothesisCreator() method ..."); - typedef GenericHypothesisCreator_i* (*GetHypothesisCreator)(const char* theHypName); GetHypothesisCreator procHandle = (GetHypothesisCreator)GetProc( libHandle, "GetHypothesisCreator" ); if (!procHandle) @@ -435,26 +433,47 @@ SMESH::SMESH_Hypothesis_ptr SMESH_Gen_i::createHypothesis(const char* theHypName // get hypothesis creator if(MYDEBUG) MESSAGE("Get Hypothesis Creator for " << theHypName); - GenericHypothesisCreator_i* aCreator = procHandle(theHypName); + aCreator = procHandle(theHypName); if (!aCreator) { throw(SALOME_Exception(LOCALIZED("no such a hypothesis in this plugin"))); } - // map hypothesis creator to a hypothesis name myHypCreatorMap[string(theHypName)] = aCreator; + return aCreator; + } + else + { + return myHypCreatorMap[string(theHypName)]; } - - // create a new hypothesis object, store its ref. in studyContext - if(MYDEBUG) MESSAGE("Create Hypothesis " << theHypName); - myHypothesis_i = - myHypCreatorMap[string(theHypName)]->Create(myPoa, GetCurrentStudyID(), &myGen); - myHypothesis_i->SetLibName(aPlatformLibName.c_str()); // for persistency assurance } catch (SALOME_Exception& S_ex) { THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM); } + return aCreator; +} + +//============================================================================= +/*! + * SMESH_Gen_i::createHypothesis + * + * Create hypothesis of given type + */ +//============================================================================= +SMESH::SMESH_Hypothesis_ptr SMESH_Gen_i::createHypothesis(const char* theHypName, + const char* theLibName) +{ + SMESH_Hypothesis_i* myHypothesis_i = 0; + SMESH::SMESH_Hypothesis_var hypothesis_i; + std::string aPlatformLibName; + typedef GenericHypothesisCreator_i* (*GetHypothesisCreator)(const char* ); + GenericHypothesisCreator_i* aCreator = getHypothesisCreator(theHypName, theLibName, aPlatformLibName); + // create a new hypothesis object, store its ref. in studyContext + if(MYDEBUG) MESSAGE("Create Hypothesis " << theHypName); + myHypothesis_i = + myHypCreatorMap[string(theHypName)]->Create(myPoa, GetCurrentStudyID(), &myGen); + myHypothesis_i->SetLibName(aPlatformLibName.c_str()); // for persistency assurance if (!myHypothesis_i) return hypothesis_i._retn(); @@ -5042,6 +5061,29 @@ void SMESH_Gen_i::Move( const SMESH::sobject_list& what, useCaseBuilder->AppendTo( where, sobj ); // append to the end of list } } +//================================================================================= +// function : IsApplicable +// purpose : Return true if algorithm can be applied +//================================================================================= +CORBA::Boolean SMESH_Gen_i::IsApplicable ( const char* theAlgoType, + const char* theLibName, + GEOM::GEOM_Object_ptr theGeomObject, + CORBA::Boolean toCheckAll) +{ + std::string aPlatformLibName; + typedef GenericHypothesisCreator_i* (*GetHypothesisCreator)(const char*); + GenericHypothesisCreator_i* aCreator = getHypothesisCreator(theAlgoType, theLibName, aPlatformLibName); + if (aCreator) + { + TopoDS_Shape shape = GeomObjectToShape( theGeomObject ); + return aCreator->IsApplicable( shape, toCheckAll ); + } + else + { + if(MYDEBUG) { MESSAGE( "Shape not defined"); } + return false; + } +} //================================================================================= // function : importData diff --git a/src/SMESH_I/SMESH_Gen_i.hxx b/src/SMESH_I/SMESH_Gen_i.hxx index e4589b843..3405a8375 100644 --- a/src/SMESH_I/SMESH_Gen_i.hxx +++ b/src/SMESH_I/SMESH_Gen_i.hxx @@ -595,13 +595,20 @@ public: void Move( const SMESH::sobject_list& what, SALOMEDS::SObject_ptr where, CORBA::Long row ); + CORBA::Boolean IsApplicable ( const char* theAlgoType, + const char* theLibName, + GEOM::GEOM_Object_ptr theShapeObject, + CORBA::Boolean toCheckAll); private: + // Get hypothesis creator + GenericHypothesisCreator_i* getHypothesisCreator( const char* theHypName, + const char* theLibName, + std::string& thePlatformLibName) + throw ( SALOME::SALOME_Exception ); // Create hypothesis of given type SMESH::SMESH_Hypothesis_ptr createHypothesis( const char* theHypName, - const char* theLibName) - throw ( SALOME::SALOME_Exception ); - + const char* theLibName); // Create empty mesh on shape SMESH::SMESH_Mesh_ptr createMesh() throw ( SALOME::SALOME_Exception ); diff --git a/src/SMESH_I/SMESH_Hypothesis_i.hxx b/src/SMESH_I/SMESH_Hypothesis_i.hxx index 4e71206c5..5cc8e54d9 100644 --- a/src/SMESH_I/SMESH_Hypothesis_i.hxx +++ b/src/SMESH_I/SMESH_Hypothesis_i.hxx @@ -134,6 +134,7 @@ public: ::SMESH_Gen* theGenImpl) = 0; // return the name of IDL module virtual std::string GetModuleName() = 0; + virtual bool IsApplicable( const TopoDS_Shape &S, bool toCheckAll ) {return true;} }; //============================================================================= diff --git a/src/StdMeshers/StdMeshers_Hexa_3D.cxx b/src/StdMeshers/StdMeshers_Hexa_3D.cxx index f6dcd1518..22b658de4 100644 --- a/src/StdMeshers/StdMeshers_Hexa_3D.cxx +++ b/src/StdMeshers/StdMeshers_Hexa_3D.cxx @@ -287,9 +287,9 @@ namespace //============================================================================= /*! * Generates hexahedron mesh on hexaedron like form using algorithm from - * "Application de l'interpolation transfinie à la création de maillages + * "Application de l'interpolation transfinie � la cr�ation de maillages * C0 ou G1 continus sur des triangles, quadrangles, tetraedres, pentaedres - * et hexaedres déformés." + * et hexaedres d�form�s." * Alain PERONNET - 8 janvier 1999 */ //============================================================================= @@ -741,6 +741,33 @@ bool StdMeshers_Hexa_3D::Compute(SMESH_Mesh & aMesh, SMESH_MesherHelper* aHelper return error( algo->GetComputeError()); } +//================================================================================ +/*! + * \brief Return true if applied compute mesh on this shape + */ +//================================================================================ + +bool StdMeshers_Hexa_3D::IsApplicable( const TopoDS_Shape & aShape, bool toCheckAll ) +{ + TopoDS_Vertex theVertex0, theVertex1; + TopTools_IndexedMapOfOrientedShape theShapeIDMap; + bool isCurShellApp; + int nbFoundShells = 0; + bool isEmpty = true; + for ( TopExp_Explorer exp0( aShape, TopAbs_SOLID ); exp0.More(); exp0.Next() ){ + nbFoundShells = 0; + for (TopExp_Explorer exp1( exp0.Current(), TopAbs_SHELL ); exp1.More(); exp1.Next(), ++nbFoundShells){ + TopoDS_Shell shell = TopoDS::Shell(exp1.Current()); + isCurShellApp = SMESH_Block::FindBlockShapes(shell, theVertex0, theVertex1, theShapeIDMap ); + if( ( toCheckAll && !isCurShellApp ) || nbFoundShells == 1 ) return false; + isEmpty = false; + } + if( !toCheckAll && isCurShellApp ) return true; + } + if( toCheckAll && !isEmpty) return true; + return false; +}; + //======================================================================= //function : ComputePentahedralMesh //purpose : diff --git a/src/StdMeshers/StdMeshers_Hexa_3D.hxx b/src/StdMeshers/StdMeshers_Hexa_3D.hxx index 86610630a..7c64bd497 100644 --- a/src/StdMeshers/StdMeshers_Hexa_3D.hxx +++ b/src/StdMeshers/StdMeshers_Hexa_3D.hxx @@ -54,6 +54,7 @@ public: virtual bool Evaluate(SMESH_Mesh & aMesh, const TopoDS_Shape & aShape, MapShapeNbElems& aResMap); + static bool IsApplicable(const TopoDS_Shape & aShape, bool toCheckAll); protected: const StdMeshers_ViscousLayers* _viscousLayersHyp; diff --git a/src/StdMeshers/StdMeshers_Quadrangle_2D.cxx b/src/StdMeshers/StdMeshers_Quadrangle_2D.cxx index 6a1351346..89e8042b4 100644 --- a/src/StdMeshers/StdMeshers_Quadrangle_2D.cxx +++ b/src/StdMeshers/StdMeshers_Quadrangle_2D.cxx @@ -904,6 +904,35 @@ bool StdMeshers_Quadrangle_2D::Evaluate(SMESH_Mesh& aMesh, return true; } +//================================================================================ +/*! + * \brief Return true if applied compute mesh on this shape + */ +//================================================================================ + +bool StdMeshers_Quadrangle_2D::IsApplicable( const TopoDS_Shape & aShape, bool toCheckAll ) +{ + int nbFoundFaces = 0; + for (TopExp_Explorer exp( aShape, TopAbs_FACE ); exp.More(); exp.Next(), ++nbFoundFaces ){ + TopoDS_Face aFace = TopoDS::Face(exp.Current()); + if ( aFace.Orientation() >= TopAbs_INTERNAL ) aFace.Orientation( TopAbs_FORWARD ); + + list< TopoDS_Edge > aWire; + list< int > nbEdgesInWire; + int nbWire = SMESH_Block::GetOrderedEdges (aFace, aWire, nbEdgesInWire); + + int nbNoDegenEdges = 0; + list::iterator edge = aWire.begin(); + for ( ; edge != aWire.end(); ++edge ){ + if ( !SMESH_Algo::isDegenerated( *edge )) + ++nbNoDegenEdges; + } + if( toCheckAll && (nbWire != 1 || nbNoDegenEdges <= 3 ) ) return false; + if( !toCheckAll && nbWire == 1 && nbNoDegenEdges > 3 ) return true; + } + if( toCheckAll && nbFoundFaces != 0) return true; + return false; +}; //================================================================================ /*! diff --git a/src/StdMeshers/StdMeshers_Quadrangle_2D.hxx b/src/StdMeshers/StdMeshers_Quadrangle_2D.hxx index 3d985a1cf..813457a1c 100644 --- a/src/StdMeshers/StdMeshers_Quadrangle_2D.hxx +++ b/src/StdMeshers/StdMeshers_Quadrangle_2D.hxx @@ -155,6 +155,8 @@ public: const TopoDS_Shape& aShape, const bool considerMesh=false); + static bool IsApplicable(const TopoDS_Shape & aShape, bool toCheckAll); + protected: bool checkNbEdgesForEvaluate(SMESH_Mesh& aMesh, diff --git a/src/StdMeshers/StdMeshers_RadialPrism_3D.cxx b/src/StdMeshers/StdMeshers_RadialPrism_3D.cxx index ebddcf2b3..5dbf7fb29 100644 --- a/src/StdMeshers/StdMeshers_RadialPrism_3D.cxx +++ b/src/StdMeshers/StdMeshers_RadialPrism_3D.cxx @@ -598,3 +598,50 @@ bool StdMeshers_RadialPrism_3D::Evaluate(SMESH_Mesh& aMesh, return true; } + +//================================================================================ +/*! + * \brief Return true if applied compute mesh on this shape + */ +//================================================================================ + +bool StdMeshers_RadialPrism_3D::IsApplicable( const TopoDS_Shape & aShape, bool toCheckAll ) +{ + bool isCurShellApp; + int nbFoundSolids = 0; + for (TopExp_Explorer exp( aShape, TopAbs_SOLID ); exp.More(); exp.Next(), ++nbFoundSolids ){ +#if OCC_VERSION_LARGE > 0x06050400 + TopoDS_Shell outerShell = BRepClass3d::OuterShell( TopoDS::Solid( exp.Current() )); +#else + TopoDS_Shell outerShell = BRepTools::OuterShell( TopoDS::Solid( exp.Current() )); +#endif + TopoDS_Shape innerShell; + int nbShells = 0; + for ( TopoDS_Iterator It (exp.Current()); It.More(); It.Next(), ++nbShells ) + if ( !outerShell.IsSame( It.Value() )) + innerShell = It.Value(); + if ( nbShells != 2 ) { nbFoundSolids--; continue; } + + int nbFaces1 = SMESH_MesherHelper:: Count( innerShell, TopAbs_FACE, 0 ); + int nbFaces2 = SMESH_MesherHelper:: Count( outerShell, TopAbs_FACE, 0 ); + if ( nbFaces1 != nbFaces2 ){ + if( toCheckAll ) return false; + continue; + } + int nbEdges1 = SMESH_MesherHelper:: Count( innerShell, TopAbs_EDGE, 0 ); + int nbEdges2 = SMESH_MesherHelper:: Count( outerShell, TopAbs_EDGE, 0 ); + if ( nbEdges1 != nbEdges2 ){ + if( toCheckAll ) return false; + continue; + } + int nbVertices1 = SMESH_MesherHelper:: Count( innerShell, TopAbs_VERTEX, 0 ); + int nbVertices2 = SMESH_MesherHelper:: Count( outerShell, TopAbs_VERTEX, 0 ); + if ( nbVertices1 != nbVertices2 ){ + if( toCheckAll ) return false; + continue; + } + if ( !toCheckAll ) return true; + } + if( toCheckAll && nbFoundSolids != 0) return true; + return false; +}; diff --git a/src/StdMeshers/StdMeshers_RadialPrism_3D.hxx b/src/StdMeshers/StdMeshers_RadialPrism_3D.hxx index 9c0728f7c..e1b1f21f4 100644 --- a/src/StdMeshers/StdMeshers_RadialPrism_3D.hxx +++ b/src/StdMeshers/StdMeshers_RadialPrism_3D.hxx @@ -55,6 +55,8 @@ public: virtual bool Evaluate(SMESH_Mesh & aMesh, const TopoDS_Shape & aShape, MapShapeNbElems& aResMap); + static bool IsApplicable(const TopoDS_Shape & aShape, bool toCheckAll); + protected: typedef std::vector TNodeColumn; diff --git a/src/StdMeshers/StdMeshers_RadialQuadrangle_1D2D.cxx b/src/StdMeshers/StdMeshers_RadialQuadrangle_1D2D.cxx index dcfc5b35d..83e667968 100644 --- a/src/StdMeshers/StdMeshers_RadialQuadrangle_1D2D.cxx +++ b/src/StdMeshers/StdMeshers_RadialQuadrangle_1D2D.cxx @@ -1281,3 +1281,23 @@ bool StdMeshers_RadialQuadrangle_1D2D::Evaluate(SMESH_Mesh& aMesh, return false; } + +//================================================================================ +/*! + * \brief Return true if applied compute mesh on this shape + */ +//================================================================================ + +bool StdMeshers_RadialQuadrangle_1D2D::IsApplicable( const TopoDS_Shape & aShape, bool toCheckAll ) +{ + int nbFoundFaces = 0; + for (TopExp_Explorer exp( aShape, TopAbs_FACE ); exp.More(); exp.Next(), ++nbFoundFaces ){ + TopoDS_Edge CircEdge, LinEdge1, LinEdge2; + int nbe = analyseFace( TopoDS_Shape( exp.Current() ), CircEdge, LinEdge1, LinEdge2 ); + Handle(Geom_Circle) aCirc = Handle(Geom_Circle)::DownCast( getCurve( CircEdge )); + if( toCheckAll && ( nbe > 3 || nbe < 1 || aCirc.IsNull() )) return false; + if( !toCheckAll && ( nbe <= 3 && nbe >= 1 && !aCirc.IsNull() )) return true; + } + if( toCheckAll && nbFoundFaces != 0 ) return true; + return false; +}; diff --git a/src/StdMeshers/StdMeshers_RadialQuadrangle_1D2D.hxx b/src/StdMeshers/StdMeshers_RadialQuadrangle_1D2D.hxx index 2f6eb780b..80f117f14 100644 --- a/src/StdMeshers/StdMeshers_RadialQuadrangle_1D2D.hxx +++ b/src/StdMeshers/StdMeshers_RadialQuadrangle_1D2D.hxx @@ -59,6 +59,8 @@ public: */ virtual void SubmeshRestored(SMESH_subMesh* subMesh); + static bool IsApplicable(const TopoDS_Shape & aShape, bool toCheckAll); + protected: bool computeLayerPositions(const gp_Pnt& p1, diff --git a/src/StdMeshers_I/StdMeshers_Hexa_3D_i.cxx b/src/StdMeshers_I/StdMeshers_Hexa_3D_i.cxx index 422633645..2aceaede2 100644 --- a/src/StdMeshers_I/StdMeshers_Hexa_3D_i.cxx +++ b/src/StdMeshers_I/StdMeshers_Hexa_3D_i.cxx @@ -83,3 +83,16 @@ StdMeshers_Hexa_3D_i::~StdMeshers_Hexa_3D_i() MESSAGE( "StdMeshers_Hexa_3D_i::GetImpl" ); return ( ::StdMeshers_Hexa_3D* )myBaseImpl; } + +//============================================================================= +/*! + * StdMeshers_Hexa_3D_i::IsApplicable + * + * Method return true if algorithm is applicable + */ +//============================================================================= + +CORBA::Boolean StdMeshers_Hexa_3D_i::IsApplicable( const TopoDS_Shape &S, CORBA::Boolean toCheckAll ) +{ + return ::StdMeshers_Hexa_3D::IsApplicable( S, toCheckAll ); +} diff --git a/src/StdMeshers_I/StdMeshers_Hexa_3D_i.hxx b/src/StdMeshers_I/StdMeshers_Hexa_3D_i.hxx index 661dc42ad..633793ba7 100644 --- a/src/StdMeshers_I/StdMeshers_Hexa_3D_i.hxx +++ b/src/StdMeshers_I/StdMeshers_Hexa_3D_i.hxx @@ -58,6 +58,9 @@ public: // Get implementation ::StdMeshers_Hexa_3D* GetImpl(); + + // Method return true if algorithm is applicable + static CORBA::Boolean IsApplicable(const TopoDS_Shape &S, CORBA::Boolean toCheckAll); }; #endif diff --git a/src/StdMeshers_I/StdMeshers_Prism_3D_i.cxx b/src/StdMeshers_I/StdMeshers_Prism_3D_i.cxx index 51392d0bb..642552338 100644 --- a/src/StdMeshers_I/StdMeshers_Prism_3D_i.cxx +++ b/src/StdMeshers_I/StdMeshers_Prism_3D_i.cxx @@ -101,4 +101,9 @@ StdMeshers_RadialPrism_3D_i::~StdMeshers_RadialPrism_3D_i() MESSAGE( "StdMeshers_RadialPrism_3D_i::GetImpl" ); return ( ::StdMeshers_RadialPrism_3D* )myBaseImpl; } +//----------------------------------------------------------------------------- +CORBA::Boolean StdMeshers_RadialPrism_3D_i::IsApplicable( const TopoDS_Shape &S, CORBA::Boolean toCheckAll ) +{ + return ::StdMeshers_RadialPrism_3D::IsApplicable( S, toCheckAll ); +} diff --git a/src/StdMeshers_I/StdMeshers_Prism_3D_i.hxx b/src/StdMeshers_I/StdMeshers_Prism_3D_i.hxx index 56e28839c..8850f4d95 100644 --- a/src/StdMeshers_I/StdMeshers_Prism_3D_i.hxx +++ b/src/StdMeshers_I/StdMeshers_Prism_3D_i.hxx @@ -77,6 +77,9 @@ public: // Get implementation ::StdMeshers_RadialPrism_3D* GetImpl(); + + // Method return true if algorithm is applicable + static CORBA::Boolean IsApplicable(const TopoDS_Shape &S, CORBA::Boolean toCheckAll); }; diff --git a/src/StdMeshers_I/StdMeshers_Quadrangle_2D_i.cxx b/src/StdMeshers_I/StdMeshers_Quadrangle_2D_i.cxx index 91fb8b0a3..d169457fa 100644 --- a/src/StdMeshers_I/StdMeshers_Quadrangle_2D_i.cxx +++ b/src/StdMeshers_I/StdMeshers_Quadrangle_2D_i.cxx @@ -85,3 +85,16 @@ StdMeshers_Quadrangle_2D_i::~StdMeshers_Quadrangle_2D_i() return ( ::StdMeshers_Quadrangle_2D* )myBaseImpl; } +//============================================================================= +/*! + * StdMeshers_Quadrangle_2D_i::IsApplicable + * + * Method return true if algorithm is applicable + */ +//============================================================================= + +CORBA::Boolean StdMeshers_Quadrangle_2D_i::IsApplicable( const TopoDS_Shape &S, CORBA::Boolean toCheckAll ) +{ + return ::StdMeshers_Quadrangle_2D::IsApplicable( S, toCheckAll ); +} + diff --git a/src/StdMeshers_I/StdMeshers_Quadrangle_2D_i.hxx b/src/StdMeshers_I/StdMeshers_Quadrangle_2D_i.hxx index 52314f312..690e9dc47 100644 --- a/src/StdMeshers_I/StdMeshers_Quadrangle_2D_i.hxx +++ b/src/StdMeshers_I/StdMeshers_Quadrangle_2D_i.hxx @@ -58,6 +58,9 @@ public: // Get implementation ::StdMeshers_Quadrangle_2D* GetImpl(); + + // Method return true if algorithm is applicable + static CORBA::Boolean IsApplicable(const TopoDS_Shape &S, CORBA::Boolean toCheckAll); }; #endif diff --git a/src/StdMeshers_I/StdMeshers_RadialQuadrangle_1D2D_i.cxx b/src/StdMeshers_I/StdMeshers_RadialQuadrangle_1D2D_i.cxx index 28a6f4658..2e085910f 100644 --- a/src/StdMeshers_I/StdMeshers_RadialQuadrangle_1D2D_i.cxx +++ b/src/StdMeshers_I/StdMeshers_RadialQuadrangle_1D2D_i.cxx @@ -66,3 +66,9 @@ StdMeshers_RadialQuadrangle_1D2D_i::~StdMeshers_RadialQuadrangle_1D2D_i() return ( ::StdMeshers_RadialQuadrangle_1D2D* )myBaseImpl; } +//----------------------------------------------------------------------------- + +CORBA::Boolean StdMeshers_RadialQuadrangle_1D2D_i::IsApplicable( const TopoDS_Shape &S, CORBA::Boolean toCheckAll ) +{ + return ::StdMeshers_RadialQuadrangle_1D2D::IsApplicable( S, toCheckAll ); +} diff --git a/src/StdMeshers_I/StdMeshers_RadialQuadrangle_1D2D_i.hxx b/src/StdMeshers_I/StdMeshers_RadialQuadrangle_1D2D_i.hxx index 18513e344..c15ea3a71 100644 --- a/src/StdMeshers_I/StdMeshers_RadialQuadrangle_1D2D_i.hxx +++ b/src/StdMeshers_I/StdMeshers_RadialQuadrangle_1D2D_i.hxx @@ -47,6 +47,9 @@ public: // Get implementation ::StdMeshers_RadialQuadrangle_1D2D* GetImpl(); + + // Method return true if algorithm is applicable + static CORBA::Boolean IsApplicable(const TopoDS_Shape &S, CORBA::Boolean toCheckAll); }; diff --git a/src/StdMeshers_I/StdMeshers_i.cxx b/src/StdMeshers_I/StdMeshers_i.cxx index ecf1dd891..146692029 100644 --- a/src/StdMeshers_I/StdMeshers_i.cxx +++ b/src/StdMeshers_I/StdMeshers_i.cxx @@ -80,11 +80,21 @@ #include "StdMeshers_ViscousLayers2D_i.hxx" #include "StdMeshers_CartesianParameters3D_i.hxx" -template class StdHypothesisCreator_i:public HypothesisCreator_i +namespace SMESH { + class ApplicableToAny + { + public: + static CORBA::Boolean IsApplicable( const TopoDS_Shape &S, CORBA::Boolean toCheckAll ){ return true; } + }; +}; +template class StdHypothesisCreator_i:public HypothesisCreator_i { public: // as we have 'module StdMeshers' in SMESH_BasicHypothesis.idl virtual std::string GetModuleName() { return "StdMeshers"; } + virtual CORBA::Boolean IsApplicable( const TopoDS_Shape & S, CORBA::Boolean toCheckAll ) { + return TIsApplicable::IsApplicable( S, toCheckAll ); + } }; //============================================================================= @@ -203,9 +213,9 @@ STDMESHERS_I_EXPORT aCreator = new StdHypothesisCreator_i; #endif else if (strcmp(aHypName, "Quadrangle_2D") == 0) - aCreator = new StdHypothesisCreator_i; + aCreator = new StdHypothesisCreator_i; else if (strcmp(aHypName, "Hexa_3D") == 0) - aCreator = new StdHypothesisCreator_i; + aCreator = new StdHypothesisCreator_i; else if (strcmp(aHypName, "Projection_1D") == 0) aCreator = new StdHypothesisCreator_i; else if (strcmp(aHypName, "Projection_1D2D") == 0) @@ -217,7 +227,7 @@ STDMESHERS_I_EXPORT else if (strcmp(aHypName, "Prism_3D") == 0) aCreator = new StdHypothesisCreator_i; else if (strcmp(aHypName, "RadialPrism_3D") == 0) - aCreator = new StdHypothesisCreator_i; + aCreator = new StdHypothesisCreator_i; else if (strcmp(aHypName, "SegmentAroundVertex_0D") == 0) aCreator = new StdHypothesisCreator_i; else if (strcmp(aHypName, "CompositeSegment_1D") == 0) @@ -227,7 +237,7 @@ STDMESHERS_I_EXPORT else if (strcmp(aHypName, "UseExisting_2D") == 0) aCreator = new StdHypothesisCreator_i; else if (strcmp(aHypName, "RadialQuadrangle_1D2D") == 0) - aCreator = new StdHypothesisCreator_i; + aCreator = new StdHypothesisCreator_i; else if (strcmp(aHypName, "Import_1D") == 0) aCreator = new StdHypothesisCreator_i; else if (strcmp(aHypName, "Import_1D2D") == 0) -- 2.39.2