]> SALOME platform Git repositories - modules/smesh.git/commitdiff
Salome HOME
23173: EDF 11552 - Problem using Add 0D element function
authoreap <eap@opencascade.com>
Tue, 29 Sep 2015 16:25:32 +0000 (19:25 +0300)
committereap <eap@opencascade.com>
Tue, 29 Sep 2015 16:25:32 +0000 (19:25 +0300)
IPAL52875: Extrusion along a path: the buttons are not active if the path is closed
IPAL52882: Hexahedron (i,j,k) makes a wrong mesh on a block with composite sides

17 files changed:
doc/salome/gui/SMESH/images/hexa_ijk_mesh.png [new file with mode: 0644]
doc/salome/gui/SMESH/images/image88.jpg [changed mode: 0755->0644]
doc/salome/gui/SMESH/images/sewing_auto.png
doc/salome/gui/SMESH/input/adding_nodes_and_elements.doc
doc/salome/gui/SMESH/input/basic_meshing_algos.doc
doc/salome/gui/SMESH/input/constructing_meshes.doc
doc/salome/gui/SMESH/input/selection_filter_library.doc
doc/salome/gui/SMESH/input/sewing_meshes.doc
src/SMESH/SMESH_MeshEditor.cxx
src/SMESHGUI/SMESHGUI_Add0DElemsOnAllNodesDlg.cxx
src/SMESHGUI/SMESHGUI_Add0DElemsOnAllNodesDlg.h
src/SMESHGUI/SMESHGUI_ExtrusionAlongPathDlg.cxx
src/SMESHGUI/SMESHGUI_MeshOp.cxx
src/SMESHGUI/SMESHGUI_SewingDlg.cxx
src/SMESHUtils/SMESH_FreeBorders.cxx
src/SMESHUtils/SMESH_MeshAlgos.cxx
src/StdMeshers/StdMeshers_CompositeHexa_3D.cxx

diff --git a/doc/salome/gui/SMESH/images/hexa_ijk_mesh.png b/doc/salome/gui/SMESH/images/hexa_ijk_mesh.png
new file mode 100644 (file)
index 0000000..577ee8e
Binary files /dev/null and b/doc/salome/gui/SMESH/images/hexa_ijk_mesh.png differ
old mode 100755 (executable)
new mode 100644 (file)
index 3b2a973..9499ab2
Binary files a/doc/salome/gui/SMESH/images/image88.jpg and b/doc/salome/gui/SMESH/images/image88.jpg differ
index 0bf19b49083d738b3d3819c8ac7ac2a02f9dfd57..f81cfe27765c7e1d8fffce8751da496f9385f733 100644 (file)
Binary files a/doc/salome/gui/SMESH/images/sewing_auto.png and b/doc/salome/gui/SMESH/images/sewing_auto.png differ
index 1aa0661ab863cad9d8f4f0c62dc9350153427fb4..855b7e5ea364c0a35c3baafc46974fd91f4bd6eb 100644 (file)
@@ -90,29 +90,35 @@ selecting them in the 3D viewer and click the \b Apply or
 \anchor adding_0delems_on_all_nodes_anchor
 <h2>Making 0D elements on Element Nodes</h2>
 
-There is another way to create 0D elements. It is possible to create 
+There is another way to create 0D elements. It is possible to create
 0D elements on all nodes of the selected mesh, sub-mesh, or a group of elements or nodes.
 
 \image html dlg_0D_on_all_nodes.png
 
-In this dialog 
+In this dialog
 <ul>
   <li> The radio-buttons allow choosing the type of object to create 0D elements on.
     <ul>
-      <li><b> Mesh, sub-mesh, group </b> -  this button allows selecting
-       a mesh, a sub-mesh or a group to create 0D elements on the nodes of its
+      <li><b> Mesh, sub-mesh, group </b> - this button allows selecting
+        a mesh, a sub-mesh or a group to create 0D elements on the nodes of its
         elements. The name of the selected object is shown in the dialog. </li>
       <li><b> Elements </b> - this button allows selecting elements in the
         VTK viewer or typing their IDs in the dialog.</li>
       <li><b> Nodes </b> - this button allows selecting nodes to create
         0D elements on in the VTK viewer or typing their IDs in the dialog.</li>
   </ul></li>
-  <li><b> Set Filter </b> button allows selecting elements or nodes 
-by filtering mesh elements or nodes with different criteria
-(see \ref filtering_elements "Filter usage").</li>
-<li> Switching on <b>Add to group</b> check-box allows specifying the
-  name of the group to which all created or found 0D elements  will be added. You can either select an existing group from
-  a drop-down list, or enter the name of the group to be created.</li>
+  <li><b> Set Filter </b> button allows selecting elements or nodes
+    by filtering mesh elements or nodes with different criteria
+    (see \ref filtering_elements "Filter usage").</li>
+  <li> Switching on <b>Add to group</b> check-box allows specifying the
+    name of the group to which all created or found (existing) 0D elements will
+    be added. You can either select an existing group from a drop-down
+    list, or enter the name of the group to be created. If a selected
+    existing \ref grouping_elements_page "group" is not Standalone
+    (Group On Geometry or Group On Filter) it will be converted to
+    Standalone.
+    \warning If <b>Add to group</b> is activated it has to be filled in.
+</li>
 </ul>
 
 
@@ -124,7 +130,7 @@ by filtering mesh elements or nodes with different criteria
 In this dialog box specify the nodes, which will form your ball elements,
 either by selecting them in the 3D viewer or by manually entering their IDs,
 specify the ball diameter and click the \b Apply or <b>Apply and
-Close</b> button.
+  Close</b> button.
 
 \image html add_ball.png
 
index 4804800c533b0239e873da8f6c3d2a4d45d169c0..090abd76f8dfd6117043c16c09b9c2f1a3624e27 100644 (file)
@@ -39,8 +39,15 @@ number of mesh segments following an 1D hypothesis.
 <li>For meshing of 3D entities (<b>solid objects</b>):</li>
 
 <ul>
