<li>\ref max_element_area_anchor "Max Element Area"</li>
<li>\ref length_from_edges_anchor "Length from Edges"</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>
<br>
<b>See Also</b> a sample TUI Script of a
\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>
*/
<li>Propagation of 1D Hypothesis on opposite edges</li>
<li>Non conform mesh allowed</li>
<li>Quadratic mesh</li>
+<li>Quadrangle preference</li>
+<li>Triangle preference</li>
</ul>
The choice of a hypothesis depends on:
\image html image146.png
From this submenu select the type of element which you would like to add to your mesh.
-\note All dialogs intended for adding nodes or elements to mesh (except dialog for adding
-0D elements) provide a possibility to add these nodes/elements to the specified group
-(or to create the group if it doesn't exist). <b>Add to group</b> box allows to choose
-an existing group for created node or element or to specify a name for new group.
+
+\note All dialogs for adding new node or element to the mesh (except for
+the dialog for 0D elements) provide a possibility to add it
+automatically to the specified group or to create it anew using
+<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>
<b>See Also</b> sample TUI Scripts of
\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
by three points: first, middle and last. All more complex \b Quadratic
\image html image152.png
-\note All dialogs intended for adding quadratic elements to mesh provide a possibility
-to add these elements to the specified group (or to create the group if it doesn't exist).
-<b>Add to group</b> box allows to choose an existing group for created element or
-to specify a name for new group.
+\note All dialogs for adding quadratic element to the mesh
+provide a possibility to add new element
+automatically to the specified group or to create it anew using
+<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
triangle by selecting them in the 3D viewer with pressed Shift
propagation are defined on an edge of a quadrangular face, the
opposite edge will have the same hypothesis, unless another hypothesis
has been locally defined on the opposite edge.
-
+
<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.
+
-*/
\ No newline at end of file
+*/
</li>
-</ol>
\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.
+
+<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>
-<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>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:
<ul>
<li><i>3D</i> <b>Tetrahedron (Netgen)</b> with Hypothesis<b>Max Element Volume</b></li>
(Number of Segments = 8)</li>
</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:
<ul>
<li><i>2D</i> Netgen 1D-2D with Hypothesis <b>Netgen Simple parameters</b>
(Number of Segments = 12)</li>
</ul>
-The submeshes can become concurrent if their algorithms leads to mesh shared subshape
-with different algorithms (or different algorithms parameters, i.e. hypothesises).
-In fact, we have three submeshes with concurrent algorithms, because
-they have different hypothesises assigned to them.
+The submeshes become concurrent if they share subshapes that can be meshed
+with different algorithms (or different hypothesises).
+In the example, we have three submeshes with concurrent algorithms,
+because they have different hypotheses.
-The first mesh computation made with:
+The first mesh computation is made with:
\image html mesh_order_123.png
<center><em>"Mesh order SubMesh_1, SubMesh_2, SubMesh_3"</em></center>
\image html mesh_order_123_res.png
<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
<center><em>"Mesh order SubMesh_2, SubMesh_1, SubMesh_3"</em></center>
\image html mesh_order_213_res.png
<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
<center><em>"Mesh order SubMesh_3, SubMesh_2, SubMesh_1"</em></center>
\image html mesh_order_321_res.png
<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
-elements and different mesh discretisation on shared edges (edges
+As we can see, each mesh computation has a different number of result
+elements and a different mesh discretisation on the shared edges (the edges
that are shared between <b>Face_1</b>, <b>Face_2</b> and <b>Face_3</b>)
-Additionally, submesh priority (order of algorithms to be applied) can
-be modified not only in separate dialog box, but in <b>Preview</b>
-also. This helps to preview different mesh results, modifying submesh
-order.
+Additionally, submesh priority (the order of applied algorithms) can
+be modified not only in a separate dialog box, but also in the
+<b>Preview</b>. This helps to preview different mesh results,
+modifying the order of submeshes.
\image html mesh_order_preview.png
<center><em>"Preview with submesh priority list box"</em></center>
-If there are no concurrent submeshes under Mesh object, then user will see the
-following information dialog box
+If there are no concurrent submeshes under the Mesh object, the user will see the
+following information.
\image html mesh_order_no_concurrent.png
<center><em>"No concurrent submeshes detected"</em></center>
-and no mesh order list box will appear in Preview dialog box.
</ol>
SALOME Platform distinguishes between the two Group types:
<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
two possible ways.
\ref tui_create_standalone_group "Create a Standalone Group"
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
\b type field. <b>Group on geometry</b> contains the elements of a certain type
\ref tui_create_group_on_geometry "Create a Group on Geometry"
operation.
-*/
\ No newline at end of file
+*/
group.</li>
</ol>
+\anchor convert_to_standalone
<em>To convert an existing group on geometry into standalone group
of elements and modify:</em>
<ol>
<ul>
<li>the coordinates of the point;</li>
<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"
-means to find elements of any type except nodes and 0D elements.</li>
+of all types related to the reference point. Choose type "All" to find
+elements of any type except for nodes and 0D elements.</li>
</ul>
</li>
allowing to highlight important elements:
<li>\subpage modifying_meshes_page "modifying meshes" with a vast
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>
Almost all mesh module functionalities are accessible via
\image html mergeelems_ico.png "Merge elements button"
<ol>
-<li>From the \b Modification choose \b Transformation and from its
-sub-menu select the <b>Merge elements</b> item. The following dialog box
+<li>Choose in the main menu \b Modification -> \b Transformation -> <b>Merge elements</b> item. The following dialog box
shall appear:</li>
\image html mergeelems_auto.png
<br>
<ul>
<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
-controls type.
+<li>\b Automatic or \b Manual Mode allows choosing how the elements
+are processed.
</ul>
<li><b>Automatic mode:</b>
<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>
</li>
-<li>If the \b Manual Mode is selected there are additional controls to
-manage the elements to be merged in more detail:
+<li>If the \b Manual Mode is selected, additional controls are
+available:
\image html mergeelems.png
<br>
<ul>
<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.
<ul>
<li>\b Remove button deletes the selected group from the list.</li>
<br>
<ul>
<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
-controls type.
+<li>\b Automatic or \b Manual Mode allows choosing how the nodes are
+processed.
<li>\b Tolerance is a maximum distance between nodes sufficient for
-merging, that is able in both dialog modes.</li>
+merging.</li>
</ul>
<li><b>Automatic mode:</b>
<br>
<ul>
-<li>In \b Automatic Mode to merge the Nodes, just input the tolerance
-value and confirm by \b Apply button.</li>
+<li>In the \b Automatic Mode all Nodes within the indicated tolerance
+will be merged.</li>
</ul>
</li><br>
-<li>If the \b Manual Mode is selected there are additional controls to
-manage the nodes to be merged in more detail:
+<li>If the \b Manual Mode is selected, additional controls are available:
<ul>
<li>\b Detect button generates the list of coincident nodes for the given
\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
operation.
<ul>
through a point or a vector of symmetry.</li>
<li>Unite meshes by \subpage sewing_meshes_page "sewing" free borders,
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>
<li>\subpage merging_elements_page "Merge Elements", considered coincident
within the indicated tolerance.</li>
\<pattern_name\>.smp file.
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
-coordinates of a node.</li>
-
-<li>A key-points line: indices of nodes to be mapped on geometrical
-vertices. An index n refers to a node described on an n-th line of
-section 2. The first node index is zero.</li>
-
-<li>The rest lines describe nodal connectivity of elements, one line
+-# The first line holds the total number of the pattern nodes (N).
+-# The next N lines describe nodes coordinates. Each line holds 2
+coordinates of a node for 2D pattern or 3 cordinates for 3D pattern.
+Note, that for 3D pattern only relateive values in range [0;1] are
+valid for coordinates of the nodes.
+-# A key-points line: indices of nodes to be mapped on geometrical
+vertices (for 2D pattern only). An index n refers to a node described
+on an n-th line of section 2. The first node index is zero. For 3D
+pattern key points are not specified.
+-# The rest lines describe nodal connectivity of elements, one line
for an element. A line holds indices of nodes forming an element. An
index n refers to a node described on an n-th line of the section
2. The first node index is zero. There must be 3 or 4 indices on a
-line: only 2d elements are allowed.</li>
-</ol>
+line for 2D pattern (only 2d elements are allowed) and 4, 5, 6 or 8
+indices for 3D pattern (only 3d elements are allowed).
The 2D pattern must contain at least one element and at least one
key-point. All key-points must lay on boundaries.
-An example of a simple smp file and a preview of a pattern described
-in this file:
-
-\image html image94.gif
+The 3D pattern must contain at least one element.
+
+An example of a simple 2D pattern smp file:
+
+\code
+!!! SALOME 2D mesh pattern file
+!!!
+!!! Nb of points:
+9
+ 200 0 !- 0
+ 100 0 !- 1
+ 0 0 !- 2
+ 0 -100 !- 3
+ 0 -200 !- 4
+ 100 -200 !- 5
+ 200 -200 !- 6
+ 200 -100 !- 7
+ 100 -100 !- 8
+!!! Indices of 4 key-points
+ 2 0 4 6
+!!! Indices of points of 6 elements
+ 0 1 8
+ 8 5 6 7
+ 2 3 8
+ 8 3 4 5
+ 8 7 0
+ 8 1 2
+\endcode
+
+The image below provides a preview of above described pattern:
+
+\image html pattern2d.png
+
+An example of a simple 3D pattern smp file:
+
+\code
+!!! SALOME 3D mesh pattern file
+!!!
+!!! Nb of points:
+9
+ 0 0 0 !- 0
+ 1 0 0 !- 1
+ 0 1 0 !- 2
+ 1 1 0 !- 3
+ 0 0 1 !- 4
+ 1 0 1 !- 5
+ 0 1 1 !- 6
+ 1 1 1 !- 7
+ 0.5 0.5 0.5 !- 8
+!!! Indices of points of 6 elements:
+ 0 1 5 4 8
+ 7 5 1 3 8
+ 3 2 6 7 8
+ 2 0 4 6 8
+ 0 2 3 1 8
+ 4 5 7 6 8
+\endcode
<br><h2>Application of pattern mapping</h2>
\image html patternmapping1.png
+<center><b> 2D Pattern Mapping dialog box</b></center>
+
\image html patternmapping2.png
+<center><b> 3D Pattern Mapping dialog box</b></center>
+
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
-key-points in the pattern; the number of key-points on internal
-boundaries of a pattern must also be equal to the number of vertices
-on internal boundaries of a face;</li>
-<li>a vertex to which the first key-point should be mapped;</li>
-<li>reverse or not the order of key-points. (The order of vertices of
-a face is counterclockwise looking from outside).</li>
-</ul>
+
+-# For 2D pattern
+ - A face having the number of vertices equal to the number of
+ key-points in the pattern; the number of key-points on internal
+ boundaries of a pattern must also be equal to the number of vertices
+ on internal boundaries of a face;
+ - A vertex to which the first key-point should be mapped;
+ - Reverse or not the order of key-points. (The order of vertices of
+ a face is counterclockwise looking from outside).
+-# For 3D pattern
+ - 3D block (Solid) object;
+ - Two vertices that specify the order of nodes in the resulting
+ mesh.
Then you either load a .smp pattern file previously created manually
by clicking on the <em>"Load pattern"</em> button, or click on the \b
-New button for automatic generation.
-\n For an automatic generation you just specify a geometrical face
-having a mesh built on it. Mesh nodes lying on face vertices become
-key-points. Additionally, you may choose the way of getting nodes
-coordinates by <b>projecting nodes on the face</b> instead of using
+New button for automatic generation of the pattern.
+
+For an automatic generation you just specify a geometrical face (for
+2D) or solid (for 3d) having a mesh built on it. Mesh nodes lying on
+face vertices become key-points of 2D pattern. Additionally, for 2D
+pattern you may choose the way of getting nodes coordinates by
+<b>projecting nodes on the face</b> instead of using
"positions on face" generated by mesher (if there is any). Faces
having a seam edge can't be used for automatic pattern creation.
When creating a pattern from an existing mesh, there are two possible
cases:
-<ol>
-<li>A sub-mesh on face is selected. A pattern is created from the 2d
-elements bound to a face by mesher. Node coordinates are either
+
+- A sub-mesh on face/solid is selected. A pattern is created from the 2d/3d
+elements bound to a face/solid by mesher. For 2D pattern, node coordinates are either
"positions on face" computed by mesher, or coordinates got by node
-projection on a geometrical surface, according to your choice.</li>
-<li>A mesh where the main shape is a face, is selected. A pattern is
-created from all the 2d elements in a mesh. If all mesh elements are
-build by mesher, the user can select the way of getting nodes
-coordinates, else all nodes are projected on a face surface.</li>
-</ol>
+projection on a geometrical surface, according to the user choice. For
+3D pattern, nodes coordinates correspond to the nodes computed by mesher.
+- A mesh where the main shape is a face/solid, is selected. A pattern is
+created from all the 2d/3d elements in a mesh. In addition, for 2D
+pattern, if all mesh elements are build by mesher, the user can select
+the way of getting nodes coordinates, else all nodes are projected on
+a face surface.
\image html a-patterntype.png
+<center><b> 2D Pattern Creation dialog box</b></center>
+
\image html a-patterntype1.png
+<center><b> 3D Pattern Creation dialog box</b></center>
+
<br><h2>Mapping algorithm</h2>
-The mapping algorithm is as follows:
-<ol>
-<li>Key-points are set in the order that they are encountered when
-walking along a pattern boundary so that elements are on the left. The
-first key-point is preserved.
-</li>
-
-<li>Find geometrical vertices corresponding to key-points by vertices
-order in a face boundary; here, "Reverse order of key-points" flag is
-taken into account.
-
-\image html image95.gif
-</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
-mapped on a geometrical edge limited by corresponding geometrical
-vertices. Node position on an edge reflects its distance from two
-key-points.
-
-\image html image96.gif
-</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
-lays at the intersection of two iso-lines, each of which intersects a
-pattern boundary at least at two points. Knowing mapped positions of
-boundary nodes, we find where isoline-boundary intersection points are
-mapped to, and hence we can find mapped isolines direction and then,
-two node positions on two mapped isolines. The eventual mapped
-position of a node is found as an average of positions on mapped
-isolines.
-
-\image html image97.gif
-</li>
-</ol>
-
-<br><b>See Also</b> a sample TUI Script of a
+The mapping algorithm for 2D case is as follows:
+
+- Key-points are set in the order that they are encountered when
+ walking along a pattern boundary so that elements are on the left. The
+ first key-point is preserved.
+- Find geometrical vertices corresponding to key-points by vertices
+ order in a face boundary; here, "Reverse order of key-points" flag is
+ taken into account. \image html image95.gif
+- Boundary nodes of a pattern are mapped onto edges of a face: a
+ node located between certain key-points on a pattern boundary is
+ mapped on a geometrical edge limited by corresponding geometrical
+ vertices. Node position on an edge reflects its distance from two
+ key-points. \image html image96.gif
+- Coordinates of a non-boundary node in a parametric space of a face
+ are defined as following. In a parametric space of a pattern, a node
+ lays at the intersection of two iso-lines, each of which intersects a
+ pattern boundary at least at two points. Knowing mapped positions of
+ boundary nodes, we find where isoline-boundary intersection points are
+ mapped to, and hence we can find mapped isolines direction and then,
+ two node positions on two mapped isolines. The eventual mapped
+ position of a node is found as an average of positions on mapped
+ isolines. \image html image97.gif
+
+For 3D case the algorithm is similar.
+
+<b>See Also</b> a sample TUI Script of a
\ref tui_pattern_mapping "Pattern Mapping" operation.
*/
- Standard point markers
The Mesh module provides a set of predefined point marker shapes
-which can be used to display points in 3D viewer.
+which can be used to display points in the 3D viewer.
Each standard point marker has two attributes: type (defines shape
form) and scale factor (defines shape size).
It is also possible to load a point marker shape from an external file.
This file should provide a description of the point texture as a set
-of lines; each line is represented as sequence of "0" and "1" symbols,
+of lines; each line is represented as a sequence of "0" and "1" symbols,
where "1" symbol means an opaque pixel and "0" symbol means a
-transparent pixel. The width of the texture correspond to the length
+transparent pixel. The width of the texture corresponds to the length
of the longest line in the file, expanded to the nearest byte-aligned
value. The height of the texture is equal to the number of non-empty
lines in the file. Note that missing symbols are replaced by "0".
<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
-and union 3 face (along axis Z) to group "gr_faces"
+and union 3 faces (along axis Z) to group "gr_faces"
\image html scaleinit02.png
-2. Perform scale operation for whole mesh with creation of new mesh:
+2. Perform scale operation for the whole mesh and create a new mesh:
\image html scale03.png
-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
-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
-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
-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
<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
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
list</b> button allows to sort the list of IDs. \b Filter button allows to
apply a definite filter to the selection of volumes.
<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
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>
</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
list.</li>
</ul>
# In this case it uses "Default Nb of Segments" preferences parameter to discretize edges
mesh.Compute()
-# The Radial Quadrange uses global or local 1d hypotheses if no its own hypotheses assigned.
+# The Radial Quadrange uses global or local 1d hypotheses if it does
+# not have its own hypotheses.
# Define global hypotheses to discretize radial edges and a local one for circular edge
global_Nb_Segments = mesh.Segment().NumberOfSegments(5)
local_Nb_Segments = mesh.Segment(circle).NumberOfSegments(10)
else: print "New Node has been added with ID ", new_id
\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>
\anchor tui_add_edge
<h3>Add Edge</h3>
\code
import geompy
-
import smesh
# define the geometry
isDone = Mesh_2.Compute()
if not isDone: print 'Mesh Mesh_2 : computation failed'
-# create a pattern
+# create a 2d pattern
pattern = smesh.GetPattern()
isDone = pattern.LoadFromFace(Mesh_2.GetMesh(), Face_2, 0)
if (isDone != 1): print 'LoadFromFace :', pattern.GetErrorCode()
# apply the pattern to a face of the first mesh
-pattern.ApplyToMeshFaces(Mesh_1.GetMesh(), [17], 0, 0)
-
+facesToSplit = Mesh_1.GetElementsByType(smesh.SMESH.FACE)
+print "Splitting %d rectangular face(s) to %d triangles..."%(len(facesToSplit), 2*len(facesToSplit))
+pattern.ApplyToMeshFaces(Mesh_1.GetMesh(), facesToSplit, 0, 0)
isDone = pattern.MakeMesh(Mesh_1.GetMesh(), 0, 0)
if (isDone != 1): print 'MakeMesh :', pattern.GetErrorCode()
+
+# create quadrangle mesh
+Mesh_3 = smesh.Mesh(Box_1)
+Mesh_3.Segment().NumberOfSegments(1)
+Mesh_3.Quadrangle()
+Mesh_3.Hexahedron()
+isDone = Mesh_3.Compute()
+if not isDone: print 'Mesh Mesh_3 : computation failed'
+
+# create a 3d pattern (hexahedrons)
+pattern_hexa = smesh.GetPattern()
+
+smp_hexa = """!!! Nb of points:
+15
+ 0 0 0 !- 0
+ 1 0 0 !- 1
+ 0 1 0 !- 2
+ 1 1 0 !- 3
+ 0 0 1 !- 4
+ 1 0 1 !- 5
+ 0 1 1 !- 6
+ 1 1 1 !- 7
+ 0.5 0 0.5 !- 8
+ 0.5 0 1 !- 9
+ 0.5 0.5 0.5 !- 10
+ 0.5 0.5 1 !- 11
+ 1 0 0.5 !- 12
+ 1 0.5 0.5 !- 13
+ 1 0.5 1 !- 14
+ !!! Indices of points of 4 elements:
+ 8 12 5 9 10 13 14 11
+ 0 8 9 4 2 10 11 6
+ 2 10 11 6 3 13 14 7
+ 0 1 12 8 2 3 13 10"""
+
+pattern_hexa.LoadFromFile(smp_hexa)
+
+# apply the pattern to a mesh
+volsToSplit = Mesh_3.GetElementsByType(smesh.SMESH.VOLUME)
+print "Splitting %d hexa volume(s) to %d hexas..."%(len(volsToSplit), 4*len(volsToSplit))
+pattern_hexa.ApplyToHexahedrons(Mesh_3.GetMesh(), volsToSplit,0,3)
+isDone = pattern_hexa.MakeMesh(Mesh_3.GetMesh(), True, True)
+if (isDone != 1): print 'MakeMesh :', pattern_hexa.GetErrorCode()
+
+# create one more quadrangle mesh
+Mesh_4 = smesh.Mesh(Box_1)
+Mesh_4.Segment().NumberOfSegments(1)
+Mesh_4.Quadrangle()
+Mesh_4.Hexahedron()
+isDone = Mesh_4.Compute()
+if not isDone: print 'Mesh Mesh_4 : computation failed'
+
+# create another 3d pattern (pyramids)
+pattern_pyra = smesh.GetPattern()
+
+smp_pyra = """!!! Nb of points:
+9
+ 0 0 0 !- 0
+ 1 0 0 !- 1
+ 0 1 0 !- 2
+ 1 1 0 !- 3
+ 0 0 1 !- 4
+ 1 0 1 !- 5
+ 0 1 1 !- 6
+ 1 1 1 !- 7
+ 0.5 0.5 0.5 !- 8
+ !!! Indices of points of 6 elements:
+ 0 1 5 4 8
+ 7 5 1 3 8
+ 3 2 6 7 8
+ 2 0 4 6 8
+ 0 2 3 1 8
+ 4 5 7 6 8"""
+
+pattern_pyra.LoadFromFile(smp_pyra)
+
+# apply the pattern to a face mesh
+volsToSplit = Mesh_4.GetElementsByType(smesh.SMESH.VOLUME)
+print "Splitting %d hexa volume(s) to %d hexas..."%(len(volsToSplit), 6*len(volsToSplit))
+pattern_pyra.ApplyToHexahedrons(Mesh_4.GetMesh(), volsToSplit,1,0)
+isDone = pattern_pyra.MakeMesh(Mesh_4.GetMesh(), True, True)
+if (isDone != 1): print 'MakeMesh :', pattern_pyra.GetErrorCode()
\endcode
<br>
Quadrangle_2D = Mesh1.Quadrangle()
isDone = Mesh1.Compute()
-#Perform scale opration for whole mesh with creation of new mesh
+#Perform scale opration for the whole mesh and creation of a new mesh
newMesh = Mesh1.ScaleMakeMesh(Mesh1,SMESH.PointStruct(100,100,200),[0.5,0.3,0.7],True,"ScaledMesh")
-#Perform scale operation for whole mesh with copy of elements
+#Perform scale operation for the whole mesh and copy elements
Mesh1.Scale(Mesh1,SMESH.PointStruct(200,100,100),[0.5,0.5,0.5],True,True)
-#Perform scale opration for two edges with moving of elements
+#Perform scale opration for two edges and move elements
Mesh1.Scale([1,2],SMESH.PointStruct(-100,100,100),[0.8,1.0,0.7],False)
-#Perform scale opration for one face with moving of elements
+#Perform scale opration for one face and move elements
Mesh1.Scale([21],SMESH.PointStruct(0,200,200),[0.7,0.7,0.7],False)
\endcode
<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>
<li><b>Orientation of faces</b> - shows vectors of orientation of
-faces of the selected mesh. Vector is shown for each 2D mesh element
-and for each free face of 3D mesh element. Vector direction is calculated by
-the first three nodes of face as a cross product of vectors n1-n2 and n1-n3.</li>
+faces of the selected mesh. The orientation vector is shown for each 2D mesh element
+and for each free face of a 3D mesh element. the vector direction is calculated by
+the first three nodes of the face produced by vectors n1-n2 and n1-n3.</li>
<li>\subpage colors_size_page "Colors / Size" - allows to select color and size of
meshes.</li>
<li>\subpage transparency_page "Transparency" - allows to change the
mesh_tree_algo_hexa.png \
mesh_tree_algo_mefisto.png \
mesh_tree_algo.png \
+ mesh_tree_algo_0D.png \
mesh_tree_algo_quad.png \
mesh_tree_algo_regular.png \
mesh_tree_algo_tetra.png \
mesh_conv_to_quad.png \
mesh_tree_hypo_layers_distribution.png \
mesh_tree_algo_radial_prism.png \
+ mesh_tree_algo_radial_quadrangle_1D2D.png \
+ mesh_tree_algo_existing_2D.png \
+ mesh_tree_algo_prism.png \
mesh_tree_algo_projection_2d.png \
mesh_hypo_source_edge.png \
mesh_hypo_source_3d.png \
<parameter name="NETGENPlugin" value="${NETGENPlugin_ROOT_DIR}/share/salome/resources/netgenplugin"/>
<parameter name="GHS3DPlugin" value="${GHS3DPlugin_ROOT_DIR}/share/salome/resources/ghs3dplugin"/>
<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"/>
</section>
</document>
ReplaceElemInGroups(volume, NewVolume, meshDS);
}
}
- if ( !theForce3d ) {
+ if ( !theForce3d && !getenv("NO_FixQuadraticElements")) {
aHelper.SetSubShape(0); // apply to the whole mesh
aHelper.FixQuadraticElements();
}
double SMESH_MesherHelper::GetNodeU(const TopoDS_Edge& E,
const SMDS_MeshNode* n,
+ const SMDS_MeshNode* inEdgeNode,
bool* check)
{
double param = 0;
- const SMDS_PositionPtr Pos = n->GetPosition();
- if(Pos->GetTypeOfPosition()==SMDS_TOP_EDGE) {
- const SMDS_EdgePosition* epos =
- static_cast<const SMDS_EdgePosition*>(n->GetPosition().get());
+ const SMDS_PositionPtr pos = n->GetPosition();
+ if ( pos->GetTypeOfPosition()==SMDS_TOP_EDGE )
+ {
+ const SMDS_EdgePosition* epos = static_cast<const SMDS_EdgePosition*>( pos.get() );
param = epos->GetUParameter();
}
- else if(Pos->GetTypeOfPosition()==SMDS_TOP_VERTEX) {
- SMESHDS_Mesh * meshDS = GetMeshDS();
- int vertexID = n->GetPosition()->GetShapeId();
- const TopoDS_Vertex& V = TopoDS::Vertex(meshDS->IndexToShape(vertexID));
- param = BRep_Tool::Parameter( V, E );
+ else if( pos->GetTypeOfPosition() == SMDS_TOP_VERTEX )
+ {
+ if ( inEdgeNode && TopExp::FirstVertex( E ).IsSame( TopExp::LastVertex( E ))) // issue 0020128
+ {
+ Standard_Real f,l;
+ BRep_Tool::Range( E, f,l );
+ double uInEdge = GetNodeU( E, inEdgeNode );
+ param = ( fabs( uInEdge - f ) < fabs( l - uInEdge )) ? f : l;
+ }
+ else
+ {
+ SMESHDS_Mesh * meshDS = GetMeshDS();
+ int vertexID = pos->GetShapeId();
+ const TopoDS_Vertex& V = TopoDS::Vertex(meshDS->IndexToShape(vertexID));
+ param = BRep_Tool::Parameter( V, E );
+ }
}
if ( check )
- *check = CheckNodeU( E, n, param, BRep_Tool::Tolerance( E ));
+ {
+ double tol = BRep_Tool::Tolerance( E );
+ double f,l; BRep_Tool::Range( E, f,l );
+ bool force = ( param < f-tol || param > l+tol );
+ if ( !force && pos->GetTypeOfPosition()==SMDS_TOP_EDGE )
+ force = ( GetMeshDS()->ShapeToIndex( E ) != pos->GetShapeId() );
+
+ *check = CheckNodeU( E, n, param, tol, force );
+ }
return param;
}
{
((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;
E = TopoDS::Edge(myShape);
edgeID = myShapeID;
}
- u[0] = GetNodeU(E,n1, force3d ? 0 : &uvOK[0]);
- u[1] = GetNodeU(E,n2, force3d ? 0 : &uvOK[1]);
+ u[0] = GetNodeU(E,n1,n2, force3d ? 0 : &uvOK[0]);
+ u[1] = GetNodeU(E,n2,n1, force3d ? 0 : &uvOK[1]);
}
if(!force3d)
{
*/
double GetNodeU(const TopoDS_Edge& theEdge,
const SMDS_MeshNode* theNode,
+ const SMDS_MeshNode* inEdgeNode=0,
bool* check=0);
/*!
* \brief Return node UV on face
#include "SMESH_MesherHelper.hxx"
#include "SMESH_subMesh.hxx"
+#include <Basics_Utils.hxx>
#include "utilities.h"
using namespace std;
{
MESSAGE("Load( file ) ");
+ Kernel_Utils::Localizer loc;
+
// file structure:
// ! This is a comment
bool SMESH_Pattern::Save (ostream& theFile)
{
MESSAGE(" ::Save(file) " );
+
+ Kernel_Utils::Localizer loc;
+
if ( !IsLoaded() ) {
MESSAGE(" Pattern not loaded ");
return setErrorCode( ERR_SAVE_NOT_LOADED );
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();
+ }
+ }
+}
+
//=============================================================================
/*!
*
// Set property for precision value for spinboxes
for ( ii = 0; ii < nbQuantities; ii++ ){
- setPreferenceProperty( precs[ii], "min", -10 );
- setPreferenceProperty( precs[ii], "max", 10 );
+ setPreferenceProperty( precs[ii], "min", -14 );
+ setPreferenceProperty( precs[ii], "max", 14 );
setPreferenceProperty( precs[ii], "precision", 2 );
}
*/
void SMESHGUI::onHypothesisEdit( int result )
{
+ if( result == 1 )
+ SMESHGUI::Modified();
updateObjBrowser( true );
}
static bool automaticUpdate();
+ static void Modified( bool = true );
+
virtual LightApp_Displayer* displayer();
virtual QString engineIOR() const;
virtual void initialize( CAM_Application* );
connect(mySelectionMgr, SIGNAL(currentSelectionChanged()), SLOT(SelectionIntoArgument()));
/* to close dialog if study frame change */
connect(mySMESHGUI, SIGNAL (SignalStudyFrameChanged()), SLOT(ClickOnCancel()));
+ connect(mySMESHGUI, SIGNAL (SignalCloseAllDialogs()), SLOT(ClickOnCancel()));
if (Reverse)
connect(Reverse, SIGNAL(stateChanged(int)), SLOT(CheckBox(int)));
myEditCurrentArgument->setText("");
myBusy = false;
+
+ SMESHGUI::Modified();
}
}
connect(mySMESHGUI, SIGNAL (SignalDeactivateActiveDialog()), SLOT(DeactivateActiveDialog()));
connect(mySMESHGUI, SIGNAL (SignalStudyFrameChanged()), SLOT(ClickOnCancel()));
+ connect(mySMESHGUI, SIGNAL (SignalCloseAllDialogs()), SLOT(ClickOnCancel()));
// set selection mode
SMESH::SetPointRepresentation(true);
SetEditCorners();
updateButtons();
+
+ SMESHGUI::Modified();
}
//=================================================================================
SMESH::DisplayActor(SMESH::GetActiveWindow(), anActor);
}// end IPAL21468
+ SMESHGUI::Modified();
+
return true;
}
return false;
//
#include "SMESHGUI_ConvToQuadOp.h"
+#include "SMESHGUI.h"
#include "SMESHGUI_ConvToQuadDlg.h"
#include "SMESHGUI_Utils.h"
}
if( aResult )
{
+ SMESHGUI::Modified();
update( UF_ObjBrowser | UF_Model | UF_Viewer );
selectionDone();
}
}
//ConstructorsClicked( GetConstructorId() );
busy = false;
+
+ SMESHGUI::Modified();
}
}
myListGrp.clear();
mySelectionMgr->clearSelected();
SMESH::UpdateView();
+ SMESHGUI::Modified();
mySMESHGUI->updateObjBrowser(true);
myBlockSelection = false;
}
SMESH::UpdateView();
+ SMESHGUI::Modified();
return true;
}
ElementsLineEdit = new QLineEdit(GroupArguments);
ElementsLineEdit->setValidator(myIdValidator);
+ ElementsLineEdit->setMaxLength(-1);
myFilterBtn = new QPushButton( tr( "SMESH_BUT_FILTER" ), GroupArguments );
connect(myFilterBtn, SIGNAL(clicked()), this, SLOT(setFilters()));
if ( myMeshActor )
SMESH::Update( myMeshActor->getIO(), myMeshActor->GetVisibility() );
+ SMESHGUI::Modified();
+
if ( MakeGroupsCheck->isEnabled() && MakeGroupsCheck->isChecked() )
mySMESHGUI->updateObjBrowser(true); // new groups may appear
//SMESH::UpdateView();
LineEditElements = new QLineEdit(GroupArguments);
LineEditElements->setValidator(myIdValidator);
+ LineEditElements->setMaxLength(-1);
myFilterBtn = new QPushButton( tr( "SMESH_BUT_FILTER" ), GroupArguments );
connect(myFilterBtn, SIGNAL(clicked()), this, SLOT(setFilters()));
mySelectionMgr->clearSelected();
mySelectedObject = SMESH::SMESH_IDSource::_nil();
SelectionIntoArgument();
+
+ SMESHGUI::Modified();
}
return true;
}
if (theWg == 0)
return;
+ QStringList aStrList;
+ foreach(int id, theIds)
+ aStrList << QString::number(id);
+
if (theWg->inherits("QListWidget"))
{
- QListWidget* aListBox = qobject_cast<QListWidget*>( theWg );
- aListBox->clear();
-
- QStringList aStrList;
- QList<int>::const_iterator anIter;
- for (anIter = theIds.begin(); anIter != theIds.end(); ++anIter)
- aStrList.append(QString("%1").arg(*anIter));
-
- aListBox->addItems(aStrList);
+ qobject_cast<QListWidget*>(theWg)->clear();
+ qobject_cast<QListWidget*>(theWg)->addItems(aStrList);
}
else if (theWg->inherits("QLineEdit"))
{
- QLineEdit* aLineEdit = qobject_cast<QLineEdit*>( theWg );
- 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);
+ qobject_cast<QLineEdit*>( theWg )->setText(aStrList.join(" "));
}
}
}
}
- int aCriterionType = myTable->GetCriterionType(aRow);
- if (aList.Extent() != 1 ||
- !myTable->CurrentCell(aRow, aCol) ||
- aCriterionType != SMESH::FT_BelongToGeom &&
- aCriterionType != SMESH::FT_BelongToPlane &&
- aCriterionType != SMESH::FT_BelongToCylinder &&
- aCriterionType != SMESH::FT_BelongToGenSurface &&
- aCriterionType != SMESH::FT_LyingOnGeom)
+ QList<int> types;
+ types << SMESH::FT_BelongToGeom << SMESH::FT_BelongToPlane
+ << SMESH::FT_BelongToCylinder << SMESH::FT_BelongToGenSurface
+ << SMESH::FT_LyingOnGeom;
+ if (aList.Extent() != 1 || !myTable->CurrentCell(aRow, aCol) ||
+ !types.contains(myTable->GetCriterionType(aRow)))
return;
Handle(SALOME_InteractiveObject) anIO = aList.First();
}
}
+ SMESHGUI::Modified();
mySMESHGUI->updateObjBrowser(true);
SMESH::UpdateView(); // asv: fix of BUG PAL5515
mySelectionMgr->clearSelected();
}
}
+ SMESHGUI::Modified();
mySMESHGUI->updateObjBrowser(true);
mySelectionMgr->clearSelected();
return true;
#include "SMESHGUI_GroupOnShapeDlg.h"
#include "SMESH_TypeFilter.hxx"
+#include "SMESHGUI.h"
#include "SMESHGUI_Utils.h"
#include "SMESHGUI_GEOMGenUtils.h"
group = mesh->CreateGroupFromGEOM( elemType, name.toLatin1().data(), geom );
}
}
+ SMESHGUI::Modified();
+
update( UF_ObjBrowser | UF_Model );
init();
if ( aRes )
{
+ SMESHGUI::Modified();
getSMESHGUI()->updateObjBrowser(true);
reset();
return true;
if ( aRes )
{
+ SMESHGUI::Modified();
getSMESHGUI()->updateObjBrowser(true);
reset();
return true;
if ( aRes )
{
+ SMESHGUI::Modified();
getSMESHGUI()->updateObjBrowser(true);
reset();
return true;
if ( aRes )
{
+ SMESHGUI::Modified();
getSMESHGUI()->updateObjBrowser(true);
reset();
return true;
SMESHGUI_HypothesisDlg* Dlg = new SMESHGUI_HypothesisDlg( this, theParent );
connect( Dlg, SIGNAL( finished( int ) ), this, SLOT( onDialogFinished( int ) ) );
connect( this, SIGNAL( finished( int ) ), obj, slot.toLatin1().constData() );
+ connect( SMESHGUI::GetSMESHGUI(), SIGNAL( SignalCloseAllDialogs() ), Dlg, SLOT( reject() ));
myDlg = Dlg;
QFrame* fr = buildFrame();
if (aHypSObject) {
if (!aHypName.isEmpty())
SMESH::SetName(aHypSObject, aHypName);
+ SMESHGUI::Modified();
SMESHGUI::GetSMESHGUI()->updateObjBrowser();
return aHypothesis._retn();
}
myDlg->SetMeshInfo( aNewInfo );
myDlg->show(); /*exec();*/
commit();
+ SMESHGUI::Modified();
}
//================================================================================
aList.Append(myMeshActor->getIO());
selectionMgr()->setSelectedObjects(aList,false);
SMESH::UpdateView();
+ SMESHGUI::Modified();
}
}
catch (const SALOME::SALOME_Exception& S_ex) {
else if ( !myToCreate )
aResult = editMeshOrSubMesh( aMess );
if ( aResult )
+ {
+ SMESHGUI::Modified();
update( UF_ObjBrowser | UF_Model );
+ }
}
catch ( const SALOME::SALOME_Exception& S_ex )
{
SUIT_OverrideCursor aWaitCursor;
bool res = myMgr ? myMgr->SetMeshOrder() : false;
+ if( res )
+ SMESHGUI::Modified();
+
delete myMgr;
myMgr = 0;
}
mySelectionMgr->clearSelected();
SMESH::UpdateView();
+ SMESHGUI::Modified();
mySMESHGUI->updateObjBrowser(true);
aList.Append(myMeshActor->getIO());
mySelectionMgr->setSelectedObjects(aList,false);
SMESH::UpdateView();
+ SMESHGUI::Modified();
reset();
}
mySelector->ClearIndex();
mySelectionMgr->setSelectedObjects( sel );
SMESH::UpdateView();
+ SMESHGUI::Modified();
}
myListBox->clear();
connect( mySMESHGUI, SIGNAL( SignalDeactivateActiveDialog() ), SLOT( DeactivateActiveDialog() ) );
/* to close dialog if study frame change */
connect( mySMESHGUI, SIGNAL( SignalStudyFrameChanged() ), SLOT( ClickOnCancel() ) );
+ connect(mySMESHGUI, SIGNAL(SignalCloseAllDialogs()), SLOT(ClickOnCancel()));
// set selection mode
SMESH::SetPointRepresentation( true );
}
}
}
+
+ SMESHGUI::Modified();
+
return true;
}
// SALOME GUI includes
#include <SUIT_Desktop.h>
+#include <SUIT_MessageBox.h>
+#include <SUIT_ResourceMgr.h>
+#include <SUIT_Session.h>
#include <QtxColorButton.h>
#include <VTKViewer_MarkerWidget.h>
+#include <LightApp_Application.h>
#include <SalomeApp_IntSpinBox.h>
// Qt includes
#include <QHBoxLayout>
#include <QGridLayout>
#include <QCheckBox>
+#include <QKeyEvent>
#define SPACING 6
#define MARGIN 11
QPushButton* buttonCancel = new QPushButton( tr( "&Cancel" ), GroupButtons );
buttonCancel->setAutoDefault( true );
+ QPushButton* buttonHelp = new QPushButton( tr( "&Help" ), GroupButtons );
+ buttonHelp->setAutoDefault( true );
+
GroupButtonsLayout->addWidget( buttonOk );
GroupButtonsLayout->addSpacing( 10 );
GroupButtonsLayout->addStretch();
GroupButtonsLayout->addWidget( buttonCancel );
+ GroupButtonsLayout->addWidget( buttonHelp );
// -------------------------------
topLayout->addWidget( ButtonGroup1 );
// -------------------------------
mySMESHGUI->SetActiveDialogBox( this );
+ myHelpFileName = "colors_size_page.html";
+
/* signals and slots connections */
connect( buttonOk, SIGNAL( clicked() ), this, SLOT( ClickOnOk() ) );
connect( buttonCancel, SIGNAL( clicked() ), this, SLOT( ClickOnCancel() ) );
+ connect( buttonHelp, SIGNAL( clicked() ), this, SLOT( ClickOnHelp() ) );
connect( mySMESHGUI, SIGNAL ( SignalDeactivateActiveDialog() ),
this, SLOT( DeactivateActiveDialog() ) );
reject();
}
+//=================================================================================
+// function : ClickOnHelp()
+// purpose :
+//=================================================================================
+void SMESHGUI_Preferences_ColorDlg::ClickOnHelp()
+{
+ LightApp_Application* app = (LightApp_Application*)(SUIT_Session::session()->activeApplication());
+ if (app)
+ app->onHelpContextModule(mySMESHGUI ? app->moduleName(mySMESHGUI->moduleName()) : QString(""), myHelpFileName);
+ else {
+ QString platform;
+#ifdef WIN32
+ platform = "winapplication";
+#else
+ platform = "application";
+#endif
+ SUIT_MessageBox::warning(this, tr("WRN_WARNING"),
+ tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE").
+ arg(app->resourceMgr()->stringValue("ExternalBrowser",
+ platform)).
+ arg(myHelpFileName));
+ }
+}
+
//=================================================================================
// function : DeactivateActiveDialog()
// purpose :
{
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();
+ }
+}
protected:
void closeEvent( QCloseEvent* );
+ void keyPressEvent( QKeyEvent* );
private slots:
void ClickOnOk();
void ClickOnCancel();
+ void ClickOnHelp();
void DeactivateActiveDialog();
void ActivateThisDialog();
QtxColorButton* btnOrientationColor;
SMESHGUI_SpinBox* SpinBox_Orientation_Scale;
QCheckBox* CheckBox_Orientation_3DVectors;
+
+ QString myHelpFileName;
};
#endif // SMESHGUI_PREFERENCES_COLORDLG_H
SelectButtonC1A1->setIcon(image1);
LineEditC1A1 = new QLineEdit(GroupC1);
LineEditC1A1->setValidator(new SMESHGUI_IdValidator(this));
+ LineEditC1A1->setMaxLength(-1);
QPushButton* filterBtn = new QPushButton( tr( "SMESH_BUT_FILTER" ), GroupC1 );
connect(filterBtn, SIGNAL(clicked()), this, SLOT(setFilters()));
bool aResult = false;
try {
SMESH::SMESH_MeshEditor_var aMeshEditor = myMesh->GetMeshEditor();
- aResult = aMeshEditor->RemoveElements(anArrayOfIdeces.inout());
+ aResult = aMeshEditor->RemoveElements(anArrayOfIdeces.in());
} catch (const SALOME::SALOME_Exception& S_ex) {
SalomeApp_Tools::QtCatchCorbaException(S_ex);
myEditCurrentArgument->clear();
myEditCurrentArgument->clear();
mySelector->ClearIndex();
SMESH::UpdateView();
+ SMESHGUI::Modified();
}
}
}
myNbOkElements = 0;
- buttonOk->setEnabled(false);
- buttonApply->setEnabled(false);
-
// hilight entered elements
if(myActor){
if(SMDS_Mesh* aMesh = myActor->GetObject()->GetMesh()){
}
}
- if (myNbOkElements) {
- buttonOk->setEnabled(true);
- buttonApply->setEnabled(true);
- }
-
myBusy = false;
+ updateButtons();
}
//=================================================================================
//=================================================================================
void SMESHGUI_RemoveElementsDlg::SelectionIntoArgument()
{
- if (myBusy) return;
+ if (myBusy) return; // busy
+ if (myFilterDlg && myFilterDlg->isVisible()) return; // filter digl active
+ if (!GroupButtons->isEnabled()) return; // inactive
// clear
- myNbOkElements = false;
+ myNbOkElements = 0;
myActor = 0;
myBusy = true;
myEditCurrentArgument->setText("");
myBusy = false;
- if (!GroupButtons->isEnabled()) // inactive
- return;
-
- buttonOk->setEnabled(false);
- buttonApply->setEnabled(false);
-
// get selected mesh
SALOME_ListIO aList;
mySelectionMgr->selectedObjects(aList,SVTK_Viewer::Type());
int nbSel = aList.Extent();
- if (nbSel != 1)
- return;
-
- Handle(SALOME_InteractiveObject) anIO = aList.First();
- myMesh = SMESH::GetMeshByIO(anIO);
- if (myMesh->_is_nil())
- return;
-
- myActor = SMESH::FindActorByEntry(anIO->getEntry());
- if (!myActor)
- return;
-
- // get selected nodes
- QString aString = "";
- int nbElems = SMESH::GetNameOfSelectedElements(mySelector,anIO,aString);
- if(nbElems < 1)
- return;
- myBusy = true;
- myEditCurrentArgument->setText(aString);
- myBusy = false;
-
- // OK
-
- myNbOkElements = nbElems;
-
- buttonOk->setEnabled(true);
- buttonApply->setEnabled(true);
+ if (nbSel == 1) {
+
+ Handle(SALOME_InteractiveObject) anIO = aList.First();
+ myMesh = SMESH::GetMeshByIO(anIO);
+
+ if (!myMesh->_is_nil()) {
+
+ myActor = SMESH::FindActorByEntry(anIO->getEntry());
+ if (myActor) {
+
+ // get selected nodes
+ QString aString = "";
+ int nbElems = SMESH::GetNameOfSelectedElements(mySelector,anIO,aString);
+ if (nbElems > 0) {
+ myBusy = true;
+ myEditCurrentArgument->setText(aString);
+ myBusy = false;
+
+ // OK
+
+ myNbOkElements = nbElems;
+ } // if (nbElems > 0)
+ } // if (myActor)
+ } // if (!myMesh->_is_nil())
+ } // if (nbSel == 1) {
+
+ updateButtons();
}
//=================================================================================
myFilterDlg->show();
}
+
+//=================================================================================
+// function : updateButtons
+// purpose : enable / disable control buttons
+//=================================================================================
+void SMESHGUI_RemoveElementsDlg::updateButtons()
+{
+ buttonOk->setEnabled(myNbOkElements > 0);
+ buttonApply->setEnabled(myNbOkElements > 0);
+}
void ActivateThisDialog();
void onTextChange( const QString& );
void setFilters();
+ void updateButtons();
};
#endif // SMESHGUI_REMOVEELEMENTSDLG_H
SelectButtonC1A1->setIcon(image1);
LineEditC1A1 = new QLineEdit(GroupC1);
LineEditC1A1->setValidator(new SMESHGUI_IdValidator(this));
+ LineEditC1A1->setMaxLength(-1);
QPushButton* filterBtn = new QPushButton( tr( "SMESH_BUT_FILTER" ), GroupC1 );
connect(filterBtn, SIGNAL(clicked()), this, SLOT(setFilters()));
bool aResult = false;
try {
SMESH::SMESH_MeshEditor_var aMeshEditor = myMesh->GetMeshEditor();
- aResult = aMeshEditor->RemoveNodes(anArrayOfIdeces.inout());
+ aResult = aMeshEditor->RemoveNodes(anArrayOfIdeces.in());
} catch (const SALOME::SALOME_Exception& S_ex) {
SalomeApp_Tools::QtCatchCorbaException(S_ex);
myEditCurrentArgument->clear();
myEditCurrentArgument->clear();
mySelector->ClearIndex();
SMESH::UpdateView();
+ SMESHGUI::Modified();
}
SMESH::SetPointRepresentation(true);
myNbOkNodes = 0;
- buttonOk->setEnabled(false);
- buttonApply->setEnabled(false);
-
// hilight entered nodes
if(myActor){
if(SMDS_Mesh* aMesh = myActor->GetObject()->GetMesh()){
}
}
- if (myNbOkNodes) {
- buttonOk->setEnabled(true);
- buttonApply->setEnabled(true);
- }
-
myBusy = false;
+ updateButtons();
}
//=================================================================================
//=================================================================================
void SMESHGUI_RemoveNodesDlg::SelectionIntoArgument()
{
- if (myBusy) return;
-
+ if (myBusy) return; // busy
+ if (myFilterDlg && myFilterDlg->isVisible()) return; // filter dlg active
+ if (!GroupButtons->isEnabled()) return; // inactive
+
// clear
- myNbOkNodes = false;
+ myNbOkNodes = 0;
myActor = 0;
myBusy = true;
myEditCurrentArgument->setText("");
myBusy = false;
- if (!GroupButtons->isEnabled()) // inactive
- return;
-
- buttonOk->setEnabled(false);
- buttonApply->setEnabled(false);
-
// get selected mesh
SALOME_ListIO aList;
mySelectionMgr->selectedObjects(aList,SVTK_Viewer::Type());
int nbSel = aList.Extent();
- if (nbSel != 1)
- return;
-
- Handle(SALOME_InteractiveObject) anIO = aList.First();
- myMesh = SMESH::GetMeshByIO(anIO);
- if (myMesh->_is_nil())
- return;
-
- myActor = SMESH::FindActorByEntry(anIO->getEntry());
- if (!myActor)
- return;
-
- // get selected nodes
-
- QString aString = "";
- int nbNodes = SMESH::GetNameOfSelectedNodes(mySelector,anIO,aString);
- if(nbNodes < 1)
- return;
- myBusy = true;
- myEditCurrentArgument->setText(aString);
- myBusy = false;
-
- // OK
-
- myNbOkNodes = true;
-
- buttonOk->setEnabled(true);
- buttonApply->setEnabled(true);
+ if (nbSel == 1) {
+
+ Handle(SALOME_InteractiveObject) anIO = aList.First();
+ myMesh = SMESH::GetMeshByIO(anIO);
+
+ if (!myMesh->_is_nil()) {
+
+ myActor = SMESH::FindActorByEntry(anIO->getEntry());
+ if (myActor) {
+
+ // get selected nodes
+ QString aString = "";
+ int nbNodes = SMESH::GetNameOfSelectedNodes(mySelector,anIO,aString);
+ if (nbNodes > 0) {
+ myBusy = true;
+ myEditCurrentArgument->setText(aString);
+ myBusy = false;
+
+ // OK
+
+ myNbOkNodes = nbNodes;
+ } // if (nbNodes > 0)
+ } // if (myActor)
+ } // if (!myMesh->_is_nil())
+ } // if (nbSel == 1)
+
+ updateButtons();
}
//=================================================================================
myFilterDlg->show();
}
+
+//=================================================================================
+// function : updateButtons
+// purpose : enable / disable control buttons
+//=================================================================================
+void SMESHGUI_RemoveNodesDlg::updateButtons()
+{
+ buttonOk->setEnabled(myNbOkNodes > 0);
+ buttonApply->setEnabled(myNbOkNodes > 0);
+}
void ActivateThisDialog();
void onTextChange( const QString& );
void setFilters();
+ void updateButtons();
};
#endif // SMESHGUI_REMOVENODESDLG_H
//mySelectionMgr->clearSelected();
SMESH::UpdateView();
+ SMESHGUI::Modified();
}
}
LineEditElements = new QLineEdit(GroupArguments);
LineEditElements->setValidator(myIdValidator);
+ LineEditElements->setMaxLength(-1);
myFilterBtn = new QPushButton( tr( "SMESH_BUT_FILTER" ), GroupArguments );
connect(myFilterBtn, SIGNAL(clicked()), this, SLOT(setFilters()));
ConstructorsClicked(GetConstructorId());
mySelectedObject = SMESH::SMESH_IDSource::_nil();
SelectionIntoArgument();
+
+ SMESHGUI::Modified();
}
return true;
SelectElementsButton->setIcon(image1);
LineEditElements = new QLineEdit(GroupArguments);
LineEditElements->setValidator(myIdValidator);
+ LineEditElements->setMaxLength(-1);
myFilterBtn = new QPushButton( tr( "SMESH_BUT_FILTER" ), GroupArguments );
connect(myFilterBtn, SIGNAL(clicked()), this, SLOT(setFilters()));
Init(false);
mySelectedObject = SMESH::SMESH_IDSource::_nil();
SelectionIntoArgument();
+
+ SMESHGUI::Modified();
}
return true;
SelectElementsButton->setIcon(image2);
LineEditElements = new QLineEdit(GroupArguments);
LineEditElements->setValidator(myIdValidator);
+ LineEditElements->setMaxLength(-1);
myFilterBtn = new QPushButton( tr( "SMESH_BUT_FILTER" ), GroupArguments );
connect(myFilterBtn, SIGNAL(clicked()), this, SLOT(setFilters()));
ConstructorsClicked(GetConstructorId());
mySelectedObject = SMESH::SMESH_IDSource::_nil();
SelectionIntoArgument();
+
+ SMESHGUI::Modified();
}
return true;
Init();
ConstructorsClicked(GetConstructorId());
+
+ SMESHGUI::Modified();
}
}
mySelectionMgr->setSelectedObjects(aList, false);
onSelectionDone();
SMESH::UpdateView();
+ SMESHGUI::Modified();
}
return aResult;
LineEditElements = new QLineEdit(GroupArguments);
LineEditElements->setValidator(myIdValidator);
+ LineEditElements->setMaxLength(-1);
myElemFilterBtn = new QPushButton( tr( "SMESH_BUT_FILTER" ), GroupArguments );
connect(myElemFilterBtn, SIGNAL(clicked()), this, SLOT(setElemFilters()));
LineEditNodes = new QLineEdit(GroupArguments);
LineEditNodes->setValidator(myIdValidator);
+ LineEditNodes->setMaxLength(-1);
QPushButton* filterNodeBtn = new QPushButton( tr( "SMESH_BUT_FILTER" ), GroupArguments );
connect(filterNodeBtn, SIGNAL(clicked()), this, SLOT(setNodeFilters()));
}
SMESH::UpdateView();
+ SMESHGUI::Modified();
Init();
mySelectedObject = SMESH::SMESH_IDSource::_nil();
SelectElementsButton->setIcon(image3);
LineEditElements = new QLineEdit(GroupArguments);
LineEditElements->setValidator(myIdValidator);
+ LineEditElements->setMaxLength(-1);
myFilterBtn = new QPushButton( tr( "SMESH_BUT_FILTER" ), GroupArguments );
connect(myFilterBtn, SIGNAL(clicked()), this, SLOT(setFilters()));
ConstructorsClicked(GetConstructorId());
mySelectedObject = SMESH::SMESH_IDSource::_nil();
SelectionIntoArgument();
+
+ SMESHGUI::Modified();
}
return true;
}
SelectElementsButton->setIcon(image2);
LineEditElements = new QLineEdit(GroupArguments);
LineEditElements->setValidator(myIdValidator);
+ LineEditElements->setMaxLength(-1);
myFilterBtn = new QPushButton( tr( "SMESH_BUT_FILTER" ), GroupArguments );
connect(myFilterBtn, SIGNAL(clicked()), this, SLOT(setFilters()));
ConstructorsClicked(GetConstructorId());
mySelectedObject = SMESH::SMESH_IDSource::_nil();
SelectionIntoArgument();
+
+ SMESHGUI::Modified();
}
return true;
LineEditElements = new QLineEdit(GroupArguments);
LineEditElements->setValidator(new SMESHGUI_IdValidator(this));
+ LineEditElements->setMaxLength(-1);
GroupArgumentsLayout->addWidget(LineEditElements, 0, 1);
// information text browser
c_cpd = MakeCompound(c_l)
c_glu = MakeGlueFaces(c_cpd, 1.e-5)
-piece = RemoveExtraEdges(c_glu)
+piece = RemoveExtraEdges(c_glu, doUnionFaces=True)
# Add in study
# ------------
p_part = MakePartition([c_piece], p_tools, [], [], ShapeType["SOLID"])
-p_blocs = RemoveExtraEdges(p_part)
+p_blocs = RemoveExtraEdges(p_part, doUnionFaces=True)
piece = MakeGlueFaces(p_blocs, 1.e-5)
# Add in study
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
# -------------
piece_cpd = MakeCompound(blocks)
-piece_ok = RemoveExtraEdges(piece_cpd)
+piece_ok = RemoveExtraEdges(piece_cpd, doUnionFaces=True)
piece = MakeGlueFaces(piece_ok, 1.e-3)
private:
- bool error(std::string& text, int code = COMPERR_ALGO_FAILED)
+ bool error(const std::string& text, int code = COMPERR_ALGO_FAILED)
{ myError = SMESH_ComputeError::New( code, text ); return false; }
bool error(const SMESH_ComputeErrorPtr& err)
if ( !myGrid.empty() )
return true;
+ SMESHDS_SubMesh* faceSubMesh = mesh.GetSubMesh( myFace )->GetSubMeshDS();
+ // check that all faces are quadrangular
+ SMDS_ElemIteratorPtr fIt = faceSubMesh->GetElements();
+ while ( fIt->more() )
+ if ( fIt->next()->NbNodes() % 4 > 0 )
+ return error("Non-quadrangular mesh faces are not allowed on sides of a composite block");
+
myIndexer._xSize = 1 + mySides.GetSide( Q_BOTTOM )->GetNbSegments( mesh );
myIndexer._ySize = 1 + mySides.GetSide( Q_LEFT )->GetNbSegments( mesh );
// store the rest nodes row by row
- SMESHDS_SubMesh* faceSubMesh = mesh.GetSubMesh( myFace )->GetSubMeshDS();
-
SMDS_MeshNode dummy(0,0,0);
const SMDS_MeshElement* firstQuad = &dummy;// most left face above the last row of found nodes
const SMDS_MeshNode* node = nItr->next();
if ( myIgnoreMediumNodes && SMESH_MeshEditor::IsMedium( node, SMDSAbs_Edge ))
continue;
- double u = helper.GetNodeU( myEdge[i], node, ¶mOK );
+ double u = helper.GetNodeU( myEdge[i], node, 0, ¶mOK );
double aLenU = GCPnts_AbscissaPoint::Length
( const_cast<GeomAdaptor_Curve&>( myC3dAdaptor[i]), myFirst[i], u );
if ( myEdgeLength[i] < aLenU ) // nonregression test "3D_mesh_NETGEN/G6"
const SMDS_MeshNode* node = nItr->next();
if ( myIgnoreMediumNodes && SMESH_MeshEditor::IsMedium( node, SMDSAbs_Edge ))
continue;
- double u = helper.GetNodeU( myEdge[i], node, ¶mOK );
+ double u = helper.GetNodeU( myEdge[i], node, 0, ¶mOK );
// paramSize is signed so orientation is taken into account
double normPar = prevNormPar + r * ( u - myFirst[i] ) / paramSize;
TError & theError)
{
TopoDS_Vertex V1;
- list< TopoDS_Edge > edges;
+ list< TopoDS_Edge > edges, internalEdges;
list< int > nbEdgesInWires;
int nbWires = SMESH_Block::GetOrderedEdges (theFace, V1, edges, nbEdgesInWires);
// split list of all edges into separate wires
TSideVector wires( nbWires );
list< int >::iterator nbE = nbEdgesInWires.begin();
- list< TopoDS_Edge >::iterator from, to;
- from = to = edges.begin();
- for ( int iW = 0; iW < nbWires; ++iW )
+ list< TopoDS_Edge >::iterator from = edges.begin(), to = from;
+ for ( int iW = 0; iW < nbWires; ++iW, ++nbE )
{
- std::advance( to, *nbE++ );
+ std::advance( to, *nbE );
if ( *nbE == 0 ) // Issue 0020676
{
--nbWires;
// assure that there is a node on the first vertex
// as StdMeshers_FaceSide::GetUVPtStruct() requires
if ( wireEdges.front().Orientation() != TopAbs_INTERNAL ) // Issue 0020676
+ {
while ( !SMESH_Algo::VertexNode( TopExp::FirstVertex( wireEdges.front(), true),
theMesh.GetMeshDS()))
{
return TSideVector(0);
}
}
- const bool isForward = true;
+ }
+ else if ( *nbE > 1 ) // Issue 0020676 (Face_pb_netgen.brep) - several internal edges in a wire
+ {
+ internalEdges.splice( internalEdges.end(), wireEdges, ++wireEdges.begin(), wireEdges.end());
+ }
+
StdMeshers_FaceSide* wire = new StdMeshers_FaceSide( theFace, wireEdges, &theMesh,
- isForward, theIgnoreMediumNodes);
+ /*isForward=*/true, theIgnoreMediumNodes);
wires[ iW ] = StdMeshers_FaceSidePtr( wire );
from = to;
}
+ while ( !internalEdges.empty() )
+ {
+ StdMeshers_FaceSide* wire = new StdMeshers_FaceSide( theFace, internalEdges.back(), &theMesh,
+ /*isForward=*/true, theIgnoreMediumNodes);
+ wires.push_back( StdMeshers_FaceSidePtr( wire ));
+ internalEdges.pop_back();
+ }
return wires;
}
{
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
{
};
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
};
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
+ *
+ * This check is valid for simple cases only
*/
//================================================================================
bool isQuadrangle(const SMDS_MeshElement* e)
{
- return ( e && e->NbNodes() == ( e->IsQuadratic() ? 8 : 4 ));
+ return ( e && e->NbCornerNodes() == 4 );
}
//================================================================================
int _nbBlocksExpected;
int _nbBlocksFound;
-#ifdef _DEBUG_
-#define _grid_access_(args) _grid.at( args )
+#ifdef _DEBUG_ // want to get SIGSEGV in case of invalid index
+#define _grid_access_(pobj, i) pobj->_grid[ ((i) < pobj->_grid.size()) ? i : int(1e100)]
#else
-#define _grid_access_(args) _grid[ args ]
+#define _grid_access_(pobj, i) pobj->_grid[ i ]
#endif
//!< Return node at XY
- const SMDS_MeshNode* getNode(int x, int y) const { return _grid_access_( _index( x, y )); }
+ const SMDS_MeshNode* getNode(int x, int y) const { return _grid_access_(this, _index( x,y ));}
//!< Set node at XY
- void setNode(int x, int y, const SMDS_MeshNode* n) { _grid_access_( _index( x, y )) = n; }
+ void setNode(int x, int y, const SMDS_MeshNode* n) { _grid_access_(this, _index( x,y )) = n; }
//!< Return an edge
SMESH_OrientedLink getEdge(EQuadEdge edge) const
{
//!< return coordinates by XY
gp_XYZ xyz(int x, int y) const
{
- return SMESH_MeshEditor::TNodeXYZ( _side->_grid_access_( _index( x, y )) );
+ return SMESH_MeshEditor::TNodeXYZ( _grid_access_(_side, _index( x, y )) );
}
//!< safely return a node by XY
const SMDS_MeshNode* node(int x, int y) const
//!< Return a corner node
const SMDS_MeshNode* cornerNode(bool isXMax, bool isYMax) const
{
- return _side->_grid_access_( _index.corner( isXMax, isYMax ));
+ return _grid_access_(_side, _index.corner( isXMax, isYMax ));
}
//!< return its size in nodes
int getHoriSize() const { return _index.xSize(); }
*/
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]; }
+ bool setSide( int i, const _OrientedBlockSide& s)
+ {
+ if (( _side[i] = s ))
+ {
+ _corners.insert( s.cornerNode(0,0));
+ _corners.insert( s.cornerNode(1,0));
+ _corners.insert( s.cornerNode(0,1));
+ _corners.insert( s.cornerNode(1,1));
+ }
+ return s;
+ }
+ void clear() { for (int i=0;i<6;++i) _side[i]=0; _corners.clear(); }
bool hasSide( const _OrientedBlockSide& s) const
{
if ( s ) for (int i=0;i<6;++i) if ( _side[i] && _side[i]._side == s._side ) return true;
return false;
}
+ int nbSides() const { int n=0; for (int i=0;i<6;++i) if ( _side[i] ) ++n; return n; }
+ bool isValid() const;
};
//================================================================================
/*!
const SMESH_Comment& error() const { return _error; }
private:
- bool fillSide( _BlockSide& side, const SMDS_MeshElement* cornerQuad);
+ bool fillSide( _BlockSide& side,
+ const SMDS_MeshElement* cornerQuad,
+ const SMDS_MeshNode* cornerNode);
bool fillRowsUntilCorner(const SMDS_MeshElement* quad,
const SMDS_MeshNode* n1,
const SMDS_MeshNode* n2,
bool alongN1N2 );
_OrientedBlockSide findBlockSide( EBoxSides startBlockSide,
EQuadEdge sharedSideEdge1,
- EQuadEdge sharedSideEdge2);
+ EQuadEdge sharedSideEdge2,
+ bool withGeometricAnalysis);
//!< update own data and data of the side bound to block
void setSideBoundToBlock( _BlockSide& side )
{
- side._nbBlocksFound++;
- if ( side.isBound() )
- {
- for ( int e = 0; e < int(Q_UNDEFINED); ++e )
+ if ( side._nbBlocksFound++, side.isBound() )
+ for ( int e = 0; e < int(NB_QUAD_SIDES); ++e )
_edge2sides[ side.getEdge( (EQuadEdge) e ) ].erase( &side );
- }
}
//!< store reason of error
int error(const SMESH_Comment& reason) { _error = reason; return 0; }
_allSides.push_back( _BlockSide() );
_BlockSide& side = _allSides.back();
- if ( !fillSide( side, face ) )
+ if ( !fillSide( side, face, *corner ) )
{
if ( !_error.empty() )
return false;
for ( int isYMax = 0; isYMax < 2; ++isYMax )
{
const SMDS_MeshNode* nCorner = side.getCornerNode(isXMax,isYMax );
- if ( !isCornerNode( nCorner ))
- return BAD_MESH_ERR;
- //_corner2sides[ nCorner ].insert( &side );
corners.push_back( nCorner );
cornerFaces.insert( side.getCornerFace( nCorner ));
}
- for ( int e = 0; e < int(Q_UNDEFINED); ++e )
+ for ( int e = 0; e < int(NB_QUAD_SIDES); ++e )
_edge2sides[ side.getEdge( (EQuadEdge) e ) ].insert( &side );
nbFacesOnSides += side.getNbFaces();
return BAD_MESH_ERR;
if ( _allSides.back()._grid.empty() )
_allSides.pop_back();
+ _DUMP_("Nb detected sides "<< _allSides.size());
// ---------------------------
// Organize sides into blocks
// ---------------------------
- // analyse sharing of sides by blocks
- int nbBlockSides = 0; // nb of block sides taking into account their sharing
- list < _BlockSide >::iterator sideIt = _allSides.begin();
- for ( ; sideIt != _allSides.end(); ++sideIt )
+ // analyse sharing of sides by blocks and sort sides by nb of adjacent sides
+ int nbBlockSides = 0; // total nb of block sides taking into account their sharing
+ multimap<int, _BlockSide* > sortedSides;
{
- _BlockSide& side = *sideIt;
- bool isSharedSide = true;
- for ( int e = 0; e < int(Q_UNDEFINED) && isSharedSide; ++e )
- isSharedSide = _edge2sides[ side.getEdge( (EQuadEdge) e ) ].size() > 2;
- side._nbBlocksFound = 0;
- side._nbBlocksExpected = isSharedSide ? 2 : 1;
- nbBlockSides += side._nbBlocksExpected;
+ list < _BlockSide >::iterator sideIt = _allSides.begin();
+ for ( ; sideIt != _allSides.end(); ++sideIt )
+ {
+ _BlockSide& side = *sideIt;
+ bool isSharedSide = true;
+ int nbAdjacent = 0;
+ for ( int e = 0; e < int(NB_QUAD_SIDES) && isSharedSide; ++e )
+ {
+ int nbAdj = _edge2sides[ side.getEdge( (EQuadEdge) e ) ].size();
+ nbAdjacent += nbAdj;
+ isSharedSide = ( nbAdj > 2 );
+ }
+ side._nbBlocksFound = 0;
+ side._nbBlocksExpected = isSharedSide ? 2 : 1;
+ nbBlockSides += side._nbBlocksExpected;
+ sortedSides.insert( make_pair( nbAdjacent, & side ));
+ }
}
// find sides of each block
while ( nbBlockSides >= 6 )
{
// get any side not bound to all blocks it belongs to
- sideIt = _allSides.begin();
- while ( sideIt != _allSides.end() && sideIt->isBound())
- ++sideIt;
+ multimap<int, _BlockSide*>::iterator i_side = sortedSides.begin();
+ while ( i_side != sortedSides.end() && i_side->second->isBound())
+ ++i_side;
// start searching for block sides from the got side
bool ok = true;
_blocks.resize( _blocks.size() + 1 );
_Block& block = _blocks.back();
- block._side[B_FRONT] = &(*sideIt);
- setSideBoundToBlock( *sideIt );
+ block.setSide( B_FRONT, i_side->second );
+ setSideBoundToBlock( *i_side->second );
nbBlockSides--;
-
- // edges of neighbour sides of B_FRONT corresponding to front's edges
- EQuadEdge edgeOfFront[4] = { Q_BOTTOM, Q_RIGHT, Q_TOP, Q_LEFT };
- EQuadEdge edgeToFind [4] = { Q_BOTTOM, Q_LEFT, Q_BOTTOM, Q_LEFT };
- for ( int i = Q_BOTTOM; ok && i <= Q_LEFT; ++i )
- ok = ( block._side[i] = findBlockSide( B_FRONT, edgeOfFront[i], edgeToFind[i]));
- if ( ok )
- ok = ( block._side[B_BACK] = findBlockSide( B_TOP, Q_TOP, Q_TOP ));
+ // edges of adjacent sides of B_FRONT corresponding to front's edges
+ EQuadEdge edgeOfFront[4] = { Q_BOTTOM, Q_RIGHT, Q_TOP, Q_LEFT };
+ EQuadEdge edgeOfAdj [4] = { Q_BOTTOM, Q_LEFT, Q_BOTTOM, Q_LEFT };
+ // first find all sides detectable w/o advanced analysis,
+ // then repeat the search, which then may pass without advanced analysis
+ for ( int advAnalys = 0; advAnalys < 2; ++advAnalys )
+ {
+ for ( int i = 0; (ok || !advAnalys) && i < NB_QUAD_SIDES; ++i )
+ if ( !block._side[i] ) // try to find 4 sides adjacent to front side
+ ok = block.setSide( i, findBlockSide( B_FRONT, edgeOfFront[i],edgeOfAdj[i],advAnalys));
+ if ( ok || !advAnalys)
+ if ( !block._side[B_BACK] && block._side[B_TOP] ) // try to find back side by top one
+ ok = block.setSide( B_BACK, findBlockSide( B_TOP, Q_TOP, Q_TOP, advAnalys ));
+ if ( !advAnalys ) ok = true;
+ }
+ ok = block.isValid();
if ( ok )
{
// check if just found block is same as one of previously found
bool isSame = false;
for ( int i = 1; i < _blocks.size() && !isSame; ++i )
- {
- _Block& prevBlock = _blocks[i-1];
- isSame = true;
- for ( int j = 0; j < 6 && isSame; ++j )
- isSame = prevBlock.hasSide( block._side[ j ]);
- }
+ isSame = ( block._corners == _blocks[i-1]._corners );
ok = !isSame;
}
// count the found sides
- _DUMP_(endl);
- for (int i = 0; i < B_UNDEFINED; ++i )
+ _DUMP_(endl << "** Block " << _blocks.size() << " valid: " << block.isValid());
+ for (int i = 0; i < NB_BLOCK_SIDES; ++i )
{
- _DUMP_("** Block side "<< SBoxSides[i] <<" "<< block._side[ i ]._side);
+ _DUMP_("\tSide "<< SBoxSides[i] <<" "<< block._side[ i ]._side);
if ( block._side[ i ] )
{
if ( ok && i != B_FRONT)
setSideBoundToBlock( *block._side[ i ]._side );
nbBlockSides--;
}
- _DUMP_("Corner 0,0 "<< block._side[ i ].cornerNode(0,0));
- _DUMP_("Corner 1,0 "<< block._side[ i ].cornerNode(1,0));
- _DUMP_("Corner 1,1 "<< block._side[ i ].cornerNode(1,1));
- _DUMP_("Corner 0,1 "<< block._side[ i ].cornerNode(0,1));
+ _DUMP_("\t corners "<<
+ block._side[ i ].cornerNode(0,0)->GetID() << ", " <<
+ block._side[ i ].cornerNode(1,0)->GetID() << ", " <<
+ block._side[ i ].cornerNode(1,1)->GetID() << ", " <<
+ block._side[ i ].cornerNode(0,1)->GetID() << ", "<<endl);
}
else
{
- _DUMP_("Not found"<<endl);
+ _DUMP_("\t not found"<<endl);
}
}
if ( !ok )
- block._side[0] = block._side[1] = block._side[2] =
- block._side[3] = block._side[4] = block._side[5] = 0;
+ block.clear();
else
nbBlocks++;
}
+ _DUMP_("Nb found blocks "<< nbBlocks <<endl);
+
if ( nbBlocks == 0 && _error.empty() )
return BAD_MESH_ERR;
*/
//================================================================================
- 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
// of nodes in two directions.
int x, y, nbX, nbY;
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
int iCorner = firstQuad->GetNodeIndex( nCorner );
const SMDS_MeshNode* nOnEdge = firstQuad->GetNode( (iCorner+1) % 4);
}
}
- 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;
}
//================================================================================
_OrientedBlockSide _Skin::findBlockSide( EBoxSides startBlockSide,
EQuadEdge sharedSideEdge1,
- EQuadEdge sharedSideEdge2)
+ EQuadEdge sharedSideEdge2,
+ bool withGeometricAnalysis)
{
_Block& block = _blocks.back();
_OrientedBlockSide& side1 = block._side[ startBlockSide ];
set< _BlockSide* > sidesOnEdge = _edge2sides[ edge ]; // copy a set
// exclude loaded sides of block from sidesOnEdge
- int nbLoadedSides = 0;
- for (int i = 0; i < B_UNDEFINED; ++i )
- {
+ for (int i = 0; i < NB_BLOCK_SIDES; ++i )
if ( block._side[ i ] )
- {
- nbLoadedSides++;
sidesOnEdge.erase( block._side[ i ]._side );
- }
- }
+
int nbSidesOnEdge = sidesOnEdge.size();
_DUMP_("nbSidesOnEdge "<< nbSidesOnEdge << " " << n1->GetID() << "-" << n2->GetID() );
if ( nbSidesOnEdge == 0 )
return 0;
_BlockSide* foundSide = 0;
- if ( nbSidesOnEdge == 1 /*|| nbSidesOnEdge == 2 && nbLoadedSides == 1 */)
+ if ( nbSidesOnEdge == 1 )
{
foundSide = *sidesOnEdge.begin();
}
else
{
- // Select one of found sides most close to startBlockSide
-
- // gravity center of already loaded block sides
- gp_XYZ gc(0,0,0);
- for (int i = 0; i < B_UNDEFINED; ++i )
- if ( block._side[ i ] )
- gc += block._side[ i ]._side->getGC();
- gc /= nbLoadedSides;
-
- gp_XYZ p1 ( n1->X(),n1->Y(),n1->Z()), p2 (n2->X(),n2->Y(),n2->Z());
- gp_Vec p1p2( p1, p2 );
-
- const SMDS_MeshElement* face1 = side1->getCornerFace( n1 );
- gp_XYZ p1Op = SMESH_MeshEditor::TNodeXYZ( oppositeNode( face1, face1->GetNodeIndex(n1)));
- gp_Vec side1Dir( p1, p1Op );
- gp_Ax2 pln( p1, p1p2, side1Dir ); // plane with normal p1p2 and X dir side1Dir
- _DUMP_(" Select adjacent for "<< side1._side << " - side dir ("
- << side1Dir.X() << ", " << side1Dir.Y() << ", " << side1Dir.Z() << ")" );
-
- map < double , _BlockSide* > angleOfSide;
set< _BlockSide* >::iterator sideIt = sidesOnEdge.begin();
- for (; sideIt != sidesOnEdge.end(); ++sideIt )
+ int nbLoadedSides = block.nbSides();
+ if ( nbLoadedSides > 1 )
{
- _BlockSide* sideI = *sideIt;
- const SMDS_MeshElement* faceI = sideI->getCornerFace( n1 );
- gp_XYZ p1Op = SMESH_MeshEditor::TNodeXYZ( oppositeNode( faceI, faceI->GetNodeIndex(n1)));
- gp_Vec sideIDir( p1, p1Op );
- // compute angle of (sideIDir projection to pln) and (X dir of pln)
- gp_Vec2d sideIDirProj( sideIDir * pln.XDirection(), sideIDir * pln.YDirection());
- double angle = sideIDirProj.Angle( gp::DX2d() );
- if ( angle < 0 ) angle += 2 * PI;
- angleOfSide.insert( make_pair( angle, sideI ));
- _DUMP_(" "<< sideI << " - side dir ("
- << sideIDir.X() << ", " << sideIDir.Y() << ", " << sideIDir.Z() << ")"
- << " angle " << angle);
+ // Find the side having more than 2 corners common with already loaded sides
+ for (; !foundSide && sideIt != sidesOnEdge.end(); ++sideIt )
+ {
+ _BlockSide* sideI = *sideIt;
+ int nbCommonCorners =
+ block._corners.count( sideI->getCornerNode(0,0)) +
+ block._corners.count( sideI->getCornerNode(1,0)) +
+ block._corners.count( sideI->getCornerNode(0,1)) +
+ block._corners.count( sideI->getCornerNode(1,1));
+ if ( nbCommonCorners > 2 )
+ foundSide = sideI;
+ }
+ }
+
+ if ( !foundSide )
+ {
+ if ( !withGeometricAnalysis ) return 0;
+
+ // Select one of found sides most close to startBlockSide
+
+ gp_XYZ p1 ( n1->X(),n1->Y(),n1->Z()), p2 (n2->X(),n2->Y(),n2->Z());
+ gp_Vec p1p2( p1, p2 );
+
+ const SMDS_MeshElement* face1 = side1->getCornerFace( n1 );
+ gp_XYZ p1Op = SMESH_MeshEditor::TNodeXYZ( oppositeNode( face1, face1->GetNodeIndex(n1)));
+ gp_Vec side1Dir( p1, p1Op );
+ gp_Ax2 pln( p1, p1p2, side1Dir ); // plane with normal p1p2 and X dir side1Dir
+ _DUMP_(" Select adjacent for "<< side1._side << " - side dir ("
+ << side1Dir.X() << ", " << side1Dir.Y() << ", " << side1Dir.Z() << ")" );
+
+ map < double , _BlockSide* > angleOfSide;
+ for (sideIt = sidesOnEdge.begin(); sideIt != sidesOnEdge.end(); ++sideIt )
+ {
+ _BlockSide* sideI = *sideIt;
+ const SMDS_MeshElement* faceI = sideI->getCornerFace( n1 );
+ gp_XYZ p1Op = SMESH_MeshEditor::TNodeXYZ( oppositeNode( faceI, faceI->GetNodeIndex(n1)));
+ gp_Vec sideIDir( p1, p1Op );
+ // compute angle of (sideIDir projection to pln) and (X dir of pln)
+ gp_Vec2d sideIDirProj( sideIDir * pln.XDirection(), sideIDir * pln.YDirection());
+ double angle = sideIDirProj.Angle( gp::DX2d() );
+ if ( angle < 0 ) angle += 2 * PI; // angle [0-2*PI]
+ angleOfSide.insert( make_pair( angle, sideI ));
+ _DUMP_(" "<< sideI << " - side dir ("
+ << sideIDir.X() << ", " << sideIDir.Y() << ", " << sideIDir.Z() << ")"
+ << " angle " << angle);
+ }
+ if ( nbLoadedSides == 1 )
+ {
+ double angF = angleOfSide.begin()->first, angL = angleOfSide.rbegin()->first;
+ if ( angF > PI ) angF = 2*PI - angF;
+ if ( angL > PI ) angL = 2*PI - angL;
+ foundSide = angF < angL ? angleOfSide.begin()->second : angleOfSide.rbegin()->second;
+ }
+ else
+ {
+ gp_XYZ gc(0,0,0); // gravity center of already loaded block sides
+ for (int i = 0; i < NB_BLOCK_SIDES; ++i )
+ if ( block._side[ i ] )
+ gc += block._side[ i ]._side->getGC();
+ gc /= nbLoadedSides;
+
+ gp_Vec gcDir( p1, gc );
+ gp_Vec2d gcDirProj( gcDir * pln.XDirection(), gcDir * pln.YDirection());
+ double gcAngle = gcDirProj.Angle( gp::DX2d() );
+ foundSide = gcAngle < 0 ? angleOfSide.rbegin()->second : angleOfSide.begin()->second;
+ }
}
- gp_Vec gcDir( p1, gc );
- gp_Vec2d gcDirProj( gcDir * pln.XDirection(), gcDir * pln.YDirection());
- double gcAngle = gcDirProj.Angle( gp::DX2d() );
- foundSide = gcAngle < 0 ? angleOfSide.rbegin()->second : angleOfSide.begin()->second;
_DUMP_(" selected "<< foundSide );
}
row2.push_back( n1 = oppositeNode( quad, i1 ));
}
+ _NodeDescriptor nDesc( row1[1] );
+ if ( nDesc == _NodeDescriptor( row1[0] ))
+ return true; // row of 2 nodes
+
// Find the rest nodes
TIDSortedElemSet emptySet, avoidSet;
- while ( !isCornerNode( n2 ))
+ //while ( !isCornerNode( n2 ))
+ while ( nDesc == _NodeDescriptor( n2 ))
{
avoidSet.clear(); avoidSet.insert( quad );
quad = SMESH_MeshEditor::FindFaceInSet( n1, n2, emptySet, avoidSet, &i1, &i2 );
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
const vector<UVPtStruct>& uv_et = quad->side[2]->GetUVPtStruct(true,1 );
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
//cout<<"Dump B:"<<endl;
TColStd_SequenceOfReal npb, npr, npt, npl;
#ifdef WIN32
# include <algorithm>
#endif
+#include <math.h>
+#include <limits>
#include <Basics_Utils.hxx>
showError();
return;
}
+#ifdef WIN32
+ if ( std::fabs(y[i]) >= HUGE_VAL)
+ y[i] = HUGE_VAL/100.;
+#else
+ if ( isinf(y[i]))
+ y[i] = std::numeric_limits<double>::max()/100.;
+#endif
+// if ( y[i] > 1e3 )
+// y[i] = 1e3;
if( i==0 || y[i]<min_y )
min_y = y[i];
if( i==0 || y[i]>max_y )
<source>ICON_SMESH_TREE_ALGO_CompositeSegment_1D</source>
<translation>mesh_tree_algo_regular.png</translation>
</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>
<source>ICON_SMESH_TREE_ALGO_Hexa_3D</source>
<translation>mesh_tree_algo_hexa.png</translation>
<source>ICON_SMESH_TREE_ALGO_Quadrangle_2D</source>
<translation>mesh_tree_algo_quad.png</translation>
</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>
<source>ICON_SMESH_TREE_ALGO_RadialPrism_3D</source>
<translation>mesh_tree_algo_radial_prism.png</translation>
</message>
<message>
<source>ICON_SMESH_TREE_ALGO_SegmentAroundVertex_0D</source>
- <translation>mesh_tree_algo_regular.png</translation>
+ <translation>mesh_tree_algo_0D.png</translation>
</message>
<message>
<source>ICON_SMESH_TREE_HYPO_Arithmetic1D</source>