Merge from V5_1_main 10/06/2010

This commit is contained in:
vsr 2010-06-10 09:43:07 +00:00
parent 9b95c5aa73
commit 3a40107689
85 changed files with 977 additions and 450 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 578 B

View File

@ -7,8 +7,6 @@
<li>\ref max_element_area_anchor "Max Element Area"</li> <li>\ref max_element_area_anchor "Max Element Area"</li>
<li>\ref length_from_edges_anchor "Length from Edges"</li> <li>\ref length_from_edges_anchor "Length from Edges"</li>
<li>\ref hypo_quad_params_anchor "Quadrangle parameters"</li> <li>\ref hypo_quad_params_anchor "Quadrangle parameters"</li>
<li>\ref quadrangle_preference_anchor "Quadrangle Preference"</li>
<li>\ref triangle_preference_anchor "Triangle Preference"</li>
</ul> </ul>
<br> <br>
@ -69,29 +67,5 @@ shows the good (left) and the bad (right) results of meshing.
<b>See Also</b> a sample TUI Script of a <b>See Also</b> a sample TUI Script of a
\ref tui_quadrangle_parameters "Quadrangle Parameters" hypothesis. \ref tui_quadrangle_parameters "Quadrangle Parameters" hypothesis.
\anchor quadrangle_preference_anchor
<h2>Quadrangle Preference</h2>
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.
<br>
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).
<br>
\anchor triangle_preference_anchor
<h2>Triangle Preference</h2>
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.
<br> <br>
*/ */

View File

@ -55,6 +55,8 @@ with other hypotheses:
<li>Propagation of 1D Hypothesis on opposite edges</li> <li>Propagation of 1D Hypothesis on opposite edges</li>
<li>Non conform mesh allowed</li> <li>Non conform mesh allowed</li>
<li>Quadratic mesh</li> <li>Quadratic mesh</li>
<li>Quadrangle preference</li>
<li>Triangle preference</li>
</ul> </ul>
The choice of a hypothesis depends on: The choice of a hypothesis depends on:

View File