-<li><em>Hexahedron (i,j,k)</em>meshing algorithm - 6-sided solids are
-  split into hexahedral (cuboid) elements.</li>
+<li><em>Hexahedron (i,j,k)</em> meshing algorithm - solids are
+  split into hexahedral elements thus forming a structured 3D
+  mesh. The algorithm requires that 2D mesh generated on a solid could
+  be considered as a mesh of a box, i.e. there should be six nodes shared
+  by three quadrangles and the rest nodes should be shared by four
+  quadrangles.
+\image html hexa_ijk_mesh.png "Structured mesh generated by Hexahedron (i,j,k) on a solid bound by 16 faces"
+</li>
+
 <li>\subpage cartesian_algo_page "Body Fitting" meshing
   algorithm - solids are split into hexahedral elements forming
   a Cartesian grid; polyhedra and other types of elements are generated
@@ -66,7 +73,7 @@ There is also a number of more specific algorithms:
 <li>\subpage projection_algos_page "for meshing by projection of another mesh"</li>
 <li>\subpage import_algos_page "for meshing by importing elements from another mesh"</li>
 <li>\subpage radial_prism_algo_page "for meshing geometrical objects with cavities"</li>
-<li>\subpage radial_quadrangle_1D2D_algo_page "for meshing special 2d faces (circles and part of circles)"</li>
+<li>\subpage radial_quadrangle_1D2D_algo_page "for meshing special faces (circles and parts of circles)"</li>
 <li>\subpage use_existing_page "Use Edges to be Created Manually" and 
 \ref use_existing_page "Use Faces to be Created Manually" algorithms can be
 used to create a 1D or a 2D mesh in a python script.</li>
index f28be8601fb47c83ebfef2fab0ed2fbc4a8d3d52..1a51128399a212ea271df42295d34c033838201c 100644 (file)
@@ -187,13 +187,9 @@ creation and computing) of the following steps:
     which is a 2D object, you do not need to define a 3D Algorithm and
     Hypotheses.
 
-    In the <b>Object Browser</b> the structure of the new mesh will be
+    In the <b>Object Browser</b> the structure of the new mesh is
     displayed as follows:
-
-    <center>
     \image html image88.jpg
-    </center>
-
     It contains: 
     <ul>
       <li>a mesh name (<em>Mesh_mechanic</em>);
@@ -203,6 +199,13 @@ creation and computing) of the following steps:
         to the hypotheses chosen at the construction of the mesh;</li>
       <li><b>Applied algorithms</b> folder containing the references
         to the algorithms chosen at the construction of the mesh.</li> 
+      <li><b>SubMeshes on Face</b> folder containing the sub-meshes
+        defined on geometrical faces. There also can be folders for
+        sub-meshes on vertices, edges, wires, shells, solids and
+        compounds.</li>
+      <li><b>Groups of Faces</b> folder containing the groups of mesh
+        faces. There also can be folders for groups of nodes, edges,
+        volumes 0D elements and balls.</li>
     </ul>
 
     There is an alternative way to assign Algorithms and Hypotheses by
@@ -212,15 +215,25 @@ creation and computing) of the following steps:
     CustomMeshers.xml file located in the home directory. CustomMeshers.xml
     file must describe sets of hypotheses in the
     same way as ${SMESH_ROOT_DIR}/share/salome/resources/smesh/StdMeshers.xml 
-    file does (sets of hypotheses are enclosed between <hypotheses-set-group>
-      tags).
-      
-      <center>
+    file does (sets of hypotheses are enclosed between \<hypotheses-set-group\>
+      tags). For example:
+~~~~~~{.xml}
+    <?xml version='1.0' encoding='us-ascii'?>
+    <!DOCTYPE meshers PUBLIC "" "desktop.dtd">
+    <meshers>
+    <hypotheses-set-group>
+        <hypotheses-set name="My favorite hypotheses"
+                        hypos="AutomaticLength"
+                        algos="CompositeSegment_1D, Quadrangle_2D, GHS3D_3D"/>
+    </hypotheses-set-group>
+    </meshers>
+~~~~~~
+<br>
+<center>
       \image html hypo_sets.png
       List of sets of hypotheses. Tag <em>[custom]</em> is
       automatically added to the sets defined by the user.
-      </center>
-
+</center>
       \note 
       - \a "Automatic" in the names of predefined sets of hypotheses
       does not actually mean that they are suitable for meshing any
index 6acd7e751aa1fdd0404c6fa2c50785d0e2d6a856..30870607574f58c3dc6b1b4465c452de6fc6ad2c 100644 (file)
@@ -3,7 +3,7 @@
 \page selection_filter_library_page Selection filter library
 
 \n Selection filter library allows creating and storing in files
-filters that can be later reused for operations on meshes. You can
+filters that can be later loaded and used for operations on meshes. You can
 access to it from the Main Menu via <b>Tools / Selection filter library</b>.
 It is also possible to save any filter by invoking the filter library
 from \a Filter dialog launched from any mesh operation.
index 18be054a399a295d45976e29686d98b469bf4277..8697b36f48b7437b7a04232c5f6acc9e28f4790d 100644 (file)
@@ -63,9 +63,9 @@ To use \b Automatic sewing:
 <li>The found groups of <b>Coincident Free Borders</b> are shown in a
   list, a group per a line. Each group has its own color which is used
   to display the borders of the group in the VTK Viewer. A free border
-  within a group is designated by IDs of its first and last nodes within
-  parenthesis. All borders present in the list will be sewn upon \b
-  Apply.</li>
+  within a group is designated by IDs of its first, second and last
+  nodes within parenthesis. All borders present in the list will be
+  sewn upon \b Apply.</li>
 <li>\b Remove button removes selected groups from the list.</li>
 <li><b>Select All</b> check-box selects all groups in the list.</li>
 <li>When a group is selected, its borders appear in <b>Edit Selected
index 146e8c12a2eccbbaa4df2033f7a1ea46c680b1b9..bb114051dae41a68fbdf8bcd3249b1564d15f5b7 100644 (file)
@@ -7963,10 +7963,6 @@ public:
   const SMDS_MeshElement* Get() const
   { return myElem; }
 
-  void Set(const SMDS_MeshElement* e) const
-  { myElem = e; }
-
-
 private:
   mutable const SMDS_MeshElement* myElem;
 };
