mirror of
https://git.salome-platform.org/gitpub/modules/smesh.git
synced 2025-01-26 20:30:33 +05:00
Merge from V7_3_BR branch 18/12/2013
This commit is contained in:
parent
8fcd118698
commit
2cd148d066
@ -28,7 +28,7 @@ CMAKE_POLICY(SET CMP0003 NEW)
|
||||
STRING(TOUPPER ${PROJECT_NAME} PROJECT_NAME_UC)
|
||||
|
||||
SET(${PROJECT_NAME_UC}_MAJOR_VERSION 7)
|
||||
SET(${PROJECT_NAME_UC}_MINOR_VERSION 2)
|
||||
SET(${PROJECT_NAME_UC}_MINOR_VERSION 3)
|
||||
SET(${PROJECT_NAME_UC}_PATCH_VERSION 0)
|
||||
SET(${PROJECT_NAME_UC}_VERSION
|
||||
${${PROJECT_NAME_UC}_MAJOR_VERSION}.${${PROJECT_NAME_UC}_MINOR_VERSION}.${${PROJECT_NAME_UC}_PATCH_VERSION})
|
||||
|
@ -20,22 +20,21 @@
|
||||
<h2>Adaptive hypothesis</h2>
|
||||
|
||||
<b>Adaptive</b> hypothesis allows to split edges into segments with a
|
||||
length that depends on curvature of edges and faces and is limited
|
||||
from up and down. In addition length of a segment depends on lengths
|
||||
of adjacent segments (that can't differ more than twice) and on
|
||||
length that depends on the curvature of edges and faces and is limited by <b>Min. Size</b>
|
||||
and <b>Max Size</b>. The length of a segment also depends on the lengths
|
||||
of adjacent segments (that can't differ more than twice) and on the
|
||||
distance to close geometrical entities (edges and faces) to avoid
|
||||
creation of narrow 2D elements.
|
||||
|
||||
\image html adaptive1d.png
|
||||
|
||||
<b>Min size</b> parameter limits minimal segment size. <b>Max size</b>
|
||||
parameter defines length of segments on stright edges. \b Deflection
|
||||
parameter gives maximal distance of a segment from a curved edge.
|
||||
- <b>Min size</b> parameter limits the minimal segment size.
|
||||
- <b>Max size</b> parameter defines the length of segments on straight edges.
|
||||
- \b Deflection parameter gives maximal distance of a segment from a curved edge.
|
||||
|
||||
\image html adaptive1d_sample_mesh.png "A geometry and a mesh generated on this geometry using Adaptive hypothesis and Netgen 2D algorithm - the size of mesh segments reflects size of geometrical features"
|
||||
\image html adaptive1d_sample_mesh.png "Adaptive hypothesis and Netgen 2D algorithm - the size of mesh segments reflects the size of geometrical features"
|
||||
|
||||
<b>See Also</b> a \ref tui_1d_adaptive "sample TUI Script" that
|
||||
creates the mesh of the above image.
|
||||
<b>See Also</b> a \ref tui_1d_adaptive "sample TUI Script" that creates mesh of the above image.
|
||||
|
||||
<br>
|
||||
\anchor arithmetic_1d_anchor
|
||||
|
@ -2,14 +2,10 @@
|
||||
|
||||
\page a2d_meshing_hypo_page 2D Meshing Hypotheses
|
||||
|
||||
<br>
|
||||
<ul>
|
||||
<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>
|
||||
</ul>
|
||||
- \ref max_element_area_anchor "Max Element Area"
|
||||
- \ref length_from_edges_anchor "Length from Edges"
|
||||
- \ref hypo_quad_params_anchor "Quadrangle parameters"
|
||||
|
||||
<br>
|
||||
\anchor max_element_area_anchor
|
||||
<h2>Max Element Area</h2>
|
||||
|
||||
@ -25,10 +21,8 @@ which will compose the mesh of these faces.
|
||||
\image html max_el_area.png "In this example, Max. element area is very small compared to the 1D hypothesis"
|
||||
|
||||
<b>See Also</b> a sample TUI Script of a
|
||||
\ref tui_max_element_area "Maximum Element Area" hypothesis
|
||||
operation.
|
||||
\ref tui_max_element_area "Maximum Element Area" hypothesis operation.
|
||||
|
||||
<br>
|
||||
\anchor length_from_edges_anchor
|
||||
<h2>Length from Edges</h2>
|
||||
|
||||
@ -39,7 +33,6 @@ of a given face.
|
||||
<b>See Also</b> a sample TUI Script of a
|
||||
\ref tui_length_from_edges "Length from Edges" hypothesis operation.
|
||||
|
||||
<br>
|
||||
\anchor hypo_quad_params_anchor
|
||||
<h2>Quadrangle parameters</h2>
|
||||
|
||||
@ -72,37 +65,34 @@ shows the good (left) and the bad (right) results of meshing.
|
||||
segments on opposite sides to define the algorithm of transition
|
||||
between them. The following types are available:
|
||||
|
||||
<ul>
|
||||
<li><b>Standard</b> is the default case, when both triangles and quadrangles
|
||||
are possible in the transition area along the finer meshed sides.</li>
|
||||
<li><b>Triangle preference</b> forces building only triangles in the
|
||||
transition area along the finer meshed sides.
|
||||
<i>This type corresponds to <b>Triangle Preference</b> additional
|
||||
hypothesis, which is obsolete now.</i></li>
|
||||
<li><b>Quadrangle preference</b> forces building only quadrangles in the
|
||||
transition area along the finer meshed sides. This hypothesis has a
|
||||
restriction: the total quantity of segments on all
|
||||
four sides of the face must be even (divisible by 2).</li>
|
||||
<i>This type corresponds to <b>Quadrangle Preference</b>
|
||||
additional hypothesis, which is obsolete now.</i></li>
|
||||
<li><b>Quadrangle preference (reversed)</b> works in the same way and
|
||||
- <b>Standard</b> is the default case, when both triangles and quadrangles
|
||||
are possible in the transition area along the finer meshed sides.
|
||||
- <b>Triangle preference</b> forces building only triangles in the
|
||||
transition area along the finer meshed sides.
|
||||
\note This type corresponds to <b>Triangle Preference</b> additional hypothesis,
|
||||
which is obsolete now.
|
||||
- <b>Quadrangle preference</b> forces building only quadrangles in the
|
||||
transition area along the finer meshed sides. This hypothesis has a
|
||||
restriction: the total quantity of segments on all
|
||||
four sides of the face must be even (divisible by 2).
|
||||
\note This type corresponds to <b>Quadrangle Preference</b> additional hypothesis,
|
||||
which is obsolete now.
|
||||
- <b>Quadrangle preference (reversed)</b> works in the same way and
|
||||
with the same restriction as <b>Quadrangle preference</b>, but
|
||||
the transition area is located along the coarser meshed sides.</li>
|
||||
<li><b>Reduced</b> type forces building only quadrangles and the transition
|
||||
between the sides is made gradually, layer by layer. This type has
|
||||
a limitation on the number of segments: one pair of opposite sides must have
|
||||
the same number of segments, the other pair must have an even difference
|
||||
between the numbers of segments on the sides. In addition, number
|
||||
of rows of faces between sides with different discretization
|
||||
should be enough for the transition. At the fastest transition
|
||||
pattern, three segments become one (see the image below), hence
|
||||
the least number of face rows needed to reduce from Nmax segments
|
||||
to Nmin segments is log<sub>3</sub>( Nmax / Nmin ). The number of
|
||||
face rows is equal to number of segments on each of equally
|
||||
discretized sides.
|
||||
\image html reduce_three_to_one.png "The fastest transition pattern: 3 to 1"
|
||||
</li>
|
||||
</ul>
|
||||
the transition area is located along the coarser meshed sides.
|
||||
- <b>Reduced</b> type forces building only quadrangles and the transition
|
||||
between the sides is made gradually, layer by layer. This type has
|
||||
a limitation on the number of segments: one pair of opposite sides must have
|
||||
the same number of segments, the other pair must have an even difference
|
||||
between the numbers of segments on the sides. In addition, the number
|
||||
of rows between sides with different discretization
|
||||
should be enough for the transition. Following the fastest transition
|
||||
pattern, three segments become one (see the image below), hence
|
||||
the least number of face rows needed to reduce from Nmax segments
|
||||
to Nmin segments is log<sub>3</sub>( Nmax / Nmin ). The number of
|
||||
face rows is equal to the number of segments on each of equally
|
||||
discretized sides.
|
||||
\image html reduce_three_to_one.png "The fastest transition pattern: 3 to 1"
|
||||
|
||||
<b>See Also</b> a sample TUI Script of a
|
||||
\ref tui_quadrangle_parameters "Quadrangle Parameters" hypothesis.
|
||||
|
@ -2,27 +2,26 @@
|
||||
|
||||
\page clipping_page Clipping
|
||||
|
||||
\n Using this menu you can create cross-section views (clipping planes)
|
||||
\b Clipping allows creating cross-section views (clipping planes)
|
||||
of your mesh.
|
||||
|
||||
To start, click on the \em New button.
|
||||
It is available as a sub-item in the context menu of an active mesh.
|
||||
|
||||
Now you must specify what mode of creating plane you want to choose:
|
||||
absolute or relative.
|
||||
To create a clipping plane, click on the \b New button in the dialog and choose how it is defined: by \b Absolute or \b Relative coordinates.
|
||||
|
||||
<b>Absolute mode</b>
|
||||
<b>Absolute Coordinates</b>
|
||||
|
||||
\image html Clipping_Absolute.png
|
||||
|
||||
- <b>Base point</b> - allows to define the coordinates of the base
|
||||
- <b>Base point</b> - allows defining the coordinates of the base
|
||||
point for the clipping plane.
|
||||
|
||||
- <b>Reset</b> - returns the base point to coordinate origin.
|
||||
|
||||
- <b>Direction</b> - allows to define the orientation of the
|
||||
- <b>Direction</b> - allows defining the orientation of the
|
||||
clipping plane.
|
||||
|
||||
- <b>Invert</b> - allows to select which part of the object will be
|
||||
- <b>Invert</b> - allows selecting, which part of the object will be
|
||||
removed and which will remain after clipping.
|
||||
|
||||
<b>Relative mode</b>
|
||||
@ -30,42 +29,34 @@ absolute or relative.
|
||||
\image html Clipping_Relative.png
|
||||
|
||||
- \b Orientation ( ||X-Y, ||X-Z or ||Y-Z).
|
||||
|
||||
- \b Distance between the opposite extremities of the boundary box of
|
||||
selected objects, if it is set to 0.5 the boundary box is split in two halves.
|
||||
|
||||
- \b Rotation (in angle degrees) <b>around X</b> (Y to Z) and <b>around
|
||||
Y</b> (X to Z) (depending on the chosen Orientation)
|
||||
|
||||
The parameters of cross-section:
|
||||
|
||||
List of <b>meshes, sub-meshes and groups</b> to which the cross-section will be applied.
|
||||
|
||||
<b>Select all</b> button allows to select and deselect all available
|
||||
objects at once.
|
||||
|
||||
If the <b>Show preview</b> button is on, you can see the clipping plane
|
||||
in the <b>3D Viewer</b>.
|
||||
|
||||
\image html before_clipping.png "The plane and the cut object"
|
||||
|
||||
Also there the possibility to interact directly with the clipping plane in 3D
|
||||
view with mouse. User can change the parameters of clipping plane by dialog data
|
||||
or by hand.
|
||||
|
||||
\image html before_clipping_preview.png "The preview plane and the cut object"
|
||||
|
||||
If the <b>Auto Apply</b> button is on, you can preview the
|
||||
The other parameters are available in both modes :
|
||||
|
||||
- <b>OpenGL clipping</b> check-box allows choosing OpenGL native clipping, which clips the whole presentation. If it is unchecked, the clipping is done on the dataset i.e. only the visibility of separate mesh cells is changed (see the examples).
|
||||
- The List contains <b>Meshes, sub-meshes and groups</b> to which the cross-section will be applied.
|
||||
- <b>Select all</b> check-box allows to selecting and deselecting all available objects at once.
|
||||
- <b>Show preview</b> check-box shows the clipping plane in the <b>3D Viewer</b>.
|
||||
- <b>Auto Apply</b> check-box shows button is on, you can preview the
|
||||
cross-section in the <b>3D Viewer</b>.
|
||||
|
||||
Also, it is possible to specify the type of clipping: using dataset,
|
||||
i.e. it only changes the visibility of separate mesh cells or alternative
|
||||
clipping - an OpenGL native one, which clips overall presentation.
|
||||
For choosing use <b>OpenGL clipping</b> checkbox.
|
||||
|
||||
\image html dataset_clipping.png "The cross-section using dataset"
|
||||
|
||||
|
||||
\image html opengl_clipping.png "The OpenGL cross-section"
|
||||
It is also possible to interact with the clipping plane directly in 3D
|
||||
view using the mouse.
|
||||
|
||||
To get a new object from \b Clipping, click \b Apply.
|
||||
|
||||
<b>Examples:</b>
|
||||
|
||||
\image html dataset_clipping.png "The cross-section using dataset"
|
||||
|
||||
\image html opengl_clipping.png "The OpenGL cross-section"
|
||||
|
||||
|
||||
*/
|
||||
|
@ -314,8 +314,8 @@ or/and hidden by other mesh elements. They can be seen after
|
||||
switching the mesh to Wireframe visualization mode or switching off
|
||||
the visualization of faces and volumes (if any).
|
||||
|
||||
<b>Bad Mesh to Group</b> button creates groups of the bad mesh entities,
|
||||
thus allowing you for more comfortable analysis of these entities.
|
||||
<b>Bad Mesh to Group</b> button creates groups of bad mesh entities
|
||||
to facilitate their analysis.
|
||||
|
||||
\image html show_bad_mesh.png
|
||||
<em>Edges bounding a hole in the surface are shown in magenta using <b>Show
|
||||
@ -341,8 +341,8 @@ this, there exist two algorithms: <b>Use existing edges</b> and <b>Use
|
||||
For example, you want to use standard algorithms to generate 1D and 3D
|
||||
meshes and to create 2D mesh by your python code. Then you
|
||||
<ol>
|
||||
<li> create a mesh object, assign an 1D algorithm,</li>
|
||||
<li> invoke \b Compute command, which computes an 1D mesh,</li>
|
||||
<li> create a mesh object, assign a 1D algorithm,</li>
|
||||
<li> invoke \b Compute command, which computes a 1D mesh,</li>
|
||||
<li> assign <b>Use existing faces</b> and a 3D algorithm,</li>
|
||||
<li> run your python code, which creates a 2D mesh,</li>
|
||||
<li> invoke \b Compute command, which computes a 3D mesh.</li>
|
||||
|
@ -2,13 +2,13 @@
|
||||
|
||||
\page cutting_quadrangles_page Cutting quadrangles
|
||||
|
||||
\n This operation allows cutting one or several quadrangle elements
|
||||
into two or four triangles.
|
||||
This operation allows cutting one or several quadrangle elements into two or four triangles.
|
||||
|
||||
<em>To cut quadrangles:</em>
|
||||
<ol>
|
||||
<li>Display a mesh, a 2D sub-mesh or a group of faces in the 3D viewer.</li>
|
||||
<li>In the \b Modification menu select the <b>Cutting of quadrangles</b> item or
|
||||
|
||||
1) Display a mesh, a 2D sub-mesh or a group of faces in the 3D viewer.
|
||||
|
||||
2) In the \b Modification menu select the <b>Cutting of quadrangles</b> item or
|
||||
click <em>"Cutting of quadrangles"</em> button in the toolbar.
|
||||
|
||||
\image html image82.png
|
||||
@ -18,50 +18,27 @@ The following dialog box will appear:
|
||||
|
||||
\image html a-cuttingofquadrangles.png
|
||||
|
||||
<ul>
|
||||
<li>The main list contains the list of quadrangles selected for cutting. You can
|
||||
click on an quadrangle in the 3D viewer and it will be highlighted (lock Shift
|
||||
keyboard button to select several quadrangles). Click \b Add button and the ID of
|
||||
this quadrangle will be added to the list. To remove a 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
|
||||
quadrangles.</li>
|
||||
<li><b>Apply to all</b> check box allows to cut all quadrangles of the selected mesh,
|
||||
sub-mesh or group.</li>
|
||||
<li>\b Preview provides a preview of cutting in the viewer. It is disabled for <b>Cut
|
||||
into 4 triangles</b> as this cutting way implies no ambiguity.</li>
|
||||
</ul>
|
||||
|
||||
<ul>
|
||||
<li>\b Criterion defines a cutting way.
|
||||
<ul>
|
||||
<li><b>Cut into 4 triangles</b> selects cutting the quadrangle into four triangles by
|
||||
inserting a new node at the center of quadrangle. The other options selects cutting
|
||||
the quadrangle into two triangles by connecting nodes of either of the two diagonals.
|
||||
<li><b>Use diagonal 1-3</b> and <b>Use diagonal 2-4</b> allows to specify the
|
||||
opposite corners which will be connected to form two new triangles.</li>
|
||||
<li><b>Use numeric functor</b> allows to choose a quality metric which will be
|
||||
optimized when choosing a diagonal for cutting a quadrangle.
|
||||
<ul>
|
||||
<li><b>Minimum diagonal</b> cuts by the shortest diagonal.</li>
|
||||
<li><b>Aspect Ratio</b> cuts by the diagonal splitting the quadrangle into
|
||||
triangles with \ref aspect_ratio_page "Aspect Ratio" closer to 1.</li>
|
||||
<li><b>Minimum Angle</b> cuts by the diagonal splitting the quadrangle into
|
||||
triangles with \ref minimum_angle_page "Minimum Angle" closer to 60
|
||||
degrees.</li>
|
||||
<li><b>Skew</b> cuts by the diagonal splitting the quadrangle into triangles
|
||||
with \ref skew_page "Skew" closer to 0.0 degrees.</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><b>Select from</b> allows to choose a sub-mesh or an existing group whose
|
||||
quadrangle elements will be automatically added to the main list.</li>
|
||||
</ul>
|
||||
- The main list contains the list of quadrangles selected for cutting. You can
|
||||
click on a quadrangle in the 3D viewer and it will be highlighted (lock Shift
|
||||
keyboard button to select several quadrangles):
|
||||
- Click \b Add button and the ID of this quadrangle will be added to the list.
|
||||
- To remove a selected element or elements from the list click \b Remove button.
|
||||
- <b>Sort list</b> button allows sorting the list of IDs.
|
||||
- \b Filter button allows applying a definite filter to the selection of quadrangles.
|
||||
- <b>Apply to all</b> check box allows cutting all quadrangles of the selected mesh, sub-mesh or group.
|
||||
- \b Preview provides a preview of cutting in the viewer. It is disabled for <b>Cut into 4 triangles</b> as this cutting way implies no ambiguity.
|
||||
- \b Criterion defines the way of cutting:
|
||||
- <b>Cut into 4 triangles</b> allows cutting a quadrangle into four triangles by inserting a new node at the center of the quadrangle. The other options allow cutting a quadrangle into two triangles by connecting the nodes of a diagonal.
|
||||
- <b>Use diagonal 1-3</b> and <b>Use diagonal 2-4</b> allow specifying the opposite corners, which will be connected to form two new triangles.
|
||||
- <b>Use numeric functor</b> allows selecting in the field below a quality metric, which will be optimized when choosing a diagonal for cutting a quadrangle:
|
||||
- <b>Minimum diagonal</b> cuts by the shortest diagonal.
|
||||
- <b>Aspect Ratio</b> cuts by the diagonal splitting the quadrangle into triangles with \ref aspect_ratio_page "Aspect Ratio" closer to 1
|
||||
- <b>Minimum Angle</b> cuts by the diagonal splitting the quadrangle into triangles with \ref minimum_angle_page "Minimum Angle" closer to 60 degrees.
|
||||
- <b>Skew</b> cuts by the diagonal splitting the quadrangle into triangles with \ref skew_page "Skew" closer to 0.0 degrees.
|
||||
- <b>Select from</b> allows choosing a sub-mesh or an existing group, whose quadrangle elements will be automatically added to the main list.
|
||||
|
||||
</li>
|
||||
<li>Click the \b Apply or <b>Apply and Close</b> button to confirm the operation.</li>
|
||||
</ol>
|
||||
3) Click the \b Apply or <b>Apply and Close</b> button to confirm the operation.
|
||||
|
||||
\image html image52.jpg "The chosen quadrangular element"
|
||||
|
||||
|
@ -2,8 +2,8 @@
|
||||
|
||||
\page double_nodes_page Duplicate Nodes or/and Elements
|
||||
|
||||
\n This operation allows to duplicate nodes or/and elements of your mesh.
|
||||
Duplication of nodes can be useful to emulate a crack in the model.
|
||||
\n This operation allows duplicating mesh nodes or/and elements, which can be useful to emulate a crack in the model.
|
||||
|
||||
Duplication consists in creation of mesh element "equal" to existing ones.
|
||||
|
||||
<em>To duplicate nodes or/and elements:</em>
|
||||
@ -31,9 +31,8 @@ Duplication consists in creation of mesh element "equal" to existing ones.
|
||||
|
||||
<br>
|
||||
\anchor mode_without_elem_anchor
|
||||
<h2>Duplicate nodes only</h2>
|
||||
|
||||
In this mode the dialog looks like:
|
||||
<h2>Duplicate nodes only</h2>
|
||||
|
||||
\image html duplicate01.png
|
||||
|
||||
@ -42,28 +41,26 @@ Parameters to be defined in this mode:
|
||||
<li><b>Group of nodes to duplicate</b> (<em>mandatory</em>): these
|
||||
nodes will be duplicated.</li>
|
||||
<li><b>Group of elements to replace nodes with new ones</b>
|
||||
(<em>optional</em>): the new nodes will replace the nodes to
|
||||
duplicate within these elements.</li>
|
||||
(<em>optional</em>): the new nodes will replace the duplicated nodes within these elements.</li>
|
||||
<li><b>Construct group with newly created nodes</b> option
|
||||
(<em>checked by default</em>): if checked - the group with just
|
||||
(<em>checked by default</em>): if checked - the group with newly
|
||||
created nodes will be built.</li>
|
||||
</ul>
|
||||
A schema below explains the crack emulation using the node duplication.
|
||||
A schema below illustrates how the crack is emulated using the node duplication.
|
||||
\image html crack_emulation_double_nodes.png "Crack emulation"
|
||||
This schema shows a virtual crack in a 2D mesh created using this duplication
|
||||
mode. In this schema:
|
||||
- Black balls are <b>nodes to duplicate</b>.
|
||||
mode:
|
||||
- Black balls are <b>duplicated nodes</b>.
|
||||
- Red balls are <b>new nodes</b>.
|
||||
- <b>Elements to replace nodes with new ones</b> are marked with green.
|
||||
|
||||
Note that in reality <b>nodes to duplicate</b> coincide with <b>new nodes</b>.
|
||||
|
||||
Note that in the reality <b>duplicated nodes</b> coincide with <b>new nodes</b>.
|
||||
|
||||
<br>
|
||||
\anchor mode_with_elem_anchor
|
||||
<h2>Duplicate nodes and border elements</h2>
|
||||
|
||||
In this mode the dialog looks like:
|
||||
|
||||
<h2>Duplicate nodes and border elements</h2>
|
||||
|
||||
\image html duplicate02.png
|
||||
|
||||
@ -77,10 +74,10 @@ Parameters to be defined in this mode:
|
||||
(<em>mandatory</em>): the new nodes will replace the nodes to
|
||||
duplicate within these elements.</li>
|
||||
<li><b>Construct group with newly created elements</b> option
|
||||
(<em>checked by default</em>): if checked - the group of just created
|
||||
(<em>checked by default</em>): if checked - the group of newly created
|
||||
elements will be built.</li>
|
||||
<li><b>Construct group with newly created nodes</b> option
|
||||
(<em>checked by default</em>): if checked - the group of just
|
||||
(<em>checked by default</em>): if checked - the group of newly
|
||||
created nodes will be built.</li>
|
||||
</ul>
|
||||
|
||||
@ -89,15 +86,14 @@ with border elements.
|
||||
\image html crack_emulation_double_nodes_with_elems.png "Crack emulation"
|
||||
This schema shows a virtual crack in a 2D mesh created using this duplication
|
||||
mode. In this schema:
|
||||
- Black segments are <b>elements to duplicate</b> (edges in 2D case).
|
||||
- Black balls (except the lowest one) are nodes of <b>elements to
|
||||
duplicate</b> that are duplicated.
|
||||
- The lowest black ball is a <b>node not to duplicate</b>.
|
||||
- Red balls are <b>creates nodes</b>.
|
||||
- Black segments are <b>duplicated elements</b> (edges in 2D case).
|
||||
- Black balls (except for the lowest one) are duplicated nodes of <b>duplicated elements</b>.
|
||||
- The lowest black ball is the <b>non-duplicated node</b>.
|
||||
- Red balls are <b>newly created nodes</b>.
|
||||
- Red segments are <b>created elements</b> (edges).
|
||||
- <b>Elements to replace nodes with new ones</b> are marked with green.
|
||||
|
||||
Note that in reality <b>nodes to duplicate</b> coincide with <b>new nodes</b>.
|
||||
Note that in the reality <b>nodes to duplicate</b> coincide with <b>new nodes</b>.
|
||||
<br>
|
||||
In a 3D case, where <b>elements to duplicate</b> are faces, the edges
|
||||
located at the "crack" (if any) are cloned automatically.
|
||||
@ -106,24 +102,22 @@ located at the "crack" (if any) are cloned automatically.
|
||||
\anchor mode_elem_only_anchor
|
||||
<h2>Duplicate elements only</h2>
|
||||
|
||||
This mode just duplicates given elements, i.e. creates new elements on
|
||||
the same nodes as the given elements.
|
||||
This mode duplicates the given elements, i.e. creates new elements with the same nodes as the given elements.
|
||||
|
||||
<br>
|
||||
In this mode the dialog looks like:
|
||||
|
||||
|
||||
\image html duplicate03.png
|
||||
|
||||
Parameters to be defined in this mode:
|
||||
<ul>
|
||||
<li><b>Group of elements to duplicate</b> (<em>mandatory</em>): these
|
||||
elements will be duplicated.</li>
|
||||
<li><b>Construct group with newly created elements</b> option
|
||||
(<em>checked by default</em>): if checked - the group of just created
|
||||
elements will be built. A name of the created group starts from
|
||||
(<em>checked by default</em>): if checked - the group of newly created
|
||||
elements will be built. The name of the created group starts from
|
||||
"DoubleElements".</li>
|
||||
</ul>
|
||||
|
||||
|
||||
<br><b>See Also</b> a sample TUI Script of a
|
||||
\ref tui_duplicate_nodes "Duplicate nodes or/and elements" operation.
|
||||
|
||||
|
@ -1,8 +1,8 @@
|
||||
/*!
|
||||
|
||||
\page extrusion_along_path_page Extrusion along a path
|
||||
\page extrusion_along_path_page Extrusion along Path
|
||||
|
||||
\n In principle, <b>Extrusion along a path</b> works in the same way
|
||||
\n In principle, <b>Extrusion along Path</b> works in the same way
|
||||
as \b Extrusion, the main difference is that we define not a vector,
|
||||
but a path of extrusion which must be a 1D mesh or 1D sub-mesh.
|
||||
To get an idea of how this algorithm works, examine several examples,
|
||||
@ -69,7 +69,7 @@ mesh.</center>
|
||||
<center>The same, but using angles {45, -45, 45, -45, 45, -45, 45,
|
||||
-45}</center>
|
||||
|
||||
<br><em>To use Extrusion along a path:</em>
|
||||
<br><em>To use Extrusion along Path:</em>
|
||||
<ol>
|
||||
<li>From the \b Modification menu choose the <b>Extrusion along a
|
||||
path</b> item or click <em>"Extrusion along a path"</em> button in the toolbar.
|
||||
@ -88,25 +88,24 @@ The following dialog common for line and planar elements will appear:
|
||||
<li>specify the <b>IDs of the elements</b> which will be extruded
|
||||
|
||||
<ul>
|
||||
<li><b>Select the whole mesh, submesh or group</b> activating this
|
||||
checkbox; or</li>
|
||||
<li>choose mesh elements with the mouse in the 3D Viewer. It is
|
||||
<li><b>Select the whole mesh, sub-mesh or group</b> activating the corresponding check-box; or</li>
|
||||
<li>Choose mesh elements with the mouse in the 3D Viewer. It is
|
||||
possible to select a whole area with a mouse frame; or</li>
|
||||
<li>input the element IDs directly in <b>ID Elements</b> field. The selected elements will be highlighted in the
|
||||
<li>Input the element IDs directly in <b>ID Elements</b> field. The selected elements will be highlighted in the
|
||||
viewer; or</li>
|
||||
<li>apply Filters. <b>Set filter</b> button allows to apply a filter to the selection of elements. See more
|
||||
about filters in the \ref selection_filter_library_page "Selection filter library" page.</li>
|
||||
</ul>
|
||||
|
||||
</li>
|
||||
<li>define the \b Path along which the elements will be extruded.<br>
|
||||
<li>Define the \b Path along which the elements will be extruded.<br>
|
||||
Path definition consists of several elements:
|
||||
<ul>
|
||||
<li><b>Mesh or submesh</b> - 1D mesh or sub-mesh, along which proceeds the extrusion</li>
|
||||
<li><b>Start node</b> - the start node. It is used to define the direction of extrusion </li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>activate <b>Generate Groups</b> checkbox if it is necessary to copy the groups of
|
||||
<li>Activate <b>Generate Groups</b> check-box if it is necessary to copy the groups of
|
||||
elements of the source mesh to the newly created one. </li>
|
||||
</ul>
|
||||
</li>
|
||||
@ -119,9 +118,8 @@ curve. By default, the <b>Base Point</b> around which the elements are rotated i
|
||||
the mass center of the elements, however, you can specify any point as
|
||||
the <b>Base Point</b> and the elements will be rotated with respect to this
|
||||
point.<br>
|
||||
Note that it is the <b>Base Point</b> whos track exactly equals to the
|
||||
path, and all the elements being extruded just keep their relative
|
||||
position around the <b>Base Point</b> at each iteration.
|
||||
Note that only the displacement of the <b>Base Point</b> exactly equals to the
|
||||
path, and all other extruded elements simply keep their position relatively to the <b>Base Point</b> at each iteration.
|
||||
</li>
|
||||
<li>The elements can also be rotated around the path to get the resulting
|
||||
mesh in a helical fashion. You can set the values of angles at the
|
||||
|
@ -38,21 +38,20 @@ group as a whole mesh.
|
||||
|
||||
\image html meshexportmesh.png
|
||||
|
||||
At export to MED and SAUV format files additional parameters are available.
|
||||
There are additional parameters available at export to MED and SAUV format files.
|
||||
<ul>
|
||||
<li><b>Automatically create groups</b> check-box specifies whether to
|
||||
create groups of all mesh entities of available dimensions or
|
||||
not. If checked, the created groups have names like "Group_On_All_Nodes",
|
||||
"Group_On_All_Faces" etc.</li>
|
||||
"Group_On_All_Faces", etc.</li>
|
||||
<li><b>Automatically define space dimension</b> check-box specifies
|
||||
whether to define space dimension for export by mesh configuration
|
||||
or not. Usually the mesh is exported as a mesh in 3D space, just as
|
||||
it is in Mesh module. The mesh can be exported as a mesh in lower
|
||||
dimension in following cases, provided that this check-box is
|
||||
checked.
|
||||
it is in Mesh module. The mesh can be exported as a mesh of a lower
|
||||
dimension in the following cases, provided that this check-box is checked:
|
||||
<ul>
|
||||
<li> 1D: if all mesh nodes lie on OX coordinate axis. </li>
|
||||
<li> 2D: if all mesh nodes lie on XOY coordinate plane. </li>
|
||||
<li> <b>1D</b>: if all mesh nodes lie on OX coordinate axis. </li>
|
||||
<li> <b>2D</b>: if all mesh nodes lie in XOY coordinate plane. </li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
|
@ -6,7 +6,7 @@
|
||||
|
||||
\n \b MESH module of SALOME is destined for:
|
||||
<ul>
|
||||
<li>\ref importing_exporting_meshes_page "import and export of meshes in different formats";</li>
|
||||
<li>\ref importing_exporting_meshes_page "import and export of meshes in various formats";</li>
|
||||
<li>\subpage about_meshes_page "meshing geometrical models"
|
||||
previously created or imported by the Geometry component; </li>
|
||||
<li>\subpage viewing_meshes_overview_page "viewing created meshes" in
|
||||
@ -18,22 +18,20 @@ allowing to highlight important elements;
|
||||
\subpage filters_page "Filters" functionality;</li>
|
||||
<li>\subpage modifying_meshes_page "modifying meshes" with a vast
|
||||
array of dedicated operations;</li>
|
||||
<li>different \subpage measurements_page "measurements" of the mesh objects;
|
||||
<li>easily setting parameters via the variables predefined in
|
||||
\subpage using_notebook_mesh_page "Salome notebook".</li>
|
||||
<li>various \subpage measurements_page "measurements" of the mesh objects.
|
||||
</ul>
|
||||
|
||||
The possibility to sort the created sub-meshes or groups is detailed on
|
||||
\subpage arranging_study_objects_page section.
|
||||
It is possible to easily set parameters via the variables predefined in
|
||||
\subpage using_notebook_mesh_page "Salome notebook".
|
||||
|
||||
Mesh module preferences are described in the \subpage mesh_preferences_page section of SALOME Mesh Help.
|
||||
Also, there is a possibility to \subpage arranging_study_objects_page "re-arrange sub-meshes and groups in the SALOME study".
|
||||
|
||||
Almost all mesh module functionalities are accessible via
|
||||
\subpage smeshpy_interface_page "Mesh module Python interface".
|
||||
|
||||
Other functions are available in <a class="el" target="_new" href="../../tui/SMESH/docutils/index.html">salome.smesh python package</a>.
|
||||
|
||||
|
||||
\image html image7.jpg "Example of MESH module usage for engineering tasks"
|
||||
|
||||
*/
|
||||
|
@ -18,79 +18,72 @@ available, but this operation will be extended in the future to support
|
||||
other mesh objects - elements, meshes, sub-meshes and groups.
|
||||
|
||||
To start <b>Minimum Distance</b> operation, select <b>Minimum Distance</b>
|
||||
item from \b Measurements menu.
|
||||
tab in \b Measurements dialog.
|
||||
|
||||
\image html min_distance.png
|
||||
|
||||
In the dialog box choose the first target and the second target mode by
|
||||
Choose the first and the second target by
|
||||
switching the corresponding radio buttons, then select the objects the distance
|
||||
between which is to be calculated (or input their IDs directly
|
||||
in case of nodes/elements) and press \em Compute button.
|
||||
in case of nodes/elements) and press \b Compute button.
|
||||
|
||||
The following types of targets are supported:
|
||||
- \em Node: single mesh node;
|
||||
- \em Element: single mesh element (not available in this version);
|
||||
- \em Object: mesh, sub-mesh or group object (not available in this
|
||||
The following targets are supported:
|
||||
- \b Node: single mesh node;
|
||||
- \b Element: single mesh element (not available in this version);
|
||||
- \b Object: mesh, sub-mesh or group object (not available in this
|
||||
version);
|
||||
- \em Origin: origin of the global co-ordinate system.
|
||||
- \b Origin: origin of the global co-ordinate system.
|
||||
|
||||
The result will
|
||||
be shown in the bottom area of the dialog box. In addition, a simple
|
||||
The result will be shown in the bottom area of the dialog. In addition, a simple
|
||||
preview will be shown in the 3D viewer.
|
||||
|
||||
\image html min_distance_preview.png
|
||||
|
||||
\section bounding_box_anchor Bounding Box
|
||||
|
||||
This operation allows to calculate the bounding box of the selected
|
||||
This operation allows calculating the bounding box of the selected
|
||||
object(s).
|
||||
|
||||
To start <b>Bounding Box</b> operation, select <b>Bounding Box</b>
|
||||
item from \b Measurements menu.
|
||||
tab in \b Measurements dialog.
|
||||
|
||||
\image html bnd_box.png
|
||||
|
||||
In the dialog box choose the required type of the object by switching the
|
||||
corresponding radio button, select the object(s) and press \em Compute button.
|
||||
Choose the required type of the object by switching the corresponding radio button, select the object(s) and press \em Compute button.
|
||||
|
||||
The following types of input are available:
|
||||
- \em Objects: select one or several mesh, sub-mesh or group objects;
|
||||
- \em Nodes: select a set of mesh nodes;
|
||||
- \em Elements: select a set of mesh elements.
|
||||
- \b Objects: one or several mesh, sub-mesh or group objects;
|
||||
- \b Nodes: a set of mesh nodes;
|
||||
- \b Elements: a set of mesh elements.
|
||||
|
||||
The result of calculation will be shown in the bottom area of the
|
||||
dialog box. In addition, a simple preview will be shown in the 3D
|
||||
viewer.
|
||||
dialog. In addition, a simple preview will be shown in the 3D viewer.
|
||||
|
||||
\image html bnd_box_preview.png
|
||||
|
||||
\section basic_properties_anchor Basic Properties
|
||||
|
||||
This operation allows calculation of length, area or volume for the the selected
|
||||
object:
|
||||
- Length is calculated as a sum of length of all 1D elements;
|
||||
- Area id a sum of area of all 2D elements
|
||||
- Volume is a sum of volume of all 3D elements.
|
||||
This operation provides calculation of length, area or volume for the the selected object:
|
||||
- \b Length is calculated as a sum of lengths of all 1D elements;
|
||||
- \b Area is a sum of areas of all 2D elements
|
||||
- \b Volume is a sum of volumes of all 3D elements.
|
||||
|
||||
To start one of <b>Basic Properties</b> calculations, select <b>Length</b>, <b>Area</b>
|
||||
or <b>Volume</b> item from <b>Measurements - Basic Properties</b> menu.
|
||||
To start a <b>Basic Properties</b> calculation, select <b>Length</b>, <b>Area</b> or <b>Volume</b> item.
|
||||
|
||||
\image html basic_props.png
|
||||
|
||||
In the dialog box select the required type of calculation (length, area or volume), select
|
||||
the the object (mesh, sub-mesh or group) and press \em Compute button.
|
||||
In the dialog box select the required type of calculation (length, area or volume) and the object (mesh, sub-mesh or group) and press \b Compute button.
|
||||
|
||||
The result of calculation will be shown in the bottom area of the
|
||||
dialog box.
|
||||
The result of calculation will be shown in the bottom area of the dialog.
|
||||
|
||||
\note
|
||||
- If mesh consists of 3D elements only, its "length" and "area" will be 0.
|
||||
- As calculation result is a sum of length, area and volume of all mesh elements,
|
||||
duplications are not taken into account; i.e. all duplicated elements
|
||||
- If the mesh consists of 3D elements only, its "length" and "area" will be 0.
|
||||
- As calculation result is a sum of lengths, areas and volumes of all mesh elements, the
|
||||
duplication is not taken into account; i.e. all duplicated elements
|
||||
(elements built on the same set of nodes) will be included into the result.
|
||||
- Similarly, intersection of elements is not taken into account.
|
||||
|
||||
<b>See Also</b> a sample TUI Script of a
|
||||
<b>See Also</b> a sample TUI Script of
|
||||
\ref tui_measurements_page "Measurement operations".
|
||||
|
||||
*/
|
||||
|
@ -124,12 +124,10 @@ preferences (zero value means no limit).
|
||||
\anchor mesh_quality_info_anchor
|
||||
<h2>Quality Information</h2>
|
||||
|
||||
The <b>Quality Info</b> tab page of the dialog box provides overal
|
||||
mesh quality controls information on the selected object - mesh,
|
||||
sub-mesh or mesh group:
|
||||
The <b>Quality Info</b> tab provides overall information about mesh quality controls on the selected object - mesh, sub-mesh or mesh group:
|
||||
- Name;
|
||||
- Nodes information:
|
||||
- Number of the free nodes;
|
||||
- Number of free nodes;
|
||||
- Number of double nodes;
|
||||
- Edges information:
|
||||
- Number of double edges;
|
||||
@ -145,21 +143,22 @@ sub-mesh or mesh group:
|
||||
<center>\image html ctrlinfo.png
|
||||
<em>"Quality Info" page</em></center>
|
||||
|
||||
\note User can set "Double nodes tolerance" in the dialog for local change
|
||||
\note It is possible to set "Double nodes tolerance" in the dialog for a local change
|
||||
or via the "Quality controls" in Mesh preferences.
|
||||
|
||||
\note For the perfomance reason, all quality control values for the big meshes are
|
||||
computed only by demand. For this, the user should press the "compute"
|
||||
button (see picture). Also, values are automatically computed if the number of the
|
||||
\note For performance reasons, all quality control values for big meshes are
|
||||
computed only by demand. For this, press the "compute"
|
||||
button. Also, values are automatically computed if the number of
|
||||
nodes / elements does not exceed the "Automatic controls compute limit" set
|
||||
via the "Mesh information" preferences (zero value means no limit).
|
||||
via the "Mesh information" preferences (zero value means that there is no limit).
|
||||
|
||||
The button \b "Dump" allows printing the information displayed in the
|
||||
dialog box to a .txt file.
|
||||
|
||||
In case you get <b>Mesh Information</b> via a TUI script, the information is
|
||||
displayed in the Python Console.
|
||||
<b>See the</b> \ref tui_viewing_mesh_infos "TUI Example".
|
||||
|
||||
See the \ref tui_viewing_mesh_infos "TUI Example".
|
||||
|
||||
*/
|
||||
|
||||
|
@ -11,22 +11,21 @@ later sessions with this module.
|
||||
|
||||
- <b>Automatic Update</b>
|
||||
- If you toggle <b>Automatic Update</b> checkbox, the model in your
|
||||
viewer automatically updated when you make changes in it, depending on
|
||||
viewer will be automatically updated when you make changes in it, depending on
|
||||
values of additional preferences specified below.
|
||||
- <b>Size limit (elements)</b> - allows to specify the maximum
|
||||
- <b>Size limit (elements)</b> - allows specifying the maximum
|
||||
number of elements in the resulting mesh for which the automatic updating
|
||||
of the presentation is performed. This option affects only
|
||||
<b>Compute</b> operation. Zero value means "no limit". Default value
|
||||
is 500 000 mesh elements.
|
||||
- <b>Incremental limit check</b> - when this control is switched on,
|
||||
check for mesh size limit will be applied not to total number of
|
||||
elements in resulting mesh, but iteratively to each entity types
|
||||
in the following order: 0D elements, edges, faces, volumes, balls;
|
||||
at each step number of entities of given type will be added to the
|
||||
total number of elements computed at previous step - if resulting
|
||||
number of elements does not exceed size limit, the entities of
|
||||
this type will be shown, otherwise user will be warned that some
|
||||
entities are not shown.
|
||||
the mesh size limit check is not applied to the total number of
|
||||
elements in the resulting mesh, it is applied iteratively to each entity type
|
||||
in the following order: 0D elements, edges, faces, volumes, balls.
|
||||
At each step the number of entities of a certain type is added to the
|
||||
total number of elements computed at the previous step - if the resulting
|
||||
number of elements does not exceed the size limit, the entities of
|
||||
this type are shown, otherwise the user is warned that some entities are not shown.
|
||||
|
||||
- <b>Quality Controls</b>
|
||||
- If you toggle <b>Display entity</b>, both faces and edges of an
|
||||
@ -68,40 +67,40 @@ later sessions with this module.
|
||||
information is shown:
|
||||
- <b>Simple</b> - as a plain text
|
||||
- <b>Tree</b> - in a tree-like form
|
||||
- <b>Automatic nodes compute limit</b> - allows to define the size limit for the
|
||||
- <b>Automatic nodes compute limit</b> - allows defining the size limit for the
|
||||
mesh groups for which the number of underlying nodes is calculated
|
||||
automatically. If the group size exceeds the value set in the preferences,
|
||||
the user will have to press \em Compute button explicitly. Zero value
|
||||
means "no limit". By default the value is set to 100 000 mesh elements.
|
||||
- <b>Automatic controls compute limit</b> - allows to define the size limit for the
|
||||
- <b>Automatic controls compute limit</b> - allows defining the size limit for the
|
||||
mesh elements for which the Aspect Ratio histogram is calculated
|
||||
automatically. If the mesh elements size exceeds the value set in the preferences,
|
||||
the user will have to press \em Compute button explicitly. Zero value
|
||||
it is possible to press \b Compute button explicitly to calculate the histogram . Zero value
|
||||
means "no limit". By default the value is set to 3 000 mesh elements.
|
||||
- <b>Show details on groups in element information tab</b> - when
|
||||
this option is switched off (default), only the names of groups, to which the node
|
||||
or element belongs, are shown in the \ref mesh_element_info_anchor "Info Tab"
|
||||
tab of "Mesh Information" dialog box. If this option is
|
||||
switched on, the detailed information on groups is shown.
|
||||
- <b>Dump base information</b> - allows to dump base mesh information to the
|
||||
- <b>Dump base information</b> - allows dumping base mesh information to the
|
||||
file, see \ref mesh_infos_page.
|
||||
- <b>Dump element information</b> - allows to dump element information to the
|
||||
- <b>Dump element information</b> - allows dumping element information to the
|
||||
file, see \ref mesh_infos_page.
|
||||
- <b>Dump additional information</b> - allows to dump additional mesh
|
||||
- <b>Dump additional information</b> - allows dumping additional mesh
|
||||
information to the file, see \ref mesh_infos_page.
|
||||
- <b>Dump controls information</b> - allows to dump quality mesh
|
||||
- <b>Dump controls information</b> - allows dumping quality mesh
|
||||
information to the file, see \ref mesh_infos_page.
|
||||
|
||||
- <b>Automatic Parameters</b>
|
||||
- <b>Ratio Bounding Box Diagonal / Max Size</b> - this parameter is
|
||||
used for automatic meshing: ratio between the bounding box of the
|
||||
used for automatic meshing. This is the ratio between the bounding box of the
|
||||
meshed object and the Max Size of segments.
|
||||
- <b>Default Number of Segments</b> - allows defining the default
|
||||
- <b>Default Number of Segments</b> - defines the default
|
||||
number of segments on each edge.
|
||||
|
||||
- <b>Mesh loading</b>
|
||||
- If <b>No mesh loading from study file at hypothesis modification</b>
|
||||
checkbox is on, the mesh data will not be loaded from the study file
|
||||
check-box is on, the mesh data will not be loaded from the study file
|
||||
when a hypothesis is modified. This allows saving time by omitting
|
||||
loading data of a large mesh that is planned to be recomputed with other parameters.
|
||||
|
||||
|
@ -21,13 +21,9 @@ The following dialog box shall appear:
|
||||
</li>
|
||||
<li>Enter the coordinates of the destination point.</li>
|
||||
<li>Check in <b>Find closest to destination</b> option or
|
||||
select the necessary node manually (X, Y, Z, dX, dY, dZ fields allow
|
||||
to see original coordinates and displacement of the node to move).
|
||||
\b Preview check-box allows to see the results of the operation.</li>
|
||||
<li>The <b>Update Destination</b> button is activated when <b>Find
|
||||
closest to destination</b> option is unchecked. Click the <b>Update
|
||||
Destination</b> button for update coordinates of the destination point
|
||||
from original coordinates of the node to move.</li>
|
||||
select the necessary node manually (X, Y, Z, dX, dY, dZ fields show the original coordinates and displacement of the node to move).
|
||||
\b Preview check-box shows the operation results.</li>
|
||||
<li> <b>Update Destination</b> button is activated when <b>Find closest to destination</b> option is unchecked. Click <b>Update Destination</b> button to update the coordinates of the destination point.</li>
|
||||
<li>Click the \b Apply or <b>Apply and Close</b> button.</li>
|
||||
</ol>
|
||||
|
||||
|
@ -84,7 +84,7 @@ IDs.
|
||||
the color defined by the <b>Threshold Value</b>.
|
||||
</li><li>
|
||||
<b>Elements of a domain</b> allows selection of entities belonging to
|
||||
one domain of a mesh. The domain is a part of mesh not connected to
|
||||
one domain of a mesh. The domain is mesh part not connected to
|
||||
other parts. <b>Threshold Value</b> locating any element of the domain can be either
|
||||
- node ID (that you can pick in the Viewer) or
|
||||
- geometrical vertex (that you can pick either in the Viewer or in the
|
||||
|
@ -658,7 +658,7 @@ bool SMESH_MeshEditor::InverseDiag (const SMDS_MeshElement * theTria1,
|
||||
|
||||
// put nodes in array and find out indices of the same ones
|
||||
const SMDS_MeshNode* aNodes [6];
|
||||
int sameInd [] = { 0, 0, 0, 0, 0, 0 };
|
||||
int sameInd [] = { -1, -1, -1, -1, -1, -1 };
|
||||
int i = 0;
|
||||
SMDS_ElemIteratorPtr it = theTria1->nodesIterator();
|
||||
while ( it->more() ) {
|
||||
@ -684,15 +684,15 @@ bool SMESH_MeshEditor::InverseDiag (const SMDS_MeshElement * theTria1,
|
||||
}
|
||||
|
||||
// find indices of 1,2 and of A,B in theTria1
|
||||
int iA = 0, iB = 0, i1 = 0, i2 = 0;
|
||||
int iA = -1, iB = 0, i1 = 0, i2 = 0;
|
||||
for ( i = 0; i < 6; i++ ) {
|
||||
if ( sameInd [ i ] == 0 ) {
|
||||
if ( sameInd [ i ] == -1 ) {
|
||||
if ( i < 3 ) i1 = i;
|
||||
else i2 = i;
|
||||
}
|
||||
else if (i < 3) {
|
||||
if ( iA ) iB = i;
|
||||
else iA = i;
|
||||
if ( iA >= 0) iB = i;
|
||||
else iA = i;
|
||||
}
|
||||
}
|
||||
// nodes 1 and 2 should not be the same
|
||||
@ -5463,7 +5463,7 @@ SMESH_MeshEditor::MakeExtrElements(TIDSortedElemSet& theElements
|
||||
for( ; itPP != fullList.end(); itPP++) {
|
||||
aPPs.push_back( *itPP );
|
||||
if ( theHasAngles && itAngles != theAngles.end() )
|
||||
aPPs.back().SetAngle( *itAngles );
|
||||
aPPs.back().SetAngle( *itAngles++ );
|
||||
}
|
||||
|
||||
TNodeOfNodeListMap mapNewNodes;
|
||||
|
@ -2667,7 +2667,7 @@ double SMESH_MesherHelper::MaxTolerance( const TopoDS_Shape& shape )
|
||||
* \return double - the angle (between -Pi and Pi), negative if the angle is concave,
|
||||
* 1e100 in case of failure
|
||||
* \waring Care about order of the EDGEs and their orientation to be as they are
|
||||
* within the FACE!
|
||||
* within the FACE! Don't pass degenerated EDGEs neither!
|
||||
*/
|
||||
//================================================================================
|
||||
|
||||
@ -2682,18 +2682,35 @@ double SMESH_MesherHelper::GetAngle( const TopoDS_Edge & theE1,
|
||||
if ( !TopExp::CommonVertex( theE1, theE2, vCommon ))
|
||||
return angle;
|
||||
double f,l;
|
||||
Handle(Geom2d_Curve) c2d1 = BRep_Tool::CurveOnSurface( theE1, theFace, f,l );
|
||||
Handle(Geom_Curve) c1 = BRep_Tool::Curve( theE1, f,l );
|
||||
Handle(Geom_Curve) c2 = BRep_Tool::Curve( theE2, f,l );
|
||||
Handle(Geom2d_Curve) c2d1 = BRep_Tool::CurveOnSurface( theE1, theFace, f,l );
|
||||
Handle(Geom_Surface) surf = BRep_Tool::Surface( theFace );
|
||||
double p1 = BRep_Tool::Parameter( vCommon, theE1 );
|
||||
double p2 = BRep_Tool::Parameter( vCommon, theE2 );
|
||||
if ( c1.IsNull() || c2.IsNull() )
|
||||
return angle;
|
||||
gp_Pnt2d uv = c2d1->Value( p1 );
|
||||
gp_XY uv = c2d1->Value( p1 ).XY();
|
||||
gp_Vec du, dv; gp_Pnt p;
|
||||
surf->D1( uv.X(), uv.Y(), p, du, dv );
|
||||
gp_Vec vec1, vec2, vecRef = du ^ dv;
|
||||
int nbLoops = 0;
|
||||
double p1tmp = p1;
|
||||
while ( vecRef.SquareMagnitude() < std::numeric_limits<double>::min() )
|
||||
{
|
||||
double dp = ( l - f ) / 1000.;
|
||||
p1tmp += dp * (( Abs( p1 - f ) > Abs( p1 - l )) ? +1. : -1.);
|
||||
uv = c2d1->Value( p1tmp ).XY();
|
||||
surf->D1( uv.X(), uv.Y(), p, du, dv );
|
||||
vecRef = du ^ dv;
|
||||
if ( ++nbLoops > 10 )
|
||||
{
|
||||
#ifdef _DEBUG_
|
||||
cout << "SMESH_MesherHelper::GetAngle(): Captured in a sigularity" << endl;
|
||||
#endif
|
||||
return angle;
|
||||
}
|
||||
}
|
||||
if ( theFace.Orientation() == TopAbs_REVERSED )
|
||||
vecRef.Reverse();
|
||||
c1->D1( p1, p, vec1 );
|
||||
|
@ -685,9 +685,9 @@
|
||||
new SalomeApp_CheckFileDlg ( SMESHGUI::desktop(), false, checkBoxes, true, true );
|
||||
fd->setWindowTitle( aTitle );
|
||||
fd->setNameFilters( filters );
|
||||
fd->selectNameFilter(aDefaultFilter);
|
||||
fd->SetChecked(0,toCreateGroups);
|
||||
fd->SetChecked(1,toFindOutDim);
|
||||
fd->selectNameFilter( aDefaultFilter );
|
||||
fd->SetChecked( toCreateGroups, 0 );
|
||||
fd->SetChecked( toFindOutDim, 1 );
|
||||
if ( !anInitialPath.isEmpty() )
|
||||
fd->setDirectory( anInitialPath );
|
||||
fd->selectFile(aMeshName);
|
||||
|
@ -113,7 +113,7 @@ namespace
|
||||
}
|
||||
namespace SMESH
|
||||
{
|
||||
class TElementSimulation {
|
||||
class TElementSimulationQuad {
|
||||
SalomeApp_Application* myApplication;
|
||||
SUIT_ViewWindow* myViewWindow;
|
||||
SVTK_ViewWindow* myVTKViewWindow;
|
||||
@ -130,7 +130,7 @@ namespace SMESH
|
||||
SMESH_FaceOrientationFilter* myFaceOrientationFilter;
|
||||
|
||||
public:
|
||||
TElementSimulation (SalomeApp_Application* theApplication)
|
||||
TElementSimulationQuad (SalomeApp_Application* theApplication)
|
||||
{
|
||||
myApplication = theApplication;
|
||||
SUIT_ViewManager* mgr = theApplication->activeViewManager();
|
||||
@ -230,7 +230,7 @@ namespace SMESH
|
||||
}
|
||||
|
||||
|
||||
~TElementSimulation()
|
||||
~TElementSimulationQuad()
|
||||
{
|
||||
if (FindVtkViewWindow(myApplication->activeViewManager(), myViewWindow)) {
|
||||
myVTKViewWindow->RemoveActor(myPreviewActor);
|
||||
@ -344,7 +344,7 @@ SMESHGUI_AddQuadraticElementDlg::SMESHGUI_AddQuadraticElementDlg( SMESHGUI* theM
|
||||
SalomeApp_Application* anApp = dynamic_cast<SalomeApp_Application*>
|
||||
(SUIT_Session::session()->activeApplication());
|
||||
|
||||
mySimulation = new SMESH::TElementSimulation (anApp);
|
||||
mySimulation = new SMESH::TElementSimulationQuad (anApp);
|
||||
mySelector = (SMESH::GetViewWindow( mySMESHGUI ))->GetSelector();
|
||||
|
||||
QString anElementName;
|
||||
@ -1039,7 +1039,7 @@ void SMESHGUI_AddQuadraticElementDlg::displaySimulation()
|
||||
{
|
||||
if ( IsValid() )
|
||||
{
|
||||
SMESH::TElementSimulation::TVTKIds anIds;
|
||||
SMESH::TElementSimulationQuad::TVTKIds anIds;
|
||||
|
||||
// Collect ids from the dialog
|
||||
int anID;
|
||||
|
@ -54,7 +54,7 @@ class LightApp_SelectionMgr;
|
||||
|
||||
namespace SMESH
|
||||
{
|
||||
struct TElementSimulation;
|
||||
struct TElementSimulationQuad;
|
||||
}
|
||||
|
||||
//=================================================================================
|
||||
@ -92,7 +92,7 @@ private:
|
||||
|
||||
SMESH::SMESH_Mesh_var myMesh;
|
||||
SMESH_Actor* myActor;
|
||||
SMESH::TElementSimulation* mySimulation;
|
||||
SMESH::TElementSimulationQuad* mySimulation;
|
||||
QString myEntry;
|
||||
GrpList myGroups;
|
||||
|
||||
|
@ -476,7 +476,6 @@ SMESHGUI_ClippingDlg::SMESHGUI_ClippingDlg( SMESHGUI* theModule, SVTK_ViewWindow
|
||||
|
||||
SliderDistance = new QSlider( Qt::Horizontal, GroupParameters );
|
||||
SliderDistance->setObjectName( "SliderDistance" );
|
||||
SliderDistance->setFocusPolicy( Qt::NoFocus );
|
||||
SliderDistance->setMinimumSize( 300, 0 );
|
||||
SliderDistance->setMinimum( 0 );
|
||||
SliderDistance->setMaximum( 100 );
|
||||
@ -498,7 +497,6 @@ SMESHGUI_ClippingDlg::SMESHGUI_ClippingDlg( SMESHGUI* theModule, SVTK_ViewWindow
|
||||
|
||||
SliderRotation1 = new QSlider( Qt::Horizontal, GroupParameters );
|
||||
SliderRotation1->setObjectName( "SliderRotation1" );
|
||||
SliderRotation1->setFocusPolicy( Qt::NoFocus );
|
||||
SliderRotation1->setMinimumSize( 300, 0 );
|
||||
SliderRotation1->setMinimum( -180 );
|
||||
SliderRotation1->setMaximum( 180 );
|
||||
@ -521,7 +519,6 @@ SMESHGUI_ClippingDlg::SMESHGUI_ClippingDlg( SMESHGUI* theModule, SVTK_ViewWindow
|
||||
|
||||
SliderRotation2 = new QSlider( Qt::Horizontal, GroupParameters );
|
||||
SliderRotation2->setObjectName( "SliderRotation2" );
|
||||
SliderRotation2->setFocusPolicy( Qt::NoFocus );
|
||||
SliderRotation2->setMinimumSize( 300, 0 );
|
||||
SliderRotation2->setMinimum( -180 );
|
||||
SliderRotation2->setMaximum( 180 );
|
||||
|
@ -198,6 +198,7 @@ namespace SMESH
|
||||
void Show( int subShapeID, GEOM::GEOM_Object_var aMainShape, bool only = false)
|
||||
{
|
||||
SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( SMESHGUI::GetSMESHGUI() );
|
||||
SUIT_ResourceMgr* resMgr = SMESH::GetResourceMgr( SMESHGUI::GetSMESHGUI() );
|
||||
std::string mainEntry;
|
||||
if ( !aMainShape->_is_nil() )
|
||||
mainEntry = aMainShape->GetStudyEntry();
|
||||
@ -226,8 +227,13 @@ namespace SMESH
|
||||
TopAbs_ShapeEnum type( aShape.ShapeType() >= TopAbs_WIRE ? TopAbs_EDGE : TopAbs_FACE );
|
||||
for ( TopExp_Explorer exp( aShape, type ); exp.More(); exp.Next() ) {
|
||||
//checkTriangulation( exp.Current() );
|
||||
if ( GEOM_Actor* anActor = getActor( exp.Current() ))
|
||||
if ( GEOM_Actor* anActor = getActor( exp.Current() ) ) {
|
||||
int UNbIsos = resMgr->integerValue( "Geometry", "iso_number_u", 1);
|
||||
int VNbIsos = resMgr->integerValue( "Geometry", "iso_number_v", 1);
|
||||
int aNbIsos[2] = { UNbIsos ? UNbIsos : 1, VNbIsos ? VNbIsos : 1 };
|
||||
anActor->SetNbIsos( aNbIsos );
|
||||
myShownActors.push_back( anActor );
|
||||
}
|
||||
}
|
||||
if ( type == TopAbs_FACE ) {
|
||||
for ( TopExp_Explorer exp( aShape, TopAbs_EDGE ); exp.More(); exp.Next() ) {
|
||||
|
@ -989,6 +989,7 @@ bool SMESHGUI_MultiEditDlg::onApply()
|
||||
|
||||
updateButtons();
|
||||
}
|
||||
obj._retn(); // else myMesh is deleted by ~obj
|
||||
|
||||
myBusy = false;
|
||||
return aResult;
|
||||
|
@ -93,10 +93,16 @@ bool SMESHGUI_Selection::processOwner( const LightApp_DataOwner* ow )
|
||||
{
|
||||
const LightApp_SVTKDataOwner* owner =
|
||||
dynamic_cast<const LightApp_SVTKDataOwner*> ( ow );
|
||||
if( owner )
|
||||
if( owner ) {
|
||||
myActors.append( dynamic_cast<SMESH_Actor*>( owner->GetActor() ) );
|
||||
else
|
||||
}
|
||||
else if ( ow ) { // SVTK selection disabled
|
||||
QString entry = ow->entry();
|
||||
myActors.append( SMESH::FindActorByEntry( entry.toStdString().c_str() ));
|
||||
}
|
||||
else {
|
||||
myActors.append( 0 );
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -107,31 +113,31 @@ bool SMESHGUI_Selection::processOwner( const LightApp_DataOwner* ow )
|
||||
QVariant SMESHGUI_Selection::parameter( const int ind, const QString& p ) const
|
||||
{
|
||||
QVariant val;
|
||||
if ( p=="client" ) val = QVariant( LightApp_Selection::parameter( p ) );
|
||||
else if ( p=="type" ) val = QVariant( myTypes[ind] );
|
||||
else if ( p=="elemTypes" ) val = QVariant( elemTypes( ind ) );
|
||||
else if ( p=="isAutoColor" ) val = QVariant( isAutoColor( ind ) );
|
||||
else if ( p=="numberOfNodes" ) val = QVariant( numberOfNodes( ind ) );
|
||||
else if ( p=="dim" ) val = QVariant( dim( ind ) );
|
||||
else if ( p=="labeledTypes" ) val = QVariant( labeledTypes( ind ) );
|
||||
else if ( p=="shrinkMode" ) val = QVariant( shrinkMode( ind ) );
|
||||
else if ( p=="entityMode" ) val = QVariant( entityMode( ind ) );
|
||||
else if ( p=="controlMode" ) val = QVariant( controlMode( ind ) );
|
||||
else if ( p=="isNumFunctor" ) val = QVariant( isNumFunctor( ind ) );
|
||||
else if ( p=="displayMode" ) val = QVariant( displayMode( ind ) );
|
||||
else if ( p=="isComputable" ) val = QVariant( isComputable( ind ) );
|
||||
else if ( p=="isPreComputable" ) val = QVariant( isPreComputable( ind ) );
|
||||
else if ( p=="hasReference" ) val = QVariant( hasReference( ind ) );
|
||||
else if ( p=="isImported" ) val = QVariant( isImported( ind ) );
|
||||
if ( p=="client" ) val = QVariant( LightApp_Selection::parameter( p ) );
|
||||
else if ( p=="type" ) val = QVariant( myTypes[ind] );
|
||||
else if ( p=="elemTypes" ) val = QVariant( elemTypes( ind ) );
|
||||
else if ( p=="isAutoColor" ) val = QVariant( isAutoColor( ind ) );
|
||||
else if ( p=="numberOfNodes" ) val = QVariant( numberOfNodes( ind ) );
|
||||
else if ( p=="dim" ) val = QVariant( dim( ind ) );
|
||||
else if ( p=="labeledTypes" ) val = QVariant( labeledTypes( ind ) );
|
||||
else if ( p=="shrinkMode" ) val = QVariant( shrinkMode( ind ) );
|
||||
else if ( p=="entityMode" ) val = QVariant( entityMode( ind ) );
|
||||
else if ( p=="controlMode" ) val = QVariant( controlMode( ind ) );
|
||||
else if ( p=="isNumFunctor" ) val = QVariant( isNumFunctor( ind ) );
|
||||
else if ( p=="displayMode" ) val = QVariant( displayMode( ind ) );
|
||||
else if ( p=="isComputable" ) val = QVariant( isComputable( ind ) );
|
||||
else if ( p=="isPreComputable" ) val = QVariant( isPreComputable( ind ) );
|
||||
else if ( p=="hasReference" ) val = QVariant( hasReference( ind ) );
|
||||
else if ( p=="isImported" ) val = QVariant( isImported( ind ) );
|
||||
else if ( p=="facesOrientationMode" ) val = QVariant( facesOrientationMode( ind ) );
|
||||
else if ( p=="groupType" ) val = QVariant( groupType( ind ) );
|
||||
else if ( p=="quadratic2DMode") val = QVariant(quadratic2DMode(ind));
|
||||
else if ( p=="isDistributionVisible") val = QVariant(isDistributionVisible(ind));
|
||||
else if ( p=="hasChildren") val = QVariant(hasChildren(ind));
|
||||
else if ( p=="nbChildren") val = QVariant(nbChildren(ind));
|
||||
else if ( p=="isContainer") val = QVariant(isContainer(ind));
|
||||
else if ( p=="groupType" ) val = QVariant( groupType( ind ) );
|
||||
else if ( p=="quadratic2DMode") val = QVariant( quadratic2DMode( ind ) );
|
||||
else if ( p=="isDistributionVisible") val = QVariant( isDistributionVisible( ind ) );
|
||||
else if ( p=="hasChildren") val = QVariant( hasChildren( ind ) );
|
||||
else if ( p=="nbChildren") val = QVariant( nbChildren( ind ) );
|
||||
else if ( p=="isContainer") val = QVariant( isContainer( ind ) );
|
||||
|
||||
if( val.isValid() )
|
||||
if ( val.isValid() )
|
||||
return val;
|
||||
else
|
||||
return LightApp_Selection::parameter( ind, p );
|
||||
@ -163,10 +169,10 @@ QList<QVariant> SMESHGUI_Selection::elemTypes( int ind ) const
|
||||
TVisualObjPtr object = actor->GetObject();
|
||||
if ( object ) {
|
||||
if ( object->GetNbEntities( SMDSAbs_0DElement )) types.append( "Elem0d" );
|
||||
if ( object->GetNbEntities( SMDSAbs_Ball )) types.append( "BallElem" );
|
||||
if ( object->GetNbEntities( SMDSAbs_Edge )) types.append( "Edge" );
|
||||
if ( object->GetNbEntities( SMDSAbs_Face )) types.append( "Face" );
|
||||
if ( object->GetNbEntities( SMDSAbs_Volume )) types.append( "Volume" );
|
||||
if ( object->GetNbEntities( SMDSAbs_Ball )) types.append( "BallElem" );
|
||||
if ( object->GetNbEntities( SMDSAbs_Edge )) types.append( "Edge" );
|
||||
if ( object->GetNbEntities( SMDSAbs_Face )) types.append( "Face" );
|
||||
if ( object->GetNbEntities( SMDSAbs_Volume )) types.append( "Volume" );
|
||||
}
|
||||
}
|
||||
return types;
|
||||
@ -183,7 +189,7 @@ QList<QVariant> SMESHGUI_Selection::labeledTypes( int ind ) const
|
||||
SMESH_Actor* actor = getActor( ind );
|
||||
if ( actor ) {
|
||||
if ( actor->GetPointsLabeled()) types.append( "Point" );
|
||||
if ( actor->GetCellsLabeled()) types.append( "Cell" );
|
||||
if ( actor->GetCellsLabeled()) types.append( "Cell" );
|
||||
}
|
||||
return types;
|
||||
}
|
||||
@ -217,8 +223,8 @@ QString SMESHGUI_Selection::quadratic2DMode( int ind ) const
|
||||
SMESH_Actor* actor = getActor( ind );
|
||||
if ( actor ) {
|
||||
switch( actor->GetQuadratic2DRepresentation() ) {
|
||||
case SMESH_Actor::eLines: return "eLines";
|
||||
case SMESH_Actor::eArcs: return "eArcs";
|
||||
case SMESH_Actor::eLines: return "eLines";
|
||||
case SMESH_Actor::eArcs: return "eArcs";
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
@ -244,9 +250,7 @@ QString SMESHGUI_Selection::shrinkMode( int ind ) const
|
||||
{
|
||||
SMESH_Actor* actor = getActor( ind );
|
||||
if ( actor && actor->IsShrunkable() ) {
|
||||
if ( actor->IsShrunk() )
|
||||
return "IsShrunk";
|
||||
return "IsNotShrunk";
|
||||
return actor->IsShrunk() ? "IsShrunk" : "IsNotShrunk";
|
||||
}
|
||||
return "IsNotShrinkable";
|
||||
}
|
||||
@ -266,7 +270,7 @@ QList<QVariant> SMESHGUI_Selection::entityMode( int ind ) const
|
||||
if ( aMode & SMESH_Actor::eFaces ) types.append( "Face" );
|
||||
if ( aMode & SMESH_Actor::eEdges ) types.append( "Edge" );
|
||||
if ( aMode & SMESH_Actor::e0DElements ) types.append( "Elem0d" );
|
||||
if ( aMode & SMESH_Actor::eBallElem ) types.append( "BallElem" );
|
||||
if ( aMode & SMESH_Actor::eBallElem ) types.append( "BallElem" );
|
||||
}
|
||||
return types;
|
||||
}
|
||||
@ -352,9 +356,7 @@ QString SMESHGUI_Selection::facesOrientationMode( int ind ) const
|
||||
{
|
||||
SMESH_Actor* actor = getActor( ind );
|
||||
if ( actor ) {
|
||||
if ( actor->GetFacesOriented() )
|
||||
return "IsOriented";
|
||||
return "IsNotOriented";
|
||||
return actor->GetFacesOriented() ? "IsOriented" : "IsNotOriented";
|
||||
}
|
||||
return "Unknown";
|
||||
}
|
||||
@ -371,9 +373,9 @@ bool SMESHGUI_Selection::isAutoColor( int ind ) const
|
||||
_PTR(SObject) sobj = SMESH::GetActiveStudyDocument()->FindObjectID( entry( ind ).toLatin1().data() );
|
||||
CORBA::Object_var obj = SMESH::SObjectToObject( sobj, SMESH::GetActiveStudyDocument() );
|
||||
|
||||
if ( ! CORBA::is_nil( obj )) {
|
||||
if ( !CORBA::is_nil( obj ) ) {
|
||||
SMESH::SMESH_Mesh_var mesh = SMESH::SMESH_Mesh::_narrow( obj );
|
||||
if ( ! mesh->_is_nil() )
|
||||
if ( !CORBA::is_nil( mesh ) )
|
||||
return mesh->GetAutoColor();
|
||||
}
|
||||
}
|
||||
@ -392,15 +394,15 @@ int SMESHGUI_Selection::numberOfNodes( int ind ) const
|
||||
_PTR(SObject) sobj = SMESH::GetActiveStudyDocument()->FindObjectID( entry( ind ).toLatin1().data() );
|
||||
CORBA::Object_var obj = SMESH::SObjectToObject( sobj, SMESH::GetActiveStudyDocument() );
|
||||
|
||||
if ( ! CORBA::is_nil( obj )) {
|
||||
if ( !CORBA::is_nil( obj ) ) {
|
||||
SMESH::SMESH_Mesh_var mesh = SMESH::SMESH_Mesh::_narrow( obj );
|
||||
if ( ! mesh->_is_nil() )
|
||||
if ( !CORBA::is_nil( mesh ) )
|
||||
return mesh->NbNodes();
|
||||
SMESH::SMESH_subMesh_var aSubMeshObj = SMESH::SMESH_subMesh::_narrow( obj );
|
||||
if ( !aSubMeshObj->_is_nil() )
|
||||
if ( !CORBA::is_nil( aSubMeshObj ) )
|
||||
return aSubMeshObj->GetNumberOfNodes(true);
|
||||
SMESH::SMESH_GroupBase_var aGroupObj = SMESH::SMESH_GroupBase::_narrow( obj );
|
||||
if ( !aGroupObj->_is_nil() )
|
||||
if ( !CORBA::is_nil( aGroupObj ) )
|
||||
return aGroupObj->IsEmpty() ? 0 : 1; // aGroupObj->Size();
|
||||
}
|
||||
}
|
||||
@ -423,20 +425,21 @@ int SMESHGUI_Selection::dim( int ind ) const
|
||||
_PTR(SObject) sobj = SMESH::GetActiveStudyDocument()->FindObjectID( entry( ind ).toLatin1().data() );
|
||||
CORBA::Object_var obj = SMESH::SObjectToObject( sobj, SMESH::GetActiveStudyDocument() );
|
||||
|
||||
if ( ! CORBA::is_nil( obj )) {
|
||||
if ( !CORBA::is_nil( obj ) ) {
|
||||
SMESH::SMESH_IDSource_var idSrc = SMESH::SMESH_IDSource::_narrow( obj );
|
||||
if ( ! idSrc->_is_nil() )
|
||||
if ( !CORBA::is_nil( idSrc ) )
|
||||
{
|
||||
SMESH::array_of_ElementType_var types = idSrc->GetTypes();
|
||||
for ( int i = 0; i < types->length(); ++ i)
|
||||
for ( int i = 0; i < types->length(); ++ i) {
|
||||
switch ( types[i] ) {
|
||||
case SMESH::EDGE : dim = std::max( dim, 1 ); break;
|
||||
case SMESH::FACE : dim = std::max( dim, 2 ); break;
|
||||
case SMESH::VOLUME: dim = std::max( dim, 3 ); break;
|
||||
case SMESH::ELEM0D: dim = std::max( dim, 0 ); break;
|
||||
case SMESH::BALL : dim = std::max( dim, 0 ); break;
|
||||
default:;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -452,36 +455,26 @@ QVariant SMESHGUI_Selection::isComputable( int ind ) const
|
||||
{
|
||||
if ( ind >= 0 && ind < myTypes.count() && myTypes[ind] != "Unknown" )
|
||||
{
|
||||
/* Handle(SALOME_InteractiveObject) io =
|
||||
static_cast<LightApp_DataOwner*>( myDataOwners[ ind ].get() )->IO();
|
||||
if ( !io.IsNull() ) {
|
||||
SMESH::SMESH_Mesh_var mesh = SMESH::GetMeshByIO(io); // m,sm,gr->m
|
||||
if ( !mesh->_is_nil() ) {*/
|
||||
_PTR(SObject) so = SMESH::GetActiveStudyDocument()->FindObjectID( entry( ind ).toLatin1().data() );
|
||||
//FindSObject( mesh );
|
||||
if ( so ) {
|
||||
CORBA::Object_var obj = SMESH::SObjectToObject(so, SMESH::GetActiveStudyDocument());
|
||||
if(!CORBA::is_nil(obj)){
|
||||
SMESH::SMESH_Mesh_var mesh = SMESH::SMESH_Mesh::_narrow( obj );
|
||||
if (!mesh->_is_nil()){
|
||||
if(mesh->HasShapeToMesh()) {
|
||||
GEOM::GEOM_Object_var shape = SMESH::GetShapeOnMeshOrSubMesh( so );
|
||||
return QVariant( !shape->_is_nil() );
|
||||
}
|
||||
else
|
||||
{
|
||||
return QVariant(!mesh->NbFaces()==0);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
GEOM::GEOM_Object_var shape = SMESH::GetShapeOnMeshOrSubMesh( so );
|
||||
return QVariant( !shape->_is_nil() );
|
||||
}
|
||||
}
|
||||
_PTR(SObject) so = SMESH::GetActiveStudyDocument()->FindObjectID( entry( ind ).toLatin1().data() );
|
||||
CORBA::Object_var obj = SMESH::SObjectToObject( so, SMESH::GetActiveStudyDocument() );
|
||||
if( !CORBA::is_nil( obj ) ) {
|
||||
SMESH::SMESH_Mesh_var mesh = SMESH::SMESH_Mesh::_narrow( obj );
|
||||
if ( !CORBA::is_nil( mesh ) ) {
|
||||
if ( mesh->HasShapeToMesh() ) {
|
||||
GEOM::GEOM_Object_var shape = SMESH::GetShapeOnMeshOrSubMesh( so );
|
||||
return QVariant( !shape->_is_nil() );
|
||||
}
|
||||
// }
|
||||
// }
|
||||
else
|
||||
{
|
||||
return QVariant( mesh->NbFaces() !=0 );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
GEOM::GEOM_Object_var shape = SMESH::GetShapeOnMeshOrSubMesh( so );
|
||||
return QVariant( !shape->_is_nil() );
|
||||
}
|
||||
}
|
||||
}
|
||||
return QVariant( false );
|
||||
}
|
||||
@ -522,10 +515,9 @@ QVariant SMESHGUI_Selection::isVisible( int ind ) const
|
||||
{
|
||||
if ( ind >= 0 && ind < myTypes.count() && myTypes[ind] != "Unknown" )
|
||||
{
|
||||
QString ent = entry( ind );
|
||||
SMESH_Actor* actor = SMESH::FindActorByEntry( ent.toLatin1().data() );
|
||||
SMESH_Actor* actor = SMESH::FindActorByEntry( entry( ind ).toLatin1().data() );
|
||||
if ( actor && actor->hasIO() ) {
|
||||
if(SVTK_ViewWindow* aViewWindow = SMESH::GetCurrentVtkView())
|
||||
if ( SVTK_ViewWindow* aViewWindow = SMESH::GetCurrentVtkView() )
|
||||
return QVariant( aViewWindow->isVisible( actor->getIO() ) );
|
||||
}
|
||||
}
|
||||
@ -542,7 +534,8 @@ bool SMESHGUI_Selection::hasChildren( int ind ) const
|
||||
if ( ind >= 0 )
|
||||
{
|
||||
_PTR(SObject) sobj = SMESH::GetActiveStudyDocument()->FindObjectID( entry( ind ).toLatin1().data() );
|
||||
return SMESH::GetActiveStudyDocument()->GetUseCaseBuilder()->HasChildren( sobj );
|
||||
if ( sobj )
|
||||
return SMESH::GetActiveStudyDocument()->GetUseCaseBuilder()->HasChildren( sobj );
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@ -558,9 +551,9 @@ int SMESHGUI_Selection::nbChildren( int ind ) const
|
||||
if ( ind >= 0 )
|
||||
{
|
||||
_PTR(SObject) sobj = SMESH::GetActiveStudyDocument()->FindObjectID( entry( ind ).toLatin1().data() );
|
||||
if ( sobj->GetStudy()->GetUseCaseBuilder()->IsUseCaseNode( sobj ) ) {
|
||||
if ( sobj && sobj->GetStudy()->GetUseCaseBuilder()->IsUseCaseNode( sobj ) ) {
|
||||
_PTR(UseCaseIterator) it = sobj->GetStudy()->GetUseCaseBuilder()->GetUseCaseIterator( sobj );
|
||||
for (it->Init(false); it->More(); it->Next()) nb++;
|
||||
for ( it->Init( false ); it->More(); it->Next() ) nb++;
|
||||
}
|
||||
}
|
||||
return nb;
|
||||
@ -583,72 +576,57 @@ bool SMESHGUI_Selection::isContainer( int ind ) const
|
||||
|
||||
int SMESHGUI_Selection::type( const QString& entry, _PTR(Study) study )
|
||||
{
|
||||
_PTR(SObject) obj (study->FindObjectID(entry.toLatin1().data()));
|
||||
if( !obj )
|
||||
return -1;
|
||||
int res = -1;
|
||||
_PTR(SObject) obj = study->FindObjectID( entry.toLatin1().data() );
|
||||
if ( obj ) {
|
||||
_PTR(SObject) ref;
|
||||
if ( obj->ReferencedObject( ref ) )
|
||||
obj = ref;
|
||||
|
||||
_PTR(SObject) ref;
|
||||
if( obj->ReferencedObject( ref ) )
|
||||
obj = ref;
|
||||
_PTR(SObject) objFather = obj->GetFather();
|
||||
_PTR(SComponent) objComponent = obj->GetFatherComponent();
|
||||
|
||||
_PTR(SObject) objFather = obj->GetFather();
|
||||
_PTR(SComponent) objComponent = obj->GetFatherComponent();
|
||||
if ( objComponent->ComponentDataType() == "SMESH" ) {
|
||||
if ( objComponent->GetIOR() == obj->GetIOR() ) {
|
||||
res = SMESH::COMPONENT;
|
||||
}
|
||||
else {
|
||||
int aLevel = obj->Depth() - objComponent->Depth(),
|
||||
aFTag = objFather->Tag(),
|
||||
anOTag = obj->Tag();
|
||||
|
||||
if( objComponent->ComponentDataType()!="SMESH" )
|
||||
return -1;
|
||||
|
||||
if( objComponent->GetIOR()==obj->GetIOR() )
|
||||
return SMESH::COMPONENT;
|
||||
|
||||
int aLevel = obj->Depth() - objComponent->Depth(),
|
||||
aFTag = objFather->Tag(),
|
||||
anOTag = obj->Tag(),
|
||||
res = -1;
|
||||
|
||||
switch (aLevel)
|
||||
{
|
||||
case 1:
|
||||
if (anOTag >= SMESH::Tag_FirstMeshRoot)
|
||||
res = SMESH::MESH;
|
||||
break;
|
||||
case 2:
|
||||
switch (aFTag)
|
||||
{
|
||||
case SMESH::Tag_HypothesisRoot:
|
||||
res = SMESH::HYPOTHESIS;
|
||||
break;
|
||||
case SMESH::Tag_AlgorithmsRoot:
|
||||
res = SMESH::ALGORITHM;
|
||||
break;
|
||||
switch ( aLevel )
|
||||
{
|
||||
case 1:
|
||||
if ( anOTag >= SMESH::Tag_FirstMeshRoot )
|
||||
res = SMESH::MESH;
|
||||
break;
|
||||
case 2:
|
||||
switch ( aFTag )
|
||||
{
|
||||
case SMESH::Tag_HypothesisRoot: res = SMESH::HYPOTHESIS; break;
|
||||
case SMESH::Tag_AlgorithmsRoot: res = SMESH::ALGORITHM; break;
|
||||
default: break;
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
switch ( aFTag )
|
||||
{
|
||||
case SMESH::Tag_SubMeshOnVertex: res = SMESH::SUBMESH_VERTEX; break;
|
||||
case SMESH::Tag_SubMeshOnEdge: res = SMESH::SUBMESH_EDGE; break;
|
||||
case SMESH::Tag_SubMeshOnFace: res = SMESH::SUBMESH_FACE; break;
|
||||
case SMESH::Tag_SubMeshOnSolid: res = SMESH::SUBMESH_SOLID; break;
|
||||
case SMESH::Tag_SubMeshOnCompound: res = SMESH::SUBMESH_COMPOUND; break;
|
||||
default:
|
||||
if ( aFTag >= SMESH::Tag_FirstGroup) res = SMESH::GROUP;
|
||||
else res = SMESH::SUBMESH;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
switch (aFTag)
|
||||
{
|
||||
case SMESH::Tag_SubMeshOnVertex:
|
||||
res = SMESH::SUBMESH_VERTEX;
|
||||
break;
|
||||
case SMESH::Tag_SubMeshOnEdge:
|
||||
res = SMESH::SUBMESH_EDGE;
|
||||
break;
|
||||
case SMESH::Tag_SubMeshOnFace:
|
||||
res = SMESH::SUBMESH_FACE;
|
||||
break;
|
||||
case SMESH::Tag_SubMeshOnSolid:
|
||||
res = SMESH::SUBMESH_SOLID;
|
||||
break;
|
||||
case SMESH::Tag_SubMeshOnCompound:
|
||||
res = SMESH::SUBMESH_COMPOUND;
|
||||
break;
|
||||
default:
|
||||
if (aFTag >= SMESH::Tag_FirstGroup)
|
||||
res = SMESH::GROUP;
|
||||
else
|
||||
res = SMESH::SUBMESH;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
@ -659,45 +637,46 @@ int SMESHGUI_Selection::type( const QString& entry, _PTR(Study) study )
|
||||
|
||||
QString SMESHGUI_Selection::typeName( const int t )
|
||||
{
|
||||
QString res = "Unknown";
|
||||
switch( t )
|
||||
{
|
||||
case SMESH::HYPOTHESIS:
|
||||
return "Hypothesis";
|
||||
res = "Hypothesis"; break;
|
||||
case SMESH::ALGORITHM:
|
||||
return "Algorithm";
|
||||
res = "Algorithm"; break;
|
||||
case SMESH::MESH:
|
||||
return "Mesh";
|
||||
res = "Mesh"; break;
|
||||
case SMESH::SUBMESH:
|
||||
return "SubMesh";
|
||||
res = "SubMesh"; break;
|
||||
case SMESH::MESHorSUBMESH:
|
||||
return "Mesh or submesh";
|
||||
res = "Mesh or submesh"; break;
|
||||
case SMESH::SUBMESH_VERTEX:
|
||||
return "Mesh vertex";
|
||||
res = "Mesh vertex"; break;
|
||||
case SMESH::SUBMESH_EDGE:
|
||||
return "Mesh edge";
|
||||
res = "Mesh edge"; break;
|
||||
case SMESH::SUBMESH_FACE:
|
||||
return "Mesh face";
|
||||
res = "Mesh face"; break;
|
||||
case SMESH::SUBMESH_SOLID:
|
||||
return "Mesh solid";
|
||||
res = "Mesh solid"; break;
|
||||
case SMESH::SUBMESH_COMPOUND:
|
||||
return "Mesh compound";
|
||||
res = "Mesh compound"; break;
|
||||
case SMESH::GROUP:
|
||||
return "Group";
|
||||
res = "Group"; break;
|
||||
case SMESH::COMPONENT:
|
||||
return "Component";
|
||||
res = "Component"; break;
|
||||
default:
|
||||
return "Unknown";
|
||||
break;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
bool SMESHGUI_Selection::isImported( const int ind ) const
|
||||
{
|
||||
QString e = entry( ind );
|
||||
_PTR(SObject) SO = SMESH::GetActiveStudyDocument()->FindObjectID( e.toLatin1().constData() );
|
||||
bool res = false;
|
||||
if( SO )
|
||||
_PTR(SObject) sobj = SMESH::GetActiveStudyDocument()->FindObjectID( entry( ind ).toLatin1().constData() );
|
||||
if ( sobj )
|
||||
{
|
||||
SMESH::SMESH_Mesh_var aMesh = SMESH::SMESH_Mesh::_narrow( SMESH::SObjectToObject( SO ) );
|
||||
SMESH::SMESH_Mesh_var aMesh = SMESH::SMESH_Mesh::_narrow( SMESH::SObjectToObject( sobj ) );
|
||||
if( !aMesh->_is_nil() )
|
||||
{
|
||||
SMESH::MedFileInfo_var inf = aMesh->GetMEDFileInfo();
|
||||
@ -714,20 +693,17 @@ bool SMESHGUI_Selection::isImported( const int ind ) const
|
||||
|
||||
QString SMESHGUI_Selection::groupType( int ind ) const
|
||||
{
|
||||
QString e = entry( ind );
|
||||
_PTR(SObject) SO = SMESH::GetActiveStudyDocument()->FindObjectID( e.toLatin1().constData() );
|
||||
if( SO )
|
||||
_PTR(SObject) sobj = SMESH::GetActiveStudyDocument()->FindObjectID( entry( ind ).toLatin1().constData() );
|
||||
if ( sobj )
|
||||
{
|
||||
SMESH::SMESH_Group_var g = SMESH::SObjectToInterface<SMESH::SMESH_Group>( SO );
|
||||
if( !g->_is_nil() )
|
||||
SMESH::SMESH_Group_var g = SMESH::SObjectToInterface<SMESH::SMESH_Group>( sobj );
|
||||
if ( !CORBA::is_nil( g ) )
|
||||
return "Group";
|
||||
|
||||
SMESH::SMESH_GroupOnGeom_var gog = SMESH::SObjectToInterface<SMESH::SMESH_GroupOnGeom>( SO );
|
||||
if( !gog->_is_nil() )
|
||||
SMESH::SMESH_GroupOnGeom_var gog = SMESH::SObjectToInterface<SMESH::SMESH_GroupOnGeom>( sobj );
|
||||
if( !CORBA::is_nil( gog ) )
|
||||
return "GroupOnGeom";
|
||||
|
||||
SMESH::SMESH_GroupOnFilter_var gof = SMESH::SObjectToInterface<SMESH::SMESH_GroupOnFilter>(SO);
|
||||
if ( !gof->_is_nil() )
|
||||
SMESH::SMESH_GroupOnFilter_var gof = SMESH::SObjectToInterface<SMESH::SMESH_GroupOnFilter>( sobj );
|
||||
if ( !CORBA::is_nil( gof ) )
|
||||
return "GroupOnFilter";
|
||||
}
|
||||
return "";
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -3067,8 +3067,8 @@ CORBA::Boolean Filter_i::SetCriteria( const SMESH::Filter::Criteria& theCriteria
|
||||
}
|
||||
|
||||
SetPredicate( aResPredicate );
|
||||
|
||||
aResPredicate->UnRegister();
|
||||
if ( !aResPredicate->_is_nil() )
|
||||
aResPredicate->UnRegister();
|
||||
|
||||
return !aResPredicate->_is_nil();
|
||||
}
|
||||
|
@ -227,22 +227,22 @@ namespace MeshEditor_I {
|
||||
}
|
||||
myMesh = mesh;
|
||||
myMeshPartIOR = meshPartIOR;
|
||||
if ( SMESH_subMesh* myMainSubMesh = mesh->GetSubMeshContaining(1) ) {
|
||||
const TDependsOnMap & subMeshes = myMainSubMesh->DependsOn();
|
||||
TDependsOnMap::const_iterator sm;
|
||||
for (sm = subMeshes.begin(); sm != subMeshes.end(); sm++)
|
||||
sm->second->SetEventListener( this, 0, sm->second );
|
||||
SMESH_subMesh* sm = mesh->GetSubMesh( mesh->GetShapeToMesh() );
|
||||
SMESH_subMeshIteratorPtr smIt = sm->getDependsOnIterator( /*includeSelf=*/true );
|
||||
while ( smIt->more() )
|
||||
{
|
||||
sm = smIt->next();
|
||||
sm->SetEventListener( this, 0, sm );
|
||||
}
|
||||
}
|
||||
}
|
||||
//!< delete self from all submeshes
|
||||
void Unset(SMESH_Mesh* mesh)
|
||||
{
|
||||
if ( SMESH_subMesh* myMainSubMesh = mesh->GetSubMeshContaining(1) ) {
|
||||
const TDependsOnMap & subMeshes = myMainSubMesh->DependsOn();
|
||||
TDependsOnMap::const_iterator sm;
|
||||
for (sm = subMeshes.begin(); sm != subMeshes.end(); sm++)
|
||||
sm->second->DeleteEventListener( this );
|
||||
if ( SMESH_subMesh* sm = mesh->GetSubMeshContaining(1) ) {
|
||||
SMESH_subMeshIteratorPtr smIt = sm->getDependsOnIterator( /*includeSelf=*/true );
|
||||
while ( smIt->more() )
|
||||
smIt->next()->DeleteEventListener( this );
|
||||
}
|
||||
myMesh = 0;
|
||||
}
|
||||
@ -1747,7 +1747,7 @@ CORBA::Boolean SMESH_MeshEditor_i::TriToQuad (const SMESH::long_array & IDsOfE
|
||||
if ( !myIsPreviewMode ) {
|
||||
// Update Python script
|
||||
TPythonDump() << "isDone = " << this << ".TriToQuad( "
|
||||
<< IDsOfElements << ", " << aNumericalFunctor << ", " << TVar( MaxAngle ) << " )";
|
||||
<< IDsOfElements << ", " << aNumericalFunctor << ", " << TVar( MaxAngle ) << " )";
|
||||
}
|
||||
|
||||
bool stat = getEditor().TriToQuad( *workElements, aCrit, MaxAngle );
|
||||
@ -1785,7 +1785,7 @@ CORBA::Boolean SMESH_MeshEditor_i::TriToQuadObject (SMESH::SMESH_IDSource_ptr
|
||||
|
||||
// Update Python script
|
||||
aTPythonDump << "isDone = " << this << ".TriToQuadObject("
|
||||
<< theObject << ", " << aNumericalFunctor << ", " << TVar( MaxAngle ) << " )";
|
||||
<< theObject << ", " << aNumericalFunctor << ", " << TVar( MaxAngle ) << " )";
|
||||
}
|
||||
|
||||
return isDone;
|
||||
|
@ -32,9 +32,8 @@
|
||||
import salome
|
||||
from salome import *
|
||||
|
||||
import GEOM
|
||||
from salome.geom import geomBuilder
|
||||
geompy = geomBuilder.New(salome.myStudy)
|
||||
import geompy
|
||||
|
||||
import SMESH, SALOMEDS
|
||||
from salome.smesh import smeshBuilder
|
||||
|
||||
@ -60,7 +59,8 @@ for pluginName in os.environ[ "SMESH_MeshersList" ].split( ":" ):
|
||||
try:
|
||||
exec( "from salome.%s.%s import *" % (pluginName, pluginBuilderName))
|
||||
except Exception, e:
|
||||
print "Exception while loading %s: %s" % ( pluginBuilderName, e )
|
||||
from salome_utils import verbose
|
||||
if verbose(): print "Exception while loading %s: %s" % ( pluginBuilderName, e )
|
||||
continue
|
||||
exec( "from salome.%s import %s" % (pluginName, pluginBuilderName))
|
||||
plugin = eval( pluginBuilderName )
|
||||
|
@ -4655,7 +4655,8 @@ for pluginName in os.environ[ "SMESH_MeshersList" ].split( ":" ):
|
||||
try:
|
||||
exec( "from salome.%s.%s import *" % (pluginName, pluginBuilderName))
|
||||
except Exception, e:
|
||||
print "Exception while loading %s: %s" % ( pluginBuilderName, e )
|
||||
from salome_utils import verbose
|
||||
if verbose(): print "Exception while loading %s: %s" % ( pluginBuilderName, e )
|
||||
continue
|
||||
exec( "from salome.%s import %s" % (pluginName, pluginBuilderName))
|
||||
plugin = eval( pluginBuilderName )
|
||||
|
@ -95,6 +95,10 @@ SET(_swig_SCRIPTS
|
||||
|
||||
SWIG_ADD_MODULE(libSMESH_Swig python ${SMESH_Swig_SOURCES})
|
||||
SWIG_LINK_LIBRARIES(libSMESH_Swig ${_link_LIBRARIES})
|
||||
IF(WIN32)
|
||||
SET_TARGET_PROPERTIES(_libSMESH_Swig PROPERTIES DEBUG_OUTPUT_NAME _libSMESH_Swig_d)
|
||||
ENDIF(WIN32)
|
||||
|
||||
INSTALL(TARGETS _libSMESH_Swig DESTINATION ${SALOME_INSTALL_LIBS})
|
||||
|
||||
INSTALL(FILES ${SMESH_Swig_HEADERS} DESTINATION ${SALOME_INSTALL_HEADERS})
|
||||
|
@ -42,6 +42,7 @@
|
||||
#include <GeomAdaptor_Curve.hxx>
|
||||
#include <Geom_Curve.hxx>
|
||||
#include <Poly_Array1OfTriangle.hxx>
|
||||
#include <Poly_PolygonOnTriangulation.hxx>
|
||||
#include <Poly_Triangulation.hxx>
|
||||
#include <TColgp_Array1OfPnt.hxx>
|
||||
#include <TopExp.hxx>
|
||||
@ -167,6 +168,37 @@ namespace // internal utils
|
||||
SegSizeTree* mySizeTree;
|
||||
};
|
||||
|
||||
//================================================================================
|
||||
/*!
|
||||
* \brief Segment of Poly_PolygonOnTriangulation
|
||||
*/
|
||||
struct Segment
|
||||
{
|
||||
gp_XYZ myPos, myDir;
|
||||
double myLength;
|
||||
|
||||
void Init( const gp_Pnt& p1, const gp_Pnt& p2 )
|
||||
{
|
||||
myPos = p1.XYZ();
|
||||
myDir = p2.XYZ() - p1.XYZ();
|
||||
myLength = myDir.Modulus();
|
||||
if ( myLength > std::numeric_limits<double>::min() )
|
||||
myDir /= myLength;
|
||||
}
|
||||
bool Distance( const gp_Pnt& P, double& dist ) const // returns length of normal projection
|
||||
{
|
||||
gp_XYZ p = P.XYZ();
|
||||
p.Subtract( myPos );
|
||||
double proj = p.Dot( myDir );
|
||||
if ( 0 < proj && proj < myLength )
|
||||
{
|
||||
p.Cross( myDir );
|
||||
dist = p.Modulus();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
//================================================================================
|
||||
/*!
|
||||
* \brief Data of triangle used to locate it in an octree and to find distance
|
||||
@ -174,14 +206,17 @@ namespace // internal utils
|
||||
*/
|
||||
struct Triangle
|
||||
{
|
||||
Bnd_B3d myBox;
|
||||
bool myIsChecked; // to mark treated trias instead of using std::set
|
||||
Bnd_B3d myBox;
|
||||
bool myIsChecked; // to mark treated trias instead of using std::set
|
||||
bool myHasNodeOnVertex;
|
||||
Segment* mySegments[3];
|
||||
// data for DistToProjection()
|
||||
gp_XYZ myN0, myEdge1, myEdge2, myNorm, myPVec;
|
||||
double myInvDet, myMaxSize2;
|
||||
gp_XYZ myN0, myEdge1, myEdge2, myNorm, myPVec;
|
||||
double myInvDet, myMaxSize2;
|
||||
|
||||
void Init( const gp_Pnt& n1, const gp_Pnt& n2, const gp_Pnt& n3 );
|
||||
bool DistToProjection( const gp_Pnt& p, double& dist ) const;
|
||||
bool DistToSegment ( const gp_Pnt& p, double& dist ) const;
|
||||
};
|
||||
//================================================================================
|
||||
/*!
|
||||
@ -197,6 +232,7 @@ namespace // internal utils
|
||||
struct TriaTreeData : public ElemTreeData
|
||||
{
|
||||
vector< Triangle > myTrias;
|
||||
vector< Segment > mySegments;
|
||||
double myFaceTol;
|
||||
double myTriasDeflection;
|
||||
BBox myBBox;
|
||||
@ -263,6 +299,28 @@ namespace // internal utils
|
||||
return bb;
|
||||
}
|
||||
};
|
||||
//================================================================================
|
||||
/*!
|
||||
* \brief Link of two nodes
|
||||
*/
|
||||
struct NLink : public std::pair< int, int >
|
||||
{
|
||||
NLink( int n1, int n2 )
|
||||
{
|
||||
if ( n1 < n2 )
|
||||
{
|
||||
first = n1;
|
||||
second = n2;
|
||||
}
|
||||
else
|
||||
{
|
||||
first = n2;
|
||||
second = n1;
|
||||
}
|
||||
}
|
||||
int N1() const { return first; }
|
||||
int N2() const { return second; }
|
||||
};
|
||||
|
||||
//================================================================================
|
||||
/*!
|
||||
@ -295,33 +353,82 @@ namespace // internal utils
|
||||
}
|
||||
for ( int i = myNodes->Lower(); i <= myNodes->Upper(); ++i )
|
||||
myBBox.Add( myNodes->Value(i).XYZ() );
|
||||
|
||||
}
|
||||
}
|
||||
//================================================================================
|
||||
/*!
|
||||
* \brief Prepare data for search of trinagles in GetMinDistInSphere()
|
||||
*/
|
||||
//================================================================================
|
||||
|
||||
void TriaTreeData::PrepareToTriaSearch()
|
||||
{
|
||||
if ( !myTrias.empty() ) return; // already done
|
||||
if ( !myPolyTrias ) return;
|
||||
|
||||
// get all boundary links and nodes on VERTEXes
|
||||
map< NLink, Segment* > linkToSegMap;
|
||||
map< NLink, Segment* >::iterator l2s;
|
||||
set< int > vertexNodes;
|
||||
TopLoc_Location loc;
|
||||
Handle(Poly_Triangulation) tr = BRep_Tool::Triangulation( mySurface.Face(), loc );
|
||||
if ( !tr.IsNull() )
|
||||
{
|
||||
TopTools_IndexedMapOfShape edgeMap;
|
||||
TopExp::MapShapes( mySurface.Face(), TopAbs_EDGE, edgeMap );
|
||||
for ( int iE = 1; iE <= edgeMap.Extent(); ++iE )
|
||||
{
|
||||
const TopoDS_Edge& edge = TopoDS::Edge( edgeMap( iE ));
|
||||
Handle(Poly_PolygonOnTriangulation) polygon =
|
||||
BRep_Tool::PolygonOnTriangulation( edge, tr, loc );
|
||||
if ( polygon.IsNull() )
|
||||
continue;
|
||||
const TColStd_Array1OfInteger& nodes = polygon->Nodes();
|
||||
for ( int i = nodes.Lower(); i < nodes.Upper(); ++i )
|
||||
linkToSegMap.insert( make_pair( NLink( nodes(i), nodes(i+1)), (Segment*)0 ));
|
||||
vertexNodes.insert( nodes( nodes.Lower()));
|
||||
vertexNodes.insert( nodes( nodes.Upper()));
|
||||
}
|
||||
// fill mySegments by boundary links
|
||||
mySegments.resize( linkToSegMap.size() );
|
||||
int iS = 0;
|
||||
for ( l2s = linkToSegMap.begin(); l2s != linkToSegMap.end(); ++l2s, ++iS )
|
||||
{
|
||||
const NLink& link = (*l2s).first;
|
||||
(*l2s).second = & mySegments[ iS ];
|
||||
mySegments[ iS ].Init( myNodes->Value( link.N1() ),
|
||||
myNodes->Value( link.N2() ));
|
||||
}
|
||||
}
|
||||
|
||||
// initialize myTrias
|
||||
myTrias.resize( myPolyTrias->Length() );
|
||||
Standard_Integer n1,n2,n3;
|
||||
for ( int i = 1; i <= myPolyTrias->Upper(); ++i )
|
||||
{
|
||||
Triangle & t = myTrias[ i-1 ];
|
||||
myPolyTrias->Value( i ).Get( n1,n2,n3 );
|
||||
myTrias[ i-1 ].Init( myNodes->Value( n1 ),
|
||||
myNodes->Value( n2 ),
|
||||
myNodes->Value( n3 ));
|
||||
}
|
||||
myTree->FillIn();
|
||||
t.Init( myNodes->Value( n1 ),
|
||||
myNodes->Value( n2 ),
|
||||
myNodes->Value( n3 ));
|
||||
int nbSeg = 0;
|
||||
if (( l2s = linkToSegMap.find( NLink( n1, n2 ))) != linkToSegMap.end())
|
||||
t.mySegments[ nbSeg++ ] = l2s->second;
|
||||
if (( l2s = linkToSegMap.find( NLink( n2, n3 ))) != linkToSegMap.end())
|
||||
t.mySegments[ nbSeg++ ] = l2s->second;
|
||||
if (( l2s = linkToSegMap.find( NLink( n3, n1 ))) != linkToSegMap.end())
|
||||
t.mySegments[ nbSeg++ ] = l2s->second;
|
||||
while ( nbSeg < 3 )
|
||||
t.mySegments[ nbSeg++ ] = NULL;
|
||||
|
||||
// TODO: mark triangles with nodes on VERTEXes to
|
||||
// less frequently compare with avoidPnt in GetMinDistInSphere()
|
||||
//
|
||||
// Handle(Poly_PolygonOnTriangulation) polygon =
|
||||
// BRep_Tool::PolygonOnTriangulation( edge, tr, loc );
|
||||
// if ( polygon.IsNull() || !pologon.HasParameters() )
|
||||
// continue;
|
||||
// Handle(TColStd_Array1OfInteger) nodeIDs = polygon->Nodes();
|
||||
t.myIsChecked = false;
|
||||
t.myHasNodeOnVertex = ( vertexNodes.count( n1 ) ||
|
||||
vertexNodes.count( n2 ) ||
|
||||
vertexNodes.count( n3 ));
|
||||
}
|
||||
|
||||
// fill the tree of triangles
|
||||
myTree->FillIn();
|
||||
}
|
||||
|
||||
//================================================================================
|
||||
@ -347,10 +454,8 @@ namespace // internal utils
|
||||
isConstSize = false;
|
||||
}
|
||||
|
||||
typedef std::pair<int,int> TLink;
|
||||
TLink link;
|
||||
map< TLink, double > lenOfDoneLink;
|
||||
map< TLink, double >::iterator link2len;
|
||||
map< NLink, double > lenOfDoneLink;
|
||||
map< NLink, double >::iterator link2len;
|
||||
|
||||
Standard_Integer n[4];
|
||||
gp_Pnt p[4];
|
||||
@ -373,11 +478,7 @@ namespace // internal utils
|
||||
maxLinkLen = 0;
|
||||
for ( int j = 0; j < 3; ++j )
|
||||
{
|
||||
if ( n[j] < n[j+1] )
|
||||
link = TLink( n[j], n[j+1] );
|
||||
else
|
||||
link = TLink( n[j+1], n[j] );
|
||||
link2len = lenOfDoneLink.insert( make_pair( link, -1. )).first;
|
||||
link2len = lenOfDoneLink.insert( make_pair( NLink( n[j], n[j+1] ), -1. )).first;
|
||||
isDone[j] = !((*link2len).second < 0 );
|
||||
a[j] = isDone[j] ? (*link2len).second : (*link2len).second = p[j].Distance( p[j+1] );
|
||||
if ( isDone[j] )
|
||||
@ -430,10 +531,13 @@ namespace // internal utils
|
||||
{
|
||||
double minDist2 = 1e100;
|
||||
const double tol2 = myFaceTol * myFaceTol;
|
||||
const double dMin2 = myTriasDeflection * myTriasDeflection;
|
||||
|
||||
TriaTreeData* me = const_cast<TriaTreeData*>( this );
|
||||
me->myFoundTriaIDs.clear();
|
||||
myTree->GetElementsInSphere( p.XYZ(), radius, me->myFoundTriaIDs );
|
||||
if ( myFoundTriaIDs.empty() )
|
||||
return minDist2;
|
||||
|
||||
Standard_Integer n[ 3 ];
|
||||
for ( size_t i = 0; i < myFoundTriaIDs.size(); ++i )
|
||||
@ -444,19 +548,35 @@ namespace // internal utils
|
||||
t.myIsChecked = true;
|
||||
|
||||
double d, minD2 = minDist2;
|
||||
bool avoidTria = false;
|
||||
myPolyTrias->Value( myFoundTriaIDs[i]+1 ).Get( n[0],n[1],n[2] );
|
||||
for ( int i = 0; i < 3; ++i )
|
||||
if ( avoidPnt && t.myHasNodeOnVertex )
|
||||
{
|
||||
const gp_Pnt& pn = myNodes->Value(n[i]);
|
||||
if ( avoidTria = ( avoidPnt && pn.SquareDistance(*avoidPnt) <= tol2 ))
|
||||
break;
|
||||
if ( !projectedOnly )
|
||||
minD2 = Min( minD2, pn.SquareDistance( p ));
|
||||
bool avoidTria = false;
|
||||
for ( int i = 0; i < 3; ++i )
|
||||
{
|
||||
const gp_Pnt& pn = myNodes->Value(n[i]);
|
||||
if ( avoidTria = ( pn.SquareDistance( *avoidPnt ) <= tol2 ))
|
||||
break;
|
||||
if ( !projectedOnly )
|
||||
minD2 = Min( minD2, pn.SquareDistance( p ));
|
||||
}
|
||||
if ( avoidTria )
|
||||
continue;
|
||||
if (( projectedOnly || minD2 < t.myMaxSize2 ) &&
|
||||
( t.DistToProjection( p, d ) || t.DistToSegment( p, d )))
|
||||
minD2 = Min( minD2, d*d );
|
||||
minDist2 = Min( minDist2, minD2 );
|
||||
}
|
||||
if ( !avoidTria )
|
||||
else if ( projectedOnly )
|
||||
{
|
||||
if ( minD2 < t.myMaxSize2 && t.DistToProjection( p, d ))
|
||||
if ( t.DistToProjection( p, d ) && d*d > dMin2 )
|
||||
minDist2 = Min( minDist2, d*d );
|
||||
}
|
||||
else
|
||||
{
|
||||
for ( int i = 0; i < 3; ++i )
|
||||
minD2 = Min( minD2, p.SquareDistance( myNodes->Value(n[i]) ));
|
||||
if ( minD2 < t.myMaxSize2 && ( t.DistToProjection( p, d ) || t.DistToSegment( p, d )))
|
||||
minD2 = Min( minD2, d*d );
|
||||
minDist2 = Min( minDist2, minD2 );
|
||||
}
|
||||
@ -526,6 +646,31 @@ namespace // internal utils
|
||||
return true;
|
||||
}
|
||||
|
||||
//================================================================================
|
||||
/*!
|
||||
* \brief Compute distance from a point to either of mySegments. Return false if the point
|
||||
* is not projected on a segment
|
||||
*/
|
||||
//================================================================================
|
||||
|
||||
bool Triangle::DistToSegment( const gp_Pnt& p, double& dist ) const
|
||||
{
|
||||
dist = 1e100;
|
||||
bool res = false;
|
||||
double d;
|
||||
for ( int i = 0; i < 3; ++i )
|
||||
{
|
||||
if ( !mySegments[ i ])
|
||||
break;
|
||||
if ( mySegments[ i ]->Distance( p, d ))
|
||||
{
|
||||
res = true;
|
||||
dist = Min( dist, d );
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
//================================================================================
|
||||
/*!
|
||||
* \brief Consturct ElementBndBoxTree of Poly_Triangulation of a FACE
|
||||
@ -993,7 +1138,7 @@ void AdaptiveAlgo::SetHypothesis( const StdMeshers_Adaptive1D* hyp )
|
||||
bool AdaptiveAlgo::Compute(SMESH_Mesh & theMesh,
|
||||
const TopoDS_Shape & theShape)
|
||||
{
|
||||
//*theProgress = 0.01;
|
||||
// *theProgress = 0.01;
|
||||
|
||||
if ( myHyp->GetMinSize() > myHyp->GetMaxSize() )
|
||||
return error( "Bad parameters: min size > max size" );
|
||||
@ -1012,7 +1157,7 @@ bool AdaptiveAlgo::Compute(SMESH_Mesh & theMesh,
|
||||
IncrementalMesh im( theMesh.GetShapeToMesh(), myHyp->GetDeflection(), /*Relatif=*/false);
|
||||
box = im.GetBox();
|
||||
}
|
||||
//*theProgress = 0.3;
|
||||
// *theProgress = 0.3;
|
||||
|
||||
// holder of segment size at each point
|
||||
SegSizeTree sizeTree( box, grading, myHyp->GetMinSize(), myHyp->GetMaxSize() );
|
||||
@ -1160,19 +1305,24 @@ bool AdaptiveAlgo::Compute(SMESH_Mesh & theMesh,
|
||||
double distToFace =
|
||||
triaSearcher->GetMinDistInSphere( pIt1->myP, pIt1->mySegSize, isAdjFace, avoidPnt );
|
||||
double allowedSize = Max( minSize, distToFace*( 1. + grading ));
|
||||
if ( 1.1 * allowedSize < pIt1->mySegSize )
|
||||
if ( allowedSize < pIt1->mySegSize )
|
||||
{
|
||||
sizeDecreased = true;
|
||||
sizeTree.SetSize( pIt1->myP, allowedSize );
|
||||
// cout << "E " << theMesh.GetMeshDS()->ShapeToIndex( eData.Edge() )
|
||||
// << "\t SetSize " << allowedSize << " at "
|
||||
// << pIt1->myP.X() <<", "<< pIt1->myP.Y()<<", "<<pIt1->myP.Z() << endl;
|
||||
pIt2 = pIt1;
|
||||
if ( --pIt2 != eData.myPoints.end() && pIt2->mySegSize > allowedSize )
|
||||
sizeTree.SetSize( eData.myC3d.Value( 0.6*pIt2->myU + 0.4*pIt1->myU ), allowedSize );
|
||||
pIt2 = pIt1;
|
||||
if ( ++pIt2 != eData.myPoints.end() && pIt2->mySegSize > allowedSize )
|
||||
sizeTree.SetSize( eData.myC3d.Value( 0.6*pIt2->myU + 0.4*pIt1->myU ), allowedSize );
|
||||
// << "\t closure detected " << endl;
|
||||
if ( 1.1 * allowedSize < pIt1->mySegSize )
|
||||
{
|
||||
sizeDecreased = true;
|
||||
sizeTree.SetSize( pIt1->myP, allowedSize );
|
||||
// cout << "E " << theMesh.GetMeshDS()->ShapeToIndex( eData.Edge() )
|
||||
// << "\t SetSize " << allowedSize << " at "
|
||||
// << pIt1->myP.X() <<", "<< pIt1->myP.Y()<<", "<<pIt1->myP.Z() << endl;
|
||||
pIt2 = pIt1;
|
||||
if ( --pIt2 != eData.myPoints.end() && pIt2->mySegSize > allowedSize )
|
||||
sizeTree.SetSize( eData.myC3d.Value( 0.6*pIt2->myU + 0.4*pIt1->myU ), allowedSize );
|
||||
pIt2 = pIt1;
|
||||
if ( ++pIt2 != eData.myPoints.end() && pIt2->mySegSize > allowedSize )
|
||||
sizeTree.SetSize( eData.myC3d.Value( 0.6*pIt2->myU + 0.4*pIt1->myU ), allowedSize );
|
||||
}
|
||||
pIt1->mySegSize = allowedSize;
|
||||
}
|
||||
++pIt1;
|
||||
@ -1193,7 +1343,7 @@ bool AdaptiveAlgo::Compute(SMESH_Mesh & theMesh,
|
||||
} // while ( sizeDecreased )
|
||||
} // loop on myEdges
|
||||
|
||||
//*theProgress = 0.3 + 0.3 * iF / double( faceMap.Extent() );
|
||||
// *theProgress = 0.3 + 0.3 * iF / double( faceMap.Extent() );
|
||||
|
||||
} // loop on faceMap
|
||||
|
||||
@ -1220,11 +1370,12 @@ bool AdaptiveAlgo::makeSegments()
|
||||
{
|
||||
EdgeData& eData = myEdges[ iE ];
|
||||
|
||||
// estimate roughly min segement size on the EDGE
|
||||
// estimate roughly min segment size on the EDGE
|
||||
double edgeMinSize = myHyp->GetMaxSize();
|
||||
EdgeData::TPntIter pIt1 = eData.myPoints.begin();
|
||||
for ( ; pIt1 != eData.myPoints.end(); ++pIt1 )
|
||||
edgeMinSize = Min( edgeMinSize, mySizeTree->GetSize( pIt1->myP ));
|
||||
edgeMinSize = Min( edgeMinSize,
|
||||
Min( pIt1->mySegSize, mySizeTree->GetSize( pIt1->myP )));
|
||||
|
||||
const double f = eData.myC3d.FirstParameter(), l = eData.myC3d.LastParameter();
|
||||
const double parLen = l - f;
|
||||
@ -1234,6 +1385,7 @@ bool AdaptiveAlgo::makeSegments()
|
||||
// compute nb of segments
|
||||
bool toRecompute = true;
|
||||
double maxSegSize = 0;
|
||||
size_t i = 1, segCount;
|
||||
//cout << "E " << theMesh.GetMeshDS()->ShapeToIndex( eData.Edge() ) << endl;
|
||||
while ( toRecompute ) // recompute if segment size at some point is less than edgeMinSize/nbDivSeg
|
||||
{
|
||||
@ -1241,11 +1393,32 @@ bool AdaptiveAlgo::makeSegments()
|
||||
nbSegs[0] = 0;
|
||||
toRecompute = false;
|
||||
|
||||
// fill nbSegs with segment size stored in EdgeData::ProbePnt::mySegSize which can
|
||||
// be less than size in mySizeTree
|
||||
pIt1 = eData.myPoints.begin();
|
||||
EdgeData::ProbePnt* pp1 = &(*pIt1), *pp2;
|
||||
for ( ++pIt1; pIt1 != eData.myPoints.end(); ++pIt1 )
|
||||
{
|
||||
pp2 = &(*pIt1);
|
||||
double size1 = Min( pp1->mySegSize, myHyp->GetMaxSize() );
|
||||
double size2 = Min( pp2->mySegSize, myHyp->GetMaxSize() );
|
||||
double r, u, du = pp2->myU - pp1->myU;
|
||||
while(( u = f + parLen * i / nbDiv ) < pp2->myU )
|
||||
{
|
||||
r = ( u - pp1->myU ) / du;
|
||||
nbSegs[i] = (1-r) * size1 + r * size2;
|
||||
++i;
|
||||
}
|
||||
if ( i < nbSegs.size() )
|
||||
nbSegs[i] = size2;
|
||||
pp1 = pp2;
|
||||
}
|
||||
// fill nbSegs with local nb of segments
|
||||
gp_Pnt p1 = eData.First().myP, p2, pDiv = p1;
|
||||
for ( size_t i = 1, segCount = 1; i < nbSegs.size(); ++i )
|
||||
for ( i = 1, segCount = 1; i < nbSegs.size(); ++i )
|
||||
{
|
||||
p2 = eData.myC3d.Value( f + parLen * i / nbDiv );
|
||||
double locSize = Min( mySizeTree->GetSize( p2 ), myHyp->GetMaxSize() );
|
||||
double locSize = Min( mySizeTree->GetSize( p2 ), nbSegs[i] );
|
||||
double nb = p1.Distance( p2 ) / locSize;
|
||||
// if ( nbSegs.size() < 30 )
|
||||
// cout << "locSize " << locSize << " nb " << nb << endl;
|
||||
@ -1274,7 +1447,7 @@ bool AdaptiveAlgo::makeSegments()
|
||||
fact = ++nbSegFinal / nbSegs.back();
|
||||
//cout << "nbSegs.back() " << nbSegs.back() << " nbSegFinal " << nbSegFinal << endl;
|
||||
params.clear();
|
||||
for ( int i = 0, segCount = 1; segCount < nbSegFinal; ++segCount )
|
||||
for ( i = 0, segCount = 1; segCount < nbSegFinal; ++segCount )
|
||||
{
|
||||
while ( nbSegs[i] * fact < segCount )
|
||||
++i;
|
||||
@ -1302,7 +1475,7 @@ bool AdaptiveAlgo::makeSegments()
|
||||
helper.SetElementsOnShape( true );
|
||||
const int ID = 0;
|
||||
const SMDS_MeshNode *n1 = nf, *n2;
|
||||
for ( size_t i = 0; i < params.size(); ++i, n1 = n2 )
|
||||
for ( i = 0; i < params.size(); ++i, n1 = n2 )
|
||||
{
|
||||
gp_Pnt p2 = eData.myC3d.Value( params[i] );
|
||||
n2 = helper.AddNode( p2.X(), p2.Y(), p2.Z(), ID, params[i] );
|
||||
|
@ -223,7 +223,10 @@ bool StdMeshers_Quadrangle_2D::Compute (SMESH_Mesh& aMesh,
|
||||
return false;
|
||||
myQuadStruct = quad;
|
||||
|
||||
bool ok = false;
|
||||
updateDegenUV( quad );
|
||||
|
||||
enum { NOT_COMPUTED = -1, COMPUTE_FAILED = 0, COMPUTE_OK = 1 };
|
||||
int res = NOT_COMPUTED;
|
||||
if (myQuadranglePreference)
|
||||
{
|
||||
int n1 = quad->side[0]->NbPoints();
|
||||
@ -236,7 +239,7 @@ bool StdMeshers_Quadrangle_2D::Compute (SMESH_Mesh& aMesh,
|
||||
if (nfull == ntmp && ((n1 != n3) || (n2 != n4)))
|
||||
{
|
||||
// special path genarating only quandrangle faces
|
||||
ok = computeQuadPref( aMesh, F, quad );
|
||||
res = computeQuadPref( aMesh, F, quad );
|
||||
}
|
||||
}
|
||||
else if (myQuadType == QUAD_REDUCED)
|
||||
@ -252,7 +255,7 @@ bool StdMeshers_Quadrangle_2D::Compute (SMESH_Mesh& aMesh,
|
||||
if ((n1 == n3 && n2 != n4 && n24tmp == n24) ||
|
||||
(n2 == n4 && n1 != n3 && n13tmp == n13))
|
||||
{
|
||||
ok = computeReduced( aMesh, F, quad );
|
||||
res = computeReduced( aMesh, F, quad );
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -270,12 +273,15 @@ bool StdMeshers_Quadrangle_2D::Compute (SMESH_Mesh& aMesh,
|
||||
}
|
||||
}
|
||||
|
||||
ok = computeQuadDominant( aMesh, F, quad );
|
||||
if ( res == NOT_COMPUTED )
|
||||
{
|
||||
res = computeQuadDominant( aMesh, F, quad );
|
||||
}
|
||||
|
||||
if ( ok && myNeedSmooth )
|
||||
if ( res == COMPUTE_OK && myNeedSmooth )
|
||||
smooth( quad );
|
||||
|
||||
return ok;
|
||||
return ( res == COMPUTE_OK );
|
||||
}
|
||||
|
||||
//================================================================================
|
||||
@ -927,6 +933,8 @@ FaceQuadStruct::Ptr StdMeshers_Quadrangle_2D::CheckNbEdges(SMESH_Mesh &
|
||||
ignoreMediumNodes, myProxyMesh));
|
||||
++iSide;
|
||||
}
|
||||
if ( quad->side.size() == 4 )
|
||||
break;
|
||||
if ( nbLoops > 8 )
|
||||
{
|
||||
error(TComm("Bug: infinite loop in StdMeshers_Quadrangle_2D::CheckNbEdges()"));
|
||||
@ -1225,8 +1233,6 @@ bool StdMeshers_Quadrangle_2D::setNormalizedGrid (SMESH_Mesh & aMesh,
|
||||
// =down
|
||||
//
|
||||
|
||||
updateDegenUV( quad );
|
||||
|
||||
int nbhoriz = Min(quad->side[0]->NbPoints(), quad->side[2]->NbPoints());
|
||||
int nbvertic = Min(quad->side[1]->NbPoints(), quad->side[3]->NbPoints());
|
||||
|
||||
@ -1412,8 +1418,6 @@ bool StdMeshers_Quadrangle_2D::computeQuadPref (SMESH_Mesh & aMesh,
|
||||
bool WisF = true;
|
||||
int i,j,geomFaceID = meshDS->ShapeToIndex(aFace);
|
||||
|
||||
updateDegenUV( quad );
|
||||
|
||||
int nb = quad->side[0]->NbPoints();
|
||||
int nr = quad->side[1]->NbPoints();
|
||||
int nt = quad->side[2]->NbPoints();
|
||||
@ -2396,8 +2400,6 @@ bool StdMeshers_Quadrangle_2D::computeReduced (SMESH_Mesh & aMesh,
|
||||
if (uv_eb.size() != nb || uv_er.size() != nr || uv_et.size() != nt || uv_el.size() != nl)
|
||||
return error(COMPERR_BAD_INPUT_MESH);
|
||||
|
||||
updateDegenUV( quad );
|
||||
|
||||
// arrays for normalized params
|
||||
TColStd_SequenceOfReal npb, npr, npt, npl;
|
||||
for (j = 0; j < nb; j++) {
|
||||
@ -3266,7 +3268,7 @@ void StdMeshers_Quadrangle_2D::updateDegenUV(FaceQuadStruct::Ptr quad)
|
||||
uv1.v = uv2.v = 0.5 * ( uv1.v + uv2.v );
|
||||
}
|
||||
|
||||
else if ( quad->side.size() == 4 )
|
||||
else if ( quad->side.size() == 4 && myQuadType == QUAD_STANDARD)
|
||||
|
||||
// Set number of nodes on a degenerated side to be same as on an opposite side
|
||||
// ----------------------------------------------------------------------------
|
||||
@ -3329,8 +3331,8 @@ void StdMeshers_Quadrangle_2D::smooth (FaceQuadStruct::Ptr quad)
|
||||
while ( fIt->more() )
|
||||
{
|
||||
const SMDS_MeshElement* face = fIt->next();
|
||||
const int nbN = face->NbCornerNodes();
|
||||
const int nInd = face->GetNodeIndex( node );
|
||||
const int nbN = face->NbCornerNodes();
|
||||
const int nInd = face->GetNodeIndex( node );
|
||||
const int prevInd = myHelper->WrapIndex( nInd - 1, nbN );
|
||||
const int nextInd = myHelper->WrapIndex( nInd + 1, nbN );
|
||||
const SMDS_MeshNode* prevNode = face->GetNode( prevInd );
|
||||
@ -3370,24 +3372,30 @@ void StdMeshers_Quadrangle_2D::smooth (FaceQuadStruct::Ptr quad)
|
||||
if ( sNode._triangles.empty() )
|
||||
continue; // not movable node
|
||||
|
||||
// compute a new XYZ
|
||||
gp_XYZ newXYZ (0,0,0);
|
||||
for ( unsigned i = 0; i < sNode._triangles.size(); ++i )
|
||||
newXYZ += sNode._triangles[i]._n1->_xyz;
|
||||
newXYZ /= sNode._triangles.size();
|
||||
|
||||
// compute a new UV by projection
|
||||
gp_XY newUV;
|
||||
proj.Perform( newXYZ );
|
||||
bool isValid = ( proj.IsDone() && proj.NbPoints() > 0 );
|
||||
if ( isValid )
|
||||
bool isValid = false;
|
||||
bool use3D = ( iLoop > 2 ); // 3 loops in 2D and 2, in 3D
|
||||
|
||||
if ( use3D )
|
||||
{
|
||||
// check validity of the newUV
|
||||
Quantity_Parameter u,v;
|
||||
proj.LowerDistanceParameters( u, v );
|
||||
newUV.SetCoord( u, v );
|
||||
for ( unsigned i = 0; i < sNode._triangles.size() && isValid; ++i )
|
||||
isValid = ( sNode._triangles[i].IsForward( newUV ) == refForward );
|
||||
// compute a new XYZ
|
||||
gp_XYZ newXYZ (0,0,0);
|
||||
for ( unsigned i = 0; i < sNode._triangles.size(); ++i )
|
||||
newXYZ += sNode._triangles[i]._n1->_xyz;
|
||||
newXYZ /= sNode._triangles.size();
|
||||
|
||||
// compute a new UV by projection
|
||||
proj.Perform( newXYZ );
|
||||
isValid = ( proj.IsDone() && proj.NbPoints() > 0 );
|
||||
if ( isValid )
|
||||
{
|
||||
// check validity of the newUV
|
||||
Quantity_Parameter u,v;
|
||||
proj.LowerDistanceParameters( u, v );
|
||||
newUV.SetCoord( u, v );
|
||||
for ( unsigned i = 0; i < sNode._triangles.size() && isValid; ++i )
|
||||
isValid = ( sNode._triangles[i].IsForward( newUV ) == refForward );
|
||||
}
|
||||
}
|
||||
if ( !isValid )
|
||||
{
|
||||
@ -3578,9 +3586,10 @@ int StdMeshers_Quadrangle_2D::getCorners(const TopoDS_Face& theFace,
|
||||
theVertices.clear();
|
||||
vector< double > angles;
|
||||
vector< TopoDS_Edge > edgeVec;
|
||||
vector< int > cornerInd;
|
||||
vector< int > cornerInd, nbSeg;
|
||||
angles.reserve( vertexByAngle.size() );
|
||||
edgeVec.reserve( vertexByAngle.size() );
|
||||
nbSeg.reserve( vertexByAngle.size() );
|
||||
cornerInd.reserve( nbCorners );
|
||||
for ( edge = theWire.begin(); edge != theWire.end(); ++edge )
|
||||
{
|
||||
@ -3595,6 +3604,13 @@ int StdMeshers_Quadrangle_2D::getCorners(const TopoDS_Face& theFace,
|
||||
}
|
||||
angles.push_back( angleByVertex.IsBound( v ) ? angleByVertex( v ) : -M_PI );
|
||||
edgeVec.push_back( *edge );
|
||||
if ( theConsiderMesh && isThereVariants )
|
||||
{
|
||||
if ( SMESHDS_SubMesh* sm = helper.GetMeshDS()->MeshElements( *edge ))
|
||||
nbSeg.push_back( sm->NbNodes() + 1 );
|
||||
else
|
||||
nbSeg.push_back( 0 );
|
||||
}
|
||||
}
|
||||
|
||||
// refine the result vector - make sides elual by length if
|
||||
|
@ -434,7 +434,7 @@ namespace VISCOUS_3D
|
||||
//vector<const SMDS_MeshNode*> _nodesAround;
|
||||
vector<_Simplex> _simplices; // for quality check
|
||||
|
||||
enum SmoothType { LAPLACIAN, CENTROIDAL, ANGULAR };
|
||||
enum SmoothType { LAPLACIAN, CENTROIDAL, ANGULAR, TFI };
|
||||
|
||||
bool Smooth(int& badNb,
|
||||
Handle(Geom_Surface)& surface,
|
||||
@ -500,7 +500,11 @@ namespace VISCOUS_3D
|
||||
bool prepareEdgeToShrink( _LayerEdge& edge, const TopoDS_Face& F,
|
||||
SMESH_MesherHelper& helper,
|
||||
const SMESHDS_SubMesh* faceSubMesh );
|
||||
void fixBadFaces(const TopoDS_Face& F, SMESH_MesherHelper& helper);
|
||||
void fixBadFaces(const TopoDS_Face& F,
|
||||
SMESH_MesherHelper& helper,
|
||||
const bool is2D,
|
||||
const int step,
|
||||
set<const SMDS_MeshNode*> * involvedNodes=NULL);
|
||||
bool addBoundaryElements();
|
||||
|
||||
bool error( const string& text, int solidID=-1 );
|
||||
@ -549,7 +553,7 @@ namespace VISCOUS_3D
|
||||
virtual vtkIdType GetVtkType() const { return -1; }
|
||||
virtual SMDSAbs_EntityType GetEntityType() const { return SMDSEntity_Last; }
|
||||
virtual SMDSAbs_GeometryType GetGeomType() const { return SMDSGeom_TRIANGLE; }
|
||||
virtual SMDS_ElemIteratorPtr elementsIterator(SMDSAbs_ElementType type) const
|
||||
virtual SMDS_ElemIteratorPtr elementsIterator(SMDSAbs_ElementType) const
|
||||
{ return SMDS_ElemIteratorPtr( new SMDS_NodeVectorElemIterator( _nn.begin(), _nn.end()));}
|
||||
};
|
||||
//--------------------------------------------------------------------------------
|
||||
@ -568,6 +572,44 @@ virtual SMDS_ElemIteratorPtr elementsIterator(SMDSAbs_ElementType type) const
|
||||
_nn[3]=_le2->_nodes[0];
|
||||
}
|
||||
};
|
||||
//--------------------------------------------------------------------------------
|
||||
/*!
|
||||
* \brief Retriever of node coordinates either directly of from a surface by node UV.
|
||||
* \warning Location of a surface is ignored
|
||||
*/
|
||||
struct NodeCoordHelper
|
||||
{
|
||||
SMESH_MesherHelper& _helper;
|
||||
const TopoDS_Face& _face;
|
||||
Handle(Geom_Surface) _surface;
|
||||
gp_XYZ (NodeCoordHelper::* _fun)(const SMDS_MeshNode* n) const;
|
||||
|
||||
NodeCoordHelper(const TopoDS_Face& F, SMESH_MesherHelper& helper, bool is2D)
|
||||
: _helper( helper ), _face( F )
|
||||
{
|
||||
if ( is2D )
|
||||
{
|
||||
TopLoc_Location loc;
|
||||
_surface = BRep_Tool::Surface( _face, loc );
|
||||
}
|
||||
if ( _surface.IsNull() )
|
||||
_fun = & NodeCoordHelper::direct;
|
||||
else
|
||||
_fun = & NodeCoordHelper::byUV;
|
||||
}
|
||||
gp_XYZ operator()(const SMDS_MeshNode* n) const { return (this->*_fun)( n ); }
|
||||
|
||||
private:
|
||||
gp_XYZ direct(const SMDS_MeshNode* n) const
|
||||
{
|
||||
return SMESH_TNodeXYZ( n );
|
||||
}
|
||||
gp_XYZ byUV (const SMDS_MeshNode* n) const
|
||||
{
|
||||
gp_XY uv = _helper.GetNodeUV( _face, n );
|
||||
return _surface->Value( uv.X(), uv.Y() ).XYZ();
|
||||
}
|
||||
};
|
||||
} // namespace VISCOUS_3D
|
||||
|
||||
//================================================================================
|
||||
@ -801,10 +843,10 @@ namespace
|
||||
double u1 = intervals( i );
|
||||
double u2 = intervals( i+1 );
|
||||
curve.D2( 0.5*( u1+u2 ), p, drv1, drv2 );
|
||||
double cross = drv2 * drv1; //drv2 ^ drv1;
|
||||
double cross = drv2 ^ drv1;
|
||||
if ( E.Orientation() == TopAbs_REVERSED )
|
||||
cross = -cross;
|
||||
isConvex = ( cross > -1e-9 );
|
||||
isConvex = ( cross > 0.1 ); //-1e-9 );
|
||||
}
|
||||
// check if concavity is strong enough to care about it
|
||||
//const double maxAngle = 5 * Standard_PI180;
|
||||
@ -873,7 +915,7 @@ namespace
|
||||
}
|
||||
void Finish() {
|
||||
if (py)
|
||||
*py << "mesh.MakeGroup('Viscous Prisms',VOLUME,FT_ElemGeomType,'=',Geom_PENTA)"<<endl;
|
||||
*py << "mesh.MakeGroup('Viscous Prisms',SMESH.VOLUME,SMESH.FT_ElemGeomType,'=',SMESH.Geom_PENTA)"<<endl;
|
||||
delete py; py=0;
|
||||
}
|
||||
~PyDump() { Finish(); }
|
||||
@ -1714,14 +1756,43 @@ bool _ViscousBuilder::setEdgeData(_LayerEdge& edge,
|
||||
if ( s.IsNull() || s.ShapeType() != TopAbs_FACE || !subIds.count( *id ))
|
||||
continue;
|
||||
totalNbFaces++;
|
||||
//nbLayerFaces += subIds.count( *id );
|
||||
F = TopoDS::Face( s );
|
||||
|
||||
// IDEA: if there is a problem with finding a normal,
|
||||
// we can compute an area-weighted sum of normals of all faces sharing the node
|
||||
gp_XY uv = helper.GetNodeUV( F, node, 0, &normOK );
|
||||
Handle(Geom_Surface) surface = BRep_Tool::Surface( F );
|
||||
surface->D1( uv.X(),uv.Y(), p, du,dv );
|
||||
surface->D1( uv.X(), uv.Y(), p, du,dv );
|
||||
geomNorm = du ^ dv;
|
||||
double size2 = geomNorm.SquareMagnitude();
|
||||
if ( size2 < 1e-10 ) // singularity
|
||||
{
|
||||
SMDS_ElemIteratorPtr fIt = node->GetInverseElementIterator(SMDSAbs_Face);
|
||||
while ( fIt->more() )
|
||||
{
|
||||
const SMDS_MeshElement* f = fIt->next();
|
||||
if ( editor.FindShape( f ) == *id )
|
||||
{
|
||||
SMESH_MeshAlgos::FaceNormal( f, (gp_XYZ&) geomNorm.XYZ(), /*normalized=*/false );
|
||||
size2 = geomNorm.SquareMagnitude();
|
||||
break;
|
||||
}
|
||||
}
|
||||
// double ddu = 0, ddv = 0;
|
||||
// if ( du.SquareMagnitude() > dv.SquareMagnitude() )
|
||||
// ddu = 1e-3;
|
||||
// else
|
||||
// ddv = 1e-3;
|
||||
// surface->D1( uv.X()+ddu, uv.Y()+ddv, p, du,dv );
|
||||
// geomNorm = du ^ dv;
|
||||
// size2 = geomNorm.SquareMagnitude();
|
||||
// if ( size2 < 1e-10 )
|
||||
// {
|
||||
// surface->D1( uv.X()-ddu, uv.Y()-ddv, p, du,dv );
|
||||
// geomNorm = du ^ dv;
|
||||
// size2 = geomNorm.SquareMagnitude();
|
||||
// }
|
||||
}
|
||||
if ( size2 > numeric_limits<double>::min() )
|
||||
geomNorm /= sqrt( size2 );
|
||||
else
|
||||
@ -1986,14 +2057,15 @@ void _ViscousBuilder::getSimplices( const SMDS_MeshNode* node,
|
||||
const _SolidData* dataToCheckOri,
|
||||
const bool toSort)
|
||||
{
|
||||
simplices.clear();
|
||||
SMDS_ElemIteratorPtr fIt = node->GetInverseElementIterator(SMDSAbs_Face);
|
||||
while ( fIt->more() )
|
||||
{
|
||||
const SMDS_MeshElement* f = fIt->next();
|
||||
const TGeomID shapeInd = f->getshapeId();
|
||||
const TGeomID shapeInd = f->getshapeId();
|
||||
if ( ingnoreShapes.count( shapeInd )) continue;
|
||||
const int nbNodes = f->NbCornerNodes();
|
||||
int srcInd = f->GetNodeIndex( node );
|
||||
const int srcInd = f->GetNodeIndex( node );
|
||||
const SMDS_MeshNode* nPrev = f->GetNode( SMESH_MesherHelper::WrapIndex( srcInd-1, nbNodes ));
|
||||
const SMDS_MeshNode* nNext = f->GetNode( SMESH_MesherHelper::WrapIndex( srcInd+1, nbNodes ));
|
||||
const SMDS_MeshNode* nOpp = f->GetNode( SMESH_MesherHelper::WrapIndex( srcInd+2, nbNodes ));
|
||||
@ -3604,6 +3676,12 @@ bool _ViscousBuilder::shrink()
|
||||
}
|
||||
}
|
||||
|
||||
dumpFunction(SMESH_Comment("beforeShrinkFace")<<f2sd->first); // debug
|
||||
SMDS_ElemIteratorPtr fIt = smDS->GetElements();
|
||||
while ( fIt->more() )
|
||||
if ( const SMDS_MeshElement* f = fIt->next() )
|
||||
dumpChangeNodes( f );
|
||||
|
||||
// Replace source nodes by target nodes in mesh faces to shrink
|
||||
const SMDS_MeshNode* nodes[20];
|
||||
for ( unsigned i = 0; i < lEdges.size(); ++i )
|
||||
@ -3617,10 +3695,10 @@ bool _ViscousBuilder::shrink()
|
||||
const SMDS_MeshElement* f = fIt->next();
|
||||
if ( !smDS->Contains( f ))
|
||||
continue;
|
||||
SMDS_ElemIteratorPtr nIt = f->nodesIterator();
|
||||
for ( int iN = 0; iN < f->NbNodes(); ++iN )
|
||||
SMDS_NodeIteratorPtr nIt = f->nodeIterator();
|
||||
for ( int iN = 0; nIt->more(); ++iN )
|
||||
{
|
||||
const SMDS_MeshNode* n = static_cast<const SMDS_MeshNode*>( nIt->next() );
|
||||
const SMDS_MeshNode* n = nIt->next();
|
||||
nodes[iN] = ( n == srcNode ? tgtNode : n );
|
||||
}
|
||||
helper.GetMeshDS()->ChangeElementNodes( f, nodes, f->NbNodes() );
|
||||
@ -3633,7 +3711,6 @@ bool _ViscousBuilder::shrink()
|
||||
// Create _SmoothNode's on face F
|
||||
vector< _SmoothNode > nodesToSmooth( smoothNodes.size() );
|
||||
{
|
||||
dumpFunction(SMESH_Comment("beforeShrinkFace")<<f2sd->first); // debug
|
||||
const bool sortSimplices = isConcaveFace;
|
||||
for ( unsigned i = 0; i < smoothNodes.size(); ++i )
|
||||
{
|
||||
@ -3645,11 +3722,10 @@ bool _ViscousBuilder::shrink()
|
||||
helper.GetNodeUV( F, n, 0, &isOkUV);
|
||||
dumpMove( n );
|
||||
}
|
||||
dumpFunctionEnd();
|
||||
}
|
||||
//if ( nodesToSmooth.empty() ) continue;
|
||||
|
||||
// Find EDGE's to shrink
|
||||
// Find EDGE's to shrink and set simpices to LayerEdge's
|
||||
set< _Shrinker1D* > eShri1D;
|
||||
{
|
||||
for ( unsigned i = 0; i < lEdges.size(); ++i )
|
||||
@ -3666,6 +3742,23 @@ bool _ViscousBuilder::shrink()
|
||||
// srinked while srinking another FACE
|
||||
srinker.RestoreParams();
|
||||
}
|
||||
getSimplices( /*tgtNode=*/edge->_nodes.back(), edge->_simplices, ignoreShapes );
|
||||
}
|
||||
}
|
||||
|
||||
bool toFixTria = false; // to improve quality of trias by diagonal swap
|
||||
if ( isConcaveFace )
|
||||
{
|
||||
const bool hasTria = _mesh->NbTriangles(), hasQuad = _mesh->NbQuadrangles();
|
||||
if ( hasTria != hasQuad ) {
|
||||
toFixTria = hasTria;
|
||||
}
|
||||
else {
|
||||
set<int> nbNodesSet;
|
||||
SMDS_ElemIteratorPtr fIt = smDS->GetElements();
|
||||
while ( fIt->more() && nbNodesSet.size() < 2 )
|
||||
nbNodesSet.insert( fIt->next()->NbCornerNodes() );
|
||||
toFixTria = ( *nbNodesSet.begin() == 3 );
|
||||
}
|
||||
}
|
||||
|
||||
@ -3676,7 +3769,7 @@ bool _ViscousBuilder::shrink()
|
||||
bool shrinked = true;
|
||||
int badNb, shriStep=0, smooStep=0;
|
||||
_SmoothNode::SmoothType smoothType
|
||||
= isConcaveFace ? _SmoothNode::CENTROIDAL : _SmoothNode::LAPLACIAN;
|
||||
= isConcaveFace ? _SmoothNode::ANGULAR : _SmoothNode::LAPLACIAN;
|
||||
while ( shrinked )
|
||||
{
|
||||
shriStep++;
|
||||
@ -3684,7 +3777,7 @@ bool _ViscousBuilder::shrink()
|
||||
// -----------------------------------------------
|
||||
dumpFunction(SMESH_Comment("moveBoundaryOnF")<<f2sd->first<<"_st"<<shriStep ); // debug
|
||||
shrinked = false;
|
||||
for ( unsigned i = 0; i < lEdges.size(); ++i )
|
||||
for ( size_t i = 0; i < lEdges.size(); ++i )
|
||||
{
|
||||
shrinked |= lEdges[i]->SetNewLength2d( surface,F,helper );
|
||||
}
|
||||
@ -3699,7 +3792,7 @@ bool _ViscousBuilder::shrink()
|
||||
// Smoothing in 2D
|
||||
// -----------------
|
||||
int nbNoImpSteps = 0;
|
||||
bool moved = true;
|
||||
bool moved = true;
|
||||
badNb = 1;
|
||||
while (( nbNoImpSteps < 5 && badNb > 0) && moved)
|
||||
{
|
||||
@ -3724,7 +3817,41 @@ bool _ViscousBuilder::shrink()
|
||||
return error(SMESH_Comment("Can't shrink 2D mesh on face ") << f2sd->first );
|
||||
if ( shriStep > 200 )
|
||||
return error(SMESH_Comment("Infinite loop at shrinking 2D mesh on face ") << f2sd->first );
|
||||
}
|
||||
|
||||
// Fix narrow triangles by swapping diagonals
|
||||
// ---------------------------------------
|
||||
if ( toFixTria )
|
||||
{
|
||||
set<const SMDS_MeshNode*> usedNodes;
|
||||
fixBadFaces( F, helper, /*is2D=*/true, shriStep, & usedNodes); // swap diagonals
|
||||
|
||||
// update working data
|
||||
set<const SMDS_MeshNode*>::iterator n;
|
||||
for ( size_t i = 0; i < nodesToSmooth.size() && !usedNodes.empty(); ++i )
|
||||
{
|
||||
n = usedNodes.find( nodesToSmooth[ i ]._node );
|
||||
if ( n != usedNodes.end())
|
||||
{
|
||||
getSimplices( nodesToSmooth[ i ]._node,
|
||||
nodesToSmooth[ i ]._simplices,
|
||||
ignoreShapes, NULL,
|
||||
/*sortSimplices=*/ smoothType == _SmoothNode::ANGULAR );
|
||||
usedNodes.erase( n );
|
||||
}
|
||||
}
|
||||
for ( size_t i = 0; i < lEdges.size() && !usedNodes.empty(); ++i )
|
||||
{
|
||||
n = usedNodes.find( /*tgtNode=*/ lEdges[i]->_nodes.back() );
|
||||
if ( n != usedNodes.end())
|
||||
{
|
||||
getSimplices( lEdges[i]->_nodes.back(),
|
||||
lEdges[i]->_simplices,
|
||||
ignoreShapes );
|
||||
usedNodes.erase( n );
|
||||
}
|
||||
}
|
||||
}
|
||||
} // while ( shrinked )
|
||||
|
||||
// No wrongly shaped faces remain; final smooth. Set node XYZ.
|
||||
bool isStructuredFixed = false;
|
||||
@ -3732,10 +3859,16 @@ bool _ViscousBuilder::shrink()
|
||||
isStructuredFixed = algo->FixInternalNodes( *data._proxyMesh, F );
|
||||
if ( !isStructuredFixed )
|
||||
{
|
||||
if ( isConcaveFace )
|
||||
fixBadFaces( F, helper ); // fix narrow faces by swapping diagonals
|
||||
for ( int st = /*highQuality ? 10 :*/ 3; st; --st )
|
||||
if ( isConcaveFace ) // fix narrow faces by swapping diagonals
|
||||
fixBadFaces( F, helper, /*is2D=*/false, ++shriStep );
|
||||
|
||||
for ( int st = 3; st; --st )
|
||||
{
|
||||
switch( st ) {
|
||||
case 1: smoothType = _SmoothNode::LAPLACIAN; break;
|
||||
case 2: smoothType = _SmoothNode::LAPLACIAN; break;
|
||||
case 3: smoothType = _SmoothNode::ANGULAR; break;
|
||||
}
|
||||
dumpFunction(SMESH_Comment("shrinkFace")<<f2sd->first<<"_st"<<++smooStep); // debug
|
||||
for ( unsigned i = 0; i < nodesToSmooth.size(); ++i )
|
||||
{
|
||||
@ -3794,54 +3927,54 @@ bool _ViscousBuilder::prepareEdgeToShrink( _LayerEdge& edge,
|
||||
edge._normal.SetCoord( uvDir.X(),uvDir.Y(), 0);
|
||||
edge._len = uvLen;
|
||||
|
||||
// IMPORTANT to have src nodes NOT yet REPLACED by tgt nodes in shrinked faces
|
||||
vector<const SMDS_MeshElement*> faces;
|
||||
multimap< double, const SMDS_MeshNode* > proj2node;
|
||||
SMDS_ElemIteratorPtr fIt = srcNode->GetInverseElementIterator(SMDSAbs_Face);
|
||||
while ( fIt->more() )
|
||||
{
|
||||
const SMDS_MeshElement* f = fIt->next();
|
||||
if ( faceSubMesh->Contains( f ))
|
||||
faces.push_back( f );
|
||||
}
|
||||
for ( unsigned i = 0; i < faces.size(); ++i )
|
||||
{
|
||||
const int nbNodes = faces[i]->NbCornerNodes();
|
||||
for ( int j = 0; j < nbNodes; ++j )
|
||||
{
|
||||
const SMDS_MeshNode* n = faces[i]->GetNode(j);
|
||||
if ( n == srcNode ) continue;
|
||||
if ( n->GetPosition()->GetTypeOfPosition() != SMDS_TOP_FACE &&
|
||||
( faces.size() > 1 || nbNodes > 3 ))
|
||||
continue;
|
||||
gp_Pnt2d uv = helper.GetNodeUV( F, n );
|
||||
gp_Vec2d uvDirN( srcUV, uv );
|
||||
double proj = uvDirN * uvDir;
|
||||
proj2node.insert( make_pair( proj, n ));
|
||||
}
|
||||
}
|
||||
// // IMPORTANT to have src nodes NOT yet REPLACED by tgt nodes in shrinked faces
|
||||
// vector<const SMDS_MeshElement*> faces;
|
||||
// multimap< double, const SMDS_MeshNode* > proj2node;
|
||||
// SMDS_ElemIteratorPtr fIt = srcNode->GetInverseElementIterator(SMDSAbs_Face);
|
||||
// while ( fIt->more() )
|
||||
// {
|
||||
// const SMDS_MeshElement* f = fIt->next();
|
||||
// if ( faceSubMesh->Contains( f ))
|
||||
// faces.push_back( f );
|
||||
// }
|
||||
// for ( unsigned i = 0; i < faces.size(); ++i )
|
||||
// {
|
||||
// const int nbNodes = faces[i]->NbCornerNodes();
|
||||
// for ( int j = 0; j < nbNodes; ++j )
|
||||
// {
|
||||
// const SMDS_MeshNode* n = faces[i]->GetNode(j);
|
||||
// if ( n == srcNode ) continue;
|
||||
// if ( n->GetPosition()->GetTypeOfPosition() != SMDS_TOP_FACE &&
|
||||
// ( faces.size() > 1 || nbNodes > 3 ))
|
||||
// continue;
|
||||
// gp_Pnt2d uv = helper.GetNodeUV( F, n );
|
||||
// gp_Vec2d uvDirN( srcUV, uv );
|
||||
// double proj = uvDirN * uvDir;
|
||||
// proj2node.insert( make_pair( proj, n ));
|
||||
// }
|
||||
// }
|
||||
|
||||
multimap< double, const SMDS_MeshNode* >::iterator p2n = proj2node.begin(), p2nEnd;
|
||||
const double minProj = p2n->first;
|
||||
const double projThreshold = 1.1 * uvLen;
|
||||
if ( minProj > projThreshold )
|
||||
{
|
||||
// tgtNode is located so that it does not make faces with wrong orientation
|
||||
return true;
|
||||
}
|
||||
// multimap< double, const SMDS_MeshNode* >::iterator p2n = proj2node.begin(), p2nEnd;
|
||||
// const double minProj = p2n->first;
|
||||
// const double projThreshold = 1.1 * uvLen;
|
||||
// if ( minProj > projThreshold )
|
||||
// {
|
||||
// // tgtNode is located so that it does not make faces with wrong orientation
|
||||
// return true;
|
||||
// }
|
||||
edge._pos.resize(1);
|
||||
edge._pos[0].SetCoord( tgtUV.X(), tgtUV.Y(), 0 );
|
||||
|
||||
// store most risky nodes in _simplices
|
||||
p2nEnd = proj2node.lower_bound( projThreshold );
|
||||
int nbSimpl = ( std::distance( p2n, p2nEnd ) + 1) / 2;
|
||||
edge._simplices.resize( nbSimpl );
|
||||
for ( int i = 0; i < nbSimpl; ++i )
|
||||
{
|
||||
edge._simplices[i]._nPrev = p2n->second;
|
||||
if ( ++p2n != p2nEnd )
|
||||
edge._simplices[i]._nNext = p2n->second;
|
||||
}
|
||||
// p2nEnd = proj2node.lower_bound( projThreshold );
|
||||
// int nbSimpl = ( std::distance( p2n, p2nEnd ) + 1) / 2;
|
||||
// edge._simplices.resize( nbSimpl );
|
||||
// for ( int i = 0; i < nbSimpl; ++i )
|
||||
// {
|
||||
// edge._simplices[i]._nPrev = p2n->second;
|
||||
// if ( ++p2n != p2nEnd )
|
||||
// edge._simplices[i]._nNext = p2n->second;
|
||||
// }
|
||||
// set UV of source node to target node
|
||||
SMDS_FacePosition* pos = static_cast<SMDS_FacePosition*>( tgtNode->GetPosition() );
|
||||
pos->SetUParameter( srcUV.X() );
|
||||
@ -3949,23 +4082,28 @@ bool _ViscousBuilder::prepareEdgeToShrink( _LayerEdge& edge,
|
||||
*/
|
||||
//================================================================================
|
||||
|
||||
void _ViscousBuilder::fixBadFaces(const TopoDS_Face& F, SMESH_MesherHelper& helper)
|
||||
void _ViscousBuilder::fixBadFaces(const TopoDS_Face& F,
|
||||
SMESH_MesherHelper& helper,
|
||||
const bool is2D,
|
||||
const int step,
|
||||
set<const SMDS_MeshNode*> * involvedNodes)
|
||||
{
|
||||
SMESH::Controls::AspectRatio qualifier;
|
||||
SMESH::Controls::TSequenceOfXYZ points(3), points1(3), points2(3);
|
||||
const double maxAspectRatio = 4.;
|
||||
const double maxAspectRatio = is2D ? 4. : 2;
|
||||
NodeCoordHelper xyz( F, helper, is2D );
|
||||
|
||||
// find bad triangles
|
||||
|
||||
vector< const SMDS_MeshElement* > badTrias;
|
||||
vector< double > badAspects;
|
||||
SMESHDS_SubMesh* sm = helper.GetMeshDS()->MeshElements( F );
|
||||
SMESHDS_SubMesh* sm = helper.GetMeshDS()->MeshElements( F );
|
||||
SMDS_ElemIteratorPtr fIt = sm->GetElements();
|
||||
while ( fIt->more() )
|
||||
{
|
||||
const SMDS_MeshElement * f = fIt->next();
|
||||
if ( f->NbCornerNodes() != 3 ) continue;
|
||||
for ( int iP = 0; iP < 3; ++iP ) points(iP+1) = SMESH_TNodeXYZ( f->GetNode(iP));
|
||||
for ( int iP = 0; iP < 3; ++iP ) points(iP+1) = xyz( f->GetNode(iP));
|
||||
double aspect = qualifier.GetValue( points );
|
||||
if ( aspect > maxAspectRatio )
|
||||
{
|
||||
@ -3973,6 +4111,18 @@ void _ViscousBuilder::fixBadFaces(const TopoDS_Face& F, SMESH_MesherHelper& help
|
||||
badAspects.push_back( aspect );
|
||||
}
|
||||
}
|
||||
if ( step == 1 )
|
||||
{
|
||||
dumpFunction(SMESH_Comment("beforeSwapDiagonals_F")<<helper.GetSubShapeID());
|
||||
SMDS_ElemIteratorPtr fIt = sm->GetElements();
|
||||
while ( fIt->more() )
|
||||
{
|
||||
const SMDS_MeshElement * f = fIt->next();
|
||||
if ( f->NbCornerNodes() == 3 )
|
||||
dumpChangeNodes( f );
|
||||
}
|
||||
dumpFunctionEnd();
|
||||
}
|
||||
if ( badTrias.empty() )
|
||||
return;
|
||||
|
||||
@ -3988,9 +4138,10 @@ void _ViscousBuilder::fixBadFaces(const TopoDS_Face& F, SMESH_MesherHelper& help
|
||||
double aspRatio [3];
|
||||
int i1, i2, i3;
|
||||
|
||||
involvedFaces.insert( badTrias[iTia] );
|
||||
if ( !involvedFaces.insert( badTrias[iTia] ).second )
|
||||
continue;
|
||||
for ( int iP = 0; iP < 3; ++iP )
|
||||
points(iP+1) = SMESH_TNodeXYZ( badTrias[iTia]->GetNode(iP));
|
||||
points(iP+1) = xyz( badTrias[iTia]->GetNode(iP));
|
||||
|
||||
// find triangles adjacent to badTrias[iTia] with better aspect ratio after diag-swaping
|
||||
int bestCouple = -1;
|
||||
@ -4006,7 +4157,7 @@ void _ViscousBuilder::fixBadFaces(const TopoDS_Face& F, SMESH_MesherHelper& help
|
||||
|
||||
// aspect ratio of an adjacent tria
|
||||
for ( int iP = 0; iP < 3; ++iP )
|
||||
points2(iP+1) = SMESH_TNodeXYZ( trias[iSide].second->GetNode(iP));
|
||||
points2(iP+1) = xyz( trias[iSide].second->GetNode(iP));
|
||||
double aspectInit = qualifier.GetValue( points2 );
|
||||
|
||||
// arrange nodes as after diag-swaping
|
||||
@ -4023,6 +4174,12 @@ void _ViscousBuilder::fixBadFaces(const TopoDS_Face& F, SMESH_MesherHelper& help
|
||||
if ( aspRatio[ iSide ] > aspectInit + badAspects[ iTia ] )
|
||||
continue;
|
||||
|
||||
// prevent inversion of a triangle
|
||||
gp_Vec norm1 = gp_Vec( points1(1), points1(3) ) ^ gp_Vec( points1(1), points1(2) );
|
||||
gp_Vec norm2 = gp_Vec( points2(1), points2(3) ) ^ gp_Vec( points2(1), points2(2) );
|
||||
if ( norm1 * norm2 < 0. && norm1.Angle( norm2 ) > 70./180.*M_PI )
|
||||
continue;
|
||||
|
||||
if ( bestCouple < 0 || aspRatio[ bestCouple ] > aspRatio[ iSide ] )
|
||||
bestCouple = iSide;
|
||||
}
|
||||
@ -4043,17 +4200,25 @@ void _ViscousBuilder::fixBadFaces(const TopoDS_Face& F, SMESH_MesherHelper& help
|
||||
// swap diagonals
|
||||
|
||||
SMESH_MeshEditor editor( helper.GetMesh() );
|
||||
dumpFunction(SMESH_Comment("beforeSwapDiagonals_F")<<helper.GetSubShapeID());
|
||||
dumpFunction(SMESH_Comment("beforeSwapDiagonals_F")<<helper.GetSubShapeID()<<"_"<<step);
|
||||
for ( size_t i = 0; i < triaCouples.size(); ++i )
|
||||
{
|
||||
dumpChangeNodes( triaCouples[i].first );
|
||||
dumpChangeNodes( triaCouples[i].second );
|
||||
editor.InverseDiag( triaCouples[i].first, triaCouples[i].second );
|
||||
}
|
||||
dumpFunctionEnd();
|
||||
|
||||
if ( involvedNodes )
|
||||
for ( size_t i = 0; i < triaCouples.size(); ++i )
|
||||
{
|
||||
involvedNodes->insert( triaCouples[i].first->begin_nodes(),
|
||||
triaCouples[i].first->end_nodes() );
|
||||
involvedNodes->insert( triaCouples[i].second->begin_nodes(),
|
||||
triaCouples[i].second->end_nodes() );
|
||||
}
|
||||
|
||||
// just for debug dump resulting triangles
|
||||
dumpFunction(SMESH_Comment("swapDiagonals_F")<<helper.GetSubShapeID());
|
||||
dumpFunction(SMESH_Comment("swapDiagonals_F")<<helper.GetSubShapeID()<<"_"<<step);
|
||||
for ( size_t i = 0; i < triaCouples.size(); ++i )
|
||||
{
|
||||
dumpChangeNodes( triaCouples[i].first );
|
||||
@ -4079,41 +4244,40 @@ bool _LayerEdge::SetNewLength2d( Handle(Geom_Surface)& surface,
|
||||
if ( _sWOL.ShapeType() == TopAbs_FACE )
|
||||
{
|
||||
gp_XY curUV = helper.GetNodeUV( F, tgtNode );
|
||||
gp_Pnt2d tgtUV( _pos[0].X(), _pos[0].Y());
|
||||
gp_Pnt2d tgtUV( _pos[0].X(), _pos[0].Y() );
|
||||
gp_Vec2d uvDir( _normal.X(), _normal.Y() );
|
||||
const double uvLen = tgtUV.Distance( curUV );
|
||||
const double kSafe = Max( 0.5, 1. - 0.1 * _simplices.size() );
|
||||
|
||||
// Select shrinking step such that not to make faces with wrong orientation.
|
||||
const double kSafe = 0.8;
|
||||
const double minStepSize = uvLen / 10;
|
||||
double stepSize = uvLen;
|
||||
for ( unsigned i = 0; i < _simplices.size(); ++i )
|
||||
for ( size_t i = 0; i < _simplices.size(); ++i )
|
||||
{
|
||||
const SMDS_MeshNode* nn[2] = { _simplices[i]._nPrev, _simplices[i]._nNext };
|
||||
for ( int j = 0; j < 2; ++j )
|
||||
if ( const SMDS_MeshNode* n = nn[j] )
|
||||
{
|
||||
gp_XY uv = helper.GetNodeUV( F, n );
|
||||
gp_Vec2d uvDirN( curUV, uv );
|
||||
double proj = uvDirN * uvDir * kSafe;
|
||||
if ( proj < stepSize && proj > minStepSize )
|
||||
stepSize = proj;
|
||||
else if ( proj < minStepSize )
|
||||
stepSize = minStepSize;
|
||||
}
|
||||
// find intersection of 2 lines: curUV-tgtUV and that connecting simplex nodes
|
||||
gp_XY uvN1 = helper.GetNodeUV( F, _simplices[i]._nPrev );
|
||||
gp_XY uvN2 = helper.GetNodeUV( F, _simplices[i]._nNext );
|
||||
gp_XY dirN = uvN2 - uvN1;
|
||||
double det = uvDir.Crossed( dirN );
|
||||
if ( Abs( det ) < std::numeric_limits<double>::min() ) continue;
|
||||
gp_XY dirN2Cur = curUV - uvN1;
|
||||
double step = dirN.Crossed( dirN2Cur ) / det;
|
||||
if ( step > 0 )
|
||||
stepSize = Min( step, stepSize );
|
||||
}
|
||||
|
||||
gp_Pnt2d newUV;
|
||||
if ( uvLen - stepSize < _len / 20. )
|
||||
if ( uvLen - stepSize < _len / 200. )
|
||||
{
|
||||
newUV = tgtUV;
|
||||
_pos.clear();
|
||||
}
|
||||
else if ( stepSize > 0 )
|
||||
{
|
||||
newUV = curUV + uvDir.XY() * stepSize * kSafe;
|
||||
}
|
||||
else
|
||||
{
|
||||
newUV = curUV + uvDir.XY() * stepSize;
|
||||
return true;
|
||||
}
|
||||
|
||||
SMDS_FacePosition* pos = static_cast<SMDS_FacePosition*>( tgtNode->GetPosition() );
|
||||
pos->SetUParameter( newUV.X() );
|
||||
pos->SetVParameter( newUV.Y() );
|
||||
@ -4177,30 +4341,24 @@ bool _SmoothNode::Smooth(int& badNb,
|
||||
|
||||
// compute new UV for the node
|
||||
gp_XY newPos (0,0);
|
||||
/* if ( how == ANGULAR && _simplices.size() == 4 )
|
||||
if ( how == TFI && _simplices.size() == 4 )
|
||||
{
|
||||
vector<gp_XY> corners; corners.reserve(4);
|
||||
gp_XY corners[4];
|
||||
for ( size_t i = 0; i < _simplices.size(); ++i )
|
||||
if ( _simplices[i]._nOpp )
|
||||
corners.push_back( helper.GetNodeUV( face, _simplices[i]._nOpp, _node ));
|
||||
if ( corners.size() == 4 )
|
||||
{
|
||||
newPos = helper.calcTFI
|
||||
( 0.5, 0.5,
|
||||
corners[0], corners[1], corners[2], corners[3],
|
||||
uv[1], uv[2], uv[3], uv[0] );
|
||||
}
|
||||
// vector<gp_XY> p( _simplices.size() * 2 + 1 );
|
||||
// p.clear();
|
||||
// for ( size_t i = 0; i < _simplices.size(); ++i )
|
||||
// {
|
||||
// p.push_back( uv[i] );
|
||||
// if ( _simplices[i]._nOpp )
|
||||
// p.push_back( helper.GetNodeUV( face, _simplices[i]._nOpp, _node ));
|
||||
// }
|
||||
// newPos = computeAngularPos( p, helper.GetNodeUV( face, _node ), refSign );
|
||||
corners[i] = helper.GetNodeUV( face, _simplices[i]._nOpp, _node );
|
||||
else
|
||||
throw SALOME_Exception(LOCALIZED("TFI smoothing: _Simplex::_nOpp not set!"));
|
||||
|
||||
newPos = helper.calcTFI ( 0.5, 0.5,
|
||||
corners[0], corners[1], corners[2], corners[3],
|
||||
uv[1], uv[2], uv[3], uv[0] );
|
||||
}
|
||||
else*/ if ( how == CENTROIDAL && _simplices.size() > 3 )
|
||||
else if ( how == ANGULAR )
|
||||
{
|
||||
newPos = computeAngularPos( uv, helper.GetNodeUV( face, _node ), refSign );
|
||||
}
|
||||
else if ( how == CENTROIDAL && _simplices.size() > 3 )
|
||||
{
|
||||
// average centers of diagonals wieghted with their reciprocal lengths
|
||||
if ( _simplices.size() == 4 )
|
||||
@ -4231,7 +4389,6 @@ bool _SmoothNode::Smooth(int& badNb,
|
||||
else
|
||||
{
|
||||
// Laplacian smooth
|
||||
//isCentroidal = false;
|
||||
for ( size_t i = 0; i < _simplices.size(); ++i )
|
||||
newPos += uv[i];
|
||||
newPos /= _simplices.size();
|
||||
@ -4249,8 +4406,6 @@ bool _SmoothNode::Smooth(int& badNb,
|
||||
|
||||
if ( nbOkAfter < nbOkBefore )
|
||||
{
|
||||
// if ( isCentroidal )
|
||||
// return Smooth( badNb, surface, helper, refSign, !isCentroidal, set3D );
|
||||
badNb += _simplices.size() - nbOkBefore;
|
||||
return false;
|
||||
}
|
||||
@ -4285,22 +4440,22 @@ gp_XY _SmoothNode::computeAngularPos(vector<gp_XY>& uv,
|
||||
{
|
||||
uv.push_back( uv.front() );
|
||||
|
||||
vector< gp_XY > edgeDir( uv.size() );
|
||||
vector< gp_XY > edgeDir ( uv.size() );
|
||||
vector< double > edgeSize( uv.size() );
|
||||
for ( size_t i = 1; i < edgeDir.size(); ++i )
|
||||
{
|
||||
edgeDir[i-1] = uv[i] - uv[i-1];
|
||||
edgeDir [i-1] = uv[i] - uv[i-1];
|
||||
edgeSize[i-1] = edgeDir[i-1].Modulus();
|
||||
if ( edgeSize[i-1] < numeric_limits<double>::min() )
|
||||
edgeDir[i-1].SetX( 100 );
|
||||
else
|
||||
edgeDir[i-1] /= edgeSize[i-1] * refSign;
|
||||
}
|
||||
edgeDir.back() = edgeDir.front();
|
||||
edgeDir.back() = edgeDir.front();
|
||||
edgeSize.back() = edgeSize.front();
|
||||
|
||||
gp_XY newPos(0,0);
|
||||
int nbEdges = 0;
|
||||
gp_XY newPos(0,0);
|
||||
int nbEdges = 0;
|
||||
double sumSize = 0;
|
||||
for ( size_t i = 1; i < edgeDir.size(); ++i )
|
||||
{
|
||||
@ -4320,7 +4475,7 @@ gp_XY _SmoothNode::computeAngularPos(vector<gp_XY>& uv,
|
||||
}
|
||||
bisec /= bisecSize;
|
||||
|
||||
gp_XY dirToN = uvToFix - p;
|
||||
gp_XY dirToN = uvToFix - p;
|
||||
double distToN = dirToN.Modulus();
|
||||
if ( bisec * dirToN < 0 )
|
||||
distToN = -distToN;
|
||||
|
@ -3,6 +3,31 @@
|
||||
<TS version="2.0" language="fr_FR">
|
||||
<context>
|
||||
<name>@default</name>
|
||||
<message>
|
||||
<source>SMESH_EDGES_WITH_LAYERS</source>
|
||||
<translation type="unfinished">Edges with layers</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>SMESH_FACES_WITH_LAYERS</source>
|
||||
<translation type="unfinished">Faces with layers
|
||||
(walls)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>SMESH_ADAPTIVE1D_TITLE</source>
|
||||
<translation type="unfinished">Hypothesis Construction</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>SMESH_MAX_SIZE</source>
|
||||
<translation type="unfinished">Max size</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>SMESH_MIN_SIZE</source>
|
||||
<translation type="unfinished">Min size</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>SMESH_ADAPTIVE1D_HYPOTHESIS</source>
|
||||
<translation type="unfinished">Adaptive</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>SMESH_ARITHMETIC_1D_HYPOTHESIS</source>
|
||||
<translation>Arithmétique 1D</translation>
|
||||
@ -486,4 +511,19 @@
|
||||
<translation>Pas</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>StdMeshersGUI_StdHypothesisCreator</name>
|
||||
<message>
|
||||
<source>TO_IGNORE_EDGES</source>
|
||||
<translation type="unfinished">Edges without layers (inlets and oulets)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>NOT_TO_IGNORE_EDGES</source>
|
||||
<translation type="unfinished">Edges with layers (walls)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>TO_IGNORE_EDGES_OR_NOT</source>
|
||||
<translation type="unfinished">Specified edges are</translation>
|
||||
</message>
|
||||
</context>
|
||||
</TS>
|
||||
|
@ -5,15 +5,15 @@
|
||||
<name>StdMeshersGUI_StdHypothesisCreator</name>
|
||||
<message>
|
||||
<source>TO_IGNORE_EDGES_OR_NOT</source>
|
||||
<translation>TO_IGNORE_EDGES_OR_NOT</translation>
|
||||
<translation>指定したエッジが</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>NOT_TO_IGNORE_EDGES</source>
|
||||
<translation>NOT_TO_IGNORE_EDGES</translation>
|
||||
<translation>エッジ層 (壁)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>TO_IGNORE_EDGES</source>
|
||||
<translation>TO_IGNORE_EDGES</translation>
|
||||
<translation>エッジ層 (入り江および oulets) なし</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
@ -46,6 +46,22 @@
|
||||
<source>SMESH_CUT_NEG_MODE</source>
|
||||
<translation>負のセクション</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>SMESH_ADAPTIVE1D_HYPOTHESIS</source>
|
||||
<translation>アダプティブ1次元Hypothesis</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>SMESH_MIN_SIZE</source>
|
||||
<translation>最小サイズ</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>SMESH_MAX_SIZE</source>
|
||||
<translation>最大サイズ</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>SMESH_ADAPTIVE1D_TITLE</source>
|
||||
<translation>Hypothesis構造</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>SMESH_DEFLECTION1D_HYPOTHESIS</source>
|
||||
<translation>変形 d</translation>
|
||||
@ -152,7 +168,7 @@
|
||||
</message>
|
||||
<message>
|
||||
<source>SMESH_MAX_LENGTH_HYPOTHESIS</source>
|
||||
<translation>最大長</translation>
|
||||
<translation>最大要素長</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>SMESH_CARTESIAN_PARAMS_HYPOTHESIS</source>
|
||||
@ -164,11 +180,11 @@
|
||||
</message>
|
||||
<message>
|
||||
<source>SMESH_VISCOUS_LAYERS_HYPOTHESIS</source>
|
||||
<translation>境界層</translation>
|
||||
<translation>境界層設定</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>SMESH_VISCOUS_LAYERS_TITLE</source>
|
||||
<translation>仮定の構成</translation>
|
||||
<translation>詳細設定</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>SMESH_TOTAL_THICKNESS</source>
|
||||
@ -180,23 +196,23 @@
|
||||
</message>
|
||||
<message>
|
||||
<source>SMESH_FACES_WO_LAYERS</source>
|
||||
<translation>顔なし層 limite\n (入力と出力)</translation>
|
||||
<translation>境界層 (入力と出力) のない顔</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>SMESH_EDGES_WO_LAYERS</source>
|
||||
<translation>エッジ層 limite\n (入力と出力) なし</translation>
|
||||
<translation>エッジ境界層 (入力と出力) なし</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>SMESH_FACES_WITH_LAYERS</source>
|
||||
<translation>SMESH_FACES_WITH_LAYERS</translation>
|
||||
<translation>面層 (壁)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>SMESH_EDGES_WITH_LAYERS</source>
|
||||
<translation>SMESH_EDGES_WITH_LAYERS</translation>
|
||||
<translation>レイヤーのエッジ</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>SMESH_MAX_LENGTH_TITLE</source>
|
||||
<translation>仮定の構成</translation>
|
||||
<translation>要素長設定</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>SMESH_CARTESIAN_PARAMS_TITLE</source>
|
||||
@ -224,7 +240,7 @@
|
||||
</message>
|
||||
<message>
|
||||
<source>SMESH_MAX_ELEMENT_VOLUME_TITLE</source>
|
||||
<translation>仮定の構成</translation>
|
||||
<translation>詳細設定</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>SMESH_NB_SEGMENTS_HYPOTHESIS</source>
|
||||
@ -352,7 +368,7 @@
|
||||
</message>
|
||||
<message>
|
||||
<source>SMESH_SOURCE_EDGE</source>
|
||||
<translation>エッジ</translation>
|
||||
<translation>Edge</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>SMESH_SOURCE_EDGES</source>
|
||||
@ -360,7 +376,7 @@
|
||||
</message>
|
||||
<message>
|
||||
<source>SMESH_SOURCE_FACE</source>
|
||||
<translation>フェース</translation>
|
||||
<translation>Face</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>SMESH_SOURCE_FACES</source>
|
||||
|
@ -129,14 +129,20 @@ class MGCleanerMonPlugDialog(Ui_MGCleanerPlugDialog,QWidget):
|
||||
self.connect(self.CB_ComputedOverlapDistance,SIGNAL("stateChanged(int)"),self.SP_OverlapDistance.setDisabled)
|
||||
|
||||
def PBHelpPressed(self):
|
||||
import SalomePyQt
|
||||
sgPyQt = SalomePyQt.SalomePyQt()
|
||||
try:
|
||||
mydir=os.environ["SMESH_ROOT_DIR"]
|
||||
except Exception:
|
||||
QMessageBox.warning( self, "Help", "Help unavailable $SMESH_ROOT_DIR not found")
|
||||
return
|
||||
maDoc=mydir+"/share/doc/salome/gui/SMESH/MGCleaner/_downloads/mg-cleaner_user_manual.pdf"
|
||||
command="xdg-open "+maDoc+";"
|
||||
subprocess.call(command, shell=True)
|
||||
|
||||
maDoc=mydir+"/share/doc/salome/gui/SMESH/MGCleaner/index.html"
|
||||
sgPyQt.helpContext(maDoc,"")
|
||||
|
||||
#maDoc=mydir+"/share/doc/salome/gui/SMESH/MGCleaner/_downloads/mg-cleaner_user_manual.pdf"
|
||||
#command="xdg-open "+maDoc+";"
|
||||
#subprocess.call(command, shell=True)
|
||||
|
||||
def PBOKPressed(self):
|
||||
if not(self.PrepareLigneCommande()):
|
||||
|
Binary file not shown.
@ -6,8 +6,8 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>800</width>
|
||||
<height>500</height>
|
||||
<width>791</width>
|
||||
<height>593</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
@ -339,7 +339,7 @@ In other words, it avoids having faces too far away from the curve they should r
|
||||
</rect>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>If the Units parameter is relative, epsilon max correspond to (per thousand) s*Tolerance/1000, where s is the size of the bounding box of the domain.
|
||||
<string>If the Units parameter is relative, epsilon max correspond to s*Tolerance, where s is the size of the bounding box of the domain.
|
||||
If the Units parameter is absolute, the tolerance parameter is expressed in model units:
|
||||
if P=2 and point coordinates are given in millimeters, the maximal chordal deviation is 2 mm.</string>
|
||||
</property>
|
||||
@ -599,13 +599,13 @@ New created vertices are saved in the .mesh file under keyword section 'Vertices
|
||||
</rect>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<double>0.890000000000000</double>
|
||||
<double>90.000000000000000</double>
|
||||
</property>
|
||||
<property name="singleStep">
|
||||
<double>0.010000000000000</double>
|
||||
<double>1.000000000000000</double>
|
||||
</property>
|
||||
<property name="value">
|
||||
<double>0.040000000000000</double>
|
||||
<double>15.000000000000000</double>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLabel" name="label_2">
|
||||
|
@ -1,16 +1,19 @@
|
||||
Advanced Remeshing Options
|
||||
==========================
|
||||
|
||||
** be aware that no control of coherency is done when you set these parameters : for instance, geometrical approximation is only allowed when yams compute a mesh for finite elements but the GUI will let you choose geometrical approximation and compute a visualisation mesh. read DISTENE documentation **
|
||||
.. note::
|
||||
Be aware that no control of coherency is done when you set these parameters : for instance, geometrical approximation is only allowed when SurfOpt computes a mesh for finite elements but the GUI will let you choose geometrical approximation and compute a visualisation mesh. See Distene's documentation for more details :
|
||||
:download:`MeshGems-SurfOpt: The automatic surface remeshing tool of the MeshGems Suite <files/mg-surfopt_user_manual.pdf>`.
|
||||
|
||||
- **Ridge detection**
|
||||
|
||||
- **Ridge detection**
|
||||
if not set (ridge detection disabled ), MeshGems-SurfOpt will not try to detect any new ridge edge by its own mechanism :
|
||||
it will consider as ridge only the ridges given in the mesh. All non-ridge edges that would have been detected as ridge by the Ridge angle paramaeter (see below split edge) will be considered as part of the same continuous patch. This option should not be checked when all the known ridges of the mesh are given and when all other possible ridges are not geometric ridges to take into account.
|
||||
|
||||
- **Point smoothing**
|
||||
- **Point smoothing**
|
||||
When not set (point smoothing is disabled), MeshGems-SurfOpt will not try to move the initial given vertices (along an edge, a ridge or onto the surface), hence MeshGems-SurfOpt will only swap edges, remove vertices or add vertices (refines) to change the mesh.
|
||||
|
||||
- **Geometrical approximation**
|
||||
- **Geometrical approximation**
|
||||
this field as well as the Chordal deviation tolerance parameter,enables the user to bound the maximal chordal deviation allowed. it avoids having sharp angles. , that is, the maximal distance allowed between the detected curve and the plane of the corresponding mesh face. It avoids having faces too far away from the curve they represent.
|
||||
|
||||
.. image:: images/Tolerance.png
|
||||
@ -20,23 +23,23 @@ this field as well as the Chordal deviation tolerance parameter,enables the user
|
||||
This parameter P enables the user to specify the maximal chordal deviation E relatively to the local curvature. the maximal chordal deviation will be set to E=P x r (r is the radius of the circumcercle) if the units parameter is set to relative or E=P if the units parameter is set to absolute.
|
||||
|
||||
|
||||
- **Ridge angle**
|
||||
- **Ridge angle**
|
||||
|
||||
This parameter specifies the angular values for the automatic detection of ridges and corners. A ridge is automatically detected if the angle between the normal vectors of two adjacent faces exceeds this value.
|
||||
|
||||
|
||||
- **Maximal/Minimal size around vertices**
|
||||
- **Maximal/Minimal size around vertices**
|
||||
|
||||
These two parameters allow the user to prescribe a Maximal/Minimal size for the mesh elements, ie the lengths of the edges.
|
||||
|
||||
|
||||
- **Mesh gradation**
|
||||
- **Mesh gradation**
|
||||
This paramater P controls the element size variation : MeshGems-SurfOpt will avoid having two adjacent egdes which sizes vary more than th given gradation. a size correction is applied to the size map : if two adjacent edges are respectively e1 and e2 long and e2 > Pxe1, then, the new size for the second edge will be set to P x e1.
|
||||
**This procedure is desactived if P=-1***
|
||||
**This procedure is desactived if P=-1**
|
||||
|
||||
|
||||
|
||||
- **Split edge**
|
||||
- **Split edge**
|
||||
If this option is activated, MeshGems-SurfOpt creates new vertices placed on the curved surface and adds them to elements.
|
||||
It may be used to obtain higher order elements.
|
||||
|
||||
|
@ -10,12 +10,12 @@ This parameter (between 0 and 10) indicates the amount of information that MeshG
|
||||
|
||||
|
||||
- **Memory Size**
|
||||
You usually don't have to set this parameter but you can choose to limit the amount of memory used by MeshGems-SurfOpt. - It requires 370 bytes per node -. Or, if you try to enrich a already big mesh (up to 2 millions nodes), you exceptionally, need to allocate more memory.
|
||||
You usually don't have to set this parameter but you can choose to limit the amount of memory used by MeshGems-SurfOpt -- It requires 370 bytes per node. Or, if you try to enrich a already big mesh (up to 2 millions nodes), you exceptionally, need to allocate more memory.
|
||||
|
||||
|
||||
- **File**
|
||||
|
||||
You can change the file used to store remeshing hypotheses. see paragraph :ref:`hypothesis-label` for further informations.
|
||||
You can change the file used to store remeshing hypotheses, see :ref:`hypothesis-label` for further informations.
|
||||
|
||||
.. image:: images/Generic.png
|
||||
:align: center
|
||||
|
@ -1,7 +1,7 @@
|
||||
Simple Remeshing Options
|
||||
=========================
|
||||
|
||||
simple case
|
||||
Simple case
|
||||
-----------
|
||||
|
||||
All options, but the input mesh, have default values. however, **you have to specify these
|
||||
@ -42,7 +42,7 @@ This is the main remeshing Option. SurfOpt always does quality improvement. It
|
||||
|
||||
It is equivalent to SurfOpt's batch option *- - uniform_flat_subdivision yes*.
|
||||
|
||||
- **Smoothing**
|
||||
- **Sandpapering**
|
||||
|
||||
A surface sandpapering without shrinkage of the given surface triangulation is performed, i.e., the high curvature variations of the given surface will be smoothed out without shrinking the volume in doing so. If ridges are defined, they will be kept as they are in the resulting mesh. It could modify the geometry.
|
||||
It is equivalent to SurfOpt's batch option *- - sand_paper yes*.
|
||||
|
BIN
src/Tools/YamsPlug/doc/files/mg-surfopt_user_manual.pdf
Normal file
BIN
src/Tools/YamsPlug/doc/files/mg-surfopt_user_manual.pdf
Normal file
Binary file not shown.
Binary file not shown.
Before Width: | Height: | Size: 39 KiB After Width: | Height: | Size: 34 KiB |
Binary file not shown.
Before Width: | Height: | Size: 63 KiB After Width: | Height: | Size: 48 KiB |
@ -76,7 +76,7 @@ class MonYamsPlugDialog(Ui_YamsPlugDialog,QWidget):
|
||||
v1=QDoubleValidator(self)
|
||||
v1.setBottom(0.)
|
||||
#v1.setTop(1000.) #per thousand... only if relative
|
||||
v1.setDecimals(2)
|
||||
v1.setDecimals(3)
|
||||
self.SP_Tolerance.setValidator(v1)
|
||||
self.SP_Tolerance.titleForWarning="Chordal Tolerance"
|
||||
|
||||
@ -102,14 +102,20 @@ class MonYamsPlugDialog(Ui_YamsPlugDialog,QWidget):
|
||||
self.connect(self.LE_ParamsFile,SIGNAL("returnPressed()"),self.paramsFileNameChanged)
|
||||
|
||||
def PBHelpPressed(self):
|
||||
import SalomePyQt
|
||||
sgPyQt = SalomePyQt.SalomePyQt()
|
||||
try :
|
||||
mydir=os.environ["SMESH_ROOT_DIR"]
|
||||
except Exception:
|
||||
QMessageBox.warning(self, "Help", "Help unavailable $SMESH_ROOT_DIR not found")
|
||||
return
|
||||
maDoc=mydir+"/share/doc/salome/gui/SMESH/yams/_downloads/mg-surfopt_user_manual.pdf"
|
||||
command="xdg-open "+maDoc+";"
|
||||
subprocess.call(command, shell=True)
|
||||
|
||||
maDoc=mydir+"/share/doc/salome/gui/SMESH/yams/index.html"
|
||||
sgPyQt.helpContext(maDoc,"")
|
||||
|
||||
#maDoc=mydir+"/share/doc/salome/gui/SMESH/yams/_downloads/mg-surfopt_user_manual.pdf"
|
||||
#command="xdg-open "+maDoc+";"
|
||||
#subprocess.call(command, shell=True)
|
||||
|
||||
def PBOKPressed(self):
|
||||
if not(self.PrepareLigneCommande()):
|
||||
@ -401,7 +407,11 @@ class MonYamsPlugDialog(Ui_YamsPlugDialog,QWidget):
|
||||
|
||||
mySObject, myEntry = guihelper.getSObjectSelected()
|
||||
if CORBA.is_nil(mySObject) or mySObject==None:
|
||||
QMessageBox.critical(self, "Mesh", "select an input mesh")
|
||||
#QMessageBox.critical(self, "Mesh", "select an input mesh")
|
||||
self.LE_MeshSmesh.setText("")
|
||||
self.MeshIn=""
|
||||
self.LE_MeshFile.setText("")
|
||||
self.fichierIn=""
|
||||
return
|
||||
self.smeshStudyTool = SMeshStudyTools()
|
||||
try:
|
||||
@ -477,7 +487,7 @@ class MonYamsPlugDialog(Ui_YamsPlugDialog,QWidget):
|
||||
if self.SP_MinSize.value() != 5 : self.commande+=" --min_size %f" %self.SP_MinSize.value()
|
||||
if self.SP_Gradation.value() != 1.3 : self.commande+=" --gradation %f" %self.SP_MaxSize.value()
|
||||
if self.SP_Memory.value() != 0 : self.commande+=" --max_memory %d" %self.SP_Memory.value()
|
||||
if self.SP_Verbosity.value() != 3 : self.commande+=" --max_memory %d" %self.SP_Verbosity.value()
|
||||
if self.SP_Verbosity.value() != 3 : self.commande+=" --verbose %d" %self.SP_Verbosity.value()
|
||||
|
||||
self.commande+=" --in " + self.fichierIn
|
||||
self.commande+=" --out " + self.fichierOut
|
||||
@ -503,22 +513,24 @@ class MonYamsPlugDialog(Ui_YamsPlugDialog,QWidget):
|
||||
self.CB_Ridge.setChecked(True)
|
||||
self.CB_Point.setChecked(True)
|
||||
self.CB_SplitEdge.setChecked(False)
|
||||
self.SP_MaxSize.setProperty("value", -2.0)
|
||||
self.SP_MinSize.setProperty("value", -2.0)
|
||||
self.SP_MaxSize.setProperty("value", 100)
|
||||
self.SP_MinSize.setProperty("value", 5)
|
||||
self.SP_Verbosity.setProperty("value", 3)
|
||||
self.SP_Memory.setProperty("value", 0)
|
||||
self.PBMeshSmeshPressed()
|
||||
self.TWOptions.setCurrentIndex(0) # Reset current active tab to the first tab
|
||||
|
||||
__dialog=None
|
||||
def getDialog():
|
||||
"""
|
||||
This function returns a singleton instance of the plugin dialog.
|
||||
c est obligatoire pour faire un show sans parent...
|
||||
It is mandatory in order to call show without a parent ...
|
||||
"""
|
||||
global __dialog
|
||||
if __dialog is None:
|
||||
__dialog = MonYamsPlugDialog()
|
||||
#else :
|
||||
# __dialog.clean()
|
||||
else :
|
||||
__dialog.clean()
|
||||
return __dialog
|
||||
|
||||
#
|
||||
|
Loading…
Reference in New Issue
Block a user