@ -26,10 +26,25 @@ following associated submenu will appear:</li>
\image html image146.png \image html image146.png
From this submenu select the type of element which you would like to add to your mesh. 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 \note All dialogs for adding new node or element to the mesh (except for
(or to create the group if it doesn't exist). <b>Add to group</b> box allows to choose the dialog for 0D elements) provide a possibility to add it
an existing group for created node or element or to specify a name for new group. automatically to the specified group or to create it anew using
<b>Add to group</b> 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 <b>Add to group</b> 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
<b>Apply</b> or <b>Apply & Close</b> 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!
</ol> </ol>
<b>See Also</b> sample TUI Scripts of <b>See Also</b> sample TUI Scripts of

View File

@ -2,7 +2,7 @@
\page adding_quadratic_elements_page Adding Quadratic Elements \page adding_quadratic_elements_page Adding Quadratic Elements
\n MESH modules allows you to work with <b>Quadratic Elements</b>. \n MESH module allows you to work with <b>Quadratic Elements</b>.
Quadratic Edge is not a straight but a broken line and can be defined 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 by three points: first, middle and last. All more complex \b Quadratic
@ -18,10 +18,24 @@ one of the following:
\image html image152.png \image html image152.png
\note All dialogs intended for adding quadratic elements to mesh provide a possibility \note All dialogs for adding quadratic element to the mesh
to add these elements to the specified group (or to create the group if it doesn't exist). provide a possibility to add new element
<b>Add to group</b> box allows to choose an existing group for created element or automatically to the specified group or to create it anew using
to specify a name for new group. <b>Add to group</b> 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 <b>Add to group</b> 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
<b>Apply</b> or <b>Apply & Close</b> 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 <b>Quadratic Element</b> specify the nodes which will form your To create any <b>Quadratic Element</b> specify the nodes which will form your
triangle by selecting them in the 3D viewer with pressed Shift triangle by selecting them in the 3D viewer with pressed Shift

View File

@ -30,6 +30,28 @@ opposite edge will have the same hypothesis, unless another hypothesis
has been locally defined on the opposite edge. has been locally defined on the opposite edge.
<br><b>See Also</b> a sample TUI Script of a <br><b>See Also</b> a sample TUI Script of a
\ref tui_propagation "Propagation hypothesis" operation. \ref tui_propagation "Propagation hypothesis" operation
<h2>Quadrangle Preference</h2>
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.
<br>
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).
<h2>Triangle Preference</h2>
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.
*/ */

View File

@ -154,21 +154,20 @@ evaluation will be displayed in the following information box:
</li> </li>
</ol>
\anchor mesh_order_anchor \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.
<em>To change submesh priority:</em>
<ol>
<li>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 <li>
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.</li>
<em>To change submesh priority:</em>
<li>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: shape. The main Mesh object:
<ul> <ul>
<li><i>3D</i> <b>Tetrahedron (Netgen)</b> with Hypothesis<b>Max Element Volume</b></li> <li><i>3D</i> <b>Tetrahedron (Netgen)</b> with Hypothesis<b>Max Element Volume</b></li>
@ -189,51 +188,50 @@ is:
(Number of Segments = 8)</li> (Number of Segments = 8)</li>
</ul> </ul>
And the last third submesh object <b>Submesh_3</b> created on <b>Face_3</b> And the last submesh object <b>Submesh_3</b> created on <b>Face_3</b>
is: is:
<ul> <ul>
<li><i>2D</i> Netgen 1D-2D with Hypothesis <b>Netgen Simple parameters</b> <li><i>2D</i> Netgen 1D-2D with Hypothesis <b>Netgen Simple parameters</b>
(Number of Segments = 12)</li> (Number of Segments = 12)</li>
</ul> </ul>
The submeshes can become concurrent if their algorithms leads to mesh shared subshape The submeshes become concurrent if they share subshapes that can be meshed
with different algorithms (or different algorithms parameters, i.e. hypothesises). with different algorithms (or different hypothesises).
In fact, we have three submeshes with concurrent algorithms, because In the example, we have three submeshes with concurrent algorithms,
they have different hypothesises assigned to them. because they have different hypotheses.
The first mesh computation made with: The first mesh computation is made with:
\image html mesh_order_123.png \image html mesh_order_123.png
<center><em>"Mesh order SubMesh_1, SubMesh_2, SubMesh_3"</em></center> <center><em>"Mesh order SubMesh_1, SubMesh_2, SubMesh_3"</em></center>
\image html mesh_order_123_res.png \image html mesh_order_123_res.png
<center><em>"Result mesh with order SubMesh_1, SubMesh_2, SubMesh_3 "</em></center> <center><em>"Result mesh with order SubMesh_1, SubMesh_2, SubMesh_3 "</em></center>
The next mesh computation with: The next mesh computation is made with:
\image html mesh_order_213.png \image html mesh_order_213.png
<center><em>"Mesh order SubMesh_2, SubMesh_1, SubMesh_3"</em></center> <center><em>"Mesh order SubMesh_2, SubMesh_1, SubMesh_3"</em></center>
\image html mesh_order_213_res.png \image html mesh_order_213_res.png
<center><em>"Result mesh with order SubMesh_2, SubMesh_1, SubMesh_3 "</em></center> <center><em>"Result mesh with order SubMesh_2, SubMesh_1, SubMesh_3 "</em></center>
And the last mesh computation with: And the last mesh computation is made with:
\image html mesh_order_321.png \image html mesh_order_321.png
<center><em>"Mesh order SubMesh_3, SubMesh_2, SubMesh_1"</em></center> <center><em>"Mesh order SubMesh_3, SubMesh_2, SubMesh_1"</em></center>
\image html mesh_order_321_res.png \image html mesh_order_321_res.png
<center><em>"Result mesh with order SubMesh_3, SubMesh_2, SubMesh_1 "</em></center> <center><em>"Result mesh with order SubMesh_3, SubMesh_2, SubMesh_1 "</em></center>
As we can see each mesh computation has different number of result As we can see, each mesh computation has a different number of result
elements and different mesh discretisation on shared edges (edges elements and a different mesh discretisation on the shared edges (the edges
that are shared between <b>Face_1</b>, <b>Face_2</b> and <b>Face_3</b>) that are shared between <b>Face_1</b>, <b>Face_2</b> and <b>Face_3</b>)
Additionally, submesh priority (order of algorithms to be applied) can Additionally, submesh priority (the order of applied algorithms) can
be modified not only in separate dialog box, but in <b>Preview</b> be modified not only in a separate dialog box, but also in the
also. This helps to preview different mesh results, modifying submesh <b>Preview</b>. This helps to preview different mesh results,
order. modifying the order of submeshes.
\image html mesh_order_preview.png \image html mesh_order_preview.png
<center><em>"Preview with submesh priority list box"</em></center> <center><em>"Preview with submesh priority list box"</em></center>
If there are no concurrent submeshes under Mesh object, then user will see the If there are no concurrent submeshes under the Mesh object, the user will see the
following information dialog box following information.
\image html mesh_order_no_concurrent.png \image html mesh_order_no_concurrent.png
<center><em>"No concurrent submeshes detected"</em></center> <center><em>"No concurrent submeshes detected"</em></center>
and no mesh order list box will appear in Preview dialog box.
</ol> </ol>

View File

@ -23,7 +23,7 @@ elements which will form your group:</li>
SALOME Platform distinguishes between the two Group types: SALOME Platform distinguishes between the two Group types:
<b>Standalone Group</b> and <b>Group on Geometry</b>. <b>Standalone Group</b> and <b>Group on Geometry</b>.
<br><h2>Standalone Group</h2> \anchor standalone_group <br><h2>"Standalone Group"</h2>
<b>Standalone Group</b> consists of mesh elements, which you can define in <b>Standalone Group</b> consists of mesh elements, which you can define in
two possible ways. 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" \ref tui_create_standalone_group "Create a Standalone Group"
operation. operation.
<br><h2>Group on Geometry</h2> \anchor group_on_geom <br><h2>"Group on Geometry"</h2>
To create a group on geometry check <b>Group on geometry</b> in the \b Group To create a group on geometry check <b>Group on geometry</b> in the \b Group
\b type field. <b>Group on geometry</b> contains the elements of a certain type \b type field. <b>Group on geometry</b> contains the elements of a certain type

View File

@ -22,6 +22,7 @@ remove the elements forming it. For more information see
group.</li> group.</li>
</ol> </ol>
\anchor convert_to_standalone
<em>To convert an existing group on geometry into standalone group <em>To convert an existing group on geometry into standalone group
of elements and modify:</em> of elements and modify:</em>
<ol> <ol>

View File

@ -24,8 +24,8 @@ The following dialog box will appear:
<ul> <ul>
<li>the coordinates of the point;</li> <li>the coordinates of the point;</li>
<li>the type of elements to be found; it is also possible to find elements <li>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" of all types related to the reference point. Choose type "All" to find
means to find elements of any type except nodes and 0D elements.</li> elements of any type except for nodes and 0D elements.</li>
</ul> </ul>
</li> </li>

View File

@ -16,7 +16,8 @@ the VTK viewer;</li>
allowing to highlight important elements: allowing to highlight important elements:
<li>\subpage modifying_meshes_page "modifying meshes" with a vast <li>\subpage modifying_meshes_page "modifying meshes" with a vast
array of dedicated operations.</li> array of dedicated operations.</li>
<li>\subpage using_notebook_mesh_page.</li> <li>easily setting parameters via the variables predefined in
\subpage using_notebook_mesh_page "Salome notebook".</li>
</ul> </ul>
Almost all mesh module functionalities are accessible via Almost all mesh module functionalities are accessible via

View File

@ -8,32 +8,31 @@ selectable in the dialog box.
\image html mergeelems_ico.png "Merge elements button" \image html mergeelems_ico.png "Merge elements button"
<ol> <ol>
<li>From the \b Modification choose \b Transformation and from its <li>Choose in the main menu \b Modification -> \b Transformation -> <b>Merge elements</b> item. The following dialog box
sub-menu select the <b>Merge elements</b> item. The following dialog box
shall appear:</li> shall appear:</li>
\image html mergeelems_auto.png \image html mergeelems_auto.png
<br> <br>
<ul> <ul>
<li>\b Name is the name of the mesh whose elements will be merged.</li> <li>\b Name is the name of the mesh whose elements will be merged.</li>
<li>\b Automatic Mode or \b Manual Mode is to switch the dialog <li>\b Automatic or \b Manual Mode allows choosing how the elements
controls type. are processed.
</ul> </ul>
<li><b>Automatic mode:</b> <li><b>Automatic mode:</b>
<ul> <ul>
<li>In \b Automatic Mode the elements that were created on the same nodes will be merged.</li> <li>In the \b Automatic Mode the elements created on the same nodes will be merged.</li>
</ul> </ul>
</li> </li>
<li>If the \b Manual Mode is selected there are additional controls to <li>If the \b Manual Mode is selected, additional controls are
manage the elements to be merged in more detail: available:
\image html mergeelems.png \image html mergeelems.png
<br> <br>
<ul> <ul>
<li>\b Detect button generates the list of coincident elements for the given \b Tolerance.</li> <li>\b Detect button generates the list of coincident elements for the given \b Tolerance.</li>
<li><b>Coincident elements</b> is a list of groupes of elements for <li><b>Coincident elements</b> is a list of groups of elements for
merging. All elements of each group will form one after the operation. merging. All elements of each group will form one after the operation.
<ul> <ul>
<li>\b Remove button deletes the selected group from the list.</li> <li>\b Remove button deletes the selected group from the list.</li>

View File

@ -17,25 +17,24 @@ shall appear:</li>
<br> <br>
<ul> <ul>
<li>\b Name is the name of the mesh whose nodes will be merged.</li> <li>\b Name is the name of the mesh whose nodes will be merged.</li>
<li>\b Automatic Mode or \b Manual Mode is to switch the dialog <li>\b Automatic or \b Manual Mode allows choosing how the nodes are
controls type. processed.
<li>\b Tolerance is a maximum distance between nodes sufficient for <li>\b Tolerance is a maximum distance between nodes sufficient for
merging, that is able in both dialog modes.</li> merging.</li>
</ul> </ul>
<li><b>Automatic mode:</b> <li><b>Automatic mode:</b>
<br> <br>
<ul> <ul>
<li>In \b Automatic Mode to merge the Nodes, just input the tolerance <li>In the \b Automatic Mode all Nodes within the indicated tolerance
value and confirm by \b Apply button.</li> will be merged.</li>
</ul> </ul>
</li><br> </li><br>
<li>If the \b Manual Mode is selected there are additional controls to <li>If the \b Manual Mode is selected, additional controls are available:
manage the nodes to be merged in more detail:
<ul> <ul>
<li>\b Detect button generates the list of coincident nodes for the given <li>\b Detect button generates the list of coincident nodes for the given
\b Tolerance.</li> \b Tolerance.</li>
<li><b>Coincident nodes</b> is a list of groupes of nodes for <li><b>Coincident nodes</b> is a list of groups of nodes for
merging. All nodes of each group will form one after the merging. All nodes of each group will form one after the
operation. operation.
<ul> <ul>

View File

@ -23,7 +23,7 @@ the mesh or some of its elements.</li>
through a point or a vector of symmetry.</li> through a point or a vector of symmetry.</li>
<li>Unite meshes by \subpage sewing_meshes_page "sewing" free borders, <li>Unite meshes by \subpage sewing_meshes_page "sewing" free borders,
conform free borders, border to side or side elements.</li> conform free borders, border to side or side elements.</li>
<li>\subpage merging_nodes_page "Merge Notes", considered coincident <li>\subpage merging_nodes_page "Merge Nodes", considered coincident
within the indicated tolerance.</li> within the indicated tolerance.</li>
<li>\subpage merging_elements_page "Merge Elements", considered coincident <li>\subpage merging_elements_page "Merge Elements", considered coincident
within the indicated tolerance.</li> within the indicated tolerance.</li>

View File

@ -11,30 +11,83 @@ located at geometrical vertices. Pattern description is stored in
\<pattern_name\>.smp file. \<pattern_name\>.smp file.
The smp file contains 4 sections: The smp file contains 4 sections:
<ol>
<li>The first line holds the number of nodes (N).</li>
<li>The next N lines describe nodes coordinates. Each line holds 2 -# The first line holds the total number of the pattern nodes (N).
coordinates of a node.</li> -# The next N lines describe nodes coordinates. Each line holds 2
coordinates of a node for 2D pattern or 3 cordinates for 3D pattern.
<li>A key-points line: indices of nodes to be mapped on geometrical Note, that for 3D pattern only relateive values in range [0;1] are
vertices. An index n refers to a node described on an n-th line of valid for coordinates of the nodes.
section 2. The first node index is zero.</li> -# 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
<li>The rest lines describe nodal connectivity of elements, one line 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 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 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 2. The first node index is zero. There must be 3 or 4 indices on a
line: only 2d elements are allowed.</li> line for 2D pattern (only 2d elements are allowed) and 4, 5, 6 or 8
</ol> indices for 3D pattern (only 3d elements are allowed).
The 2D pattern must contain at least one element and at least one The 2D pattern must contain at least one element and at least one
key-point. All key-points must lay on boundaries. key-point. All key-points must lay on boundaries.
An example of a simple smp file and a preview of a pattern described The 3D pattern must contain at least one element.
in this file:
\image html image94.gif 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
<br><h2>Application of pattern mapping</h2> <br><h2>Application of pattern mapping</h2>
@ -50,72 +103,77 @@ The following dialog box shall appear:
\image html patternmapping1.png \image html patternmapping1.png
<center><b> 2D Pattern Mapping dialog box</b></center>
\image html patternmapping2.png \image html patternmapping2.png
<center><b> 3D Pattern Mapping dialog box</b></center>
To apply a pattern to a geometrical object, you should specify: To apply a pattern to a geometrical object, you should specify:
<ul>
<li>a face having the number of vertices equal to the number of -# 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 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 boundaries of a pattern must also be equal to the number of vertices
on internal boundaries of a face;</li> on internal boundaries of a face;
<li>a vertex to which the first key-point should be mapped;</li> - A vertex to which the first key-point should be mapped;
<li>reverse or not the order of key-points. (The order of vertices of - Reverse or not the order of key-points. (The order of vertices of
a face is counterclockwise looking from outside).</li> a face is counterclockwise looking from outside).
</ul> -# 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 Then you either load a .smp pattern file previously created manually
by clicking on the <em>"Load pattern"</em> button, or click on the \b by clicking on the <em>"Load pattern"</em> button, or click on the \b
New button for automatic generation. New button for automatic generation of the pattern.
\n For an automatic generation you just specify a geometrical face
having a mesh built on it. Mesh nodes lying on face vertices become For an automatic generation you just specify a geometrical face (for
key-points. Additionally, you may choose the way of getting nodes 2D) or solid (for 3d) having a mesh built on it. Mesh nodes lying on
coordinates by <b>projecting nodes on the face</b> instead of using face vertices become key-points of 2D pattern. Additionally, for 2D
pattern you may choose the way of getting nodes coordinates by
<b>projecting nodes on the face</b> instead of using
"positions on face" generated by mesher (if there is any). Faces "positions on face" generated by mesher (if there is any). Faces
having a seam edge can't be used for automatic pattern creation. having a seam edge can't be used for automatic pattern creation.
When creating a pattern from an existing mesh, there are two possible When creating a pattern from an existing mesh, there are two possible
cases: cases:
<ol>
<li>A sub-mesh on face is selected. A pattern is created from the 2d - A sub-mesh on face/solid is selected. A pattern is created from the 2d/3d
elements bound to a face by mesher. Node coordinates are either 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 "positions on face" computed by mesher, or coordinates got by node
projection on a geometrical surface, according to your choice.</li> projection on a geometrical surface, according to the user choice. For
<li>A mesh where the main shape is a face, is selected. A pattern is 3D pattern, nodes coordinates correspond to the nodes computed by mesher.
created from all the 2d elements in a mesh. If all mesh elements are - A mesh where the main shape is a face/solid, is selected. A pattern is
build by mesher, the user can select the way of getting nodes created from all the 2d/3d elements in a mesh. In addition, for 2D
coordinates, else all nodes are projected on a face surface.</li> pattern, if all mesh elements are build by mesher, the user can select
</ol> the way of getting nodes coordinates, else all nodes are projected on
a face surface.
\image html a-patterntype.png \image html a-patterntype.png
<center><b> 2D Pattern Creation dialog box</b></center>
\image html a-patterntype1.png \image html a-patterntype1.png
<center><b> 3D Pattern Creation dialog box</b></center>
<br><h2>Mapping algorithm</h2> <br><h2>Mapping algorithm</h2>
The mapping algorithm is as follows: The mapping algorithm for 2D case is as follows:
<ol>
<li>Key-points are set in the order that they are encountered when - 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 walking along a pattern boundary so that elements are on the left. The
first key-point is preserved. first key-point is preserved.
</li> - Find geometrical vertices corresponding to key-points by vertices
<li>Find geometrical vertices corresponding to key-points by vertices
order in a face boundary; here, "Reverse order of key-points" flag is order in a face boundary; here, "Reverse order of key-points" flag is
taken into account. taken into account. \image html image95.gif
- Boundary nodes of a pattern are mapped onto edges of a face: a
\image html image95.gif
</li>
<li>Boundary nodes of a pattern are mapped onto edges of a face: a
node located between certain key-points on a pattern boundary is node located between certain key-points on a pattern boundary is
mapped on a geometrical edge limited by corresponding geometrical mapped on a geometrical edge limited by corresponding geometrical
vertices. Node position on an edge reflects its distance from two vertices. Node position on an edge reflects its distance from two
key-points. key-points. \image html image96.gif
- Coordinates of a non-boundary node in a parametric space of a face
\image html image96.gif
</li>
<li>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 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 lays at the intersection of two iso-lines, each of which intersects a
pattern boundary at least at two points. Knowing mapped positions of pattern boundary at least at two points. Knowing mapped positions of
@ -123,13 +181,11 @@ boundary nodes, we find where isoline-boundary intersection points are
mapped to, and hence we can find mapped isolines direction and then, mapped to, and hence we can find mapped isolines direction and then,
two node positions on two mapped isolines. The eventual mapped two node positions on two mapped isolines. The eventual mapped
position of a node is found as an average of positions on mapped position of a node is found as an average of positions on mapped
isolines. isolines. \image html image97.gif
\image html image97.gif For 3D case the algorithm is similar.
</li>
</ol>
<br><b>See Also</b> a sample TUI Script of a <b>See Also</b> a sample TUI Script of a
\ref tui_pattern_mapping "Pattern Mapping" operation. \ref tui_pattern_mapping "Pattern Mapping" operation.
*/ */

View File

@ -9,7 +9,7 @@ shapes or by loading a custom texture from an external file.
- Standard point markers - Standard point markers
The Mesh module provides a set of predefined point marker shapes 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 Each standard point marker has two attributes: type (defines shape
form) and scale factor (defines shape size). 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. 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 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 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 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 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". lines in the file. Note that missing symbols are replaced by "0".

View File

@ -69,17 +69,17 @@ name in the adjacent box);</li>
<b>Example of using:</b> <b>Example of using:</b>
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 \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 \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 \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 \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 \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 \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 \image html scale09.png

View File

@ -23,7 +23,7 @@ The following dialog box will appear:
<li>The main list contains the list of volumes. You can click on <li>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 a volume in the 3D viewer and it will be highlighted (lock Shift
keyboard button to select several volumes). Click \b Add button and 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. <b>Sort selected element or elements from the list click \b Remove button. <b>Sort
list</b> button allows to sort the list of IDs. \b Filter button allows to list</b> button allows to sort the list of IDs. \b Filter button allows to
apply a definite filter to the selection of volumes. apply a definite filter to the selection of volumes.
@ -40,12 +40,12 @@ volumes of the currently displayed mesh or submesh.</li>
<li><b>Into 5 tetrahedra</b> and <b>Into 6 tetrahedra</b> allows to <li><b>Into 5 tetrahedra</b> and <b>Into 6 tetrahedra</b> allows to
specify the number of tetrahedra a hexahedron will be split into. If the specified method does 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 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.</li> 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.</li>
</ul> </ul>
</li> </li>
<li><b>Select from</b> set of fields allows to choose a submesh or an <li><b>Select from</b> a set of fields allows to choose a submesh or an
existing group whose elements will be automatically added to the existing group whose elements will be automatically added to the
list.</li> list.</li>
</ul> </ul>

View File

@ -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 # In this case it uses "Default Nb of Segments" preferences parameter to discretize edges
mesh.Compute() 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 # Define global hypotheses to discretize radial edges and a local one for circular edge
global_Nb_Segments = mesh.Segment().NumberOfSegments(5) global_Nb_Segments = mesh.Segment().NumberOfSegments(5)
local_Nb_Segments = mesh.Segment(circle).NumberOfSegments(10) local_Nb_Segments = mesh.Segment(circle).NumberOfSegments(10)

View File

@ -22,6 +22,26 @@ if new_id == 0: print "KO node addition."
else: print "New Node has been added with ID ", new_id else: print "New Node has been added with ID ", new_id
\endcode \endcode
<br>
\anchor tui_add_0DElement
<h3>Add 0D Element</h3>
\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
<br> <br>
\anchor tui_add_edge \anchor tui_add_edge
<h3>Add Edge</h3> <h3>Add Edge</h3>
@ -768,7 +788,6 @@ mesh.RotationSweepObject(GroupRotate, axisXYZ, angle45, 4, 1e-5)
\code \code
import geompy import geompy
import smesh import smesh
# define the geometry # define the geometry
@ -802,17 +821,100 @@ algo2D.MaxElementArea(240)
isDone = Mesh_2.Compute() isDone = Mesh_2.Compute()
if not isDone: print 'Mesh Mesh_2 : computation failed' if not isDone: print 'Mesh Mesh_2 : computation failed'
# create a pattern # create a 2d pattern
pattern = smesh.GetPattern() pattern = smesh.GetPattern()
isDone = pattern.LoadFromFace(Mesh_2.GetMesh(), Face_2, 0) isDone = pattern.LoadFromFace(Mesh_2.GetMesh(), Face_2, 0)
if (isDone != 1): print 'LoadFromFace :', pattern.GetErrorCode() if (isDone != 1): print 'LoadFromFace :', pattern.GetErrorCode()
# apply the pattern to a face of the first mesh # 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) isDone = pattern.MakeMesh(Mesh_1.GetMesh(), 0, 0)
if (isDone != 1): print 'MakeMesh :', pattern.GetErrorCode() 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 \endcode
<br> <br>

View File

@ -62,16 +62,16 @@ Nb_Segments_1.SetDistrType( 0 )
Quadrangle_2D = Mesh1.Quadrangle() Quadrangle_2D = Mesh1.Quadrangle()
isDone = Mesh1.Compute() 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") 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) 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) 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) Mesh1.Scale([21],SMESH.PointStruct(0,200,200),[0.7,0.7,0.7],False)
\endcode \endcode

View File

@ -37,9 +37,9 @@ Faces, Edges or both.</li>
<li><b>2D Quadratic</b> - allows to select between the representation <li><b>2D Quadratic</b> - allows to select between the representation
of quadratic edges as broken <b>lines</b> or as <b>arcs</b></li> of quadratic edges as broken <b>lines</b> or as <b>arcs</b></li>
<li><b>Orientation of faces</b> - shows vectors of orientation of <li><b>Orientation of faces</b> - shows vectors of orientation of
faces of the selected mesh. Vector is shown for each 2D mesh element faces of the selected mesh. The orientation vector is shown for each 2D mesh element
and for each free face of 3D mesh element. Vector direction is calculated by and for each free face of a 3D mesh element. the vector direction is calculated by
the first three nodes of face as a cross product of vectors n1-n2 and n1-n3.</li> the first three nodes of the face produced by vectors n1-n2 and n1-n3.</li>
<li>\subpage colors_size_page "Colors / Size" - allows to select color and size of <li>\subpage colors_size_page "Colors / Size" - allows to select color and size of
meshes.</li> meshes.</li>
<li>\subpage transparency_page "Transparency" - allows to change the <li>\subpage transparency_page "Transparency" - allows to change the

View File

@ -80,6 +80,7 @@ dist_salomeres_DATA = \
mesh_tree_algo_hexa.png \ mesh_tree_algo_hexa.png \
mesh_tree_algo_mefisto.png \ mesh_tree_algo_mefisto.png \
mesh_tree_algo.png \ mesh_tree_algo.png \
mesh_tree_algo_0D.png \
mesh_tree_algo_quad.png \ mesh_tree_algo_quad.png \
mesh_tree_algo_regular.png \ mesh_tree_algo_regular.png \
mesh_tree_algo_tetra.png \ mesh_tree_algo_tetra.png \
@ -149,6 +150,9 @@ dist_salomeres_DATA = \
mesh_conv_to_quad.png \ mesh_conv_to_quad.png \
mesh_tree_hypo_layers_distribution.png \ mesh_tree_hypo_layers_distribution.png \
mesh_tree_algo_radial_prism.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_tree_algo_projection_2d.png \
mesh_hypo_source_edge.png \ mesh_hypo_source_edge.png \
mesh_hypo_source_3d.png \ mesh_hypo_source_3d.png \

View File

@ -99,7 +99,7 @@
<parameter name="NETGENPlugin" value="${NETGENPlugin_ROOT_DIR}/share/salome/resources/netgenplugin"/> <parameter name="NETGENPlugin" value="${NETGENPlugin_ROOT_DIR}/share/salome/resources/netgenplugin"/>
<parameter name="GHS3DPlugin" value="${GHS3DPlugin_ROOT_DIR}/share/salome/resources/ghs3dplugin"/> <parameter name="GHS3DPlugin" value="${GHS3DPlugin_ROOT_DIR}/share/salome/resources/ghs3dplugin"/>
<parameter name="BLSURFPlugin" value="${BLSURFPlugin_ROOT_DIR}/share/salome/resources"/> <parameter name="BLSURFPlugin" value="${BLSURFPlugin_ROOT_DIR}/share/salome/resources"/>
<parameter name="HexoticPLUGIN" value="${HexoticPlugin_ROOT_DIR}/share/salome/resources"/> <parameter name="HexoticPlugin" value="${HexoticPLUGIN_ROOT_DIR}/share/salome/resources/hexoticplugin"/>
<parameter name="GHS3DPRLPlugin" value="${GHS3DPRLPLUGIN_ROOT_DIR}/share/salome/resources"/> <parameter name="GHS3DPRLPlugin" value="${GHS3DPRLPLUGIN_ROOT_DIR}/share/salome/resources"/>
</section> </section>
</document> </document>

Binary file not shown.

After

Width:  |  Height:  |  Size: 253 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 270 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 314 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 338 B

View File

@ -9056,7 +9056,7 @@ void SMESH_MeshEditor::ConvertToQuadratic(const bool theForce3d)
ReplaceElemInGroups(volume, NewVolume, meshDS); ReplaceElemInGroups(volume, NewVolume, meshDS);
} }
} }
if ( !theForce3d ) { if ( !theForce3d && !getenv("NO_FixQuadraticElements")) {
aHelper.SetSubShape(0); // apply to the whole mesh aHelper.SetSubShape(0); // apply to the whole mesh
aHelper.FixQuadraticElements(); aHelper.FixQuadraticElements();
} }