index 295f5c52ee5c5a51caf30abcc6d1850b0d467ffc..96fca0d9f0f4e658cf0e94ae1e8d60964a707c9e 100644 (file)
@@ -223,6 +223,7 @@ SMESHGUI_Add0DElemsOnAllNodesOp::SMESHGUI_Add0DElemsOnAllNodesOp()
 
   connect( myDlg,              SIGNAL( selTypeChanged(int) ), SLOT( onSelTypeChange(int)));
   connect( myDlg->myFilterBtn, SIGNAL( clicked()),            SLOT( onSetFilter() ));
+  connect( myDlg->myGroupBox,  SIGNAL( clicked(bool)),        SLOT( updateButtons() ));
 }
 
 //================================================================================
@@ -270,6 +271,7 @@ void SMESHGUI_Add0DElemsOnAllNodesOp::selectionDone()
 
   myIO.Nullify();
   myDlg->setObjectText( 0, "");
+  updateButtons();
 
   SALOME_ListIO aList;
   selectionMgr()->selectedObjects( aList );
@@ -297,7 +299,8 @@ void SMESHGUI_Add0DElemsOnAllNodesOp::selectionDone()
   // fill the list of existing groups
   myDlg->myGroupListCmBox->clear();
   myDlg->myGroupListCmBox->addItem( QString() );
-  if ( !myIO.IsNull() && myIO->hasEntry()) {
+  if ( !myIO.IsNull() && myIO->hasEntry())
+  {
     SMESH::SMESH_Mesh_var mesh = SMESH::GetMeshByIO( myIO );
     _PTR(SObject)       meshSO = SMESH::ObjectToSObject( mesh );
     _PTR(SObject) group0DRoot;
@@ -313,7 +316,42 @@ void SMESHGUI_Add0DElemsOnAllNodesOp::selectionDone()
           myDlg->myGroupListCmBox->addItem( groupName.c_str() );
       }
     }
+    // enable buttons
+    updateButtons();
+  }
+}
+
+//=======================================================================
+//function : updateButtons
+//purpose  : enable [Apply]
+//=======================================================================
+
+void SMESHGUI_Add0DElemsOnAllNodesOp::updateButtons()
+{
+  bool ok = false;
+
+  if (( !myIO.IsNull() && myIO->hasEntry() && !myDlg->objectText( 0 ).isEmpty() ) &&
+      ( !myDlg->myGroupBox->isChecked() || !myDlg->myGroupListCmBox->currentText().isEmpty() ))
+  {
+    SMESH::SMESH_Mesh_var mesh = SMESH::GetMeshByIO( myIO );
+    if ( !mesh->_is_nil() )
+    {
+      if ( myDlg->getSelectionType() == SEL_OBJECT )
+        ok = true;
+      else
+      {
+        QString        ids = myDlg->objectText( 0 );
+        QStringList idList = ids.split( " ", QString::SkipEmptyParts );
+        const bool  isElem = ( myDlg->getSelectionType() == SEL_ELEMENTS );
+        QStringList::iterator idIt = idList.begin();
+        for ( ; idIt != idList.end() && !ok; ++idIt )
+          ok = ( mesh->GetElementType( idIt->toLong(), isElem ) != SMESH::ALL );
+      }
+    }
   }
+
+  myDlg->button( QtxDialog::Apply )->setEnabled( ok );
+  myDlg->button( QtxDialog::OK    )->setEnabled( ok );
 }
 
 //================================================================================
@@ -496,3 +534,14 @@ void SMESHGUI_Add0DElemsOnAllNodesOp::onSetFilter()
 
   myFilterDlg->show();
 }
+
+//=======================================================================
+//function : onTextChanged
+//purpose  : SLOT called when the user types IDs
+//=======================================================================
+
+void SMESHGUI_Add0DElemsOnAllNodesOp::onTextChanged( int obj, const QStringList& text )
+{
+  SMESHGUI_SelectionOp::onTextChanged( obj, text );
+  updateButtons();
+}
index 49ae8724a086f827340fe4b58a24a44c6cdb4014..805b9316ba90962bcb24809958b96e0a28c641b7 100644 (file)
@@ -99,6 +99,8 @@ class SMESHGUI_EXPORT SMESHGUI_Add0DElemsOnAllNodesOp : public SMESHGUI_Selectio
   virtual bool                   onApply();
   void                           onSelTypeChange(int);
   void                           onSetFilter();
+  virtual void                   onTextChanged( int, const QStringList& );
+  void                           updateButtons();
 
  private:
   SMESHGUI_Add0DElemsOnAllNodesDlg* myDlg;
