From 3a401076892f2f372c58a07199e36486a6c5c9af Mon Sep 17 00:00:00 2001 From: vsr Date: Thu, 10 Jun 2010 09:43:07 +0000 Subject: [PATCH] Merge from V5_1_main 10/06/2010 --- doc/salome/gui/SMESH/images/colors_size.png | Bin 21537 -> 28249 bytes doc/salome/gui/SMESH/images/image94.gif | Bin 5678 -> 0 bytes doc/salome/gui/SMESH/images/pattern2d.png | Bin 0 -> 578 bytes .../gui/SMESH/input/2d_meshing_hypo.doc | 26 -- doc/salome/gui/SMESH/input/about_hypo.doc | 2 + .../SMESH/input/adding_nodes_and_elements.doc | 23 +- .../SMESH/input/adding_quadratic_elements.doc | 24 +- .../gui/SMESH/input/additional_hypo.doc | 28 +- .../gui/SMESH/input/constructing_meshes.doc | 54 ++- .../gui/SMESH/input/creating_groups.doc | 6 +- doc/salome/gui/SMESH/input/editing_groups.doc | 1 + .../gui/SMESH/input/find_element_by_point.doc | 4 +- doc/salome/gui/SMESH/input/index.doc | 3 +- .../gui/SMESH/input/merging_elements.doc | 15 +- doc/salome/gui/SMESH/input/merging_nodes.doc | 15 +- .../gui/SMESH/input/modifying_meshes.doc | 2 +- .../gui/SMESH/input/pattern_mapping.doc | 210 ++++++---- doc/salome/gui/SMESH/input/point_marker.doc | 6 +- doc/salome/gui/SMESH/input/scale.doc | 14 +- doc/salome/gui/SMESH/input/split_to_tetra.doc | 6 +- .../SMESH/input/tui_defining_hypotheses.doc | 3 +- .../gui/SMESH/input/tui_modifying_meshes.doc | 110 +++++- .../SMESH/input/tui_transforming_meshes.doc | 8 +- .../SMESH/input/viewing_meshes_overview.doc | 6 +- resources/Makefile.am | 4 + resources/SalomeApp.xml | 2 +- resources/mesh_tree_algo_0D.png | Bin 0 -> 253 bytes resources/mesh_tree_algo_existing_2D.png | Bin 0 -> 270 bytes resources/mesh_tree_algo_prism.png | Bin 0 -> 314 bytes .../mesh_tree_algo_radial_quadrangle_1D2D.png | Bin 0 -> 338 bytes src/SMESH/SMESH_MeshEditor.cxx | 2 +- src/SMESH/SMESH_MesherHelper.cxx | 58 ++- src/SMESH/SMESH_MesherHelper.hxx | 1 + src/SMESH/SMESH_Pattern.cxx | 6 + src/SMESHGUI/SMESHGUI.cxx | 22 +- src/SMESHGUI/SMESHGUI.h | 2 + src/SMESHGUI/SMESHGUI_AddMeshElementDlg.cxx | 3 + .../SMESHGUI_AddQuadraticElementDlg.cxx | 3 + src/SMESHGUI/SMESHGUI_BuildCompoundDlg.cxx | 2 + src/SMESHGUI/SMESHGUI_ConvToQuadOp.cxx | 2 + .../SMESHGUI_CreatePolyhedralVolumeDlg.cxx | 2 + src/SMESHGUI/SMESHGUI_DeleteGroupDlg.cxx | 1 + src/SMESHGUI/SMESHGUI_EditMeshDlg.cxx | 1 + .../SMESHGUI_ExtrusionAlongPathDlg.cxx | 3 + src/SMESHGUI/SMESHGUI_ExtrusionDlg.cxx | 3 + src/SMESHGUI/SMESHGUI_FilterDlg.cxx | 41 +- src/SMESHGUI/SMESHGUI_GroupDlg.cxx | 2 + src/SMESHGUI/SMESHGUI_GroupOnShapeDlg.cxx | 3 + src/SMESHGUI/SMESHGUI_GroupOpDlg.cxx | 4 + src/SMESHGUI/SMESHGUI_Hypotheses.cxx | 1 + src/SMESHGUI/SMESHGUI_HypothesesUtils.cxx | 1 + src/SMESHGUI/SMESHGUI_Make2DFrom3DOp.cxx | 1 + src/SMESHGUI/SMESHGUI_MakeNodeAtPointDlg.cxx | 1 + src/SMESHGUI/SMESHGUI_MeshOp.cxx | 3 + src/SMESHGUI/SMESHGUI_MeshOrderOp.cxx | 3 + src/SMESHGUI/SMESHGUI_MeshPatternDlg.cxx | 1 + src/SMESHGUI/SMESHGUI_MoveNodesDlg.cxx | 1 + src/SMESHGUI/SMESHGUI_MultiEditDlg.cxx | 1 + src/SMESHGUI/SMESHGUI_NodesDlg.cxx | 4 + .../SMESHGUI_Preferences_ColorDlg.cxx | 52 +++ src/SMESHGUI/SMESHGUI_Preferences_ColorDlg.h | 4 + src/SMESHGUI/SMESHGUI_RemoveElementsDlg.cxx | 89 ++--- src/SMESHGUI/SMESHGUI_RemoveElementsDlg.h | 1 + src/SMESHGUI/SMESHGUI_RemoveNodesDlg.cxx | 92 ++--- src/SMESHGUI/SMESHGUI_RemoveNodesDlg.h | 1 + src/SMESHGUI/SMESHGUI_RenumberingDlg.cxx | 1 + src/SMESHGUI/SMESHGUI_RevolutionDlg.cxx | 3 + src/SMESHGUI/SMESHGUI_RotationDlg.cxx | 3 + src/SMESHGUI/SMESHGUI_ScaleDlg.cxx | 3 + src/SMESHGUI/SMESHGUI_SewingDlg.cxx | 2 + src/SMESHGUI/SMESHGUI_SingleEditDlg.cxx | 1 + src/SMESHGUI/SMESHGUI_SmoothingDlg.cxx | 3 + src/SMESHGUI/SMESHGUI_SymmetryDlg.cxx | 3 + src/SMESHGUI/SMESHGUI_TranslationDlg.cxx | 3 + src/SMESHGUI/SMESHGUI_WhatIsDlg.cxx | 1 + src/SMESH_SWIG/ex06_hole1boolean.py | 2 +- src/SMESH_SWIG/ex07_hole1partition.py | 2 +- src/SMESH_SWIG/ex11_grid3partition.py | 2 +- src/SMESH_SWIG/ex13_hole1partial.py | 2 +- .../StdMeshers_CompositeHexa_3D.cxx | 11 +- src/StdMeshers/StdMeshers_FaceSide.cxx | 30 +- src/StdMeshers/StdMeshers_HexaFromSkin_3D.cxx | 358 ++++++++++++------ src/StdMeshers/StdMeshers_Quadrangle_2D.cxx | 3 + .../StdMeshersGUI_DistrPreview.cxx | 11 + src/StdMeshersGUI/StdMeshers_images.ts | 18 +- 85 files changed, 989 insertions(+), 462 deletions(-) delete mode 100755 doc/salome/gui/SMESH/images/image94.gif create mode 100644 doc/salome/gui/SMESH/images/pattern2d.png create mode 100644 resources/mesh_tree_algo_0D.png create mode 100644 resources/mesh_tree_algo_existing_2D.png create mode 100644 resources/mesh_tree_algo_prism.png create mode 100644 resources/mesh_tree_algo_radial_quadrangle_1D2D.png diff --git a/doc/salome/gui/SMESH/images/colors_size.png b/doc/salome/gui/SMESH/images/colors_size.png index 58210c0bc7456dbd7555b34dfc34fd6376e70a34..53b14620cb6e6fe19d7f8b27ca50cc2a9dd3d66c 100755 GIT binary patch literal 28249 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 literal 21537 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 V;Q5Jg`IPWUrBmSLzX3;5FI@lt diff --git a/doc/salome/gui/SMESH/images/image94.gif b/doc/salome/gui/SMESH/images/image94.gif deleted file mode 100755 index 7313f5deb3336d5476d340d3b3c36047754adfbc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5678 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\ref max_element_area_anchor "Max Element Area"
  • \ref length_from_edges_anchor "Length from Edges"
  • \ref hypo_quad_params_anchor "Quadrangle parameters"
  • -
  • \ref quadrangle_preference_anchor "Quadrangle Preference"
  • -
  • \ref triangle_preference_anchor "Triangle Preference"

  • @@ -69,29 +67,5 @@ shows the good (left) and the bad (right) results of meshing. See Also a sample TUI Script of a \ref tui_quadrangle_parameters "Quadrangle Parameters" hypothesis. -\anchor quadrangle_preference_anchor -

    Quadrangle Preference

    - -This algorithm can be used together with Quadrangle (Mapping) and Netgen 2D -algorithms. - -It allows Netgen 2D to build quadrangular meshes at any conditions. - -It allows Quadrangle (Mapping) to build quadrangular meshes even if the number -of nodes at the opposite edges of a meshed face is not equal, -otherwise this mesh will contain some triangular elements. -
    -This hypothesis has one restriction on its work: the total quantity of -segments on all four sides of the face must be even (divisible by 2). - - -
    -\anchor triangle_preference_anchor -

    Triangle Preference

    - -This algorithm can be used only together with Quadrangle (Mapping) -algorithm. It allows to build triangular mesh faces in the refinement -area if the number of nodes at the opposite edges of a meshed face is not equal, -otherwise refinement area will contain some quadrangular elements.
    */ diff --git a/doc/salome/gui/SMESH/input/about_hypo.doc b/doc/salome/gui/SMESH/input/about_hypo.doc index 9d9db7b32..0e8ac1007 100644 --- a/doc/salome/gui/SMESH/input/about_hypo.doc +++ b/doc/salome/gui/SMESH/input/about_hypo.doc @@ -55,6 +55,8 @@ with other hypotheses:
  • Propagation of 1D Hypothesis on opposite edges
  • Non conform mesh allowed
  • Quadratic mesh
  • +
  • Quadrangle preference
  • +
  • Triangle preference
  • The choice of a hypothesis depends on: diff --git a/doc/salome/gui/SMESH/input/adding_nodes_and_elements.doc b/doc/salome/gui/SMESH/input/adding_nodes_and_elements.doc index 451823b74..5c99e8e79 100644 --- a/doc/salome/gui/SMESH/input/adding_nodes_and_elements.doc +++ b/doc/salome/gui/SMESH/input/adding_nodes_and_elements.doc @@ -26,10 +26,25 @@ following associated submenu will appear: \image html image146.png From this submenu select the type of element which you would like to add to your mesh. -\note All dialogs intended for adding nodes or elements to mesh (except dialog for adding -0D elements) provide a possibility to add these nodes/elements to the specified group -(or to create the group if it doesn't exist). Add to group box allows to choose -an existing group for created node or element or to specify a name for new group. + +\note All dialogs for adding new node or element to the mesh (except for +the dialog for 0D elements) provide a possibility to add it +automatically to the specified group or to create it anew using +Add to group box, that allows to choose an existing group for +the created node or element or to give the name to a new group. By +default, the Add to group check box is switched off. If user +swiches this check box on, the combo box listing all currently +existing groups of the corresponding type becomes available. By +default, no any group is selected. In such a case, when user presses +Apply or Apply & Close button, the warning message box +informing the user about the necessity to input new group name is +shown. The combo box lists both \ref standalone_group "standalone groups" +and \ref group_on_geom "groups on geometry". If the user has +chosen the group on geometry, he is warned and proposed to +\ref convert_to_standalone "convert this group to the standalone". +If user refuses converting operation, an operation is cancelled and +new node/element is not created! + See Also sample TUI Scripts of diff --git a/doc/salome/gui/SMESH/input/adding_quadratic_elements.doc b/doc/salome/gui/SMESH/input/adding_quadratic_elements.doc index 2a587d147..83736c85d 100644 --- a/doc/salome/gui/SMESH/input/adding_quadratic_elements.doc +++ b/doc/salome/gui/SMESH/input/adding_quadratic_elements.doc @@ -2,7 +2,7 @@ \page adding_quadratic_elements_page Adding Quadratic Elements -\n MESH modules allows you to work with Quadratic Elements. +\n MESH module allows you to work with Quadratic Elements. Quadratic Edge is not a straight but a broken line and can be defined by three points: first, middle and last. All more complex \b Quadratic @@ -18,10 +18,24 @@ one of the following: \image html image152.png -\note All dialogs intended for adding quadratic elements to mesh provide a possibility -to add these elements to the specified group (or to create the group if it doesn't exist). -Add to group box allows to choose an existing group for created element or -to specify a name for new group. +\note All dialogs for adding quadratic element to the mesh +provide a possibility to add new element +automatically to the specified group or to create it anew using +Add to group box, that allows to choose an existing group for +the created node or element or to give the name to a new group. By +default, the Add to group check box is switched off. If user +swiches this check box on, the combo box listing all currently +existing groups of the corresponding type becomes available. By +default, no any group is selected. In such a case, when user presses +Apply or Apply & Close button, the warning message box +informing the user about the necessity to input new group name is +shown. The combo box lists both \ref standalone_group "standalone groups" +and \ref group_on_geom "groups on geometry". If the user has +chosen the group on geometry, he is warned and proposed to +\ref convert_to_standalone "convert this group to the standalone". +If user refuses converting operation, an operation is cancelled and +new node/element is not created! + To create any Quadratic Element specify the nodes which will form your triangle by selecting them in the 3D viewer with pressed Shift diff --git a/doc/salome/gui/SMESH/input/additional_hypo.doc b/doc/salome/gui/SMESH/input/additional_hypo.doc index 9687bdf2d..1205e19b0 100644 --- a/doc/salome/gui/SMESH/input/additional_hypo.doc +++ b/doc/salome/gui/SMESH/input/additional_hypo.doc @@ -28,8 +28,30 @@ hypothesis onto an opposite edge. If a local hypothesis and propagation are defined on an edge of a quadrangular face, the opposite edge will have the same hypothesis, unless another hypothesis has been locally defined on the opposite edge. - +
    See Also a sample TUI Script of a -\ref tui_propagation "Propagation hypothesis" operation. +\ref tui_propagation "Propagation hypothesis" operation + +

    Quadrangle Preference

    + +This additional hypothesis can be used together with Quadrangle (Mapping) and Netgen 2D +algorithms. + +It allows Netgen 2D to build quadrangular meshes at any conditions. + +It allows Quadrangle (Mapping) to build quadrangular meshes even if the number +of nodes at the opposite edges of a meshed face is not equal, +otherwise this mesh will contain some triangular elements. +
    +This hypothesis has one restriction on its work: the total quantity of +segments on all four sides of the face must be even (divisible by 2). + +

    Triangle Preference

    + +This additional hypothesis can be used only together with Quadrangle (Mapping) +algorithm. It allows to build triangular mesh faces in the refinement +area if the number of nodes at the opposite edges of a meshed face is not equal, +otherwise refinement area will contain some quadrangular elements. + -*/ \ No newline at end of file +*/ diff --git a/doc/salome/gui/SMESH/input/constructing_meshes.doc b/doc/salome/gui/SMESH/input/constructing_meshes.doc index 042b66320..ace081140 100644 --- a/doc/salome/gui/SMESH/input/constructing_meshes.doc +++ b/doc/salome/gui/SMESH/input/constructing_meshes.doc @@ -154,21 +154,20 @@ evaluation will be displayed in the following information box: - \anchor mesh_order_anchor -It is allowed to change submesh priority in mesh computation when -there are concurrent submeshes present. I.e. user can change priority of -applying algorithms on shared subshapes of Mesh shape. + +
  • +If the mesh contains concurrent submeshes, it is possible to change +the priority of their computation, i.e. to change the priority of +applying algorithms to the shared subshapes of the Mesh shape.
  • + To change submesh priority: -
      -
    1. From the Mesh menu choose the "Change submesh priority" on -selected Mesh item, or invoke from popup menu. The opened dialogue box -shows a list of submeshes in the order of their priority. Algorithm and its -hypotheses of a submesh being upper in the list are applied before those of -a submesh lower in the list. -There is an example of submesh order modifications of Mesh created on a Box +
    2. Choose "Change submesh priority" from the Mesh menu or a popup menu. The opened dialogue +shows a list of submeshes in the order of their priority. + +There is an example of submesh order modifications of the Mesh created on a Box shape. The main Mesh object:
      • 3D Tetrahedron (Netgen) with HypothesisMax Element Volume
      • @@ -189,51 +188,50 @@ is: (Number of Segments = 8)
      -And the last third submesh object Submesh_3 created on Face_3 +And the last submesh object Submesh_3 created on Face_3 is:
      • 2D Netgen 1D-2D with Hypothesis Netgen Simple parameters (Number of Segments = 12)
      -The submeshes can become concurrent if their algorithms leads to mesh shared subshape -with different algorithms (or different algorithms parameters, i.e. hypothesises). -In fact, we have three submeshes with concurrent algorithms, because -they have different hypothesises assigned to them. +The submeshes become concurrent if they share subshapes that can be meshed +with different algorithms (or different hypothesises). +In the example, we have three submeshes with concurrent algorithms, +because they have different hypotheses. -The first mesh computation made with: +The first mesh computation is made with: \image html mesh_order_123.png
      "Mesh order SubMesh_1, SubMesh_2, SubMesh_3"
      \image html mesh_order_123_res.png
      "Result mesh with order SubMesh_1, SubMesh_2, SubMesh_3 "
      -The next mesh computation with: +The next mesh computation is made with: \image html mesh_order_213.png
      "Mesh order SubMesh_2, SubMesh_1, SubMesh_3"
      \image html mesh_order_213_res.png
      "Result mesh with order SubMesh_2, SubMesh_1, SubMesh_3 "
      -And the last mesh computation with: +And the last mesh computation is made with: \image html mesh_order_321.png
      "Mesh order SubMesh_3, SubMesh_2, SubMesh_1"
      \image html mesh_order_321_res.png
      "Result mesh with order SubMesh_3, SubMesh_2, SubMesh_1 "
      -As we can see each mesh computation has different number of result -elements and different mesh discretisation on shared edges (edges +As we can see, each mesh computation has a different number of result +elements and a different mesh discretisation on the shared edges (the edges that are shared between Face_1, Face_2 and Face_3) -Additionally, submesh priority (order of algorithms to be applied) can -be modified not only in separate dialog box, but in Preview -also. This helps to preview different mesh results, modifying submesh -order. +Additionally, submesh priority (the order of applied algorithms) can +be modified not only in a separate dialog box, but also in the +Preview. This helps to preview different mesh results, +modifying the order of submeshes. \image html mesh_order_preview.png
      "Preview with submesh priority list box"
      -If there are no concurrent submeshes under Mesh object, then user will see the -following information dialog box +If there are no concurrent submeshes under the Mesh object, the user will see the +following information. \image html mesh_order_no_concurrent.png
      "No concurrent submeshes detected"
      -and no mesh order list box will appear in Preview dialog box.
    diff --git a/doc/salome/gui/SMESH/input/creating_groups.doc b/doc/salome/gui/SMESH/input/creating_groups.doc index 4d74a3aa0..29b17f1ae 100644 --- a/doc/salome/gui/SMESH/input/creating_groups.doc +++ b/doc/salome/gui/SMESH/input/creating_groups.doc @@ -23,7 +23,7 @@ elements which will form your group: SALOME Platform distinguishes between the two Group types: Standalone Group and Group on Geometry. -

    Standalone Group

    +\anchor standalone_group

    "Standalone Group"

    Standalone Group consists of mesh elements, which you can define in two possible ways. @@ -79,7 +79,7 @@ be changed, the new one will not be modified. \ref tui_create_standalone_group "Create a Standalone Group" operation. -

    Group on Geometry

    +\anchor group_on_geom

    "Group on Geometry"

    To create a group on geometry check Group on geometry in the \b Group \b type field. Group on geometry contains the elements of a certain type @@ -98,4 +98,4 @@ selected in green. \ref tui_create_group_on_geometry "Create a Group on Geometry" operation. -*/ \ No newline at end of file +*/ diff --git a/doc/salome/gui/SMESH/input/editing_groups.doc b/doc/salome/gui/SMESH/input/editing_groups.doc index 6cbe5ceb4..d255c3f82 100644 --- a/doc/salome/gui/SMESH/input/editing_groups.doc +++ b/doc/salome/gui/SMESH/input/editing_groups.doc @@ -22,6 +22,7 @@ remove the elements forming it. For more information see group. +\anchor convert_to_standalone To convert an existing group on geometry into standalone group of elements and modify:
      diff --git a/doc/salome/gui/SMESH/input/find_element_by_point.doc b/doc/salome/gui/SMESH/input/find_element_by_point.doc index 34380aed4..fcdadea29 100644 --- a/doc/salome/gui/SMESH/input/find_element_by_point.doc +++ b/doc/salome/gui/SMESH/input/find_element_by_point.doc @@ -24,8 +24,8 @@ The following dialog box will appear:
      • the coordinates of the point;
      • the type of elements to be found; it is also possible to find elements -of all types related to the reference point. To be exact, type "All" -means to find elements of any type except nodes and 0D elements.
      • +of all types related to the reference point. Choose type "All" to find +elements of any type except for nodes and 0D elements.
      diff --git a/doc/salome/gui/SMESH/input/index.doc b/doc/salome/gui/SMESH/input/index.doc index 2de722d16..7e18d2b68 100644 --- a/doc/salome/gui/SMESH/input/index.doc +++ b/doc/salome/gui/SMESH/input/index.doc @@ -16,7 +16,8 @@ the VTK viewer; allowing to highlight important elements:
    1. \subpage modifying_meshes_page "modifying meshes" with a vast array of dedicated operations.
    2. -
    3. \subpage using_notebook_mesh_page.
    4. +
    5. easily setting parameters via the variables predefined in +\subpage using_notebook_mesh_page "Salome notebook".
    6. Almost all mesh module functionalities are accessible via diff --git a/doc/salome/gui/SMESH/input/merging_elements.doc b/doc/salome/gui/SMESH/input/merging_elements.doc index d677e179e..50513d58f 100644 --- a/doc/salome/gui/SMESH/input/merging_elements.doc +++ b/doc/salome/gui/SMESH/input/merging_elements.doc @@ -8,32 +8,31 @@ selectable in the dialog box. \image html mergeelems_ico.png "Merge elements button"
        -
      1. From the \b Modification choose \b Transformation and from its -sub-menu select the Merge elements item. The following dialog box +
      2. Choose in the main menu \b Modification -> \b Transformation -> Merge elements item. The following dialog box shall appear:
      3. \image html mergeelems_auto.png
        • \b Name is the name of the mesh whose elements will be merged.
        • -
        • \b Automatic Mode or \b Manual Mode is to switch the dialog -controls type. +
        • \b Automatic or \b Manual Mode allows choosing how the elements +are processed.
      4. Automatic mode:
          -
        • In \b Automatic Mode the elements that were created on the same nodes will be merged.
        • +
        • In the \b Automatic Mode the elements created on the same nodes will be merged.
      5. -
      6. If the \b Manual Mode is selected there are additional controls to -manage the elements to be merged in more detail: +
      7. If the \b Manual Mode is selected, additional controls are +available: \image html mergeelems.png
        • \b Detect button generates the list of coincident elements for the given \b Tolerance.
        • -
        • Coincident elements is a list of groupes of elements for +
        • Coincident elements is a list of groups of elements for merging. All elements of each group will form one after the operation.
          • \b Remove button deletes the selected group from the list.
          • diff --git a/doc/salome/gui/SMESH/input/merging_nodes.doc b/doc/salome/gui/SMESH/input/merging_nodes.doc index d94d6f49d..eb17e0a14 100644 --- a/doc/salome/gui/SMESH/input/merging_nodes.doc +++ b/doc/salome/gui/SMESH/input/merging_nodes.doc @@ -17,25 +17,24 @@ shall appear:
            • \b Name is the name of the mesh whose nodes will be merged.
            • -
            • \b Automatic Mode or \b Manual Mode is to switch the dialog -controls type. +
            • \b Automatic or \b Manual Mode allows choosing how the nodes are +processed.
            • \b Tolerance is a maximum distance between nodes sufficient for -merging, that is able in both dialog modes.
            • +merging.
          • Automatic mode:
              -
            • In \b Automatic Mode to merge the Nodes, just input the tolerance -value and confirm by \b Apply button.
            • +
            • In the \b Automatic Mode all Nodes within the indicated tolerance +will be merged.

          • -
          • If the \b Manual Mode is selected there are additional controls to -manage the nodes to be merged in more detail: +
          • If the \b Manual Mode is selected, additional controls are available:
            • \b Detect button generates the list of coincident nodes for the given \b Tolerance.
            • -
            • Coincident nodes is a list of groupes of nodes for +
            • Coincident nodes is a list of groups of nodes for merging. All nodes of each group will form one after the operation.
                diff --git a/doc/salome/gui/SMESH/input/modifying_meshes.doc b/doc/salome/gui/SMESH/input/modifying_meshes.doc index afa553f1b..05180eb4b 100644 --- a/doc/salome/gui/SMESH/input/modifying_meshes.doc +++ b/doc/salome/gui/SMESH/input/modifying_meshes.doc @@ -23,7 +23,7 @@ the mesh or some of its elements. through a point or a vector of symmetry.
              • Unite meshes by \subpage sewing_meshes_page "sewing" free borders, conform free borders, border to side or side elements.
              • -
              • \subpage merging_nodes_page "Merge Notes", considered coincident +
              • \subpage merging_nodes_page "Merge Nodes", considered coincident within the indicated tolerance.
              • \subpage merging_elements_page "Merge Elements", considered coincident within the indicated tolerance.
              • diff --git a/doc/salome/gui/SMESH/input/pattern_mapping.doc b/doc/salome/gui/SMESH/input/pattern_mapping.doc index db4be4144..1a48a4644 100644 --- a/doc/salome/gui/SMESH/input/pattern_mapping.doc +++ b/doc/salome/gui/SMESH/input/pattern_mapping.doc @@ -11,30 +11,83 @@ located at geometrical vertices. Pattern description is stored in \.smp file. The smp file contains 4 sections: -
                  -
                1. The first line holds the number of nodes (N).
                2. -
                3. The next N lines describe nodes coordinates. Each line holds 2 -coordinates of a node.
                4. - -
                5. A key-points line: indices of nodes to be mapped on geometrical -vertices. An index n refers to a node described on an n-th line of -section 2. The first node index is zero.
                6. - -
                7. The rest lines describe nodal connectivity of elements, one line +-# The first line holds the total number of the pattern nodes (N). +-# The next N lines describe nodes coordinates. Each line holds 2 +coordinates of a node for 2D pattern or 3 cordinates for 3D pattern. +Note, that for 3D pattern only relateive values in range [0;1] are +valid for coordinates of the nodes. +-# A key-points line: indices of nodes to be mapped on geometrical +vertices (for 2D pattern only). An index n refers to a node described +on an n-th line of section 2. The first node index is zero. For 3D +pattern key points are not specified. +-# The rest lines describe nodal connectivity of elements, one line for an element. A line holds indices of nodes forming an element. An index n refers to a node described on an n-th line of the section 2. The first node index is zero. There must be 3 or 4 indices on a -line: only 2d elements are allowed.
                8. -
                +line for 2D pattern (only 2d elements are allowed) and 4, 5, 6 or 8 +indices for 3D pattern (only 3d elements are allowed). The 2D pattern must contain at least one element and at least one key-point. All key-points must lay on boundaries. -An example of a simple smp file and a preview of a pattern described -in this file: - -\image html image94.gif +The 3D pattern must contain at least one element. + +An example of a simple 2D pattern smp file: + +\code +!!! SALOME 2D mesh pattern file +!!! +!!! Nb of points: +9 + 200 0 !- 0 + 100 0 !- 1 + 0 0 !- 2 + 0 -100 !- 3 + 0 -200 !- 4 + 100 -200 !- 5 + 200 -200 !- 6 + 200 -100 !- 7 + 100 -100 !- 8 +!!! Indices of 4 key-points + 2 0 4 6 +!!! Indices of points of 6 elements + 0 1 8 + 8 5 6 7 + 2 3 8 + 8 3 4 5 + 8 7 0 + 8 1 2 +\endcode + +The image below provides a preview of above described pattern: + +\image html pattern2d.png + +An example of a simple 3D pattern smp file: + +\code +!!! SALOME 3D mesh pattern file +!!! +!!! Nb of points: +9 + 0 0 0 !- 0 + 1 0 0 !- 1 + 0 1 0 !- 2 + 1 1 0 !- 3 + 0 0 1 !- 4 + 1 0 1 !- 5 + 0 1 1 !- 6 + 1 1 1 !- 7 + 0.5 0.5 0.5 !- 8 +!!! Indices of points of 6 elements: + 0 1 5 4 8 + 7 5 1 3 8 + 3 2 6 7 8 + 2 0 4 6 8 + 0 2 3 1 8 + 4 5 7 6 8 +\endcode

                Application of pattern mapping

                @@ -50,86 +103,89 @@ The following dialog box shall appear: \image html patternmapping1.png +
                2D Pattern Mapping dialog box
                + \image html patternmapping2.png +
                3D Pattern Mapping dialog box
                + To apply a pattern to a geometrical object, you should specify: -
                  -
                • a face having the number of vertices equal to the number of -key-points in the pattern; the number of key-points on internal -boundaries of a pattern must also be equal to the number of vertices -on internal boundaries of a face;
                • -
                • a vertex to which the first key-point should be mapped;
                • -
                • reverse or not the order of key-points. (The order of vertices of -a face is counterclockwise looking from outside).
                • -
                + +-# For 2D pattern + - A face having the number of vertices equal to the number of + key-points in the pattern; the number of key-points on internal + boundaries of a pattern must also be equal to the number of vertices + on internal boundaries of a face; + - A vertex to which the first key-point should be mapped; + - Reverse or not the order of key-points. (The order of vertices of + a face is counterclockwise looking from outside). +-# For 3D pattern + - 3D block (Solid) object; + - Two vertices that specify the order of nodes in the resulting + mesh. Then you either load a .smp pattern file previously created manually by clicking on the "Load pattern" button, or click on the \b -New button for automatic generation. -\n For an automatic generation you just specify a geometrical face -having a mesh built on it. Mesh nodes lying on face vertices become -key-points. Additionally, you may choose the way of getting nodes -coordinates by projecting nodes on the face instead of using +New button for automatic generation of the pattern. + +For an automatic generation you just specify a geometrical face (for +2D) or solid (for 3d) having a mesh built on it. Mesh nodes lying on +face vertices become key-points of 2D pattern. Additionally, for 2D +pattern you may choose the way of getting nodes coordinates by +projecting nodes on the face instead of using "positions on face" generated by mesher (if there is any). Faces having a seam edge can't be used for automatic pattern creation. When creating a pattern from an existing mesh, there are two possible cases: -
                  -
                1. A sub-mesh on face is selected. A pattern is created from the 2d -elements bound to a face by mesher. Node coordinates are either + +- A sub-mesh on face/solid is selected. A pattern is created from the 2d/3d +elements bound to a face/solid by mesher. For 2D pattern, node coordinates are either "positions on face" computed by mesher, or coordinates got by node -projection on a geometrical surface, according to your choice.
                2. -
                3. A mesh where the main shape is a face, is selected. A pattern is -created from all the 2d elements in a mesh. If all mesh elements are -build by mesher, the user can select the way of getting nodes -coordinates, else all nodes are projected on a face surface.
                4. -
                +projection on a geometrical surface, according to the user choice. For +3D pattern, nodes coordinates correspond to the nodes computed by mesher. +- A mesh where the main shape is a face/solid, is selected. A pattern is +created from all the 2d/3d elements in a mesh. In addition, for 2D +pattern, if all mesh elements are build by mesher, the user can select +the way of getting nodes coordinates, else all nodes are projected on +a face surface. \image html a-patterntype.png +
                2D Pattern Creation dialog box
                + \image html a-patterntype1.png +
                3D Pattern Creation dialog box
                +

                Mapping algorithm

                -The mapping algorithm is as follows: -
                  -
                1. Key-points are set in the order that they are encountered when -walking along a pattern boundary so that elements are on the left. The -first key-point is preserved. -
                2. - -
                3. Find geometrical vertices corresponding to key-points by vertices -order in a face boundary; here, "Reverse order of key-points" flag is -taken into account. - -\image html image95.gif -
                4. - -
                5. Boundary nodes of a pattern are mapped onto edges of a face: a -node located between certain key-points on a pattern boundary is -mapped on a geometrical edge limited by corresponding geometrical -vertices. Node position on an edge reflects its distance from two -key-points. - -\image html image96.gif -
                6. - -
                7. Coordinates of a non-boundary node in a parametric space of a face -are defined as following. In a parametric space of a pattern, a node -lays at the intersection of two iso-lines, each of which intersects a -pattern boundary at least at two points. Knowing mapped positions of -boundary nodes, we find where isoline-boundary intersection points are -mapped to, and hence we can find mapped isolines direction and then, -two node positions on two mapped isolines. The eventual mapped -position of a node is found as an average of positions on mapped -isolines. - -\image html image97.gif -
                8. -
                - -
                See Also a sample TUI Script of a +The mapping algorithm for 2D case is as follows: + +- Key-points are set in the order that they are encountered when + walking along a pattern boundary so that elements are on the left. The + first key-point is preserved. +- Find geometrical vertices corresponding to key-points by vertices + order in a face boundary; here, "Reverse order of key-points" flag is + taken into account. \image html image95.gif +- Boundary nodes of a pattern are mapped onto edges of a face: a + node located between certain key-points on a pattern boundary is + mapped on a geometrical edge limited by corresponding geometrical + vertices. Node position on an edge reflects its distance from two + key-points. \image html image96.gif +- Coordinates of a non-boundary node in a parametric space of a face + are defined as following. In a parametric space of a pattern, a node + lays at the intersection of two iso-lines, each of which intersects a + pattern boundary at least at two points. Knowing mapped positions of + boundary nodes, we find where isoline-boundary intersection points are + mapped to, and hence we can find mapped isolines direction and then, + two node positions on two mapped isolines. The eventual mapped + position of a node is found as an average of positions on mapped + isolines. \image html image97.gif + +For 3D case the algorithm is similar. + +See Also a sample TUI Script of a \ref tui_pattern_mapping "Pattern Mapping" operation. */ diff --git a/doc/salome/gui/SMESH/input/point_marker.doc b/doc/salome/gui/SMESH/input/point_marker.doc index c298893ef..40c2b932b 100644 --- a/doc/salome/gui/SMESH/input/point_marker.doc +++ b/doc/salome/gui/SMESH/input/point_marker.doc @@ -9,7 +9,7 @@ shapes or by loading a custom texture from an external file. - Standard point markers The Mesh module provides a set of predefined point marker shapes -which can be used to display points in 3D viewer. +which can be used to display points in the 3D viewer. Each standard point marker has two attributes: type (defines shape form) and scale factor (defines shape size). @@ -23,9 +23,9 @@ form) and scale factor (defines shape size). It is also possible to load a point marker shape from an external file. This file should provide a description of the point texture as a set -of lines; each line is represented as sequence of "0" and "1" symbols, +of lines; each line is represented as a sequence of "0" and "1" symbols, where "1" symbol means an opaque pixel and "0" symbol means a -transparent pixel. The width of the texture correspond to the length +transparent pixel. The width of the texture corresponds to the length of the longest line in the file, expanded to the nearest byte-aligned value. The height of the texture is equal to the number of non-empty lines in the file. Note that missing symbols are replaced by "0". diff --git a/doc/salome/gui/SMESH/input/scale.doc b/doc/salome/gui/SMESH/input/scale.doc index 5b10fb5a5..b833903b6 100644 --- a/doc/salome/gui/SMESH/input/scale.doc +++ b/doc/salome/gui/SMESH/input/scale.doc @@ -69,17 +69,17 @@ name in the adjacent box); Example of using: -1. Create quandrangle mesh 3x3 on simple planar face (200x200) +1. Create quandrangle mesh 3x3 on a simple planar face (200x200) \image html scaleinit01.png -and union 3 face (along axis Z) to group "gr_faces" +and union 3 faces (along axis Z) to group "gr_faces" \image html scaleinit02.png -2. Perform scale operation for whole mesh with creation of new mesh: +2. Perform scale operation for the whole mesh and create a new mesh: \image html scale03.png @@ -89,7 +89,7 @@ result after operation: -3. Perform scale operation for whole mesh with copy of elements: +3. Perform scale operation for the whole mesh and copy elements: \image html scale04.png @@ -99,7 +99,7 @@ result after operation: -4. Perform scale operation for group of faces with copy of elements: +4. Perform scale operation for a group of faces and copy elements: \image html scale06.png @@ -109,7 +109,7 @@ result after operation: -5. Perform scale operation for two edges with moving of elements: +5. Perform scale operation for two edges and move elements: \image html scale07.png @@ -119,7 +119,7 @@ result after operation: -6. Perform scale operation for one face with moving of elements: +6. Perform scale operation for one face and move elements: \image html scale09.png diff --git a/doc/salome/gui/SMESH/input/split_to_tetra.doc b/doc/salome/gui/SMESH/input/split_to_tetra.doc index 57efb37eb..4817a3f2f 100644 --- a/doc/salome/gui/SMESH/input/split_to_tetra.doc +++ b/doc/salome/gui/SMESH/input/split_to_tetra.doc @@ -23,7 +23,7 @@ The following dialog box will appear:
              • The main list contains the list of volumes. You can click on a volume in the 3D viewer and it will be highlighted (lock Shift keyboard button to select several volumes). Click \b Add button and -the ID of this volume will be added to the list. To remove a +the ID of this volume will be added to the list. To remove the selected element or elements from the list click \b Remove button. Sort list button allows to sort the list of IDs. \b Filter button allows to apply a definite filter to the selection of volumes. @@ -40,12 +40,12 @@ volumes of the currently displayed mesh or submesh.
              • Into 5 tetrahedra and Into 6 tetrahedra allows to specify the number of tetrahedra a hexahedron will be split into. If the specified method does not allow to get a conform mesh, a generic solution is applied: an additional node -is created at gravity center of a hexahedron, serving an apex of tetrahedra, all quadrangle sides of the hexahedron are split into two triangles each serving a base of a new tetrahedron.
              • +is created at the gravity center of a hexahedron, serving an apex of tetrahedra, all quadrangle sides of the hexahedron are split into two triangles each serving a base of a new tetrahedron.
            • -
            • Select from set of fields allows to choose a submesh or an +
            • Select from a set of fields allows to choose a submesh or an existing group whose elements will be automatically added to the list.
            diff --git a/doc/salome/gui/SMESH/input/tui_defining_hypotheses.doc b/doc/salome/gui/SMESH/input/tui_defining_hypotheses.doc index 80944666e..1aa91d9d5 100644 --- a/doc/salome/gui/SMESH/input/tui_defining_hypotheses.doc +++ b/doc/salome/gui/SMESH/input/tui_defining_hypotheses.doc @@ -536,7 +536,8 @@ radial_Quad_algo = mesh.Quadrangle(algo=RADIAL_QUAD) # In this case it uses "Default Nb of Segments" preferences parameter to discretize edges mesh.Compute() -# The Radial Quadrange uses global or local 1d hypotheses if no its own hypotheses assigned. +# The Radial Quadrange uses global or local 1d hypotheses if it does +# not have its own hypotheses. # Define global hypotheses to discretize radial edges and a local one for circular edge global_Nb_Segments = mesh.Segment().NumberOfSegments(5) local_Nb_Segments = mesh.Segment(circle).NumberOfSegments(10) diff --git a/doc/salome/gui/SMESH/input/tui_modifying_meshes.doc b/doc/salome/gui/SMESH/input/tui_modifying_meshes.doc index 66b6361fa..2e8f75291 100644 --- a/doc/salome/gui/SMESH/input/tui_modifying_meshes.doc +++ b/doc/salome/gui/SMESH/input/tui_modifying_meshes.doc @@ -22,6 +22,26 @@ if new_id == 0: print "KO node addition." else: print "New Node has been added with ID ", new_id \endcode +
            +\anchor tui_add_0DElement +

            Add 0D Element

            + +\code +import SMESH_mechanic + +mesh = SMESH_mechanic.mesh + +# add node +node_id = mesh.AddNode(50, 10, 0) + +# add 0D Element +new_id = mesh.Add0DElement(node_id) + +print "" +if new_id == 0: print "KO node addition." +else: print "New 0D Element has been added with ID ", new_id +\endcode +
            \anchor tui_add_edge

            Add Edge

            @@ -768,7 +788,6 @@ mesh.RotationSweepObject(GroupRotate, axisXYZ, angle45, 4, 1e-5) \code import geompy - import smesh # define the geometry @@ -802,17 +821,100 @@ algo2D.MaxElementArea(240) isDone = Mesh_2.Compute() if not isDone: print 'Mesh Mesh_2 : computation failed' -# create a pattern +# create a 2d pattern pattern = smesh.GetPattern() isDone = pattern.LoadFromFace(Mesh_2.GetMesh(), Face_2, 0) if (isDone != 1): print 'LoadFromFace :', pattern.GetErrorCode() # apply the pattern to a face of the first mesh -pattern.ApplyToMeshFaces(Mesh_1.GetMesh(), [17], 0, 0) - +facesToSplit = Mesh_1.GetElementsByType(smesh.SMESH.FACE) +print "Splitting %d rectangular face(s) to %d triangles..."%(len(facesToSplit), 2*len(facesToSplit)) +pattern.ApplyToMeshFaces(Mesh_1.GetMesh(), facesToSplit, 0, 0) isDone = pattern.MakeMesh(Mesh_1.GetMesh(), 0, 0) if (isDone != 1): print 'MakeMesh :', pattern.GetErrorCode() + +# create quadrangle mesh +Mesh_3 = smesh.Mesh(Box_1) +Mesh_3.Segment().NumberOfSegments(1) +Mesh_3.Quadrangle() +Mesh_3.Hexahedron() +isDone = Mesh_3.Compute() +if not isDone: print 'Mesh Mesh_3 : computation failed' + +# create a 3d pattern (hexahedrons) +pattern_hexa = smesh.GetPattern() + +smp_hexa = """!!! Nb of points: +15 + 0 0 0 !- 0 + 1 0 0 !- 1 + 0 1 0 !- 2 + 1 1 0 !- 3 + 0 0 1 !- 4 + 1 0 1 !- 5 + 0 1 1 !- 6 + 1 1 1 !- 7 + 0.5 0 0.5 !- 8 + 0.5 0 1 !- 9 + 0.5 0.5 0.5 !- 10 + 0.5 0.5 1 !- 11 + 1 0 0.5 !- 12 + 1 0.5 0.5 !- 13 + 1 0.5 1 !- 14 + !!! Indices of points of 4 elements: + 8 12 5 9 10 13 14 11 + 0 8 9 4 2 10 11 6 + 2 10 11 6 3 13 14 7 + 0 1 12 8 2 3 13 10""" + +pattern_hexa.LoadFromFile(smp_hexa) + +# apply the pattern to a mesh +volsToSplit = Mesh_3.GetElementsByType(smesh.SMESH.VOLUME) +print "Splitting %d hexa volume(s) to %d hexas..."%(len(volsToSplit), 4*len(volsToSplit)) +pattern_hexa.ApplyToHexahedrons(Mesh_3.GetMesh(), volsToSplit,0,3) +isDone = pattern_hexa.MakeMesh(Mesh_3.GetMesh(), True, True) +if (isDone != 1): print 'MakeMesh :', pattern_hexa.GetErrorCode() + +# create one more quadrangle mesh +Mesh_4 = smesh.Mesh(Box_1) +Mesh_4.Segment().NumberOfSegments(1) +Mesh_4.Quadrangle() +Mesh_4.Hexahedron() +isDone = Mesh_4.Compute() +if not isDone: print 'Mesh Mesh_4 : computation failed' + +# create another 3d pattern (pyramids) +pattern_pyra = smesh.GetPattern() + +smp_pyra = """!!! Nb of points: +9 + 0 0 0 !- 0 + 1 0 0 !- 1 + 0 1 0 !- 2 + 1 1 0 !- 3 + 0 0 1 !- 4 + 1 0 1 !- 5 + 0 1 1 !- 6 + 1 1 1 !- 7 + 0.5 0.5 0.5 !- 8 + !!! Indices of points of 6 elements: + 0 1 5 4 8 + 7 5 1 3 8 + 3 2 6 7 8 + 2 0 4 6 8 + 0 2 3 1 8 + 4 5 7 6 8""" + +pattern_pyra.LoadFromFile(smp_pyra) + +# apply the pattern to a face mesh +volsToSplit = Mesh_4.GetElementsByType(smesh.SMESH.VOLUME) +print "Splitting %d hexa volume(s) to %d hexas..."%(len(volsToSplit), 6*len(volsToSplit)) +pattern_pyra.ApplyToHexahedrons(Mesh_4.GetMesh(), volsToSplit,1,0) +isDone = pattern_pyra.MakeMesh(Mesh_4.GetMesh(), True, True) +if (isDone != 1): print 'MakeMesh :', pattern_pyra.GetErrorCode() \endcode
            diff --git a/doc/salome/gui/SMESH/input/tui_transforming_meshes.doc b/doc/salome/gui/SMESH/input/tui_transforming_meshes.doc index 1658e58c5..c55b2a492 100644 --- a/doc/salome/gui/SMESH/input/tui_transforming_meshes.doc +++ b/doc/salome/gui/SMESH/input/tui_transforming_meshes.doc @@ -62,16 +62,16 @@ Nb_Segments_1.SetDistrType( 0 ) Quadrangle_2D = Mesh1.Quadrangle() isDone = Mesh1.Compute() -#Perform scale opration for whole mesh with creation of new mesh +#Perform scale opration for the whole mesh and creation of a new mesh newMesh = Mesh1.ScaleMakeMesh(Mesh1,SMESH.PointStruct(100,100,200),[0.5,0.3,0.7],True,"ScaledMesh") -#Perform scale operation for whole mesh with copy of elements +#Perform scale operation for the whole mesh and copy elements Mesh1.Scale(Mesh1,SMESH.PointStruct(200,100,100),[0.5,0.5,0.5],True,True) -#Perform scale opration for two edges with moving of elements +#Perform scale opration for two edges and move elements Mesh1.Scale([1,2],SMESH.PointStruct(-100,100,100),[0.8,1.0,0.7],False) -#Perform scale opration for one face with moving of elements +#Perform scale opration for one face and move elements Mesh1.Scale([21],SMESH.PointStruct(0,200,200),[0.7,0.7,0.7],False) \endcode diff --git a/doc/salome/gui/SMESH/input/viewing_meshes_overview.doc b/doc/salome/gui/SMESH/input/viewing_meshes_overview.doc index 207c4dda5..17f4c5f7f 100644 --- a/doc/salome/gui/SMESH/input/viewing_meshes_overview.doc +++ b/doc/salome/gui/SMESH/input/viewing_meshes_overview.doc @@ -37,9 +37,9 @@ Faces, Edges or both.
          • 2D Quadratic - allows to select between the representation of quadratic edges as broken lines or as arcs
          • Orientation of faces - shows vectors of orientation of -faces of the selected mesh. Vector is shown for each 2D mesh element -and for each free face of 3D mesh element. Vector direction is calculated by -the first three nodes of face as a cross product of vectors n1-n2 and n1-n3.
          • +faces of the selected mesh. The orientation vector is shown for each 2D mesh element +and for each free face of a 3D mesh element. the vector direction is calculated by +the first three nodes of the face produced by vectors n1-n2 and n1-n3.
          • \subpage colors_size_page "Colors / Size" - allows to select color and size of meshes.
          • \subpage transparency_page "Transparency" - allows to change the diff --git a/resources/Makefile.am b/resources/Makefile.am index ca671b982..97f2c3b6f 100644 --- a/resources/Makefile.am +++ b/resources/Makefile.am @@ -80,6 +80,7 @@ dist_salomeres_DATA = \ mesh_tree_algo_hexa.png \ mesh_tree_algo_mefisto.png \ mesh_tree_algo.png \ + mesh_tree_algo_0D.png \ mesh_tree_algo_quad.png \ mesh_tree_algo_regular.png \ mesh_tree_algo_tetra.png \ @@ -149,6 +150,9 @@ dist_salomeres_DATA = \ mesh_conv_to_quad.png \ mesh_tree_hypo_layers_distribution.png \ mesh_tree_algo_radial_prism.png \ + mesh_tree_algo_radial_quadrangle_1D2D.png \ + mesh_tree_algo_existing_2D.png \ + mesh_tree_algo_prism.png \ mesh_tree_algo_projection_2d.png \ mesh_hypo_source_edge.png \ mesh_hypo_source_3d.png \ diff --git a/resources/SalomeApp.xml b/resources/SalomeApp.xml index 173cbd077..e4ddfa738 100644 --- a/resources/SalomeApp.xml +++ b/resources/SalomeApp.xml @@ -99,7 +99,7 @@ - + diff --git a/resources/mesh_tree_algo_0D.png b/resources/mesh_tree_algo_0D.png new file mode 100644 index 0000000000000000000000000000000000000000..5725a17d485ee586acef350023ea2d54a0113153 GIT binary patch literal 253 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`oCO|{#S9G6>p_??PHLhIP>?0v z(btiIVPjv-@4(4GzCyA`kS_y6l_~>6Lo)-z&;LOBB?CjL0RzLU1O^7H84L{K`IF+0 zx&hS|d%8G=RNPAX^Z&m+vnqo^!wd-x76wL_jf@z?ktXk^i4z6oY!A#xI*r3*c5g%i31sKUcy2S41qEo7@83VvN3FF=acrCH}5addInEdKbLh*2~7YV Cia-hg literal 0 HcmV?d00001 diff --git a/resources/mesh_tree_algo_existing_2D.png b/resources/mesh_tree_algo_existing_2D.png new file mode 100644 index 0000000000000000000000000000000000000000..db0de789a571c9d3d418eb314af6fe47f5496634 GIT binary patch literal 270 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`oCO|{#S9G6>p_??PHLhIP>?0v z(btiIVPjv-@4(4GzCyA`kS_y6l_~>6Lo)-z&;LOBB?CjL0RzLU1O^7H84L{K`IF+0 zx&hU;c)B=-RNPAX^Z&m+vnqo^!wd-x76wL_jf_Cz0)v~I+nzcW4h1!*S&a>X^A$ld z;tWh3ofFA|^bwaeX)!=!B02(F^0YUp0!2FJOetg) tu@h%x5l~)Q$*9nv;l~cM0b~su!`h7ovQv*Xeh0dT!PC{xWt~$(699Q=NKya* literal 0 HcmV?d00001 diff --git a/resources/mesh_tree_algo_prism.png b/resources/mesh_tree_algo_prism.png new file mode 100644 index 0000000000000000000000000000000000000000..0025d48b8a5b0eba2e9b330763a49266d916e718 GIT binary patch literal 314 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`oCO|{#S9G6>p_??PHLhIP>?0v z(btiIVPjv-@4(4GzCyA`kS_y6l_~>6Lo)-z&;LOBB?CjL0RzLU1O^7H84L{K`IF+0 zx&hU0@N{tuskoK&=l_3uW>p4-hKK@B10$m(Q^^cPWg~eIKa*!x9gp+pT|U}8h7Al! zif+n!XB8L(9DGj9+0YukQH!P1GDQDi7J~yrVg+N$iB%Q3i`}=EL5dteHQZG~s%D&rfkqi7o%VUr_TUl^69eNB jkIXz44uvkDsRtOsPZ%EF@}g!5(CrMKu6{1-oD!M<5%5|a literal 0 HcmV?d00001 diff --git a/resources/mesh_tree_algo_radial_quadrangle_1D2D.png b/resources/mesh_tree_algo_radial_quadrangle_1D2D.png new file mode 100644 index 0000000000000000000000000000000000000000..234ed3055b0f5a70e2bf695c933a375c6c4301ac GIT binary patch literal 338 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`oCO|{#S9G6>p_??PHLhIP>?0v z(btiIVPjv-@4(4GzCyA`kS_y6l_~>6Lo)-z&;LOBB?CjL0RzLU1O^7H84L{K`IF+0 zx&hUm@N{tuskoK&=l_3uW>p4-h6o21Wo6|qO$TSmPE!y+f#-f-Z-HY9Gp8h*fP>Es z7RR=OJS>uJ@0?N?1RQi)=5*u;m|bUJ5fIkvovr;Ra1U!zaxtd^gP~$JL!#3%Pge=q=rAAT}6yMExvgjhzP?jL{nk{9phx>?Y`pd`WlqOp^YfvJOYc2Y#c zqe~q!GZ+|;w48REk(Q#Lzzk$NtqCqeIlGw8X@knMHyjCMClC U(r51GetPosition(); - if(Pos->GetTypeOfPosition()==SMDS_TOP_EDGE) { - const SMDS_EdgePosition* epos = - static_cast(n->GetPosition().get()); + const SMDS_PositionPtr pos = n->GetPosition(); + if ( pos->GetTypeOfPosition()==SMDS_TOP_EDGE ) + { + const SMDS_EdgePosition* epos = static_cast( pos.get() ); param = epos->GetUParameter(); } - else if(Pos->GetTypeOfPosition()==SMDS_TOP_VERTEX) { - SMESHDS_Mesh * meshDS = GetMeshDS(); - int vertexID = n->GetPosition()->GetShapeId(); - const TopoDS_Vertex& V = TopoDS::Vertex(meshDS->IndexToShape(vertexID)); - param = BRep_Tool::Parameter( V, E ); + else if( pos->GetTypeOfPosition() == SMDS_TOP_VERTEX ) + { + if ( inEdgeNode && TopExp::FirstVertex( E ).IsSame( TopExp::LastVertex( E ))) // issue 0020128 + { + Standard_Real f,l; + BRep_Tool::Range( E, f,l ); + double uInEdge = GetNodeU( E, inEdgeNode ); + param = ( fabs( uInEdge - f ) < fabs( l - uInEdge )) ? f : l; + } + else + { + SMESHDS_Mesh * meshDS = GetMeshDS(); + int vertexID = pos->GetShapeId(); + const TopoDS_Vertex& V = TopoDS::Vertex(meshDS->IndexToShape(vertexID)); + param = BRep_Tool::Parameter( V, E ); + } } if ( check ) - *check = CheckNodeU( E, n, param, BRep_Tool::Tolerance( E )); + { + double tol = BRep_Tool::Tolerance( E ); + double f,l; BRep_Tool::Range( E, f,l ); + bool force = ( param < f-tol || param > l+tol ); + if ( !force && pos->GetTypeOfPosition()==SMDS_TOP_EDGE ) + force = ( GetMeshDS()->ShapeToIndex( E ) != pos->GetShapeId() ); + + *check = CheckNodeU( E, n, param, tol, force ); + } return param; } @@ -667,6 +687,20 @@ bool SMESH_MesherHelper::CheckNodeU(const TopoDS_Edge& E, { ((SMESH_MesherHelper*) this)->myOkNodePosShapes.insert( n->GetPosition()->GetShapeId() ); } + if (( u < f-tol || u > l+tol ) && force ) + { + // node is on vertex but is set on periodic but trimmed edge (issue 0020890) + try + { + // do not use IsPeriodic() as Geom_TrimmedCurve::IsPeriodic () returns false + double period = curve->Period(); + u = ( u < f ) ? u + period : u - period; + } + catch (Standard_Failure& exc) + { + return false; + } + } } } return true; @@ -739,8 +773,8 @@ const SMDS_MeshNode* SMESH_MesherHelper::GetMediumNode(const SMDS_MeshNode* n1, E = TopoDS::Edge(myShape); edgeID = myShapeID; } - u[0] = GetNodeU(E,n1, force3d ? 0 : &uvOK[0]); - u[1] = GetNodeU(E,n2, force3d ? 0 : &uvOK[1]); + u[0] = GetNodeU(E,n1,n2, force3d ? 0 : &uvOK[0]); + u[1] = GetNodeU(E,n2,n1, force3d ? 0 : &uvOK[1]); } if(!force3d) { diff --git a/src/SMESH/SMESH_MesherHelper.hxx b/src/SMESH/SMESH_MesherHelper.hxx index f26ed4f6f..3fece8a82 100644 --- a/src/SMESH/SMESH_MesherHelper.hxx +++ b/src/SMESH/SMESH_MesherHelper.hxx @@ -269,6 +269,7 @@ public: */ double GetNodeU(const TopoDS_Edge& theEdge, const SMDS_MeshNode* theNode, + const SMDS_MeshNode* inEdgeNode=0, bool* check=0); /*! * \brief Return node UV on face diff --git a/src/SMESH/SMESH_Pattern.cxx b/src/SMESH/SMESH_Pattern.cxx index c3a9126a3..43ee8669d 100644 --- a/src/SMESH/SMESH_Pattern.cxx +++ b/src/SMESH/SMESH_Pattern.cxx @@ -73,6 +73,7 @@ #include "SMESH_MesherHelper.hxx" #include "SMESH_subMesh.hxx" +#include #include "utilities.h" using namespace std; @@ -210,6 +211,8 @@ bool SMESH_Pattern::Load (const char* theFileContents) { MESSAGE("Load( file ) "); + Kernel_Utils::Localizer loc; + // file structure: // ! This is a comment @@ -353,6 +356,9 @@ bool SMESH_Pattern::Load (const char* theFileContents) bool SMESH_Pattern::Save (ostream& theFile) { MESSAGE(" ::Save(file) " ); + + Kernel_Utils::Localizer loc; + if ( !IsLoaded() ) { MESSAGE(" Pattern not loaded "); return setErrorCode( ERR_SAVE_NOT_LOADED ); diff --git a/src/SMESHGUI/SMESHGUI.cxx b/src/SMESHGUI/SMESHGUI.cxx index fb0d75917..f777acbc4 100644 --- a/src/SMESHGUI/SMESHGUI.cxx +++ b/src/SMESHGUI/SMESHGUI.cxx @@ -1483,6 +1483,22 @@ SalomeApp_Study* SMESHGUI::activeStudy() return NULL; } +//============================================================================= +/*! + * + */ +//============================================================================= +void SMESHGUI::Modified( bool theIsUpdateActions ) +{ + if( SalomeApp_Application* app = dynamic_cast( SUIT_Session::session()->activeApplication() ) ) { + if( SalomeApp_Study* appStudy = dynamic_cast( app->activeStudy() ) ) { + appStudy->Modified(); + if( theIsUpdateActions ) + app->updateActions(); + } + } +} + //============================================================================= /*! * @@ -3845,8 +3861,8 @@ void SMESHGUI::createPreferences() // Set property for precision value for spinboxes for ( ii = 0; ii < nbQuantities; ii++ ){ - setPreferenceProperty( precs[ii], "min", -10 ); - setPreferenceProperty( precs[ii], "max", 10 ); + setPreferenceProperty( precs[ii], "min", -14 ); + setPreferenceProperty( precs[ii], "max", 14 ); setPreferenceProperty( precs[ii], "precision", 2 ); } @@ -4869,5 +4885,7 @@ int SMESHGUI::addVtkFontPref( const QString& label, const int pId, const QString */ void SMESHGUI::onHypothesisEdit( int result ) { + if( result == 1 ) + SMESHGUI::Modified(); updateObjBrowser( true ); } diff --git a/src/SMESHGUI/SMESHGUI.h b/src/SMESHGUI/SMESHGUI.h index 503740c61..0099a20bd 100644 --- a/src/SMESHGUI/SMESHGUI.h +++ b/src/SMESHGUI/SMESHGUI.h @@ -79,6 +79,8 @@ public : static bool automaticUpdate(); + static void Modified( bool = true ); + virtual LightApp_Displayer* displayer(); virtual QString engineIOR() const; virtual void initialize( CAM_Application* ); diff --git a/src/SMESHGUI/SMESHGUI_AddMeshElementDlg.cxx b/src/SMESHGUI/SMESHGUI_AddMeshElementDlg.cxx index 03ade25cb..a5d12e559 100644 --- a/src/SMESHGUI/SMESHGUI_AddMeshElementDlg.cxx +++ b/src/SMESHGUI/SMESHGUI_AddMeshElementDlg.cxx @@ -447,6 +447,7 @@ void SMESHGUI_AddMeshElementDlg::Init() connect(mySelectionMgr, SIGNAL(currentSelectionChanged()), SLOT(SelectionIntoArgument())); /* to close dialog if study frame change */ connect(mySMESHGUI, SIGNAL (SignalStudyFrameChanged()), SLOT(ClickOnCancel())); + connect(mySMESHGUI, SIGNAL (SignalCloseAllDialogs()), SLOT(ClickOnCancel())); if (Reverse) connect(Reverse, SIGNAL(stateChanged(int)), SLOT(CheckBox(int))); @@ -570,6 +571,8 @@ void SMESHGUI_AddMeshElementDlg::ClickOnApply() myEditCurrentArgument->setText(""); myBusy = false; + + SMESHGUI::Modified(); } } diff --git a/src/SMESHGUI/SMESHGUI_AddQuadraticElementDlg.cxx b/src/SMESHGUI/SMESHGUI_AddQuadraticElementDlg.cxx index 601006b70..d190c35e3 100644 --- a/src/SMESHGUI/SMESHGUI_AddQuadraticElementDlg.cxx +++ b/src/SMESHGUI/SMESHGUI_AddQuadraticElementDlg.cxx @@ -666,6 +666,7 @@ void SMESHGUI_AddQuadraticElementDlg::Init() connect(mySMESHGUI, SIGNAL (SignalDeactivateActiveDialog()), SLOT(DeactivateActiveDialog())); connect(mySMESHGUI, SIGNAL (SignalStudyFrameChanged()), SLOT(ClickOnCancel())); + connect(mySMESHGUI, SIGNAL (SignalCloseAllDialogs()), SLOT(ClickOnCancel())); // set selection mode SMESH::SetPointRepresentation(true); @@ -806,6 +807,8 @@ void SMESHGUI_AddQuadraticElementDlg::ClickOnApply() SetEditCorners(); updateButtons(); + + SMESHGUI::Modified(); } //================================================================================= diff --git a/src/SMESHGUI/SMESHGUI_BuildCompoundDlg.cxx b/src/SMESHGUI/SMESHGUI_BuildCompoundDlg.cxx index fe9e5317e..bc6c1daf5 100644 --- a/src/SMESHGUI/SMESHGUI_BuildCompoundDlg.cxx +++ b/src/SMESHGUI/SMESHGUI_BuildCompoundDlg.cxx @@ -331,6 +331,8 @@ bool SMESHGUI_BuildCompoundDlg::ClickOnApply() SMESH::DisplayActor(SMESH::GetActiveWindow(), anActor); }// end IPAL21468 + SMESHGUI::Modified(); + return true; } return false; diff --git a/src/SMESHGUI/SMESHGUI_ConvToQuadOp.cxx b/src/SMESHGUI/SMESHGUI_ConvToQuadOp.cxx index f5ed5ea15..5b8777753 100644 --- a/src/SMESHGUI/SMESHGUI_ConvToQuadOp.cxx +++ b/src/SMESHGUI/SMESHGUI_ConvToQuadOp.cxx @@ -27,6 +27,7 @@ // #include "SMESHGUI_ConvToQuadOp.h" +#include "SMESHGUI.h" #include "SMESHGUI_ConvToQuadDlg.h" #include "SMESHGUI_Utils.h" @@ -234,6 +235,7 @@ bool SMESHGUI_ConvToQuadOp::onApply() } if( aResult ) { + SMESHGUI::Modified(); update( UF_ObjBrowser | UF_Model | UF_Viewer ); selectionDone(); } diff --git a/src/SMESHGUI/SMESHGUI_CreatePolyhedralVolumeDlg.cxx b/src/SMESHGUI/SMESHGUI_CreatePolyhedralVolumeDlg.cxx index 1501f0825..864537e84 100644 --- a/src/SMESHGUI/SMESHGUI_CreatePolyhedralVolumeDlg.cxx +++ b/src/SMESHGUI/SMESHGUI_CreatePolyhedralVolumeDlg.cxx @@ -574,6 +574,8 @@ void SMESHGUI_CreatePolyhedralVolumeDlg::ClickOnApply() } //ConstructorsClicked( GetConstructorId() ); busy = false; + + SMESHGUI::Modified(); } } diff --git a/src/SMESHGUI/SMESHGUI_DeleteGroupDlg.cxx b/src/SMESHGUI/SMESHGUI_DeleteGroupDlg.cxx index 95906a3f9..63ce53b12 100644 --- a/src/SMESHGUI/SMESHGUI_DeleteGroupDlg.cxx +++ b/src/SMESHGUI/SMESHGUI_DeleteGroupDlg.cxx @@ -219,6 +219,7 @@ bool SMESHGUI_DeleteGroupDlg::onApply() myListGrp.clear(); mySelectionMgr->clearSelected(); SMESH::UpdateView(); + SMESHGUI::Modified(); mySMESHGUI->updateObjBrowser(true); myBlockSelection = false; diff --git a/src/SMESHGUI/SMESHGUI_EditMeshDlg.cxx b/src/SMESHGUI/SMESHGUI_EditMeshDlg.cxx index 5405ec451..64559a58a 100644 --- a/src/SMESHGUI/SMESHGUI_EditMeshDlg.cxx +++ b/src/SMESHGUI/SMESHGUI_EditMeshDlg.cxx @@ -672,6 +672,7 @@ bool SMESHGUI_EditMeshDlg::ClickOnApply() } SMESH::UpdateView(); + SMESHGUI::Modified(); return true; } diff --git a/src/SMESHGUI/SMESHGUI_ExtrusionAlongPathDlg.cxx b/src/SMESHGUI/SMESHGUI_ExtrusionAlongPathDlg.cxx index b2ca95017..7b9997de3 100644 --- a/src/SMESHGUI/SMESHGUI_ExtrusionAlongPathDlg.cxx +++ b/src/SMESHGUI/SMESHGUI_ExtrusionAlongPathDlg.cxx @@ -167,6 +167,7 @@ SMESHGUI_ExtrusionAlongPathDlg::SMESHGUI_ExtrusionAlongPathDlg( SMESHGUI* theMod ElementsLineEdit = new QLineEdit(GroupArguments); ElementsLineEdit->setValidator(myIdValidator); + ElementsLineEdit->setMaxLength(-1); myFilterBtn = new QPushButton( tr( "SMESH_BUT_FILTER" ), GroupArguments ); connect(myFilterBtn, SIGNAL(clicked()), this, SLOT(setFilters())); @@ -671,6 +672,8 @@ bool SMESHGUI_ExtrusionAlongPathDlg::ClickOnApply() if ( myMeshActor ) SMESH::Update( myMeshActor->getIO(), myMeshActor->GetVisibility() ); + SMESHGUI::Modified(); + if ( MakeGroupsCheck->isEnabled() && MakeGroupsCheck->isChecked() ) mySMESHGUI->updateObjBrowser(true); // new groups may appear //SMESH::UpdateView(); diff --git a/src/SMESHGUI/SMESHGUI_ExtrusionDlg.cxx b/src/SMESHGUI/SMESHGUI_ExtrusionDlg.cxx index 89ebc7f55..b402a0dfe 100644 --- a/src/SMESHGUI/SMESHGUI_ExtrusionDlg.cxx +++ b/src/SMESHGUI/SMESHGUI_ExtrusionDlg.cxx @@ -165,6 +165,7 @@ SMESHGUI_ExtrusionDlg::SMESHGUI_ExtrusionDlg (SMESHGUI* theModule) LineEditElements = new QLineEdit(GroupArguments); LineEditElements->setValidator(myIdValidator); + LineEditElements->setMaxLength(-1); myFilterBtn = new QPushButton( tr( "SMESH_BUT_FILTER" ), GroupArguments ); connect(myFilterBtn, SIGNAL(clicked()), this, SLOT(setFilters())); @@ -572,6 +573,8 @@ bool SMESHGUI_ExtrusionDlg::ClickOnApply() mySelectionMgr->clearSelected(); mySelectedObject = SMESH::SMESH_IDSource::_nil(); SelectionIntoArgument(); + + SMESHGUI::Modified(); } return true; } diff --git a/src/SMESHGUI/SMESHGUI_FilterDlg.cxx b/src/SMESHGUI/SMESHGUI_FilterDlg.cxx index 711d9a220..f9b4af034 100755 --- a/src/SMESHGUI/SMESHGUI_FilterDlg.cxx +++ b/src/SMESHGUI/SMESHGUI_FilterDlg.cxx @@ -2517,31 +2517,18 @@ void SMESHGUI_FilterDlg::setIdsToWg (QWidget* theWg, const QList& theIds) if (theWg == 0) return; + QStringList aStrList; + foreach(int id, theIds) + aStrList << QString::number(id); + if (theWg->inherits("QListWidget")) { - QListWidget* aListBox = qobject_cast( theWg ); - aListBox->clear(); - - QStringList aStrList; - QList::const_iterator anIter; - for (anIter = theIds.begin(); anIter != theIds.end(); ++anIter) - aStrList.append(QString("%1").arg(*anIter)); - - aListBox->addItems(aStrList); + qobject_cast(theWg)->clear(); + qobject_cast(theWg)->addItems(aStrList); } else if (theWg->inherits("QLineEdit")) { - QLineEdit* aLineEdit = qobject_cast( theWg ); - QString aStr; - QList::const_iterator anIter; - - for (anIter = theIds.begin(); anIter != theIds.end(); ++ anIter) - aStr += QString("%1 ").arg(*anIter); - - if (!aStr.isEmpty()) - aStr.remove(aStr.length() - 1, 1); - - aLineEdit->setText(aStr); + qobject_cast( theWg )->setText(aStrList.join(" ")); } } @@ -2987,14 +2974,12 @@ void SMESHGUI_FilterDlg::onSelectionDone() } } - int aCriterionType = myTable->GetCriterionType(aRow); - if (aList.Extent() != 1 || - !myTable->CurrentCell(aRow, aCol) || - aCriterionType != SMESH::FT_BelongToGeom && - aCriterionType != SMESH::FT_BelongToPlane && - aCriterionType != SMESH::FT_BelongToCylinder && - aCriterionType != SMESH::FT_BelongToGenSurface && - aCriterionType != SMESH::FT_LyingOnGeom) + QList types; + types << SMESH::FT_BelongToGeom << SMESH::FT_BelongToPlane + << SMESH::FT_BelongToCylinder << SMESH::FT_BelongToGenSurface + << SMESH::FT_LyingOnGeom; + if (aList.Extent() != 1 || !myTable->CurrentCell(aRow, aCol) || + !types.contains(myTable->GetCriterionType(aRow))) return; Handle(SALOME_InteractiveObject) anIO = aList.First(); diff --git a/src/SMESHGUI/SMESHGUI_GroupDlg.cxx b/src/SMESHGUI/SMESHGUI_GroupDlg.cxx index 351c4bc1f..28461ee4f 100644 --- a/src/SMESHGUI/SMESHGUI_GroupDlg.cxx +++ b/src/SMESHGUI/SMESHGUI_GroupDlg.cxx @@ -852,6 +852,7 @@ bool SMESHGUI_GroupDlg::onApply() } } + SMESHGUI::Modified(); mySMESHGUI->updateObjBrowser(true); SMESH::UpdateView(); // asv: fix of BUG PAL5515 mySelectionMgr->clearSelected(); @@ -957,6 +958,7 @@ bool SMESHGUI_GroupDlg::onApply() } } + SMESHGUI::Modified(); mySMESHGUI->updateObjBrowser(true); mySelectionMgr->clearSelected(); return true; diff --git a/src/SMESHGUI/SMESHGUI_GroupOnShapeDlg.cxx b/src/SMESHGUI/SMESHGUI_GroupOnShapeDlg.cxx index f5b003709..9fefa98da 100644 --- a/src/SMESHGUI/SMESHGUI_GroupOnShapeDlg.cxx +++ b/src/SMESHGUI/SMESHGUI_GroupOnShapeDlg.cxx @@ -27,6 +27,7 @@ #include "SMESHGUI_GroupOnShapeDlg.h" #include "SMESH_TypeFilter.hxx" +#include "SMESHGUI.h" #include "SMESHGUI_Utils.h" #include "SMESHGUI_GEOMGenUtils.h" @@ -347,6 +348,8 @@ bool SMESHGUI_GroupOnShapeOp::onApply() group = mesh->CreateGroupFromGEOM( elemType, name.toLatin1().data(), geom ); } } + SMESHGUI::Modified(); + update( UF_ObjBrowser | UF_Model ); init(); diff --git a/src/SMESHGUI/SMESHGUI_GroupOpDlg.cxx b/src/SMESHGUI/SMESHGUI_GroupOpDlg.cxx index 15d772347..39941b26a 100644 --- a/src/SMESHGUI/SMESHGUI_GroupOpDlg.cxx +++ b/src/SMESHGUI/SMESHGUI_GroupOpDlg.cxx @@ -604,6 +604,7 @@ bool SMESHGUI_UnionGroupsDlg::onApply() if ( aRes ) { + SMESHGUI::Modified(); getSMESHGUI()->updateObjBrowser(true); reset(); return true; @@ -706,6 +707,7 @@ bool SMESHGUI_IntersectGroupsDlg::onApply() if ( aRes ) { + SMESHGUI::Modified(); getSMESHGUI()->updateObjBrowser(true); reset(); return true; @@ -872,6 +874,7 @@ bool SMESHGUI_CutGroupsDlg::onApply() if ( aRes ) { + SMESHGUI::Modified(); getSMESHGUI()->updateObjBrowser(true); reset(); return true; @@ -1023,6 +1026,7 @@ bool SMESHGUI_DimGroupDlg::onApply() if ( aRes ) { + SMESHGUI::Modified(); getSMESHGUI()->updateObjBrowser(true); reset(); return true; diff --git a/src/SMESHGUI/SMESHGUI_Hypotheses.cxx b/src/SMESHGUI/SMESHGUI_Hypotheses.cxx index 6f7237c9f..b6e28773a 100644 --- a/src/SMESHGUI/SMESHGUI_Hypotheses.cxx +++ b/src/SMESHGUI/SMESHGUI_Hypotheses.cxx @@ -122,6 +122,7 @@ void SMESHGUI_GenericHypothesisCreator::editHypothesis( SMESH::SMESH_Hypothesis_ SMESHGUI_HypothesisDlg* Dlg = new SMESHGUI_HypothesisDlg( this, theParent ); connect( Dlg, SIGNAL( finished( int ) ), this, SLOT( onDialogFinished( int ) ) ); connect( this, SIGNAL( finished( int ) ), obj, slot.toLatin1().constData() ); + connect( SMESHGUI::GetSMESHGUI(), SIGNAL( SignalCloseAllDialogs() ), Dlg, SLOT( reject() )); myDlg = Dlg; QFrame* fr = buildFrame(); diff --git a/src/SMESHGUI/SMESHGUI_HypothesesUtils.cxx b/src/SMESHGUI/SMESHGUI_HypothesesUtils.cxx index e8d9204f8..005e6a873 100644 --- a/src/SMESHGUI/SMESHGUI_HypothesesUtils.cxx +++ b/src/SMESHGUI/SMESHGUI_HypothesesUtils.cxx @@ -414,6 +414,7 @@ namespace SMESH if (aHypSObject) { if (!aHypName.isEmpty()) SMESH::SetName(aHypSObject, aHypName); + SMESHGUI::Modified(); SMESHGUI::GetSMESHGUI()->updateObjBrowser(); return aHypothesis._retn(); } diff --git a/src/SMESHGUI/SMESHGUI_Make2DFrom3DOp.cxx b/src/SMESHGUI/SMESHGUI_Make2DFrom3DOp.cxx index fb404641f..ffbc3b80d 100644 --- a/src/SMESHGUI/SMESHGUI_Make2DFrom3DOp.cxx +++ b/src/SMESHGUI/SMESHGUI_Make2DFrom3DOp.cxx @@ -233,6 +233,7 @@ void SMESHGUI_Make2DFrom3DOp::startOperation() myDlg->SetMeshInfo( aNewInfo ); myDlg->show(); /*exec();*/ commit(); + SMESHGUI::Modified(); } //================================================================================ diff --git a/src/SMESHGUI/SMESHGUI_MakeNodeAtPointDlg.cxx b/src/SMESHGUI/SMESHGUI_MakeNodeAtPointDlg.cxx index 0792b596c..ee35301f0 100644 --- a/src/SMESHGUI/SMESHGUI_MakeNodeAtPointDlg.cxx +++ b/src/SMESHGUI/SMESHGUI_MakeNodeAtPointDlg.cxx @@ -424,6 +424,7 @@ bool SMESHGUI_MakeNodeAtPointOp::onApply() aList.Append(myMeshActor->getIO()); selectionMgr()->setSelectedObjects(aList,false); SMESH::UpdateView(); + SMESHGUI::Modified(); } } catch (const SALOME::SALOME_Exception& S_ex) { diff --git a/src/SMESHGUI/SMESHGUI_MeshOp.cxx b/src/SMESHGUI/SMESHGUI_MeshOp.cxx index 1739b419c..4ceb159ee 100644 --- a/src/SMESHGUI/SMESHGUI_MeshOp.cxx +++ b/src/SMESHGUI/SMESHGUI_MeshOp.cxx @@ -150,7 +150,10 @@ bool SMESHGUI_MeshOp::onApply() else if ( !myToCreate ) aResult = editMeshOrSubMesh( aMess ); if ( aResult ) + { + SMESHGUI::Modified(); update( UF_ObjBrowser | UF_Model ); + } } catch ( const SALOME::SALOME_Exception& S_ex ) { diff --git a/src/SMESHGUI/SMESHGUI_MeshOrderOp.cxx b/src/SMESHGUI/SMESHGUI_MeshOrderOp.cxx index 494d4eabf..511191c13 100644 --- a/src/SMESHGUI/SMESHGUI_MeshOrderOp.cxx +++ b/src/SMESHGUI/SMESHGUI_MeshOrderOp.cxx @@ -138,6 +138,9 @@ bool SMESHGUI_MeshOrderOp::onApply() SUIT_OverrideCursor aWaitCursor; bool res = myMgr ? myMgr->SetMeshOrder() : false; + if( res ) + SMESHGUI::Modified(); + delete myMgr; myMgr = 0; diff --git a/src/SMESHGUI/SMESHGUI_MeshPatternDlg.cxx b/src/SMESHGUI/SMESHGUI_MeshPatternDlg.cxx index f08d017d9..2f3a7a235 100755 --- a/src/SMESHGUI/SMESHGUI_MeshPatternDlg.cxx +++ b/src/SMESHGUI/SMESHGUI_MeshPatternDlg.cxx @@ -510,6 +510,7 @@ bool SMESHGUI_MeshPatternDlg::onApply() } mySelectionMgr->clearSelected(); SMESH::UpdateView(); + SMESHGUI::Modified(); mySMESHGUI->updateObjBrowser(true); diff --git a/src/SMESHGUI/SMESHGUI_MoveNodesDlg.cxx b/src/SMESHGUI/SMESHGUI_MoveNodesDlg.cxx index f4c26bb9f..ac5438382 100644 --- a/src/SMESHGUI/SMESHGUI_MoveNodesDlg.cxx +++ b/src/SMESHGUI/SMESHGUI_MoveNodesDlg.cxx @@ -356,6 +356,7 @@ bool SMESHGUI_MoveNodesDlg::onApply() aList.Append(myMeshActor->getIO()); mySelectionMgr->setSelectedObjects(aList,false); SMESH::UpdateView(); + SMESHGUI::Modified(); reset(); } diff --git a/src/SMESHGUI/SMESHGUI_MultiEditDlg.cxx b/src/SMESHGUI/SMESHGUI_MultiEditDlg.cxx index 98b047400..341ffb284 100755 --- a/src/SMESHGUI/SMESHGUI_MultiEditDlg.cxx +++ b/src/SMESHGUI/SMESHGUI_MultiEditDlg.cxx @@ -1052,6 +1052,7 @@ bool SMESHGUI_MultiEditDlg::onApply() mySelector->ClearIndex(); mySelectionMgr->setSelectedObjects( sel ); SMESH::UpdateView(); + SMESHGUI::Modified(); } myListBox->clear(); diff --git a/src/SMESHGUI/SMESHGUI_NodesDlg.cxx b/src/SMESHGUI/SMESHGUI_NodesDlg.cxx index d12100ca2..84abe5242 100644 --- a/src/SMESHGUI/SMESHGUI_NodesDlg.cxx +++ b/src/SMESHGUI/SMESHGUI_NodesDlg.cxx @@ -379,6 +379,7 @@ void SMESHGUI_NodesDlg::Init() connect( mySMESHGUI, SIGNAL( SignalDeactivateActiveDialog() ), SLOT( DeactivateActiveDialog() ) ); /* to close dialog if study frame change */ connect( mySMESHGUI, SIGNAL( SignalStudyFrameChanged() ), SLOT( ClickOnCancel() ) ); + connect(mySMESHGUI, SIGNAL(SignalCloseAllDialogs()), SLOT(ClickOnCancel())); // set selection mode SMESH::SetPointRepresentation( true ); @@ -526,6 +527,9 @@ bool SMESHGUI_NodesDlg::ClickOnApply() } } } + + SMESHGUI::Modified(); + return true; } diff --git a/src/SMESHGUI/SMESHGUI_Preferences_ColorDlg.cxx b/src/SMESHGUI/SMESHGUI_Preferences_ColorDlg.cxx index 85311c6b7..7d03f2779 100644 --- a/src/SMESHGUI/SMESHGUI_Preferences_ColorDlg.cxx +++ b/src/SMESHGUI/SMESHGUI_Preferences_ColorDlg.cxx @@ -33,8 +33,12 @@ // SALOME GUI includes #include +#include +#include +#include #include #include +#include #include // Qt includes @@ -45,6 +49,7 @@ #include #include #include +#include #define SPACING 6 #define MARGIN 11 @@ -186,10 +191,14 @@ SMESHGUI_Preferences_ColorDlg::SMESHGUI_Preferences_ColorDlg( SMESHGUI* theModul QPushButton* buttonCancel = new QPushButton( tr( "&Cancel" ), GroupButtons ); buttonCancel->setAutoDefault( true ); + QPushButton* buttonHelp = new QPushButton( tr( "&Help" ), GroupButtons ); + buttonHelp->setAutoDefault( true ); + GroupButtonsLayout->addWidget( buttonOk ); GroupButtonsLayout->addSpacing( 10 ); GroupButtonsLayout->addStretch(); GroupButtonsLayout->addWidget( buttonCancel ); + GroupButtonsLayout->addWidget( buttonHelp ); // ------------------------------- topLayout->addWidget( ButtonGroup1 ); @@ -200,9 +209,12 @@ SMESHGUI_Preferences_ColorDlg::SMESHGUI_Preferences_ColorDlg( SMESHGUI* theModul // ------------------------------- mySMESHGUI->SetActiveDialogBox( this ); + myHelpFileName = "colors_size_page.html"; + /* signals and slots connections */ connect( buttonOk, SIGNAL( clicked() ), this, SLOT( ClickOnOk() ) ); connect( buttonCancel, SIGNAL( clicked() ), this, SLOT( ClickOnCancel() ) ); + connect( buttonHelp, SIGNAL( clicked() ), this, SLOT( ClickOnHelp() ) ); connect( mySMESHGUI, SIGNAL ( SignalDeactivateActiveDialog() ), this, SLOT( DeactivateActiveDialog() ) ); @@ -239,6 +251,30 @@ void SMESHGUI_Preferences_ColorDlg::ClickOnCancel() reject(); } +//================================================================================= +// function : ClickOnHelp() +// purpose : +//================================================================================= +void SMESHGUI_Preferences_ColorDlg::ClickOnHelp() +{ + LightApp_Application* app = (LightApp_Application*)(SUIT_Session::session()->activeApplication()); + if (app) + app->onHelpContextModule(mySMESHGUI ? app->moduleName(mySMESHGUI->moduleName()) : QString(""), myHelpFileName); + else { + QString platform; +#ifdef WIN32 + platform = "winapplication"; +#else + platform = "application"; +#endif + SUIT_MessageBox::warning(this, tr("WRN_WARNING"), + tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE"). + arg(app->resourceMgr()->stringValue("ExternalBrowser", + platform)). + arg(myHelpFileName)); + } +} + //================================================================================= // function : DeactivateActiveDialog() // purpose : @@ -447,3 +483,19 @@ int SMESHGUI_Preferences_ColorDlg::getCustomMarkerID() const { return MarkerWidget->getCustomMarkerID(); } + +//================================================================================= +// function : keyPressEvent() +// purpose : +//================================================================================= +void SMESHGUI_Preferences_ColorDlg::keyPressEvent( QKeyEvent* e ) +{ + QDialog::keyPressEvent( e ); + if ( e->isAccepted() ) + return; + + if ( e->key() == Qt::Key_F1 ) { + e->accept(); + ClickOnHelp(); + } +} diff --git a/src/SMESHGUI/SMESHGUI_Preferences_ColorDlg.h b/src/SMESHGUI/SMESHGUI_Preferences_ColorDlg.h index dc26a9384..aaaa499a6 100644 --- a/src/SMESHGUI/SMESHGUI_Preferences_ColorDlg.h +++ b/src/SMESHGUI/SMESHGUI_Preferences_ColorDlg.h @@ -71,10 +71,12 @@ public: protected: void closeEvent( QCloseEvent* ); + void keyPressEvent( QKeyEvent* ); private slots: void ClickOnOk(); void ClickOnCancel(); + void ClickOnHelp(); void DeactivateActiveDialog(); void ActivateThisDialog(); @@ -93,6 +95,8 @@ private: QtxColorButton* btnOrientationColor; SMESHGUI_SpinBox* SpinBox_Orientation_Scale; QCheckBox* CheckBox_Orientation_3DVectors; + + QString myHelpFileName; }; #endif // SMESHGUI_PREFERENCES_COLORDLG_H diff --git a/src/SMESHGUI/SMESHGUI_RemoveElementsDlg.cxx b/src/SMESHGUI/SMESHGUI_RemoveElementsDlg.cxx index c6ff898f3..a007feb0f 100644 --- a/src/SMESHGUI/SMESHGUI_RemoveElementsDlg.cxx +++ b/src/SMESHGUI/SMESHGUI_RemoveElementsDlg.cxx @@ -123,6 +123,7 @@ SMESHGUI_RemoveElementsDlg SelectButtonC1A1->setIcon(image1); LineEditC1A1 = new QLineEdit(GroupC1); LineEditC1A1->setValidator(new SMESHGUI_IdValidator(this)); + LineEditC1A1->setMaxLength(-1); QPushButton* filterBtn = new QPushButton( tr( "SMESH_BUT_FILTER" ), GroupC1 ); connect(filterBtn, SIGNAL(clicked()), this, SLOT(setFilters())); @@ -232,7 +233,7 @@ void SMESHGUI_RemoveElementsDlg::ClickOnApply() bool aResult = false; try { SMESH::SMESH_MeshEditor_var aMeshEditor = myMesh->GetMeshEditor(); - aResult = aMeshEditor->RemoveElements(anArrayOfIdeces.inout()); + aResult = aMeshEditor->RemoveElements(anArrayOfIdeces.in()); } catch (const SALOME::SALOME_Exception& S_ex) { SalomeApp_Tools::QtCatchCorbaException(S_ex); myEditCurrentArgument->clear(); @@ -244,6 +245,7 @@ void SMESHGUI_RemoveElementsDlg::ClickOnApply() myEditCurrentArgument->clear(); mySelector->ClearIndex(); SMESH::UpdateView(); + SMESHGUI::Modified(); } } } @@ -310,9 +312,6 @@ void SMESHGUI_RemoveElementsDlg::onTextChange(const QString& theNewText) myNbOkElements = 0; - buttonOk->setEnabled(false); - buttonApply->setEnabled(false); - // hilight entered elements if(myActor){ if(SMDS_Mesh* aMesh = myActor->GetObject()->GetMesh()){ @@ -334,12 +333,8 @@ void SMESHGUI_RemoveElementsDlg::onTextChange(const QString& theNewText) } } - if (myNbOkElements) { - buttonOk->setEnabled(true); - buttonApply->setEnabled(true); - } - myBusy = false; + updateButtons(); } //================================================================================= @@ -348,56 +343,52 @@ void SMESHGUI_RemoveElementsDlg::onTextChange(const QString& theNewText) //================================================================================= void SMESHGUI_RemoveElementsDlg::SelectionIntoArgument() { - if (myBusy) return; + if (myBusy) return; // busy + if (myFilterDlg && myFilterDlg->isVisible()) return; // filter digl active + if (!GroupButtons->isEnabled()) return; // inactive // clear - myNbOkElements = false; + myNbOkElements = 0; myActor = 0; myBusy = true; myEditCurrentArgument->setText(""); myBusy = false; - if (!GroupButtons->isEnabled()) // inactive - return; - - buttonOk->setEnabled(false); - buttonApply->setEnabled(false); - // get selected mesh SALOME_ListIO aList; mySelectionMgr->selectedObjects(aList,SVTK_Viewer::Type()); int nbSel = aList.Extent(); - if (nbSel != 1) - return; - - Handle(SALOME_InteractiveObject) anIO = aList.First(); - myMesh = SMESH::GetMeshByIO(anIO); - if (myMesh->_is_nil()) - return; - - myActor = SMESH::FindActorByEntry(anIO->getEntry()); - if (!myActor) - return; - - // get selected nodes - QString aString = ""; - int nbElems = SMESH::GetNameOfSelectedElements(mySelector,anIO,aString); - if(nbElems < 1) - return; - myBusy = true; - myEditCurrentArgument->setText(aString); - myBusy = false; - - // OK - - myNbOkElements = nbElems; - - buttonOk->setEnabled(true); - buttonApply->setEnabled(true); + if (nbSel == 1) { + + Handle(SALOME_InteractiveObject) anIO = aList.First(); + myMesh = SMESH::GetMeshByIO(anIO); + + if (!myMesh->_is_nil()) { + + myActor = SMESH::FindActorByEntry(anIO->getEntry()); + if (myActor) { + + // get selected nodes + QString aString = ""; + int nbElems = SMESH::GetNameOfSelectedElements(mySelector,anIO,aString); + if (nbElems > 0) { + myBusy = true; + myEditCurrentArgument->setText(aString); + myBusy = false; + + // OK + + myNbOkElements = nbElems; + } // if (nbElems > 0) + } // if (myActor) + } // if (!myMesh->_is_nil()) + } // if (nbSel == 1) { + + updateButtons(); } //================================================================================= @@ -523,3 +514,13 @@ void SMESHGUI_RemoveElementsDlg::setFilters() myFilterDlg->show(); } + +//================================================================================= +// function : updateButtons +// purpose : enable / disable control buttons +//================================================================================= +void SMESHGUI_RemoveElementsDlg::updateButtons() +{ + buttonOk->setEnabled(myNbOkElements > 0); + buttonApply->setEnabled(myNbOkElements > 0); +} diff --git a/src/SMESHGUI/SMESHGUI_RemoveElementsDlg.h b/src/SMESHGUI/SMESHGUI_RemoveElementsDlg.h index 246c78a47..9a372bb27 100644 --- a/src/SMESHGUI/SMESHGUI_RemoveElementsDlg.h +++ b/src/SMESHGUI/SMESHGUI_RemoveElementsDlg.h @@ -107,6 +107,7 @@ private slots: void ActivateThisDialog(); void onTextChange( const QString& ); void setFilters(); + void updateButtons(); }; #endif // SMESHGUI_REMOVEELEMENTSDLG_H diff --git a/src/SMESHGUI/SMESHGUI_RemoveNodesDlg.cxx b/src/SMESHGUI/SMESHGUI_RemoveNodesDlg.cxx index fc6c78a30..58fd31fb3 100644 --- a/src/SMESHGUI/SMESHGUI_RemoveNodesDlg.cxx +++ b/src/SMESHGUI/SMESHGUI_RemoveNodesDlg.cxx @@ -123,6 +123,7 @@ SMESHGUI_RemoveNodesDlg SelectButtonC1A1->setIcon(image1); LineEditC1A1 = new QLineEdit(GroupC1); LineEditC1A1->setValidator(new SMESHGUI_IdValidator(this)); + LineEditC1A1->setMaxLength(-1); QPushButton* filterBtn = new QPushButton( tr( "SMESH_BUT_FILTER" ), GroupC1 ); connect(filterBtn, SIGNAL(clicked()), this, SLOT(setFilters())); @@ -234,7 +235,7 @@ void SMESHGUI_RemoveNodesDlg::ClickOnApply() bool aResult = false; try { SMESH::SMESH_MeshEditor_var aMeshEditor = myMesh->GetMeshEditor(); - aResult = aMeshEditor->RemoveNodes(anArrayOfIdeces.inout()); + aResult = aMeshEditor->RemoveNodes(anArrayOfIdeces.in()); } catch (const SALOME::SALOME_Exception& S_ex) { SalomeApp_Tools::QtCatchCorbaException(S_ex); myEditCurrentArgument->clear(); @@ -246,6 +247,7 @@ void SMESHGUI_RemoveNodesDlg::ClickOnApply() myEditCurrentArgument->clear(); mySelector->ClearIndex(); SMESH::UpdateView(); + SMESHGUI::Modified(); } SMESH::SetPointRepresentation(true); @@ -316,9 +318,6 @@ void SMESHGUI_RemoveNodesDlg::onTextChange(const QString& theNewText) myNbOkNodes = 0; - buttonOk->setEnabled(false); - buttonApply->setEnabled(false); - // hilight entered nodes if(myActor){ if(SMDS_Mesh* aMesh = myActor->GetObject()->GetMesh()){ @@ -340,12 +339,8 @@ void SMESHGUI_RemoveNodesDlg::onTextChange(const QString& theNewText) } } - if (myNbOkNodes) { - buttonOk->setEnabled(true); - buttonApply->setEnabled(true); - } - myBusy = false; + updateButtons(); } //================================================================================= @@ -354,56 +349,51 @@ void SMESHGUI_RemoveNodesDlg::onTextChange(const QString& theNewText) //================================================================================= void SMESHGUI_RemoveNodesDlg::SelectionIntoArgument() { - if (myBusy) return; - + if (myBusy) return; // busy + if (myFilterDlg && myFilterDlg->isVisible()) return; // filter dlg active + if (!GroupButtons->isEnabled()) return; // inactive + // clear - myNbOkNodes = false; + myNbOkNodes = 0; myActor = 0; myBusy = true; myEditCurrentArgument->setText(""); myBusy = false; - if (!GroupButtons->isEnabled()) // inactive - return; - - buttonOk->setEnabled(false); - buttonApply->setEnabled(false); - // get selected mesh SALOME_ListIO aList; mySelectionMgr->selectedObjects(aList,SVTK_Viewer::Type()); int nbSel = aList.Extent(); - if (nbSel != 1) - return; - - Handle(SALOME_InteractiveObject) anIO = aList.First(); - myMesh = SMESH::GetMeshByIO(anIO); - if (myMesh->_is_nil()) - return; - - myActor = SMESH::FindActorByEntry(anIO->getEntry()); - if (!myActor) - return; - - // get selected nodes - - QString aString = ""; - int nbNodes = SMESH::GetNameOfSelectedNodes(mySelector,anIO,aString); - if(nbNodes < 1) - return; - myBusy = true; - myEditCurrentArgument->setText(aString); - myBusy = false; - - // OK - - myNbOkNodes = true; - - buttonOk->setEnabled(true); - buttonApply->setEnabled(true); + if (nbSel == 1) { + + Handle(SALOME_InteractiveObject) anIO = aList.First(); + myMesh = SMESH::GetMeshByIO(anIO); + + if (!myMesh->_is_nil()) { + + myActor = SMESH::FindActorByEntry(anIO->getEntry()); + if (myActor) { + + // get selected nodes + QString aString = ""; + int nbNodes = SMESH::GetNameOfSelectedNodes(mySelector,anIO,aString); + if (nbNodes > 0) { + myBusy = true; + myEditCurrentArgument->setText(aString); + myBusy = false; + + // OK + + myNbOkNodes = nbNodes; + } // if (nbNodes > 0) + } // if (myActor) + } // if (!myMesh->_is_nil()) + } // if (nbSel == 1) + + updateButtons(); } //================================================================================= @@ -530,3 +520,13 @@ void SMESHGUI_RemoveNodesDlg::setFilters() myFilterDlg->show(); } + +//================================================================================= +// function : updateButtons +// purpose : enable / disable control buttons +//================================================================================= +void SMESHGUI_RemoveNodesDlg::updateButtons() +{ + buttonOk->setEnabled(myNbOkNodes > 0); + buttonApply->setEnabled(myNbOkNodes > 0); +} diff --git a/src/SMESHGUI/SMESHGUI_RemoveNodesDlg.h b/src/SMESHGUI/SMESHGUI_RemoveNodesDlg.h index 866757ef5..2ce8f9e7e 100644 --- a/src/SMESHGUI/SMESHGUI_RemoveNodesDlg.h +++ b/src/SMESHGUI/SMESHGUI_RemoveNodesDlg.h @@ -107,6 +107,7 @@ private slots: void ActivateThisDialog(); void onTextChange( const QString& ); void setFilters(); + void updateButtons(); }; #endif // SMESHGUI_REMOVENODESDLG_H diff --git a/src/SMESHGUI/SMESHGUI_RenumberingDlg.cxx b/src/SMESHGUI/SMESHGUI_RenumberingDlg.cxx index 5ebfe5062..67a1a4220 100644 --- a/src/SMESHGUI/SMESHGUI_RenumberingDlg.cxx +++ b/src/SMESHGUI/SMESHGUI_RenumberingDlg.cxx @@ -243,6 +243,7 @@ void SMESHGUI_RenumberingDlg::ClickOnApply() //mySelectionMgr->clearSelected(); SMESH::UpdateView(); + SMESHGUI::Modified(); } } diff --git a/src/SMESHGUI/SMESHGUI_RevolutionDlg.cxx b/src/SMESHGUI/SMESHGUI_RevolutionDlg.cxx index f6edc503f..d292d2996 100644 --- a/src/SMESHGUI/SMESHGUI_RevolutionDlg.cxx +++ b/src/SMESHGUI/SMESHGUI_RevolutionDlg.cxx @@ -146,6 +146,7 @@ SMESHGUI_RevolutionDlg::SMESHGUI_RevolutionDlg( SMESHGUI* theModule ) LineEditElements = new QLineEdit(GroupArguments); LineEditElements->setValidator(myIdValidator); + LineEditElements->setMaxLength(-1); myFilterBtn = new QPushButton( tr( "SMESH_BUT_FILTER" ), GroupArguments ); connect(myFilterBtn, SIGNAL(clicked()), this, SLOT(setFilters())); @@ -557,6 +558,8 @@ bool SMESHGUI_RevolutionDlg::ClickOnApply() ConstructorsClicked(GetConstructorId()); mySelectedObject = SMESH::SMESH_IDSource::_nil(); SelectionIntoArgument(); + + SMESHGUI::Modified(); } return true; diff --git a/src/SMESHGUI/SMESHGUI_RotationDlg.cxx b/src/SMESHGUI/SMESHGUI_RotationDlg.cxx index f2855bb7a..1dc48b0b3 100644 --- a/src/SMESHGUI/SMESHGUI_RotationDlg.cxx +++ b/src/SMESHGUI/SMESHGUI_RotationDlg.cxx @@ -134,6 +134,7 @@ SMESHGUI_RotationDlg::SMESHGUI_RotationDlg( SMESHGUI* theModule ) SelectElementsButton->setIcon(image1); LineEditElements = new QLineEdit(GroupArguments); LineEditElements->setValidator(myIdValidator); + LineEditElements->setMaxLength(-1); myFilterBtn = new QPushButton( tr( "SMESH_BUT_FILTER" ), GroupArguments ); connect(myFilterBtn, SIGNAL(clicked()), this, SLOT(setFilters())); @@ -456,6 +457,8 @@ bool SMESHGUI_RotationDlg::ClickOnApply() Init(false); mySelectedObject = SMESH::SMESH_IDSource::_nil(); SelectionIntoArgument(); + + SMESHGUI::Modified(); } return true; diff --git a/src/SMESHGUI/SMESHGUI_ScaleDlg.cxx b/src/SMESHGUI/SMESHGUI_ScaleDlg.cxx index 97976bf04..b9a5c1a0b 100644 --- a/src/SMESHGUI/SMESHGUI_ScaleDlg.cxx +++ b/src/SMESHGUI/SMESHGUI_ScaleDlg.cxx @@ -154,6 +154,7 @@ SMESHGUI_ScaleDlg::SMESHGUI_ScaleDlg( SMESHGUI* theModule ) SelectElementsButton->setIcon(image2); LineEditElements = new QLineEdit(GroupArguments); LineEditElements->setValidator(myIdValidator); + LineEditElements->setMaxLength(-1); myFilterBtn = new QPushButton( tr( "SMESH_BUT_FILTER" ), GroupArguments ); connect(myFilterBtn, SIGNAL(clicked()), this, SLOT(setFilters())); @@ -526,6 +527,8 @@ bool SMESHGUI_ScaleDlg::ClickOnApply() ConstructorsClicked(GetConstructorId()); mySelectedObject = SMESH::SMESH_IDSource::_nil(); SelectionIntoArgument(); + + SMESHGUI::Modified(); } return true; diff --git a/src/SMESHGUI/SMESHGUI_SewingDlg.cxx b/src/SMESHGUI/SMESHGUI_SewingDlg.cxx index cd63b5e12..cc8fbf136 100644 --- a/src/SMESHGUI/SMESHGUI_SewingDlg.cxx +++ b/src/SMESHGUI/SMESHGUI_SewingDlg.cxx @@ -533,6 +533,8 @@ bool SMESHGUI_SewingDlg::ClickOnApply() Init(); ConstructorsClicked(GetConstructorId()); + + SMESHGUI::Modified(); } } diff --git a/src/SMESHGUI/SMESHGUI_SingleEditDlg.cxx b/src/SMESHGUI/SMESHGUI_SingleEditDlg.cxx index bb73bcbd5..d005010e4 100755 --- a/src/SMESHGUI/SMESHGUI_SingleEditDlg.cxx +++ b/src/SMESHGUI/SMESHGUI_SingleEditDlg.cxx @@ -514,6 +514,7 @@ bool SMESHGUI_SingleEditDlg::onApply() mySelectionMgr->setSelectedObjects(aList, false); onSelectionDone(); SMESH::UpdateView(); + SMESHGUI::Modified(); } return aResult; diff --git a/src/SMESHGUI/SMESHGUI_SmoothingDlg.cxx b/src/SMESHGUI/SMESHGUI_SmoothingDlg.cxx index 3b83752eb..be2178dbb 100644 --- a/src/SMESHGUI/SMESHGUI_SmoothingDlg.cxx +++ b/src/SMESHGUI/SMESHGUI_SmoothingDlg.cxx @@ -138,6 +138,7 @@ SMESHGUI_SmoothingDlg::SMESHGUI_SmoothingDlg( SMESHGUI* theModule ) LineEditElements = new QLineEdit(GroupArguments); LineEditElements->setValidator(myIdValidator); + LineEditElements->setMaxLength(-1); myElemFilterBtn = new QPushButton( tr( "SMESH_BUT_FILTER" ), GroupArguments ); connect(myElemFilterBtn, SIGNAL(clicked()), this, SLOT(setElemFilters())); @@ -152,6 +153,7 @@ SMESHGUI_SmoothingDlg::SMESHGUI_SmoothingDlg( SMESHGUI* theModule ) LineEditNodes = new QLineEdit(GroupArguments); LineEditNodes->setValidator(myIdValidator); + LineEditNodes->setMaxLength(-1); QPushButton* filterNodeBtn = new QPushButton( tr( "SMESH_BUT_FILTER" ), GroupArguments ); connect(filterNodeBtn, SIGNAL(clicked()), this, SLOT(setNodeFilters())); @@ -395,6 +397,7 @@ bool SMESHGUI_SmoothingDlg::ClickOnApply() } SMESH::UpdateView(); + SMESHGUI::Modified(); Init(); mySelectedObject = SMESH::SMESH_IDSource::_nil(); diff --git a/src/SMESHGUI/SMESHGUI_SymmetryDlg.cxx b/src/SMESHGUI/SMESHGUI_SymmetryDlg.cxx index 6fec286e3..2a3562e3d 100644 --- a/src/SMESHGUI/SMESHGUI_SymmetryDlg.cxx +++ b/src/SMESHGUI/SMESHGUI_SymmetryDlg.cxx @@ -145,6 +145,7 @@ SMESHGUI_SymmetryDlg::SMESHGUI_SymmetryDlg( SMESHGUI* theModule ) SelectElementsButton->setIcon(image3); LineEditElements = new QLineEdit(GroupArguments); LineEditElements->setValidator(myIdValidator); + LineEditElements->setMaxLength(-1); myFilterBtn = new QPushButton( tr( "SMESH_BUT_FILTER" ), GroupArguments ); connect(myFilterBtn, SIGNAL(clicked()), this, SLOT(setFilters())); @@ -546,6 +547,8 @@ bool SMESHGUI_SymmetryDlg::ClickOnApply() ConstructorsClicked(GetConstructorId()); mySelectedObject = SMESH::SMESH_IDSource::_nil(); SelectionIntoArgument(); + + SMESHGUI::Modified(); } return true; } diff --git a/src/SMESHGUI/SMESHGUI_TranslationDlg.cxx b/src/SMESHGUI/SMESHGUI_TranslationDlg.cxx index 6b2e2398d..fac987991 100644 --- a/src/SMESHGUI/SMESHGUI_TranslationDlg.cxx +++ b/src/SMESHGUI/SMESHGUI_TranslationDlg.cxx @@ -157,6 +157,7 @@ SMESHGUI_TranslationDlg::SMESHGUI_TranslationDlg( SMESHGUI* theModule ) SelectElementsButton->setIcon(image2); LineEditElements = new QLineEdit(GroupArguments); LineEditElements->setValidator(myIdValidator); + LineEditElements->setMaxLength(-1); myFilterBtn = new QPushButton( tr( "SMESH_BUT_FILTER" ), GroupArguments ); connect(myFilterBtn, SIGNAL(clicked()), this, SLOT(setFilters())); @@ -530,6 +531,8 @@ bool SMESHGUI_TranslationDlg::ClickOnApply() ConstructorsClicked(GetConstructorId()); mySelectedObject = SMESH::SMESH_IDSource::_nil(); SelectionIntoArgument(); + + SMESHGUI::Modified(); } return true; diff --git a/src/SMESHGUI/SMESHGUI_WhatIsDlg.cxx b/src/SMESHGUI/SMESHGUI_WhatIsDlg.cxx index 5c78a9d13..027919627 100755 --- a/src/SMESHGUI/SMESHGUI_WhatIsDlg.cxx +++ b/src/SMESHGUI/SMESHGUI_WhatIsDlg.cxx @@ -130,6 +130,7 @@ SMESHGUI_WhatIsDlg::SMESHGUI_WhatIsDlg( SMESHGUI* theModule ) LineEditElements = new QLineEdit(GroupArguments); LineEditElements->setValidator(new SMESHGUI_IdValidator(this)); + LineEditElements->setMaxLength(-1); GroupArgumentsLayout->addWidget(LineEditElements, 0, 1); // information text browser diff --git a/src/SMESH_SWIG/ex06_hole1boolean.py b/src/SMESH_SWIG/ex06_hole1boolean.py index 3c5054590..2a2784e91 100644 --- a/src/SMESH_SWIG/ex06_hole1boolean.py +++ b/src/SMESH_SWIG/ex06_hole1boolean.py @@ -109,7 +109,7 @@ c_l.append(baseHexa4) c_cpd = MakeCompound(c_l) c_glu = MakeGlueFaces(c_cpd, 1.e-5) -piece = RemoveExtraEdges(c_glu) +piece = RemoveExtraEdges(c_glu, doUnionFaces=True) # Add in study # ------------ diff --git a/src/SMESH_SWIG/ex07_hole1partition.py b/src/SMESH_SWIG/ex07_hole1partition.py index 6ef4f6c3d..50f8d07a8 100644 --- a/src/SMESH_SWIG/ex07_hole1partition.py +++ b/src/SMESH_SWIG/ex07_hole1partition.py @@ -72,7 +72,7 @@ p_tools.append(MakePlane(p_centre, MakeVectorDXDYDZ(-g_largeur, 0, g_longueur), p_part = MakePartition([c_piece], p_tools, [], [], ShapeType["SOLID"]) -p_blocs = RemoveExtraEdges(p_part) +p_blocs = RemoveExtraEdges(p_part, doUnionFaces=True) piece = MakeGlueFaces(p_blocs, 1.e-5) # Add in study diff --git a/src/SMESH_SWIG/ex11_grid3partition.py b/src/SMESH_SWIG/ex11_grid3partition.py index 6b2407af9..3e5f6712b 100644 --- a/src/SMESH_SWIG/ex11_grid3partition.py +++ b/src/SMESH_SWIG/ex11_grid3partition.py @@ -85,7 +85,7 @@ p_tools.append(MakePlane(e_centre, MakeVectorDXDYDZ(-1, 0, 1), g_trim)) p_part = MakePartition([e_blo1, e_blo2, e_blo3], p_tools, [], [], ShapeType["SOLID"]) -p_element = RemoveExtraEdges(p_part) +p_element = RemoveExtraEdges(p_part, doUnionFaces=True) # Grid and glue # ------------- diff --git a/src/SMESH_SWIG/ex13_hole1partial.py b/src/SMESH_SWIG/ex13_hole1partial.py index c11080657..24ae387f5 100644 --- a/src/SMESH_SWIG/ex13_hole1partial.py +++ b/src/SMESH_SWIG/ex13_hole1partial.py @@ -206,7 +206,7 @@ blocks.append(full_parts) piece_cpd = MakeCompound(blocks) -piece_ok = RemoveExtraEdges(piece_cpd) +piece_ok = RemoveExtraEdges(piece_cpd, doUnionFaces=True) piece = MakeGlueFaces(piece_ok, 1.e-3) diff --git a/src/StdMeshers/StdMeshers_CompositeHexa_3D.cxx b/src/StdMeshers/StdMeshers_CompositeHexa_3D.cxx index d55c17513..24a1e3fa9 100644 --- a/src/StdMeshers/StdMeshers_CompositeHexa_3D.cxx +++ b/src/StdMeshers/StdMeshers_CompositeHexa_3D.cxx @@ -205,7 +205,7 @@ public: //** Access to member fields **// private: - bool error(std::string& text, int code = COMPERR_ALGO_FAILED) + bool error(const std::string& text, int code = COMPERR_ALGO_FAILED) { myError = SMESH_ComputeError::New( code, text ); return false; } bool error(const SMESH_ComputeErrorPtr& err) @@ -987,6 +987,13 @@ bool _QuadFaceGrid::LoadGrid( SMESH_Mesh& mesh ) if ( !myGrid.empty() ) return true; + SMESHDS_SubMesh* faceSubMesh = mesh.GetSubMesh( myFace )->GetSubMeshDS(); + // check that all faces are quadrangular + SMDS_ElemIteratorPtr fIt = faceSubMesh->GetElements(); + while ( fIt->more() ) + if ( fIt->next()->NbNodes() % 4 > 0 ) + return error("Non-quadrangular mesh faces are not allowed on sides of a composite block"); + myIndexer._xSize = 1 + mySides.GetSide( Q_BOTTOM )->GetNbSegments( mesh ); myIndexer._ySize = 1 + mySides.GetSide( Q_LEFT )->GetNbSegments( mesh ); @@ -997,8 +1004,6 @@ bool _QuadFaceGrid::LoadGrid( SMESH_Mesh& mesh ) // store the rest nodes row by row - SMESHDS_SubMesh* faceSubMesh = mesh.GetSubMesh( myFace )->GetSubMeshDS(); - SMDS_MeshNode dummy(0,0,0); const SMDS_MeshElement* firstQuad = &dummy;// most left face above the last row of found nodes diff --git a/src/StdMeshers/StdMeshers_FaceSide.cxx b/src/StdMeshers/StdMeshers_FaceSide.cxx index c0cef600d..036da0ba9 100644 --- a/src/StdMeshers/StdMeshers_FaceSide.cxx +++ b/src/StdMeshers/StdMeshers_FaceSide.cxx @@ -270,7 +270,7 @@ const vector& StdMeshers_FaceSide::GetUVPtStruct(bool isXConst, const SMDS_MeshNode* node = nItr->next(); if ( myIgnoreMediumNodes && SMESH_MeshEditor::IsMedium( node, SMDSAbs_Edge )) continue; - double u = helper.GetNodeU( myEdge[i], node, ¶mOK ); + double u = helper.GetNodeU( myEdge[i], node, 0, ¶mOK ); double aLenU = GCPnts_AbscissaPoint::Length ( const_cast( myC3dAdaptor[i]), myFirst[i], u ); if ( myEdgeLength[i] < aLenU ) // nonregression test "3D_mesh_NETGEN/G6" @@ -288,7 +288,7 @@ const vector& StdMeshers_FaceSide::GetUVPtStruct(bool isXConst, const SMDS_MeshNode* node = nItr->next(); if ( myIgnoreMediumNodes && SMESH_MeshEditor::IsMedium( node, SMDSAbs_Edge )) continue; - double u = helper.GetNodeU( myEdge[i], node, ¶mOK ); + double u = helper.GetNodeU( myEdge[i], node, 0, ¶mOK ); // paramSize is signed so orientation is taken into account double normPar = prevNormPar + r * ( u - myFirst[i] ) / paramSize; @@ -585,18 +585,17 @@ TSideVector StdMeshers_FaceSide::GetFaceWires(const TopoDS_Face& theFace, TError & theError) { TopoDS_Vertex V1; - list< TopoDS_Edge > edges; + list< TopoDS_Edge > edges, internalEdges; list< int > nbEdgesInWires; int nbWires = SMESH_Block::GetOrderedEdges (theFace, V1, edges, nbEdgesInWires); // split list of all edges into separate wires TSideVector wires( nbWires ); list< int >::iterator nbE = nbEdgesInWires.begin(); - list< TopoDS_Edge >::iterator from, to; - from = to = edges.begin(); - for ( int iW = 0; iW < nbWires; ++iW ) + list< TopoDS_Edge >::iterator from = edges.begin(), to = from; + for ( int iW = 0; iW < nbWires; ++iW, ++nbE ) { - std::advance( to, *nbE++ ); + std::advance( to, *nbE ); if ( *nbE == 0 ) // Issue 0020676 { --nbWires; @@ -608,6 +607,7 @@ TSideVector StdMeshers_FaceSide::GetFaceWires(const TopoDS_Face& theFace, // assure that there is a node on the first vertex // as StdMeshers_FaceSide::GetUVPtStruct() requires if ( wireEdges.front().Orientation() != TopAbs_INTERNAL ) // Issue 0020676 + { while ( !SMESH_Algo::VertexNode( TopExp::FirstVertex( wireEdges.front(), true), theMesh.GetMeshDS())) { @@ -619,12 +619,24 @@ TSideVector StdMeshers_FaceSide::GetFaceWires(const TopoDS_Face& theFace, return TSideVector(0); } } - const bool isForward = true; + } + else if ( *nbE > 1 ) // Issue 0020676 (Face_pb_netgen.brep) - several internal edges in a wire + { + internalEdges.splice( internalEdges.end(), wireEdges, ++wireEdges.begin(), wireEdges.end()); + } + StdMeshers_FaceSide* wire = new StdMeshers_FaceSide( theFace, wireEdges, &theMesh, - isForward, theIgnoreMediumNodes); + /*isForward=*/true, theIgnoreMediumNodes); wires[ iW ] = StdMeshers_FaceSidePtr( wire ); from = to; } + while ( !internalEdges.empty() ) + { + StdMeshers_FaceSide* wire = new StdMeshers_FaceSide( theFace, internalEdges.back(), &theMesh, + /*isForward=*/true, theIgnoreMediumNodes); + wires.push_back( StdMeshers_FaceSidePtr( wire )); + internalEdges.pop_back(); + } return wires; } diff --git a/src/StdMeshers/StdMeshers_HexaFromSkin_3D.cxx b/src/StdMeshers/StdMeshers_HexaFromSkin_3D.cxx index 28b628c5c..6e8448e0a 100644 --- a/src/StdMeshers/StdMeshers_HexaFromSkin_3D.cxx +++ b/src/StdMeshers/StdMeshers_HexaFromSkin_3D.cxx @@ -51,7 +51,7 @@ namespace { enum EBoxSides //!< sides of the block { - B_BOTTOM=0, B_RIGHT, B_TOP, B_LEFT, B_FRONT, B_BACK, B_UNDEFINED + B_BOTTOM=0, B_RIGHT, B_TOP, B_LEFT, B_FRONT, B_BACK, NB_BLOCK_SIDES }; const char* SBoxSides[] = //!< names of block sides { @@ -59,7 +59,7 @@ namespace }; enum EQuadEdge //!< edges of quadrangle side { - Q_BOTTOM, Q_RIGHT, Q_TOP, Q_LEFT, Q_UNDEFINED + Q_BOTTOM = 0, Q_RIGHT, Q_TOP, Q_LEFT, NB_QUAD_SIDES }; @@ -84,9 +84,42 @@ namespace return true; } + //================================================================================ + /*! + * \brief Description of node used to detect corner nodes + */ + struct _NodeDescriptor + { + int nbInverseFaces, nbNodesInInverseFaces; + + _NodeDescriptor(const SMDS_MeshNode* n): nbInverseFaces(0), nbNodesInInverseFaces(0) + { + if ( n ) + { + set nodes; + SMDS_ElemIteratorPtr fIt = n->GetInverseElementIterator(SMDSAbs_Face ); + while ( fIt->more() ) + { + const SMDS_MeshElement* face = fIt->next(); + nodes.insert( face->begin_nodes(), face->end_nodes() ); + nbInverseFaces++; + } + nbNodesInInverseFaces = nodes.size(); + } + } + bool operator==(const _NodeDescriptor& other) const + { + return + nbInverseFaces == other.nbInverseFaces && + nbNodesInInverseFaces == other.nbNodesInInverseFaces; + } + }; + //================================================================================ /*! * \brief return true if a node is at block corner + * + * This check is valid for simple cases only */ //================================================================================ @@ -103,7 +136,7 @@ namespace bool isQuadrangle(const SMDS_MeshElement* e) { - return ( e && e->NbNodes() == ( e->IsQuadratic() ? 8 : 4 )); + return ( e && e->NbCornerNodes() == 4 ); } //================================================================================ @@ -189,15 +222,15 @@ namespace int _nbBlocksExpected; int _nbBlocksFound; -#ifdef _DEBUG_ -#define _grid_access_(args) _grid.at( args ) +#ifdef _DEBUG_ // want to get SIGSEGV in case of invalid index +#define _grid_access_(pobj, i) pobj->_grid[ ((i) < pobj->_grid.size()) ? i : int(1e100)] #else -#define _grid_access_(args) _grid[ args ] +#define _grid_access_(pobj, i) pobj->_grid[ i ] #endif //!< Return node at XY - const SMDS_MeshNode* getNode(int x, int y) const { return _grid_access_( _index( x, y )); } + const SMDS_MeshNode* getNode(int x, int y) const { return _grid_access_(this, _index( x,y ));} //!< Set node at XY - void setNode(int x, int y, const SMDS_MeshNode* n) { _grid_access_( _index( x, y )) = n; } + void setNode(int x, int y, const SMDS_MeshNode* n) { _grid_access_(this, _index( x,y )) = n; } //!< Return an edge SMESH_OrientedLink getEdge(EQuadEdge edge) const { @@ -242,7 +275,7 @@ namespace //!< return coordinates by XY gp_XYZ xyz(int x, int y) const { - return SMESH_MeshEditor::TNodeXYZ( _side->_grid_access_( _index( x, y )) ); + return SMESH_MeshEditor::TNodeXYZ( _grid_access_(_side, _index( x, y )) ); } //!< safely return a node by XY const SMDS_MeshNode* node(int x, int y) const @@ -259,7 +292,7 @@ namespace //!< Return a corner node const SMDS_MeshNode* cornerNode(bool isXMax, bool isYMax) const { - return _side->_grid_access_( _index.corner( isXMax, isYMax )); + return _grid_access_(_side, _index.corner( isXMax, isYMax )); } //!< return its size in nodes int getHoriSize() const { return _index.xSize(); } @@ -276,14 +309,29 @@ namespace */ struct _Block { - _OrientedBlockSide _side[6]; // 6 sides of a sub-block + _OrientedBlockSide _side[6]; // 6 sides of a sub-block + set _corners; const _OrientedBlockSide& getSide(int i) const { return _side[i]; } + bool setSide( int i, const _OrientedBlockSide& s) + { + if (( _side[i] = s )) + { + _corners.insert( s.cornerNode(0,0)); + _corners.insert( s.cornerNode(1,0)); + _corners.insert( s.cornerNode(0,1)); + _corners.insert( s.cornerNode(1,1)); + } + return s; + } + void clear() { for (int i=0;i<6;++i) _side[i]=0; _corners.clear(); } bool hasSide( const _OrientedBlockSide& s) const { if ( s ) for (int i=0;i<6;++i) if ( _side[i] && _side[i]._side == s._side ) return true; return false; } + int nbSides() const { int n=0; for (int i=0;i<6;++i) if ( _side[i] ) ++n; return n; } + bool isValid() const; }; //================================================================================ /*! @@ -300,7 +348,9 @@ namespace const SMESH_Comment& error() const { return _error; } private: - bool fillSide( _BlockSide& side, const SMDS_MeshElement* cornerQuad); + bool fillSide( _BlockSide& side, + const SMDS_MeshElement* cornerQuad, + const SMDS_MeshNode* cornerNode); bool fillRowsUntilCorner(const SMDS_MeshElement* quad, const SMDS_MeshNode* n1, const SMDS_MeshNode* n2, @@ -309,16 +359,14 @@ namespace bool alongN1N2 ); _OrientedBlockSide findBlockSide( EBoxSides startBlockSide, EQuadEdge sharedSideEdge1, - EQuadEdge sharedSideEdge2); + EQuadEdge sharedSideEdge2, + bool withGeometricAnalysis); //!< update own data and data of the side bound to block void setSideBoundToBlock( _BlockSide& side ) { - side._nbBlocksFound++; - if ( side.isBound() ) - { - for ( int e = 0; e < int(Q_UNDEFINED); ++e ) + if ( side._nbBlocksFound++, side.isBound() ) + for ( int e = 0; e < int(NB_QUAD_SIDES); ++e ) _edge2sides[ side.getEdge( (EQuadEdge) e ) ].erase( &side ); - } } //!< store reason of error int error(const SMESH_Comment& reason) { _error = reason; return 0; } @@ -383,7 +431,7 @@ namespace _allSides.push_back( _BlockSide() ); _BlockSide& side = _allSides.back(); - if ( !fillSide( side, face ) ) + if ( !fillSide( side, face, *corner ) ) { if ( !_error.empty() ) return false; @@ -394,13 +442,10 @@ namespace for ( int isYMax = 0; isYMax < 2; ++isYMax ) { const SMDS_MeshNode* nCorner = side.getCornerNode(isXMax,isYMax ); - if ( !isCornerNode( nCorner )) - return BAD_MESH_ERR; - //_corner2sides[ nCorner ].insert( &side ); corners.push_back( nCorner ); cornerFaces.insert( side.getCornerFace( nCorner )); } - for ( int e = 0; e < int(Q_UNDEFINED); ++e ) + for ( int e = 0; e < int(NB_QUAD_SIDES); ++e ) _edge2sides[ side.getEdge( (EQuadEdge) e ) ].insert( &side ); nbFacesOnSides += side.getNbFaces(); @@ -425,23 +470,33 @@ namespace return BAD_MESH_ERR; if ( _allSides.back()._grid.empty() ) _allSides.pop_back(); + _DUMP_("Nb detected sides "<< _allSides.size()); // --------------------------- // Organize sides into blocks // --------------------------- - // analyse sharing of sides by blocks - int nbBlockSides = 0; // nb of block sides taking into account their sharing - list < _BlockSide >::iterator sideIt = _allSides.begin(); - for ( ; sideIt != _allSides.end(); ++sideIt ) + // analyse sharing of sides by blocks and sort sides by nb of adjacent sides + int nbBlockSides = 0; // total nb of block sides taking into account their sharing + multimap sortedSides; { - _BlockSide& side = *sideIt; - bool isSharedSide = true; - for ( int e = 0; e < int(Q_UNDEFINED) && isSharedSide; ++e ) - isSharedSide = _edge2sides[ side.getEdge( (EQuadEdge) e ) ].size() > 2; - side._nbBlocksFound = 0; - side._nbBlocksExpected = isSharedSide ? 2 : 1; - nbBlockSides += side._nbBlocksExpected; + list < _BlockSide >::iterator sideIt = _allSides.begin(); + for ( ; sideIt != _allSides.end(); ++sideIt ) + { + _BlockSide& side = *sideIt; + bool isSharedSide = true; + int nbAdjacent = 0; + for ( int e = 0; e < int(NB_QUAD_SIDES) && isSharedSide; ++e ) + { + int nbAdj = _edge2sides[ side.getEdge( (EQuadEdge) e ) ].size(); + nbAdjacent += nbAdj; + isSharedSide = ( nbAdj > 2 ); + } + side._nbBlocksFound = 0; + side._nbBlocksExpected = isSharedSide ? 2 : 1; + nbBlockSides += side._nbBlocksExpected; + sortedSides.insert( make_pair( nbAdjacent, & side )); + } } // find sides of each block @@ -449,9 +504,9 @@ namespace while ( nbBlockSides >= 6 ) { // get any side not bound to all blocks it belongs to - sideIt = _allSides.begin(); - while ( sideIt != _allSides.end() && sideIt->isBound()) - ++sideIt; + multimap::iterator i_side = sortedSides.begin(); + while ( i_side != sortedSides.end() && i_side->second->isBound()) + ++i_side; // start searching for block sides from the got side bool ok = true; @@ -459,37 +514,40 @@ namespace _blocks.resize( _blocks.size() + 1 ); _Block& block = _blocks.back(); - block._side[B_FRONT] = &(*sideIt); - setSideBoundToBlock( *sideIt ); + block.setSide( B_FRONT, i_side->second ); + setSideBoundToBlock( *i_side->second ); nbBlockSides--; - - // edges of neighbour sides of B_FRONT corresponding to front's edges - EQuadEdge edgeOfFront[4] = { Q_BOTTOM, Q_RIGHT, Q_TOP, Q_LEFT }; - EQuadEdge edgeToFind [4] = { Q_BOTTOM, Q_LEFT, Q_BOTTOM, Q_LEFT }; - for ( int i = Q_BOTTOM; ok && i <= Q_LEFT; ++i ) - ok = ( block._side[i] = findBlockSide( B_FRONT, edgeOfFront[i], edgeToFind[i])); - if ( ok ) - ok = ( block._side[B_BACK] = findBlockSide( B_TOP, Q_TOP, Q_TOP )); + // edges of adjacent sides of B_FRONT corresponding to front's edges + EQuadEdge edgeOfFront[4] = { Q_BOTTOM, Q_RIGHT, Q_TOP, Q_LEFT }; + EQuadEdge edgeOfAdj [4] = { Q_BOTTOM, Q_LEFT, Q_BOTTOM, Q_LEFT }; + // first find all sides detectable w/o advanced analysis, + // then repeat the search, which then may pass without advanced analysis + for ( int advAnalys = 0; advAnalys < 2; ++advAnalys ) + { + for ( int i = 0; (ok || !advAnalys) && i < NB_QUAD_SIDES; ++i ) + if ( !block._side[i] ) // try to find 4 sides adjacent to front side + ok = block.setSide( i, findBlockSide( B_FRONT, edgeOfFront[i],edgeOfAdj[i],advAnalys)); + if ( ok || !advAnalys) + if ( !block._side[B_BACK] && block._side[B_TOP] ) // try to find back side by top one + ok = block.setSide( B_BACK, findBlockSide( B_TOP, Q_TOP, Q_TOP, advAnalys )); + if ( !advAnalys ) ok = true; + } + ok = block.isValid(); if ( ok ) { // check if just found block is same as one of previously found bool isSame = false; for ( int i = 1; i < _blocks.size() && !isSame; ++i ) - { - _Block& prevBlock = _blocks[i-1]; - isSame = true; - for ( int j = 0; j < 6 && isSame; ++j ) - isSame = prevBlock.hasSide( block._side[ j ]); - } + isSame = ( block._corners == _blocks[i-1]._corners ); ok = !isSame; } // count the found sides - _DUMP_(endl); - for (int i = 0; i < B_UNDEFINED; ++i ) + _DUMP_(endl << "** Block " << _blocks.size() << " valid: " << block.isValid()); + for (int i = 0; i < NB_BLOCK_SIDES; ++i ) { - _DUMP_("** Block side "<< SBoxSides[i] <<" "<< block._side[ i ]._side); + _DUMP_("\tSide "<< SBoxSides[i] <<" "<< block._side[ i ]._side); if ( block._side[ i ] ) { if ( ok && i != B_FRONT) @@ -497,22 +555,24 @@ namespace setSideBoundToBlock( *block._side[ i ]._side ); nbBlockSides--; } - _DUMP_("Corner 0,0 "<< block._side[ i ].cornerNode(0,0)); - _DUMP_("Corner 1,0 "<< block._side[ i ].cornerNode(1,0)); - _DUMP_("Corner 1,1 "<< block._side[ i ].cornerNode(1,1)); - _DUMP_("Corner 0,1 "<< block._side[ i ].cornerNode(0,1)); + _DUMP_("\t corners "<< + block._side[ i ].cornerNode(0,0)->GetID() << ", " << + block._side[ i ].cornerNode(1,0)->GetID() << ", " << + block._side[ i ].cornerNode(1,1)->GetID() << ", " << + block._side[ i ].cornerNode(0,1)->GetID() << ", "<GetNode(i))) - nCorner = firstQuad->GetNode(i); - if ( !nCorner ) return false; - // get a node on block edge int iCorner = firstQuad->GetNodeIndex( nCorner ); const SMDS_MeshNode* nOnEdge = firstQuad->GetNode( (iCorner+1) % 4); @@ -611,7 +666,14 @@ namespace } } - return true; + // check side validity + bool ok = + side.getCornerFace( side.getCornerNode( 0, 0 )) && + side.getCornerFace( side.getCornerNode( 1, 0 )) && + side.getCornerFace( side.getCornerNode( 0, 1 )) && + side.getCornerFace( side.getCornerNode( 1, 1 )); + + return ok; } //================================================================================ @@ -622,7 +684,8 @@ namespace _OrientedBlockSide _Skin::findBlockSide( EBoxSides startBlockSide, EQuadEdge sharedSideEdge1, - EQuadEdge sharedSideEdge2) + EQuadEdge sharedSideEdge2, + bool withGeometricAnalysis) { _Block& block = _blocks.back(); _OrientedBlockSide& side1 = block._side[ startBlockSide ]; @@ -637,67 +700,93 @@ namespace set< _BlockSide* > sidesOnEdge = _edge2sides[ edge ]; // copy a set // exclude loaded sides of block from sidesOnEdge - int nbLoadedSides = 0; - for (int i = 0; i < B_UNDEFINED; ++i ) - { + for (int i = 0; i < NB_BLOCK_SIDES; ++i ) if ( block._side[ i ] ) - { - nbLoadedSides++; sidesOnEdge.erase( block._side[ i ]._side ); - } - } + int nbSidesOnEdge = sidesOnEdge.size(); _DUMP_("nbSidesOnEdge "<< nbSidesOnEdge << " " << n1->GetID() << "-" << n2->GetID() ); if ( nbSidesOnEdge == 0 ) return 0; _BlockSide* foundSide = 0; - if ( nbSidesOnEdge == 1 /*|| nbSidesOnEdge == 2 && nbLoadedSides == 1 */) + if ( nbSidesOnEdge == 1 ) { foundSide = *sidesOnEdge.begin(); } else { - // Select one of found sides most close to startBlockSide - - // gravity center of already loaded block sides - gp_XYZ gc(0,0,0); - for (int i = 0; i < B_UNDEFINED; ++i ) - if ( block._side[ i ] ) - gc += block._side[ i ]._side->getGC(); - gc /= nbLoadedSides; - - gp_XYZ p1 ( n1->X(),n1->Y(),n1->Z()), p2 (n2->X(),n2->Y(),n2->Z()); - gp_Vec p1p2( p1, p2 ); - - const SMDS_MeshElement* face1 = side1->getCornerFace( n1 ); - gp_XYZ p1Op = SMESH_MeshEditor::TNodeXYZ( oppositeNode( face1, face1->GetNodeIndex(n1))); - gp_Vec side1Dir( p1, p1Op ); - gp_Ax2 pln( p1, p1p2, side1Dir ); // plane with normal p1p2 and X dir side1Dir - _DUMP_(" Select adjacent for "<< side1._side << " - side dir (" - << side1Dir.X() << ", " << side1Dir.Y() << ", " << side1Dir.Z() << ")" ); - - map < double , _BlockSide* > angleOfSide; set< _BlockSide* >::iterator sideIt = sidesOnEdge.begin(); - for (; sideIt != sidesOnEdge.end(); ++sideIt ) + int nbLoadedSides = block.nbSides(); + if ( nbLoadedSides > 1 ) { - _BlockSide* sideI = *sideIt; - const SMDS_MeshElement* faceI = sideI->getCornerFace( n1 ); - gp_XYZ p1Op = SMESH_MeshEditor::TNodeXYZ( oppositeNode( faceI, faceI->GetNodeIndex(n1))); - gp_Vec sideIDir( p1, p1Op ); - // compute angle of (sideIDir projection to pln) and (X dir of pln) - gp_Vec2d sideIDirProj( sideIDir * pln.XDirection(), sideIDir * pln.YDirection()); - double angle = sideIDirProj.Angle( gp::DX2d() ); - if ( angle < 0 ) angle += 2 * PI; - angleOfSide.insert( make_pair( angle, sideI )); - _DUMP_(" "<< sideI << " - side dir (" - << sideIDir.X() << ", " << sideIDir.Y() << ", " << sideIDir.Z() << ")" - << " angle " << angle); + // Find the side having more than 2 corners common with already loaded sides + for (; !foundSide && sideIt != sidesOnEdge.end(); ++sideIt ) + { + _BlockSide* sideI = *sideIt; + int nbCommonCorners = + block._corners.count( sideI->getCornerNode(0,0)) + + block._corners.count( sideI->getCornerNode(1,0)) + + block._corners.count( sideI->getCornerNode(0,1)) + + block._corners.count( sideI->getCornerNode(1,1)); + if ( nbCommonCorners > 2 ) + foundSide = sideI; + } + } + + if ( !foundSide ) + { + if ( !withGeometricAnalysis ) return 0; + + // Select one of found sides most close to startBlockSide + + gp_XYZ p1 ( n1->X(),n1->Y(),n1->Z()), p2 (n2->X(),n2->Y(),n2->Z()); + gp_Vec p1p2( p1, p2 ); + + const SMDS_MeshElement* face1 = side1->getCornerFace( n1 ); + gp_XYZ p1Op = SMESH_MeshEditor::TNodeXYZ( oppositeNode( face1, face1->GetNodeIndex(n1))); + gp_Vec side1Dir( p1, p1Op ); + gp_Ax2 pln( p1, p1p2, side1Dir ); // plane with normal p1p2 and X dir side1Dir + _DUMP_(" Select adjacent for "<< side1._side << " - side dir (" + << side1Dir.X() << ", " << side1Dir.Y() << ", " << side1Dir.Z() << ")" ); + + map < double , _BlockSide* > angleOfSide; + for (sideIt = sidesOnEdge.begin(); sideIt != sidesOnEdge.end(); ++sideIt ) + { + _BlockSide* sideI = *sideIt; + const SMDS_MeshElement* faceI = sideI->getCornerFace( n1 ); + gp_XYZ p1Op = SMESH_MeshEditor::TNodeXYZ( oppositeNode( faceI, faceI->GetNodeIndex(n1))); + gp_Vec sideIDir( p1, p1Op ); + // compute angle of (sideIDir projection to pln) and (X dir of pln) + gp_Vec2d sideIDirProj( sideIDir * pln.XDirection(), sideIDir * pln.YDirection()); + double angle = sideIDirProj.Angle( gp::DX2d() ); + if ( angle < 0 ) angle += 2 * PI; // angle [0-2*PI] + angleOfSide.insert( make_pair( angle, sideI )); + _DUMP_(" "<< sideI << " - side dir (" + << sideIDir.X() << ", " << sideIDir.Y() << ", " << sideIDir.Z() << ")" + << " angle " << angle); + } + if ( nbLoadedSides == 1 ) + { + double angF = angleOfSide.begin()->first, angL = angleOfSide.rbegin()->first; + if ( angF > PI ) angF = 2*PI - angF; + if ( angL > PI ) angL = 2*PI - angL; + foundSide = angF < angL ? angleOfSide.begin()->second : angleOfSide.rbegin()->second; + } + else + { + gp_XYZ gc(0,0,0); // gravity center of already loaded block sides + for (int i = 0; i < NB_BLOCK_SIDES; ++i ) + if ( block._side[ i ] ) + gc += block._side[ i ]._side->getGC(); + gc /= nbLoadedSides; + + gp_Vec gcDir( p1, gc ); + gp_Vec2d gcDirProj( gcDir * pln.XDirection(), gcDir * pln.YDirection()); + double gcAngle = gcDirProj.Angle( gp::DX2d() ); + foundSide = gcAngle < 0 ? angleOfSide.rbegin()->second : angleOfSide.begin()->second; + } } - gp_Vec gcDir( p1, gc ); - gp_Vec2d gcDirProj( gcDir * pln.XDirection(), gcDir * pln.YDirection()); - double gcAngle = gcDirProj.Angle( gp::DX2d() ); - foundSide = gcAngle < 0 ? angleOfSide.rbegin()->second : angleOfSide.begin()->second; _DUMP_(" selected "<< foundSide ); } @@ -759,9 +848,14 @@ namespace row2.push_back( n1 = oppositeNode( quad, i1 )); } + _NodeDescriptor nDesc( row1[1] ); + if ( nDesc == _NodeDescriptor( row1[0] )) + return true; // row of 2 nodes + // Find the rest nodes TIDSortedElemSet emptySet, avoidSet; - while ( !isCornerNode( n2 )) + //while ( !isCornerNode( n2 )) + while ( nDesc == _NodeDescriptor( n2 )) { avoidSet.clear(); avoidSet.insert( quad ); quad = SMESH_MeshEditor::FindFaceInSet( n1, n2, emptySet, avoidSet, &i1, &i2 ); @@ -804,7 +898,31 @@ namespace return SMDS_Mesh::FindFace(n1, n2, n3, n4 ); } -} + //================================================================================ + /*! + * \brief Checks own validity + */ + //================================================================================ + + bool _Block::isValid() const + { + bool ok = ( nbSides() == 6 ); + + // check only corners depending on side selection + EBoxSides adjacent[4] = { B_BOTTOM, B_RIGHT, B_TOP, B_LEFT }; + EQuadEdge edgeAdj [4] = { Q_TOP, Q_RIGHT, Q_TOP, Q_RIGHT }; + EQuadEdge edgeBack[4] = { Q_BOTTOM, Q_RIGHT, Q_TOP, Q_LEFT }; + + for ( int i=0; ok && i < NB_QUAD_SIDES; ++i ) + { + SMESH_OrientedLink eBack = _side[ B_BACK ].edge( edgeBack[i] ); + SMESH_OrientedLink eAdja = _side[ adjacent[i] ].edge( edgeAdj[i] ); + ok = ( eBack == eAdja ); + } + return ok; + } + +} // namespace //======================================================================= //function : StdMeshers_HexaFromSkin_3D diff --git a/src/StdMeshers/StdMeshers_Quadrangle_2D.cxx b/src/StdMeshers/StdMeshers_Quadrangle_2D.cxx index 5e2031c23..1c0cf5e5b 100644 --- a/src/StdMeshers/StdMeshers_Quadrangle_2D.cxx +++ b/src/StdMeshers/StdMeshers_Quadrangle_2D.cxx @@ -1483,6 +1483,9 @@ bool StdMeshers_Quadrangle_2D::ComputeQuadPref (SMESH_Mesh & aMesh, const vector& uv_et = quad->side[2]->GetUVPtStruct(true,1 ); const vector& uv_el = quad->side[3]->GetUVPtStruct(false,0); + if ( uv_eb.size() != nb || uv_er.size() != nr || uv_et.size() != nt || uv_el.size() != nl ) + return error( COMPERR_BAD_INPUT_MESH ); + // arrays for normalized params //cout<<"Dump B:"< #endif +#include +#include #include @@ -262,6 +264,15 @@ void StdMeshersGUI_DistrPreview::update() showError(); return; } +#ifdef WIN32 + if ( std::fabs(y[i]) >= HUGE_VAL) + y[i] = HUGE_VAL/100.; +#else + if ( isinf(y[i])) + y[i] = std::numeric_limits::max()/100.; +#endif +// if ( y[i] > 1e3 ) +// y[i] = 1e3; if( i==0 || y[i]max_y ) diff --git a/src/StdMeshersGUI/StdMeshers_images.ts b/src/StdMeshersGUI/StdMeshers_images.ts index fa4ca5767..da9130846 100644 --- a/src/StdMeshersGUI/StdMeshers_images.ts +++ b/src/StdMeshersGUI/StdMeshers_images.ts @@ -105,6 +105,14 @@ ICON_SMESH_TREE_ALGO_CompositeSegment_1D mesh_tree_algo_regular.png + + ICON_SMESH_TREE_ALGO_UseExisting_2D + mesh_tree_algo_existing_2D.png + + + ICON_SMESH_TREE_ALGO_UseExisting_1D + mesh_tree_algo_regular.png + ICON_SMESH_TREE_ALGO_Hexa_3D mesh_tree_algo_hexa.png @@ -129,6 +137,14 @@ ICON_SMESH_TREE_ALGO_Quadrangle_2D mesh_tree_algo_quad.png + + ICON_SMESH_TREE_ALGO_RadialQuadrangle_1D2D + mesh_tree_algo_radial_quadrangle_1D2D.png + + + ICON_SMESH_TREE_ALGO_Prism_3D + mesh_tree_algo_prism.png + ICON_SMESH_TREE_ALGO_RadialPrism_3D mesh_tree_algo_radial_prism.png @@ -139,7 +155,7 @@ ICON_SMESH_TREE_ALGO_SegmentAroundVertex_0D - mesh_tree_algo_regular.png + mesh_tree_algo_0D.png ICON_SMESH_TREE_HYPO_Arithmetic1D -- 2.39.2