View File

@ -597,23 +597,43 @@ gp_XY SMESH_MesherHelper::GetMiddleUV(const Handle(Geom_Surface)& surface,
double SMESH_MesherHelper::GetNodeU(const TopoDS_Edge& E, double SMESH_MesherHelper::GetNodeU(const TopoDS_Edge& E,
const SMDS_MeshNode* n, const SMDS_MeshNode* n,
const SMDS_MeshNode* inEdgeNode,
bool* check) bool* check)
{ {
double param = 0; double param = 0;
const SMDS_PositionPtr Pos = n->GetPosition(); const SMDS_PositionPtr pos = n->GetPosition();
if(Pos->GetTypeOfPosition()==SMDS_TOP_EDGE) { if ( pos->GetTypeOfPosition()==SMDS_TOP_EDGE )
const SMDS_EdgePosition* epos = {
static_cast<const SMDS_EdgePosition*>(n->GetPosition().get()); const SMDS_EdgePosition* epos = static_cast<const SMDS_EdgePosition*>( pos.get() );
param = epos->GetUParameter(); param = epos->GetUParameter();
} }
else if(Pos->GetTypeOfPosition()==SMDS_TOP_VERTEX) { 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(); SMESHDS_Mesh * meshDS = GetMeshDS();
int vertexID = n->GetPosition()->GetShapeId(); int vertexID = pos->GetShapeId();
const TopoDS_Vertex& V = TopoDS::Vertex(meshDS->IndexToShape(vertexID)); const TopoDS_Vertex& V = TopoDS::Vertex(meshDS->IndexToShape(vertexID));
param = BRep_Tool::Parameter( V, E ); param = BRep_Tool::Parameter( V, E );
} }
}
if ( check ) 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; return param;
} }
@ -667,6 +687,20 @@ bool SMESH_MesherHelper::CheckNodeU(const TopoDS_Edge& E,
{ {
((SMESH_MesherHelper*) this)->myOkNodePosShapes.insert( n->GetPosition()->GetShapeId() ); ((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; return true;
@ -739,8 +773,8 @@ const SMDS_MeshNode* SMESH_MesherHelper::GetMediumNode(const SMDS_MeshNode* n1,
E = TopoDS::Edge(myShape); E = TopoDS::Edge(myShape);
edgeID = myShapeID; edgeID = myShapeID;
} }
u[0] = GetNodeU(E,n1, force3d ? 0 : &uvOK[0]); u[0] = GetNodeU(E,n1,n2, force3d ? 0 : &uvOK[0]);
u[1] = GetNodeU(E,n2, force3d ? 0 : &uvOK[1]); u[1] = GetNodeU(E,n2,n1, force3d ? 0 : &uvOK[1]);
} }
if(!force3d) if(!force3d)
{ {

View File

@ -269,6 +269,7 @@ public:
*/ */
double GetNodeU(const TopoDS_Edge& theEdge, double GetNodeU(const TopoDS_Edge& theEdge,
const SMDS_MeshNode* theNode, const SMDS_MeshNode* theNode,
const SMDS_MeshNode* inEdgeNode=0,
bool* check=0); bool* check=0);
/*! /*!
* \brief Return node UV on face * \brief Return node UV on face

View File

@ -73,6 +73,7 @@
#include "SMESH_MesherHelper.hxx" #include "SMESH_MesherHelper.hxx"
#include "SMESH_subMesh.hxx" #include "SMESH_subMesh.hxx"
#include <Basics_Utils.hxx>
#include "utilities.h" #include "utilities.h"
using namespace std; using namespace std;
@ -210,6 +211,8 @@ bool SMESH_Pattern::Load (const char* theFileContents)
{ {
MESSAGE("Load( file ) "); MESSAGE("Load( file ) ");
Kernel_Utils::Localizer loc;
// file structure: // file structure:
// ! This is a comment // ! This is a comment
@ -353,6 +356,9 @@ bool SMESH_Pattern::Load (const char* theFileContents)
bool SMESH_Pattern::Save (ostream& theFile) bool SMESH_Pattern::Save (ostream& theFile)
{ {
MESSAGE(" ::Save(file) " ); MESSAGE(" ::Save(file) " );
Kernel_Utils::Localizer loc;
if ( !IsLoaded() ) { if ( !IsLoaded() ) {
MESSAGE(" Pattern not loaded "); MESSAGE(" Pattern not loaded ");
return setErrorCode( ERR_SAVE_NOT_LOADED ); return setErrorCode( ERR_SAVE_NOT_LOADED );

View File

@ -1483,6 +1483,22 @@ SalomeApp_Study* SMESHGUI::activeStudy()
return NULL; return NULL;
} }
//=============================================================================
/*!
*
*/
//=============================================================================
void SMESHGUI::Modified( bool theIsUpdateActions )
{
if( SalomeApp_Application* app = dynamic_cast<SalomeApp_Application*>( SUIT_Session::session()->activeApplication() ) ) {
if( SalomeApp_Study* appStudy = dynamic_cast<SalomeApp_Study*>( app->activeStudy() ) ) {
appStudy->Modified();
if( theIsUpdateActions )
app->updateActions();
}
}
}
//============================================================================= //=============================================================================
/*! /*!
* *
@ -3845,8 +3861,8 @@ void SMESHGUI::createPreferences()
// Set property for precision value for spinboxes // Set property for precision value for spinboxes
for ( ii = 0; ii < nbQuantities; ii++ ){ for ( ii = 0; ii < nbQuantities; ii++ ){
setPreferenceProperty( precs[ii], "min", -10 ); setPreferenceProperty( precs[ii], "min", -14 );
setPreferenceProperty( precs[ii], "max", 10 ); setPreferenceProperty( precs[ii], "max", 14 );
setPreferenceProperty( precs[ii], "precision", 2 ); 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 ) void SMESHGUI::onHypothesisEdit( int result )
{ {
if( result == 1 )
SMESHGUI::Modified();
updateObjBrowser( true ); updateObjBrowser( true );
} }

View File

@ -79,6 +79,8 @@ public :
static bool automaticUpdate(); static bool automaticUpdate();
static void Modified( bool = true );
virtual LightApp_Displayer* displayer(); virtual LightApp_Displayer* displayer();
virtual QString engineIOR() const; virtual QString engineIOR() const;
virtual void initialize( CAM_Application* ); virtual void initialize( CAM_Application* );

View File

@ -447,6 +447,7 @@ void SMESHGUI_AddMeshElementDlg::Init()
connect(mySelectionMgr, SIGNAL(currentSelectionChanged()), SLOT(SelectionIntoArgument())); connect(mySelectionMgr, SIGNAL(currentSelectionChanged()), SLOT(SelectionIntoArgument()));
/* to close dialog if study frame change */ /* to close dialog if study frame change */
connect(mySMESHGUI, SIGNAL (SignalStudyFrameChanged()), SLOT(ClickOnCancel())); connect(mySMESHGUI, SIGNAL (SignalStudyFrameChanged()), SLOT(ClickOnCancel()));
connect(mySMESHGUI, SIGNAL (SignalCloseAllDialogs()), SLOT(ClickOnCancel()));
if (Reverse) if (Reverse)
connect(Reverse, SIGNAL(stateChanged(int)), SLOT(CheckBox(int))); connect(Reverse, SIGNAL(stateChanged(int)), SLOT(CheckBox(int)));
@ -570,6 +571,8 @@ void SMESHGUI_AddMeshElementDlg::ClickOnApply()
myEditCurrentArgument->setText(""); myEditCurrentArgument->setText("");
myBusy = false; myBusy = false;
SMESHGUI::Modified();
} }
} }

View File

@ -666,6 +666,7 @@ void SMESHGUI_AddQuadraticElementDlg::Init()
connect(mySMESHGUI, SIGNAL (SignalDeactivateActiveDialog()), SLOT(DeactivateActiveDialog())); connect(mySMESHGUI, SIGNAL (SignalDeactivateActiveDialog()), SLOT(DeactivateActiveDialog()));
connect(mySMESHGUI, SIGNAL (SignalStudyFrameChanged()), SLOT(ClickOnCancel())); connect(mySMESHGUI, SIGNAL (SignalStudyFrameChanged()), SLOT(ClickOnCancel()));
connect(mySMESHGUI, SIGNAL (SignalCloseAllDialogs()), SLOT(ClickOnCancel()));
// set selection mode // set selection mode
SMESH::SetPointRepresentation(true); SMESH::SetPointRepresentation(true);
@ -806,6 +807,8 @@ void SMESHGUI_AddQuadraticElementDlg::ClickOnApply()
SetEditCorners(); SetEditCorners();
updateButtons(); updateButtons();
SMESHGUI::Modified();
} }
//================================================================================= //=================================================================================

View File

@ -331,6 +331,8 @@ bool SMESHGUI_BuildCompoundDlg::ClickOnApply()
SMESH::DisplayActor(SMESH::GetActiveWindow(), anActor); SMESH::DisplayActor(SMESH::GetActiveWindow(), anActor);
}// end IPAL21468 }// end IPAL21468
SMESHGUI::Modified();
return true; return true;
} }
return false; return false;

View File

@ -27,6 +27,7 @@
// //
#include "SMESHGUI_ConvToQuadOp.h" #include "SMESHGUI_ConvToQuadOp.h"
#include "SMESHGUI.h"
#include "SMESHGUI_ConvToQuadDlg.h" #include "SMESHGUI_ConvToQuadDlg.h"
#include "SMESHGUI_Utils.h" #include "SMESHGUI_Utils.h"
@ -234,6 +235,7 @@ bool SMESHGUI_ConvToQuadOp::onApply()
} }
if( aResult ) if( aResult )
{ {
SMESHGUI::Modified();
update( UF_ObjBrowser | UF_Model | UF_Viewer ); update( UF_ObjBrowser | UF_Model | UF_Viewer );
selectionDone(); selectionDone();
} }

View File

@ -574,6 +574,8 @@ void SMESHGUI_CreatePolyhedralVolumeDlg::ClickOnApply()
} }
//ConstructorsClicked( GetConstructorId() ); //ConstructorsClicked( GetConstructorId() );
busy = false; busy = false;
SMESHGUI::Modified();
} }
} }

View File

@ -219,6 +219,7 @@ bool SMESHGUI_DeleteGroupDlg::onApply()
myListGrp.clear(); myListGrp.clear();
mySelectionMgr->clearSelected(); mySelectionMgr->clearSelected();
SMESH::UpdateView(); SMESH::UpdateView();
SMESHGUI::Modified();
mySMESHGUI->updateObjBrowser(true); mySMESHGUI->updateObjBrowser(true);
myBlockSelection = false; myBlockSelection = false;

View File

@ -672,6 +672,7 @@ bool SMESHGUI_EditMeshDlg::ClickOnApply()
} }
SMESH::UpdateView(); SMESH::UpdateView();
SMESHGUI::Modified();
return true; return true;
} }

View File