index 53b2cbf48824146d3d824ba2cc55d9df6993bbaa..4c6ebea19f80fb13dbc262c88ba0023942875a82 100644 (file)
@@ -253,7 +253,7 @@ SMESHGUI_ExtrusionAlongPathDlg::SMESHGUI_ExtrusionAlongPathDlg( SMESHGUI* theMod
   OkButton->setAutoDefault(true);
   OkButton->setDefault(true);
 
-  ApplyButton = new QPushButton(tr("SMESH_BUT_APPLY"), GroupButtons);
+  ApplyButton = new QPushButton(tr("SMESH_BUT_APPLY"), GroupButtons); 
   ApplyButton->setAutoDefault(true);
 
   CloseButton = new QPushButton(tr("SMESH_BUT_CLOSE"), GroupButtons);
@@ -444,64 +444,64 @@ bool SMESHGUI_ExtrusionAlongPathDlg::ClickOnApply()
 
     mesh->SetParameters( aParameters.join(":").toLatin1().constData() );
 
-      SMESH::ListOfIDSources_var nodes = new SMESH::ListOfIDSources();
-      SMESH::ListOfIDSources_var edges = new SMESH::ListOfIDSources();
-      SMESH::ListOfIDSources_var faces = new SMESH::ListOfIDSources();
-      maxSelType = SelectorWdg->GetSelected( nodes, edges, faces );
-
-      // is it necessary to switch on the next Display Mode?
-      SMESH::ElementType newType = (SMESH::ElementType)( maxSelType + 1 );
-      SMESH::array_of_ElementType_var oldTypes = mesh->GetTypes();
-      meshHadNewTypeBefore = false;
-      for ( size_t i = 0; i < oldTypes->length() && !meshHadNewTypeBefore; ++i )
-        meshHadNewTypeBefore = ( oldTypes[i] >= newType );
-
-      SMESH::SMESH_MeshEditor_var aMeshEditor = mesh->GetMeshEditor();
-      SMESH::SMESH_MeshEditor::Extrusion_Error retVal;
-
-      SMESH::ListOfGroups_var groups =
-        aMeshEditor->ExtrusionAlongPathObjects( nodes, edges, faces, myPath,
-                                                GEOM::GEOM_Object::_nil(),
-                                                aNodeStart, AnglesGrp->isChecked(),
-                                                anAngles, LinearAnglesCheck->isChecked(),
-                                                BasePointGrp->isChecked(), aBasePoint,
-                                                makeGroups, retVal );
-
-      wc.suspend();
-      switch (retVal) {
-      case SMESH::SMESH_MeshEditor::EXTR_NO_ELEMENTS:
-        SUIT_MessageBox::warning(this,
-                                 tr("SMESH_ERROR"),
-                                 tr("NO_ELEMENTS_SELECTED"));
-        return false; break;
-      case SMESH::SMESH_MeshEditor::EXTR_PATH_NOT_EDGE:
-        SUIT_MessageBox::warning(this,
-                                 tr("SMESH_ERROR"),
-                                 tr("SELECTED_PATH_IS_NOT_EDGE"));
-        return false; break;
-      case SMESH::SMESH_MeshEditor::EXTR_BAD_PATH_SHAPE:
-        SUIT_MessageBox::warning(this,
-                                 tr("SMESH_ERROR"),
-                                 tr("BAD_SHAPE_TYPE"));
-        return false; break;
-      case SMESH::SMESH_MeshEditor::EXTR_BAD_STARTING_NODE:
-        SUIT_MessageBox::warning(this,
-                                 tr("SMESH_ERROR"),
-                                 tr("EXTR_BAD_STARTING_NODE"));
-        return false; break;
-      case SMESH::SMESH_MeshEditor::EXTR_BAD_ANGLES_NUMBER:
-        SUIT_MessageBox::warning(this,
-                                 tr("SMESH_ERROR"),
-                                 tr("WRONG_ANGLES_NUMBER"));
-        return false; break;
-      case SMESH::SMESH_MeshEditor::EXTR_CANT_GET_TANGENT:
-        SUIT_MessageBox::warning(this,
-                                 tr("SMESH_ERROR"),
-                                 tr("CANT_GET_TANGENT"));
-        return false; break;
-      case SMESH::SMESH_MeshEditor::EXTR_OK:
-        break;
-      }
+    SMESH::ListOfIDSources_var nodes = new SMESH::ListOfIDSources();
+    SMESH::ListOfIDSources_var edges = new SMESH::ListOfIDSources();
+    SMESH::ListOfIDSources_var faces = new SMESH::ListOfIDSources();
+    maxSelType = SelectorWdg->GetSelected( nodes, edges, faces );
+
+    // is it necessary to switch on the next Display Mode?
+    SMESH::ElementType newType = (SMESH::ElementType)( maxSelType + 1 );
+    SMESH::array_of_ElementType_var oldTypes = mesh->GetTypes();
+    meshHadNewTypeBefore = false;
+    for ( size_t i = 0; i < oldTypes->length() && !meshHadNewTypeBefore; ++i )
+      meshHadNewTypeBefore = ( oldTypes[i] >= newType );
+
+    SMESH::SMESH_MeshEditor_var aMeshEditor = mesh->GetMeshEditor();
+    SMESH::SMESH_MeshEditor::Extrusion_Error retVal;
+
+    SMESH::ListOfGroups_var groups =
+      aMeshEditor->ExtrusionAlongPathObjects( nodes, edges, faces, myPath,
+                                              GEOM::GEOM_Object::_nil(),
+                                              aNodeStart, AnglesGrp->isChecked(),
+                                              anAngles, LinearAnglesCheck->isChecked(),
+                                              BasePointGrp->isChecked(), aBasePoint,
+                                              makeGroups, retVal );
+
+    wc.suspend();
+    switch (retVal) {
+    case SMESH::SMESH_MeshEditor::EXTR_NO_ELEMENTS:
+      SUIT_MessageBox::warning(this,
+                               tr("SMESH_ERROR"),
+                               tr("NO_ELEMENTS_SELECTED"));
+      return false; break;
+    case SMESH::SMESH_MeshEditor::EXTR_PATH_NOT_EDGE:
+      SUIT_MessageBox::warning(this,
+                               tr("SMESH_ERROR"),
+                               tr("SELECTED_PATH_IS_NOT_EDGE"));
+      return false; break;
+    case SMESH::SMESH_MeshEditor::EXTR_BAD_PATH_SHAPE:
+      SUIT_MessageBox::warning(this,
+                               tr("SMESH_ERROR"),
+                               tr("BAD_SHAPE_TYPE"));
+      return false; break;
+    case SMESH::SMESH_MeshEditor::EXTR_BAD_STARTING_NODE:
+      SUIT_MessageBox::warning(this,
+                               tr("SMESH_ERROR"),
+                               tr("EXTR_BAD_STARTING_NODE"));
+      return false; break;
+    case SMESH::SMESH_MeshEditor::EXTR_BAD_ANGLES_NUMBER:
+      SUIT_MessageBox::warning(this,
+                               tr("SMESH_ERROR"),
+                               tr("WRONG_ANGLES_NUMBER"));
+      return false; break;
+    case SMESH::SMESH_MeshEditor::EXTR_CANT_GET_TANGENT:
+      SUIT_MessageBox::warning(this,
+                               tr("SMESH_ERROR"),
+                               tr("CANT_GET_TANGENT"));
+      return false; break;
+    case SMESH::SMESH_MeshEditor::EXTR_OK:
+      break;
+    }
   } catch (...) {
     return false;
   }
