Salome HOME
0022364, 0022363: EDF SMESH: Create Mesh dialog box improvement
authoreap <eap@opencascade.com>
Fri, 14 Feb 2014 12:03:10 +0000 (16:03 +0400)
committereap <eap@opencascade.com>
Fri, 14 Feb 2014 12:03:10 +0000 (16:03 +0400)
doc/salome/gui/SMESH/images/createmesh-inv.png [changed mode: 0755->0644]
doc/salome/gui/SMESH/input/constructing_meshes.doc
src/SMESHGUI/SMESHGUI_Hypotheses.cxx
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

old mode 100755 (executable)
new mode 100644 (file)
index c7f7c31..2180d41
Binary files a/doc/salome/gui/SMESH/images/createmesh-inv.png and b/doc/salome/gui/SMESH/images/createmesh-inv.png differ
index 0671f89..dcb55a7 100644 (file)
@@ -33,14 +33,15 @@ written in Python.
     <br>
   </li>
   <li>Apply \subpage basic_meshing_algos_page "meshing algorithms" and
-    \subpage about_hypo_page "hypotheses" which will be used at computation of
+    \subpage about_hypo_page "hypotheses" which will be used to compute
     this mesh.
 
     "Create mesh" dialog box contains several tab pages titled \b 3D,
     \b 2D, \b 1D and \b 0D. The title of each page reflects the
     dimension of the CAD model (geometry) the algorithms listed on
-    this page affect. For example, \b 3D page lists the algorithms
-    that affect 3D geometrical objects (solids).
+    this page affect and the maximal dimension of elements the algorithms
+    generate. For example, \b 3D page lists the algorithms that affect
+    3D geometrical objects (solids).
 
     \note
     - Some page(s) can be disabled if the source geometrical
@@ -86,9 +87,24 @@ written in Python.
     <em>"Edit Hypothesis" button</em>
     </center>
 