@ -167,6 +167,7 @@ SMESHGUI_ExtrusionAlongPathDlg::SMESHGUI_ExtrusionAlongPathDlg( SMESHGUI* theMod
ElementsLineEdit = new QLineEdit(GroupArguments); ElementsLineEdit = new QLineEdit(GroupArguments);
ElementsLineEdit->setValidator(myIdValidator); ElementsLineEdit->setValidator(myIdValidator);
ElementsLineEdit->setMaxLength(-1);
myFilterBtn = new QPushButton( tr( "SMESH_BUT_FILTER" ), GroupArguments ); myFilterBtn = new QPushButton( tr( "SMESH_BUT_FILTER" ), GroupArguments );
connect(myFilterBtn, SIGNAL(clicked()), this, SLOT(setFilters())); connect(myFilterBtn, SIGNAL(clicked()), this, SLOT(setFilters()));
@ -671,6 +672,8 @@ bool SMESHGUI_ExtrusionAlongPathDlg::ClickOnApply()
if ( myMeshActor ) if ( myMeshActor )
SMESH::Update( myMeshActor->getIO(), myMeshActor->GetVisibility() ); SMESH::Update( myMeshActor->getIO(), myMeshActor->GetVisibility() );
SMESHGUI::Modified();
if ( MakeGroupsCheck->isEnabled() && MakeGroupsCheck->isChecked() ) if ( MakeGroupsCheck->isEnabled() && MakeGroupsCheck->isChecked() )
mySMESHGUI->updateObjBrowser(true); // new groups may appear mySMESHGUI->updateObjBrowser(true); // new groups may appear
//SMESH::UpdateView(); //SMESH::UpdateView();

View File

@ -165,6 +165,7 @@ SMESHGUI_ExtrusionDlg::SMESHGUI_ExtrusionDlg (SMESHGUI* theModule)
LineEditElements = new QLineEdit(GroupArguments); LineEditElements = new QLineEdit(GroupArguments);
LineEditElements->setValidator(myIdValidator); LineEditElements->setValidator(myIdValidator);
LineEditElements->setMaxLength(-1);
myFilterBtn = new QPushButton( tr( "SMESH_BUT_FILTER" ), GroupArguments ); myFilterBtn = new QPushButton( tr( "SMESH_BUT_FILTER" ), GroupArguments );
connect(myFilterBtn, SIGNAL(clicked()), this, SLOT(setFilters())); connect(myFilterBtn, SIGNAL(clicked()), this, SLOT(setFilters()));
@ -572,6 +573,8 @@ bool SMESHGUI_ExtrusionDlg::ClickOnApply()
mySelectionMgr->clearSelected(); mySelectionMgr->clearSelected();
mySelectedObject = SMESH::SMESH_IDSource::_nil(); mySelectedObject = SMESH::SMESH_IDSource::_nil();
SelectionIntoArgument(); SelectionIntoArgument();
SMESHGUI::Modified();
} }
return true; return true;
} }

View File

@ -2517,31 +2517,18 @@ void SMESHGUI_FilterDlg::setIdsToWg (QWidget* theWg, const QList<int>& theIds)
if (theWg == 0) if (theWg == 0)
return; return;
QStringList aStrList;
foreach(int id, theIds)
aStrList << QString::number(id);
if (theWg->inherits("QListWidget")) if (theWg->inherits("QListWidget"))
{ {
QListWidget* aListBox = qobject_cast<QListWidget*>( theWg ); qobject_cast<QListWidget*>(theWg)->clear();
aListBox->clear(); qobject_cast<QListWidget*>(theWg)->addItems(aStrList);
QStringList aStrList;
QList<int>::const_iterator anIter;
for (anIter = theIds.begin(); anIter != theIds.end(); ++anIter)
aStrList.append(QString("%1").arg(*anIter));
aListBox->addItems(aStrList);
} }
else if (theWg->inherits("QLineEdit")) else if (theWg->inherits("QLineEdit"))
{ {
QLineEdit* aLineEdit = qobject_cast<QLineEdit*>( theWg ); qobject_cast<QLineEdit*>( theWg )->setText(aStrList.join(" "));
QString aStr;
QList<int>::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);
} }
} }
@ -2987,14 +2974,12 @@ void SMESHGUI_FilterDlg::onSelectionDone()
} }
} }
int aCriterionType = myTable->GetCriterionType(aRow); QList<int> types;
if (aList.Extent() != 1 || types << SMESH::FT_BelongToGeom << SMESH::FT_BelongToPlane
!myTable->CurrentCell(aRow, aCol) || << SMESH::FT_BelongToCylinder << SMESH::FT_BelongToGenSurface
aCriterionType != SMESH::FT_BelongToGeom && << SMESH::FT_LyingOnGeom;
aCriterionType != SMESH::FT_BelongToPlane && if (aList.Extent() != 1 || !myTable->CurrentCell(aRow, aCol) ||
aCriterionType != SMESH::FT_BelongToCylinder && !types.contains(myTable->GetCriterionType(aRow)))
aCriterionType != SMESH::FT_BelongToGenSurface &&
aCriterionType != SMESH::FT_LyingOnGeom)
return; return;
Handle(SALOME_InteractiveObject) anIO = aList.First(); Handle(SALOME_InteractiveObject) anIO = aList.First();

View File

@ -852,6 +852,7 @@ bool SMESHGUI_GroupDlg::onApply()
} }
} }
SMESHGUI::Modified();
mySMESHGUI->updateObjBrowser(true); mySMESHGUI->updateObjBrowser(true);
SMESH::UpdateView(); // asv: fix of BUG PAL5515 SMESH::UpdateView(); // asv: fix of BUG PAL5515
mySelectionMgr->clearSelected(); mySelectionMgr->clearSelected();
@ -957,6 +958,7 @@ bool SMESHGUI_GroupDlg::onApply()
} }
} }
SMESHGUI::Modified();
mySMESHGUI->updateObjBrowser(true); mySMESHGUI->updateObjBrowser(true);
mySelectionMgr->clearSelected(); mySelectionMgr->clearSelected();
return true; return true;

View File

@ -27,6 +27,7 @@
#include "SMESHGUI_GroupOnShapeDlg.h" #include "SMESHGUI_GroupOnShapeDlg.h"
#include "SMESH_TypeFilter.hxx" #include "SMESH_TypeFilter.hxx"
#include "SMESHGUI.h"
#include "SMESHGUI_Utils.h" #include "SMESHGUI_Utils.h"
#include "SMESHGUI_GEOMGenUtils.h" #include "SMESHGUI_GEOMGenUtils.h"
@ -347,6 +348,8 @@ bool SMESHGUI_GroupOnShapeOp::onApply()
group = mesh->CreateGroupFromGEOM( elemType, name.toLatin1().data(), geom ); group = mesh->CreateGroupFromGEOM( elemType, name.toLatin1().data(), geom );
} }
} }
SMESHGUI::Modified();
update( UF_ObjBrowser | UF_Model ); update( UF_ObjBrowser | UF_Model );
init(); init();

View File

@ -604,6 +604,7 @@ bool SMESHGUI_UnionGroupsDlg::onApply()
if ( aRes ) if ( aRes )
{ {
SMESHGUI::Modified();
getSMESHGUI()->updateObjBrowser(true); getSMESHGUI()->updateObjBrowser(true);
reset(); reset();
return true; return true;
@ -706,6 +707,7 @@ bool SMESHGUI_IntersectGroupsDlg::onApply()
if ( aRes ) if ( aRes )
{ {
SMESHGUI::Modified();
getSMESHGUI()->updateObjBrowser(true); getSMESHGUI()->updateObjBrowser(true);
reset(); reset();
return true; return true;
@ -872,6 +874,7 @@ bool SMESHGUI_CutGroupsDlg::onApply()
if ( aRes ) if ( aRes )
{ {
SMESHGUI::Modified();
getSMESHGUI()->updateObjBrowser(true); getSMESHGUI()->updateObjBrowser(true);
reset(); reset();
return true; return true;
@ -1023,6 +1026,7 @@ bool SMESHGUI_DimGroupDlg::onApply()
if ( aRes ) if ( aRes )
{ {
SMESHGUI::Modified();
getSMESHGUI()->updateObjBrowser(true); getSMESHGUI()->updateObjBrowser(true);
reset(); reset();
return true; return true;

View File

@ -122,6 +122,7 @@ void SMESHGUI_GenericHypothesisCreator::editHypothesis( SMESH::SMESH_Hypothesis_
SMESHGUI_HypothesisDlg* Dlg = new SMESHGUI_HypothesisDlg( this, theParent ); SMESHGUI_HypothesisDlg* Dlg = new SMESHGUI_HypothesisDlg( this, theParent );
connect( Dlg, SIGNAL( finished( int ) ), this, SLOT( onDialogFinished( int ) ) ); connect( Dlg, SIGNAL( finished( int ) ), this, SLOT( onDialogFinished( int ) ) );
connect( this, SIGNAL( finished( int ) ), obj, slot.toLatin1().constData() ); connect( this, SIGNAL( finished( int ) ), obj, slot.toLatin1().constData() );
connect( SMESHGUI::GetSMESHGUI(), SIGNAL( SignalCloseAllDialogs() ), Dlg, SLOT( reject() ));
myDlg = Dlg; myDlg = Dlg;
QFrame* fr = buildFrame(); QFrame* fr = buildFrame();

View File

@ -414,6 +414,7 @@ namespace SMESH
if (aHypSObject) { if (aHypSObject) {
if (!aHypName.isEmpty()) if (!aHypName.isEmpty())
SMESH::SetName(aHypSObject, aHypName); SMESH::SetName(aHypSObject, aHypName);
SMESHGUI::Modified();
SMESHGUI::GetSMESHGUI()->updateObjBrowser(); SMESHGUI::GetSMESHGUI()->updateObjBrowser();
return aHypothesis._retn(); return aHypothesis._retn();
} }

View File

@ -233,6 +233,7 @@ void SMESHGUI_Make2DFrom3DOp::startOperation()
myDlg->SetMeshInfo( aNewInfo ); myDlg->SetMeshInfo( aNewInfo );
myDlg->show(); /*exec();*/ myDlg->show(); /*exec();*/
commit(); commit();
SMESHGUI::Modified();
} }
//================================================================================ //================================================================================

View File

@ -424,6 +424,7 @@ bool SMESHGUI_MakeNodeAtPointOp::onApply()
aList.Append(myMeshActor->getIO()); aList.Append(myMeshActor->getIO());
selectionMgr()->setSelectedObjects(aList,false); selectionMgr()->setSelectedObjects(aList,false);
SMESH::UpdateView(); SMESH::UpdateView();
SMESHGUI::Modified();
} }
} }
catch (const SALOME::SALOME_Exception& S_ex) { catch (const SALOME::SALOME_Exception& S_ex) {

View File

@ -150,8 +150,11 @@ bool SMESHGUI_MeshOp::onApply()
else if ( !myToCreate ) else if ( !myToCreate )
aResult = editMeshOrSubMesh( aMess ); aResult = editMeshOrSubMesh( aMess );
if ( aResult ) if ( aResult )
{
SMESHGUI::Modified();
update( UF_ObjBrowser | UF_Model ); update( UF_ObjBrowser | UF_Model );
} }
}
catch ( const SALOME::SALOME_Exception& S_ex ) catch ( const SALOME::SALOME_Exception& S_ex )
{ {
SalomeApp_Tools::QtCatchCorbaException( S_ex ); SalomeApp_Tools::QtCatchCorbaException( S_ex );

View File

@ -138,6 +138,9 @@ bool SMESHGUI_MeshOrderOp::onApply()
SUIT_OverrideCursor aWaitCursor; SUIT_OverrideCursor aWaitCursor;
bool res = myMgr ? myMgr->SetMeshOrder() : false; bool res = myMgr ? myMgr->SetMeshOrder() : false;
if( res )
SMESHGUI::Modified();
delete myMgr; delete myMgr;
myMgr = 0; myMgr = 0;

View File

@ -510,6 +510,7 @@ bool SMESHGUI_MeshPatternDlg::onApply()
} }
mySelectionMgr->clearSelected(); mySelectionMgr->clearSelected();
SMESH::UpdateView(); SMESH::UpdateView();
SMESHGUI::Modified();
mySMESHGUI->updateObjBrowser(true); mySMESHGUI->updateObjBrowser(true);

View File

@ -356,6 +356,7 @@ bool SMESHGUI_MoveNodesDlg::onApply()
aList.Append(myMeshActor->getIO()); aList.Append(myMeshActor->getIO());
mySelectionMgr->setSelectedObjects(aList,false); mySelectionMgr->setSelectedObjects(aList,false);
SMESH::UpdateView(); SMESH::UpdateView();
SMESHGUI::Modified();
reset(); reset();
} }

View File

@ -1052,6 +1052,7 @@ bool SMESHGUI_MultiEditDlg::onApply()
mySelector->ClearIndex(); mySelector->ClearIndex();
mySelectionMgr->setSelectedObjects( sel ); mySelectionMgr->setSelectedObjects( sel );
SMESH::UpdateView(); SMESH::UpdateView();
SMESHGUI::Modified();
} }
myListBox->clear(); myListBox->clear();

View File

@ -379,6 +379,7 @@ void SMESHGUI_NodesDlg::Init()
connect( mySMESHGUI, SIGNAL( SignalDeactivateActiveDialog() ), SLOT( DeactivateActiveDialog() ) ); connect( mySMESHGUI, SIGNAL( SignalDeactivateActiveDialog() ), SLOT( DeactivateActiveDialog() ) );
/* to close dialog if study frame change */ /* to close dialog if study frame change */
connect( mySMESHGUI, SIGNAL( SignalStudyFrameChanged() ), SLOT( ClickOnCancel() ) ); connect( mySMESHGUI, SIGNAL( SignalStudyFrameChanged() ), SLOT( ClickOnCancel() ) );
connect(mySMESHGUI, SIGNAL(SignalCloseAllDialogs()), SLOT(ClickOnCancel()));
// set selection mode // set selection mode
SMESH::SetPointRepresentation( true ); SMESH::SetPointRepresentation( true );
@ -526,6 +527,9 @@ bool SMESHGUI_NodesDlg::ClickOnApply()
} }
} }
} }
SMESHGUI::Modified();
return true; return true;
} }

View File