@@ -1048,11 +1048,19 @@ bool SMESHGUI_ExtrusionAlongPathDlg::isValuesValid()
   if ( type != SMESH::NODE )
     return false;
 
-  SMESH::long_array_var elems = mesh->GetNodeInverseElements( aNodeStart );
-  if ( elems->length() != 1 ||
-       mesh->GetElementType( elems[0], true ) != SMESH::EDGE )
-    return false;
-
+  if ( mesh->HasShapeToMesh() )
+  {
+    SMESH::NodePosition_var pos = mesh->GetNodePosition( aNodeStart );
+    if ( pos->shapeType != GEOM::VERTEX )
+      return false;
+  }
+  else
+  {
+    SMESH::long_array_var elems = mesh->GetNodeInverseElements( aNodeStart );
+    if ( elems->length() != 1 ||
+         mesh->GetElementType( elems[0], true ) != SMESH::EDGE )
+      return false;
+  }
   return true;
 }
 
index 0b4c1eafc67d3753614e943d80bb4576d9e41b52..f4912f423c753877767ad74630ff7bc9bb8b21dc 100644 (file)
@@ -206,11 +206,11 @@ void SMESHGUI_MeshOp::startOperation()
     for ( int i = SMESH::DIM_0D; 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 ) ) );
+               this, SLOT( onAlgoSelected( const int ) ) );
     }
     connect( myDlg, SIGNAL( hypoSet( const QString& )), SLOT( onHypoSet( const QString& )));
     connect( myDlg, SIGNAL( geomSelectionByMesh( bool )), SLOT( onGeomSelectionByMesh( bool )));
@@ -1583,11 +1583,12 @@ void SMESHGUI_MeshOp::onAlgoSelected( const int theIndex,
       // remember current algo
       prevAlgo = algoByDim[ dim ] = hypData( dim, Algo, algoIndex );
     }
-    if ( myMaxShapeDim == SMESH::DIM_3D && forward && algoDim == SMESH::DIM_1D ) {
-       algoDim = SMESH::DIM_3D;
-       forward = -1;
-       a3DAlgo = prevAlgo;
-       continue;
+    if ( myMaxShapeDim == SMESH::DIM_3D && forward && algoDim == SMESH::DIM_1D )
+    {
+      algoDim = SMESH::DIM_3D;
+      forward = -1;
+      a3DAlgo = prevAlgo;
+      continue;
     }
   }
 
index 00ce12ef3044de3849791cec619aaa2049334d75..3753dff1d9762c8b3037c729a259845adbe5dd61 100644 (file)
@@ -54,6 +54,7 @@
 #include <SVTK_ViewModel.h>
 #include <SVTK_ViewWindow.h>
 #include <SalomeApp_IntSpinBox.h>
+#include <SalomeApp_Tools.h>
 
 // OCCT includes
 #include <TColStd_MapOfInteger.hxx>
@@ -832,8 +833,9 @@ QString SMESHGUI_SewingDlg::getPartText(const SMESH::FreeBorderPart& aPART)
     if ( 0 <= aPART.node1    && aPART.node1 < aBRD.nodeIDs.length() &&
          0 <= aPART.nodeLast && aPART.nodeLast < aBRD.nodeIDs.length() )
     {
-      text += QString("( %1 %2 ) ")
+      text += QString("( %1 %2 %3 ) ")
         .arg( aBRD.nodeIDs[ aPART.node1 ] )
+        .arg( aBRD.nodeIDs[ aPART.node2 ] )
         .arg( aBRD.nodeIDs[ aPART.nodeLast ] );
     }
   }
@@ -883,30 +885,30 @@ void SMESHGUI_SewingDlg::onDetectClicked()
 
   SMESH::SMESH_MeshEditor_var editor = myMesh->GetMeshEditor();
   myBorders = editor->FindCoincidentFreeBorders( SpinBoxTolerance->GetValue() );
-  if ( !haveBorders() )
-    return;
-
-  for ( size_t i = 0; i < myBorderDisplayers.size(); ++i )
+  if ( haveBorders() )
   {
-    delete myBorderDisplayers[ i ];
-    myBorderDisplayers[ i ] = 0;
-  }
-  myBorderDisplayers.resize( myBorders->coincidentGroups.length(), 0 );
+    for ( size_t i = 0; i < myBorderDisplayers.size(); ++i )
+    {
+      delete myBorderDisplayers[ i ];
+      myBorderDisplayers[ i ] = 0;
+    }
+    myBorderDisplayers.resize( myBorders->coincidentGroups.length(), 0 );
 
-  for ( CORBA::ULong i = 0; i < myBorders->coincidentGroups.length(); ++i )
-  {
-    QString groupText = getGroupText( i );
-    if ( groupText.isEmpty() )
-      continue;
-
-    QColor groupColor;
-    groupColor.setHsvF( float(i) / myBorders->coincidentGroups.length(), 1., 1. );
-    QPixmap icon( QSize( 20, 20 ));
-    icon.fill( groupColor );
-
-    QListWidgetItem * item = new QListWidgetItem( icon, groupText, ListCoincident );
-    item->setData( GROUP_COLOR, groupColor );
-    item->setData( GROUP_INDEX, i );
+    for ( CORBA::ULong i = 0; i < myBorders->coincidentGroups.length(); ++i )
+    {
+      QString groupText = getGroupText( i );
+      if ( groupText.isEmpty() )
+        continue;
+
+      QColor groupColor;
+      groupColor.setHsvF( float(i) / myBorders->coincidentGroups.length(), 1., 1. );
+      QPixmap icon( QSize( 20, 20 ));
+      icon.fill( groupColor );
+
+      QListWidgetItem * item = new QListWidgetItem( icon, groupText, ListCoincident );
+      item->setData( GROUP_COLOR, groupColor );
+      item->setData( GROUP_INDEX, i );
+    }
   }
   myBusy = false;
 
@@ -1389,7 +1391,11 @@ bool SMESHGUI_SewingDlg::ClickOnApply()
         QString msg = tr(QString("ERROR_%1").arg(anError).toLatin1().data());
         SUIT_MessageBox::warning(this, tr("SMESH_WRN_WARNING"), msg);
       }
