Salome HOME
reflect algo<->algo and algo->hypos dependencies in GUI
authoreap <eap@opencascade.com>
Mon, 10 Apr 2006 15:24:41 +0000 (15:24 +0000)
committereap <eap@opencascade.com>
Mon, 10 Apr 2006 15:24:41 +0000 (15:24 +0000)
resources/StdMeshers.xml
src/SMESHGUI/SMESHGUI_Hypotheses.h
src/SMESHGUI/SMESHGUI_HypothesesUtils.cxx
src/SMESHGUI/SMESHGUI_HypothesesUtils.h
src/SMESHGUI/SMESHGUI_MeshDlg.cxx
src/SMESHGUI/SMESHGUI_MeshDlg.h
src/SMESHGUI/SMESHGUI_MeshOp.cxx
src/SMESHGUI/SMESHGUI_MeshOp.h
src/SMESHGUI/SMESHGUI_XmlHandler.cxx

index 6daf06253c936a2ea5d1435d88479271cbca3c5d..3f9de1a55cb186ef02fa83db23e2c49321e03cf4 100644 (file)
     <algorithm type="Regular_1D"
               label-id="Wire discretisation"
               icon-id="mesh_algo_regular.png"
-         dim="1"/>
+               hypos="LocalLength,Arithmetic1D,StartEndLength,NumberOfSegments,Deflection1D,AutomaticLength"
+               opt-hypos="Propagation,QuadraticMesh"
+               output="EDGE"
+               dim="1"/>
 
     <algorithm type="MEFISTO_2D"
               label-id="Triangle (Mefisto)"
               icon-id="mesh_algo_mefisto.png"
-         dim="2"/>
+               hypos="LengthFromEdges"
+               input="EDGE"
+               output="TRIA"
+               dim="2"/>
 
     <algorithm type="Quadrangle_2D"
                label-id="Quadrangle (Mapping)"
                icon-id="mesh_algo_quad.png"
+               opt-hypos="QuadranglePreference"
+               input="EDGE"
+               output="QUAD"
                dim="2"/>
 
     <algorithm type="Hexa_3D"
                label-id="Hexahedron (i,j,k)"
                icon-id="mesh_algo_hexa.png"
+               input="QUAD"
                dim="3"/>
   </algorithms>
 </meshers-group>
index b62ccdbd0a7087de42f35a57f3ec8caabe10ba1c..47546d233799bf99b9ac7522d74520c3db2b96b9 100644 (file)
@@ -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<int>& 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<int> 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
 };
 
 /*!
index 5f4d6d2f418756cac85fda695112aaa621f6d54a..556dc5591ffda71982444351eefd0765be1905b0 100644 (file)
@@ -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)
   {
index 2fb920af91c60e99f87f4ee7322916b5a17685b3..15767b0f7aa476b42f5851a44c8cc26c97837d90 100644 (file)
@@ -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,
index a9dbbcaa1e54b24814f24c38716fc10337d51d8a..7b1b6e77c051d3759b3715da13f159140bf526bf 100644 (file)
@@ -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 <None>, enables otherwise
+ * SLOT called when current hypothesis changed. Disables "Edit hypothesis" button
+ * if current hypothesis is <None>, 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 );
 }
 
 //================================================================================
index f12773bd100f3ca1f0d5c7af8c4db64800fd7bfc..0e97c8c30abc3f9e149e29f1b18daa45abb28149 100644 (file)
@@ -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
-
-
-
-
index 823ad4d7f34829107c69380cd683672ccd45ea10..8fe50a06a701d2947c6afa381743e68187212f66 100644 (file)
@@ -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<SMESH::SMESH_Hypothesis_var>& theHypVars )
+                                    QValueList<SMESH::SMESH_Hypothesis_var>& 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<SMESH::SMESH_Hypothesis_var>& 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<SMESH::SMESH_Hypothesis_var> 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<SMESH::SMESH_Hypothesis_var>& aHypVarList = myExistingHyps[ theDim ][ Algo ];
   QValueList<SMESH::SMESH_Hypothesis_var>::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();
       }
index 13546ff2232483e78d456beb0bdc9a0daafd8f97..51492c3ee53cb9797191978e07303a59af4f4be6 100644 (file)
@@ -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<HypothesisData*> 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<SMESH::SMESH_Hypothesis_var>& theHypVars );
+                                               QStringList&  theHyps, 
+                                               QValueList<SMESH::SMESH_Hypothesis_var>& 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
index 76e13851121aaad8cfe30da10b0e2904c25ed5a2..15cea62b589637b72cc6871e78d8808116d3bde5 100644 (file)
@@ -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")
       {