@ -33,8 +33,12 @@
// SALOME GUI includes // SALOME GUI includes
#include <SUIT_Desktop.h> #include <SUIT_Desktop.h>
#include <SUIT_MessageBox.h>
#include <SUIT_ResourceMgr.h>
#include <SUIT_Session.h>
#include <QtxColorButton.h> #include <QtxColorButton.h>
#include <VTKViewer_MarkerWidget.h> #include <VTKViewer_MarkerWidget.h>
#include <LightApp_Application.h>
#include <SalomeApp_IntSpinBox.h> #include <SalomeApp_IntSpinBox.h>
// Qt includes // Qt includes
@ -45,6 +49,7 @@
#include <QHBoxLayout> #include <QHBoxLayout>
#include <QGridLayout> #include <QGridLayout>
#include <QCheckBox> #include <QCheckBox>
#include <QKeyEvent>
#define SPACING 6 #define SPACING 6
#define MARGIN 11 #define MARGIN 11
@ -186,10 +191,14 @@ SMESHGUI_Preferences_ColorDlg::SMESHGUI_Preferences_ColorDlg( SMESHGUI* theModul
QPushButton* buttonCancel = new QPushButton( tr( "&Cancel" ), GroupButtons ); QPushButton* buttonCancel = new QPushButton( tr( "&Cancel" ), GroupButtons );
buttonCancel->setAutoDefault( true ); buttonCancel->setAutoDefault( true );
QPushButton* buttonHelp = new QPushButton( tr( "&Help" ), GroupButtons );
buttonHelp->setAutoDefault( true );
GroupButtonsLayout->addWidget( buttonOk ); GroupButtonsLayout->addWidget( buttonOk );
GroupButtonsLayout->addSpacing( 10 ); GroupButtonsLayout->addSpacing( 10 );
GroupButtonsLayout->addStretch(); GroupButtonsLayout->addStretch();
GroupButtonsLayout->addWidget( buttonCancel ); GroupButtonsLayout->addWidget( buttonCancel );
GroupButtonsLayout->addWidget( buttonHelp );
// ------------------------------- // -------------------------------
topLayout->addWidget( ButtonGroup1 ); topLayout->addWidget( ButtonGroup1 );
@ -200,9 +209,12 @@ SMESHGUI_Preferences_ColorDlg::SMESHGUI_Preferences_ColorDlg( SMESHGUI* theModul
// ------------------------------- // -------------------------------
mySMESHGUI->SetActiveDialogBox( this ); mySMESHGUI->SetActiveDialogBox( this );
myHelpFileName = "colors_size_page.html";
/* signals and slots connections */ /* signals and slots connections */
connect( buttonOk, SIGNAL( clicked() ), this, SLOT( ClickOnOk() ) ); connect( buttonOk, SIGNAL( clicked() ), this, SLOT( ClickOnOk() ) );
connect( buttonCancel, SIGNAL( clicked() ), this, SLOT( ClickOnCancel() ) ); connect( buttonCancel, SIGNAL( clicked() ), this, SLOT( ClickOnCancel() ) );
connect( buttonHelp, SIGNAL( clicked() ), this, SLOT( ClickOnHelp() ) );
connect( mySMESHGUI, SIGNAL ( SignalDeactivateActiveDialog() ), connect( mySMESHGUI, SIGNAL ( SignalDeactivateActiveDialog() ),
this, SLOT( DeactivateActiveDialog() ) ); this, SLOT( DeactivateActiveDialog() ) );
@ -239,6 +251,30 @@ void SMESHGUI_Preferences_ColorDlg::ClickOnCancel()
reject(); 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() // function : DeactivateActiveDialog()
// purpose : // purpose :
@ -447,3 +483,19 @@ int SMESHGUI_Preferences_ColorDlg::getCustomMarkerID() const
{ {
return MarkerWidget->getCustomMarkerID(); 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();
}
}

View File

@ -71,10 +71,12 @@ public:
protected: protected:
void closeEvent( QCloseEvent* ); void closeEvent( QCloseEvent* );
void keyPressEvent( QKeyEvent* );
private slots: private slots:
void ClickOnOk(); void ClickOnOk();
void ClickOnCancel(); void ClickOnCancel();
void ClickOnHelp();
void DeactivateActiveDialog(); void DeactivateActiveDialog();
void ActivateThisDialog(); void ActivateThisDialog();
@ -93,6 +95,8 @@ private:
QtxColorButton* btnOrientationColor; QtxColorButton* btnOrientationColor;
SMESHGUI_SpinBox* SpinBox_Orientation_Scale; SMESHGUI_SpinBox* SpinBox_Orientation_Scale;
QCheckBox* CheckBox_Orientation_3DVectors; QCheckBox* CheckBox_Orientation_3DVectors;
QString myHelpFileName;
}; };
#endif // SMESHGUI_PREFERENCES_COLORDLG_H #endif // SMESHGUI_PREFERENCES_COLORDLG_H

View File

@ -123,6 +123,7 @@ SMESHGUI_RemoveElementsDlg
SelectButtonC1A1->setIcon(image1); SelectButtonC1A1->setIcon(image1);
LineEditC1A1 = new QLineEdit(GroupC1); LineEditC1A1 = new QLineEdit(GroupC1);
LineEditC1A1->setValidator(new SMESHGUI_IdValidator(this)); LineEditC1A1->setValidator(new SMESHGUI_IdValidator(this));
LineEditC1A1->setMaxLength(-1);
QPushButton* filterBtn = new QPushButton( tr( "SMESH_BUT_FILTER" ), GroupC1 ); QPushButton* filterBtn = new QPushButton( tr( "SMESH_BUT_FILTER" ), GroupC1 );
connect(filterBtn, SIGNAL(clicked()), this, SLOT(setFilters())); connect(filterBtn, SIGNAL(clicked()), this, SLOT(setFilters()));
@ -232,7 +233,7 @@ void SMESHGUI_RemoveElementsDlg::ClickOnApply()
bool aResult = false; bool aResult = false;
try { try {
SMESH::SMESH_MeshEditor_var aMeshEditor = myMesh->GetMeshEditor(); SMESH::SMESH_MeshEditor_var aMeshEditor = myMesh->GetMeshEditor();
aResult = aMeshEditor->RemoveElements(anArrayOfIdeces.inout()); aResult = aMeshEditor->RemoveElements(anArrayOfIdeces.in());
} catch (const SALOME::SALOME_Exception& S_ex) { } catch (const SALOME::SALOME_Exception& S_ex) {
SalomeApp_Tools::QtCatchCorbaException(S_ex); SalomeApp_Tools::QtCatchCorbaException(S_ex);
myEditCurrentArgument->clear(); myEditCurrentArgument->clear();
@ -244,6 +245,7 @@ void SMESHGUI_RemoveElementsDlg::ClickOnApply()
myEditCurrentArgument->clear(); myEditCurrentArgument->clear();
mySelector->ClearIndex(); mySelector->ClearIndex();
SMESH::UpdateView(); SMESH::UpdateView();
SMESHGUI::Modified();
} }
} }
} }
@ -310,9 +312,6 @@ void SMESHGUI_RemoveElementsDlg::onTextChange(const QString& theNewText)
myNbOkElements = 0; myNbOkElements = 0;
buttonOk->setEnabled(false);
buttonApply->setEnabled(false);
// hilight entered elements // hilight entered elements
if(myActor){ if(myActor){
if(SMDS_Mesh* aMesh = myActor->GetObject()->GetMesh()){ 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; myBusy = false;
updateButtons();
} }
//================================================================================= //=================================================================================
@ -348,46 +343,39 @@ void SMESHGUI_RemoveElementsDlg::onTextChange(const QString& theNewText)
//================================================================================= //=================================================================================
void SMESHGUI_RemoveElementsDlg::SelectionIntoArgument() 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 // clear
myNbOkElements = false; myNbOkElements = 0;
myActor = 0; myActor = 0;
myBusy = true; myBusy = true;
myEditCurrentArgument->setText(""); myEditCurrentArgument->setText("");
myBusy = false; myBusy = false;
if (!GroupButtons->isEnabled()) // inactive
return;
buttonOk->setEnabled(false);
buttonApply->setEnabled(false);
// get selected mesh // get selected mesh
SALOME_ListIO aList; SALOME_ListIO aList;
mySelectionMgr->selectedObjects(aList,SVTK_Viewer::Type()); mySelectionMgr->selectedObjects(aList,SVTK_Viewer::Type());
int nbSel = aList.Extent(); int nbSel = aList.Extent();
if (nbSel != 1) if (nbSel == 1) {
return;
Handle(SALOME_InteractiveObject) anIO = aList.First(); Handle(SALOME_InteractiveObject) anIO = aList.First();
myMesh = SMESH::GetMeshByIO(anIO); myMesh = SMESH::GetMeshByIO(anIO);
if (myMesh->_is_nil())
return; if (!myMesh->_is_nil()) {
myActor = SMESH::FindActorByEntry(anIO->getEntry()); myActor = SMESH::FindActorByEntry(anIO->getEntry());
if (!myActor) if (myActor) {
return;
// get selected nodes // get selected nodes
QString aString = ""; QString aString = "";
int nbElems = SMESH::GetNameOfSelectedElements(mySelector,anIO,aString); int nbElems = SMESH::GetNameOfSelectedElements(mySelector,anIO,aString);
if(nbElems < 1) if (nbElems > 0) {
return;
myBusy = true; myBusy = true;
myEditCurrentArgument->setText(aString); myEditCurrentArgument->setText(aString);
myBusy = false; myBusy = false;
@ -395,9 +383,12 @@ void SMESHGUI_RemoveElementsDlg::SelectionIntoArgument()
// OK // OK
myNbOkElements = nbElems; myNbOkElements = nbElems;
} // if (nbElems > 0)
} // if (myActor)
} // if (!myMesh->_is_nil())
} // if (nbSel == 1) {
buttonOk->setEnabled(true); updateButtons();
buttonApply->setEnabled(true);
} }
//================================================================================= //=================================================================================
@ -523,3 +514,13 @@ void SMESHGUI_RemoveElementsDlg::setFilters()
myFilterDlg->show(); myFilterDlg->show();
} }
//=================================================================================
// function : updateButtons
// purpose : enable / disable control buttons
//=================================================================================
void SMESHGUI_RemoveElementsDlg::updateButtons()
{
buttonOk->setEnabled(myNbOkElements > 0);
buttonApply->setEnabled(myNbOkElements > 0);
}

View File

@ -107,6 +107,7 @@ private slots:
void ActivateThisDialog(); void ActivateThisDialog();
void onTextChange( const QString& ); void onTextChange( const QString& );
void setFilters(); void setFilters();
void updateButtons();
}; };
#endif // SMESHGUI_REMOVEELEMENTSDLG_H #endif // SMESHGUI_REMOVEELEMENTSDLG_H

View File

@ -123,6 +123,7 @@ SMESHGUI_RemoveNodesDlg
SelectButtonC1A1->setIcon(image1); SelectButtonC1A1->setIcon(image1);
LineEditC1A1 = new QLineEdit(GroupC1); LineEditC1A1 = new QLineEdit(GroupC1);
LineEditC1A1->setValidator(new SMESHGUI_IdValidator(this)); LineEditC1A1->setValidator(new SMESHGUI_IdValidator(this));
LineEditC1A1->setMaxLength(-1);
QPushButton* filterBtn = new QPushButton( tr( "SMESH_BUT_FILTER" ), GroupC1 ); QPushButton* filterBtn = new QPushButton( tr( "SMESH_BUT_FILTER" ), GroupC1 );
connect(filterBtn, SIGNAL(clicked()), this, SLOT(setFilters())); connect(filterBtn, SIGNAL(clicked()), this, SLOT(setFilters()));
@ -234,7 +235,7 @@ void SMESHGUI_RemoveNodesDlg::ClickOnApply()
bool aResult = false; bool aResult = false;
try { try {
SMESH::SMESH_MeshEditor_var aMeshEditor = myMesh->GetMeshEditor(); SMESH::SMESH_MeshEditor_var aMeshEditor = myMesh->GetMeshEditor();
aResult = aMeshEditor->RemoveNodes(anArrayOfIdeces.inout()); aResult = aMeshEditor->RemoveNodes(anArrayOfIdeces.in());
} catch (const SALOME::SALOME_Exception& S_ex) { } catch (const SALOME::SALOME_Exception& S_ex) {
SalomeApp_Tools::QtCatchCorbaException(S_ex); SalomeApp_Tools::QtCatchCorbaException(S_ex);
myEditCurrentArgument->clear(); myEditCurrentArgument->clear();
@ -246,6 +247,7 @@ void SMESHGUI_RemoveNodesDlg::ClickOnApply()
myEditCurrentArgument->clear(); myEditCurrentArgument->clear();
mySelector->ClearIndex(); mySelector->ClearIndex();
SMESH::UpdateView(); SMESH::UpdateView();
SMESHGUI::Modified();
} }
SMESH::SetPointRepresentation(true); SMESH::SetPointRepresentation(true);
@ -316,9 +318,6 @@ void SMESHGUI_RemoveNodesDlg::onTextChange(const QString& theNewText)
myNbOkNodes = 0; myNbOkNodes = 0;
buttonOk->setEnabled(false);
buttonApply->setEnabled(false);
// hilight entered nodes // hilight entered nodes
if(myActor){ if(myActor){
if(SMDS_Mesh* aMesh = myActor->GetObject()->GetMesh()){ 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; myBusy = false;
updateButtons();
} }
//================================================================================= //=================================================================================
@ -354,56 +349,51 @@ void SMESHGUI_RemoveNodesDlg::onTextChange(const QString& theNewText)
//================================================================================= //=================================================================================
void SMESHGUI_RemoveNodesDlg::SelectionIntoArgument() 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 // clear
myNbOkNodes = false; myNbOkNodes = 0;
myActor = 0; myActor = 0;
myBusy = true; myBusy = true;
myEditCurrentArgument->setText(""); myEditCurrentArgument->setText("");
myBusy = false; myBusy = false;
if (!GroupButtons->isEnabled()) // inactive
return;
buttonOk->setEnabled(false);
buttonApply->setEnabled(false);
// get selected mesh // get selected mesh
SALOME_ListIO aList; SALOME_ListIO aList;
mySelectionMgr->selectedObjects(aList,SVTK_Viewer::Type()); mySelectionMgr->selectedObjects(aList,SVTK_Viewer::Type());
int nbSel = aList.Extent(); int nbSel = aList.Extent();
if (nbSel != 1) if (nbSel == 1) {
return;
Handle(SALOME_InteractiveObject) anIO = aList.First(); Handle(SALOME_InteractiveObject) anIO = aList.First();
myMesh = SMESH::GetMeshByIO(anIO); myMesh = SMESH::GetMeshByIO(anIO);
if (myMesh->_is_nil())
return; if (!myMesh->_is_nil()) {
myActor = SMESH::FindActorByEntry(anIO->getEntry()); myActor = SMESH::FindActorByEntry(anIO->getEntry());
if (!myActor) if (myActor) {
return;
// get selected nodes // get selected nodes
QString aString = ""; QString aString = "";
int nbNodes = SMESH::GetNameOfSelectedNodes(mySelector,anIO,aString); int nbNodes = SMESH::GetNameOfSelectedNodes(mySelector,anIO,aString);
if(nbNodes < 1) if (nbNodes > 0) {
return;
myBusy = true; myBusy = true;
myEditCurrentArgument->setText(aString); myEditCurrentArgument->setText(aString);
myBusy = false; myBusy = false;
// OK // OK
myNbOkNodes = true; myNbOkNodes = nbNodes;
} // if (nbNodes > 0)
} // if (myActor)
} // if (!myMesh->_is_nil())
} // if (nbSel == 1)
buttonOk->setEnabled(true); updateButtons();
buttonApply->setEnabled(true);
} }
//================================================================================= //=================================================================================
@ -530,3 +520,13 @@ void SMESHGUI_RemoveNodesDlg::setFilters()
myFilterDlg->show(); myFilterDlg->show();
} }
//=================================================================================
// function : updateButtons
// purpose : enable / disable control buttons
//=================================================================================
void SMESHGUI_RemoveNodesDlg::updateButtons()
{
buttonOk->setEnabled(myNbOkNodes > 0);
buttonApply->setEnabled(myNbOkNodes > 0);
}