-    } catch (...) {
+    }
+    catch ( const SALOME::SALOME_Exception& S_ex )
+    {
+      SalomeApp_Tools::QtCatchCorbaException( S_ex );
+      return false;
     }
 
     if (aResult) {
@@ -1887,7 +1893,6 @@ SMESHGUI_SewingDlg::BorderGroupDisplayer::~BorderGroupDisplayer()
     }
   }
   myIdPreview.SetPointsLabeled(false);
-  //myViewWindow->Repaint();
 }
 
 void SMESHGUI_SewingDlg::BorderGroupDisplayer::Hide()
@@ -2010,7 +2015,6 @@ void SMESHGUI_SewingDlg::BorderGroupDisplayer::Update()
       myPartActors[ i ]->SetMarkerStd( VTK::MT_POINT, 13 );
       myPartActors[ i ]->SetPickable ( false );
       myViewWindow->AddActor( myPartActors[ i ]);
-      //myViewWindow->Repaint();
     }
   }
 }
index 939178f739fac9b744261c3a1941f9344bdb74d5..6d180f8c26b19c0ebe081c317f07cd3d42e22fe0 100644 (file)
@@ -54,12 +54,13 @@ namespace
 
     BNode(const SMDS_MeshNode * node): SMESH_TNodeXYZ( node ) {}
     const SMDS_MeshNode * Node() const { return _node; }
-    void AddLinked( BEdge* e ) const;
-    void AddClose ( const BEdge* e, double u ) const;
+    void   AddLinked( BEdge* e ) const;
+    void   AddClose ( const BEdge* e, double u ) const;
     BEdge* GetCloseEdge( size_t i ) const { return myCloseEdges[i].first; }
     double GetCloseU( size_t i ) const { return myCloseEdges[i].second; }
     BEdge* GetCloseEdgeOfBorder( int borderID, double * u = 0 ) const;
-    bool IsCloseEdge( const BEdge* ) const;
+    bool   HasCloseEdgeWithNode( const BNode* n ) const;
+    bool   IsCloseEdge( const BEdge*, double * u = 0 ) const;
     bool operator<(const BNode& other) const { return Node()->GetID() < other.Node()->GetID(); }
   };
   /*!
@@ -149,8 +150,8 @@ namespace
       // is1st shows which end of toE is projected on this at u
       double u2;
       const double eps = 0.1;
-      if ( toE == myBNode1->GetCloseEdgeOfBorder( toE->myBorderID, &u2 ) ||
-           toE == myBNode2->GetCloseEdgeOfBorder( toE->myBorderID, &u2 ))
+      if ( myBNode1->IsCloseEdge( toE, &u2 ) ||
+           myBNode2->IsCloseEdge( toE, &u2 ))
         return (( 0 < u2 && u2 < 1 ) &&     // u2 is proj param of myBNode's on toE
                 ( Abs( u2 - int( !is1st )) > eps ));
 
@@ -164,24 +165,59 @@ namespace
       if ( this->myCloseBorders != bordIDs )
         return false;
 
-      eRange[0] = this;
-      while ( eRange[0]->myPrev && eRange[0]->myPrev->myCloseBorders == bordIDs )
+      if ( bordIDs.size() == 1 && bordIDs.count( myBorderID )) // border close to self
       {
-        if ( eRange[0]->myPrev == this /*|| eRange[0]->myPrev->myInGroup*/ )
-          break;
-        eRange[0] = eRange[0]->myPrev;
-      }
-
-      eRange[1] = this;
-      if ( eRange[0]->myPrev != this ) // not closed range
-        while ( eRange[1]->myNext && eRange[1]->myNext->myCloseBorders == bordIDs )
+        double u;
+        eRange[0] = this;
+        while ( eRange[0]->myBNode1->GetCloseEdgeOfBorder( myBorderID, &u ))
+        {
+          if ( eRange[0]->myPrev == this || u < 0 || u > 1 )
+            break;
+          eRange[0] = eRange[0]->myPrev;
+        }
+        eRange[1] = this;
+        while ( eRange[1]->myBNode2->GetCloseEdgeOfBorder( myBorderID, &u ))
         {
-          if ( eRange[1]->myNext == this /*|| eRange[1]->myNext->myInGroup*/ )
+          if ( eRange[1]->myNext == this || u < 0 || u > 1 )
             break;
           eRange[1] = eRange[1]->myNext;
         }
+      }
+      else
+      {
+        eRange[0] = this;
+        while ( eRange[0]->myPrev && eRange[0]->myPrev->myCloseBorders == bordIDs )
+        {
+          if ( eRange[0]->myPrev == this )
+            break;
+          eRange[0] = eRange[0]->myPrev;
+        }
 
-      return ( eRange[0] != eRange[1] );
+        eRange[1] = this;
+        if ( eRange[0]->myPrev != this ) // not closed border
+          while ( eRange[1]->myNext && eRange[1]->myNext->myCloseBorders == bordIDs )
+          {
+            if ( eRange[1]->myNext == this )
+              break;
+            eRange[1] = eRange[1]->myNext;
+          }
+      }
+
+      if ( eRange[0] == eRange[1] )
+      {
+        std::set<int>::iterator closeBord = eRange[0]->myCloseBorders.begin();
+        for ( ; closeBord != eRange[0]->myCloseBorders.end(); ++closeBord )
+        {
+          if ( BEdge* be = eRange[0]->myBNode1->GetCloseEdgeOfBorder( *closeBord ))
+            if ( be->myCloseBorders == eRange[0]->myCloseBorders )
+              return true;
+          if ( BEdge* be = eRange[0]->myBNode2->GetCloseEdgeOfBorder( *closeBord ))
+            if ( be->myCloseBorders == eRange[0]->myCloseBorders )
+              return true;
+        }
+        return false;
+      }
+      return true;
     }
   }; // class BEdge
 
