+ 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 Update list of algorithms and hypotheses according to currently selected
+ * algorithm, geometry and mesh type
+ */
+//================================================================================
+void SMESHGUI_MeshOp::setFilteredAlgoData()
+{
+ // keep current algorithms
+ HypothesisData* curAlgos[ 4 ];
+ for ( int dim = 0; dim <= 3; ++dim )
+ curAlgos[ dim ] = hypData( dim, Algo, currentHyp( dim, Algo ));
+
+ // find out myMaxShapeDim by checking algorithm applicability to geometry
+
+ int curMeshType = myDlg->currentMeshType();
+ myDlg->setCurrentMeshType( MT_ANY );
+ QStringList algosAvailable;
+ // get available algorithms taking into account geometry only
+ if ( myGeom->_is_nil() )
+ {
+ myMaxShapeDim = 3;
+
+ if ( myToCreate ) // readMesh() has done it if !myToCreate
+ for ( int dim = 0; dim <= 3; ++dim )
+ availableHyps( dim, Algo, algosAvailable, myAvailableHypData[ dim ][ Algo ] );
+ }
+ else
+ {
+ if ( myGeomEntry != myLastGeomEntry )
+ myHypMapIsApplicable.clear();
+
+ for ( int dim = 0; dim <= 3; ++dim )
+ {
+ availableHyps( dim, Algo, algosAvailable, myAvailableHypData[ dim ][ Algo ] );
+ if ( algosAvailable.count() )
+ myMaxShapeDim = dim;
+ }
+ if ( !myGeomEntry.isEmpty() )
+ myLastGeomEntry = myGeomEntry;
+ }
+ myDlg->setMaxHypoDim( myMaxShapeDim );
+
+ // set mesh types according to myMaxShapeDim
+ updateMeshTypeList();
+
+ // update available hypo-sets that depend on geometry and mesh type
+ myDlg->setCurrentMeshType( Max( MT_ANY, curMeshType ));
+ updateHypoSets(); // it sets myAvailableHypData by curMeshType
+
+ // restore current algorithms according to changed myAvailableHypData
+ algosAvailable.clear();
+ for ( int dim = 0; dim <= 3; ++dim )
+ {
+ int algoIndex = myAvailableHypData[ dim ][ Algo ].indexOf( curAlgos[ dim ]);
+ while ( algosAvailable.count() <= algoIndex )
+ algosAvailable << "";
+ myDlg->tab( dim )->setAvailableHyps( Algo, algosAvailable );
+ setCurrentHyp( dim, Algo, algoIndex );
+ if ( algoIndex < 0 )
+ curAlgos[ dim ] = 0;
+ }
+
+ // find a selected algo, current or of highest dimension
+ int algoDim = myDlg->currentTab();
+ if ( !curAlgos[ algoDim ])
+ for ( algoDim = SMESH::DIM_3D; algoDim >= SMESH::DIM_0D; algoDim-- )
+ if ( curAlgos[ algoDim ] )
+ break;
+ if ( algoDim < SMESH::DIM_0D )
+ algoDim = myMaxShapeDim;
+
+ // set algorithms and hypotheses according to all parameters (mesh type etc)
+ onAlgoSelected( currentHyp( algoDim, Algo ), algoDim );
+}
+
+//================================================================================
+/*!
+ * \brief Set available algos and hypos according to the selected algorithm
+ * \param theIndex - algorithm index
+ * \param theDim - algorithm dimension
+ */
+//================================================================================
+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;
+ const int algoDim = aDim;
+
+ // 2 loops: backward and forward from algo dimension (forward == to higher dimension)
+ for ( int forward = 1; forward >= 0; --forward )
+ {
+ int dim = algoDim, lastDim = SMESH::DIM_3D, dir = 1;
+ if ( !forward ) {
+ dim = algoDim - 1; lastDim = SMESH::DIM_0D; dir = -1;
+ }
+ //bool noCompatible = false;
+ for ( ; dim * dir <= lastDim * dir; dim += dir)
+ {
+ // if ( noCompatible ) // the selected algo has no compatible ones (like 1D2D3D algo)
+ // {
+ // anAvailable.clear();
+ // myDlg->tab( dim )->setAvailableHyps( Algo, anAvailable );
+ // myAvailableHypData[dim][Algo].clear();
+ // algoByDim[ dim ] = 0;
+ // }
+ // else
+ {
+ int algoIndex = currentHyp( dim, Algo );
+ HypothesisData *curAlgo = hypData( dim, Algo, algoIndex );
+
+ // set new available algorithms
+ HypothesisData *prevAlgo = 0;
+ if ( dim != algoDim )
+ for ( int prevDim = dim + 1; prevDim <=3 && !prevAlgo; ++prevDim )
+ prevAlgo = hypData( prevDim, Algo, currentHyp( prevDim, Algo ));
+ availableHyps( dim, Algo, anAvailable, myAvailableHypData[dim][Algo], prevAlgo );
+ myDlg->tab( dim )->setAvailableHyps( Algo, anAvailable );
+
+ //noCompatible = ( prevAlgo && !forward && anAvailable.isEmpty() );
+
+ // set current algo
+ algoIndex = myAvailableHypData[dim][Algo].indexOf( curAlgo );
+ setCurrentHyp( dim, Algo, algoIndex, /*updateHyps=*/true );
+
+ algoByDim[ dim ] = hypData( dim, Algo, algoIndex );
+ }
+
+ // activate tabs according to algorithms availability
+ if ( anAvailable.isEmpty() ) myDlg->disableTab( dim );
+ else myDlg->enableTab( dim );
+
+ } // loop on dims
+ } // loops backward and forward
+
+
+ // set hypotheses corresponding to the found algorithms
+
+ _PTR(SObject) pComp = SMESH::getStudy()->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;
+ QString curHypType;
+ HypothesisData* hypData = 0;
+ if ( hypIndex >= 0 && hypIndex < myExistingHyps[ dim ][ type ].count() )
+ {
+ curHyp = myExistingHyps[ dim ][ type ][ hypIndex ].first;
+ if ( !curHyp->_is_nil() )
+ {
+ curHypType = SMESH::toQStr( curHyp->GetName() );
+ hypData = SMESH::GetHypothesisData( curHypType );
+ }
+ }
+ 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 );
+ if ( !algoDeselectedByUser &&
+ myObjHyps[ dim ][ type ].count() > 0 &&
+ curHypType == SMESH::toQStr( myObjHyps[ dim ][ type ].first().first->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 )
+ {
+ if ( hypData && !isCompatible( curAlgo, hypData, type ))
+ curHyp = SMESH::SMESH_Hypothesis::_nil();
+ availableHyps( dim, type, anAvailable, myAvailableHypData[ dim ][ type ], curAlgo );
+ existingHyps ( dim, type, pComp, 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 );
+ }
+ }
+ return;
+}
+
+//================================================================================
+/*!
+ * \brief Create a sub-mesh on internal edges in the case where the global algorithm
+ * is of type 1D-2D[-3D] so that the internal edges would remain not meshed.
+ */
+//================================================================================
+
+void SMESHGUI_MeshOp::createSubMeshOnInternalEdges( SMESH::SMESH_Mesh_ptr theMesh,
+ GEOM::GEOM_Object_ptr theMainShape )
+{
+ if ( theMesh->_is_nil() || theMainShape->_is_nil() )
+ return;
+
+ if ( isAccessibleDim( 1 ))
+ return; // global 1D algorithm is/can be assigned
+
+ const HypothesesSet::SetType internSet = HypothesesSet::INTERN;
+ bool toCreate = true;
+ bool toCreateMandatory = ( myHypoSet &&
+ myAverageSize > 0 &&
+ ( myHypoSet->init( /*algo=*/ true, internSet ), myHypoSet->more()) &&
+ ( myHypoSet->init( /*algo=*/false, internSet ), myHypoSet->more()));
+ if ( !toCreateMandatory ) // ask the user
+ toCreate = false; // can't pass both mesh and geometry to Create Submesh operation (so far?)
+ // toCreate = SUIT_MessageBox::warning( SMESHGUI::desktop(),
+ // QObject::tr("SMESH_WRN_WARNING"),
+ // QObject::tr("SMESH_CREATE_SUBMESH_ON_INTERNAL_EDGES"),
+ // QObject::tr("SMESH_BUT_YES"),
+ // QObject::tr("SMESH_BUT_NO"), 1, 0);
+ if ( !toCreate )
+ return;
+
+ TopoDS_Shape shape;
+ if ( !GEOMBase::GetShape( theMainShape, shape ))
+ return;
+
+ std::vector< TopoDS_Shape > internalEdges;
+ for ( TopExp_Explorer edge( shape, TopAbs_EDGE, TopAbs_WIRE ); edge.More(); edge.Next() )
+ internalEdges.push_back( edge.Current() );
+
+ if ( internalEdges.empty() )
+ return;
+
+ TopTools_IndexedMapOfShape shapeIDs;
+ TopExp::MapShapes( shape, shapeIDs );
+
+ std::set< int > intIDSet;
+ for ( size_t i = 0; i < internalEdges.size(); ++i )
+ intIDSet.insert( shapeIDs.FindIndex( internalEdges[ i ]));
+
+ GEOM::GEOM_Gen_var geomGen = theMainShape->GetGen();
+ if (geomGen->_is_nil()) return;
+
+ GEOM::GEOM_Object_var edgeGroup;
+ GEOM::GEOM_IShapesOperations_wrap sOp = geomGen->GetIShapesOperations();
+ GEOM::GEOM_IGroupOperations_wrap gOp = geomGen->GetIGroupOperations();
+ GEOM::ListOfGO_var geomGroups = sOp->GetExistingSubObjects( theMainShape,
+ /*groupsOnly=*/true );
+ for ( CORBA::ULong i = 0; i < geomGroups->length(); ++i )
+ {
+ GEOM::ListOfLong_var ids = gOp->GetObjects( geomGroups[ i ]);
+ std::set< int > idSet( & ids[0], & ids[0] + ids->length() );
+ if ( idSet == intIDSet )
+ {
+ edgeGroup = geomGroups[ i ];
+ break;
+ }
+ }
+
+ if ( edgeGroup->_is_nil() )
+ {
+ GEOM::GEOM_Object_var edgeGroup = gOp->CreateGroup( theMainShape, TopAbs_EDGE );
+
+ GEOM::ListOfLong_var edgeIDs = new GEOM::ListOfLong;
+ edgeIDs->length( internalEdges.size() );
+ std::set< int >::iterator id = intIDSet.begin();
+ for ( size_t i = 0; i < intIDSet.size(); ++i, ++id )
+ edgeIDs[ i ] = *id;
+ gOp->UnionIDs( edgeGroup, edgeIDs );
+
+ SALOMEDS::SObject_wrap so = geomGen->AddInStudy( edgeGroup, "Internal edges", theMainShape );
+ }
+
+ if ( !toCreateMandatory )
+ {
+ // show Create Sub-mesh dislog
+ // _PTR(SObject) aMeshSO = SMESH::FindSObject( theMesh );
+ // selectionMgr()->clearFilters();
+ // selectObject( pSubmesh );
+ // SMESHGUI::GetSMESHGUI()->switchToOperation( SMESHOp::OpEditMeshOrSubMesh );
+ return;
+ }
+
+ // create a sub-mesh using myAverageSize w/o GUI
+
+ SMESH::SMESH_subMesh_var subMesh = theMesh->GetSubMesh( edgeGroup, "" );
+
+ for ( int isAlgo = 1; isAlgo >= 0; --isAlgo )
+ for ( myHypoSet->init( isAlgo, internSet ); myHypoSet->more(); myHypoSet->next() )
+ {
+ QString aHypoTypeName = myHypoSet->current();
+ HypothesisData* aHypData = SMESH::GetHypothesisData( aHypoTypeName );
+ if ( !aHypData )
+ continue;
+
+ myDim = aHypData->Dim[0];
+ if ( myDim != 1 )
+ continue;
+
+ // create or/and set
+ SMESH::SMESH_Hypothesis_var newHypo;
+ if ( isAlgo )
+ {
+ myAvailableHypData[ myDim ][ Algo ].clear();
+ myAvailableHypData[ myDim ][ Algo ] << aHypData;
+ QStringList hypList; hypList << aHypoTypeName;
+ myDlg->tab( myDim )->setAvailableHyps( Algo, hypList );
+ setCurrentHyp( myDim, Algo, 0 );
+ newHypo = getAlgo( myDim );
+ }
+ else
+ {
+ SMESH::HypInitParams params = { 2, myAverageSize, false };
+ newHypo = getInitParamsHypothesis( aHypData->TypeName, aHypData->ServerLibName, & params );
+ QString hypName = GetUniqueName( getHypoNames(), aHypData->Label );
+ SALOMEDS::SObject_wrap so =
+ SMESHGUI::GetSMESHGen()->PublishInStudy( SALOMEDS::SObject::_nil(), newHypo,
+ hypName.toUtf8().data() );
+ }
+ SMESH::AddHypothesisOnSubMesh( subMesh, newHypo );
+ }
+
+ return;
+}
+
+//================================================================================
+/*!
+ * \brief Ask the user to enter an average size which will be used to create
+ * hypotheses of a hypo-set basing on this size
+ * \param [out] averageSize - average element size
+ * \return bool - false if the user canceled the dialog
+ */
+//================================================================================
+
+bool SMESHGUI_MeshOp::getAverageSize( double & averageSize )
+{
+ HypothesisData* hypData = SMESH::GetHypothesisData( "MaxLength" );
+ if ( !hypData )
+ return false;
+
+ SMESH::SMESH_Hypothesis_var hyp = getInitParamsHypothesis( hypData->TypeName,
+ hypData->ServerLibName );
+ if ( hyp->_is_nil() )
+ return false;
+
+ SMESHGUI_GenericHypothesisCreator* aCreator = SMESH::GetHypothesisCreator( hypData->TypeName );
+ if ( !aCreator )
+ return false;