-    Most standard 2D and 3D algorithms can work without hypotheses
-    using some default parameters. The use of additional hypotheses
-    is optional (i.e. you may leave "None" in this box).
+    Most 2D and 3D algorithms can work without hypotheses using some
+    default meshing parameters. Some algorithms does not require any
+    hypothesis. After selection of an algorithm "Hypothesis" field of
+    the dialog can contain:
+    <ul>
+      <li> <em><Default></em> if the algorithm can work using default
+      parameters.</li>
+      <li> <em><None></em> if the algorithm requires a hypothesis defining
+      its parameters.</li>
+      <li> Nothing if the algorithm has no parameters to tune.</li>
+    </ul>
+    After selection of an algorithm "Add. Hypothesis" field of
+    the dialog can contain:
+    <ul>
+      <li> <em><None></em> if the algorithm can be additionally tuned
+      using an additional hypothesis.</li>
+      <li> Nothing if the algorithm has no additional parameters to tune.</li>
+    </ul>
 
     Proceed in the same way with 2D and 1D Algorithms and Hypotheses that
     will be used to mesh faces and edges of your geometry. (Note
index e8ebeea..9801cfd 100644 (file)
@@ -711,9 +711,10 @@ HypothesisData::HypothesisData( const QString& theTypeName,
                                 const QString& theClientLibName,
                                 const QString& theLabel,
                                 const QString& theIconId,
+                                const QString& theContext,
                                 const QList<int>& theDim,
-                                const bool theIsAux,
-                                const QStringList& theNeededHypos,
+                                const bool theIsAuxOrNeedHyp,
+                                const QStringList& theBasicHypos,
                                 const QStringList& theOptionalHypos,
                                 const QStringList& theInputTypes,
                                 const QStringList& theOutputTypes,
@@ -725,9 +726,10 @@ HypothesisData::HypothesisData( const QString& theTypeName,
     ClientLibName( theClientLibName ),
     Label( theLabel ),
     IconId( theIconId ),
+    Context( theContext ),
     Dim( theDim ),
-    IsAux( theIsAux ),
-    NeededHypos( theNeededHypos ),
+    IsAuxOrNeedHyp( theIsAuxOrNeedHyp ),
+    BasicHypos( theBasicHypos ),
     OptionalHypos( theOptionalHypos ),
     InputTypes( theInputTypes ),
     OutputTypes( theOutputTypes ),
index 83da609..b67a6dd 100644 (file)
@@ -173,7 +173,7 @@ class HypothesisData
 public:
   HypothesisData( const QString&, const QString&, const QString&,
                   const QString&, const QString&, const QString&,
-                  const QList<int>&, const bool,
+                  const QString&, const QList<int>&, const bool,
                   const QStringList&, const QStringList&,
                   const QStringList&, const QStringList&,
                   const bool=true, const bool supportSub=false );
@@ -184,13 +184,15 @@ public:
   QString ClientLibName;   //!< client library name
   QString Label;           //!< label
   QString IconId;          //!< icon identifier
+  QString Context;         //!< ["GLOBAL","LOCAL","ANY"(default)]
   QList<int> Dim;          //!< list of supported dimensions (see SMESH::Dimension enumeration)
-  bool IsAux;              //!< TRUE if given hypothesis is auxiliary one, FALSE otherwise
+  bool IsAuxOrNeedHyp;     //!< TRUE if given hypothesis is auxiliary one, FALSE otherwise
+  //!<                          TRUE if given algorithm can't work w/o hypotheses
   bool IsNeedGeometry;     //!< TRUE if the algorithm works with shapes only, FALSE otherwise
   bool IsSupportSubmeshes; //!< TRUE if the algo building all-dim elems supports submeshes
 
   // for algorithm only: dependencies algo <-> algo and algo -> hypos
-  QStringList NeededHypos;  //!< list of obligatory hypotheses
+  QStringList BasicHypos;   //!< list of basic 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 5800395..627570f 100644 (file)
@@ -266,23 +266,28 @@ namespace SMESH
   }
 
 
-  QStringList GetAvailableHypotheses( const bool isAlgo, 
-                                      const int theDim,                          
+  QStringList GetAvailableHypotheses( const bool isAlgo,
+                                      const int  theDim,
                                       const bool isAux,
-                                      const bool isNeedGeometry)
+                                      const bool isNeedGeometry,
+                                      const bool isSubMesh)
   {
     QStringList aHypList;
 
     // Init list of available hypotheses, if needed
     InitAvailableHypotheses();
     bool checkGeometry = ( !isNeedGeometry && isAlgo );
+    const char* context = isSubMesh ? "LOCAL" : "GLOBAL";
     // fill list of hypotheses/algorithms
     THypothesisDataMap& pMap = isAlgo ? myAlgorithmsMap : myHypothesesMap;
     THypothesisDataMap::ConstIterator anIter;
     for ( anIter = pMap.begin(); anIter != pMap.end(); anIter++ ) {
       HypothesisData* aData = anIter.value();
       if(!aData || aData->Label.isEmpty()) continue;
-      if ( ( theDim < 0 || aData->Dim.contains( theDim ) ) && aData->IsAux == isAux) {
+      if (( theDim < 0 || aData->Dim.contains( theDim )) &&
+          ( isAlgo || aData->IsAuxOrNeedHyp == isAux ) &&
+          ( aData->Context == "ANY" || aData->Context == context ))
+      {
         if (checkGeometry) {
           if (aData->IsNeedGeometry == isNeedGeometry)
             aHypList.append(anIter.key());
@@ -384,7 +389,7 @@ namespace SMESH
     isAuxiliary = false;
     if ( !algoData )
       return false;
-    if ( algoData->NeededHypos.contains( hypType ))
+    if ( algoData->BasicHypos.contains( hypType ))
       return true;
     if ( algoData->OptionalHypos.contains( hypType)) {
       isAuxiliary = true;
index 333418b..1b2046f 100644 (file)
@@ -69,7 +69,8 @@ namespace SMESH
   QStringList GetAvailableHypotheses( const bool, 
                                       const int = -1, 
                                       const bool = false,
-                                      const bool = true);
+                                      const bool = true,
+                                      const bool = false);
   SMESHGUI_EXPORT
   QStringList GetHypothesesSets( int, const QString& );
 
index 94d9ce6..13c6cf6 100644 (file)
@@ -149,16 +149,20 @@ void SMESHGUI_MeshTab::setAvailableHyps( const int theId, const QStringList& the
   myAvailableHyps[ theId ] = theHyps;
 
   bool enable = ! theHyps.isEmpty();
-  if ( theId == Algo )
+  if ( theId == Algo ) // fill list of algos
   {
     myHyp[ Algo ]->clear();
-    myHyp[ Algo ]->addItem( tr( "NONE" ) );
-    myHyp[ Algo ]->addItems( theHyps );
-    myHyp[ Algo ]->setCurrentIndex( 0 );
+    if ( enable )
+    {
+      myHyp[ Algo ]->addItem( tr( "NONE" ) );
+      myHyp[ Algo ]->addItems( theHyps );
+      myHyp[ Algo ]->setCurrentIndex( 0 );
+    }
   }
-  else {
+  else // enable buttons
+  {
     myCreateHyp[ theId ]->setEnabled( enable );
-    myEditHyp[ theId ]->setEnabled( false );
+    myEditHyp  [ theId ]->setEnabled( false );
   }
   myHyp[ theId ]->setEnabled( enable );
 }
@@ -166,21 +170,30 @@ void SMESHGUI_MeshTab::setAvailableHyps( const int theId, const QStringList& the
 //================================================================================
 /*!
  * \brief Sets existing hypothesis
-  * \param theId - identifier of hypothesis (main or additional, see HypType enumeration)
-  * \param theHyps - list of available hypothesis names
- * 
+ * \param theId - identifier of hypothesis (main or additional, see HypType enumeration)
+ * \param theHyps - list of available hypothesis names
+ * \param theDefaultAvlbl - \c true means that the algorithm can with w/o hypothesis
+ *                          with some default parameters
+ *
  * Sets existing main or additional hypothesis for this tab
  */
 //================================================================================
-void SMESHGUI_MeshTab::setExistingHyps( const int theId, const QStringList& theHyps )
+void SMESHGUI_MeshTab::setExistingHyps( const int          theId,
+                                        const QStringList& theHyps,
+                                        bool               theDefaultAvlbl)
 {
   if ( theId != Algo )
   {
+    bool enable = ! myAvailableHyps[ theId ].isEmpty();
     myHyp[ theId ]->clear();
-    myHyp[ theId ]->addItem( tr( "NONE" ) );
-    myHyp[ theId ]->addItems( theHyps );
-    myHyp[ theId ]->setCurrentIndex( 0 );
-    myHyp[ theId ]->setEnabled( !theHyps.isEmpty() );
+    if ( enable )
+    {
+      QString none = tr( theDefaultAvlbl ? "DEFAULT" : ( theId == AddHyp ) ? "NONE" : "NONE" );
+      myHyp[ theId ]->addItem( none );
+      myHyp[ theId ]->addItems( theHyps );
+      myHyp[ theId ]->setCurrentIndex( 0 );
+    }
+    myHyp    [ theId ]->setEnabled( enable );
     myEditHyp[ theId ]->setEnabled( false );
   }
 }
@@ -188,9 +201,9 @@ void SMESHGUI_MeshTab::setExistingHyps( const int theId, const QStringList& theH
 //================================================================================
 /*!
  * \brief Adds hypothesis in combo box of available ones
 * \param theId - identifier of hypothesis (main or additional, see HypType enumeration)
 * \param theHyp - name of hypothesis to be added
- * 
+ * \param theId - identifier of hypothesis (main or additional, see HypType enumeration)
+ * \param theHyp - name of hypothesis to be added
+ *
  * Adds hypothesis in combo box of available ones. This method is called by operation
  * after creation of new hypothesis.
  */
index 08f11ff..e8ea69f 100644 (file)
@@ -119,7 +119,7 @@ public:
   virtual ~SMESHGUI_MeshTab();
   
   void                         setAvailableHyps( const int, const QStringList& );
-  void                         setExistingHyps( const int, const QStringList& );
+  void                         setExistingHyps( const int, const QStringList&, bool=false);
   void                         addHyp( const int, const QString& );
   void                         renameHyp( const int, const int, const QString& );
   void                         setCurrentHyp( const int, const int );
index 4fe3a65..f91dbca 100644 (file)
@@ -63,6 +63,7 @@
 // Qt includes
 #include <QStringList>
 #include <QLineEdit>
+#include <QApplication>
 
 // OCCT includes
 #include <TopoDS.hxx>
@@ -213,10 +214,13 @@ void SMESHGUI_MeshOp::startOperation()
     connect( myDlg, SIGNAL( hypoSet( const QString& )), SLOT( onHypoSet( const QString& )));
     connect( myDlg, SIGNAL( geomSelectionByMesh( bool )), SLOT( onGeomSelectionByMesh( bool )));
     connect( myDlg, SIGNAL( selectMeshType( const int, const int ) ), SLOT( onAlgoSetByMeshType( const int, const int)));
-    if ( myToCreate )
+    if ( myToCreate ) {
       if ( myIsMesh ) myHelpFileName = "constructing_meshes_page.html";
-      else myHelpFileName = "constructing_submeshes_page.html";
-    else myHelpFileName = "editing_meshes_page.html";
+      else            myHelpFileName = "constructing_submeshes_page.html";
+    }
+    else {
+      myHelpFileName = "editing_meshes_page.html";
+    }
   }
   SMESHGUI_SelectionOp::startOperation();
   // iterate through dimensions and get available algoritms, set them to the dialog
@@ -255,6 +259,7 @@ void SMESHGUI_MeshOp::startOperation()
   selectionDone();
 
   myIgnoreAlgoSelection = false;
+  myHasConcurrentSubBefore = false;
 
   myObjectToSelect.clear();
 }
@@ -594,15 +599,16 @@ void SMESHGUI_MeshOp::selectionDone()
       {
         if (pObj != 0)
         {
-          SMESH::SMESH_subMesh_var aVar =
+          SMESH::SMESH_subMesh_var submeshVar =
             SMESH::SMESH_subMesh::_narrow( _CAST( SObject,pObj )->GetObject() );
-          myDlg->setObjectShown( SMESHGUI_MeshDlg::Mesh, !aVar->_is_nil() );
+          myDlg->setObjectShown( SMESHGUI_MeshDlg::Mesh, !submeshVar->_is_nil() );
           myDlg->setObjectShown( SMESHGUI_MeshDlg::Geom, true );
           myDlg->objectWg( SMESHGUI_MeshDlg::Mesh, SMESHGUI_MeshDlg::Btn )->hide();
           myDlg->objectWg( SMESHGUI_MeshDlg::Geom, SMESHGUI_MeshDlg::Btn )->hide();
           myDlg->updateGeometry();
           myDlg->adjustSize();
           readMesh();
+          myIsMesh = submeshVar->_is_nil();
         }
         else
           myDlg->reset();
@@ -676,7 +682,7 @@ void SMESHGUI_MeshOp::selectionDone()
         myDlg->disableTab(i);
       }
       myMaxShapeDim = -1;
-      //Hide labels and fields (Mesh ang Geometry)
+      //Hide labels and fields (Mesh and Geometry)
       myDlg->setObjectShown( SMESHGUI_MeshDlg::Mesh, false );
       myDlg->setObjectShown( SMESHGUI_MeshDlg::Geom, false );
       myDlg->adjustSize();
@@ -740,9 +746,13 @@ bool SMESHGUI_MeshOp::isValid( QString& theMess ) const
   if ( myToCreate )
   {
     QString aGeomEntry = myDlg->selectedObject( SMESHGUI_MeshDlg::Geom );
-    if ( aGeomEntry == "" )
+    if ( aGeomEntry.isEmpty() )
     {
-      theMess = tr( "GEOMETRY_OBJECT_IS_NOT_DEFINED" );
+      theMess = tr( myIsMesh ?
+                    "GEOMETRY_OBJECT_IS_NOT_DEFINED_MESH" :
+                    "GEOMETRY_OBJECT_IS_NOT_DEFINED_SUBMESH");
+      if ( !myIsMesh )
+        return false;
       dlg()->show();
       if ( SUIT_MessageBox::warning( myDlg, tr( "SMESH_WRN_WARNING" ), theMess,
            SUIT_MessageBox::Yes, SUIT_MessageBox::No ) == SUIT_MessageBox::No )
@@ -831,7 +841,7 @@ void SMESHGUI_MeshOp::availableHyps( const int       theDim,
   theHyps.clear();
   bool isAlgo = ( theHypType == Algo );
   bool isAux  = ( theHypType == AddHyp );
-  QStringList aHypTypeNameList = SMESH::GetAvailableHypotheses( isAlgo, theDim, isAux, myIsOnGeometry );
+  QStringList aHypTypeNameList = SMESH::GetAvailableHypotheses( isAlgo, theDim, isAux, myIsOnGeometry, !myIsMesh );
 
   QStringList::const_iterator anIter;
   for ( anIter = aHypTypeNameList.begin(); anIter != aHypTypeNameList.end(); ++anIter )
@@ -847,23 +857,23 @@ void SMESHGUI_MeshOp::availableHyps( const int       theDim,
 //================================================================================
 /*!
  * \brief Gets existing hypotheses or algorithms
 * \param theDim - specifies dimension of returned hypotheses/algorifms
 * \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 theHyps - output list of names.
 * \param theHypVars - output list of variables.
 * \param theAlgoData - to select hypos able to be used by this algo (optional)
 \param theDim - specifies dimension of returned hypotheses/algorifms
 \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 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
  */
 //================================================================================
-void SMESHGUI_MeshOp::existingHyps( const int theDim,
-                                    const int theHypType,
-                                    _PTR(SObject) theFather,
-                                    QStringList& theHyps,
-                                    THypList& theHypList,
+void SMESHGUI_MeshOp::existingHyps( const int       theDim,
+                                    const int       theHypType,
+                                    _PTR(SObject)   theFather,
+                                    QStringList&    theHyps,
+                                    THypList&       theHypList,
                                     HypothesisData* theAlgoData)
 {
   // Clear hypoheses list
@@ -916,7 +926,7 @@ void SMESHGUI_MeshOp::existingHyps( const int theDim,
             if ( !aData) continue;
             if ( ( theDim == -1 || aData->Dim.contains( theDim ) ) &&
                  ( isCompatible ( theAlgoData, aData, theHypType )) &&
-                 ( isAux == aData->IsAux ))
+                 ( theHypType == Algo || isAux == aData->IsAuxOrNeedHyp ))
             {
               std::string aHypName = aName->Value();
               theHyps.append( aHypName.c_str() );
@@ -1494,6 +1504,7 @@ void SMESHGUI_MeshOp::onAlgoSelected( const int theIndex,
         }
       }
       // get hyps compatible with curAlgo
+      bool defaulHypAvlbl = false;
       if ( curAlgo )
       {
         // check if a selected hyp is compatible with the curAlgo
@@ -1504,10 +1515,11 @@ void SMESHGUI_MeshOp::onAlgoSelected( const int theIndex,
         }
         existingHyps( dim, type, pObj, anExisting, myExistingHyps[ dim ][ type ], curAlgo);
         availableHyps( dim, type, anAvailable, myAvailableHypData[ dim ][ type ], curAlgo);
+        defaulHypAvlbl = (type == MainHyp && !curAlgo->IsAuxOrNeedHyp );
       }
       // set list of hypotheses
       myDlg->tab( dim )->setAvailableHyps( type, anAvailable );
-      myDlg->tab( dim )->setExistingHyps( type, anExisting );
+      myDlg->tab( dim )->setExistingHyps( type, anExisting, defaulHypAvlbl );
 
       // set current existing hypothesis
       if ( !curHyp->_is_nil() && !anExisting.isEmpty() )
@@ -1826,6 +1838,8 @@ bool SMESHGUI_MeshOp::createSubMesh( QString& theMess, QStringList& theEntryList
   selectObject( _PTR(SObject)() );
   selectionDone();
 
+  checkSubMeshConcurrency( aMeshVar, aSubMeshVar, /*askUser=*/true );
+
   return true;
 }
 
@@ -1991,7 +2005,7 @@ SMESH::SMESH_Hypothesis_var SMESHGUI_MeshOp::getAlgo( const int theDim )
 
 //================================================================================
 /*!
- * \brief Reads parameters of an edited mesh and assigns them to the dialog
+ * \brief Reads parameters of an edited mesh/sub-mesh and assigns them to the dialog
  *
  * Called when mesh is edited only.
  */
@@ -2016,6 +2030,7 @@ void SMESHGUI_MeshOp::readMesh()
         QString aMeshName = name( aMeshSO );
         myDlg->setObjectText( SMESHGUI_MeshDlg::Mesh, aMeshName );
       }
+      myHasConcurrentSubBefore = checkSubMeshConcurrency( aMeshVar, aSubMeshVar );
     }
 
     // Get name of geometry object
@@ -2031,6 +2046,7 @@ void SMESHGUI_MeshOp::readMesh()
   // Get hypotheses and algorithms assigned to the mesh/sub-mesh
   QStringList anExisting;
   const int lastDim = ( myIsOnGeometry ) ? SMESH::DIM_0D : SMESH::DIM_3D;
+  bool algoFound = false;
   for ( int dim = SMESH::DIM_3D; dim >= lastDim; --dim )
   {
     // get algorithm
@@ -2047,10 +2063,12 @@ void SMESHGUI_MeshOp::readMesh()
 //         myAvailableHypData[ dim ][ Algo ].push_back( algoData );
 //         aHypIndex = myAvailableHypData[ dim ][ hypType ].count() - 1;
 //       }
+      algoFound = ( aHypIndex > -1 );
     }
     setCurrentHyp( dim, Algo, aHypIndex );
     // set existing and available hypothesis according to the selected algo
-    onAlgoSelected( aHypIndex, dim );
+    if ( aHypIndex > -1 || !algoFound )
+      onAlgoSelected( aHypIndex, dim );
   }
 
   // get hypotheses
@@ -2187,6 +2205,14 @@ bool SMESHGUI_MeshOp::editMeshOrSubMesh( QString& theMess )
     }
   }
 
+  SALOMEDS_SObject* aSObject = _CAST(SObject, pObj);
+  CORBA::Object_var anObject = aSObject->GetObject();
+  SMESH::SMESH_Mesh_var       aMeshVar = SMESH::SMESH_Mesh::_narrow( anObject );
+  SMESH::SMESH_subMesh_var aSubMeshVar = SMESH::SMESH_subMesh::_narrow( anObject );
+  bool isMesh = !aMeshVar->_is_nil();
+  if ( !isMesh && !aSubMeshVar->_is_nil() )
+    aMeshVar = aSubMeshVar->GetFather();
+
   // Assign new algorithms and hypotheses
   for ( int dim = aDim; dim <= SMESH::DIM_3D; dim++ )
   {
@@ -2199,18 +2225,11 @@ bool SMESHGUI_MeshOp::editMeshOrSubMesh( QString& theMess )
     if ( !anAlgoVar->_is_nil() && // some algo selected and
          myObjHyps[ dim ][ Algo ].count() == 0 ) // no algo assigned
     {
-      SALOMEDS_SObject* aSObject = _CAST(SObject, pObj);
-      CORBA::Object_var anObject = aSObject->GetObject();
-      SMESH::SMESH_Mesh_var aMeshVar = SMESH::SMESH_Mesh::_narrow( anObject );
-      bool isMesh = !aMeshVar->_is_nil();
-      if ( isMesh ) {
+      if ( isMesh )
         SMESH::AddHypothesisOnMesh( aMeshVar, anAlgoVar );
-      } else {
-        SMESH::SMESH_subMesh_var aVar =
-          SMESH::SMESH_subMesh::_narrow( _CAST(SObject,pObj)->GetObject() );
-        if ( !aVar->_is_nil() )
-          SMESH::AddHypothesisOnSubMesh( aVar, anAlgoVar );
-      }
+      else if ( !aSubMeshVar->_is_nil() )
+        SMESH::AddHypothesisOnSubMesh( aSubMeshVar, anAlgoVar );
+
       myObjHyps[ dim ][ Algo ].append( THypItem( anAlgoVar, aName) );
     }
 
@@ -2235,24 +2254,14 @@ bool SMESHGUI_MeshOp::editMeshOrSubMesh( QString& theMess )
       }
 
       // assign new hypotheses
-      if ( aNewHypIndex != anOldHypIndex && aNewHypIndex != -1 )
+      if ( aNewHypIndex != anOldHypIndex && aNewHypIndex > -1 )
       {
-        SMESH::SMESH_Mesh_var aMeshVar =
-          SMESH::SMESH_Mesh::_narrow( _CAST(SObject,pObj)->GetObject() );
-        bool isMesh = !aMeshVar->_is_nil();
         if ( isMesh )
-        {
           SMESH::AddHypothesisOnMesh
             (aMeshVar, myExistingHyps[ dim ][ hypType ][ aNewHypIndex ].first );
-        }
-        else
-        {
-          SMESH::SMESH_subMesh_var aVar =
-            SMESH::SMESH_subMesh::_narrow( _CAST(SObject,pObj)->GetObject() );
-          if ( !aVar->_is_nil() )
-            SMESH::AddHypothesisOnSubMesh
-              ( aVar, myExistingHyps[ dim ][ hypType ][ aNewHypIndex ].first );
-        }
+        else if ( !aSubMeshVar->_is_nil() )
+          SMESH::AddHypothesisOnSubMesh
+            ( aSubMeshVar, myExistingHyps[ dim ][ hypType ][ aNewHypIndex ].first );
       }
       // reread all hypotheses of mesh if necessary
       QStringList anExisting;
@@ -2260,11 +2269,63 @@ bool SMESHGUI_MeshOp::editMeshOrSubMesh( QString& theMess )
     }
   }
 
+  myHasConcurrentSubBefore =
+    checkSubMeshConcurrency( aMeshVar, aSubMeshVar, /*askUser=*/!myHasConcurrentSubBefore );
+
   return true;
 }
 
 //================================================================================
 /*!
+ * \brief Checks if a concurrent sub-meshes appear as result of sub-mesh
+ *        creation/edition and, if (askUser) , proposes the uses to set up a desired
+ *        order of sub-mesh computation.
+ *        Returns \c true if a sub-mesh concurrency detected.
+ */
+//================================================================================
+
+bool SMESHGUI_MeshOp::checkSubMeshConcurrency(SMESH::SMESH_Mesh_ptr    mesh,
+                                              SMESH::SMESH_subMesh_ptr submesh,
+                                              bool                     askUser)
+{
+  if ( CORBA::is_nil( mesh ) || CORBA::is_nil( submesh ))
+    return false;
+
+  bool isNewConcurrent = mesh->IsUnorderedSubMesh( submesh->GetId() );
+  if ( isNewConcurrent && askUser )
+  {
+    int butID = SUIT_MessageBox::warning( myDlg->parentWidget(), tr( "SMESH_WARNING" ),
+                                          tr("CONCURRENT_SUBMESH_APPEARS"),
+                                          tr("SMESH_BUT_YES"), tr("SMESH_BUT_NO"));
+    if ( butID == 0 )
+    {
+      _PTR(SObject) meshSO = SMESH::FindSObject( mesh );
+      LightApp_SelectionMgr* aSelectionMgr = selectionMgr();
+      if ( meshSO && aSelectionMgr )
+      {
+        myDlg->setEnabled( false ); // disactivate selection
+        selectionMgr()->clearFilters();
+        selectObject( meshSO );
+        SMESHGUI::GetSMESHGUI()->OnGUIEvent( 713 ); // MESH_ORDER
+        qApp->processEvents();
+
+        myDlg->setEnabled( true );
+        int obj = myDlg->getActiveObject();
+        onActivateObject( obj ); // restore filter
+        if ( !myToCreate )
+        {
+          selectObject( SMESH::FindSObject( submesh ));
+          selectionDone();
+        }
+      }
+    }
+  }
+
+  return isNewConcurrent;
+}
+
+//================================================================================
+/*!
  * \brief Verifies whether given operator is valid for this one
  * \param theOtherOp - other operation
  * \return Returns TRUE if the given operator is valid for this one, FALSE otherwise
index 5f56882..90d49e2 100644 (file)
@@ -111,6 +111,9 @@ private:
   bool                           createMesh( QString&, QStringList& );
   bool                           createSubMesh( QString&, QStringList& );
   bool                           editMeshOrSubMesh( QString& );
+  bool                           checkSubMeshConcurrency( SMESH::SMESH_Mesh_ptr    mesh,
+                                                          SMESH::SMESH_subMesh_ptr submesh,
+                                                          bool                     askUser=false);
 
   int                            currentHyp( const int, const int ) const;
   bool                           isAccessibleDim( const int ) const;
@@ -135,6 +138,7 @@ private:
   bool                           myToCreate;
   bool                           myIsMesh;
   bool                           myIsOnGeometry; //!< TRUE if edited mesh accotiated with geometrical object
+  bool                           myHasConcurrentSubBefore;
 
   TDim2Type2HypList              myExistingHyps; //!< all hypothesis of SMESH module
   TDim2Type2HypList              myObjHyps;      //!< hypothesis assigned to the current 
index 0ca286b..74b42da 100644 (file)
@@ -123,9 +123,11 @@ bool SMESHGUI_XmlHandler::startElement (const QString&, const QString&,
     if (atts.value("type") != "")
     {
       QString aHypAlType = atts.value("type");
-      QString aLabel = atts.value("label-id");
-      QString anIcon = atts.value("icon-id");
-      bool isAux = atts.value("auxiliary") == "true";
+      QString     aLabel = atts.value("label-id");
+      QString     anIcon = atts.value("icon-id");
+      bool isAuxOrNeedHyp = ( qName == "hypothesis" ?
+                              atts.value("auxiliary") == "true" :
+                              atts.value("need-hyp" ) == "true" );
       bool isNeedGeom = true, isSupportSubmeshes = false;
       QString aNeedGeom = atts.value("need-geom");
       if ( !aNeedGeom.isEmpty() )
@@ -133,6 +135,11 @@ bool SMESHGUI_XmlHandler::startElement (const QString&, const QString&,
       QString suppSub = atts.value("support-submeshes");
       if ( !suppSub.isEmpty() )
         isSupportSubmeshes = (suppSub == "true");
+      QString context = atts.value("context");
+      if ( context.isEmpty() )
+        context = "ANY";
+      else
+        context = context.toUpper();
 
       QString aDimStr = atts.value("dim");
       aDimStr = aDimStr.remove( ' ' );
@@ -162,7 +169,7 @@ bool SMESHGUI_XmlHandler::startElement (const QString&, const QString&,
       if ( !aHypAlType.contains( BAD_HYP_FLAG ) ) {
         HypothesisData* aHypData =
           new HypothesisData (aHypAlType, myPluginName, myServerLib, myClientLib,
-                              aLabel, anIcon, aDim, isAux,
+                              aLabel, anIcon, context, aDim, isAuxOrNeedHyp,
                               attr[ HYPOS ], attr[ OPT_HYPOS ], attr[ INPUT ], attr[ OUTPUT ],
                               isNeedGeom, isSupportSubmeshes );