From 69a203b6d49da1ff98aaf5c53842ee6ab9efcec1 Mon Sep 17 00:00:00 2001 From: eap Date: Mon, 10 Apr 2006 15:24:41 +0000 Subject: [PATCH] reflect algo<->algo and algo->hypos dependencies in GUI --- resources/StdMeshers.xml | 14 +- src/SMESHGUI/SMESHGUI_Hypotheses.h | 37 ++- src/SMESHGUI/SMESHGUI_HypothesesUtils.cxx | 43 ++- src/SMESHGUI/SMESHGUI_HypothesesUtils.h | 7 + src/SMESHGUI/SMESHGUI_MeshDlg.cxx | 27 +- src/SMESHGUI/SMESHGUI_MeshDlg.h | 6 +- src/SMESHGUI/SMESHGUI_MeshOp.cxx | 347 ++++++++++++++++++---- src/SMESHGUI/SMESHGUI_MeshOp.h | 36 ++- src/SMESHGUI/SMESHGUI_XmlHandler.cxx | 17 +- 9 files changed, 428 insertions(+), 106 deletions(-) diff --git a/resources/StdMeshers.xml b/resources/StdMeshers.xml index 6daf06253..3f9de1a55 100644 --- a/resources/StdMeshers.xml +++ b/resources/StdMeshers.xml @@ -85,21 +85,31 @@ + hypos="LocalLength,Arithmetic1D,StartEndLength,NumberOfSegments,Deflection1D,AutomaticLength" + opt-hypos="Propagation,QuadraticMesh" + output="EDGE" + dim="1"/> + hypos="LengthFromEdges" + input="EDGE" + output="TRIA" + dim="2"/> diff --git a/src/SMESHGUI/SMESHGUI_Hypotheses.h b/src/SMESHGUI/SMESHGUI_Hypotheses.h index b62ccdbd0..47546d233 100644 --- a/src/SMESHGUI/SMESHGUI_Hypotheses.h +++ b/src/SMESHGUI/SMESHGUI_Hypotheses.h @@ -128,22 +128,31 @@ private: class HypothesisData { public: - HypothesisData( const QString& thePluginName, + HypothesisData( const QString& theTypeName, + const QString& thePluginName, const QString& theServerLibName, const QString& theClientLibName, const QString& theLabel, const QString& theIconId, const QValueList& theDim, - const bool theIsAux ) -: PluginName( thePluginName ), - ServerLibName( theServerLibName ), - ClientLibName( theClientLibName ), - Label( theLabel ), - IconId( theIconId ), - Dim( theDim ), - IsAux( theIsAux ) - {}; - + const bool theIsAux, + const QStringList& theNeededHypos, + const QStringList& theOptionalHypos, + const QStringList& theInputTypes, + const QStringList& theOutputTypes) + : TypeName( theTypeName ), + PluginName( thePluginName ), + ServerLibName( theServerLibName ), + ClientLibName( theClientLibName ), + Label( theLabel ), + IconId( theIconId ), + Dim( theDim ), + IsAux( theIsAux ), + NeededHypos( theNeededHypos ), OptionalHypos( theOptionalHypos ), + InputTypes( theInputTypes ), OutputTypes( theOutputTypes ) + {}; + + QString TypeName; //!< hypothesis type name QString PluginName; //!< plugin name QString ServerLibName; //!< server library name QString ClientLibName; //!< client library name @@ -151,6 +160,12 @@ class HypothesisData QString IconId; //!< icon identifier QValueList Dim; //!< list of supported dimensions (see SMESH::Dimension enumeration) bool IsAux; //!< TRUE if given hypothesis is auxiliary one, FALSE otherwise + + // for algorithm only: dependencies algo <-> algo and algo -> hypos + QStringList NeededHypos; //!< list of obligatory hypotheses + QStringList OptionalHypos;//!< list of optional hypotheses + QStringList InputTypes; //!< list of element types required as a prerequisite + QStringList OutputTypes; //!< list of types of generated elements }; /*! diff --git a/src/SMESHGUI/SMESHGUI_HypothesesUtils.cxx b/src/SMESHGUI/SMESHGUI_HypothesesUtils.cxx index 5f4d6d2f4..556dc5591 100644 --- a/src/SMESHGUI/SMESHGUI_HypothesesUtils.cxx +++ b/src/SMESHGUI/SMESHGUI_HypothesesUtils.cxx @@ -250,17 +250,50 @@ namespace SMESH{ // Init list of available hypotheses, if needed InitAvailableHypotheses(); - if (myHypothesesMap.find(aHypType) == myHypothesesMap.end()) { - if (myAlgorithmsMap.find(aHypType) != myAlgorithmsMap.end()) { - aHypData = myAlgorithmsMap[aHypType]; - } + THypothesisDataMap::iterator type_data = myHypothesesMap.find(aHypType); + if (type_data != myHypothesesMap.end()) { + aHypData = type_data->second; } else { - aHypData = myHypothesesMap[aHypType]; + type_data = myAlgorithmsMap.find(aHypType); + if (type_data != myAlgorithmsMap.end()) + aHypData = type_data->second; } return aHypData; } + bool IsAvailableHypothesis(const HypothesisData* algoData, + const QString& hypType, + bool& isAuxiliary) + { + isAuxiliary = false; + if ( !algoData ) + return false; + if ( algoData->NeededHypos.contains( hypType )) + return true; + if ( algoData->OptionalHypos.contains( hypType)) { + isAuxiliary = true; + return true; + } + return false; + } + + bool IsCompatibleAlgorithm(const HypothesisData* algo1Data, + const HypothesisData* algo2Data) + { + if ( !algo1Data || !algo2Data ) + return false; + const HypothesisData* algoIn = algo1Data, *algoMain = algo2Data; + if ( algoIn->Dim.first() > algoMain->Dim.first() ) { + algoIn = algo2Data; algoMain = algo1Data; + } + // look for any output type of algoIn between input types of algoMain + QStringList::const_iterator inElemType = algoIn->OutputTypes.begin(); + for ( ; inElemType != algoIn->OutputTypes.end(); ++inElemType ) + if ( algoMain->InputTypes.contains( *inElemType )) + return true; + return false; + } SMESHGUI_GenericHypothesisCreator* GetHypothesisCreator(const char* aHypType) { diff --git a/src/SMESHGUI/SMESHGUI_HypothesesUtils.h b/src/SMESHGUI/SMESHGUI_HypothesesUtils.h index 2fb920af9..15767b0f7 100644 --- a/src/SMESHGUI/SMESHGUI_HypothesesUtils.h +++ b/src/SMESHGUI/SMESHGUI_HypothesesUtils.h @@ -61,6 +61,13 @@ namespace SMESH{ HypothesisData* GetHypothesisData(const char* aHypType); + bool IsAvailableHypothesis(const HypothesisData* algoData, + const QString& hypType, + bool& isOptional); + + bool IsCompatibleAlgorithm(const HypothesisData* algo1Data, + const HypothesisData* algo2Data); + SMESHGUI_GenericHypothesisCreator* GetHypothesisCreator(const char* aHypType); SMESH::SMESH_Hypothesis_ptr CreateHypothesis(const char* aHypType, diff --git a/src/SMESHGUI/SMESHGUI_MeshDlg.cxx b/src/SMESHGUI/SMESHGUI_MeshDlg.cxx index a9dbbcaa1..7b1b6e77c 100644 --- a/src/SMESHGUI/SMESHGUI_MeshDlg.cxx +++ b/src/SMESHGUI/SMESHGUI_MeshDlg.cxx @@ -115,6 +115,7 @@ SMESHGUI_MeshTab::SMESHGUI_MeshTab( QWidget* theParent ) connect( myEditHyp[ i ], SIGNAL( clicked() ), SLOT( onEditHyp() ) ); connect( myHyp[ i ], SIGNAL( activated( int ) ), SLOT( onHyp( int ) ) ); } + connect( myHyp[ Algo ], SIGNAL( activated( int ) ), SLOT( onHyp( int ) ) ); // Initialize controls @@ -141,6 +142,8 @@ SMESHGUI_MeshTab::~SMESHGUI_MeshTab() void SMESHGUI_MeshTab::setAvailableHyps( const int theId, const QStringList& theHyps ) { myAvailableHyps[ theId ] = theHyps; + + bool enable = ! theHyps.isEmpty(); if ( theId == Algo ) { myHyp[ Algo ]->clear(); @@ -148,6 +151,11 @@ void SMESHGUI_MeshTab::setAvailableHyps( const int theId, const QStringList& the myHyp[ Algo ]->insertStringList( theHyps ); myHyp[ Algo ]->setCurrentItem( 0 ); } + else { + myCreateHyp[ theId ]->setEnabled( enable ); + myEditHyp[ theId ]->setEnabled( false ); + } + myHyp[ theId ]->setEnabled( enable ); } //================================================================================ @@ -295,15 +303,20 @@ void SMESHGUI_MeshTab::onEditHyp() /*! * \brief Updates "Edit hypothesis" button state * - * SLOT called when current hypothesis changed disables "Edit hypothesis" button - * if current hypothesis is , enables otherwise + * SLOT called when current hypothesis changed. Disables "Edit hypothesis" button + * if current hypothesis is , enables otherwise. + * If an algorithm changed, emits selectAlgo( theIndex ) signal */ //================================================================================ void SMESHGUI_MeshTab::onHyp( int theIndex ) { const QObject* aSender = sender(); - int anIndex = aSender == myHyp[ MainHyp ] ? MainHyp : AddHyp; - myEditHyp[ anIndex ]->setEnabled( theIndex > 0 ); + if ( aSender == myHyp[ Algo ] ) + emit selectAlgo( theIndex - 1 ); // - 1 because there is NONE on the top + else { + int anIndex = aSender == myHyp[ MainHyp ] ? MainHyp : AddHyp; + myEditHyp[ anIndex ]->setEnabled( theIndex > 0 ); + } } //================================================================================ @@ -379,9 +392,9 @@ SMESHGUI_MeshDlg::SMESHGUI_MeshDlg( const bool theToCreate, const bool theIsMesh myTabs[ Dim1D ] = new SMESHGUI_MeshTab( myTabWg ); myTabs[ Dim2D ] = new SMESHGUI_MeshTab( myTabWg ); myTabs[ Dim3D ] = new SMESHGUI_MeshTab( myTabWg ); - myTabWg->addTab( myTabs[ Dim1D ], tr( "DIM_1D" ) ); - myTabWg->addTab( myTabs[ Dim2D ], tr( "DIM_2D" ) ); myTabWg->addTab( myTabs[ Dim3D ], tr( "DIM_3D" ) ); + myTabWg->addTab( myTabs[ Dim2D ], tr( "DIM_2D" ) ); + myTabWg->addTab( myTabs[ Dim1D ], tr( "DIM_1D" ) ); // Hypotheses Sets myHypoSetPopup = new QPopupMenu(); @@ -462,7 +475,7 @@ void SMESHGUI_MeshDlg::reset() //================================================================================ void SMESHGUI_MeshDlg::setCurrentTab( const int theId ) { - myTabWg->setCurrentPage( theId ); + myTabWg->setCurrentPage( Dim3D - theId ); } //================================================================================ diff --git a/src/SMESHGUI/SMESHGUI_MeshDlg.h b/src/SMESHGUI/SMESHGUI_MeshDlg.h index f12773bd1..0e97c8c30 100644 --- a/src/SMESHGUI/SMESHGUI_MeshDlg.h +++ b/src/SMESHGUI/SMESHGUI_MeshDlg.h @@ -129,6 +129,8 @@ signals: //!< Emited when "Create hypothesis" button clicked void editHyp( const int theHypType, const int theIndex ); //!< Emited when "Edit hypothesis" button clicked + void selectAlgo( const int theIndex ); + //!< Emited when an algorithm is selected private slots: @@ -150,7 +152,3 @@ private: }; #endif - - - - diff --git a/src/SMESHGUI/SMESHGUI_MeshOp.cxx b/src/SMESHGUI/SMESHGUI_MeshOp.cxx index 823ad4d7f..8fe50a06a 100644 --- a/src/SMESHGUI/SMESHGUI_MeshOp.cxx +++ b/src/SMESHGUI/SMESHGUI_MeshOp.cxx @@ -203,9 +203,11 @@ void SMESHGUI_MeshOp::startOperation() for ( int i = SMESH::DIM_1D; i <= SMESH::DIM_3D; i++ ) { connect( myDlg->tab( i ), SIGNAL( createHyp( const int, const int ) ), - this, SLOT( onCreateHyp( const int, const int) ) ); + this, SLOT( onCreateHyp( const int, const int ) ) ); connect( myDlg->tab( i ), SIGNAL( editHyp( const int, const int ) ), - this, SLOT( onEditHyp( const int, const int) ) ); + this, SLOT( onEditHyp( const int, const int ) ) ); + connect( myDlg->tab( i ), SIGNAL( selectAlgo( const int ) ), + this, SLOT( onAlgoSelected( const int ) ) ); } connect( myDlg, SIGNAL( hypoSet( const QString& )), SLOT( onHypoSet( const QString& ))); connect( myDlg, SIGNAL( geomSelectionByMesh( bool )), SLOT( onGeomSelectionByMesh( bool ))); @@ -217,22 +219,19 @@ void SMESHGUI_MeshOp::startOperation() } SMESHGUI_SelectionOp::startOperation(); - // iterate through dimensions and get available and existing algoritms and hypotheses, + // iterate through dimensions and get available algoritms, // set them to the dialog - int i, j; _PTR(SComponent) aFather = SMESH::GetActiveStudyDocument()->FindComponent( "SMESH" ); - for ( i = SMESH::DIM_1D; i <= SMESH::DIM_3D; i++ ) + for ( int i = SMESH::DIM_1D; i <= SMESH::DIM_3D; i++ ) { SMESHGUI_MeshTab* aTab = myDlg->tab( i ); - QStringList anAvailable, anExisting; - for ( j = Algo; j <= AddHyp; j++ ) - { - availableHyps( i, j, anAvailable ); - existingHyps( i, j, aFather, anExisting, myExistingHyps[ i ][ j ] ); - - aTab->setAvailableHyps( j, anAvailable ); - aTab->setExistingHyps( j, anExisting ); - } + QStringList anAvailable; + // clear available hypotheses + aTab->setAvailableHyps( MainHyp, anAvailable ); + aTab->setAvailableHyps( AddHyp, anAvailable ); + // set algos + availableHyps( i, Algo, anAvailable, myAvailableHypData[i][Algo] ); + aTab->setAvailableHyps( Algo, anAvailable ); } if ( myToCreate ) { @@ -244,7 +243,7 @@ void SMESHGUI_MeshOp::startOperation() myDlg->setHypoSets( SMESH::GetHypothesesSets() ); - myDlg->setCurrentTab( SMESH::DIM_1D ); + myDlg->setCurrentTab( SMESH::DIM_3D ); myDlg->show(); selectionDone(); @@ -580,6 +579,31 @@ bool SMESHGUI_MeshOp::isValid( QString& theMess ) const return true; } +//================================================================================ +/*! + * \brief check compatibility of the algorithm and another algorithm or hypothesis + * \param theAlgoData - algorithm data + * \param theHypData - hypothesis data + * \param theHypType - hypothesis type + * \param theHypTypeName - hypothesis type name, must be provided if 2-nd arg is not algo + * \retval bool - check result + */ +//================================================================================ + +static bool isCompatible(const HypothesisData* theAlgoData, + const HypothesisData* theHypData, + const int theHypType) +{ + if ( !theAlgoData ) + return true; + + if ( theHypType == SMESHGUI_MeshOp::Algo ) + return SMESH::IsCompatibleAlgorithm( theAlgoData, theHypData ); + + bool isAux; + return ( SMESH::IsAvailableHypothesis( theAlgoData, theHypData->TypeName, isAux )); +} + //================================================================================ /*! * \brief Gets available hypotheses or algorithms @@ -587,22 +611,31 @@ bool SMESHGUI_MeshOp::isValid( QString& theMess ) const * \param theHypType - specifies whether algorims or hypotheses or additional ones * are retrieved (possible values are in HypType enumeration) * \param theHyps - Output list of hypotheses' names + * \param theAlgoData - to select hypos able to be used by this algo (optional) * * Gets available hypotheses or algorithm in accordance with input parameters */ //================================================================================ -void SMESHGUI_MeshOp::availableHyps( const int theDim, - const int theHypType, - QStringList& theHyps ) const +void SMESHGUI_MeshOp::availableHyps( const int theDim, + const int theHypType, + QStringList& theHyps, + THypDataList& theDataList, + HypothesisData* theAlgoData ) const { + theDataList.clear(); theHyps.clear(); - QStringList aHypTypeNameList = SMESH::GetAvailableHypotheses( - theHypType == Algo , theDim, theHypType == AddHyp ); + bool isAlgo = ( theHypType == Algo ); + bool isAux = ( theHypType == AddHyp ); + QStringList aHypTypeNameList = SMESH::GetAvailableHypotheses( isAlgo, theDim, isAux ); + QStringList::const_iterator anIter; for ( anIter = aHypTypeNameList.begin(); anIter != aHypTypeNameList.end(); ++anIter ) { HypothesisData* aData = SMESH::GetHypothesisData( *anIter ); - theHyps.append( aData->Label ); + if ( isCompatible ( theAlgoData, aData, theHypType )) { + theDataList.append( aData ); + theHyps.append( aData->Label ); + } } } @@ -613,8 +646,10 @@ void SMESHGUI_MeshOp::availableHyps( const int theDim, * \param theHypType - specifies whether algorims or hypotheses or additional ones * are retrieved (possible values are in HypType enumeration) * \param theFather - start object for finding ( may be component, mesh, or sub-mesh ) + * \param theDataList - output list of hypotheses data * \param theHyps - output list of names. * \param theHypVars - output list of variables. + * \param theAlgoData - to select hypos able to be used by this algo (optional) * * Gets existing (i.e. already created) hypotheses or algorithm in accordance with * input parameters @@ -624,7 +659,8 @@ void SMESHGUI_MeshOp::existingHyps( const int theDim, const int theHypType, _PTR(SObject) theFather, QStringList& theHyps, - QValueList& theHypVars ) + QValueList& theHypVars, + HypothesisData* theAlgoData) { // Clear hypoheses list theHyps.clear(); @@ -633,6 +669,8 @@ void SMESHGUI_MeshOp::existingHyps( const int theDim, if ( !theFather ) return; + const bool isAux = ( theHypType == AddHyp ); + _PTR(SObject) aHypRoot; _PTR(GenericAttribute) anAttr; _PTR(AttributeName) aName; @@ -672,8 +710,10 @@ void SMESHGUI_MeshOp::existingHyps( const int theDim, QString aHypType( aHypVar->GetName() ); HypothesisData* aData = SMESH::GetHypothesisData( aHypType ); if ( ( theDim == -1 || aData->Dim.contains( theDim ) ) && - ( theHypType == AddHyp ) == aData->IsAux ) + ( isCompatible ( theAlgoData, aData, theHypType )) && + ( isAux == aData->IsAux )) { + //theDataList.append( aData ); theHyps.append( aName->Value().c_str() ); theHypVars.append( aHypVar ); } @@ -744,6 +784,24 @@ SMESHGUI_MeshOp::getInitParamsHypothesis( const QString& aHypType, return SMESH::SMESH_Hypothesis::_nil(); } +//================================================================================ +/*! + * \Brief Returns tab dimention + * \param tab - the tab in the dlg + * \param dlg - my dialogue + * \retval int - dimention + */ +//================================================================================ + +static int getTabDim (const QObject* tab, SMESHGUI_MeshDlg* dlg ) +{ + int aDim = -1; + for (int i = SMESH::DIM_1D; i <= SMESH::DIM_3D; i++) + if (tab == dlg->tab(i)) + aDim = i; + return aDim; +} + //================================================================================ /*! * \brief Create hypothesis @@ -757,19 +815,15 @@ SMESHGUI_MeshOp::getInitParamsHypothesis( const QString& aHypType, void SMESHGUI_MeshOp::onCreateHyp( const int theHypType, const int theIndex ) { // Specifies dimension of hypothesis to be created - const QObject* aSender = sender(); - int aDim = -1; - for (int i = SMESH::DIM_1D; i <= SMESH::DIM_3D; i++) - if (aSender == myDlg->tab(i)) - aDim = i; + int aDim = getTabDim( sender(), myDlg ); if (aDim == -1) return; // Specifies type of hypothesis to be created - QStringList aHypTypeNames = SMESH::GetAvailableHypotheses(false, aDim, theHypType == AddHyp); - if (theIndex < 0 || theIndex >= aHypTypeNames.count()) + THypDataList& dataList = myAvailableHypData[ aDim ][ theHypType ]; + if (theIndex < 0 || theIndex >= dataList.count()) return; - QString aHypTypeName = aHypTypeNames[ theIndex ]; + QString aHypTypeName = dataList[ theIndex ]->TypeName; // Create hypothesis createHypothesis(aDim, theHypType, aHypTypeName); @@ -792,8 +846,7 @@ void SMESHGUI_MeshOp::createHypothesis (const int theDim, return; // existing hypos - QValueList& aList = myExistingHyps[theDim][theType]; - int nbHyp = aList.count(); + int nbHyp = myExistingHyps[theDim][theType].count(); QString aClientLibName = aData->ClientLibName; if (aClientLibName == "") { @@ -817,8 +870,9 @@ void SMESHGUI_MeshOp::createHypothesis (const int theDim, _PTR(SComponent) aFather = SMESH::GetActiveStudyDocument()->FindComponent("SMESH"); + HypothesisData* algoData = hypData( theDim, Algo, currentHyp( theDim, Algo )); QStringList aNewHyps; - existingHyps(theDim, theType, aFather, aNewHyps, myExistingHyps[theDim][theType]); + existingHyps(theDim, theType, aFather, aNewHyps, myExistingHyps[theDim][theType], algoData); if (aNewHyps.count() > nbHyp) { for (int i = nbHyp; i < aNewHyps.count(); i++) myDlg->tab(theDim)->addHyp(theType, aNewHyps[i]); @@ -838,15 +892,13 @@ void SMESHGUI_MeshOp::createHypothesis (const int theDim, void SMESHGUI_MeshOp::onEditHyp( const int theHypType, const int theIndex ) { // Speicfies dimension of hypothesis to be created - const QObject* aSender = sender(); - int aDim = -1; - for ( int i = SMESH::DIM_1D; i <= SMESH::DIM_3D; i++ ) - if ( aSender == myDlg->tab( i ) ) - aDim = i; - if ( aDim == -1 ) + int aDim = getTabDim( sender(), myDlg ); + if (aDim == -1) return; QValueList aList = myExistingHyps[ aDim ][ theHypType ]; + if ( theIndex < 0 || theIndex >= aList.count() ) + return; SMESH::SMESH_Hypothesis_var aHyp = aList[ theIndex - 1 ]; if ( aHyp->_is_nil() ) return; @@ -857,6 +909,150 @@ void SMESHGUI_MeshOp::onEditHyp( const int theHypType, const int theIndex ) aCreator->edit( aHyp.in(), dlg() ); } +//================================================================================ +/*! + * \brief access to hypothesis data + * \param theDim - hyp dimension + * \param theHypType - hyp type (Algo,MainHyp or AddHyp) + * \param theIndex - index in the list + * \retval HypothesisData* - result data, may be 0 + */ +//================================================================================ + +HypothesisData* SMESHGUI_MeshOp::hypData( const int theDim, + const int theHypType, + const int theIndex) +{ + if ( theDim > -1 && theDim < 3 && + theHypType > -1 && theHypType < NbHypTypes && + theIndex > -1 && theIndex < myAvailableHypData[ theDim ][ theHypType ].count() ) + return myAvailableHypData[ theDim ][ theHypType ][ theIndex ]; + return 0; +} + +//================================================================================ +/*! + * \brief Set available algos and hypos according to the selected algorithm + * \param theIndex - algorithm index + */ +//================================================================================ + +void SMESHGUI_MeshOp::onAlgoSelected( const int theIndex, + const int theDim ) +{ + if ( myIgnoreAlgoSelection ) + return; + + int aDim = theDim < 0 ? getTabDim( sender(), myDlg ): theDim; + if (aDim == -1) + return; + + // find highest available dimension, all algos of this dimension are available for choice + int aTopDim = -1; + for (int i = SMESH::DIM_1D; i <= SMESH::DIM_3D; i++) + if (isAccessibleDim( i )) + aTopDim = i; + if (aTopDim == -1) + return; + + HypothesisData* algoData = hypData( aDim, Algo, theIndex ); + HypothesisData* algoByDim[3]; + 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 algorithms of other dimentions are compatible with + // the selected one + + // 2 loops: backward and forward from algo dimension + for ( int forward = false; forward <= true; ++forward ) + { + int dim = aDim + 1, lastDim = SMESH::DIM_3D, dir = 1; + if ( !forward ) { + dim = aDim - 1; lastDim = SMESH::DIM_1D; dir = -1; + } + HypothesisData* prevAlgo = algoData; + for ( ; dim * dir <= lastDim * dir ; dim += dir ) + { + if ( !isAccessibleDim( dim )) + continue; + // get currently selected algo + int algoIndex = currentHyp( dim, Algo ); + HypothesisData* curAlgo = hypData( dim, Algo, algoIndex ); + if ( curAlgo ) { // some algo selected + if ( !isCompatible( prevAlgo, curAlgo, Algo )) + curAlgo = 0; + } + // set new available algoritms + availableHyps( dim, Algo, anAvailable, myAvailableHypData[dim][Algo], prevAlgo ); + 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 ); + myDlg->tab( dim )->setAvailableHyps( Algo, anAvailable ); + + // restore previously selected algo + algoIndex = myAvailableHypData[dim][Algo].findIndex( curAlgo ); + if ( algoIndex < 0 && soleCompatible ) + // select the sole compatible algo + algoIndex = myAvailableHypData[dim][Algo].findIndex( soleCompatible ); + setCurrentHyp( dim, Algo, algoIndex ); + + // remember current algo + prevAlgo = algoByDim[ dim ] = hypData( dim, Algo, algoIndex ); + } + } + + // set hypotheses corresponding to the found algoritms + + QString anObjEntry = myDlg->selectedObject( SMESHGUI_MeshDlg::Obj ); + _PTR(SObject) pObj = studyDS()->FindObjectID( anObjEntry.latin1() ); + if ( !pObj ) + pObj = SMESH::GetActiveStudyDocument()->FindComponent("SMESH"); + + for ( int dim = SMESH::DIM_1D; dim <= SMESH::DIM_3D; dim++ ) + { + if ( !isAccessibleDim( dim )) + continue; + for ( int type = MainHyp; type < NbHypTypes; type++ ) + { + myAvailableHypData[ dim ][ type ].clear(); + QStringList anAvailable, anExisting; + SMESH::SMESH_Hypothesis_var curHyp; + + // get hyps compatible with curAlgo + if ( HypothesisData* curAlgo = algoByDim[ dim ] ) + { + // get current existing hypothesis + int hypIndex = currentHyp( dim, type ); + if ( hypIndex >= 0 && hypIndex < myExistingHyps[ dim ][ type ].count() ) { + curHyp = myExistingHyps[ dim ][ type ][ hypIndex ]; + QString hypTypeName = curHyp->GetName(); + HypothesisData* hypData = SMESH::GetHypothesisData( hypTypeName ); + if ( !isCompatible( curAlgo, hypData, type )) + curHyp = SMESH::SMESH_Hypothesis::_nil(); + } + existingHyps( dim, type, pObj, anExisting, myExistingHyps[ dim ][ type ], curAlgo); + availableHyps( dim, type, anAvailable, myAvailableHypData[ dim ][ type ], curAlgo); + } + // set list of hypotheses + myDlg->tab( dim )->setAvailableHyps( type, anAvailable ); + myDlg->tab( dim )->setExistingHyps( type, anExisting ); + + // set current hypothesis + int hypIndex = -1; + if ( !curHyp->_is_nil() && !anExisting.isEmpty() ) + hypIndex = this->find( curHyp, myExistingHyps[ dim ][ type ]); + setCurrentHyp( dim, type, hypIndex ); + } + } +} + //================================================================================ /*! * \brief Creates and selects hypothesis of hypotheses set @@ -886,12 +1082,21 @@ void SMESHGUI_MeshOp::onHypoSet( const QString& theSetName ) int aDim = aHypData->Dim[0]; // create or/and set if (isAlgo) { - QStringList aHypTypeNameList = SMESH::GetAvailableHypotheses(isAlgo, aDim); - int index = aHypTypeNameList.findIndex(aHypoTypeName); - if (index < 0) continue; - setCurrentHyp(aDim, aHypType, index); - } else { - createHypothesis(aDim, aHypType, aHypoTypeName); + QStringList tmp; + availableHyps( aDim, Algo, tmp, myAvailableHypData[aDim][Algo] ); + int index = myAvailableHypData[aDim][Algo].findIndex( aHypData ); + setCurrentHyp( aDim, Algo, index ); + onAlgoSelected( index, aDim ); + } + else { + bool mainHyp = true; + int index = myAvailableHypData[aDim][MainHyp].findIndex( aHypData ); + if ( index < 0 ) { + mainHyp = false; + index = myAvailableHypData[aDim][AddHyp].findIndex( aHypData ); + } + if (index >= 0) + createHypothesis(aDim, mainHyp ? MainHyp : AddHyp, aHypoTypeName); } } // loop on hypos in the set } // loop on algo/hypo @@ -1033,7 +1238,7 @@ int SMESHGUI_MeshOp::currentHyp( const int theDim, const int theHypType ) const * \retval bool - result */ //================================================================================ -bool SMESHGUI_MeshOp::isAccessibleDim( const int theDim) const +bool SMESHGUI_MeshOp::isAccessibleDim( const int theDim ) const { return myDlg->tab( theDim )->isEnabled(); } @@ -1052,7 +1257,9 @@ void SMESHGUI_MeshOp::setCurrentHyp( const int theDim, const int theHypType, const int theIndex ) { + myIgnoreAlgoSelection = true; myDlg->tab( theDim )->setCurrentHyp( theHypType, theIndex + 1 ); + myIgnoreAlgoSelection = false; } //================================================================================ @@ -1094,11 +1301,20 @@ void SMESHGUI_MeshOp::setDefaultName() const SMESH::SMESH_Hypothesis_var SMESHGUI_MeshOp::getAlgo( const int theDim ) { SMESH::SMESH_Hypothesis_var anAlgoVar; + + // get type of the selected algo int aHypIndex = currentHyp( theDim, Algo ); - QStringList aHypTypeNameList = SMESH::GetAvailableHypotheses( true, theDim, false ); - if ( aHypIndex < 0 || aHypIndex >= aHypTypeNameList.count() ) + THypDataList& dataList = myAvailableHypData[ theDim ][ Algo ]; + if ( aHypIndex < 0 || aHypIndex >= dataList.count()) return anAlgoVar; - QString aHypName = aHypTypeNameList[ aHypIndex ]; + QString aHypName = dataList[ aHypIndex ]->TypeName; + + // get existing algoritms + _PTR(SObject) pObj = SMESH::GetActiveStudyDocument()->FindComponent("SMESH"); + QStringList tmp; + existingHyps( theDim, Algo, pObj, tmp, myExistingHyps[ theDim ][ Algo ]); + + // look for anexisting algo of such a type QValueList& aHypVarList = myExistingHyps[ theDim ][ Algo ]; QValueList::iterator anIter; for ( anIter = aHypVarList.begin(); anIter != aHypVarList.end(); anIter++ ) @@ -1195,26 +1411,21 @@ void SMESHGUI_MeshOp::readMesh() existingHyps( dim, Algo, pObj, anExisting, myObjHyps[ dim ][ Algo ] ); if ( myObjHyps[ dim ][ Algo ].count() > 0 ) { + // find algo index among available ones SMESH::SMESH_Hypothesis_var aVar = myObjHyps[ dim ][ Algo ].first(); QString aHypTypeName = aVar->GetName(); - - QStringList aHypTypeNameList = SMESH::GetAvailableHypotheses( true , dim, false ); - for ( int i = 0, n = aHypTypeNameList.count(); i < n; i++ ) - if ( aHypTypeName == aHypTypeNameList[ i ] ) - { - aHypIndex = i; - break; - } + HypothesisData* algoData = SMESH::GetHypothesisData( aHypTypeName ); + aHypIndex = myAvailableHypData[ dim ][ Algo ].findIndex ( algoData ); } setCurrentHyp( dim, Algo, aHypIndex ); + onAlgoSelected( aHypIndex, dim ); // get hypotheses for ( int hypType = MainHyp; hypType <= AddHyp; hypType++ ) { // get hypotheses existingHyps( dim, hypType, pObj, anExisting, myObjHyps[ dim ][ hypType ] ); - // find index of requered hypothesis among existing ones for this dimension - // and hyp types + // find index of requered hypothesis among existing ones for this dimension and type int aHypIndex = -1; if ( myObjHyps[ dim ][ hypType ].count() > 0 ) aHypIndex = find( myObjHyps[ dim ][ hypType ].first(), @@ -1331,9 +1542,10 @@ bool SMESHGUI_MeshOp::editMeshOrSubMesh( QString& theMess ) } } // remove old algorithm - if ( toDelete ) - SMESH::RemoveHypothesisOrAlgorithmOnMesh - ( pObj, myObjHyps[ dim ][ Algo ].first() ); + if ( toDelete ) { + SMESH::RemoveHypothesisOrAlgorithmOnMesh ( pObj, myObjHyps[ dim ][ Algo ].first() ); + myObjHyps[ dim ][ Algo ].clear(); + } // assign new algorithm if ( toAdd ) { @@ -1348,6 +1560,7 @@ bool SMESHGUI_MeshOp::editMeshOrSubMesh( QString& theMess ) if ( !aVar->_is_nil() ) SMESH::AddHypothesisOnSubMesh( aVar, anAlgoVar ); } + myObjHyps[ dim ][ Algo ].append( anAlgoVar ); } // assign hypotheses @@ -1361,9 +1574,11 @@ bool SMESHGUI_MeshOp::editMeshOrSubMesh( QString& theMess ) if ( aNewHypIndex != anOldHypIndex ) { // remove old hypotheses - if ( anOldHypIndex >= 0 ) + if ( anOldHypIndex >= 0 ) { SMESH::RemoveHypothesisOrAlgorithmOnMesh( pObj, myExistingHyps[ dim ][ hypType ][ anOldHypIndex ] ); + myExistingHyps.remove( anOldHypIndex ); + } // assign new hypotheses if ( aNewHypIndex != -1 ) @@ -1435,9 +1650,9 @@ void SMESHGUI_MeshOp::onGeomSelectionByMesh( bool theByMesh ) SMESH::SMESH_Mesh_var aMeshVar = SMESH::SMESH_Mesh::_narrow( _CAST( SObject,pMesh )->GetObject() ); if ( !aMeshVar->_is_nil() ) { - myDlg->hide(); + myDlg->hide(); // stop processing selection myShapeByMeshOp->setModule( getSMESHGUI() ); - myShapeByMeshOp->setStudy( 0 ); + myShapeByMeshOp->setStudy( 0 ); // it's really necessary myShapeByMeshOp->SetMesh( aMeshVar ); myShapeByMeshOp->start(); } diff --git a/src/SMESHGUI/SMESHGUI_MeshOp.h b/src/SMESHGUI/SMESHGUI_MeshOp.h index 13546ff22..51492c3ee 100644 --- a/src/SMESHGUI/SMESHGUI_MeshOp.h +++ b/src/SMESHGUI/SMESHGUI_MeshOp.h @@ -41,6 +41,7 @@ class SMESHGUI_MeshDlg; class SMESHGUI_ShapeByMeshOp; +class HypothesisData; /*! * \brief Operation for mech creation or editing @@ -51,9 +52,10 @@ class SMESHGUI_MeshOp : public SMESHGUI_SelectionOp { Q_OBJECT - enum HypType{ Algo = 0, MainHyp, AddHyp }; - public: + + enum HypType{ Algo = 0, MainHyp, AddHyp, NbHypTypes }; + SMESHGUI_MeshOp( const bool theToCreate, const bool theIsMesh = true ); virtual ~SMESHGUI_MeshOp(); @@ -73,17 +75,28 @@ protected slots: void onGeomSelectionByMesh( bool ); void onPublishShapeByMeshDlg(SUIT_Operation*); void onCloseShapeByMeshDlg(SUIT_Operation*); + void onAlgoSelected( const int theIndex, + const int theDim = -1); private: + + typedef QValueList THypDataList; // typedef: list of hypothesis data + bool isValid( QString& ) const; - void availableHyps( const int theDim, - const int theHypType, - QStringList& theHyps ) const; - void existingHyps( const int theDim, - const int theHypType, + void availableHyps( const int theDim, + const int theHypType, + QStringList& theHyps, + THypDataList& theDataList, + HypothesisData* theAlgoData = 0 ) const; + void existingHyps( const int theDim, + const int theHypType, _PTR(SObject) theFather, - QStringList& theHyps, - QValueList& theHypVars ); + QStringList& theHyps, + QValueList& theHypVars, + HypothesisData* theAlgoData = 0); + HypothesisData* hypData( const int theDim, + const int theHypType, + const int theIndex); // access to myAvailableHypData void createHypothesis(const int theDim, const int theType, const QString& theTypeName); @@ -119,6 +132,11 @@ private: DimToHypMap myExistingHyps; //!< all hypothesis of SMESH module DimToHypMap myObjHyps; //!< hypothesis assigned to the current // edited mesh/sub-mesh + + // hypdata corresponding to hypotheses present in myDlg + THypDataList myAvailableHypData[3][NbHypTypes]; + + bool myIgnoreAlgoSelection; }; #endif diff --git a/src/SMESHGUI/SMESHGUI_XmlHandler.cxx b/src/SMESHGUI/SMESHGUI_XmlHandler.cxx index 76e138511..15cea62b5 100644 --- a/src/SMESHGUI/SMESHGUI_XmlHandler.cxx +++ b/src/SMESHGUI/SMESHGUI_XmlHandler.cxx @@ -128,10 +128,23 @@ bool SMESHGUI_XmlHandler::startElement (const QString&, const QString&, if ( isOk ) aDim.append( aVal - 1 ); } + + // for algo + enum { HYPOS = 0, OPT_HYPOS, INPUT, OUTPUT, NB_ATTRIBUTES }; + const char* name [NB_ATTRIBUTES] = { "hypos", "opt-hypos", "input", "output" }; + QStringList attr [NB_ATTRIBUTES]; + for ( int i = 0; i < NB_ATTRIBUTES; ++i ) { + QString aStr = atts.value( name[i] ); + if ( !aStr.isEmpty() ) { + aStr.remove( ' ' ); + attr[ i ] = QStringList::split( ',', aStr ); + } + } HypothesisData* aHypLibNames = - new HypothesisData (myPluginName, myServerLib, myClientLib, - aLabel, anIcon, aDim, isAux ); + new HypothesisData (aHypAlType, myPluginName, myServerLib, myClientLib, + aLabel, anIcon, aDim, isAux, + attr[ HYPOS ], attr[ OPT_HYPOS ], attr[ INPUT ], attr[ OUTPUT ]); if (qName == "algorithm") { -- 2.30.2