View File

@ -107,6 +107,7 @@ private slots:
void ActivateThisDialog(); void ActivateThisDialog();
void onTextChange( const QString& ); void onTextChange( const QString& );
void setFilters(); void setFilters();
void updateButtons();
}; };
#endif // SMESHGUI_REMOVENODESDLG_H #endif // SMESHGUI_REMOVENODESDLG_H

View File

@ -243,6 +243,7 @@ void SMESHGUI_RenumberingDlg::ClickOnApply()
//mySelectionMgr->clearSelected(); //mySelectionMgr->clearSelected();
SMESH::UpdateView(); SMESH::UpdateView();
SMESHGUI::Modified();
} }
} }

View File

@ -146,6 +146,7 @@ SMESHGUI_RevolutionDlg::SMESHGUI_RevolutionDlg( SMESHGUI* theModule )
LineEditElements = new QLineEdit(GroupArguments); LineEditElements = new QLineEdit(GroupArguments);
LineEditElements->setValidator(myIdValidator); LineEditElements->setValidator(myIdValidator);
LineEditElements->setMaxLength(-1);
myFilterBtn = new QPushButton( tr( "SMESH_BUT_FILTER" ), GroupArguments ); myFilterBtn = new QPushButton( tr( "SMESH_BUT_FILTER" ), GroupArguments );
connect(myFilterBtn, SIGNAL(clicked()), this, SLOT(setFilters())); connect(myFilterBtn, SIGNAL(clicked()), this, SLOT(setFilters()));
@ -557,6 +558,8 @@ bool SMESHGUI_RevolutionDlg::ClickOnApply()
ConstructorsClicked(GetConstructorId()); ConstructorsClicked(GetConstructorId());
mySelectedObject = SMESH::SMESH_IDSource::_nil(); mySelectedObject = SMESH::SMESH_IDSource::_nil();
SelectionIntoArgument(); SelectionIntoArgument();
SMESHGUI::Modified();
} }
return true; return true;

View File

@ -134,6 +134,7 @@ SMESHGUI_RotationDlg::SMESHGUI_RotationDlg( SMESHGUI* theModule )
SelectElementsButton->setIcon(image1); SelectElementsButton->setIcon(image1);
LineEditElements = new QLineEdit(GroupArguments); LineEditElements = new QLineEdit(GroupArguments);
LineEditElements->setValidator(myIdValidator); LineEditElements->setValidator(myIdValidator);
LineEditElements->setMaxLength(-1);
myFilterBtn = new QPushButton( tr( "SMESH_BUT_FILTER" ), GroupArguments ); myFilterBtn = new QPushButton( tr( "SMESH_BUT_FILTER" ), GroupArguments );
connect(myFilterBtn, SIGNAL(clicked()), this, SLOT(setFilters())); connect(myFilterBtn, SIGNAL(clicked()), this, SLOT(setFilters()));
@ -456,6 +457,8 @@ bool SMESHGUI_RotationDlg::ClickOnApply()
Init(false); Init(false);
mySelectedObject = SMESH::SMESH_IDSource::_nil(); mySelectedObject = SMESH::SMESH_IDSource::_nil();
SelectionIntoArgument(); SelectionIntoArgument();
SMESHGUI::Modified();
} }
return true; return true;

View File

@ -154,6 +154,7 @@ SMESHGUI_ScaleDlg::SMESHGUI_ScaleDlg( SMESHGUI* theModule )
SelectElementsButton->setIcon(image2); SelectElementsButton->setIcon(image2);
LineEditElements = new QLineEdit(GroupArguments); LineEditElements = new QLineEdit(GroupArguments);
LineEditElements->setValidator(myIdValidator); LineEditElements->setValidator(myIdValidator);
LineEditElements->setMaxLength(-1);
myFilterBtn = new QPushButton( tr( "SMESH_BUT_FILTER" ), GroupArguments ); myFilterBtn = new QPushButton( tr( "SMESH_BUT_FILTER" ), GroupArguments );
connect(myFilterBtn, SIGNAL(clicked()), this, SLOT(setFilters())); connect(myFilterBtn, SIGNAL(clicked()), this, SLOT(setFilters()));
@ -526,6 +527,8 @@ bool SMESHGUI_ScaleDlg::ClickOnApply()
ConstructorsClicked(GetConstructorId()); ConstructorsClicked(GetConstructorId());
mySelectedObject = SMESH::SMESH_IDSource::_nil(); mySelectedObject = SMESH::SMESH_IDSource::_nil();
SelectionIntoArgument(); SelectionIntoArgument();
SMESHGUI::Modified();
} }
return true; return true;

View File

@ -533,6 +533,8 @@ bool SMESHGUI_SewingDlg::ClickOnApply()
Init(); Init();
ConstructorsClicked(GetConstructorId()); ConstructorsClicked(GetConstructorId());
SMESHGUI::Modified();
} }
} }

View File

@ -514,6 +514,7 @@ bool SMESHGUI_SingleEditDlg::onApply()
mySelectionMgr->setSelectedObjects(aList, false); mySelectionMgr->setSelectedObjects(aList, false);
onSelectionDone(); onSelectionDone();
SMESH::UpdateView(); SMESH::UpdateView();
SMESHGUI::Modified();
} }
return aResult; return aResult;

View File

@ -138,6 +138,7 @@ SMESHGUI_SmoothingDlg::SMESHGUI_SmoothingDlg( SMESHGUI* theModule )
LineEditElements = new QLineEdit(GroupArguments); LineEditElements = new QLineEdit(GroupArguments);
LineEditElements->setValidator(myIdValidator); LineEditElements->setValidator(myIdValidator);
LineEditElements->setMaxLength(-1);
myElemFilterBtn = new QPushButton( tr( "SMESH_BUT_FILTER" ), GroupArguments ); myElemFilterBtn = new QPushButton( tr( "SMESH_BUT_FILTER" ), GroupArguments );
connect(myElemFilterBtn, SIGNAL(clicked()), this, SLOT(setElemFilters())); connect(myElemFilterBtn, SIGNAL(clicked()), this, SLOT(setElemFilters()));
@ -152,6 +153,7 @@ SMESHGUI_SmoothingDlg::SMESHGUI_SmoothingDlg( SMESHGUI* theModule )
LineEditNodes = new QLineEdit(GroupArguments); LineEditNodes = new QLineEdit(GroupArguments);
LineEditNodes->setValidator(myIdValidator); LineEditNodes->setValidator(myIdValidator);
LineEditNodes->setMaxLength(-1);
QPushButton* filterNodeBtn = new QPushButton( tr( "SMESH_BUT_FILTER" ), GroupArguments ); QPushButton* filterNodeBtn = new QPushButton( tr( "SMESH_BUT_FILTER" ), GroupArguments );
connect(filterNodeBtn, SIGNAL(clicked()), this, SLOT(setNodeFilters())); connect(filterNodeBtn, SIGNAL(clicked()), this, SLOT(setNodeFilters()));
@ -395,6 +397,7 @@ bool SMESHGUI_SmoothingDlg::ClickOnApply()
} }
SMESH::UpdateView(); SMESH::UpdateView();
SMESHGUI::Modified();
Init(); Init();
mySelectedObject = SMESH::SMESH_IDSource::_nil(); mySelectedObject = SMESH::SMESH_IDSource::_nil();

View File

@ -145,6 +145,7 @@ SMESHGUI_SymmetryDlg::SMESHGUI_SymmetryDlg( SMESHGUI* theModule )
SelectElementsButton->setIcon(image3); SelectElementsButton->setIcon(image3);
LineEditElements = new QLineEdit(GroupArguments); LineEditElements = new QLineEdit(GroupArguments);
LineEditElements->setValidator(myIdValidator); LineEditElements->setValidator(myIdValidator);
LineEditElements->setMaxLength(-1);
myFilterBtn = new QPushButton( tr( "SMESH_BUT_FILTER" ), GroupArguments ); myFilterBtn = new QPushButton( tr( "SMESH_BUT_FILTER" ), GroupArguments );
connect(myFilterBtn, SIGNAL(clicked()), this, SLOT(setFilters())); connect(myFilterBtn, SIGNAL(clicked()), this, SLOT(setFilters()));
@ -546,6 +547,8 @@ bool SMESHGUI_SymmetryDlg::ClickOnApply()
ConstructorsClicked(GetConstructorId()); ConstructorsClicked(GetConstructorId());
mySelectedObject = SMESH::SMESH_IDSource::_nil(); mySelectedObject = SMESH::SMESH_IDSource::_nil();
SelectionIntoArgument(); SelectionIntoArgument();
SMESHGUI::Modified();
} }
return true; return true;
} }

View File

@ -157,6 +157,7 @@ SMESHGUI_TranslationDlg::SMESHGUI_TranslationDlg( SMESHGUI* theModule )
SelectElementsButton->setIcon(image2); SelectElementsButton->setIcon(image2);
LineEditElements = new QLineEdit(GroupArguments); LineEditElements = new QLineEdit(GroupArguments);
LineEditElements->setValidator(myIdValidator); LineEditElements->setValidator(myIdValidator);
LineEditElements->setMaxLength(-1);
myFilterBtn = new QPushButton( tr( "SMESH_BUT_FILTER" ), GroupArguments ); myFilterBtn = new QPushButton( tr( "SMESH_BUT_FILTER" ), GroupArguments );
connect(myFilterBtn, SIGNAL(clicked()), this, SLOT(setFilters())); connect(myFilterBtn, SIGNAL(clicked()), this, SLOT(setFilters()));
@ -530,6 +531,8 @@ bool SMESHGUI_TranslationDlg::ClickOnApply()
ConstructorsClicked(GetConstructorId()); ConstructorsClicked(GetConstructorId());
mySelectedObject = SMESH::SMESH_IDSource::_nil(); mySelectedObject = SMESH::SMESH_IDSource::_nil();
SelectionIntoArgument(); SelectionIntoArgument();
SMESHGUI::Modified();
} }
return true; return true;

View File

@ -130,6 +130,7 @@ SMESHGUI_WhatIsDlg::SMESHGUI_WhatIsDlg( SMESHGUI* theModule )
LineEditElements = new QLineEdit(GroupArguments); LineEditElements = new QLineEdit(GroupArguments);
LineEditElements->setValidator(new SMESHGUI_IdValidator(this)); LineEditElements->setValidator(new SMESHGUI_IdValidator(this));
LineEditElements->setMaxLength(-1);
GroupArgumentsLayout->addWidget(LineEditElements, 0, 1); GroupArgumentsLayout->addWidget(LineEditElements, 0, 1);
// information text browser // information text browser

View File

@ -109,7 +109,7 @@ c_l.append(baseHexa4)
c_cpd = MakeCompound(c_l) c_cpd = MakeCompound(c_l)
c_glu = MakeGlueFaces(c_cpd, 1.e-5) c_glu = MakeGlueFaces(c_cpd, 1.e-5)
piece = RemoveExtraEdges(c_glu) piece = RemoveExtraEdges(c_glu, doUnionFaces=True)
# Add in study # Add in study
# ------------ # ------------

View File

@ -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_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) piece = MakeGlueFaces(p_blocs, 1.e-5)
# Add in study # Add in study

View File

@ -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_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 # Grid and glue
# ------------- # -------------

View File

@ -206,7 +206,7 @@ blocks.append(full_parts)
piece_cpd = MakeCompound(blocks) piece_cpd = MakeCompound(blocks)
piece_ok = RemoveExtraEdges(piece_cpd) piece_ok = RemoveExtraEdges(piece_cpd, doUnionFaces=True)
piece = MakeGlueFaces(piece_ok, 1.e-3) piece = MakeGlueFaces(piece_ok, 1.e-3)

View File

@ -205,7 +205,7 @@ public: //** Access to member fields **//
private: 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; } { myError = SMESH_ComputeError::New( code, text ); return false; }
bool error(const SMESH_ComputeErrorPtr& err) bool error(const SMESH_ComputeErrorPtr& err)
@ -987,6 +987,13 @@ bool _QuadFaceGrid::LoadGrid( SMESH_Mesh& mesh )
if ( !myGrid.empty() ) if ( !myGrid.empty() )
return true; 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._xSize = 1 + mySides.GetSide( Q_BOTTOM )->GetNbSegments( mesh );
myIndexer._ySize = 1 + mySides.GetSide( Q_LEFT )->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 // store the rest nodes row by row
SMESHDS_SubMesh* faceSubMesh = mesh.GetSubMesh( myFace )->GetSubMeshDS();
SMDS_MeshNode dummy(0,0,0); SMDS_MeshNode dummy(0,0,0);
const SMDS_MeshElement* firstQuad = &dummy;// most left face above the last row of found nodes const SMDS_MeshElement* firstQuad = &dummy;// most left face above the last row of found nodes