@@ -197,8 +233,7 @@ namespace
     if ( e1->myPrev )
     {
       for ( bord = bordIDs.begin(); bord != bordIDs.end(); ++bord )
-        if ((  *bord != e1->myBorderID ) &&
-            (( be = e1->myBNode1->GetCloseEdgeOfBorder( *bord, &u ))) &&
+        if ((( be = e1->myBNode1->GetCloseEdgeOfBorder( *bord, &u ))) &&
             (  be->myInGroup == groupID ) &&
             (  0 < u && u < 1 ) &&
             (  be->IsOverlappingProjection( e1->myPrev, u, false )))
@@ -206,12 +241,17 @@ namespace
           e1 = e1->myPrev;
           break;
         }
+      if ( bord == bordIDs.end() && // not extended
+           e1->myBNode1->HasCloseEdgeWithNode( e1->myPrev->myBNode1 ))
+      {
+        e1 = e1->myPrev;
+      }
+      e1->myInGroup = groupID;
     }
     if ( e2->myNext )
     {
       for ( bord = bordIDs.begin(); bord != bordIDs.end(); ++bord )
-        if ((  *bord != e2->myBorderID ) &&
-            (( be = e2->myBNode2->GetCloseEdgeOfBorder( *bord, &u ))) &&
+        if ((( be = e2->myBNode2->GetCloseEdgeOfBorder( *bord, &u ))) &&
             (  be->myInGroup == groupID ) &&
             (  0 < u && u < 1 ) &&
             (  be->IsOverlappingProjection( e2->myNext, u, true )))
@@ -219,6 +259,12 @@ namespace
           e2 = e2->myNext;
           break;
         }
+      if ( bord == bordIDs.end() && // not extended
+           e2->myBNode2->HasCloseEdgeWithNode( e2->myNext->myBNode2 ))
+      {
+        e2 = e2->myNext;
+      }
+      e2->myInGroup = groupID;
     }
   }
 
@@ -261,11 +307,22 @@ namespace
     if ( uPtr ) *uPtr = u;
     return e;
   }
-  bool BNode::IsCloseEdge( const BEdge* e ) const
+  bool BNode::HasCloseEdgeWithNode( const BNode* n ) const
+  {
+    for ( size_t i = 0; i < myCloseEdges.size(); ++i )
+      if ( GetCloseEdge( i )->Contains( n ) &&
+           0 < GetCloseU( i ) && GetCloseU( i ) < 1 )
+        return true;
+    return false;
+  }
+  bool BNode::IsCloseEdge( const BEdge* e, double * uPtr ) const
   {
     for ( size_t i = 0; i < myCloseEdges.size(); ++i )
       if ( e == GetCloseEdge( i ) )
+      {
+        if ( uPtr ) *uPtr = GetCloseU( i );
         return true;
+      }
     return false;
   }
 
