+ // get Entry of the Geom object
+ QString aGeomEntry = myDlg->selectedObject( SMESHGUI_MeshDlg::Geom );
+ QString aMeshEntry = myDlg->selectedObject( SMESHGUI_MeshDlg::Mesh );
+ QString anObjEntry = myDlg->selectedObject( SMESHGUI_MeshDlg::Obj );
+
+ if ( myToCreate && myIsMesh )
+ aMeshEntry = aGeomEntry;
+
+ if ( aMeshEntry != aGeomEntry ) { // Get Geom object from Mesh of a sub-mesh being edited
+ _PTR(SObject) pObj = studyDS()->FindObjectID( aMeshEntry.toLatin1().data() );
+ GEOM::GEOM_Object_var aGeomVar = SMESH::GetShapeOnMeshOrSubMesh( pObj );
+ aMeshEntry = ( aGeomVar->_is_nil() ) ? QString() : SMESH::toQStr( aGeomVar->GetStudyEntry() );
+ }
+
+ if ( aMeshEntry == "" && aGeomEntry == "" ) { // get geom of an object being edited
+ _PTR(SObject) pObj = studyDS()->FindObjectID( anObjEntry.toLatin1().data() );
+ bool isMesh;
+ GEOM::GEOM_Object_var aGeomVar = SMESH::GetShapeOnMeshOrSubMesh( pObj, &isMesh );
+ if ( !aGeomVar->_is_nil() )
+ {
+ aGeomEntry = SMESH::toQStr( aGeomVar->GetStudyEntry() );
+ if ( isMesh )
+ aMeshEntry = aGeomEntry;
+ }
+ }
+
+ if ( anObjEntry != "" && aGeomEntry != "" && aMeshEntry == "" ) {
+ // take geometry from submesh being created
+ _PTR(SObject) pObj = studyDS()->FindObjectID( anObjEntry.toLatin1().data() );
+ if ( pObj ) {
+ // if current object is sub-mesh
+ SMESH::SMESH_subMesh_var aSubMeshVar =
+ SMESH::SMESH_subMesh::_narrow( _CAST( SObject,pObj )->GetObject() );
+ if ( !aSubMeshVar->_is_nil() ) {
+ SMESH::SMESH_Mesh_var aMeshVar = aSubMeshVar->GetFather();
+ if ( !aMeshVar->_is_nil() ) {
+ _PTR(SObject) aMeshSO = SMESH::FindSObject( aMeshVar );
+ GEOM::GEOM_Object_var aGeomVar = SMESH::GetShapeOnMeshOrSubMesh( aMeshSO );
+ if ( !aGeomVar->_is_nil() )
+ aMeshEntry = SMESH::toQStr( aGeomVar->GetStudyEntry() );
+ }
+ }
+ }
+ }
+
+ theCreator->setShapeEntry( aGeomEntry );
+ if ( aMeshEntry != "" )
+ theCreator->setMainShapeEntry( aMeshEntry );
+
+ theCreator->setNoGeomMesh( !myIsOnGeometry && myIsMesh && !myToCreate );
+}
+
+//================================================================================
+/*!
+ * \Brief Returns tab dimension
+ * \param tab - the tab in the dlg
+ * \param dlg - my dialogue
+ * \retval int - dimension
+ */
+//================================================================================
+static int getTabDim (const QObject* tab, SMESHGUI_MeshDlg* dlg )
+{
+ int aDim = -1;
+ for (int i = SMESH::DIM_0D; i <= SMESH::DIM_3D; i++)
+ if (tab == dlg->tab(i))
+ aDim = i;
+ return aDim;
+}
+
+//================================================================================
+/*!
+ * \brief Create hypothesis
+ * \param theHypType - hypothesis category (main or additional)
+ * \param theIndex - index of type of hypothesis to be cerated
+ *
+ * Specifies dimension of hypothesis to be created (using sender() method),
+ * specifies its type and calls method for hypothesis creation
+ */
+//================================================================================
+void SMESHGUI_MeshOp::onCreateHyp( const int theHypType, const int theIndex )
+{
+ // Specifies dimension of hypothesis to be created
+ int aDim = getTabDim( sender(), myDlg );
+ if (aDim == -1)
+ return;
+
+ // Specifies type of hypothesis to be created
+ THypDataList& dataList = myAvailableHypData[ aDim ][ theHypType ];
+ if (theIndex < 0 || theIndex >= dataList.count())
+ return;
+ QString aHypTypeName = dataList[ theIndex ]->TypeName;
+
+ // Create hypothesis
+ createHypothesis(aDim, theHypType, aHypTypeName);
+}
+
+namespace
+{
+ QString GetUniqueName (const QStringList& theHypNames,
+ const QString& theName,
+ size_t theIteration = 1)
+ {
+ QString aName = theName + "_" + QString::number( theIteration );
+ if ( theHypNames.contains( aName ) )
+ return GetUniqueName( theHypNames, theName, ++theIteration );
+ return aName;
+ }
+}
+
+//================================================================================
+/*!
+ * Create hypothesis and update dialog.
+ * \param theDim - dimension of hypothesis to be created
+ * \param theType - hypothesis category (algorithm, hypothesis, additional hypothesis)
+ * \param theTypeName - specifies hypothesis to be created
+ */
+//================================================================================
+void SMESHGUI_MeshOp::createHypothesis(const int theDim,
+ const int theType,
+ const QString& theTypeName)
+{
+ HypothesisData* aData = SMESH::GetHypothesisData(theTypeName);
+ if (!aData)
+ return;
+
+ myDim = theDim;
+ myType = theType;
+
+ // get a unique hyp name
+ QStringList aHypNames;
+ TDim2Type2HypList::const_iterator aDimIter = myExistingHyps.begin();
+ for ( ; aDimIter != myExistingHyps.end(); aDimIter++) {
+ const TType2HypList& aType2HypList = aDimIter.value();
+ TType2HypList::const_iterator aTypeIter = aType2HypList.begin();
+ for ( ; aTypeIter != aType2HypList.end(); aTypeIter++) {
+ const THypList& aHypList = aTypeIter.value();
+ THypList::const_iterator anIter = aHypList.begin();
+ for ( ; anIter != aHypList.end(); anIter++) {
+ const THypItem& aHypItem = *anIter;
+ const QString& aHypName = aHypItem.second;
+ aHypNames.append(aHypName);
+ }
+ }
+ }
+ QString aHypName = GetUniqueName( aHypNames, aData->Label);
+
+ // existing hypos
+ bool dialog = false;
+
+ QString aClientLibName = aData->ClientLibName;
+ if (aClientLibName == "") {
+ // Call hypothesis creation server method (without GUI)
+ SMESH::SMESH_Hypothesis_var aHyp =
+ SMESH::CreateHypothesis(theTypeName, aHypName, false);
+ aHyp.out();
+ }
+ else {
+ // Get hypotheses creator client (GUI)
+ SMESHGUI_GenericHypothesisCreator* aCreator = SMESH::GetHypothesisCreator(theTypeName);
+
+ // Create hypothesis
+ if (aCreator)
+ {
+ // Get parameters appropriate to initialize a new hypothesis
+ SMESH::SMESH_Hypothesis_var initParamHyp =
+ getInitParamsHypothesis(theTypeName, aData->ServerLibName);
+
+ removeCustomFilters(); // Issue 0020170
+
+ // set shapes, of mesh and sub-mesh if any
+ initHypCreator( aCreator );
+
+ myDlg->setEnabled( false );
+ aCreator->create(initParamHyp, aHypName, myDlg, this, SLOT( onHypoCreated( int ) ) );
+ dialog = true;
+ }
+ else
+ {
+ SMESH::SMESH_Hypothesis_var aHyp =
+ SMESH::CreateHypothesis(theTypeName, aHypName, false);
+ aHyp.out();
+ }
+ }
+
+ if( !dialog )
+ onHypoCreated(2);
+}
+
+//================================================================================
+/*!
+ * Necessary steps after hypothesis creation
+ * \param result - creation result:
+ * 0 = rejected
+ * 1 = accepted
+ * 2 = additional value meaning that slot is called not from dialog box
+ */
+//================================================================================
+void SMESHGUI_MeshOp::onHypoCreated( int result )
+{
+ if( result != 2 )
+ {
+ int obj = myDlg->getActiveObject();
+ onActivateObject( obj ); // Issue 0020170. Restore filters
+ myDlg->setEnabled( true );
+ }
+
+ _PTR(SComponent) aFather = SMESH::GetActiveStudyDocument()->FindComponent("SMESH");
+
+ int nbHyp = myExistingHyps[myDim][myType].count();
+ HypothesisData* algoData = hypData( myDim, Algo, currentHyp( myDim, Algo ));
+ QStringList aNewHyps;
+ existingHyps(myDim, myType, aFather, aNewHyps, myExistingHyps[myDim][myType], algoData);
+ if (aNewHyps.count() > nbHyp)
+ {
+ for (int i = nbHyp; i < aNewHyps.count(); i++)
+ myDlg->tab(myDim)->addHyp(myType, aNewHyps[i]);
+ }
+
+ if( result!=2 && myHypoSet )
+ processSet();
+}
+
+//================================================================================
+/*!
+ * \brief Calls plugin methods for hypothesis editing
+ * \param theHypType - specifies whether main hypothesis or additional one
+ * is edited
+ * \param theIndex - index of existing hypothesis
+ *
+ * Calls plugin methods for hypothesis editing
+ */
+//================================================================================
+void SMESHGUI_MeshOp::onEditHyp( const int theHypType, const int theIndex )
+{
+ // Speicfies dimension of hypothesis to be created
+ int aDim = getTabDim( sender(), myDlg );
+ if (aDim == -1)
+ return;
+
+ const THypList& aList = myExistingHyps[ aDim ][ theHypType ];
+ if ( theIndex < 0 || theIndex >= aList.count() )
+ return;
+ const THypItem& aHypItem = aList[ theIndex ];
+ SMESH::SMESH_Hypothesis_var aHyp = aHypItem.first;
+ if ( aHyp->_is_nil() )
+ return;
+
+ SMESHGUI_GenericHypothesisCreator* aCreator =
+ SMESH::GetHypothesisCreator( SMESH::toQStr( aHyp->GetName() ));
+ if ( aCreator )
+ {
+ // set initial parameters
+ SMESH::SMESH_Hypothesis_var initParamHyp =
+ getInitParamsHypothesis( SMESH::toQStr( aHyp->GetName() ),
+ SMESH::toQStr( aHyp->GetLibName() ));
+ aCreator->setInitParamsHypothesis( initParamHyp );
+
+ // set shapes, of mesh and sub-mesh if any
+ initHypCreator( aCreator );
+
+ removeCustomFilters(); // Issue 0020170
+ myDlg->setEnabled( false );
+
+ aCreator->edit( aHyp.in(), aHypItem.second, dlg(), this, SLOT( onHypoEdited( int ) ) );
+ }
+}
+
+//================================================================================
+/*!
+ * Necessary steps after hypothesis edition
+ * \param result - creation result:
+ * 0 = rejected
+ * 1 = accepted
+ */
+//================================================================================
+void SMESHGUI_MeshOp::onHypoEdited( int result )
+{
+ int obj = myDlg->getActiveObject();
+ onActivateObject( obj ); // Issue 0020170. Restore filters
+ myDlg->setEnabled( true );
+}
+
+//================================================================================
+/*!
+ * \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 <= SMESH::DIM_3D &&
+ 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 curDim = getTabDim( sender(), myDlg );
+ int aDim = theDim < 0 ? curDim : theDim;
+ if (aDim == -1)
+ return;
+
+ const bool isSubmesh = ( myToCreate ? !myIsMesh : myDlg->isObjectShown( SMESHGUI_MeshDlg::Mesh ));
+
+ HypothesisData* algoData = hypData( aDim, Algo, theIndex );
+ HypothesisData* algoByDim[4];
+ algoByDim[ aDim ] = algoData;
+
+ QStringList anAvailable;
+
+ // enable / disable tabs
+ if ( myIsOnGeometry ) {
+ for (int i = SMESH::DIM_3D; i >= SMESH::DIM_0D; i--) {
+ if ( i > aDim ) {
+ if ( i > myMaxShapeDim ) myDlg->disableTab( i );
+ else myDlg->enableTab( i );
+ }
+ else if ( i == aDim ) {
+ continue;
+ }
+ else {//( i < aDim )
+ if ( algoData && algoData->InputTypes.isEmpty() ) {
+ myDlg->disableTab( i );
+ for ( int type = Algo, nbTypes = nbDlgHypTypes(i); type < nbTypes; type++ )
+ setCurrentHyp(i, type, -1);
+ }
+ else {
+ myDlg->enableTab( i );
+ }
+ }
+ }
+ }
+
+ int algoDim = aDim;
+ HypothesisData* a3DAlgo = 0;
+ // 2 loops: backward and forward from algo dimension
+ for ( int forward = 0; forward <= 1; ++forward )
+ {
+ int dim = algoDim + 1, lastDim = SMESH::DIM_3D, dir = 1;
+ if ( !forward ) {
+ dim = algoDim - 1; lastDim = SMESH::DIM_0D; dir = -1;
+ }
+ HypothesisData* prevAlgo = algoData;
+ bool noCompatible = false;
+ for ( ; dim * dir <= lastDim * dir; dim += dir)
+ {
+ if ( !isAccessibleDim( dim ))
+ continue;
+ if ( noCompatible ) { // the selected algo has no compatible ones
+ anAvailable.clear();
+ myDlg->tab( dim )->setAvailableHyps( Algo, anAvailable );
+ myAvailableHypData[dim][Algo].clear();
+ algoByDim[ dim ] = 0;
+ continue;
+ }
+ HypothesisData* nextAlgo = 0;
+ if ( myMaxShapeDim == SMESH::DIM_3D && a3DAlgo && dim == SMESH::DIM_2D ) {
+ nextAlgo = a3DAlgo;
+ }
+ // get currently selected algo
+ int algoIndex = currentHyp( dim, Algo );
+ HypothesisData* curAlgo = hypData( dim, Algo, algoIndex );
+
+ QString anCompareType = currentMeshTypeName(myDlg->currentMeshType());
+ QString anCurrentCompareType = "";
+ if ( dim == SMESH::DIM_3D || anCompareType == "ANY" )
+ anCurrentCompareType = anCompareType;
+ else if ( dim == SMESH::DIM_2D ) {
+ anCurrentCompareType = (anCompareType == "HEXA" || anCompareType == "QUAD") ? "QUAD" : "TRIA";
+ nextAlgo = 0;
+ }
+
+ // set new available algorithms
+ availableHyps( dim, Algo, anAvailable, myAvailableHypData[dim][Algo], prevAlgo, nextAlgo, anCurrentCompareType);
+ HypothesisData* soleCompatible = 0;
+ if ( anAvailable.count() == 1 )
+ soleCompatible = myAvailableHypData[dim][Algo][0];
+ myDlg->tab( dim )->setAvailableHyps( Algo, anAvailable );
+ noCompatible = anAvailable.isEmpty();
+ algoIndex = myAvailableHypData[dim][Algo].indexOf( curAlgo );
+ if ( !isSubmesh && algoIndex < 0 && soleCompatible && !forward && dim == curDim ) {
+ // select the sole compatible algo
+ algoIndex = 0;
+ }
+ setCurrentHyp( dim, Algo, algoIndex );
+
+ // remember current algo
+ prevAlgo = algoByDim[ dim ] = hypData( dim, Algo, algoIndex );
+
+ } // loop on dims
+
+ if ( myMaxShapeDim == SMESH::DIM_3D && forward && algoDim == SMESH::DIM_1D )
+ {
+ algoDim = SMESH::DIM_3D;
+ forward = -1;
+ a3DAlgo = prevAlgo;
+ continue;
+ }
+ } // loops backward and forward
+
+
+ // set hypotheses corresponding to the found algorithms
+
+ _PTR(SObject) pObj = SMESH::GetActiveStudyDocument()->FindComponent("SMESH");
+
+ for ( int dim = SMESH::DIM_0D; dim <= SMESH::DIM_3D; dim++ )
+ {
+ if ( !isAccessibleDim( dim ))
+ continue;
+
+ // get indices of selected hyps
+ const int nbTypes = nbDlgHypTypes(dim);
+ std::vector<int> hypIndexByType( nbTypes, -1 );
+ for ( int dlgType = MainHyp; dlgType < nbTypes; dlgType++ )
+ {
+ hypIndexByType[ dlgType ] = currentHyp( dim, dlgType );
+ }
+
+ // update hyps
+ for ( int dlgType = MainHyp; dlgType < nbTypes; dlgType++ )
+ {
+ const int type = Min( dlgType, AddHyp );
+ myAvailableHypData[ dim ][ type ].clear();
+ QStringList anAvailable, anExisting;
+
+ HypothesisData* curAlgo = algoByDim[ dim ];
+ int hypIndex = hypIndexByType[ dlgType ];
+
+ SMESH::SMESH_Hypothesis_var curHyp;
+ if ( hypIndex >= 0 && hypIndex < myExistingHyps[ dim ][ type ].count() )
+ curHyp = myExistingHyps[ dim ][ type ][ hypIndex ].first;
+
+ if ( !myToCreate && !curAlgo && !curHyp->_is_nil() ) { // edition, algo not selected
+ // try to find algo by selected hypothesis in order to keep it selected
+ bool algoDeselectedByUser = ( theDim < 0 && aDim == dim );
+ QString curHypType = SMESH::toQStr( curHyp->GetName() );
+ if ( !algoDeselectedByUser &&
+ myObjHyps[ dim ][ type ].count() > 0 &&
+ curHypType == SMESH::toQStr( myObjHyps[ dim ][ type ].first().first->GetName()) )
+ {
+ HypothesisData* hypData = SMESH::GetHypothesisData( SMESH::toQStr( curHyp->GetName() ));
+ for (int i = 0; i < myAvailableHypData[ dim ][ Algo ].count(); ++i) {
+ curAlgo = myAvailableHypData[ dim ][ Algo ][ i ];
+ if (curAlgo && hypData && isCompatible(curAlgo, hypData, type))
+ break;
+ else
+ curAlgo = 0;
+ }
+ }
+ }
+ // get hyps compatible with curAlgo
+ bool defaulHypAvlbl = false;
+ if ( curAlgo )
+ {
+ // check if a selected hyp is compatible with the curAlgo
+ if ( !curHyp->_is_nil() ) {
+ HypothesisData* hypData = SMESH::GetHypothesisData( SMESH::toQStr( curHyp->GetName() ));
+ if ( !isCompatible( curAlgo, hypData, type ))
+ curHyp = SMESH::SMESH_Hypothesis::_nil();
+ }
+ availableHyps( dim, type, anAvailable, myAvailableHypData[ dim ][ type ], curAlgo);
+ existingHyps( dim, type, pObj, anExisting, myExistingHyps[ dim ][ type ], curAlgo);
+ defaulHypAvlbl = (type == MainHyp && !curAlgo->IsAuxOrNeedHyp );
+ }
+ // set list of hypotheses
+ if ( dlgType <= AddHyp )
+ {
+ myDlg->tab( dim )->setAvailableHyps( type, anAvailable );
+ myDlg->tab( dim )->setExistingHyps( type, anExisting, defaulHypAvlbl );
+ }
+ // set current existing hypothesis
+ if ( !curHyp->_is_nil() && !anExisting.isEmpty() )
+ hypIndex = this->find( curHyp, myExistingHyps[ dim ][ type ]);
+ else
+ hypIndex = -1;
+ if ( !isSubmesh && myToCreate && hypIndex < 0 && anExisting.count() == 1 && dim == curDim )
+ {
+ // none is yet selected => select the sole existing if it is not optional
+ CORBA::String_var hypTypeName = myExistingHyps[ dim ][ type ].first().first->GetName();
+ bool isOptional = true;
+ if ( algoByDim[ dim ] &&
+ SMESH::IsAvailableHypothesis( algoByDim[ dim ], hypTypeName.in(), isOptional ) &&
+ !isOptional )
+ hypIndex = 0;
+ }
+ setCurrentHyp( dim, dlgType, hypIndex );
+ }
+ }
+}
+
+//================================================================================
+/*!
+ * \brief Creates and selects hypothesis of hypotheses set
+ * \param theSetName - The name of hypotheses set
+ */
+//================================================================================
+void SMESHGUI_MeshOp::onHypoSet( const QString& theSetName )
+{
+ myHypoSet = SMESH::GetHypothesesSet(theSetName);
+ if (!myHypoSet)
+ return;
+
+ // clear all hyps
+ for (int dim = SMESH::DIM_0D; dim <= SMESH::DIM_3D; dim++) {
+ setCurrentHyp(dim, Algo, -1);
+ setCurrentHyp(dim, AddHyp, -1);
+ setCurrentHyp(dim, MainHyp, -1);
+ }
+
+ myHypoSet->init(true); //algorithms
+ processSet();
+ myHypoSet->init(false); //hypotheses
+ processSet();
+ myHypoSet = 0;
+}
+
+//================================================================================
+/*!
+ * \brief One step of hypothesis/algorithm list creation
+ *
+ * Creates a hypothesis or an algorithm for current item of internal list of names myHypoSet
+ */
+//================================================================================
+void SMESHGUI_MeshOp::processSet()
+{
+ myHypoSet->next();
+ if( !myHypoSet->more() )
+ return;
+
+ bool isAlgo = myHypoSet->isAlgo();
+ QString aHypoTypeName = myHypoSet->current();
+ HypothesisData* aHypData = SMESH::GetHypothesisData(aHypoTypeName);
+ if (!aHypData)
+ {
+ processSet();
+ return;
+ }
+
+ int aDim = aHypData->Dim[0];
+ // create or/and set
+ if (isAlgo)
+ {
+ int index = myAvailableHypData[aDim][Algo].indexOf( aHypData );
+ if ( index < 0 )
+ {
+ QStringList anAvailable;
+ availableHyps( aDim, Algo, anAvailable, myAvailableHypData[aDim][Algo] );
+ myDlg->tab( aDim )->setAvailableHyps( Algo, anAvailable );
+ index = myAvailableHypData[aDim][Algo].indexOf( aHypData );
+ }
+ setCurrentHyp( aDim, Algo, index );
+ onAlgoSelected( index, aDim );
+ processSet();
+ }
+ else
+ {
+ bool mainHyp = true;
+ QStringList anAvailable;
+ availableHyps( aDim, MainHyp, anAvailable, myAvailableHypData[aDim][MainHyp] );
+ myDlg->tab( aDim )->setAvailableHyps( MainHyp, anAvailable );
+ int index = myAvailableHypData[aDim][MainHyp].indexOf( aHypData );
+ if ( index < 0 )
+ {
+ mainHyp = false;
+ index = myAvailableHypData[aDim][AddHyp].indexOf( aHypData );
+ }
+ if (index >= 0)
+ createHypothesis(aDim, mainHyp ? MainHyp : AddHyp, aHypoTypeName);
+ else
+ processSet();
+ }
+}