View File

@ -270,7 +270,7 @@ const vector<UVPtStruct>& StdMeshers_FaceSide::GetUVPtStruct(bool isXConst,
const SMDS_MeshNode* node = nItr->next(); const SMDS_MeshNode* node = nItr->next();
if ( myIgnoreMediumNodes && SMESH_MeshEditor::IsMedium( node, SMDSAbs_Edge )) if ( myIgnoreMediumNodes && SMESH_MeshEditor::IsMedium( node, SMDSAbs_Edge ))
continue; continue;
double u = helper.GetNodeU( myEdge[i], node, &paramOK ); double u = helper.GetNodeU( myEdge[i], node, 0, &paramOK );
double aLenU = GCPnts_AbscissaPoint::Length double aLenU = GCPnts_AbscissaPoint::Length
( const_cast<GeomAdaptor_Curve&>( myC3dAdaptor[i]), myFirst[i], u ); ( const_cast<GeomAdaptor_Curve&>( myC3dAdaptor[i]), myFirst[i], u );
if ( myEdgeLength[i] < aLenU ) // nonregression test "3D_mesh_NETGEN/G6" if ( myEdgeLength[i] < aLenU ) // nonregression test "3D_mesh_NETGEN/G6"
@ -288,7 +288,7 @@ const vector<UVPtStruct>& StdMeshers_FaceSide::GetUVPtStruct(bool isXConst,
const SMDS_MeshNode* node = nItr->next(); const SMDS_MeshNode* node = nItr->next();
if ( myIgnoreMediumNodes && SMESH_MeshEditor::IsMedium( node, SMDSAbs_Edge )) if ( myIgnoreMediumNodes && SMESH_MeshEditor::IsMedium( node, SMDSAbs_Edge ))
continue; continue;
double u = helper.GetNodeU( myEdge[i], node, &paramOK ); double u = helper.GetNodeU( myEdge[i], node, 0, &paramOK );
// paramSize is signed so orientation is taken into account // paramSize is signed so orientation is taken into account
double normPar = prevNormPar + r * ( u - myFirst[i] ) / paramSize; double normPar = prevNormPar + r * ( u - myFirst[i] ) / paramSize;
@ -585,18 +585,17 @@ TSideVector StdMeshers_FaceSide::GetFaceWires(const TopoDS_Face& theFace,
TError & theError) TError & theError)
{ {
TopoDS_Vertex V1; TopoDS_Vertex V1;
list< TopoDS_Edge > edges; list< TopoDS_Edge > edges, internalEdges;
list< int > nbEdgesInWires; list< int > nbEdgesInWires;
int nbWires = SMESH_Block::GetOrderedEdges (theFace, V1, edges, nbEdgesInWires); int nbWires = SMESH_Block::GetOrderedEdges (theFace, V1, edges, nbEdgesInWires);
// split list of all edges into separate wires // split list of all edges into separate wires
TSideVector wires( nbWires ); TSideVector wires( nbWires );
list< int >::iterator nbE = nbEdgesInWires.begin(); list< int >::iterator nbE = nbEdgesInWires.begin();
list< TopoDS_Edge >::iterator from, to; list< TopoDS_Edge >::iterator from = edges.begin(), to = from;
from = to = edges.begin(); for ( int iW = 0; iW < nbWires; ++iW, ++nbE )
for ( int iW = 0; iW < nbWires; ++iW )
{ {
std::advance( to, *nbE++ ); std::advance( to, *nbE );
if ( *nbE == 0 ) // Issue 0020676 if ( *nbE == 0 ) // Issue 0020676
{ {
--nbWires; --nbWires;
@ -608,6 +607,7 @@ TSideVector StdMeshers_FaceSide::GetFaceWires(const TopoDS_Face& theFace,
// assure that there is a node on the first vertex // assure that there is a node on the first vertex
// as StdMeshers_FaceSide::GetUVPtStruct() requires // as StdMeshers_FaceSide::GetUVPtStruct() requires
if ( wireEdges.front().Orientation() != TopAbs_INTERNAL ) // Issue 0020676 if ( wireEdges.front().Orientation() != TopAbs_INTERNAL ) // Issue 0020676
{
while ( !SMESH_Algo::VertexNode( TopExp::FirstVertex( wireEdges.front(), true), while ( !SMESH_Algo::VertexNode( TopExp::FirstVertex( wireEdges.front(), true),
theMesh.GetMeshDS())) theMesh.GetMeshDS()))
{ {
@ -619,12 +619,24 @@ TSideVector StdMeshers_FaceSide::GetFaceWires(const TopoDS_Face& theFace,
return TSideVector(0); 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, StdMeshers_FaceSide* wire = new StdMeshers_FaceSide( theFace, wireEdges, &theMesh,
isForward, theIgnoreMediumNodes); /*isForward=*/true, theIgnoreMediumNodes);
wires[ iW ] = StdMeshers_FaceSidePtr( wire ); wires[ iW ] = StdMeshers_FaceSidePtr( wire );
from = to; 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; return wires;
} }

View File

@ -51,7 +51,7 @@ namespace
{ {
enum EBoxSides //!< sides of the block 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 const char* SBoxSides[] = //!< names of block sides
{ {
@ -59,7 +59,7 @@ namespace
}; };
enum EQuadEdge //!< edges of quadrangle side 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; 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<const SMDS_MeshNode*> 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 * \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) 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 _nbBlocksExpected;
int _nbBlocksFound; int _nbBlocksFound;
#ifdef _DEBUG_ #ifdef _DEBUG_ // want to get SIGSEGV in case of invalid index
#define _grid_access_(args) _grid.at( args ) #define _grid_access_(pobj, i) pobj->_grid[ ((i) < pobj->_grid.size()) ? i : int(1e100)]
#else #else
#define _grid_access_(args) _grid[ args ] #define _grid_access_(pobj, i) pobj->_grid[ i ]
#endif #endif
//!< Return node at XY //!< 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 //!< 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 //!< Return an edge
SMESH_OrientedLink getEdge(EQuadEdge edge) const SMESH_OrientedLink getEdge(EQuadEdge edge) const
{ {
@ -242,7 +275,7 @@ namespace
//!< return coordinates by XY //!< return coordinates by XY
gp_XYZ xyz(int x, int y) const 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 //!< safely return a node by XY
const SMDS_MeshNode* node(int x, int y) const const SMDS_MeshNode* node(int x, int y) const
@ -259,7 +292,7 @@ namespace
//!< Return a corner node //!< Return a corner node
const SMDS_MeshNode* cornerNode(bool isXMax, bool isYMax) const 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 //!< return its size in nodes
int getHoriSize() const { return _index.xSize(); } int getHoriSize() const { return _index.xSize(); }
@ -277,13 +310,28 @@ namespace
struct _Block struct _Block
{ {
_OrientedBlockSide _side[6]; // 6 sides of a sub-block _OrientedBlockSide _side[6]; // 6 sides of a sub-block
set<const SMDS_MeshNode*> _corners;
const _OrientedBlockSide& getSide(int i) const { return _side[i]; } 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 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; if ( s ) for (int i=0;i<6;++i) if ( _side[i] && _side[i]._side == s._side ) return true;
return false; 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; } const SMESH_Comment& error() const { return _error; }
private: 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, bool fillRowsUntilCorner(const SMDS_MeshElement* quad,
const SMDS_MeshNode* n1, const SMDS_MeshNode* n1,
const SMDS_MeshNode* n2, const SMDS_MeshNode* n2,
@ -309,17 +359,15 @@ namespace
bool alongN1N2 ); bool alongN1N2 );
_OrientedBlockSide findBlockSide( EBoxSides startBlockSide, _OrientedBlockSide findBlockSide( EBoxSides startBlockSide,
EQuadEdge sharedSideEdge1, EQuadEdge sharedSideEdge1,
EQuadEdge sharedSideEdge2); EQuadEdge sharedSideEdge2,
bool withGeometricAnalysis);
//!< update own data and data of the side bound to block //!< update own data and data of the side bound to block
void setSideBoundToBlock( _BlockSide& side ) void setSideBoundToBlock( _BlockSide& side )
{ {
side._nbBlocksFound++; if ( side._nbBlocksFound++, side.isBound() )
if ( side.isBound() ) for ( int e = 0; e < int(NB_QUAD_SIDES); ++e )
{
for ( int e = 0; e < int(Q_UNDEFINED); ++e )
_edge2sides[ side.getEdge( (EQuadEdge) e ) ].erase( &side ); _edge2sides[ side.getEdge( (EQuadEdge) e ) ].erase( &side );
} }
}
//!< store reason of error //!< store reason of error
int error(const SMESH_Comment& reason) { _error = reason; return 0; } int error(const SMESH_Comment& reason) { _error = reason; return 0; }
@ -383,7 +431,7 @@ namespace
_allSides.push_back( _BlockSide() ); _allSides.push_back( _BlockSide() );
_BlockSide& side = _allSides.back(); _BlockSide& side = _allSides.back();
if ( !fillSide( side, face ) ) if ( !fillSide( side, face, *corner ) )
{ {
if ( !_error.empty() ) if ( !_error.empty() )
return false; return false;
@ -394,13 +442,10 @@ namespace
for ( int isYMax = 0; isYMax < 2; ++isYMax ) for ( int isYMax = 0; isYMax < 2; ++isYMax )
{ {
const SMDS_MeshNode* nCorner = side.getCornerNode(isXMax,isYMax ); const SMDS_MeshNode* nCorner = side.getCornerNode(isXMax,isYMax );
if ( !isCornerNode( nCorner ))
return BAD_MESH_ERR;
//_corner2sides[ nCorner ].insert( &side );
corners.push_back( nCorner ); corners.push_back( nCorner );
cornerFaces.insert( side.getCornerFace( 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 ); _edge2sides[ side.getEdge( (EQuadEdge) e ) ].insert( &side );
nbFacesOnSides += side.getNbFaces(); nbFacesOnSides += side.getNbFaces();
@ -425,23 +470,33 @@ namespace
return BAD_MESH_ERR; return BAD_MESH_ERR;
if ( _allSides.back()._grid.empty() ) if ( _allSides.back()._grid.empty() )
_allSides.pop_back(); _allSides.pop_back();
_DUMP_("Nb detected sides "<< _allSides.size());
// --------------------------- // ---------------------------
// Organize sides into blocks // Organize sides into blocks
// --------------------------- // ---------------------------
// analyse sharing of sides by blocks // analyse sharing of sides by blocks and sort sides by nb of adjacent sides
int nbBlockSides = 0; // nb of block sides taking into account their sharing int nbBlockSides = 0; // total nb of block sides taking into account their sharing
multimap<int, _BlockSide* > sortedSides;
{
list < _BlockSide >::iterator sideIt = _allSides.begin(); list < _BlockSide >::iterator sideIt = _allSides.begin();
for ( ; sideIt != _allSides.end(); ++sideIt ) for ( ; sideIt != _allSides.end(); ++sideIt )
{ {
_BlockSide& side = *sideIt; _BlockSide& side = *sideIt;
bool isSharedSide = true; bool isSharedSide = true;
for ( int e = 0; e < int(Q_UNDEFINED) && isSharedSide; ++e ) int nbAdjacent = 0;
isSharedSide = _edge2sides[ side.getEdge( (EQuadEdge) e ) ].size() > 2; 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._nbBlocksFound = 0;
side._nbBlocksExpected = isSharedSide ? 2 : 1; side._nbBlocksExpected = isSharedSide ? 2 : 1;
nbBlockSides += side._nbBlocksExpected; nbBlockSides += side._nbBlocksExpected;
sortedSides.insert( make_pair( nbAdjacent, & side ));
}
} }
// find sides of each block // find sides of each block
@ -449,9 +504,9 @@ namespace
while ( nbBlockSides >= 6 ) while ( nbBlockSides >= 6 )
{ {
// get any side not bound to all blocks it belongs to // get any side not bound to all blocks it belongs to
sideIt = _allSides.begin(); multimap<int, _BlockSide*>::iterator i_side = sortedSides.begin();
while ( sideIt != _allSides.end() && sideIt->isBound()) while ( i_side != sortedSides.end() && i_side->second->isBound())
++sideIt; ++i_side;
// start searching for block sides from the got side // start searching for block sides from the got side
bool ok = true; bool ok = true;
@ -459,37 +514,40 @@ namespace
_blocks.resize( _blocks.size() + 1 ); _blocks.resize( _blocks.size() + 1 );
_Block& block = _blocks.back(); _Block& block = _blocks.back();
block._side[B_FRONT] = &(*sideIt); block.setSide( B_FRONT, i_side->second );
setSideBoundToBlock( *sideIt ); setSideBoundToBlock( *i_side->second );
nbBlockSides--; nbBlockSides--;
// edges of neighbour sides of B_FRONT corresponding to front's edges // edges of adjacent sides of B_FRONT corresponding to front's edges
EQuadEdge edgeOfFront[4] = { Q_BOTTOM, Q_RIGHT, Q_TOP, Q_LEFT }; EQuadEdge edgeOfFront[4] = { Q_BOTTOM, Q_RIGHT, Q_TOP, Q_LEFT };
EQuadEdge edgeToFind [4] = { Q_BOTTOM, Q_LEFT, Q_BOTTOM, Q_LEFT }; EQuadEdge edgeOfAdj [4] = { Q_BOTTOM, Q_LEFT, Q_BOTTOM, Q_LEFT };
for ( int i = Q_BOTTOM; ok && i <= Q_LEFT; ++i ) // first find all sides detectable w/o advanced analysis,
ok = ( block._side[i] = findBlockSide( B_FRONT, edgeOfFront[i], edgeToFind[i])); // then repeat the search, which then may pass without advanced analysis
if ( ok ) for ( int advAnalys = 0; advAnalys < 2; ++advAnalys )
ok = ( block._side[B_BACK] = findBlockSide( B_TOP, Q_TOP, Q_TOP )); {
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 ) if ( ok )
{ {
// check if just found block is same as one of previously found // check if just found block is same as one of previously found
bool isSame = false; bool isSame = false;
for ( int i = 1; i < _blocks.size() && !isSame; ++i ) for ( int i = 1; i < _blocks.size() && !isSame; ++i )
{ isSame = ( block._corners == _blocks[i-1]._corners );
_Block& prevBlock = _blocks[i-1];
isSame = true;
for ( int j = 0; j < 6 && isSame; ++j )
isSame = prevBlock.hasSide( block._side[ j ]);
}
ok = !isSame; ok = !isSame;
} }
// count the found sides // count the found sides
_DUMP_(endl); _DUMP_(endl << "** Block " << _blocks.size() << " valid: " << block.isValid());
for (int i = 0; i < B_UNDEFINED; ++i ) 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 ( block._side[ i ] )
{ {
if ( ok && i != B_FRONT) if ( ok && i != B_FRONT)
@ -497,22 +555,24 @@ namespace
setSideBoundToBlock( *block._side[ i ]._side ); setSideBoundToBlock( *block._side[ i ]._side );
nbBlockSides--; nbBlockSides--;
} }
_DUMP_("Corner 0,0 "<< block._side[ i ].cornerNode(0,0)); _DUMP_("\t corners "<<
_DUMP_("Corner 1,0 "<< block._side[ i ].cornerNode(1,0)); block._side[ i ].cornerNode(0,0)->GetID() << ", " <<
_DUMP_("Corner 1,1 "<< block._side[ i ].cornerNode(1,1)); block._side[ i ].cornerNode(1,0)->GetID() << ", " <<
_DUMP_("Corner 0,1 "<< block._side[ i ].cornerNode(0,1)); block._side[ i ].cornerNode(1,1)->GetID() << ", " <<
block._side[ i ].cornerNode(0,1)->GetID() << ", "<<endl);
} }
else else
{ {
_DUMP_("Not found"<<endl); _DUMP_("\t not found"<<endl);
} }
} }
if ( !ok ) if ( !ok )
block._side[0] = block._side[1] = block._side[2] = block.clear();
block._side[3] = block._side[4] = block._side[5] = 0;
else else
nbBlocks++; nbBlocks++;
} }
_DUMP_("Nb found blocks "<< nbBlocks <<endl);
if ( nbBlocks == 0 && _error.empty() ) if ( nbBlocks == 0 && _error.empty() )
return BAD_MESH_ERR; return BAD_MESH_ERR;
@ -525,7 +585,9 @@ namespace
*/ */
//================================================================================ //================================================================================
bool _Skin::fillSide( _BlockSide& side, const SMDS_MeshElement* cornerQuad) bool _Skin::fillSide( _BlockSide& side,
const SMDS_MeshElement* cornerQuad,
const SMDS_MeshNode* nCorner)
{ {
// Find out size of block side mesured in nodes and by the way find two rows // Find out size of block side mesured in nodes and by the way find two rows
// of nodes in two directions. // of nodes in two directions.
@ -533,13 +595,6 @@ namespace
int x, y, nbX, nbY; int x, y, nbX, nbY;
const SMDS_MeshElement* firstQuad = cornerQuad; const SMDS_MeshElement* firstQuad = cornerQuad;
{ {
// get corner node of cornerQuad
const SMDS_MeshNode* nCorner = 0;
for ( int i = 0; i < 4 && !nCorner; ++i )
if ( isCornerNode( firstQuad->GetNode(i)))
nCorner = firstQuad->GetNode(i);
if ( !nCorner ) return false;
// get a node on block edge // get a node on block edge
int iCorner = firstQuad->GetNodeIndex( nCorner ); int iCorner = firstQuad->GetNodeIndex( nCorner );
const SMDS_MeshNode* nOnEdge = firstQuad->GetNode( (iCorner+1) % 4); 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, _OrientedBlockSide _Skin::findBlockSide( EBoxSides startBlockSide,
EQuadEdge sharedSideEdge1, EQuadEdge sharedSideEdge1,
EQuadEdge sharedSideEdge2) EQuadEdge sharedSideEdge2,
bool withGeometricAnalysis)
{ {
_Block& block = _blocks.back(); _Block& block = _blocks.back();
_OrientedBlockSide& side1 = block._side[ startBlockSide ]; _OrientedBlockSide& side1 = block._side[ startBlockSide ];
@ -637,35 +700,45 @@ namespace
set< _BlockSide* > sidesOnEdge = _edge2sides[ edge ]; // copy a set set< _BlockSide* > sidesOnEdge = _edge2sides[ edge ]; // copy a set
// exclude loaded sides of block from sidesOnEdge // exclude loaded sides of block from sidesOnEdge
int nbLoadedSides = 0; for (int i = 0; i < NB_BLOCK_SIDES; ++i )
for (int i = 0; i < B_UNDEFINED; ++i )
{
if ( block._side[ i ] ) if ( block._side[ i ] )
{
nbLoadedSides++;
sidesOnEdge.erase( block._side[ i ]._side ); sidesOnEdge.erase( block._side[ i ]._side );
}
}
int nbSidesOnEdge = sidesOnEdge.size(); int nbSidesOnEdge = sidesOnEdge.size();
_DUMP_("nbSidesOnEdge "<< nbSidesOnEdge << " " << n1->GetID() << "-" << n2->GetID() ); _DUMP_("nbSidesOnEdge "<< nbSidesOnEdge << " " << n1->GetID() << "-" << n2->GetID() );
if ( nbSidesOnEdge == 0 ) if ( nbSidesOnEdge == 0 )
return 0; return 0;
_BlockSide* foundSide = 0; _BlockSide* foundSide = 0;
if ( nbSidesOnEdge == 1 /*|| nbSidesOnEdge == 2 && nbLoadedSides == 1 */) if ( nbSidesOnEdge == 1 )
{ {
foundSide = *sidesOnEdge.begin(); foundSide = *sidesOnEdge.begin();
} }
else else
{ {
// Select one of found sides most close to startBlockSide set< _BlockSide* >::iterator sideIt = sidesOnEdge.begin();
int nbLoadedSides = block.nbSides();
if ( nbLoadedSides > 1 )
{
// 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;
}
}
// gravity center of already loaded block sides if ( !foundSide )
gp_XYZ gc(0,0,0); {
for (int i = 0; i < B_UNDEFINED; ++i ) if ( !withGeometricAnalysis ) return 0;
if ( block._side[ i ] )
gc += block._side[ i ]._side->getGC(); // Select one of found sides most close to startBlockSide
gc /= nbLoadedSides;
gp_XYZ p1 ( n1->X(),n1->Y(),n1->Z()), p2 (n2->X(),n2->Y(),n2->Z()); gp_XYZ p1 ( n1->X(),n1->Y(),n1->Z()), p2 (n2->X(),n2->Y(),n2->Z());
gp_Vec p1p2( p1, p2 ); gp_Vec p1p2( p1, p2 );
@ -678,8 +751,7 @@ namespace
<< side1Dir.X() << ", " << side1Dir.Y() << ", " << side1Dir.Z() << ")" ); << side1Dir.X() << ", " << side1Dir.Y() << ", " << side1Dir.Z() << ")" );
map < double , _BlockSide* > angleOfSide; map < double , _BlockSide* > angleOfSide;
set< _BlockSide* >::iterator sideIt = sidesOnEdge.begin(); for (sideIt = sidesOnEdge.begin(); sideIt != sidesOnEdge.end(); ++sideIt )
for (; sideIt != sidesOnEdge.end(); ++sideIt )
{ {
_BlockSide* sideI = *sideIt; _BlockSide* sideI = *sideIt;
const SMDS_MeshElement* faceI = sideI->getCornerFace( n1 ); const SMDS_MeshElement* faceI = sideI->getCornerFace( n1 );
@ -688,16 +760,33 @@ namespace
// compute angle of (sideIDir projection to pln) and (X dir of pln) // compute angle of (sideIDir projection to pln) and (X dir of pln)
gp_Vec2d sideIDirProj( sideIDir * pln.XDirection(), sideIDir * pln.YDirection()); gp_Vec2d sideIDirProj( sideIDir * pln.XDirection(), sideIDir * pln.YDirection());
double angle = sideIDirProj.Angle( gp::DX2d() ); double angle = sideIDirProj.Angle( gp::DX2d() );
if ( angle < 0 ) angle += 2 * PI; if ( angle < 0 ) angle += 2 * PI; // angle [0-2*PI]
angleOfSide.insert( make_pair( angle, sideI )); angleOfSide.insert( make_pair( angle, sideI ));
_DUMP_(" "<< sideI << " - side dir (" _DUMP_(" "<< sideI << " - side dir ("
<< sideIDir.X() << ", " << sideIDir.Y() << ", " << sideIDir.Z() << ")" << sideIDir.X() << ", " << sideIDir.Y() << ", " << sideIDir.Z() << ")"
<< " angle " << angle); << " 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_Vec gcDir( p1, gc );
gp_Vec2d gcDirProj( gcDir * pln.XDirection(), gcDir * pln.YDirection()); gp_Vec2d gcDirProj( gcDir * pln.XDirection(), gcDir * pln.YDirection());
double gcAngle = gcDirProj.Angle( gp::DX2d() ); double gcAngle = gcDirProj.Angle( gp::DX2d() );
foundSide = gcAngle < 0 ? angleOfSide.rbegin()->second : angleOfSide.begin()->second; foundSide = gcAngle < 0 ? angleOfSide.rbegin()->second : angleOfSide.begin()->second;
}
}
_DUMP_(" selected "<< foundSide ); _DUMP_(" selected "<< foundSide );
} }
@ -759,9 +848,14 @@ namespace
row2.push_back( n1 = oppositeNode( quad, i1 )); 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 // Find the rest nodes
TIDSortedElemSet emptySet, avoidSet; TIDSortedElemSet emptySet, avoidSet;
while ( !isCornerNode( n2 )) //while ( !isCornerNode( n2 ))
while ( nDesc == _NodeDescriptor( n2 ))
{ {
avoidSet.clear(); avoidSet.insert( quad ); avoidSet.clear(); avoidSet.insert( quad );
quad = SMESH_MeshEditor::FindFaceInSet( n1, n2, emptySet, avoidSet, &i1, &i2 ); quad = SMESH_MeshEditor::FindFaceInSet( n1, n2, emptySet, avoidSet, &i1, &i2 );
@ -804,7 +898,31 @@ namespace
return SMDS_Mesh::FindFace(n1, n2, n3, n4 ); 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 //function : StdMeshers_HexaFromSkin_3D

View File

@ -1483,6 +1483,9 @@ bool StdMeshers_Quadrangle_2D::ComputeQuadPref (SMESH_Mesh & aMesh,
const vector<UVPtStruct>& uv_et = quad->side[2]->GetUVPtStruct(true,1 ); const vector<UVPtStruct>& uv_et = quad->side[2]->GetUVPtStruct(true,1 );
const vector<UVPtStruct>& uv_el = quad->side[3]->GetUVPtStruct(false,0); const vector<UVPtStruct>& 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 // arrays for normalized params
//cout<<"Dump B:"<<endl; //cout<<"Dump B:"<<endl;
TColStd_SequenceOfReal npb, npr, npt, npl; TColStd_SequenceOfReal npb, npr, npt, npl;

View File

@ -50,6 +50,8 @@
#ifdef WIN32 #ifdef WIN32
# include <algorithm> # include <algorithm>
#endif #endif
#include <math.h>
#include <limits>
#include <Basics_Utils.hxx> #include <Basics_Utils.hxx>
@ -262,6 +264,15 @@ void StdMeshersGUI_DistrPreview::update()
showError(); showError();
return; 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<double>::max()/100.;
#endif
// if ( y[i] > 1e3 )
// y[i] = 1e3;
if( i==0 || y[i]<min_y ) if( i==0 || y[i]<min_y )
min_y = y[i]; min_y = y[i];
if( i==0 || y[i]>max_y ) if( i==0 || y[i]>max_y )

View File

@ -105,6 +105,14 @@
<source>ICON_SMESH_TREE_ALGO_CompositeSegment_1D</source> <source>ICON_SMESH_TREE_ALGO_CompositeSegment_1D</source>
<translation>mesh_tree_algo_regular.png</translation> <translation>mesh_tree_algo_regular.png</translation>
</message> </message>
<message>
<source>ICON_SMESH_TREE_ALGO_UseExisting_2D</source>
<translation>mesh_tree_algo_existing_2D.png</translation>
</message>
<message>
<source>ICON_SMESH_TREE_ALGO_UseExisting_1D</source>
<translation>mesh_tree_algo_regular.png</translation>
</message>
<message> <message>
<source>ICON_SMESH_TREE_ALGO_Hexa_3D</source> <source>ICON_SMESH_TREE_ALGO_Hexa_3D</source>
<translation>mesh_tree_algo_hexa.png</translation> <translation>mesh_tree_algo_hexa.png</translation>
@ -129,6 +137,14 @@
<source>ICON_SMESH_TREE_ALGO_Quadrangle_2D</source> <source>ICON_SMESH_TREE_ALGO_Quadrangle_2D</source>
<translation>mesh_tree_algo_quad.png</translation> <translation>mesh_tree_algo_quad.png</translation>
</message> </message>
<message>
<source>ICON_SMESH_TREE_ALGO_RadialQuadrangle_1D2D</source>
<translation>mesh_tree_algo_radial_quadrangle_1D2D.png</translation>
</message>
<message>
<source>ICON_SMESH_TREE_ALGO_Prism_3D</source>
<translation>mesh_tree_algo_prism.png</translation>
</message>
<message> <message>
<source>ICON_SMESH_TREE_ALGO_RadialPrism_3D</source> <source>ICON_SMESH_TREE_ALGO_RadialPrism_3D</source>
<translation>mesh_tree_algo_radial_prism.png</translation> <translation>mesh_tree_algo_radial_prism.png</translation>
@ -139,7 +155,7 @@
</message> </message>
<message> <message>
<source>ICON_SMESH_TREE_ALGO_SegmentAroundVertex_0D</source> <source>ICON_SMESH_TREE_ALGO_SegmentAroundVertex_0D</source>
<translation>mesh_tree_algo_regular.png</translation> <translation>mesh_tree_algo_0D.png</translation>
</message> </message>
<message> <message>
<source>ICON_SMESH_TREE_HYPO_Arithmetic1D</source> <source>ICON_SMESH_TREE_HYPO_Arithmetic1D</source>