@@ -315,6 +372,7 @@ void SMESH_MeshAlgos::FindCoincidentFreeBorders(SMDS_Mesh&              mesh,
   // find free links
   typedef NCollection_DataMap<SMESH_TLink, const SMDS_MeshElement*, TLinkHasher > TLink2FaceMap;
   TLink2FaceMap linkMap;
+  int nbSharedLinks = 0;
   SMDS_FaceIteratorPtr faceIt = mesh.facesIterator();
   while ( faceIt->more() )
   {
@@ -327,27 +385,36 @@ void SMESH_MeshAlgos::FindCoincidentFreeBorders(SMDS_Mesh&              mesh,
     {
       const SMDS_MeshNode* n1 = nodeIt->next();
       SMESH_TLink link( n0, n1 );
-      if ( !linkMap.Bind( link, face ))
-        linkMap.UnBind( link );
+      if ( const SMDS_MeshElement** faceInMap = linkMap.ChangeSeek( link ))
+      {
+        nbSharedLinks += bool( *faceInMap );
+        *faceInMap = 0;
+      }
+      else
+      {
+        linkMap.Bind( link, face );
+      }
       n0 = n1;
     }
   }
-  if ( linkMap.IsEmpty() )
+  if ( linkMap.Extent() == nbSharedLinks )
     return;
 
   // form free borders
   std::set   < BNode > bNodes;
-  std::vector< BEdge > bEdges( linkMap.Extent() );
+  std::vector< BEdge > bEdges( linkMap.Extent() - nbSharedLinks );
 
   TLink2FaceMap::Iterator linkIt( linkMap );
-  for ( int iEdge = 0; linkIt.More(); linkIt.Next(), ++iEdge )
+  for ( int iEdge = 0; linkIt.More(); linkIt.Next() )
   {
+    if ( !linkIt.Value() ) continue;
     const SMESH_TLink & link = linkIt.Key();
     std::set< BNode >::iterator n1 = bNodes.insert( BNode( link.node1() )).first;
     std::set< BNode >::iterator n2 = bNodes.insert( BNode( link.node2() )).first;
     bEdges[ iEdge ].Set( &*n1, &*n2, linkIt.Value(), iEdge+1 );
     n1->AddLinked( & bEdges[ iEdge ] );
     n2->AddLinked( & bEdges[ iEdge ] );
+    ++iEdge;
   }
   linkMap.Clear();
 
@@ -563,36 +630,44 @@ void SMESH_MeshAlgos::FindCoincidentFreeBorders(SMDS_Mesh&              mesh,
     }
     beRange[1]->myInGroup = groupID;
 
+    // get starting edge of each close border
+    closeEdges.clear();
+    be = beRange[0];
+    if ( be->myCloseBorders.empty() )
+      be = beRange[0]->myNext;
+    std::set<int>::iterator closeBord = be->myCloseBorders.begin();
+    for ( ; closeBord != be->myCloseBorders.end(); ++closeBord )
+      if ( BEdge* e = be->myBNode2->GetCloseEdgeOfBorder( *closeBord ))
+        closeEdges.push_back( e );
+
+    for ( size_t iE = 0; iE < closeEdges.size(); ++iE )
+      if ( be->myCloseBorders != closeEdges[iE]->myCloseBorders )
+      {
+        closeBord = closeEdges[iE]->myCloseBorders.begin();
+        for ( ; closeBord != closeEdges[iE]->myCloseBorders.end(); ++closeBord )
+          if ( !be->myCloseBorders.count( *closeBord ))
+            if ( BEdge* e = closeEdges[iE]->myBNode2->GetCloseEdgeOfBorder( *closeBord ))
+              if ( std::find( closeEdges.begin(), closeEdges.end(), e ) == closeEdges.end() )
+                closeEdges.push_back( e );
+      }
+
     // add parts of other borders
 
     BEdge* be1st = beRange[0];
-    closeEdges.clear();
-    std::set<int>::iterator closeBord = be1st->myCloseBorders.begin();
-    for ( ; closeBord != be1st->myCloseBorders.end(); ++closeBord )
-      closeEdges.push_back( be1st->myBNode2->GetCloseEdgeOfBorder( *closeBord ));
-
     for ( size_t iE = 0; iE < closeEdges.size(); ++iE )
     {
       be = closeEdges[ iE ];
       if ( !be ) continue;
 
       bool ok = be->GetRangeOfSameCloseBorders( beRange, be->myCloseBorders );
-      if ( !ok && be->myPrev )
-        ok = be->myPrev->GetRangeOfSameCloseBorders( beRange, be1st->myCloseBorders );
-      if ( !ok && be->myNext )
-        ok = be->myNext->GetRangeOfSameCloseBorders( beRange, be1st->myCloseBorders );
+      // if ( !ok && be->myPrev )
+      //   ok = be->myPrev->GetRangeOfSameCloseBorders( beRange, be1st->myCloseBorders );
+      // if ( !ok && be->myNext )
+      //   ok = be->myNext->GetRangeOfSameCloseBorders( beRange, be1st->myCloseBorders );
       if ( !ok )
         continue;
 
       be = beRange[0];
-      if ( be->myCloseBorders != be1st->myCloseBorders )
-      {
-        //add missing edges to closeEdges
-        closeBord = be->myCloseBorders.begin();
-        for ( ; closeBord != be->myCloseBorders.end(); ++closeBord )
-          if ( !be1st->myCloseBorders.count( *closeBord ))
-            closeEdges.push_back( be->myBNode2->GetCloseEdgeOfBorder( *closeBord ));
-      }
 
       ranges.push_back( beRange[0] );
       ranges.push_back( beRange[1] );
@@ -645,9 +720,11 @@ void SMESH_MeshAlgos::FindCoincidentFreeBorders(SMDS_Mesh&              mesh,
           part._node2    = beRange[0]->myID + 1;
           part._nodeLast = beRange[1]->myID + 1;
         }
+        // if ( group[0]._node2 != part._node2 )
         group.push_back( part );
       }
-      foundFreeBordes._coincidentGroups.push_back( group );
+      //if ( group.size() > 1 )
+        foundFreeBordes._coincidentGroups.push_back( group );
     }
     else
     {
index 1a9dd65bb6a5d6ea1c601ab841369e520ef1f5a3..a5171703b8f692055813d3ef2a70c29d2d364510 100644 (file)
@@ -1541,10 +1541,8 @@ SMESH_MeshAlgos::FindFaceInSet(const SMDS_MeshNode*    n1,
   const SMDS_MeshElement* face = 0;
 
   SMDS_ElemIteratorPtr invElemIt = n1->GetInverseElementIterator(SMDSAbs_Face);
-  //MESSAGE("n1->GetInverseElementIterator(SMDSAbs_Face) " << invElemIt);
   while ( invElemIt->more() && !face ) // loop on inverse faces of n1
   {
-    //MESSAGE("in while ( invElemIt->more() && !face )");
     const SMDS_MeshElement* elem = invElemIt->next();
     if (avoidSet.count( elem ))
       continue;
@@ -1563,9 +1561,6 @@ SMESH_MeshAlgos::FindFaceInSet(const SMDS_MeshNode*    n1,
     if ( !face && elem->IsQuadratic())
     {
       // analysis for quadratic elements using all nodes
-      // const SMDS_VtkFace* F = dynamic_cast<const SMDS_VtkFace*>(elem);
-      // if (!F) throw SALOME_Exception(LOCALIZED("not an SMDS_VtkFace"));
-      // use special nodes iterator
       SMDS_ElemIteratorPtr anIter = elem->interlacedNodesElemIterator();
       const SMDS_MeshNode* prevN = static_cast<const SMDS_MeshNode*>( anIter->next() );
       for ( i1 = -1, i2 = 0; anIter->more() && !face; i1++, i2++ )
index 6edbf2b85f4749bc80ddd8b501ff52319c9659fa..7c9dca548a82d1b0f12bd63bec0590e07ca3ecf1 100644 (file)
@@ -1115,9 +1115,9 @@ bool _QuadFaceGrid::LoadGrid( SMESH_Mesh& mesh )
 
   // store the rest nodes row by row
 
-  const SMDS_MeshNode* dummy = mesh.GetMeshDS()->AddNode(0,0,0);
-  const SMDS_MeshElement* firstQuad = dummy; // most left face above the last row of found nodes
-  
+  TIDSortedElemSet emptySet, avoidSet;
+  const SMDS_MeshElement* firstQuad = 0; // most left face above the last row of found nodes
+
   int nbFoundNodes = myIndexer._xSize;
   while ( nbFoundNodes != myGrid.size() )
   {
@@ -1134,8 +1134,6 @@ bool _QuadFaceGrid::LoadGrid( SMESH_Mesh& mesh )
     //     o---o  o  o  o  o
     //n1down    n2down
     //
-    TIDSortedElemSet emptySet, avoidSet;
-    avoidSet.insert( firstQuad );
     firstQuad = SMESH_MeshAlgos::FindFaceInSet( n1down, n2down, emptySet, avoidSet);
     while ( firstQuad && !faceSubMesh->Contains( firstQuad )) {
       avoidSet.insert( firstQuad );
@@ -1182,8 +1180,8 @@ bool _QuadFaceGrid::LoadGrid( SMESH_Mesh& mesh )
       n1down = myGrid[ nbFoundNodes - myIndexer._xSize - 1 ];
       n1up   = n2up;
     }
+    avoidSet.clear(); avoidSet.insert( firstQuad );
   }
-  mesh.GetMeshDS()->RemoveNode(dummy);
   DumpGrid(); // debug
 
   return true;