# Modified by : Alexander BORODIN (OCN) - autotools usage
# Created from configure.in.base
#
-AC_INIT([Salome2 Project SMESH module], [5.1.4], [webmaster.salome@opencascade.com], [SalomeSMESH])
+AC_INIT([Salome2 Project SMESH module], [5.1.5], [webmaster.salome@opencascade.com], [SalomeSMESH])
AC_CONFIG_AUX_DIR(adm_local/unix/config_files)
AC_CANONICAL_HOST
AC_CANONICAL_TARGET
# chmod +x ./bin/salome/*; \
#])
+AC_CONFIG_COMMANDS([hack_libtool],[
+sed -i "s%^CC=\"\(.*\)\"%hack_libtool (){ \n\
+ if test \"\$(echo \$[@] | grep -E '\\\-L/usr/lib(/../lib)?(64)? ')\" == \"\" \n\
+ then\n\
+ cmd=\"\1 \$[@]\"\n\
+ else\n\
+ cmd=\"\1 \"\`echo \$[@] | sed -r -e 's|(.*)-L/usr/lib(/../lib)?(64)? (.*)|\\\1\\\4 -L/usr/lib\\\3|g'\`\n\
+ fi\n\
+ \$cmd\n\
+}\n\
+CC=\"hack_libtool\"%g" libtool
+],[])
+
# This list is initiated using autoscan and must be updated manually
# when adding a new file <filename>.in to manage. When you execute
# autoscan, the Makefile list is generated in the output file configure.scan.
idl/Makefile \
Makefile
])
-
-AC_HACK_LIBTOOL
PAPEROPT_a4 = -D latex_paper_size=a4
ALLSPHINXOPTS = -d doctrees $(PAPEROPT_a4) $(SPHINXOPTS) $(SOURCEDIR)
-SPHINX_PYTHONPATH = $(prefix)/lib/python$(PYTHON_VERSION)/site-packages/salome:$(KERNEL_ROOT_DIR)/bin/salome:$(KERNEL_ROOT_DIR)/lib/python$(PYTHON_VERSION)/site-packages/salome:$(OMNIORB_ROOT)/lib/python$(PYTHON_VERSION)/site-packages
+SPHINX_PYTHONPATH = $(prefix)/lib/python$(PYTHON_VERSION)/site-packages/salome:$(prefix)/lib64/python$(PYTHON_VERSION)/site-packages/salome:$(KERNEL_ROOT_DIR)/bin/salome:$(KERNEL_ROOT_DIR)/lib/python$(PYTHON_VERSION)/site-packages/salome:$(KERNEL_ROOT_DIR)/lib64/python$(PYTHON_VERSION)/site-packages/salome:$(OMNIORB_ROOT)/lib/python$(PYTHON_VERSION)/site-packages:$(OMNIORB_ROOT)/lib64/python$(PYTHON_VERSION)/site-packages
SPHINX_LD_LIBRARY_PATH = $(KERNEL_ROOT_DIR)/lib/salome:$(OMNIORB_ROOT)/lib
usr_docs: doxyfile_py doxyfile
- echo "===========================================" ; \
- echo "Generating Python interface documentation"; \
- echo "===========================================" ; \
- $(DOXYGEN) doxyfile_py ; \
- echo "===========================================" ; \
- echo "Replacing smeshDC by smesh" ; \
- echo "===========================================" ; \
- files=`find smeshpy_doc -type f` ; \
- for filen in $${files} ; do \
- sed -e "s/\<smeshDC\>/smesh/g" -e "s/smesh\.smesh/smesh/g" \
- -e "s/smesh::smesh/smesh/g" $${filen} > $${filen}_ ; \
- mv -f $${filen}_ $${filen} ; \
- done ; \
- echo "===========================================" ; \
- echo "Generating GUI documentation" ; \
- echo "===========================================" ; \
- $(DOXYGEN) doxyfile ;
+ echo "===========================================" ; \
+ echo "Replacing smeshDC by smesh" ; \
+ echo "===========================================" ; \
+ sed -e "/class smeshDC/d" -e "s/^ *#/#/g" -e "s/^ *def /def /g" \
+ -e "s/smeshDC/smesh/g" $(top_srcdir)/src/SMESH_SWIG/smeshDC.py > \
+ $(top_builddir)/src/SMESH_SWIG/smesh.py ; \
+ echo "===========================================" ; \
+ echo "Generating Python interface documentation"; \
+ echo "===========================================" ; \
+ $(DOXYGEN) doxyfile_py ; \
+ echo "===========================================" ; \
+ echo "Generating GUI documentation" ; \
+ echo "===========================================" ; \
+ $(DOXYGEN) doxyfile ; \
+ rm -f $(top_builddir)/src/SMESH_SWIG/smesh.py
docs: usr_docs
#---------------------------------------------------------------------------
#Input related options
#---------------------------------------------------------------------------
-INPUT = @top_srcdir@/src/SMESH_SWIG
-FILE_PATTERNS = smeshDC.py
+INPUT = @top_builddir@/src/SMESH_SWIG
+FILE_PATTERNS = smesh.py
IMAGE_PATH = @srcdir@/images
RECURSIVE = NO
EXAMPLE_PATH = @top_srcdir@/src/SMESH_SWIG
<br>
<ul>
<li>\ref arithmetic_1d_anchor "Arithmetic 1D"</li>
-<li>\ref average_length_anchor "Average Length"</li>
+<li>\ref average_length_anchor "Local Length"</li>
<li>\ref max_length_anchor "Max Size"</li>
<li>\ref deflection_1d_anchor "Deflection 1D"</li>
<li>\ref number_of_segments_anchor "Number of segments"</li>
<br>
\anchor average_length_anchor
-<h2>Average Length hypothesis</h2>
+<h2>Local Length hypothesis</h2>
-<b>Average Length</b> hypothesis can be applied for meshing of edges
+<b>Local Length</b> hypothesis can be applied for meshing of edges
composing your geometrical object. Definition of this hypothesis
consists of setting the \b length of segments, which will split these
edges, and the \b precision of rounding. The points on the edges
\image html a-averagelength.png
-\image html b-erage_length.png "Average length hypothesis - all 1D mesh elements are roughly equal"
+\image html b-erage_length.png "Local Length hypothesis - all 1D mesh elements are roughly equal"
<b>See Also</b> a sample TUI Script of a
-\ref tui_average_length "Defining Average Length" hypothesis
+\ref tui_average_length "Defining Local Length" hypothesis
operation.
<br>\anchor max_length_anchor
<b>Start and End Length</b> hypothesis allows to divide a geometrical edge
into segments so that the first and the last segments have a specified
-length. The length medium segments changes with automatically chosen
+length. The length of medium segments changes with automatically chosen
geometric progression. Then mesh nodes are
constructed at segment ends location and 1D mesh elements are
constructed on them.
\anchor hypo_quad_params_anchor
<h2>Quadrangle parameters</h2>
-<b>Quadrangle parameters</b> is a hypothesis for
-Quadrangle (Mapping), which allows using this algorithm for meshing of
-triangular faces.In this case it is necessary to select the <b>Base vertex</b>
-used as a degenerated edge.
+\image html hypo_quad_params_dialog.png "Quadrangle parameters creation/edition dialog"
+
+<b>Quadrangle parameters</b> is a hypothesis for Quadrangle (Mapping).
+
+<b>Base vertex</b> parameter allows using Quadrangle (Mapping)
+algorithm for meshing of triangular faces. In this case it is
+necessary to select the vertex, which will be used as the fourth edge
+(degenerated).
\image html hypo_quad_params_1.png "A face built from 3 edges"
\image html hypo_quad_params_res.png "The resulting mesh"
-This hypothesis can be also used to mesh a segment of a circular face.
-Please, consider that there is a limitation on the selectiion of the degenerated
+This parameter can be also used to mesh a segment of a circular face.
+Please, consider that there is a limitation on the selection of the
vertex for the faces built with the angle > 180 degrees (see the picture).
\image html hypo_quad_params_2.png "3/4 of a circular face"
-In this case, selection of a wrong vertex for the <b>Quadrangle parameters</b>
-hypothesis will generate a wrong mesh. The picture below
+In this case, selection of a wrong vertex for the <b>Base vertex</b>
+parameter will generate a wrong mesh. The picture below
shows the good (left) and the bad (right) results of meshing.
\image html hypo_quad_params_res_2.png "The resulting meshes"
+<b>Type</b> parameter is used on faces with a different number of
+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
+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.</li>
+</ul>
+
<b>See Also</b> a sample TUI Script of a
\ref tui_quadrangle_parameters "Quadrangle Parameters" hypothesis.
\page filters_page About filters
-\b Filters allows to pick only those mesh elements which satisfy to
-specific condition or set of conditions. Filters can be used to create
+\b Filters allow picking only the mesh elements satisfying to a
+specific condition or a set of conditions. Filters can be used to create
or edit mesh groups, remove elements from the mesh object, control
mesh quality by different parameters, etc.
modes:
- In GUI, filters are available in some dialog boxes via an additional
-"Set Filters" button, clicking on which opens specific dialog box
+"Set Filters" button, clicking on which opens the dialog box
allowing to specify the list of filter criterions to be applied to the
-current selection. Follow to the \subpage selection_filter_library_page page to learn more
+current selection. See \subpage selection_filter_library_page page to learn more
about selection filters and their usage in GUI.
-- In Python scripts, filters can be used to choose only some of mesh
- entities (nodes and/or elements) for the operations which require
- list of the entities as input parameter (create/modify group, remove
+- In Python scripts, filters can be used to choose only some mesh
+ entities (nodes and/or elements) for the operations, which require the
+ list of entities as input parameter (create/modify group, remove
nodes/elements, etc). The page \ref tui_filters_page provides
- examples of the filters usage in the Python scripts.
-
+ examples of the filters usage in Python scripts.
*/
<b>edges</b>):</li>
<ul>
<li>\ref arithmetic_1d_anchor "Arithmetic 1D"</li>
-<li>\ref average_length_anchor "Average Length"</li>
+<li>\ref average_length_anchor "Local Length"</li>
<li>\ref max_length_anchor "Max Size"</li>
<li>\ref deflection_1d_anchor "Deflection 1D"</li>
<li>\ref number_of_segments_anchor "Number of segments"</li>
From this submenu select the type of element which you would like to add to your mesh.
-\note All dialogs for adding new node or element to the mesh (except for
-the dialog for 0D elements) provide a possibility to add it
-automatically to the specified group or to create it anew using
-<b>Add to group</b> box, that allows to choose an existing group for
-the created node or element or to give the name to a new group. By
-default, the <b>Add to group</b> check box is switched off. If user
+\note All dialogs for new node or element adding to the mesh (except for
+the dialog for 0D elements) provide the possibility to automatically add
+a node or element to the specified group or to create the anew using
+<b>Add to group</b> box, that allows choosing an existing group for
+the created node or element or giving the name to a new group. By
+default, the <b>Add to group</b> check box is switched off. If the user
swiches this check box on, the combo box listing all currently
existing groups of the corresponding type becomes available. By
-default, no any group is selected. In such a case, when user presses
+default, no group is selected. In this case, when the user presses
<b>Apply</b> or <b>Apply & Close</b> button, the warning message box
-informing the user about the necessity to input new group name is
-shown. The combo box lists both \ref standalone_group "standalone groups"
-and \ref group_on_geom "groups on geometry". If the user has
-chosen the group on geometry, he is warned and proposed to
-\ref convert_to_standalone "convert this group to the standalone".
-If user refuses converting operation, an operation is cancelled and
-new node/element is not created!
+informs the user about the necessity to input new group name. The
+combo box lists both \ref standalone_group "standalone groups"
+and \ref group_on_geom "groups on geometry". If the user chooses a
+group on geometry, he is warned and proposed to
+\ref convert_to_standalone "convert this group to standalone".
+If the user rejects conversion operation, it is cancelled and
+a new node/element is not created!
</ol>
\image html image152.png
-\note All dialogs for adding quadratic element to the mesh
-provide a possibility to add new element
-automatically to the specified group or to create it anew using
-<b>Add to group</b> box, that allows to choose an existing group for
-the created node or element or to give the name to a new group. By
-default, the <b>Add to group</b> check box is switched off. If user
+\note All dialogs for quadratic element adding to the mesh
+provide the possibility to automatically add an element
+to the specified group or to create the group anew using
+<b>Add to group</b> box, that allows choosing an existing group for
+the created node or element or giving the name to a new group. By
+default, the <b>Add to group</b> check box is switched off. If the user
swiches this check box on, the combo box listing all currently
existing groups of the corresponding type becomes available. By
-default, no any group is selected. In such a case, when user presses
+default, no group is selected. In this case, when the user presses
<b>Apply</b> or <b>Apply & Close</b> button, the warning message box
-informing the user about the necessity to input new group name is
-shown. The combo box lists both \ref standalone_group "standalone groups"
-and \ref group_on_geom "groups on geometry". If the user has
-chosen the group on geometry, he is warned and proposed to
-\ref convert_to_standalone "convert this group to the standalone".
-If user refuses converting operation, an operation is cancelled and
-new node/element is not created!
+informs the user about the necessity to input a new group name. The
+combo box lists both \ref standalone_group "standalone groups"
+and \ref group_on_geom "groups on geometry". If the user chooses a
+group on geometry, he is warned and proposed to
+\ref convert_to_standalone "convert this group to standalone".
+If the user rejects conversion operation, it is cancelled and
+a new quadratic element is not created.
To create any <b>Quadratic Element</b> specify the nodes which will form your
It allows Quadrangle (Mapping) to build quadrangular meshes even if the number
of nodes at the opposite edges of a meshed face is not equal,
-otherwise this mesh will contain some triangular elements.
+otherwise this mesh will contain some triangular elements. <i>This use
+case is obsolete now. Use <b>Quadrangle Parameters</b> hypothesis with
+type <b>Quadrangle Preference</b> set instead.</i>
<br>
This hypothesis has one restriction on its work: the total quantity of
segments on all four sides of the face must be even (divisible by 2).
-<h2>Triangle Preference</h2>
+<h2>Triangle Preference <i>(obsolete)</i></h2>
This additional hypothesis can be used only together with Quadrangle (Mapping)
algorithm. It allows to build triangular mesh faces in the refinement
area if the number of nodes at the opposite edges of a meshed face is not equal,
otherwise refinement area will contain some quadrangular elements.
-
+<i>This hypothesis is obsolete now. Use <b>Quadrangle Parameters</b>
+hypothesis with type <b>Triangle Preference</b> set instead.</i>
*/
\anchor standalone_group <br><h2>"Standalone Group"</h2>
<b>Standalone Group</b> consists of mesh elements, which you can define in
-the next possible ways:
+the following ways:
<ul>
<li>Choosing them manually with the mouse in the 3D Viewer. You can
click on an element in the 3D viewer and it will be highlighted. After
about filters on the
\ref selection_filter_library_page "Selection filter library" page.</li>
<li>By adding all existing entities of the chosen type to the
-group. For this purpose, it is necessary to turn on the <b>Select
-All</b> check box. In this mode, all controls which allow selection of
-the entities manually or by filters, are disabled.</li>
+group. For this turn on the <b>Select All</b> check box. In this
+mode all controls, which allow selecting the entities manually or by filters, are disabled.</li>
</ul>
To remove a selected element or elements from the list click the
\b Remove button. The <b>Sort List</b> button allows to sort the list of IDs of
/*!
-\page double_nodes_page Duplicating Nodes
+\page double_nodes_page Duplicate Nodes
\n This operation allows to duplicate nodes of your mesh.
+Duplication consists in replacement of an existing mesh element by another one.
+Lower level elements of the duplicated ones are cloned
+automatically.
<em>To duplicate nodes:</em>
<ol>
\image html duplicate01.png
Parameters to be defined in this mode:
-<ol>
+<ul>
<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 duplicated nodes
will be associated with these elements.</li>
<li><b>Construct group with newly created nodes</b> option (<em>checked by default</em>):
- if checked - the group with just created nodes will be builded.</li>
-</ol>
+ if checked - the group with just created nodes will be built.</li>
+</ul>
<br>
\anchor mode_with_elem_anchor
\image html duplicate02.png
Parameters to be defined in this mode:
-<ol>
+<ul>
<li><b>Group of elements to duplicate</b> (<em>mandatory</em>): these elements will be duplicated.</li>
<li><b>Group of nodes at not to duplicate</b> (<em>optional</em>): group of nodes at crack bottom
which will not be duplicated.</li>
<li><b>Group of elements to replace nodes with new ones</b> (<em>mandatory</em>): the duplicated nodes
will be associated with these elements.</li>
<li><b>Construct group with newly created elements</b> option (<em>checked by default</em>):
- if checked - the group with just created elements will be builded.</li>
-</ol>
+ if checked - the group with just created elements will be built.</li>
+</ul>
<br><b>See Also</b> a sample TUI Script of a \ref tui_duplicate_nodes "Duplicate nodes" operation.
Almost all mesh module functionalities are accessible via
\subpage smeshpy_interface_page "Mesh module Python interface".
+Also it can be useful to have a look at the
+\subpage smeshpypkg_page "documentation on SMESH python package".
+
+
\image html image7.jpg "Example of MESH module usage for engineering tasks"
*/
/*!
-\page make_2dmesh_from_3d_page Generate the skin elements (2D) of a mesh having 3D elements
+\page make_2dmesh_from_3d_page Generate boundary elements
-\n This functionality allows to generate 2D mesh elements as a skin
-on the existing 3D mesh elements.
+\n This functionality allows to generate mesh elements on the borders of
+elements of a higher dimension.
-<em>To generate 2D mesh:</em>
+<em>To generate border elements:</em>
<ol>
-<li>From the Modification menu choose "Create 2D mesh from 3D"
-item, or choose from the popup menu.
+<li>From the Modification menu choose "Create boundary elements"
+item, or click "Create boundary elements" button in the toolbar
-\image html 2d_from_3d_menu.png
+\image html 2d_from_3d_ico.png "Create boundary elements icon"
-The algorithm detects boundary volume faces without connections to
-other volumes and creates 2D mesh elements on face nodes. If the mesh
-already contains 2D elements on the detected nodes, new elements are not
-created. The the resulting dialog shows mesh information statistics
-about the newly created 2D mesh elements.
+The following dialog box will appear:
+\image html 2d_from_3d_dlg.png "Create boundary elements dialog box".
+</li>
+<li>Check in the dialog box one of three radio buttons corresponding to
+the type of operation you would like to perform.</li>
+<li>Fill the other fields available in the dialog box.</li>
+<li>Click the \b Apply or <b>Apply and Close</b> button to perform the operation.</li>
</ol>
+\n "Create boundary elements" dialog allows creation of boundary elements
+of three types.
+<ul>
+<li><b>2D from 3D</b> creates mesh faces on free facets of volume elements</li>
+<li><b>1D from 2D</b> creates mesh edges on free edges of mesh faces</li>
+<li><b>1D from 3D</b> creates mesh edges on all borders of free facets of volume elements</li>
+</ul>
+Here a <em>free facet</em> means a facet shared by only one volume, a <em>free edge</em>
+means an edge shared by only one mesh face.
+
+In this dialog:
+<ul>
+<li>specify the <b>Mesh, submesh or group</b>, the boundary which of
+will be analyzed.</li>
+<li>specify the <b>Target</b> mesh, where the boundary elements will
+ be created.
+ <ul>
+ <li><b>This mesh</b> adds elements in the selected mesh or the mesh
+ the selected submesh or group belongs to.</li>
+ <li><b>New mesh</b> adds elements to a new mesh. The new mesh appears
+ in the Object Browser with the name that you can change in the adjacent box. </li>
+ </ul></li>
+<li>activate <b>Copy source mesh</b> checkbox to copy 2D or 3D
+ elements (depending on the operation type), which belong to the analyzed
+<b>Mesh, submesh or group</b> field, to the new mesh.</li>
+<li>deactivate <b>Copy missing elements only</b> checkbox to copy
+ boundary elements already present in the analyzed mesh to the
+ new mesh.</li>
+<li>activate <b>Create group</b> checkbox to create a group to which the
+ missing boundary elements are added. The new group appears
+ in the Object Browser with the name that you can change in the adjacent box. </li>
+</ul>
+<br><b>See Also</b> a sample TUI Script of a \ref tui_make_2dmesh_from_3d "Create boundary elements" operation.
+
*/
its elements.</li>
<li>\subpage rotation_page "Rotate" by the indicated axis and angle
the mesh or some of its elements.</li>
-<li>\subpage scale_page "Scale Transform" the mesh or some of its elements.</li>
+<li>\subpage scale_page "Scale Transform" the mesh or some of its
+elements.</li>
+<li>\subpage double_nodes_page "Duplicate nodes".</li>
<li>Create a \subpage symmetry_page "symmetrical copy" of the mesh
through a point or a vector of symmetry.</li>
<li>Unite meshes by \subpage sewing_meshes_page "sewing" free borders,
<li>Apply \subpage pattern_mapping_page "pattern mapping".</li>
<li>\subpage convert_to_from_quadratic_mesh_page "Convert regular mesh to quadratic",
or vice versa.</li>
-<li>Create \subpage double_nodes_page "double nodes".</li>
-<li>\subpage make_2dmesh_from_3d_page "Create 2D mesh from 3D".</li>
+<li>\subpage make_2dmesh_from_3d_page "Generate boundary elements".</li>
</ul>
- <b>Number of Segments</b> has the same sense as \ref
number_of_segments_anchor "Number of segments" hypothesis with
equidistant distribution.
-- <b>Average Length</b> has the same sense as \ref
-average_length_anchor "Average Length" hypothesis.
+- <b>Local Length</b> has the same sense as \ref
+average_length_anchor "Local Length" hypothesis.
\b 2D group allows defining the size of 2D elements
- <b>Length from edges</b> if checked in, acts like \ref
<br><h2>About patterns</h2>
The pattern describes a mesh to generate: positions of nodes within a
-geometrical domain and nodal connectivity of elements. As well, a
-pattern specifies the so-called key-points, i.e. nodes that will be
-located at geometrical vertices. Pattern description is stored in
+geometrical domain and nodal connectivity of elements. A
+pattern also specifies the so-called key-points, i.e. the nodes that will be
+located at geometrical vertices. The pattern description is stored in
\<pattern_name\>.smp file.
The smp file contains 4 sections:
--# The first line holds the total number of the pattern nodes (N).
--# The next N lines describe nodes coordinates. Each line holds 2
-coordinates of a node for 2D pattern or 3 cordinates for 3D pattern.
-Note, that for 3D pattern only relateive values in range [0;1] are
-valid for coordinates of the nodes.
--# A key-points line: indices of nodes to be mapped on geometrical
-vertices (for 2D pattern only). An index n refers to a node described
-on an n-th line of section 2. The first node index is zero. For 3D
-pattern key points are not specified.
--# The rest lines describe nodal connectivity of elements, one line
-for an element. A line holds indices of nodes forming an element. An
-index n refers to a node described on an n-th line of the section
-2. The first node index is zero. There must be 3 or 4 indices on a
-line for 2D pattern (only 2d elements are allowed) and 4, 5, 6 or 8
-indices for 3D pattern (only 3d elements are allowed).
-
-The 2D pattern must contain at least one element and at least one
-key-point. All key-points must lay on boundaries.
-
-The 3D pattern must contain at least one element.
+-# The first line indicates the total number of pattern nodes (N).
+-# The next N lines describe nodes coordinates. Each line contains 2
+node coordinates for a 2D pattern or 3 node cordinates for a 3D pattern.
+Note, that node coordinates of a 3D pattern can be defined only by relative values in range [0;1].
+-# The key-points line contains the indices of the nodes to be mapped on geometrical
+vertices (for a 2D pattern only). Index n refers to the node described
+on the n-th line of section 2. The index of the first node zero. For a 3D pattern the key points are not specified.
+-# The remaining lines describe nodal connectivity of elements, one line
+for each element. Each line holds indices of nodes forming an element.
+Index n refers to the node described on the n-th line of section 2.
+The first node index is zero. There must be 3 or 4 indices on each
+line for a 2D pattern (only 2d elements are allowed) and 4, 5, 6 or 8
+indices for a 3D pattern (only 3d elements are allowed).
+
+A 2D pattern must contain at least one element and at least one
+key-point. All key-points must lie on boundaries.
+
+A 3D pattern must contain at least one element.
An example of a simple 2D pattern smp file:
8 1 2
\endcode
-The image below provides a preview of above described pattern:
+The image below provides a preview of the above pattern:
\image html pattern2d.png
\image html image98.png
<center><em>"Pattern mapping" button</em></center>
-The following dialog box shall appear:
+The following dialog box will appear:
+
+\n For a <b>2D pattern</b>
\image html patternmapping1.png
-<center><b> 2D Pattern Mapping dialog box</b></center>
+In this dialog you should specify:
+
+<ul>
+<li> \b Pattern, which can be loaded from .smp pattern file previously
+created manually or generated automatically from an existing mesh or submesh.</li>
+<li> \b Face with the number of vertices equal to the number of
+ key-points in the pattern; the number of key-points on internal
+ boundaries of the pattern must also be equal to the number of vertices
+ on internal boundaries of the face;</li>
+<li> \b Vertex to which the first key-point should be mapped;</li>
+Alternatively, it is possible to select <b>Refine selected mesh elements</b>
+checkbox and apply the pattern to
+<li> <b>Mesh Face</b> instead of a geometric Face</li>
+<li> and select \b Node instead of vertex.</li>
+
+Additionally it is possible to:
+<li> <b>Reverse the order of key-points</b> By default, the vertices of
+ a face are ordered counterclockwise.<li>
+<li> Enable to <b> Create polygons near boundary</b> </li>
+<li> and <b>Create polyhedrons near boundary</b><li>
+</ul>
+
+\n For a <b>3D pattern</b>
\image html patternmapping2.png
-<center><b> 3D Pattern Mapping dialog box</b></center>
+In this dialog you should specify:
+<ul>
+<li> \b Pattern, which can be loaded from .smp pattern file previously
+created manually or generated automatically from an existing mesh or submesh.</li>
+ <li> A 3D block (Solid) object;</li>
+ <li> Two vertices that specify the order of nodes in the resulting mesh.</li>
+Alternatively, it is possible to select <b>Refine selected mesh elements</b>
+checkbox and apply the pattern to
+<li> One or several <b>Mesh volumes</b> instead of a geometric 3D
+object</li>
+<li> and select two /b Nodes instead of vertices.</li>
+Additionally it is possible to:
+<li> Enable to <b> Create polygons near boundary</b> </li>
+<li> and <b>Create polyhedrons near boundary</b><li>
+</ul>
+
+\n Automatic Generation
+
+To generate a pattern automatically from an existing mesh or submesh,
+click \b New button.
+
+The following dialog box will appear:
-To apply a pattern to a geometrical object, you should specify:
+\image html a-patterntype1.png
--# For 2D pattern
- - A face having the number of vertices equal to the number of
- key-points in the pattern; the number of key-points on internal
- boundaries of a pattern must also be equal to the number of vertices
- on internal boundaries of a face;
- - A vertex to which the first key-point should be mapped;
- - Reverse or not the order of key-points. (The order of vertices of
- a face is counterclockwise looking from outside).
--# For 3D pattern
- - 3D block (Solid) object;
- - Two vertices that specify the order of nodes in the resulting
- mesh.
-
-Then you either load a .smp pattern file previously created manually
-by clicking on the <em>"Load pattern"</em> button, or click on the \b
-New button for automatic generation of the pattern.
-
-For an automatic generation you just specify a geometrical face (for
-2D) or solid (for 3d) having a mesh built on it. Mesh nodes lying on
-face vertices become key-points of 2D pattern. Additionally, for 2D
-pattern you may choose the way of getting nodes coordinates by
-<b>projecting nodes on the face</b> instead of using
-"positions on face" generated by mesher (if there is any). Faces
-having a seam edge can't be used for automatic pattern creation.
-
-When creating a pattern from an existing mesh, there are two possible
-cases:
-
-- A sub-mesh on face/solid is selected. A pattern is created from the 2d/3d
-elements bound to a face/solid by mesher. For 2D pattern, node coordinates are either
-"positions on face" computed by mesher, or coordinates got by node
-projection on a geometrical surface, according to the user choice. For
-3D pattern, nodes coordinates correspond to the nodes computed by mesher.
-- A mesh where the main shape is a face/solid, is selected. A pattern is
-created from all the 2d/3d elements in a mesh. In addition, for 2D
-pattern, if all mesh elements are build by mesher, the user can select
-the way of getting nodes coordinates, else all nodes are projected on
-a face surface.
+In this dialog you should specify:
-\image html a-patterntype.png
+<ul>
+<li> <b>Mesh or Submesh</b>, which is a meshed geometrical face (for a
+2D pattern) or a meshed solid (for a 3D pattern). Mesh nodes lying on
+the face vertices become key-points of the pattern. </li>
+<li> A custom <b>Pattern Name </b> </li>
+<li>Additionally, for a 2D pattern you may choose to
+<b>Project nodes on the face</b> to get node coordinates instead of using
+"positions on face" generated by the mesher (if there is any). The faces
+having a seam edge cannot be used for automatic pattern creation.</li>
+</ul>
-<center><b> 2D Pattern Creation dialog box</b></center>
+When a pattern is created from an existing mesh, two cases are possible:
-\image html a-patterntype1.png
+- A sub-mesh on a face/solid is selected. The pattern is created from the 2d/3d
+elements bound to the face/solid by the mesher. For a 2D pattern, the node coordinates are either
+"positions on face" computed by the mesher, or coordinates got by node
+projection on a geometrical surface, according to the user choice. For
+a 3D pattern, the node coordinates correspond to the nodes computed by
+the mesher.
+- A mesh, where the main shape is a face/solid, is selected. The pattern is
+created from all 2d/3d elements in a mesh. In addition, if all mesh
+elements of a 2D pattern are built by the mesher, the user can select
+how to get node coordinates, otherwise all nodes are projected on
+a face surface.
-<center><b> 3D Pattern Creation dialog box</b></center>
<br><h2>Mapping algorithm</h2>
-The mapping algorithm for 2D case is as follows:
-
-- Key-points are set in the order that they are encountered when
- walking along a pattern boundary so that elements are on the left. The
- first key-point is preserved.
-- Find geometrical vertices corresponding to key-points by vertices
- order in a face boundary; here, "Reverse order of key-points" flag is
- taken into account. \image html image95.gif
-- Boundary nodes of a pattern are mapped onto edges of a face: a
- node located between certain key-points on a pattern boundary is
- mapped on a geometrical edge limited by corresponding geometrical
- vertices. Node position on an edge reflects its distance from two
- key-points. \image html image96.gif
-- Coordinates of a non-boundary node in a parametric space of a face
- are defined as following. In a parametric space of a pattern, a node
- lays at the intersection of two iso-lines, each of which intersects a
- pattern boundary at least at two points. Knowing mapped positions of
- boundary nodes, we find where isoline-boundary intersection points are
- mapped to, and hence we can find mapped isolines direction and then,
- two node positions on two mapped isolines. The eventual mapped
- position of a node is found as an average of positions on mapped
- isolines. \image html image97.gif
-
-For 3D case the algorithm is similar.
+The mapping algorithm for a 2D case is as follows:
+
+- The key-points are set counterclockwise in the order corresponding
+ to their location on the pattern boundary. The first key-point is preserved.
+- The geometrical vertices corresponding to the key-points are found
+ on face boundary. Here, "Reverse order of key-points" flag is set.
+\image html image95.gif
+- The boundary nodes of the pattern are mapped onto the edges of the face: a
+ node located between two key-points on the pattern boundary is
+ mapped on the geometrical edge limited by the corresponding geometrical
+ vertices. The node position on the edge depends on its distance from the
+ key-points.
+\image html image96.gif
+- The cordinates of a non-boundary node in the parametric space of the face
+ are defined in the following way. In the parametric space of the
+ pattern, the node lies at the intersection of two iso-lines. Both
+ of them intersect the pattern boundary at two
+ points at least. If the mapped positions of boundary nodes are known, it is
+ possible to find, where the points at the intersection of isolines
+ and boundaries are mapped. Then it is possible to find
+ the direction of mapped isolinesection and, filally, the poitions of
+ two nodes on two mapped isolines. The eventual mapped
+ position of the node is found as an average of the positions on mapped
+ isolines.
+\image html image97.gif
+
+The 3D algorithm is similar.
<b>See Also</b> a sample TUI Script of a
\ref tui_pattern_mapping "Pattern Mapping" operation.
\anchor removing_orphan_nodes_anchor
<h2>Removing orphan nodes</h2>
-There is a quick way to remove all the orphan (free) nodes.
+There is a quick way to remove all orphan (free) nodes.
-<em>To remove the orphan nodes:</em>
+<em>To remove orphan nodes:</em>
<ol>
<li>Select your mesh in the Object Browser or in the 3D viewer.</li>
<li>From the <em>Modification</em> menu choose <em>Remove</em> and from the associated
-submenu select the <em>Orphan Nodes</em>, or just click <em>"Remove orphan nodes"</em>
+submenu select <em>Orphan Nodes</em>, or just click <em>"Remove orphan nodes"</em>
button in the toolbar.
\image html remove_orphan_nodes_icon.png
\image html removeorphannodes.png
-Confirm removing nodes by pressing "Yes" button.
+Confirm nodes removal by pressing "Yes" button.
</ol>
<br>
length, which is more, less or equal (within a given <b>Tolerance</b>) to the predefined
<b>Threshold Value</b>. See also a
\ref length_2d_page "Length 2D quality control".
+</li><li>
+<b>Coplanar faces</b> selects mesh faces neighboring the one selected
+by ID in <b>Threshold Value</b> field, if the angle between the
+normal to the neighboring face and the normal to the selected face is less then the
+angular tolerance (defined in degrees). Selection continues among all neighbor faces of already
+selected ones.<br>
</li>
</ul>
<br>
\anchor tui_average_length
-<h3>Average Length</h3>
+<h3>Local Length</h3>
\code
from geompy import *
\endcode
\anchor tui_quadrangle_parameters
-<h2>Quadrangle Parameters example </h2>
+<h2>Quadrangle Parameters example 1 (meshing a face with 3 edges) </h2>
\code
import geompy
import smesh
Quadrangle_Parameters_1 = smesh.CreateHypothesis('QuadrangleParams')
Quadrangle_Parameters_1.SetTriaVertex( 8 )
-# Define 1D hypothesis and cmpute the mesh
+# Define 1D hypothesis and compute the mesh
Regular_1D = Mesh_1.Segment()
Nb_Segments_1 = Regular_1D.NumberOfSegments(10)
Nb_Segments_1.SetDistrType( 0 )
Mesh_1.Compute()
\endcode
+<h2>Quadrangle Parameters example 2 (using different types) </h2>
+\code
+import geompy
+import smesh
+import StdMeshers
+
+# Make quadrangle face and explode it on edges.
+Vertex_1 = geompy.MakeVertex(0, 0, 0)
+Vertex_2 = geompy.MakeVertex(40, 0, 0)
+Vertex_3 = geompy.MakeVertex(40, 30, 0)
+Vertex_4 = geompy.MakeVertex(0, 30, 0)
+Quadrangle_Face_1 = geompy.MakeQuad4Vertices(Vertex_1, Vertex_4, Vertex_3, Vertex_2)
+[Edge_1,Edge_2,Edge_3,Edge_4] = geompy.SubShapeAllSorted(Quadrangle_Face_1, geompy.ShapeType["EDGE"])
+geompy.addToStudy( Vertex_1, "Vertex_1" )
+geompy.addToStudy( Vertex_2, "Vertex_2" )
+geompy.addToStudy( Vertex_3, "Vertex_3" )
+geompy.addToStudy( Vertex_4, "Vertex_4" )
+geompy.addToStudy( Quadrangle_Face_1, "Quadrangle Face_1" )
+geompy.addToStudyInFather( Quadrangle_Face_1, Edge_2, "Edge_2" )
+
+# Set the Geometry for meshing
+Mesh_1 = smesh.Mesh(Quadrangle_Face_1)
+
+# Create Quadrangle parameters and
+# define the Type as Quadrangle Preference
+Quadrangle_Parameters_1 = smesh.CreateHypothesis('QuadrangleParams')
+Quadrangle_Parameters_1.SetQuadType( StdMeshers.QUAD_QUADRANGLE_PREF )
+
+# Define other hypotheses and algorithms
+Regular_1D = Mesh_1.Segment()
+Nb_Segments_1 = Regular_1D.NumberOfSegments(4)
+Nb_Segments_1.SetDistrType( 0 )
+status = Mesh_1.AddHypothesis(Quadrangle_Parameters_1)
+Quadrangle_2D = Mesh_1.Quadrangle()
+
+# Define submesh on one edge to provide different number of segments
+Regular_1D_1 = Mesh_1.Segment(geom=Edge_2)
+Nb_Segments_2 = Regular_1D_1.NumberOfSegments(10)
+Nb_Segments_2.SetDistrType( 0 )
+SubMesh_1 = Regular_1D_1.GetSubMesh()
+
+# Compute mesh (with Quadrangle Preference type)
+isDone = Mesh_1.Compute()
+
+# Change type to Reduced and compute again
+Quadrangle_Parameters_1.SetQuadType( StdMeshers.QUAD_REDUCED )
+isDone = Mesh_1.Compute()
+\endcode
+
+
\n Other meshing algorithms:
<ul>
\page tui_filters_page Filters usage
-Filters allows to pick only those mesh elements which satisfy to
-specific condition or set of conditions. Filters can be used to create
+Filters allow picking only the mesh elements satisfying to a
+specific condition or a set of conditions. Filters can be used to create
or edit mesh groups, remove elements from the mesh object, control
mesh quality by different parameters, etc.
using logical operator \a NOT.
Mesh filters use the functionality of mesh quality controls to filter
-mesh nodes / elements by specific characteristic (Area, Length, etc).
+mesh nodes / elements by a specific characteristic (Area, Length, etc).
This page provides a short description of the existing mesh filters,
-describing required parameters and gives simple examples of usage in
+describes required parameters and gives simple examples of usage in
Python scripts.
\sa \ref tui_quality_controls_page
salome.sg.updateObjBrowser(0)
\endcode
+<br>
+\anchor tui_make_2dmesh_from_3d
+<h3>Create boundary elements</h3>
+
+\code
+# The objective of these samples is to illustrate the following use cases:
+# 1) The mesh MESH1 with 3D cells has no or only a part of its skin (2D cells):
+# 1.1) Add the 2D skin (missing 2D cells) to MESH1 (what is done now by the algorithm).
+# 1.2) Create a new 3D Mesh MESH2 that consists of MESH1 and added 2D skin cells.
+# 1.3) Create a new 2D Mesh MESH3 that consists only of 2D skin cells.
+# 2) The mesh MESH1 with 3D cells has all its skin (2D cells):
+# Create a new 2D Mesh MESH3 that consists only of 2D skin cells.
+#
+# In all cases an option to create a group containing these 2D skin cells is available.
+
+from smesh import *
+
+box = geompy.MakeBoxDXDYDZ(1,1,1)
+geompy.addToStudy(box,"box")
+boxFace = geompy.SubShapeAll(box, geompy.ShapeType["FACE"])[0]
+geompy.addToStudyInFather(box,boxFace,"boxFace")
+
+MESH1 = Mesh(box,"MESH1")
+MESH1.AutomaticHexahedralization()
+
+init_nb_edges = MESH1.NbEdges()
+init_nb_faces = MESH1.NbFaces()
+init_nb_volumes = MESH1.NbVolumes()
+
+# =========================================================================================
+# 1) The mesh MESH1 with 3D cells has no or only a part of its skin (2D cells)
+# =========================================================================================
+# remove some faces
+all_faces = MESH1.GetElementsByType(SMESH.FACE)
+rm_faces = all_faces[:init_nb_faces/5] + all_faces[4*init_nb_faces/5:]
+MESH1.RemoveElements(rm_faces)
+assert(MESH1.NbFaces() == init_nb_faces-len(rm_faces))
+
+# 1.1) Add the 2D skin (missing 2D cells) to MESH1
+# -------------------------------------------------
+# add missing faces
+# 1.1.1) to the whole mesh
+m,g = MESH1.MakeBoundaryMesh(MESH1)
+assert(init_nb_faces == MESH1.NbFaces())
+assert(init_nb_edges == MESH1.NbEdges())
+assert(m)
+assert(not g)
+
+# 1.1.2) to some elements
+MESH1.RemoveElements(rm_faces)
+MESH1.MakeBoundaryMesh([])
+assert(init_nb_faces != MESH1.NbFaces())
+volumes = MESH1.GetElementsByType(SMESH.VOLUME)
+for v in volumes:
+ MESH1.MakeBoundaryMesh([v])
+assert(init_nb_faces == MESH1.NbFaces())
+assert(init_nb_edges == MESH1.NbEdges())
+
+# 1.1.3) to a group of elements
+volGroup1 = MESH1.CreateEmptyGroup(SMESH.VOLUME, "volGroup1")
+volGroup1.Add( volumes[: init_nb_volumes/2])
+volGroup2 = MESH1.CreateEmptyGroup(SMESH.VOLUME, "volGroup2")
+volGroup1.Add( volumes[init_nb_volumes/2:])
+MESH1.RemoveElements(rm_faces)
+MESH1.MakeBoundaryMesh(volGroup1)
+MESH1.MakeBoundaryMesh(volGroup2)
+assert(init_nb_faces == MESH1.NbFaces())
+assert(init_nb_edges == MESH1.NbEdges())
+
+# 1.1.4) to a submesh.
+# The submesh has no volumes, so it is required to check if it passes without crash and does not create
+# missing faces
+faceSubmesh = MESH1.GetSubMesh( boxFace, "boxFace" )
+MESH1.RemoveElements(rm_faces)
+MESH1.MakeBoundaryMesh(faceSubmesh)
+assert(init_nb_faces != MESH1.NbFaces())
+
+# check group creation
+MESH1.RemoveElements(rm_faces)
+groupName = "added to mesh"
+m,group = MESH1.MakeBoundaryMesh(MESH1,groupName=groupName)
+assert(group)
+assert(group.GetName() == groupName)
+assert(group.Size() == len(rm_faces))
+
+
+# 1.2) Create a new 3D Mesh MESH2 that consists of MESH1 and added 2D skin cells.
+# ------------------------------------------------------------------------------
+MESH1.RemoveElements(rm_faces)
+meshName = "MESH2"
+MESH2,group = MESH1.MakeBoundaryMesh(MESH1,meshName=meshName,toCopyElements=True)
+assert(MESH2)
+assert(MESH2.GetName() == meshName)
+assert(MESH2.NbVolumes() == MESH1.NbVolumes())
+assert(MESH2.NbFaces() == len(rm_faces))
+
+# check group creation
+MESH1.RemoveElements(rm_faces)
+MESH2,group = MESH1.MakeBoundaryMesh(MESH1,meshName="MESH2_0",
+ groupName=groupName,toCopyElements=True)
+assert(group)
+assert(group.GetName() == groupName)
+assert(group.Size() == len(rm_faces))
+assert(group.GetMesh()._is_equivalent(MESH2.GetMesh()))
+
+# 1.3) Create a new 2D Mesh MESH3 that consists only of 2D skin cells.
+# -----------------------------------------------------------------------
+MESH1.RemoveElements(rm_faces)
+meshName = "MESH3"
+MESH3,group = MESH1.MakeBoundaryMesh(MESH1,meshName=meshName,toCopyExistingBondary=True)
+assert(MESH3)
+assert(not group)
+assert(MESH3.GetName() == meshName)
+assert(MESH3.NbVolumes() == 0)
+assert(MESH3.NbFaces() == init_nb_faces)
+
+# check group creation
+MESH1.RemoveElements(rm_faces)
+MESH3,group = MESH1.MakeBoundaryMesh(MESH1,meshName=meshName,
+ groupName=groupName, toCopyExistingBondary=True)
+assert(group)
+assert(group.GetName() == groupName)
+assert(group.Size() == len(rm_faces))
+assert(group.GetMesh()._is_equivalent(MESH3.GetMesh()))
+assert(MESH3.NbFaces() == init_nb_faces)
+
+# ==================================================================
+# 2) The mesh MESH1 with 3D cells has all its skin (2D cells)
+# Create a new 2D Mesh MESH3 that consists only of 2D skin cells.
+# ==================================================================
+MESH1.MakeBoundaryMesh(MESH1)
+MESH3,group = MESH1.MakeBoundaryMesh(MESH1,meshName=meshName,toCopyExistingBondary=True)
+assert(MESH3)
+assert(not group)
+assert(MESH3.NbVolumes() == 0)
+assert(MESH3.NbFaces() == init_nb_faces)
+
+# check group creation
+MESH3,group = MESH1.MakeBoundaryMesh(MESH1,meshName=meshName,
+ groupName=groupName, toCopyExistingBondary=True)
+assert(group)
+assert(group.GetName() == groupName)
+assert(group.Size() == 0)
+assert(group.GetMesh()._is_equivalent(MESH3.GetMesh()))
+assert(MESH3.NbFaces() == init_nb_faces)
+
+# ================
+# Make 1D from 2D
+# ================
+
+MESH1.Clear()
+MESH1.Compute()
+MESH1.RemoveElements( MESH1.GetElementsByType(SMESH.EDGE))
+
+rm_faces = faceSubmesh.GetIDs()[:2] # to remove few adjacent faces
+nb_missing_edges = 2 + 2*len(rm_faces)
+
+MESH1.RemoveElements(rm_faces)
+mesh,group = MESH1.MakeBoundaryMesh(MESH1, BND_1DFROM2D)
+assert( MESH1.NbEdges() == nb_missing_edges )
+
+
+\endcode
*/
/*!
* StdMeshers_QuadrangleParams: interface of "Quadrangle Params" hypothesis
*/
+ enum QuadType
+ {
+ QUAD_STANDARD,
+ QUAD_TRIANGLE_PREF,
+ QUAD_QUADRANGLE_PREF,
+ QUAD_QUADRANGLE_PREF_REVERSED,
+ QUAD_REDUCED,
+ QUAD_NB_TYPES /* this is not a type of quadrangulation */
+ };
+
interface StdMeshers_QuadrangleParams : SMESH::SMESH_Hypothesis
{
/*!
* Get the entry of the main object
*/
string GetObjectEntry();
+
+ /*!
+ * Set the type of quadrangulation
+ */
+ void SetQuadType( in QuadType type );
+
+ /*!
+ * Get the type of quadrangulation
+ */
+ QuadType GetQuadType();
};
/*!
FT_LinearOrQuadratic,
FT_GroupColor,
FT_ElemGeomType,
+ FT_CoplanarFaces,
FT_LessThan,
FT_MoreThan,
FT_EqualTo,
void SetGeometryType( in GeometryType theType );
};
+ /*!
+ * Functor "Coplanar faces"
+ * Returns true if a mesh face is a coplanar neighbour to a given one. It checks
+ * if normal of a face has angle with the threshold face less than a tolerance.
+ */
+ interface CoplanarFaces : Predicate{
+ void SetFace ( in long theFaceID );
+ void SetTolerance( in double theToler );
+ };
+
/*!
* Filter
*/
* BinaryOp - binary logical operation FT_LogicalAND, FT_LogicalOR or
* (FT_Undefined must be for the last criterion)
* ThresholdStr - Threshold value defined as string. Used for:
- * 1. Diaposon of identifiers. Example: "1,2,3,5-10,12,27-29"
+ * 1. Diapason of identifiers. Example: "1,2,3,5-10,12,27-29"
* 2. BelongToGeom predicate for storing name of shape
* 3. GroupColor predicate for storing group color "0.2;0;0.5"
* ThresholdID - One more threshold value defined as string. Used for:
* 1. BelongToGeom predicate for storing id of shape
* Tolerance - Tolerance is used for comparators (EqualTo comparision) and for
- * "Belong to plane" and "Belong to cylinder" predicates
+ * "Belong to plane", "Belong to cylinder" etc predicates
* TypeOfElement - type of element SMESH::NODE, SMESH::FACE (used by BelongToGeom predicate only)
* Precision - Precision of numerical functors
*/
GroupColor CreateGroupColor();
ElemGeomType CreateElemGeomType();
+ CoplanarFaces CreateCoplanarFaces();
/*!
* Create comparators ( predicates )
module SMESH
{
+ enum Bnd_Dimension { BND_2DFROM3D, BND_1DFROM3D, BND_1DFROM2D };
+
/*!
* This interface makes modifications on the Mesh - removing elements and nodes etc.
*/
in GEOM::GEOM_Object theShape );
/*!
- * \brief Generated skin mesh (containing 2D cells) from 3D mesh
+ * \brief Generates skin mesh (containing 2D cells) from 3D mesh
* The created 2D mesh elements based on nodes of free faces of boundary volumes
* \return TRUE if operation has been completed successfully, FALSE otherwise
*/
boolean Make2DMeshFrom3D();
+ /*!
+ * \brief Creates missing boundary elements
+ * \param elements - elements whose boundary is to be checked
+ * \param dimension - defines type of boundary elements to create
+ * \param groupName - a name of group to store created boundary elements in,
+ * "" means not to create the group
+ * \param meshName - a name of new mesh to store created boundary elements in,
+ * "" means not to create the new mesh
+ * \param toCopyElements - if true, the checked elements will be copied into the new mesh
+ * \param toCopyExistingBondary - if true, not only new but also pre-existing
+ * boundary elements will be copied into the new mesh
+ * \param group - returns the create group, if any
+ * \retval SMESH::SMESH_Mesh - the mesh where elements were added to
+ */
+ SMESH::SMESH_Mesh MakeBoundaryMesh(in SMESH_IDSource elements,
+ in Bnd_Dimension dimension,
+ in string groupName,
+ in string meshName,
+ in boolean toCopyElements,
+ in boolean toCopyExistingBondary,
+ out SMESH_Group group);
+
};
};
mesh_pyramid.png \
mesh_quad_n.png \
mesh_quad.png \
+ mesh_quadrangle_quadpref.png \
+ mesh_quadrangle_quadpref_reversed.png \
+ mesh_quadrangle_reduced.png \
+ mesh_quadrangle_standard.png \
+ mesh_quadrangle_triapref.png \
mesh_rem_element.png \
mesh_rem_node.png \
mesh_rem_orphan_nodes.png \
<parameter name="scalar_bar_vertical_y" value="0.1" />
<parameter name="DisplayMode" value="true" />
<parameter name="auto_update" value="true" />
+ <parameter name="update_limit" value="500000" />
<parameter name="display_mode" value="1" />
<parameter name="auto_groups" value="false"/>
<parameter name="show_result_notification" value="2"/>
<hypothesis type="MaxElementVolume"
label-id="Max. Element Volume"
icon-id="mesh_hypo_volume.png"
- need-geom = "false"
+ need-geom="false"
dim="3"/>
<hypothesis type="ProjectionSource3D"
#include "SMESH_ControlsDef.hxx"
#include <set>
+#include <limits>
#include <BRepAdaptor_Surface.hxx>
#include <BRepClass_FaceClassifier.hxx>
*/
namespace{
+
+ inline gp_XYZ gpXYZ(const SMDS_MeshNode* aNode )
+ {
+ return gp_XYZ(aNode->X(), aNode->Y(), aNode->Z() );
+ }
+
inline double getAngle( const gp_XYZ& P1, const gp_XYZ& P2, const gp_XYZ& P3 )
{
gp_Vec v1( P1 - P2 ), v2( P3 - P2 );
return aResult;
}
+ gp_XYZ getNormale( const SMDS_MeshFace* theFace, bool* ok=0 )
+ {
+ int aNbNode = theFace->NbNodes();
+
+ gp_XYZ q1 = gpXYZ( theFace->GetNode(1)) - gpXYZ( theFace->GetNode(0));
+ gp_XYZ q2 = gpXYZ( theFace->GetNode(2)) - gpXYZ( theFace->GetNode(0));
+ gp_XYZ n = q1 ^ q2;
+ if ( aNbNode > 3 ) {
+ gp_XYZ q3 = gpXYZ( theFace->GetNode(3)) - gpXYZ( theFace->GetNode(0));
+ n += q2 ^ q3;
+ }
+ double len = n.Modulus();
+ bool zeroLen = ( len <= numeric_limits<double>::min());
+ if ( !zeroLen )
+ n /= len;
+
+ if (ok) *ok = !zeroLen;
+
+ return n;
+ }
}
using namespace SMESH::Controls;
/*
- FUNCTORS
-*/
+ * FUNCTORS
+ */
/*
Class : NumericalFunctor
return myGeomType;
}
+//================================================================================
+/*!
+ * \brief Class CoplanarFaces
+ */
+//================================================================================
+
+CoplanarFaces::CoplanarFaces()
+ : myMesh(0), myFaceID(0), myToler(0)
+{
+}
+bool CoplanarFaces::IsSatisfy( long theElementId )
+{
+ if ( myCoplanarIDs.empty() )
+ {
+ // Build a set of coplanar face ids
+
+ if ( !myMesh || !myFaceID || !myToler )
+ return false;
+
+ const SMDS_MeshElement* face = myMesh->FindElement( myFaceID );
+ if ( !face || face->GetType() != SMDSAbs_Face )
+ return false;
+
+ bool normOK;
+ gp_Vec myNorm = getNormale( static_cast<const SMDS_MeshFace*>(face), &normOK );
+ if (!normOK)
+ return false;
+
+ const double radianTol = myToler * PI180;
+ typedef SMDS_StdIterator< const SMDS_MeshElement*, SMDS_ElemIteratorPtr > TFaceIt;
+ std::set<const SMDS_MeshElement*> checkedFaces, checkedNodes;
+ std::list<const SMDS_MeshElement*> faceQueue( 1, face );
+ while ( !faceQueue.empty() )
+ {
+ face = faceQueue.front();
+ if ( checkedFaces.insert( face ).second )
+ {
+ gp_Vec norm = getNormale( static_cast<const SMDS_MeshFace*>(face), &normOK );
+ if (!normOK || myNorm.Angle( norm ) <= radianTol)
+ {
+ myCoplanarIDs.insert( face->GetID() );
+ std::set<const SMDS_MeshElement*> neighborFaces;
+ for ( int i = 0; i < face->NbCornerNodes(); ++i )
+ {
+ const SMDS_MeshNode* n = face->GetNode( i );
+ if ( checkedNodes.insert( n ).second )
+ neighborFaces.insert( TFaceIt( n->GetInverseElementIterator(SMDSAbs_Face)),
+ TFaceIt());
+ }
+ faceQueue.insert( faceQueue.end(), neighborFaces.begin(), neighborFaces.end() );
+ }
+ }
+ faceQueue.pop_front();
+ }
+ }
+ return myCoplanarIDs.count( theElementId );
+}
+
/*
- Class : RangeOfIds
- Description : Predicate for Range of Ids.
- Range may be specified with two ways.
- 1. Using AddToRange method
- 2. With SetRangeStr method. Parameter of this method is a string
- like as "1,2,3,50-60,63,67,70-"
+ *Class : RangeOfIds
+ *Description : Predicate for Range of Ids.
+ * Range may be specified with two ways.
+ * 1. Using AddToRange method
+ * 2. With SetRangeStr method. Parameter of this method is a string
+ * like as "1,2,3,50-60,63,67,70-"
*/
//=======================================================================
}
}
-static gp_XYZ getNormale( const SMDS_MeshFace* theFace )
-{
- gp_XYZ n;
- int aNbNode = theFace->NbNodes();
- TColgp_Array1OfXYZ anArrOfXYZ(1,4);
- SMDS_ElemIteratorPtr aNodeItr = theFace->nodesIterator();
- int i = 1;
- for ( ; aNodeItr->more() && i <= 4; i++ ) {
- SMDS_MeshNode* aNode = (SMDS_MeshNode*)aNodeItr->next();
- anArrOfXYZ.SetValue(i, gp_XYZ( aNode->X(), aNode->Y(), aNode->Z() ) );
- }
-
- gp_XYZ q1 = anArrOfXYZ.Value(2) - anArrOfXYZ.Value(1);
- gp_XYZ q2 = anArrOfXYZ.Value(3) - anArrOfXYZ.Value(1);
- n = q1 ^ q2;
- if ( aNbNode > 3 ) {
- gp_XYZ q3 = anArrOfXYZ.Value(4) - anArrOfXYZ.Value(1);
- n += q2 ^ q3;
- }
- double len = n.Modulus();
- if ( len > 0 )
- n /= len;
-
- return n;
-}
-
bool ManifoldPart::findConnected
( const ManifoldPart::TDataMapFacePtrInt& theAllFacePtrInt,
SMDS_MeshFace* theStartFace,
class SMESHCONTROLS_EXPORT ElemGeomType: public virtual Predicate{
public:
ElemGeomType();
- virtual void SetMesh( const SMDS_Mesh* theMesh );
- virtual bool IsSatisfy( long theElementId );
- void SetType( SMDSAbs_ElementType theType );
- virtual SMDSAbs_ElementType GetType() const;
- void SetGeomType( SMDSAbs_GeometryType theType );
+ virtual void SetMesh( const SMDS_Mesh* theMesh );
+ virtual bool IsSatisfy( long theElementId );
+ void SetType( SMDSAbs_ElementType theType );
+ virtual SMDSAbs_ElementType GetType() const;
+ void SetGeomType( SMDSAbs_GeometryType theType );
virtual SMDSAbs_GeometryType GetGeomType() const;
private:
};
typedef boost::shared_ptr<ElemGeomType> ElemGeomTypePtr;
+ /*
+ Class : CoplanarFaces
+ Description : Predicate to check angle between faces
+ */
+ class SMESHCONTROLS_EXPORT CoplanarFaces: public virtual Predicate
+ {
+ public:
+ CoplanarFaces();
+ void SetFace( long theID ) { myFaceID = theID; }
+ long GetFace() const { return myFaceID; }
+ void SetTolerance (const double theToler) { myToler = theToler; }
+ double GetTolerance () const { return myToler; }
+ virtual void SetMesh( const SMDS_Mesh* theMesh ) { myMesh = theMesh; }
+ virtual SMDSAbs_ElementType GetType() const { return SMDSAbs_Face; }
+
+ virtual bool IsSatisfy( long theElementId );
+
+ private:
+ const SMDS_Mesh* myMesh;
+ long myFaceID;
+ double myToler;
+ std::set< long > myCoplanarIDs;
+ };
+ typedef boost::shared_ptr<CoplanarFaces> CoplanarFacesPtr;
+
/*
FILTER
*/
//
#include "SMESH_HypoFilter.hxx"
+#include "SMESH_Gen.hxx"
#include "SMESH_Hypothesis.hxx"
+#include "SMESH_MesherHelper.hxx"
#include "SMESH_subMesh.hxx"
#include <TopExp_Explorer.hxx>
//=======================================================================
bool SMESH_HypoFilter::IsAssignedToPredicate::IsOk(const SMESH_Hypothesis* aHyp,
- const TopoDS_Shape& aShape) const
+ const TopoDS_Shape& aShape) const
{
return ( !_mainShape.IsNull() && !aShape.IsNull() && _mainShape.IsSame( aShape ));
}
bool SMESH_HypoFilter::IsMoreLocalThanPredicate::IsOk(const SMESH_Hypothesis* aHyp,
const TopoDS_Shape& aShape) const
{
- // issue 0020963
- // if aShape is COMPOUND (i.e. most probably a GEOM group) then
- // it is more local if it contains shapes of less dimension than _shapeType
- if ( aShape.ShapeType() == TopAbs_COMPOUND )
- for ( int moreLocalType = _shapeType+1; moreLocalType < int(TopAbs_SHAPE); ++moreLocalType )
- if ( TopExp_Explorer( aShape, TopAbs_ShapeEnum(moreLocalType)).More())
- return true;
- return ( aShape.ShapeType() > _shapeType );
+ if ( SMESH_MesherHelper::IsSubShape( aShape, /*mainShape=*/_shape ))
+ return true;
+
+ if ( aShape.ShapeType() == TopAbs_COMPOUND &&
+ !SMESH_MesherHelper::IsSubShape( _shape, /*mainShape=*/aShape)) // issue 0020963
+ {
+ for ( int type = TopAbs_SOLID; type < TopAbs_SHAPE; ++type )
+ if ( aHyp->GetDim() == SMESH_Gen::GetShapeDim( TopAbs_ShapeEnum( type )))
+ for ( TopExp_Explorer exp( aShape, TopAbs_ShapeEnum( type )); exp.More(); exp.Next())
+ if ( SMESH_MesherHelper::IsSubShape( exp.Current(), /*mainShape=*/_shape ))
+ return true;
+ }
+ return false;
}
//=======================================================================
// SMESH SMESH : implementaion of SMESH idl descriptions
// File : SMESH_HypoFilter.hxx
// Module : SMESH
-// $Header$
//
#ifndef SMESH_HypoFilter_HeaderFile
#define SMESH_HypoFilter_HeaderFile
};
struct IsMoreLocalThanPredicate : public SMESH_HypoPredicate {
- TopAbs_ShapeEnum _shapeType;
- IsMoreLocalThanPredicate( const TopoDS_Shape& shape ):_shapeType(shape.ShapeType()){}
+ TopoDS_Shape _shape;
+ IsMoreLocalThanPredicate( const TopoDS_Shape& shape ):_shape(shape){}
bool IsOk(const SMESH_Hypothesis* aHyp,
const TopoDS_Shape& aShape) const;
};
#include "SMDS_SpacePosition.hxx"
#include "SMDS_QuadraticFaceOfNodes.hxx"
#include "SMDS_MeshGroup.hxx"
+#include "SMDS_SetIterator.hxx"
#include "SMESHDS_Group.hxx"
#include "SMESHDS_Mesh.hxx"
typedef map<const SMDS_MeshElement*, list<const SMDS_MeshNode*> > TElemOfNodeListMap;
typedef map<const SMDS_MeshElement*, list<const SMDS_MeshElement*> > TElemOfElemListMap;
+typedef SMDS_SetIterator< SMDS_pElement, TIDSortedElemSet::const_iterator> TSetIterator;
+
//=======================================================================
//function : SMESH_MeshEditor
//purpose :
node[16],node[17],node[18],node[19] );
}
}
+ if ( e ) myLastCreatedElems.Append( e );
return e;
}
}
}
else if ( theCopy ) {
- if ( SMDS_MeshElement* copy = AddElement( nodes, elem->GetType(), elem->IsPoly() )) {
- myLastCreatedElems.Append( copy );
+ if ( AddElement( nodes, elem->GetType(), elem->IsPoly() ))
srcElems.Append( elem );
- }
}
else {
// reverse element as it was reversed by transformation
{
public:
- ElementBndBoxTree(const SMDS_Mesh& mesh, SMDSAbs_ElementType elemType);
+ ElementBndBoxTree(const SMDS_Mesh& mesh, SMDSAbs_ElementType elemType, double tolerance = NodeRadius );
void getElementsNearPoint( const gp_Pnt& point, TIDSortedElemSet& foundElems);
void getElementsNearLine ( const gp_Ax1& line, TIDSortedElemSet& foundElems);
~ElementBndBoxTree();
{
const SMDS_MeshElement* _element;
int _refCount; // an ElementBox can be included in several tree branches
- ElementBox(const SMDS_MeshElement* elem);
+ ElementBox(const SMDS_MeshElement* elem, double tolerance);
};
vector< ElementBox* > _elements;
};
*/
//================================================================================
- ElementBndBoxTree::ElementBndBoxTree(const SMDS_Mesh& mesh, SMDSAbs_ElementType elemType)
+ ElementBndBoxTree::ElementBndBoxTree(const SMDS_Mesh& mesh, SMDSAbs_ElementType elemType, double tolerance)
:SMESH_Octree( new SMESH_Octree::Limit( MaxLevel, /*minSize=*/0. ))
{
int nbElems = mesh.GetMeshInfo().NbElements( elemType );
SMDS_ElemIteratorPtr elemIt = mesh.elementsIterator( elemType );
while ( elemIt->more() )
- _elements.push_back( new ElementBox( elemIt->next() ));
+ _elements.push_back( new ElementBox( elemIt->next(),tolerance ));
if ( _elements.size() > MaxNbElemsInLeaf )
compute();
*/
//================================================================================
- ElementBndBoxTree::ElementBox::ElementBox(const SMDS_MeshElement* elem)
+ ElementBndBoxTree::ElementBox::ElementBox(const SMDS_MeshElement* elem, double tolerance)
{
_element = elem;
_refCount = 1;
SMDS_ElemIteratorPtr nIt = elem->nodesIterator();
while ( nIt->more() )
Add( SMESH_MeshEditor::TNodeXYZ( cast2Node( nIt->next() )));
- Enlarge( NodeRadius );
+ Enlarge( tolerance );
}
} // namespace
elemSize = max( dist, elemSize );
}
}
- _tolerance = 1e-6 * elemSize;
+ _tolerance = 1e-4 * elemSize;
}
}
return _tolerance;
if ( !_ebbTree || _elementType != type )
{
if ( _ebbTree ) delete _ebbTree;
- _ebbTree = new ElementBndBoxTree( *_mesh, _elementType = type );
+ _ebbTree = new ElementBndBoxTree( *_mesh, _elementType = type, tolerance );
}
TIDSortedElemSet suspectElems;
_ebbTree->getElementsNearPoint( point, suspectElems );
continue;
if ( theIsDoubleElem )
- myLastCreatedElems.Append( AddElement(newNodes, anElem->GetType(), anElem->IsPoly()) );
+ AddElement(newNodes, anElem->GetType(), anElem->IsPoly());
else
theMeshDS->ChangeElementNodes( anElem, &newNodes[ 0 ], anElem->NbNodes() );
//================================================================================
/*!
- * \brief Generated skin mesh (containing 2D cells) from 3D mesh
+ * \brief Generates skin mesh (containing 2D cells) from 3D mesh
* The created 2D mesh elements based on nodes of free faces of boundary volumes
* \return TRUE if operation has been completed successfully, FALSE otherwise
*/
nbExisted++;
continue; // face already exsist
}
- myLastCreatedElems.Append( AddElement(nodes, SMDSAbs_Face, isPoly && iface == 1) );
+ AddElement(nodes, SMDSAbs_Face, isPoly && iface == 1);
nbCreated++;
}
}
return ( nbFree==(nbExisted+nbCreated) );
}
+
+namespace
+{
+ inline const SMDS_MeshNode* getNodeWithSameID(SMESHDS_Mesh* mesh, const SMDS_MeshNode* node)
+ {
+ if ( const SMDS_MeshNode* n = mesh->FindNode( node->GetID() ))
+ return n;
+ return mesh->AddNodeWithID( node->X(),node->Y(),node->Z(), node->GetID() );
+ }
+}
+//================================================================================
+/*!
+ * \brief Creates missing boundary elements
+ * \param elements - elements whose boundary is to be checked
+ * \param dimension - defines type of boundary elements to create
+ * \param group - a group to store created boundary elements in
+ * \param targetMesh - a mesh to store created boundary elements in
+ * \param toCopyElements - if true, the checked elements will be copied into the targetMesh
+ * \param toCopyExistingBondary - if true, not only new but also pre-existing
+ * boundary elements will be copied into the targetMesh
+ */
+//================================================================================
+
+void SMESH_MeshEditor::MakeBoundaryMesh(const TIDSortedElemSet& elements,
+ Bnd_Dimension dimension,
+ SMESH_Group* group/*=0*/,
+ SMESH_Mesh* targetMesh/*=0*/,
+ bool toCopyElements/*=false*/,
+ bool toCopyExistingBondary/*=false*/)
+{
+ SMDSAbs_ElementType missType = (dimension == BND_2DFROM3D) ? SMDSAbs_Face : SMDSAbs_Edge;
+ SMDSAbs_ElementType elemType = (dimension == BND_1DFROM2D) ? SMDSAbs_Face : SMDSAbs_Volume;
+ // hope that all elements are of the same type, do not check them all
+ if ( !elements.empty() && (*elements.begin())->GetType() != elemType )
+ throw SALOME_Exception(LOCALIZED("wrong element type"));
+
+ if ( !targetMesh )
+ toCopyElements = toCopyExistingBondary = false;
+
+ SMESH_MeshEditor tgtEditor( targetMesh ? targetMesh : myMesh );
+ SMESHDS_Mesh* aMesh = GetMeshDS(), *tgtMeshDS = tgtEditor.GetMeshDS();
+
+ SMDS_VolumeTool vTool;
+ TIDSortedElemSet emptySet, avoidSet;
+ int inode;
+
+ typedef vector<const SMDS_MeshNode*> TConnectivity;
+
+ SMDS_ElemIteratorPtr eIt;
+ if (elements.empty())
+ eIt = aMesh->elementsIterator(elemType);
+ else
+ eIt = SMDS_ElemIteratorPtr( new TSetIterator( elements.begin(), elements.end() ));
+
+ while (eIt->more())
+ {
+ const SMDS_MeshElement* elem = eIt->next();
+ const int iQuad = elem->IsQuadratic();
+
+ // 1. For an elem, get present bnd elements and connectivities of missing bnd elements
+ vector<const SMDS_MeshElement*> presentBndElems;
+ vector<TConnectivity> missingBndElems;
+ TConnectivity nodes;
+ if ( vTool.Set(elem) ) // elem is a volume ------------------------------------------
+ {
+ vTool.SetExternalNormal();
+ for ( int iface = 0, n = vTool.NbFaces(); iface < n; iface++ )
+ {
+ if (!vTool.IsFreeFace(iface))
+ continue;
+ int nbFaceNodes = vTool.NbFaceNodes(iface);
+ const SMDS_MeshNode** nn = vTool.GetFaceNodes(iface);
+ if ( missType == SMDSAbs_Edge ) // boundary edges
+ {
+ nodes.resize( 2+iQuad );
+ for ( int i = 0; i < nbFaceNodes; i += 1+iQuad)
+ {
+ for ( int j = 0; j < nodes.size(); ++j )
+ nodes[j] =nn[i+j];
+ if ( const SMDS_MeshElement* edge =
+ aMesh->FindElement(nodes,SMDSAbs_Edge,/*noMedium=*/0))
+ presentBndElems.push_back( edge );
+ else
+ missingBndElems.push_back( nodes );
+ }
+ }
+ else // boundary face
+ {
+ nodes.clear();
+ for ( inode = 0; inode < nbFaceNodes; inode += 1+iQuad)
+ nodes.push_back( nn[inode] );
+ if (iQuad)
+ for ( inode = 1; inode < nbFaceNodes; inode += 2)
+ nodes.push_back( nn[inode] );
+
+ if (const SMDS_MeshFace * f = aMesh->FindFace( nodes ) )
+ presentBndElems.push_back( f );
+ else
+ missingBndElems.push_back( nodes );
+ }
+ }
+ }
+ else // elem is a face ------------------------------------------
+ {
+ avoidSet.clear(), avoidSet.insert( elem );
+ int nbNodes = elem->NbCornerNodes();
+ nodes.resize( 2 /*+ iQuad*/);
+ for ( int i = 0; i < nbNodes; i++ )
+ {
+ nodes[0] = elem->GetNode(i);
+ nodes[1] = elem->GetNode((i+1)%nbNodes);
+ if ( FindFaceInSet( nodes[0], nodes[1], emptySet, avoidSet))
+ continue; // not free link
+
+ //if ( iQuad )
+ //nodes[2] = elem->GetNode( i + nbNodes );
+ if ( const SMDS_MeshElement* edge =
+ aMesh->FindElement(nodes,SMDSAbs_Edge,/*noMedium=*/true))
+ presentBndElems.push_back( edge );
+ else
+ missingBndElems.push_back( nodes );
+ }
+ }
+
+ // 2. Add missing boundary elements
+ if ( targetMesh != myMesh )
+ // instead of making a map of nodes in this mesh and targetMesh,
+ // we create nodes with same IDs. We can renumber them later, if needed
+ for ( int i = 0; i < missingBndElems.size(); ++i )
+ {
+ TConnectivity& srcNodes = missingBndElems[i];
+ TConnectivity nodes( srcNodes.size() );
+ for ( inode = 0; inode < nodes.size(); ++inode )
+ nodes[inode] = getNodeWithSameID( tgtMeshDS, srcNodes[inode] );
+ tgtEditor.AddElement(nodes, missType, elem->IsPoly() && nodes.size()/(iQuad+1)>4);
+ }
+ else
+ for ( int i = 0; i < missingBndElems.size(); ++i )
+ {
+ TConnectivity& nodes = missingBndElems[i];
+ tgtEditor.AddElement(nodes, missType, elem->IsPoly() && nodes.size()/(iQuad+1)>4);
+ }
+
+ // 3. Copy present boundary elements
+ if ( toCopyExistingBondary )
+ for ( int i = 0 ; i < presentBndElems.size(); ++i )
+ {
+ const SMDS_MeshElement* e = presentBndElems[i];
+ TConnectivity nodes( e->NbNodes() );
+ for ( inode = 0; inode < nodes.size(); ++inode )
+ nodes[inode] = getNodeWithSameID( tgtMeshDS, e->GetNode(inode) );
+ tgtEditor.AddElement(nodes, missType, e->IsPoly());
+ // leave only missing elements in tgtEditor.myLastCreatedElems
+ tgtEditor.myLastCreatedElems.Remove( tgtEditor.myLastCreatedElems.Size() );
+ }
+ } // loop on given elements
+
+ // 4. Fill group with missing boundary elements
+ if ( group )
+ {
+ if ( SMESHDS_Group* g = dynamic_cast<SMESHDS_Group*>( group->GetGroupDS() ))
+ for ( int i = 0; i < tgtEditor.myLastCreatedElems.Size(); ++i )
+ g->SMDSGroup().Add( tgtEditor.myLastCreatedElems( i+1 ));
+ }
+ tgtEditor.myLastCreatedElems.Clear();
+
+ // 5. Copy given elements
+ if ( toCopyElements )
+ {
+ if (elements.empty())
+ eIt = aMesh->elementsIterator(elemType);
+ else
+ eIt = SMDS_ElemIteratorPtr( new TSetIterator( elements.begin(), elements.end() ));
+ while (eIt->more())
+ {
+ const SMDS_MeshElement* elem = eIt->next();
+ TConnectivity nodes( elem->NbNodes() );
+ for ( inode = 0; inode < nodes.size(); ++inode )
+ nodes[inode] = getNodeWithSameID( tgtMeshDS, elem->GetNode(inode) );
+ tgtEditor.AddElement(nodes, elemType, elem->IsPoly());
+
+ tgtEditor.myLastCreatedElems.Clear();
+ }
+ }
+ return;
+}
const TIDSortedElemSet& theNodesNot,
const TopoDS_Shape& theShape );
- /*!
- * \brief Generated skin mesh (containing 2D cells) from 3D mesh
- * The created 2D mesh elements based on nodes of free faces of boundary volumes
- * \return TRUE if operation has been completed successfully, FALSE otherwise
- */
bool Make2DMeshFrom3D();
-
+
+ enum Bnd_Dimension { BND_2DFROM3D, BND_1DFROM3D, BND_1DFROM2D };
+
+ void MakeBoundaryMesh(const TIDSortedElemSet& elements,
+ Bnd_Dimension dimension,
+ SMESH_Group* group = 0,
+ SMESH_Mesh* targetMesh = 0,
+ bool toCopyElements = false,
+ bool toCopyExistingBondary = false);
+
private:
/*!
static_cast<const SMDS_FacePosition*>(n->GetPosition().get());
uv.SetCoord(fpos->GetUParameter(),fpos->GetVParameter());
if ( check )
- uvOK = CheckNodeUV( F, n, uv.ChangeCoord(), 2*BRep_Tool::Tolerance( F ));
+ uvOK = CheckNodeUV( F, n, uv.ChangeCoord(), 10*MaxTolerance( F ));
}
else if(Pos->GetTypeOfPosition()==SMDS_TOP_EDGE)
{
else
uv.SetCoord(0.,0.);
if ( check || !validU )
- uvOK = CheckNodeUV( F, n, uv.ChangeCoord(), 2*BRep_Tool::Tolerance( E ),/*force=*/ !validU );
+ uvOK = CheckNodeUV( F, n, uv.ChangeCoord(), 10*MaxTolerance( F ),/*force=*/ !validU );
// for a node on a seam edge select one of UVs on 2 pcurves
if ( n2 && IsSeamShape( edgeID ) )
shape.ShapeType() == TopAbs_COMPOUND && aMesh->GetMeshDS()->IsGroupOfSubShapes( shape );
}
+//================================================================================
+/*!
+ * \brief Return maximal tolerance of shape
+ */
+//================================================================================
+
+double SMESH_MesherHelper::MaxTolerance( const TopoDS_Shape& shape )
+{
+ double tol = Precision::Confusion();
+ TopExp_Explorer exp;
+ for ( exp.Init( shape, TopAbs_FACE ); exp.More(); exp.Next() )
+ tol = Max( tol, BRep_Tool::Tolerance( TopoDS::Face( exp.Current())));
+ for ( exp.Init( shape, TopAbs_EDGE ); exp.More(); exp.Next() )
+ tol = Max( tol, BRep_Tool::Tolerance( TopoDS::Edge( exp.Current())));
+ for ( exp.Init( shape, TopAbs_VERTEX ); exp.More(); exp.Next() )
+ tol = Max( tol, BRep_Tool::Tolerance( TopoDS::Vertex( exp.Current())));
+
+ return tol;
+}
+
//=======================================================================
//function : IsQuadraticMesh
//purpose : Check mesh without geometry for: if all elements on this shape are quadratic,
static bool IsSubShape( const TopoDS_Shape& shape, SMESH_Mesh* aMesh );
+ static double MaxTolerance( const TopoDS_Shape& shape );
+
public:
// ---------- PUBLIC INSTANCE METHODS ----------
SalomeApp_Application* anApp = dynamic_cast<SalomeApp_Application*>( SUIT_Session::session()->activeApplication() );
SUIT_ViewManager* vm = anApp->activeViewManager();
- int nbSf = vm->getViewsCount();
+ int nbSf = vm ? vm->getViewsCount() : 0;
SALOME_ListIteratorOfListIO It(selected);
std::string anEntry = SO->GetID();
/** Erase graphical object **/
- if(SO->FindAttribute(anAttr, "AttributeIOR")){
+ if(SO->FindAttribute(anAttr, "AttributeIOR") && vm ){
QVector<SUIT_ViewWindow*> aViews = vm->getViews();
for(int i = 0; i < nbSf; i++){
SUIT_ViewWindow *sf = aViews[i];
return 0;
}
-bool SMESHGUI::automaticUpdate()
+//=============================================================================
+/*!
+ *
+ */
+//=============================================================================
+bool SMESHGUI::automaticUpdate(unsigned int requestedSize, bool* limitExceeded)
{
SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr();
if ( !resMgr )
return false;
- return resMgr->booleanValue( "SMESH", "auto_update", false );
+ bool autoUpdate = resMgr->booleanValue( "SMESH", "auto_update", false );
+ long updateLimit = resMgr->integerValue( "SMESH", "update_limit", 500000 );
+ bool exceeded = updateLimit > 0 && requestedSize > updateLimit;
+ if ( limitExceeded ) *limitExceeded = autoUpdate && exceeded;
+ return autoUpdate && !exceeded;
}
//=============================================================================
// General tab ------------------------------------------------------------------------
int genTab = addPreference( tr( "PREF_TAB_GENERAL" ) );
- int updateGroup = addPreference( tr( "PREF_GROUP_UPDATE" ), genTab );
- addPreference( tr( "PREF_AUTO_UPDATE" ), updateGroup, LightApp_Preferences::Bool, "SMESH", "auto_update" );
+ int autoUpdate = addPreference( tr( "PREF_AUTO_UPDATE" ), genTab, LightApp_Preferences::Auto, "SMESH", "auto_update" );
+ int lim = addPreference( tr( "PREF_UPDATE_LIMIT" ), autoUpdate, LightApp_Preferences::IntSpin, "SMESH", "update_limit" );
+ setPreferenceProperty( lim, "min", 0 );
+ setPreferenceProperty( lim, "max", 100000000 );
+ setPreferenceProperty( lim, "step", 1000 );
+ setPreferenceProperty( lim, "special", tr( "PREF_UPDATE_LIMIT_NOLIMIT" ) );
int qaGroup = addPreference( tr( "PREF_GROUP_QUALITY" ), genTab );
setPreferenceProperty( qaGroup, "columns", 2 );
bool isActiveStudyLocked();
- static bool automaticUpdate();
+ static bool automaticUpdate(unsigned int requestedSize = 0, bool* limitExceeded = 0);
static void Modified( bool = true );
#define COLONIZE(str) (QString(str).contains(":") > 0 ? QString(str) : QString(str) + " :" )
+/* OBSOLETE
static void addSeparator( QWidget* parent )
{
QGridLayout* l = qobject_cast<QGridLayout*>( parent->layout() );
l->addWidget( hline, row, i );
}
}
+*/
enum TCol {
COL_ALGO = 0, COL_SHAPE, COL_ERROR, COL_SHAPEID, COL_PUBLISHED, COL_BAD_MESH, NB_COLUMNS
// SHOW MESH
// NPAL16631: if ( getSMESHGUI()->automaticUpdate() )
- if ( !memoryLack && getSMESHGUI()->automaticUpdate() )
+ SUIT_ResourceMgr* resMgr = SMESH::GetResourceMgr( SMESHGUI::GetSMESHGUI() );
+ long newSize = myMesh->NbElements();
+ long limitSize = resMgr->integerValue( "SMESH", "update_limit", 500000 );
+ bool limitExceeded;
+ if ( !memoryLack )
{
- try {
+ if ( getSMESHGUI()->automaticUpdate( newSize, &limitExceeded ) )
+ {
+ try {
#if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
- OCC_CATCH_SIGNALS;
+ OCC_CATCH_SIGNALS;
#endif
- SMESH::Update(myIObject, true);
- }
- catch (...) {
+ SMESH::Update(myIObject, true);
+ }
+ catch (...) {
#ifdef _DEBUG_
- MESSAGE ( "Exception thrown during mesh visualization" );
+ MESSAGE ( "Exception thrown during mesh visualization" );
#endif
- if ( SMDS_Mesh::CheckMemory(true) ) { // has memory to show warning?
- SMESH::OnVisuException();
- }
- else {
- memoryLack = true;
- }
+ if ( SMDS_Mesh::CheckMemory(true) ) { // has memory to show warning?
+ SMESH::OnVisuException();
+ }
+ else {
+ memoryLack = true;
+ }
+ }
}
+ else if ( limitExceeded )
+ {
+ SUIT_MessageBox::warning( desktop(),
+ tr( "SMESH_WRN_WARNING" ),
+ tr( "SMESH_WRN_SIZE_LIMIT_EXCEEDED" ).arg( newSize ).arg( limitSize ) );
+ }
}
LightApp_SelectionMgr *Sel = selectionMgr();
if ( Sel )
void SMESHGUI_BaseComputeOp::showComputeResult( const bool theMemoryLack,
const bool theNoCompError,
SMESH::compute_error_array_var& theCompErrors,
- const bool theNoHypoError,
+ const bool theNoHypoError,
const QString& theHypErrors )
{
bool hasShape = myMesh->HasShapeToMesh();
SMESH::MeshPreviewStruct_var previewData =
gen->Precompute(myMesh, myMainShape, (SMESH::Dimension)dim, aShapesId);
+
SMESH::MeshPreviewStruct* previewRes = previewData._retn();
if ( previewRes && previewRes->nodesXYZ.length() > 0 )
{
#include "SMESHGUI_Filter.h"
#include "SMESHGUI_FilterUtils.h"
#include "SMESHGUI_FilterLibraryDlg.h"
+#include "SMESHGUI_SpinBox.h"
#include <SMESH_Actor.h>
#include <SMESH_NumberFilter.hxx>
#include <SMESH_TypeFilter.hxx>
-#include <SMESHGUI_SpinBox.h>
// SALOME GEOM includes
#include <GEOMBase.h>
}
if (!valid && theMsg) {
SUIT_MessageBox::information(SMESHGUI::desktop(), tr("SMESH_INSUFFICIENT_DATA"),
- tr("SMESHGUI_INVALID_PARAMETERS"));
+ tr("SMESHGUI_INVALID_PARAMETERS"));
return false;
}
}
if ( qobject_cast<SMESHGUI_SpinBox*>( myWidgets[ theId ] ) ) {
SMESHGUI_SpinBox* sb = qobject_cast<SMESHGUI_SpinBox*>( myWidgets[ theId ] );
double val = sb->GetValue();
- double min = pow(10, -(sb->decimals()));
+ double min = pow(10.0, -(sb->decimals()));
sb->RangeStepAndValidator( 0., 1.e20, 0.1, precision ? precision : "len_tol_precision" );
sb->SetValue( qMax( val, min ) );
}
QtxColorButton* clrBtn = qobject_cast<QtxColorButton*>(aTable->cellWidget(i, 2));
if (clrBtn && !clrBtn->color().isValid())
errMsg = tr( "GROUPCOLOR_ERROR" );
- } else if (aCriterion == SMESH::FT_RangeOfIds ||
- aCriterion == SMESH::FT_BelongToGeom ||
- aCriterion == SMESH::FT_BelongToPlane ||
- aCriterion == SMESH::FT_BelongToCylinder ||
- aCriterion == SMESH::FT_BelongToGenSurface ||
- aCriterion == SMESH::FT_ElemGeomType ||
- aCriterion == SMESH::FT_LyingOnGeom) {
+ }
+ else if (aCriterion == SMESH::FT_RangeOfIds ||
+ aCriterion == SMESH::FT_BelongToGeom ||
+ aCriterion == SMESH::FT_BelongToPlane ||
+ aCriterion == SMESH::FT_BelongToCylinder ||
+ aCriterion == SMESH::FT_BelongToGenSurface ||
+ aCriterion == SMESH::FT_ElemGeomType ||
+ aCriterion == SMESH::FT_CoplanarFaces ||
+ aCriterion == SMESH::FT_LyingOnGeom)
+ {
if (aTable->text(i, 2).isEmpty())
errMsg = tr( "ERROR" );
}
if (!aRes && aTable->isEditable(i, 2))
errMsg = tr( "ERROR" );
else if (aType == SMESH::EDGE &&
- GetCriterionType(i, aType) == SMESH::FT_MultiConnection &&
- aThreshold == 1)
+ GetCriterionType(i, aType) == SMESH::FT_MultiConnection &&
+ aThreshold == 1)
errMsg = tr( "MULTIEDGES_ERROR" );
}
}
else if ( aCriterionType == SMESH::FT_ElemGeomType )
theCriterion.Threshold = (double)((ComboItem*)aTable->item(theRow, 2))->value();
+ else if ( aCriterionType == SMESH::FT_CoplanarFaces )
+ theCriterion.ThresholdID = aTable->text(theRow, 2).toLatin1().constData();
else if ( aCriterionType != SMESH::FT_RangeOfIds &&
aCriterionType != SMESH::FT_BelongToGeom &&
aCriterionType != SMESH::FT_BelongToPlane &&
aCriterionType != SMESH::FT_BelongToCylinder &&
aCriterionType != SMESH::FT_BelongToGenSurface &&
- aCriterionType != SMESH::FT_LyingOnGeom)
+ aCriterionType != SMESH::FT_LyingOnGeom )
{
theCriterion.Compare = ((ComboItem*)aTable->item(theRow, 1))->value();
theCriterion.Threshold = aTable->item(theRow, 2)->text().toDouble();
ComboItem* typeBox = (ComboItem*)aTable->item(theRow, 2);
typeBox->setValue( (int)(theCriterion.Threshold + 0.5) );
}
+ else if (theCriterion.Type == SMESH::FT_CoplanarFaces )
+ {
+ aTable->item( theRow, 2 )->setText( QString( theCriterion.ThresholdID ) );
+ }
else if (theCriterion.Type != SMESH::FT_RangeOfIds &&
- theCriterion.Type != SMESH::FT_BelongToGeom &&
- theCriterion.Type != SMESH::FT_BelongToPlane &&
- theCriterion.Type != SMESH::FT_BelongToCylinder &&
- theCriterion.Type != SMESH::FT_BelongToGenSurface &&
- theCriterion.Type != SMESH::FT_LyingOnGeom &&
- theCriterion.Type != SMESH::FT_FreeBorders &&
- theCriterion.Type != SMESH::FT_FreeEdges &&
- theCriterion.Type != SMESH::FT_FreeNodes &&
- theCriterion.Type != SMESH::FT_FreeFaces &&
- theCriterion.Type != SMESH::FT_BadOrientedVolume &&
- theCriterion.Type != SMESH::FT_LinearOrQuadratic)
+ theCriterion.Type != SMESH::FT_BelongToGeom &&
+ theCriterion.Type != SMESH::FT_BelongToPlane &&
+ theCriterion.Type != SMESH::FT_BelongToCylinder &&
+ theCriterion.Type != SMESH::FT_BelongToGenSurface &&
+ theCriterion.Type != SMESH::FT_LyingOnGeom &&
+ theCriterion.Type != SMESH::FT_CoplanarFaces &&
+ theCriterion.Type != SMESH::FT_FreeBorders &&
+ theCriterion.Type != SMESH::FT_FreeEdges &&
+ theCriterion.Type != SMESH::FT_FreeNodes &&
+ theCriterion.Type != SMESH::FT_FreeFaces &&
+ theCriterion.Type != SMESH::FT_BadOrientedVolume &&
+ theCriterion.Type != SMESH::FT_LinearOrQuadratic)
+ {
aTable->item( theRow, 2 )->setText(QString("%1").arg(theCriterion.Threshold, 0, 'g', 15));
+ }
else
{
aTable->item( theRow, 2 )->setText(QString(theCriterion.ThresholdStr));
aTable->item( theRow, 5 )->setText( QString( theCriterion.ThresholdID ) );
}
- if (theCriterion.Compare == SMESH::FT_EqualTo ||
- theCriterion.Type == SMESH::FT_BelongToPlane ||
- theCriterion.Type == SMESH::FT_BelongToCylinder ||
- theCriterion.Type == SMESH::FT_BelongToGenSurface ||
- theCriterion.Type == SMESH::FT_BelongToGeom ||
- theCriterion.Type == SMESH::FT_LyingOnGeom)
+ if (theCriterion.Compare == SMESH::FT_EqualTo ||
+ theCriterion.Type == SMESH::FT_BelongToPlane ||
+ theCriterion.Type == SMESH::FT_BelongToCylinder ||
+ theCriterion.Type == SMESH::FT_BelongToGenSurface ||
+ theCriterion.Type == SMESH::FT_BelongToGeom ||
+ theCriterion.Type == SMESH::FT_LyingOnGeom ||
+ theCriterion.Type == SMESH::FT_CoplanarFaces)
{
QTableWidgetItem* anItem = aTable->item(theRow, 0);
if (!myAddWidgets.contains(anItem))
{
myAddWidgets[ anItem ] = new AdditionalWidget(myWgStack);
+ myAddWidgets[ anItem ]->SetPrecision( AdditionalWidget::Tolerance, getPrecision( theCriterion.Type ) );
myWgStack->addWidget(myAddWidgets[ anItem ]);
}
myAddWidgets[ anItem ]->SetDouble(AdditionalWidget::Tolerance, theCriterion.Tolerance);
}
emit CriterionChanged(theRow, aType);
-
}
//=======================================================================
ComboItem* anItem = ((ComboItem*)aTable->item(aRow, 0));
int aCriterion = GetCriterionType(aRow);
- bool toEnable = ((ComboItem*)aTable->item(aRow, 1))->value() == SMESH::FT_EqualTo &&
- aCriterion != SMESH::FT_RangeOfIds &&
- aCriterion != SMESH::FT_FreeEdges &&
- aCriterion != SMESH::FT_FreeFaces &&
- aCriterion != SMESH::FT_BadOrientedVolume;
+ bool toEnable = ((((ComboItem*)aTable->item(aRow, 1))->value() == SMESH::FT_EqualTo &&
+ aCriterion != SMESH::FT_RangeOfIds &&
+ aCriterion != SMESH::FT_FreeEdges &&
+ aCriterion != SMESH::FT_FreeFaces &&
+ aCriterion != SMESH::FT_BadOrientedVolume)
+ ||
+ aCriterion == SMESH::FT_CoplanarFaces);
if (!myAddWidgets.contains(anItem))
{
case SMESH::FT_Warping:
case SMESH::FT_MinimumAngle:
case SMESH::FT_Skew:
+ case SMESH::FT_CoplanarFaces:
retval = "angle_precision"; break;
case SMESH::FT_Area:
retval = "area_precision"; break;
bool isComboItem = false;
if (aTableItem) {
int aTableType = aTable->item(row, 2)->type();
- isComboItem = aTableType == aComboType ? true : false;
+ isComboItem = ( aTableType == aComboType );
}
if ( (aCriterionType != SMESH::FT_GroupColor && clrBtn) ||
aTable->blockSignals( isSignalsBlocked );
}
- if (aType == SMESH::NODE && aCriterionType == SMESH::FT_FreeNodes ||
- aType == SMESH::EDGE && aCriterionType == SMESH::FT_FreeBorders ||
- aType == SMESH::FACE && (aCriterionType == SMESH::FT_FreeEdges ||
- aCriterionType == SMESH::FT_FreeFaces) ||
- aType == SMESH::VOLUME && aCriterionType == SMESH::FT_BadOrientedVolume ||
+ if ((aType == SMESH::NODE && aCriterionType == SMESH::FT_FreeNodes ) ||
+ (aType == SMESH::EDGE && aCriterionType == SMESH::FT_FreeBorders ) ||
+ (aType == SMESH::FACE && (aCriterionType == SMESH::FT_FreeEdges ||
+ aCriterionType == SMESH::FT_FreeFaces)) ||
+ (aType == SMESH::VOLUME && aCriterionType == SMESH::FT_BadOrientedVolume) ||
aCriterionType == SMESH::FT_LinearOrQuadratic ||
aCriterionType == SMESH::FT_GroupColor ||
- aCriterionType == SMESH::FT_ElemGeomType)
+ aCriterionType == SMESH::FT_ElemGeomType ||
+ aCriterionType == SMESH::FT_CoplanarFaces
+ )
{
bool isSignalsBlocked = aTable->signalsBlocked();
aTable->blockSignals( true );
aCompareItem->clear();
aTable->setEditable(false, row, 1);
aTable->setEditable(aCriterionType == SMESH::FT_GroupColor ||
- aCriterionType == SMESH::FT_ElemGeomType, row, 2);
+ aCriterionType == SMESH::FT_ElemGeomType ||
+ aCriterionType == SMESH::FT_CoplanarFaces, row, 2);
aTable->blockSignals( isSignalsBlocked );
}
else if (aCriterionType == SMESH::FT_RangeOfIds ||
aCriteria[ SMESH::FT_LinearOrQuadratic ] = tr("LINEAR");
aCriteria[ SMESH::FT_GroupColor ] = tr("GROUP_COLOR");
aCriteria[ SMESH::FT_ElemGeomType ] = tr("GEOM_TYPE");
+ aCriteria[ SMESH::FT_CoplanarFaces ] = tr("COPLANAR_FACES");
}
return aCriteria;
}
// Purpose : Set text and internal value in cell of ID value
//=======================================================================
void SMESHGUI_FilterTable::SetID( const int theRow,
- const QString& theText,
- const int theEntityType )
+ const QString& theText,
+ const int theEntityType )
{
Table* aTable = myTables[ theEntityType == -1 ? GetType() : theEntityType ];
aTable->item( theRow, 5 )->setText( theText );
aType == SMESH::FT_BelongToPlane ||
aType == SMESH::FT_BelongToCylinder ||
aType == SMESH::FT_BelongToGenSurface ||
- aType == SMESH::FT_LyingOnGeom) {
+ aType == SMESH::FT_LyingOnGeom)
+ {
QString aName;
myTable->GetThreshold(i, aName);
}
}
}
+ else if (aType == SMESH::FT_CoplanarFaces)
+ {
+ QString faceID;
+ myTable->GetThreshold(i, faceID);
+ if ( faceID.isEmpty() )
+ {
+ SUIT_MessageBox::information(SMESHGUI::desktop(), tr("SMESH_INSUFFICIENT_DATA"),
+ tr("FACE_ID_NOT_SELECTED"));
+ return false;
+ }
+ if ( myMesh->_is_nil() )
+ {
+ SUIT_MessageBox::information(SMESHGUI::desktop(), tr("SMESH_INSUFFICIENT_DATA"),
+ tr("MESH_IS_NOT_SELECTED"));
+ return false;
+ }
+ if ( myMesh->GetElementType( faceID.toLong(), /*iselem=*/true) != SMESH::FACE )
+ {
+ SUIT_MessageBox::information(SMESHGUI::desktop(), tr("SMESH_INSUFFICIENT_DATA"),
+ tr("NOT_FACE_ID").arg(faceID));
+ return false;
+ }
+ }
}
return true;
}
//=======================================================================
-// name : SMESHGUI_FilterDlg::SetGroupIds
+// name : SMESHGUI_FilterDlg::SetMesh
// Purpose : Set mesh
//=======================================================================
void SMESHGUI_FilterDlg::SetMesh (SMESH::SMESH_Mesh_var theMesh)
QList<int> types;
types << SMESH::FT_BelongToGeom << SMESH::FT_BelongToPlane
<< SMESH::FT_BelongToCylinder << SMESH::FT_BelongToGenSurface
- << SMESH::FT_LyingOnGeom;
+ << SMESH::FT_LyingOnGeom << SMESH::FT_CoplanarFaces;
if (aList.Extent() != 1 || !myTable->CurrentCell(aRow, aCol) ||
!types.contains(myTable->GetCriterionType(aRow)))
return;
- Handle(SALOME_InteractiveObject) anIO = aList.First();
- GEOM::GEOM_Object_var anObj = SMESH::IObjectToInterface<GEOM::GEOM_Object>(anIO);
- if (!anObj->_is_nil())
+ if ( myTable->GetCriterionType(aRow) == SMESH::FT_CoplanarFaces )
+ {
+ QString aString;
+ int nbElems = SMESH::GetNameOfSelectedElements(mySelector,//myViewWindow->GetSelector(),
+ aList.First(), aString);
+ if (nbElems == 1)
+ myTable->SetThreshold(aRow, aString);
+ }
+ else
+ {
+ Handle(SALOME_InteractiveObject) anIO = aList.First();
+ GEOM::GEOM_Object_var anObj = SMESH::IObjectToInterface<GEOM::GEOM_Object>(anIO);
+ if (!anObj->_is_nil())
{
myTable->SetThreshold(aRow, GEOMBase::GetName(anObj));
//myTable->SetID( aRow, GEOMBase::GetIORFromObject(anObj));
myTable->SetID(aRow, anIO->getEntry());
}
+ }
}
if (mySelectionMgr == 0)
return;
- TColStd_MapOfInteger allTypes;
- for( int i=0; i<10; i++ )
- allTypes.Add( i );
+// TColStd_MapOfInteger allTypes;
+// for( int i=0; i<10; i++ )
+// allTypes.Add( i );
SalomeApp_Study* aStudy = dynamic_cast<SalomeApp_Study*>( mySMESHGUI->application()->activeStudy() );
if( !aStudy )
return;
aCriterionType == SMESH::FT_BelongToPlane ||
aCriterionType == SMESH::FT_BelongToCylinder ||
aCriterionType == SMESH::FT_BelongToGenSurface ||
- aCriterionType == SMESH::FT_LyingOnGeom)) {
-
+ aCriterionType == SMESH::FT_LyingOnGeom))
+ {
if (aCriterionType == SMESH::FT_BelongToGeom ||
aCriterionType == SMESH::FT_BelongToGenSurface ||
aCriterionType == SMESH::FT_LyingOnGeom) {
}
myIsSelectionChanged = true;
- } else {
+ }
+ else
+ {
if (myIsSelectionChanged) {
- mySelectionMgr->installFilter( new GEOM_TypeFilter( aStudy, -1 ) ); // This filter deactivates selection
+ // mySelectionMgr->installFilter( new GEOM_TypeFilter( aStudy, -1 ) ); // This filter deactivates selection
+ // Impossible to select any object in the OB on the second opening of FilterDlg
}
}
}
if ( !aStudy ) return false;
// mesh
- _PTR(SObject) meshSO = aStudy->FindObjectID( myMeshID.toLatin1().data() );
+ _PTR(SObject) meshSO = aStudy->FindObjectID( myMeshID.toLatin1().data() );
SMESH::SMESH_Mesh_var mesh = SMESH::SObjectToInterface<SMESH::SMESH_Mesh>( meshSO );
if ( mesh->_is_nil() ) return false;
update( UF_ObjBrowser | UF_Model );
- init();
+ // Re-init controls to create the next group
+ myElemGeoIDs.clear();
+ myNodeGeoIDs.clear();
+ removeCustomFilters();
+ myDlg->myNodeGeomList->clear();
+ myDlg->myElemGeomList->clear();
+ myDlg->myElemGeomBtn->setChecked(false);
+ myDlg->myNodeGeomBtn->setChecked(false);
+ myDlg->updateButtons();
return !group->_is_nil();
}
//
// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
//
+// File : SMESHGUI_Make2DFrom3D.cxx
+// Author : Vadim SANDLER, Open CASCADE S.A.S. (vadim.sandler@opencascade.com)
-// File : SMESHGUI_Make2DFrom3DOp.cxx
-// Author : Open CASCADE S.A.S.
-// SMESH includes
-//
#include "SMESHGUI_Make2DFrom3DOp.h"
#include "SMESHGUI.h"
#include "SMESHGUI_Utils.h"
-#include "SMESHGUI_VTKUtils.h"
#include "SMESHGUI_MeshUtils.h"
-#include "SMESHGUI_MeshInfosBox.h"
+#include "SMESH_TypeFilter.hxx"
+#include "SMESH_LogicalFilter.hxx"
// SALOME GUI includes
-#include <LightApp_SelectionMgr.h>
-
+#include <LightApp_UpdateFlags.h>
+#include <SalomeApp_Tools.h>
+#include <SalomeApp_Study.h>
#include <SUIT_Desktop.h>
#include <SUIT_MessageBox.h>
-#include <SUIT_ResourceMgr.h>
#include <SUIT_OverrideCursor.h>
-#include <SALOME_ListIO.hxx>
-
-// SALOME KERNEL includes
-#include <SALOMEDS_SObject.hxx>
-#include <SALOMEDSClient_SObject.hxx>
-
-// Qt includes
// IDL includes
#include <SALOMEconfig.h>
-#include CORBA_SERVER_HEADER(SMESH_Gen)
-#include CORBA_SERVER_HEADER(SMESH_MeshEditor)
+#include CORBA_SERVER_HEADER(SMESH_Group)
-#include <QFrame>
-#include <QLabel>
-#include <QPixmap>
+// Qt includes
#include <QGroupBox>
-#include <QPushButton>
-#include <QVBoxLayout>
-
-// MESH includes
-#include "SMDSAbs_ElementType.hxx"
-#include "SMDSAbs_ElementType.hxx"
-
+#include <QRadioButton>
+#include <QLineEdit>
+#include <QCheckBox>
+#include <QHBoxLayout>
+#include <QGridLayout>
#define SPACING 6
#define MARGIN 11
-// =========================================================================================
/*!
- * \brief Dialog to show creted mesh statistic
- */
-//=======================================================================
+ \class SMESHGUI_Make2DFrom3DDlg
+ \brief Copy Mesh dialog box
+*/
SMESHGUI_Make2DFrom3DDlg::SMESHGUI_Make2DFrom3DDlg( QWidget* parent )
- : SMESHGUI_Dialog( parent, false, true, Close/* | Help*/ )
+ : SMESHGUI_Dialog( parent, false, true, OK | Apply | Close | Help )
{
+ // title
setWindowTitle( tr("CAPTION") );
- QVBoxLayout* aDlgLay = new QVBoxLayout (mainFrame());
+
+ // mesh
+ setObjectPixmap( "SMESH", tr( "ICON_SELECT" ) );
+ createObject( tr( "MESH" ), mainFrame(), Mesh );
+
+ // mode
+ QGroupBox* aModeGrp = new QGroupBox( tr( "MODE" ), mainFrame() );
+ QHBoxLayout* aModeGrpLayout = new QHBoxLayout( aModeGrp );
+ aModeGrpLayout->setMargin( MARGIN );
+ aModeGrpLayout->setSpacing( SPACING );
+ my2dFrom3dRB = new QRadioButton( tr( "2D_FROM_3D" ), aModeGrp );
+ my1dFrom2dRB = new QRadioButton( tr( "1D_FROM_2D" ), aModeGrp );
+ my1dFrom3dRB = new QRadioButton( tr( "1D_FROM_3D" ), aModeGrp );
+ aModeGrpLayout->addWidget( my2dFrom3dRB );
+ aModeGrpLayout->addWidget( my1dFrom2dRB );
+ aModeGrpLayout->addWidget( my1dFrom3dRB );
+
+ // target
+ QGroupBox* aTargetGrp = new QGroupBox( tr( "TARGET" ), mainFrame() );
+ QGridLayout* aTargetGrpLayout = new QGridLayout( aTargetGrp );
+ aTargetGrpLayout->setMargin( MARGIN );
+ aTargetGrpLayout->setSpacing( SPACING );
+ myThisMeshRB = new QRadioButton( tr( "THIS_MESH" ), aTargetGrp );
+ myNewMeshRB = new QRadioButton( tr( "NEW_MESH" ), aTargetGrp );
+ myMeshName = new QLineEdit( aTargetGrp );
+ myCopyCheck = new QCheckBox( tr( "COPY_SRC" ), aTargetGrp );
+ myMissingCheck = new QCheckBox( tr( "MISSING_ONLY" ), aTargetGrp );
+ aTargetGrpLayout->addWidget( myThisMeshRB, 0, 0 );
+ aTargetGrpLayout->addWidget( myNewMeshRB, 1, 0 );
+ aTargetGrpLayout->addWidget( myMeshName, 1, 1 );
+ aTargetGrpLayout->addWidget( myCopyCheck, 2, 0 );
+ aTargetGrpLayout->addWidget( myMissingCheck, 2, 1 );
+ myGroupCheck = new QCheckBox( tr( "CREATE_GROUP" ), mainFrame() );
+ myGroupName = new QLineEdit( mainFrame() );
+
+ // layout
+ QGridLayout* aDlgLay = new QGridLayout( mainFrame() );
aDlgLay->setMargin( 0 );
aDlgLay->setSpacing( SPACING );
- QFrame* aMainFrame = createMainFrame(mainFrame());
- aDlgLay->addWidget(aMainFrame);
- aDlgLay->setStretchFactor(aMainFrame, 1);
+ aDlgLay->addWidget( objectWg( Mesh, Label ), 0, 0 );
+ aDlgLay->addWidget( objectWg( Mesh, Btn ), 0, 1 );
+ aDlgLay->addWidget( objectWg( Mesh, Control ), 0, 2 );
+ aDlgLay->addWidget( aModeGrp, 1, 0, 1, 3 );
+ aDlgLay->addWidget( aTargetGrp, 2, 0, 1, 3 );
+ aDlgLay->addWidget( myGroupCheck, 3, 0 );
+ aDlgLay->addWidget( myGroupName, 3, 1, 1, 2 );
+
+ // connect signals
+ connect( myThisMeshRB, SIGNAL( clicked() ), this, SLOT( onTargetChanged() ) );
+ connect( myNewMeshRB, SIGNAL( clicked() ), this, SLOT( onTargetChanged() ) );
+ connect( myGroupCheck, SIGNAL( clicked() ), this, SLOT( onGroupChecked() ) );
+
+ // init dlg
+ my2dFrom3dRB->setChecked( true );
+ myThisMeshRB->setChecked( true );
+ myMissingCheck->setChecked( true );
+ onTargetChanged();
+ onGroupChecked();
}
-// =========================================================================================
-/*!
- * \brief Dialog destructor
- */
-//=======================================================================
-
SMESHGUI_Make2DFrom3DDlg::~SMESHGUI_Make2DFrom3DDlg()
{
}
-//=======================================================================
-// function : createMainFrame()
-// purpose : Create frame containing dialog's fields
-//=======================================================================
-
-QFrame* SMESHGUI_Make2DFrom3DDlg::createMainFrame (QWidget* theParent)
+SMESH::Bnd_Dimension SMESHGUI_Make2DFrom3DDlg::mode() const
{
- QFrame* aFrame = new QFrame(theParent);
+ if ( my2dFrom3dRB->isChecked() )
+ return SMESH::BND_2DFROM3D;
+ else if ( my1dFrom2dRB->isChecked() )
+ return SMESH::BND_1DFROM2D;
+ else
+ return SMESH::BND_1DFROM3D;
+}
- SUIT_ResourceMgr* rm = resourceMgr();
- QPixmap iconCompute (rm->loadPixmap("SMESH", tr("ICON_2D_FROM_3D")));
+bool SMESHGUI_Make2DFrom3DDlg::needNewMesh() const
+{
+ return myNewMeshRB->isChecked();
+}
- // Mesh name
- QGroupBox* nameBox = new QGroupBox(tr("SMESH_MESHINFO_NAME"), aFrame );
- QHBoxLayout* nameBoxLayout = new QHBoxLayout(nameBox);
- nameBoxLayout->setMargin(MARGIN); nameBoxLayout->setSpacing(SPACING);
- myMeshName = new QLabel(nameBox);
- nameBoxLayout->addWidget(myMeshName);
+QString SMESHGUI_Make2DFrom3DDlg::getNewMeshName() const
+{
+ return myMeshName->text().trimmed();
+}
- // Mesh Info
+void SMESHGUI_Make2DFrom3DDlg::setNewMeshName( const QString& name )
+{
+ myMeshName->setText( name );
+}
- myFullInfo = new SMESHGUI_MeshInfosBox(true, aFrame);
+bool SMESHGUI_Make2DFrom3DDlg::needGroup() const
+{
+ return myGroupCheck->isChecked();
+}
- // add all widgets to aFrame
- QVBoxLayout* aLay = new QVBoxLayout(aFrame);
- aLay->setMargin( 0 );
- aLay->setSpacing( 0 );
- aLay->addWidget( nameBox );
- aLay->addWidget( myFullInfo );
+QString SMESHGUI_Make2DFrom3DDlg::getGroupName() const
+{
+ return myGroupName->text().trimmed();
+}
- ((QPushButton*) button( OK ))->setDefault( true );
- return aFrame;
+void SMESHGUI_Make2DFrom3DDlg::setGroupName( const QString& name )
+{
+ myGroupName->setText( name );
}
-//================================================================================
-/*!
- * \brief set name of the mesh
-*/
-//================================================================================
+bool SMESHGUI_Make2DFrom3DDlg::copySource() const
+{
+ return myCopyCheck->isChecked();
+}
-void SMESHGUI_Make2DFrom3DDlg::SetMeshName(const QString& theName)
+bool SMESHGUI_Make2DFrom3DDlg::copyMissingOnly() const
{
- myMeshName->setText( theName );
+ return myMissingCheck->isChecked();
}
-//================================================================================
-/*!
- * \brief set mesh info
-*/
-//================================================================================
+void SMESHGUI_Make2DFrom3DDlg::onTargetChanged()
+{
+ myMeshName->setEnabled( myNewMeshRB->isChecked() );
+ myCopyCheck->setEnabled( myNewMeshRB->isChecked() );
+ myMissingCheck->setEnabled( myNewMeshRB->isChecked() );
+}
-void SMESHGUI_Make2DFrom3DDlg::SetMeshInfo(const SMESH::long_array& theInfo)
+void SMESHGUI_Make2DFrom3DDlg::onGroupChecked()
{
- myFullInfo->SetMeshInfo( theInfo );
+ myGroupName->setEnabled( myGroupCheck->isChecked() );
}
-//================================================================================
/*!
- * \brief Constructor
+ \class SMESHGUI_Make2DFrom3DOp
+ \brief Copy Mesh operation class
*/
-//================================================================================
SMESHGUI_Make2DFrom3DOp::SMESHGUI_Make2DFrom3DOp()
- : SMESHGUI_Operation()
+ : SMESHGUI_SelectionOp()
{
- myDlg = new SMESHGUI_Make2DFrom3DDlg(desktop());
}
-//================================================================================
-/*!
- * \brief Desctructor
-*/
-//================================================================================
-
SMESHGUI_Make2DFrom3DOp::~SMESHGUI_Make2DFrom3DOp()
{
+ if ( myDlg )
+ delete myDlg;
}
-//================================================================================
-/*!
- * \brief perform it's intention action: compute 2D mesh on 3D
- */
-//================================================================================
+LightApp_Dialog* SMESHGUI_Make2DFrom3DOp::dlg() const
+{
+ return myDlg;
+}
void SMESHGUI_Make2DFrom3DOp::startOperation()
{
- myMesh = SMESH::SMESH_Mesh::_nil();
+ if( !myDlg )
+ myDlg = new SMESHGUI_Make2DFrom3DDlg( desktop() );
+
+ mySrc = SMESH::SMESH_IDSource::_nil();
- // check selection
- LightApp_SelectionMgr *Sel = selectionMgr();
- SALOME_ListIO selected; Sel->selectedObjects( selected );
+ myHelpFileName = "make_2dmesh_from_3d_page.html";
- int nbSel = selected.Extent();
- if (nbSel != 1) {
- SUIT_MessageBox::warning(desktop(),
- tr("SMESH_WRN_WARNING"),
- tr("SMESH_WRN_NO_AVAILABLE_DATA"));
- onCancel();
- return;
- }
+ SMESHGUI_SelectionOp::startOperation();
+
+ myDlg->activateObject( SMESHGUI_Make2DFrom3DDlg::Mesh );
+ myDlg->setNewMeshName( SMESH::UniqueName( "Mesh_1" ) );
+ myDlg->setGroupName( SMESH::UniqueName( "Group" ) );
+ myDlg->show();
+
+ selectionDone();
+}
- Handle(SALOME_InteractiveObject) anIO = selected.First();
- myMesh = SMESH::GetMeshByIO(anIO);
- if (myMesh->_is_nil()) {
- SUIT_MessageBox::warning(desktop(),
- tr("SMESH_WRN_WARNING"),
- tr("SMESH_WRN_NO_AVAILABLE_DATA"));
- onCancel();
- return;
+void SMESHGUI_Make2DFrom3DOp::selectionDone()
+{
+ if ( !dlg() ) return;
+
+ if ( dlg()->isVisible() ) {
+ try {
+ QStringList names, ids;
+ LightApp_Dialog::TypesList types;
+ selected( names, types, ids );
+ if ( names.count() == 1 )
+ myDlg->selectObject( names, types, ids );
+ else
+ myDlg->clearSelection();
+ }
+ catch ( const SALOME::SALOME_Exception& S_ex ) {
+ SalomeApp_Tools::QtCatchCorbaException( S_ex );
+ }
+ catch ( ... ) {
+ }
}
+}
- SMESHGUI_Operation::startOperation();
+SUIT_SelectionFilter* SMESHGUI_Make2DFrom3DOp::createFilter( const int theId ) const
+{
+ SUIT_SelectionFilter* f = 0;
+ if ( theId == SMESHGUI_Make2DFrom3DDlg::Mesh ) {
+ QList<SUIT_SelectionFilter*> filters;
+ filters.append( new SMESH_TypeFilter( MESHorSUBMESH ) );
+ filters.append( new SMESH_TypeFilter( GROUP ) );
+ f = new SMESH_LogicalFilter( filters, SMESH_LogicalFilter::LO_OR );
+ }
+ return f;
+}
+bool SMESHGUI_Make2DFrom3DOp::isValid( QString& msg ) const
+{
+ if ( !dlg() ) return false;
+
+ // check if any source data is selected
+ QString entry = myDlg->selectedObject( SMESHGUI_Make2DFrom3DDlg::Mesh );
+ SMESH::SMESH_IDSource_var obj;
+ _PTR(SObject) sobj = SMESHGUI::activeStudy()->studyDS()->FindObjectID( entry.toLatin1().constData() );
+ if ( sobj )
+ obj = SMESH::SObjectToInterface<SMESH::SMESH_IDSource>( sobj );
+
+ if ( obj->_is_nil() ) {
+ msg = tr( "SMESH_ERR_NO_INPUT_MESH" );
+ return false;
+ }
- // backup mesh info before 2D mesh computation
- SMESH::long_array_var anOldInfo = myMesh->GetMeshInfo();
+ // check if source contains elements of required type
+ SMESH::Bnd_Dimension mode = myDlg->mode();
+ SMESH::array_of_ElementType_var types = obj->GetTypes();
+ bool has3d = false;
+ bool has2d = false;
+ for ( int i = 0; i < types->length(); i++ ) {
+ if ( types[i] == SMESH::VOLUME ) has3d = true;
+ else if ( types[i] == SMESH::FACE ) has2d = true;
+ }
- if (!compute2DMesh()) {
- SUIT_MessageBox::warning(desktop(),
- tr("SMESH_WRN_WARNING"),
- tr("SMESH_WRN_COMPUTE_FAILED"));
- onCancel();
- return;
- }
- // get new mesh statistic
- SMESH::long_array_var aNewInfo = myMesh->GetMeshInfo();
- // get difference in mesh statistic from old to new
- for ( int i = SMDSEntity_Node; i < SMDSEntity_Last; i++ )
- aNewInfo[i] -= anOldInfo[i];
-
- // update presentation
- SMESH::Update(anIO, SMESH::eDisplay);
-
- // show computated result
- _PTR(SObject) aMeshSObj = SMESH::FindSObject(myMesh);
- if ( aMeshSObj )
- myDlg->SetMeshName( aMeshSObj->GetName().c_str() );
- myDlg->SetMeshInfo( aNewInfo );
- myDlg->show(); /*exec();*/
- commit();
- SMESHGUI::Modified();
-}
-
-//================================================================================
-/*!
- * \brief compute 2D mesh on initial 3D
- */
-//================================================================================
+ if ( ( mode == SMESH::BND_2DFROM3D || mode == SMESH::BND_1DFROM3D ) && !has3d ) {
+ msg = tr( "SMESH_ERR_NO_3D_ELEMENTS" );
+ return false;
+ }
+ else if ( mode == SMESH::BND_1DFROM2D && !has2d ) {
+ msg = tr( "SMESH_ERR_NO_2D_ELEMENTS" );
+ return false;
+ }
+
+ // check if new mesh name is specified
+ if ( myDlg->needNewMesh() && myDlg->getNewMeshName().isEmpty() ) {
+ msg = tr( "SMESH_ERR_MESH_NAME_NOT_SPECIFIED" );
+ return false;
+ }
+
+ // check if group name is specified
+ if ( myDlg->needGroup() && myDlg->getGroupName().isEmpty() ) {
+ msg = tr( "SMESH_ERR_GRP_NAME_NOT_SPECIFIED" );
+ return false;
+ }
+
+ return true;
+}
bool SMESHGUI_Make2DFrom3DOp::compute2DMesh()
{
SUIT_OverrideCursor wc;
- SMESH::SMESH_MeshEditor_var aMeshEditor = myMesh->GetMeshEditor();
- return aMeshEditor->Make2DMeshFrom3D();
+
+ bool ok = false;
+ try {
+ QString entry = myDlg->selectedObject( SMESHGUI_Make2DFrom3DDlg::Mesh );
+ _PTR(SObject) sobj = SMESHGUI::activeStudy()->studyDS()->FindObjectID( entry.toLatin1().constData() );
+ SMESH::SMESH_IDSource_var obj = SMESH::SObjectToInterface<SMESH::SMESH_IDSource>( sobj );
+
+ SMESH::Bnd_Dimension mode = myDlg->mode();
+ QString meshName = myDlg->needNewMesh() ? myDlg->getNewMeshName() : QString();
+ QString groupName = myDlg->needGroup() ? myDlg->getGroupName() : QString();
+ bool copySrc = myDlg->copySource();
+ bool copyAll = !myDlg->copyMissingOnly();
+
+ SMESH::SMESH_Mesh_var srcMesh = SMESH::SMESH_Mesh::_narrow( obj );
+ if ( CORBA::is_nil( srcMesh ) ) {
+ SMESH::SMESH_subMesh_var subMesh = SMESH::SMESH_subMesh::_narrow( obj );
+ if ( !CORBA::is_nil( subMesh ) )
+ srcMesh = subMesh->GetFather();
+ }
+ if ( CORBA::is_nil( srcMesh ) ) {
+ SMESH::SMESH_GroupBase_var grp = SMESH::SMESH_GroupBase::_narrow( obj );
+ if ( !CORBA::is_nil( grp ) )
+ srcMesh = grp->GetMesh();
+ }
+
+ if ( !CORBA::is_nil( srcMesh ) ) {
+ SMESH::SMESH_MeshEditor_var aMeshEditor = srcMesh->GetMeshEditor();
+ SMESH::SMESH_Group_var newGrp;
+ SMESH::SMESH_Mesh_var mesh = aMeshEditor->MakeBoundaryMesh( obj.in(),
+ mode,
+ groupName.toLatin1().constData(),
+ meshName.toLatin1().constData(),
+ copySrc,
+ copyAll,
+ newGrp.out() );
+ if ( !mesh->_is_nil() ) {
+#ifdef WITHGENERICOBJ
+ mesh->Destroy();
+#endif
+ }
+ if ( !newGrp->_is_nil() ) {
+#ifdef WITHGENERICOBJ
+ newGrp->Destroy();
+#endif
+ }
+ ok = true;
+ }
+ }
+ catch ( ... ) {
+ }
+ return ok;
+}
+
+bool SMESHGUI_Make2DFrom3DOp::onApply()
+{
+ if ( isStudyLocked() )
+ return false;
+
+ QString msg;
+ if ( !isValid( msg ) ) {
+ dlg()->show();
+ if ( msg != "" )
+ SUIT_MessageBox::warning( myDlg, tr( "SMESH_ERROR" ), msg );
+ return false;
+ }
+
+ bool res = false;
+ try {
+ res = compute2DMesh();
+ }
+ catch ( const SALOME::SALOME_Exception& S_ex ) {
+ SalomeApp_Tools::QtCatchCorbaException( S_ex );
+ }
+ catch ( ... ) {
+ }
+
+ if ( res ) {
+ SMESHGUI::Modified();
+ update( UF_ObjBrowser | UF_Model );
+ myDlg->setNewMeshName( SMESH::UniqueName( "Mesh_1" ) );
+ myDlg->setGroupName( SMESH::UniqueName( "Group" ) );
+ }
+ else {
+ SUIT_MessageBox::warning( myDlg, tr( "SMESH_ERROR" ), tr( "SMESH_OPERATION_FAILED" ) );
+ }
+
+ return res;
}
//
// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
//
-
-// SMESH SMESHGUI : GUI for SMESH component
// File : SMESHGUI_Make2DFrom3D.h
-// Author : Open CASCADE S.A.S.
-//
+// Author : Vadim SANDLER, Open CASCADE S.A.S. (vadim.sandler@opencascade.com)
+
#ifndef SMESHGUI_Make2DFrom3DOp_H
#define SMESHGUI_Make2DFrom3DOp_H
// SMESH includes
#include "SMESH_SMESHGUI.hxx"
-
#include "SMESHGUI_Dialog.h"
-#include "SMESHGUI_Operation.h"
+#include "SMESHGUI_SelectionOp.h"
-// IDL includes
#include <SALOMEconfig.h>
-#include CORBA_SERVER_HEADER(SMESH_Mesh)
+#include CORBA_SERVER_HEADER(SMESH_MeshEditor)
-class QFrame;
-class SMESHGUI_MeshInfosBox;
+class QCheckBox;
+class QLineEdit;
+class QRadioButton;
/*!
* \brief Dialog to show result mesh statistic
*/
-class SMESHGUI_Make2DFrom3DDlg : public SMESHGUI_Dialog
+class SMESHGUI_EXPORT SMESHGUI_Make2DFrom3DDlg : public SMESHGUI_Dialog
{
Q_OBJECT
- public:
+public:
+ enum { Mesh };
+
SMESHGUI_Make2DFrom3DDlg( QWidget* );
virtual ~SMESHGUI_Make2DFrom3DDlg();
- void SetMeshName(const QString& theName);
- void SetMeshInfo(const SMESH::long_array& theInfo);
-
- private:
- QFrame* createMainFrame( QWidget* );
-
- private:
- QLabel* myMeshName;
- SMESHGUI_MeshInfosBox* myFullInfo;
+ SMESH::Bnd_Dimension mode() const;
+
+ bool needNewMesh() const;
+ QString getNewMeshName() const;
+ void setNewMeshName( const QString& );
+
+ bool needGroup() const;
+ QString getGroupName() const;
+ void setGroupName( const QString& );
+
+ bool copySource() const;
+ bool copyMissingOnly() const;
+
+private slots:
+ void onTargetChanged();
+ void onGroupChecked();
+
+private:
+ QRadioButton* my2dFrom3dRB;
+ QRadioButton* my1dFrom2dRB;
+ QRadioButton* my1dFrom3dRB;
+ QRadioButton* myThisMeshRB;
+ QRadioButton* myNewMeshRB;
+ QLineEdit* myMeshName;
+ QCheckBox* myCopyCheck;
+ QCheckBox* myMissingCheck;
+ QCheckBox* myGroupCheck;
+ QLineEdit* myGroupName;
};
-
/*!
* \brief Operation to compute 2D mesh on 3D
*/
-class SMESHGUI_Make2DFrom3DOp : public SMESHGUI_Operation
+class SMESHGUI_EXPORT SMESHGUI_Make2DFrom3DOp : public SMESHGUI_SelectionOp
{
- public:
+ Q_OBJECT
+
+public:
SMESHGUI_Make2DFrom3DOp();
virtual ~SMESHGUI_Make2DFrom3DOp();
- protected:
+ virtual LightApp_Dialog* dlg() const;
+
+protected:
virtual void startOperation();
+ virtual void selectionDone();
+ virtual SUIT_SelectionFilter* createFilter( const int ) const;
+ bool isValid( QString& ) const;
+
+protected slots:
+ virtual bool onApply();
- private:
+private:
bool compute2DMesh();
- private:
- SMESH::SMESH_Mesh_var myMesh;
+private:
+ SMESH::SMESH_IDSource_var mySrc;
QPointer<SMESHGUI_Make2DFrom3DDlg> myDlg;
};
}
return baseName;
}
+
+ QString UniqueName(const QString& theBaseName, _PTR(SObject) theParent, const QString& thePostfix)
+ {
+ QString baseName = thePostfix.isEmpty() ?
+ theBaseName : theBaseName + "_" + thePostfix;
+ QString name = baseName;
+ if ( _PTR(Study) aStudy = GetActiveStudyDocument() ) {
+ _PTR(SObject) p = theParent;
+ if ( !p ) p = aStudy->FindComponent( "SMESH" );
+ if ( p ) {
+ _PTR(ChildIterator) iter = aStudy->NewChildIterator( p );
+ int idx = 0;
+ while( true ) {
+ bool found = false;
+ for ( ; iter->More(); iter->Next() ) {
+ _PTR(SObject) so = iter->Value();
+ if ( !so ) continue; // skip bad objects
+ _PTR(SObject) ref;
+ if ( so->ReferencedObject( ref ) ) continue; // skip references
+ QString n = so->GetName().c_str();
+ if ( !n.isEmpty() && n == name ) {
+ QStringList names = name.split("_", QString::KeepEmptyParts);
+ if ( names.count() > 0 ) {
+ bool ok;
+ names.last().toInt( &ok );
+ if ( ok )
+ names.removeLast();
+ }
+ names.append( QString::number( ++idx ) );
+ name = names.join( "_" );
+ found = true;
+ break;
+ }
+ }
+ if ( !found ) break;
+ }
+ }
+ }
+ return name;
+ }
} // end of namespace SMESH
// SALOME GUI includes
#include <SALOME_InteractiveObject.hxx>
+// SALOME KERNEL includes
+#include <SALOMEDSClient_definitions.hxx>
+
// IDL includes
#include <SALOMEconfig.h>
#include CORBA_SERVER_HEADER(SMESH_Mesh)
+class SALOMEDSClient_SObject;
+
namespace SMESH
{
SMESHGUI_EXPORT
SMESHGUI_EXPORT
QString UniqueMeshName( const QString&, const QString& = QString() );
+ SMESHGUI_EXPORT
+ QString UniqueName( const QString&, _PTR(SObject) = _PTR(SObject)(), const QString& = QString() );
}
#endif // SMESHGUI_MESHUTILS_H
</message>
<message>
<source>MEN_2D_FROM_3D</source>
- <translation>Create 2D mesh from 3D</translation>
+ <translation>Create boundary elements</translation>
</message>
<message>
<source>MEN_MESH_ORDER</source>
<source>SMESH_WRN_VIEWER_VTK</source>
<translation>Study frame with VTK Viewer must be activated</translation>
</message>
+ <message>
+ <source>SMESH_WRN_SIZE_LIMIT_EXCEEDED</source>
+ <translation>No automatic update of the presentation has been done: new mesh size (%1 elements) exceeds current size limit (%2 elements).
+Please check preferences of Mesh module.
+</translation>
+ </message>
<message>
<source>SMESH_WRN_WARNING</source>
<translation>Warning</translation>
</message>
<message>
<source>STB_2D_FROM_3D</source>
- <translation>Create 2D mesh from 3D</translation>
+ <translation>Create boundary elements</translation>
</message>
<message>
<source>STB_MESH_ORDER</source>
</message>
<message>
<source>TOP_2D_FROM_3D</source>
- <translation>Create 2D mesh from 3D</translation>
+ <translation>Create boundary elements</translation>
</message>
<message>
<source>TOP_MESH_ORDER</source>
<source>PREF_AUTO_UPDATE</source>
<translation>Automatic update</translation>
</message>
+ <message>
+ <source>PREF_UPDATE_LIMIT</source>
+ <translation>Size limit (elements)</translation>
+ </message>
+ <message>
+ <source>PREF_UPDATE_LIMIT_NOLIMIT</source>
+ <translation>No limit</translation>
+ </message>
<message>
<source>PREF_BACKFACE</source>
<translation>Back face</translation>
<source>PREF_GROUP_SELECTION</source>
<translation>Selection</translation>
</message>
- <message>
- <source>PREF_GROUP_UPDATE</source>
- <translation>Update</translation>
- </message>
<message>
<source>PREF_HIGHLIGHT_COLOR</source>
<translation>Highlight color</translation>
<translation>No valid mesh object selected</translation>
</message>
</context>
-<context>
- <name>SMESHGUI_Make2DFrom3DDlg</name>
- <message>
- <source>CAPTION</source>
- <translation>Create 2D mesh from 3D</translation>
- </message>
-</context>
<context>
<name>SMESHGUI_CreatePatternDlg</name>
<message>
<source>SHAPE_IS_NOT_A_PLANE</source>
<translation>"%1" is not a plane
Please select a plane and try again</translation>
+ </message>
+ <message>
+ <source>FACE_ID_NOT_SELECTED</source>
+ <translation>Mesh face is not selected
+Please specify it and try again</translation>
+ </message>
+ <message>
+ <source>NOT_FACE_ID</source>
+ <translation>"%1" is not an ID of a mesh face.
+Please select a face and try again</translation>
</message>
<message>
<source>SOURCE</source>
<source>COMPARE</source>
<translation>Compare</translation>
</message>
+ <message>
+ <source>COPLANAR_FACES</source>
+ <translation>Coplanar faces</translation>
+ </message>
<message>
<source>COPY_FROM</source>
<translation>Copy from...</translation>
<translation>Construct group with newly created elements</translation>
</message>
</context>
+<context>
+ <name>SMESHGUI_Make2DFrom3DDlg</name>
+ <message>
+ <source>CAPTION</source>
+ <translation>Create boundary elements</translation>
+ </message>
+ <message>
+ <source>MESH</source>
+ <translation>Mesh, submesh or group</translation>
+ </message>
+ <message>
+ <source>MODE</source>
+ <translation>Mode</translation>
+ </message>
+ <message>
+ <source>2D_FROM_3D</source>
+ <translation>2D from 3D</translation>
+ </message>
+ <message>
+ <source>1D_FROM_3D</source>
+ <translation>1D from 3D</translation>
+ </message>
+ <message>
+ <source>1D_FROM_2D</source>
+ <translation>1D from 2D</translation>
+ </message>
+ <message>
+ <source>TARGET</source>
+ <translation>Target</translation>
+ </message>
+ <message>
+ <source>THIS_MESH</source>
+ <translation>This mesh</translation>
+ </message>
+ <message>
+ <source>NEW_MESH</source>
+ <translation>New mesh</translation>
+ </message>
+ <message>
+ <source>COPY_SRC</source>
+ <translation>Copy source mesh</translation>
+ </message>
+ <message>
+ <source>MISSING_ONLY</source>
+ <translation>Copy missing elements only</translation>
+ </message>
+ <message>
+ <source>CREATE_GROUP</source>
+ <translation>Create group</translation>
+ </message>
+</context>
+<context>
+ <name>SMESHGUI_Make2DFrom3DOp</name>
+ <message>
+ <source>SMESH_ERR_NO_INPUT_MESH</source>
+ <translation>Source mesh, sub-mesh or group is not specified</translation>
+ </message>
+ <message>
+ <source>SMESH_ERR_NO_3D_ELEMENTS</source>
+ <translation>The source object does not contain 3D elements</translation>
+ </message>
+ <message>
+ <source>SMESH_ERR_NO_2D_ELEMENTS</source>
+ <translation>The source object does not contain 2D elements</translation>
+ </message>
+ <message>
+ <source>SMESH_ERR_MESH_NAME_NOT_SPECIFIED</source>
+ <translation>New mesh name is not specified</translation>
+ </message>
+ <message>
+ <source>SMESH_ERR_GRP_NAME_NOT_SPECIFIED</source>
+ <translation>Group name is not specified</translation>
+ </message>
+</context>
</TS>
</message>
<message>
<source>MEN_2D_FROM_3D</source>
- <translation>Créer un maillage 2D à partir de 3D</translation>
+ <translation>Créer les éléments de frontière</translation>
</message>
<message>
<source>MEN_MESH_ORDER</source>
<source>SMESH_WRN_VIEWER_VTK</source>
<translation>Il faut ouvrir la scène dans le visualisateur VTK</translation>
</message>
+ <message>
+ <source>SMESH_WRN_SIZE_LIMIT_EXCEEDED</source>
+ <translation>La présentation n'a pas été mise à jour automatiquement: la taille nouvelle du maillage (%1 éléments) dépasse la limite de taille actuelle (%2 éléments).
+Il serait utile de changer la limite dans les préférences du module Mesh.
+</translation>
+ </message>
<message>
<source>SMESH_WRN_WARNING</source>
<translation>Avertissement</translation>
</message>
<message>
<source>STB_2D_FROM_3D</source>
- <translation>Créer un maillage 2D à partir de 3D</translation>
+ <translation>Créer les éléments de frontière</translation>
</message>
<message>
<source>STB_MESH_ORDER</source>
</message>
<message>
<source>TOP_2D_FROM_3D</source>
- <translation>Créer un Maillage 2D à partir de 3D</translation>
+ <translation>Créer les éléments de frontière</translation>
</message>
<message>
<source>TOP_MESH_ORDER</source>
<source>PREF_AUTO_UPDATE</source>
<translation>Mettre à Jour Automatiquement</translation>
</message>
+ <message>
+ <source>PREF_UPDATE_LIMIT</source>
+ <translation>Limite de taille (nombre d'éléments)</translation>
+ </message>
+ <message>
+ <source>PREF_UPDATE_LIMIT_NOLIMIT</source>
+ <translation>Sans limite</translation>
+ </message>
<message>
<source>PREF_BACKFACE</source>
<translation>Face Arrière</translation>
<source>PREF_GROUP_SELECTION</source>
<translation>Sélection</translation>
</message>
- <message>
- <source>PREF_GROUP_UPDATE</source>
- <translation>Mettre à jour</translation>
- </message>
<message>
<source>PREF_HIGHLIGHT_COLOR</source>
<translation>Couleur de sélection</translation>
<translation>Un maillage valide n'est pas choisi</translation>
</message>
</context>
-<context>
- <name>SMESHGUI_Make2DFrom3DDlg</name>
- <message>
- <source>CAPTION</source>
- <translation>Créer un maillage 2D à partir de 3D</translation>
- </message>
-</context>
<context>
<name>SMESHGUI_CreatePatternDlg</name>
<message>
</message>
</context>
<context>
- <name>SMESHGUI_EditMeshDlg</name>
+ <name>SMESHGUI_MergeDlg</name>
<message>
<source>COINCIDENT_ELEMENTS</source>
<translation>Eléments Coïncidents</translation>
<source>SELECT_ALL</source>
<translation>Choisir Tous</translation>
</message>
+ <message>
+ <source>EXCLUDE_GROUPS</source>
+ <translation>Exclure les Groupes</translation>
+ </message>
</context>
<context>
<name>SMESHGUI_ExtrusionAlongPathDlg</name>
<source>SHAPE_IS_NOT_A_PLANE</source>
<translation>"%1" n'est pas un plan
Choisissez un plan et essayez de nouveau</translation>
+ </message>
+ <message>
+ <source>FACE_ID_NOT_SELECTED</source>
+ <translation>La face de maillage n'est pas choisie.
+Indiquez-la et essayez de nouveau.</translation>
+ </message>
+ <message>
+ <source>NOT_FACE_ID</source>
+ <translation>"%1" n'est l'ID valide d'une face du maillage.
+Choisissez la face et essayez de nouveau.</translation>
</message>
<message>
<source>SOURCE</source>
<source>COMPARE</source>
<translation>Comparer</translation>
</message>
+ <message>
+ <source>COPLANAR_FACES</source>
+ <translation>Faces Coplanaires</translation>
+ </message>
<message>
<source>COPY_FROM</source>
<translation>Copier de...</translation>
<source>SPLIT_HEX_TO_6_TETRA</source>
<translation>En 6 tétraèdres</translation>
</message>
+ <message>
+ <source>SPLIT_HEX_TO_24_TETRA</source>
+ <translation>En 24 tétraèdres</translation>
+ </message>
</context>
<context>
<name>SMESHGUI_PrecisionDlg</name>
<translation>Construire un groupe avec les éléments créés de nouveau</translation>
</message>
</context>
+<context>
+ <name>SMESHGUI_Make2DFrom3DDlg</name>
+ <message>
+ <source>CAPTION</source>
+ <translation>Créer les éléments de frontière</translation>
+ </message>
+ <message>
+ <source>MESH</source>
+ <translation>Maillage, sous-maillage ou groupe</translation>
+ </message>
+ <message>
+ <source>MODE</source>
+ <translation>Mode</translation>
+ </message>
+ <message>
+ <source>2D_FROM_3D</source>
+ <translation>2D à partir de 3D</translation>
+ </message>
+ <message>
+ <source>1D_FROM_3D</source>
+ <translation>1D à partir de 3D</translation>
+ </message>
+ <message>
+ <source>1D_FROM_2D</source>
+ <translation>1D à partir de 2D</translation>
+ </message>
+ <message>
+ <source>TARGET</source>
+ <translation>Cible</translation>
+ </message>
+ <message>
+ <source>THIS_MESH</source>
+ <translation>Ce maillage</translation>
+ </message>
+ <message>
+ <source>NEW_MESH</source>
+ <translation>Maillage nouveau</translation>
+ </message>
+ <message>
+ <source>COPY_SRC</source>
+ <translation>Copier le maillage source</translation>
+ </message>
+ <message>
+ <source>MISSING_ONLY</source>
+ <translation>Copier seulment les éléments manquants</translation>
+ </message>
+ <message>
+ <source>CREATE_GROUP</source>
+ <translation>Créer un groupe</translation>
+ </message>
+</context>
+<context>
+ <name>SMESHGUI_Make2DFrom3DOp</name>
+ <message>
+ <source>SMESH_ERR_NO_INPUT_MESH</source>
+ <translation>Aucun maillage, sous-maillage ou groupe source n'est indiqué</translation>
+ </message>
+ <message>
+ <source>SMESH_ERR_NO_3D_ELEMENTS</source>
+ <translation>L'objet source ne contient pas d'éléments 3D</translation>
+ </message>
+ <message>
+ <source>SMESH_ERR_NO_2D_ELEMENTS</source>
+ <translation>L'objet source ne contient pas d'éléments 2D</translation>
+ </message>
+ <message>
+ <source>SMESH_ERR_MESH_NAME_NOT_SPECIFIED</source>
+ <translation>Le nouveau nom du maillage n'est pas indiqué</translation>
+ </message>
+ <message>
+ <source>SMESH_ERR_GRP_NAME_NOT_SPECIFIED</source>
+ <translation>Le nom du groupe n'est pas indiqué</translation>
+ </message>
+</context>
</TS>
case FT_BelongToCylinder: myStream<< "aBelongToCylinder"; break;
case FT_BelongToGenSurface:myStream<<"aBelongToGenSurface";break;
case FT_LyingOnGeom: myStream<< "aLyingOnGeom"; break;
+ case FT_CoplanarFaces: myStream<< "aCoplanarFaces"; break;
case FT_RangeOfIds: myStream<< "aRangeOfIds"; break;
case FT_BadOrientedVolume:myStream<< "aBadOrientedVolume";break;
case FT_LinearOrQuadratic:myStream<< "aLinearOrQuadratic";break;
GeometryType ElemGeomType_i::GetGeometryType() const
{
- return (GeometryType)myElemGeomTypePtr->GetGeomType();;
+ return (GeometryType)myElemGeomTypePtr->GetGeomType();
}
FunctorType ElemGeomType_i::GetFunctorType()
return SMESH::FT_ElemGeomType;
}
+/*
+ Class : CoplanarFaces_i
+ Description : Returns true if a mesh face is a coplanar neighbour to a given one
+*/
+CoplanarFaces_i::CoplanarFaces_i()
+{
+ myCoplanarFacesPtr.reset(new Controls::CoplanarFaces());
+ myFunctorPtr = myPredicatePtr = myCoplanarFacesPtr;
+}
+
+void CoplanarFaces_i::SetFace ( CORBA::Long theFaceID )
+{
+ myCoplanarFacesPtr->SetFace(theFaceID);
+ TPythonDump()<<this<<".SetFace("<<theFaceID<<")";
+}
+
+void CoplanarFaces_i::SetTolerance( CORBA::Double theToler )
+{
+ myCoplanarFacesPtr->SetTolerance(theToler);
+ TPythonDump()<<this<<".SetTolerance("<<theToler<<")";
+}
+
+CORBA::Long CoplanarFaces_i::GetFace () const
+{
+ return myCoplanarFacesPtr->GetFace();
+}
+
+char* CoplanarFaces_i::GetFaceAsString () const
+{
+ TCollection_AsciiString str(Standard_Integer(myCoplanarFacesPtr->GetFace()));
+ return CORBA::string_dup( str.ToCString() );
+}
+
+CORBA::Double CoplanarFaces_i::GetTolerance() const
+{
+ return myCoplanarFacesPtr->GetTolerance();
+}
+
+FunctorType CoplanarFaces_i::GetFunctorType()
+{
+ return SMESH::FT_CoplanarFaces;
+}
+
/*
Class : Comparator_i
Description : Base class for comparators
return anObj._retn();
}
+CoplanarFaces_ptr FilterManager_i::CreateCoplanarFaces()
+{
+ SMESH::CoplanarFaces_i* aServant = new SMESH::CoplanarFaces_i();
+ SMESH::CoplanarFaces_var anObj = aServant->_this();
+ TPythonDump()<<aServant<<" = "<<this<<".CreateCoplanarFaces()";
+ return anObj._retn();
+}
+
FreeBorders_ptr FilterManager_i::CreateFreeBorders()
{
SMESH::FreeBorders_i* aServant = new SMESH::FreeBorders_i();
theCriteria[ i ].TypeOfElement = aPred->GetElementType();
theCriteria[ i ].Tolerance = aPred->GetTolerance();
+ return true;
+ }
+ case FT_CoplanarFaces:
+ {
+ CoplanarFaces_i* aPred = dynamic_cast<CoplanarFaces_i*>( thePred );
+
+ CORBA::ULong i = theCriteria->length();
+ theCriteria->length( i + 1 );
+
+ theCriteria[ i ] = createCriterion();
+ CORBA::String_var faceId = aPred->GetFaceAsString();
+
+ theCriteria[ i ].Type = FT_CoplanarFaces;
+ theCriteria[ i ].ThresholdID = faceId;
+ theCriteria[ i ].Tolerance = aPred->GetTolerance();
+
return true;
}
case FT_RangeOfIds:
aPredicate = tmpPred;
break;
}
+ case SMESH::FT_CoplanarFaces:
+ {
+ SMESH::CoplanarFaces_ptr tmpPred = aFilterMgr->CreateCoplanarFaces();
+ tmpPred->SetFace( atol (aThresholdID ));
+ tmpPred->SetTolerance( aTolerance );
+ aPredicate = tmpPred;
+ break;
+ }
default:
continue;
Controls::ElemGeomTypePtr myElemGeomTypePtr;
};
+ /*
+ Class : CoplanarFaces_i
+ Description : Returns true if a mesh face is a coplanar neighbour to a given one
+ */
+ class SMESH_I_EXPORT CoplanarFaces_i: public virtual POA_SMESH::CoplanarFaces,
+ public virtual Predicate_i
+ {
+ public:
+ CoplanarFaces_i();
+ FunctorType GetFunctorType();
+
+ void SetFace ( CORBA::Long theFaceID );
+ void SetTolerance( CORBA::Double theToler );
+ char* GetFaceAsString () const;
+ CORBA::Long GetFace () const;
+ CORBA::Double GetTolerance () const;
+ private:
+ Controls::CoplanarFacesPtr myCoplanarFacesPtr;
+ };
+
/*
Class : Comparator_i
Description : Base class for comparators
FreeFaces_ptr CreateFreeFaces();
RangeOfIds_ptr CreateRangeOfIds();
-
BadOrientedVolume_ptr CreateBadOrientedVolume();
LinearOrQuadratic_ptr CreateLinearOrQuadratic();
-
GroupColor_ptr CreateGroupColor();
-
ElemGeomType_ptr CreateElemGeomType();
+ CoplanarFaces_ptr CreateCoplanarFaces();
LessThan_ptr CreateLessThan();
MoreThan_ptr CreateMoreThan();
bool isMultiFile ) {
if(MYDEBUG) MESSAGE( "SMESH_Gen_i::SaveASCII" );
SALOMEDS::TMPFile_var aStreamFile = Save( theComponent, theURL, isMultiFile );
- //return aStreamFile._retn();
+ return aStreamFile._retn();
//after usual saving needs to encipher binary to text string
//Any binary symbol will be represent as "|xx" () hexadecimal format number
const char* theURL,
bool isMultiFile ) {
if(MYDEBUG) MESSAGE( "SMESH_Gen_i::LoadASCII" );
- //return Load( theComponent, theStream, theURL, isMultiFile );
+ return Load( theComponent, theStream, theURL, isMultiFile );
//before call main ::Load method it's need for decipher text format to
//binary ( "|xx" => x' )
#include "SMESH_Filter_i.hxx"
#include "SMESH_PythonDump.hxx"
+#include CORBA_SERVER_HEADER(SMESH_Filter)
+
#include "utilities.h"
using namespace SMESH;
SMESHDS_Group* aGroupDS = dynamic_cast<SMESHDS_Group*>( GetGroupDS() );
if (aGroupDS) {
SMESH::long_array_var anIds;
- if ( !CORBA::is_nil(SMESH::SMESH_GroupBase::_narrow(theSource)) &&
- SMESH::SMESH_GroupBase::_narrow(theSource)->GetType() == GetType() ) {
+ SMESH::SMESH_GroupBase_var group = SMESH::SMESH_GroupBase::_narrow(theSource);
+ SMESH::SMESH_Mesh_var mesh = SMESH::SMESH_Mesh::_narrow(theSource);
+ SMESH::SMESH_subMesh_var submesh = SMESH::SMESH_subMesh::_narrow(theSource);
+ SMESH::Filter_var filter = SMESH::Filter::_narrow(theSource);
+ if ( !group->_is_nil())
+ anIds = group->GetType()==GetType() ? theSource->GetIDs() : new SMESH::long_array();
+ else if ( !mesh->_is_nil() )
+ anIds = mesh->GetElementsByType( GetType() );
+ else if ( !submesh->_is_nil())
+ anIds = submesh->GetElementsByType( GetType() );
+ else if ( !filter->_is_nil() )
+ anIds = filter->GetElementType()==GetType() ? theSource->GetIDs() : new SMESH::long_array();
+ else
anIds = theSource->GetIDs();
- }
- else if ( !CORBA::is_nil(SMESH::SMESH_Mesh::_narrow(theSource)) ) {
- anIds = SMESH::SMESH_Mesh::_narrow(theSource)->GetElementsByType( GetType() );
- }
- else if ( !CORBA::is_nil(SMESH::SMESH_subMesh::_narrow(theSource)) ) {
- anIds = SMESH::SMESH_subMesh::_narrow(theSource)->GetElementsByType( GetType() );
- }
- else {
- anIds->length( 0 );
- }
for ( int i = 0, total = anIds->length(); i < total; i++ ) {
if ( aGroupDS->Add((int)anIds[i]) ) nbAdd++;
}
// Author : Nicolas REJNERI
// Module : SMESH
//
+#ifdef WNT
+#define NOMINMAX
+#endif
+
#include "SMESH_MeshEditor_i.hxx"
#include "SMDS_Mesh0DElement.hxx"
::SMESH_MeshEditor aMeshEditor( myMesh );
bool aResult = aMeshEditor.Make2DMeshFrom3D();
storeResult( aMeshEditor) ;
-
+
TPythonDump() << "isDone = " << this << ".Make2DMeshFrom3D()";
return aResult;
}
+
+// issue 20749 ===================================================================
+/*!
+ * \brief Creates missing boundary elements
+ * \param elements - elements whose boundary is to be checked
+ * \param dimension - defines type of boundary elements to create
+ * \param groupName - a name of group to store created boundary elements in,
+ * "" means not to create the group
+ * \param meshName - a name of new mesh to store created boundary elements in,
+ * "" means not to create the new mesh
+ * \param toCopyElements - if true, the checked elements will be copied into the new mesh
+ * \param toCopyExistingBondary - if true, not only new but also pre-existing
+ * boundary elements will be copied into the new mesh
+ * \param group - returns the create group, if any
+ * \retval SMESH::SMESH_Mesh - the mesh where elements were added to
+ */
+// ================================================================================
+
+SMESH::SMESH_Mesh_ptr
+SMESH_MeshEditor_i::MakeBoundaryMesh(SMESH::SMESH_IDSource_ptr idSource,
+ SMESH::Bnd_Dimension dim,
+ const char* groupName,
+ const char* meshName,
+ CORBA::Boolean toCopyElements,
+ CORBA::Boolean toCopyExistingBondary,
+ SMESH::SMESH_Group_out group)
+{
+ initData();
+
+ if ( dim > SMESH::BND_1DFROM2D )
+ THROW_SALOME_CORBA_EXCEPTION("Invalid boundary dimension", SALOME::BAD_PARAM);
+
+
+ SMESHDS_Mesh* aMeshDS = GetMeshDS();
+
+ SMESH::SMESH_Mesh_var mesh_var;
+ SMESH::SMESH_Group_var group_var;
+
+ TPythonDump pyDump;
+
+ TIDSortedElemSet elements;
+ SMDSAbs_ElementType elemType = (dim == SMESH::BND_1DFROM2D) ? SMDSAbs_Face : SMDSAbs_Volume;
+ if ( idSourceToSet( idSource, aMeshDS, elements, elemType,/*emptyIfIsMesh=*/true ))
+ {
+ // mesh to fill in
+ mesh_var =
+ strlen(meshName) ? makeMesh(meshName) : SMESH::SMESH_Mesh::_duplicate(myMesh_i->_this());
+ SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh_var );
+ // other mesh
+ SMESH_Mesh* smesh_mesh = (mesh_i==myMesh_i) ? (SMESH_Mesh*)0 : &mesh_i->GetImpl();
+
+ // group of new boundary elements
+ SMESH_Group* smesh_group = 0;
+ if ( strlen(groupName) )
+ {
+ group_var = mesh_i->CreateGroup( SMESH::ElementType(elemType),groupName);
+ if ( SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>( group_var ))
+ smesh_group = group_i->GetSmeshGroup();
+ }
+
+ // do it
+ ::SMESH_MeshEditor aMeshEditor( myMesh );
+ aMeshEditor.MakeBoundaryMesh( elements,
+ ::SMESH_MeshEditor::Bnd_Dimension(dim),
+ smesh_group,
+ smesh_mesh,
+ toCopyElements,
+ toCopyExistingBondary);
+ storeResult( aMeshEditor );
+ }
+
+ // result of MakeBoundaryMesh() is a tuple (mesh, group)
+ if ( mesh_var->_is_nil() )
+ pyDump << myMesh_i->_this() << ", ";
+ else
+ pyDump << mesh_var << ", ";
+ if ( group_var->_is_nil() )
+ pyDump << "_NoneGroup = "; // assignment to None is forbiden
+ else
+ pyDump << group_var << " = ";
+ pyDump << this << ".MakeBoundaryMesh( "
+ << idSource << ", "
+ << dim << ", "
+ << groupName << ", "
+ << meshName<< ", "
+ << toCopyElements << ", "
+ << toCopyExistingBondary << ")";
+
+ group = group_var._retn();
+ return mesh_var._retn();
+}
const SMESH::ListOfGroups& theNodesNot,
GEOM::GEOM_Object_ptr theShape );
- /*!
- * \brief Generated skin mesh (containing 2D cells) from 3D mesh
- * The created 2D mesh elements based on nodes of free faces of boundary volumes
- * \return TRUE if operation has been completed successfully, FALSE otherwise
- */
- CORBA::Boolean Make2DMeshFrom3D();
-
- private: //!< private methods
+ /*!
+ * \brief Generated skin mesh (containing 2D cells) from 3D mesh
+ * The created 2D mesh elements based on nodes of free faces of boundary volumes
+ * \return TRUE if operation has been completed successfully, FALSE otherwise
+ */
+ CORBA::Boolean Make2DMeshFrom3D();
+
+ SMESH::SMESH_Mesh_ptr MakeBoundaryMesh(SMESH::SMESH_IDSource_ptr elements,
+ SMESH::Bnd_Dimension dimension,
+ const char* groupName,
+ const char* meshName,
+ CORBA::Boolean toCopyElements,
+ CORBA::Boolean toCopyMissingBondary,
+ SMESH::SMESH_Group_out group);
+
+private: //!< private methods
SMESHDS_Mesh * GetMeshDS() { return myMesh->GetMeshDS(); }
long nbNodes = NbNodes();
aResult->length( nbNodes );
- SMDS_NodeIteratorPtr anIt = aSMESHDS_Mesh->nodesIterator();
+ SMDS_NodeIteratorPtr anIt = aSMESHDS_Mesh->nodesIterator(/*idInceasingOrder=*/true);
for ( int i = 0, n = nbNodes; i < n && anIt->more(); i++ )
aResult[i] = anIt->next()->GetID();
<< CreatePolygons << ", " << CreatePolyedrs << " )";
addErrorCode( "MakeMesh" );
- return myPattern.MakeMesh( aMesh, CreatePolygons, CreatePolyedrs );
+ int nb = aMesh->NbNodes() + aMesh->NbEdges() + aMesh->NbFaces() + aMesh->NbVolumes();
+
+ bool res = myPattern.MakeMesh( aMesh, CreatePolygons, CreatePolyedrs );
+
+ if ( nb > 0 && nb != aMesh->NbNodes() + aMesh->NbEdges() + aMesh->NbFaces() + aMesh->NbVolumes())
+ aMesh->SetIsModified(true);
+
+ return res;
}
//=======================================================================
SMESH::array_of_ElementType* SMESH_subMesh_i::GetTypes()
{
SMESH::array_of_ElementType_var types = new SMESH::array_of_ElementType;
- types->length( 1 );
+
::SMESH_subMesh* aSubMesh = _mesh_i->_mapSubMesh[_localId];
- switch ( ::SMESH_Gen::GetShapeDim( aSubMesh->GetSubShape() ))
+ TopoDS_Shape shape = aSubMesh->GetSubShape();
+ while ( !shape.IsNull() && shape.ShapeType() == TopAbs_COMPOUND )
{
- case 0: types[0] = SMESH::ELEM0D; break;
- case 1: types[0] = SMESH::EDGE; break;
- case 2: types[0] = SMESH::FACE; break;
- case 3: types[0] = SMESH::VOLUME; break;
- default:
- types->length(0);
+ TopoDS_Iterator it( shape );
+ shape = it.More() ? it.Value() : TopoDS_Shape();
+ }
+ if ( !shape.IsNull() )
+ {
+ types->length( 1 );
+ switch ( ::SMESH_Gen::GetShapeDim( shape ))
+ {
+ case 0: types[0] = SMESH::ELEM0D; break;
+ case 1: types[0] = SMESH::EDGE; break;
+ case 2: types[0] = SMESH::FACE; break;
+ case 3: types[0] = SMESH::VOLUME; break;
+ default:
+ types->length(0);
+ }
}
return types._retn();
}
## @defgroup l3_hypos_ghs3dh GHS3D Parameters hypothesis
## @defgroup l3_hypos_blsurf BLSURF Parameters hypothesis
## @defgroup l3_hypos_hexotic Hexotic Parameters hypothesis
+## @defgroup l3_hypos_quad Quadrangle Parameters hypothesis
## @defgroup l3_hypos_additi Additional Hypotheses
## @}
# Methods of splitting a hexahedron into tetrahedra
Hex_5Tet, Hex_6Tet, Hex_24Tet = 1, 2, 3
+# import items of enum QuadType
+for e in StdMeshers.QuadType._items: exec('%s = StdMeshers.%s'%(e,e))
+
## Converts an angle from degrees to radians
def DegreesToRadians(AngleInDegrees):
from math import pi
else:
print "Error: The treshold should be a string."
return None
+ elif CritType == FT_CoplanarFaces:
+ # Checks the treshold
+ if isinstance(aTreshold, int):
+ aCriterion.ThresholdID = "%s"%aTreshold
+ elif isinstance(aTreshold, str):
+ ID = int(aTreshold)
+ if ID < 1:
+ raise ValueError, "Invalid ID of mesh face: '%s'"%aTreshold
+ aCriterion.ThresholdID = aTreshold
+ else:
+ raise ValueError,\
+ "The treshold should be an ID of mesh face and not '%s'"%aTreshold
elif CritType == FT_ElemGeomType:
# Checks the treshold
try:
# @return SMESH_Group
# @ingroup l2_grps_create
def MakeGroupByFilter(self, groupName, theFilter):
- anIds = theFilter.GetElementsId(self.mesh)
- anElemType = theFilter.GetElementType()
- group = self.MakeGroupByIds(groupName, anElemType, anIds)
+ group = self.CreateEmptyGroup(theFilter.GetElementType(), groupName)
+ theFilter.SetMesh( self.mesh )
+ group.AddFrom( theFilter )
return group
## Passes mesh elements through the given filter and return IDs of fitting elements
# @return a list of ids
# @ingroup l1_controls
def GetIdsFromFilter(self, theFilter):
- return theFilter.GetElementsId(self.mesh)
+ theFilter.SetMesh( self.mesh )
+ return theFilter.GetIDs()
## Verifies whether a 2D mesh element has free edges (edges connected to one face only)\n
# Returns a list of special structures (borders).
def SplitVolumesIntoTetra(self, elemIDs, method=Hex_5Tet ):
if isinstance( elemIDs, Mesh ):
elemIDs = elemIDs.GetMesh()
+ if ( isinstance( elemIDs, list )):
+ elemIDs = self.editor.MakeIDSource(elemIDs, SMESH.VOLUME)
self.editor.SplitVolumesIntoTetra(elemIDs, method)
## Splits quadrangle faces near triangular facets of volumes
# @ingroup l2_modif_edit
def Make2DMeshFrom3D(self):
return self.editor. Make2DMeshFrom3D()
-
+
+ ## Creates missing boundary elements
+ # @param elements - elements whose boundary is to be checked:
+ # mesh, group, sub-mesh or list of elements
+ # @param dimension - defines type of boundary elements to create:
+ # SMESH.BND_2DFROM3D, SMESH.BND_1DFROM3D, SMESH.BND_1DFROM2D
+ # @param groupName - a name of group to store created boundary elements in,
+ # "" means not to create the group
+ # @param meshName - a name of new mesh to store created boundary elements in,
+ # "" means not to create the new mesh
+ # @param toCopyElements - if true, the checked elements will be copied into the new mesh
+ # @param toCopyExistingBondary - if true, not only new but also pre-existing
+ # boundary elements will be copied into the new mesh
+ # @return tuple (mesh, group) where bondary elements were added to
+ # @ingroup l2_modif_edit
+ def MakeBoundaryMesh(self, elements, dimension=SMESH.BND_2DFROM3D, groupName="", meshName="",
+ toCopyElements=False, toCopyExistingBondary=False):
+ if isinstance( elements, Mesh ):
+ elements = elements.GetMesh()
+ if ( isinstance( elements, list )):
+ elemType = SMESH.ALL
+ if elements: elemType = self.GetElementType( elements[0], iselem=True)
+ elements = self.editor.MakeIDSource(elements, elemType)
+ mesh, group = self.editor.MakeBoundaryMesh(elements,dimension,groupName,meshName,
+ toCopyElements,toCopyExistingBondary)
+ if mesh: mesh = self.smeshpyD.Mesh(mesh)
+ return mesh, group
+
## Renumber mesh nodes
# @ingroup l2_modif_renumber
def RenumberNodes(self):
def FindCoincidentNodesOnPart (self, SubMeshOrGroup, Tolerance, exceptNodes=[]):
if (isinstance( SubMeshOrGroup, Mesh )):
SubMeshOrGroup = SubMeshOrGroup.GetMesh()
- if not isinstance( ExceptSubMeshOrGroups, list):
- ExceptSubMeshOrGroups = [ ExceptSubMeshOrGroups ]
- if ExceptSubMeshOrGroups and isinstance( ExceptSubMeshOrGroups[0], int):
- ExceptSubMeshOrGroups = [ self.editor.MakeIDSource( ExceptSubMeshOrGroups, SMESH.NODE)]
- return self.editor.FindCoincidentNodesOnPartBut(SubMeshOrGroup, Tolerance,ExceptSubMeshOrGroups)
+ if not isinstance( exceptNodes, list):
+ exceptNodes = [ exceptNodes ]
+ if exceptNodes and isinstance( exceptNodes[0], int):
+ exceptNodes = [ self.editor.MakeIDSource( exceptNodes, SMESH.NODE)]
+ return self.editor.FindCoincidentNodesOnPartBut(SubMeshOrGroup, Tolerance,exceptNodes)
## Merges nodes
# @param GroupsOfNodes the list of groups of nodes
pass
except:
name = mesh.geompyD.SubShapeName(geom, piece)
- mesh.geompyD.addToStudyInFather(piece, geom, name)
+ if not name:
+ name = "%s_%s"%(geom.GetShapeType(), id(geom%1000))
pass
self.subm = mesh.mesh.GetSubMesh(geom, algo.GetName())
# @ingroup l3_algos_basic
class Mesh_Quadrangle(Mesh_Algorithm):
+ params=0
+
## Private constructor.
def __init__(self, mesh, geom=0):
Mesh_Algorithm.__init__(self)
self.Create(mesh, geom, "Quadrangle_2D")
+ return
- ## Defines "QuadranglePreference" hypothesis, forcing construction
- # of quadrangles if the number of nodes on the opposite edges is not the same
- # while the total number of nodes on edges is even
- #
- # @ingroup l3_hypos_additi
- def QuadranglePreference(self):
- hyp = self.Hypothesis("QuadranglePreference", UseExisting=1,
- CompareMethod=self.CompareEqualHyp)
- return hyp
+ ## Defines "QuadrangleParameters" hypothesis
+ # @param quadType defines the algorithm of transition between differently descretized
+ # sides of a geometrical face:
+ # - QUAD_STANDARD - both triangles and quadrangles are possible in the transition
+ # area along the finer meshed sides.
+ # - QUAD_TRIANGLE_PREF - only triangles are built in the transition area along the
+ # finer meshed sides.
+ # - QUAD_QUADRANGLE_PREF - only quadrangles are built in the transition area along
+ # the finer meshed sides, iff the total quantity of segments on
+ # all four sides of the face is even (divisible by 2).
+ # - QUAD_QUADRANGLE_PREF_REVERSED - same as QUAD_QUADRANGLE_PREF but the transition
+ # area is located along the coarser meshed sides.
+ # - QUAD_REDUCED - only quadrangles are built 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.
+ # @param triangleVertex: vertex of a trilateral geometrical face, around which triangles
+ # will be created while other elements will be quadrangles.
+ # Vertex can be either a GEOM_Object or a vertex ID within the
+ # shape to mesh
+ # @param UseExisting: if ==true - searches for the existing hypothesis created with
+ # the same parameters, else (default) - creates a new one
+ # @ingroup l3_hypos_quad
+ def QuadrangleParameters(self, quadType=StdMeshers.QUAD_STANDARD, triangleVertex=0, UseExisting=0):
+ vertexID = triangleVertex
+ if isinstance( triangleVertex, geompyDC.GEOM._objref_GEOM_Object ):
+ vertexID = self.mesh.geompyD.GetSubShapeID( self.mesh.geom, triangleVertex )
+ if not self.params:
+ compFun = lambda hyp,args: \
+ hyp.GetQuadType() == args[0] and \
+ ( hyp.GetTriaVertex()==args[1] or ( hyp.GetTriaVertex()<1 and args[1]<1))
+ self.params = self.Hypothesis("QuadrangleParams", [quadType,vertexID],
+ UseExisting = UseExisting, CompareMethod=compFun)
+ pass
+ if self.params.GetQuadType() != quadType:
+ self.params.SetQuadType(quadType)
+ if vertexID > 0:
+ self.params.SetTriaVertex( vertexID )
+ return self.params
- ## Defines "TrianglePreference" hypothesis, forcing construction
- # of triangles in the refinement area if the number of nodes
- # on the opposite edges is not the same
- #
- # @ingroup l3_hypos_additi
- def TrianglePreference(self):
- hyp = self.Hypothesis("TrianglePreference", UseExisting=1,
- CompareMethod=self.CompareEqualHyp)
- return hyp
+ ## Defines "QuadrangleParams" hypothesis with a type of quadrangulation that only
+ # quadrangles are built in the transition area along the finer meshed sides,
+ # iff the total quantity of segments on all four sides of the face is even.
+ # @param reversed if True, transition area is located along the coarser meshed sides.
+ # @param UseExisting: if ==true - searches for the existing hypothesis created with
+ # the same parameters, else (default) - creates a new one
+ # @ingroup l3_hypos_quad
+ def QuadranglePreference(self, reversed=False, UseExisting=0):
+ if reversed:
+ return self.QuadrangleParameters(QUAD_QUADRANGLE_PREF_REVERSED,UseExisting=UseExisting)
+ return self.QuadrangleParameters(QUAD_QUADRANGLE_PREF,UseExisting=UseExisting)
+
+ ## Defines "QuadrangleParams" hypothesis with a type of quadrangulation that only
+ # triangles are built in the transition area along the finer meshed sides.
+ # @param UseExisting: if ==true - searches for the existing hypothesis created with
+ # the same parameters, else (default) - creates a new one
+ # @ingroup l3_hypos_quad
+ def TrianglePreference(self, UseExisting=0):
+ return self.QuadrangleParameters(QUAD_TRIANGLE_PREF,UseExisting=UseExisting)
+
+ ## Defines "QuadrangleParams" hypothesis with a type of quadrangulation that only
+ # quadrangles are built 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.
+ # @param UseExisting: if ==true - searches for the existing hypothesis created with
+ # the same parameters, else (default) - creates a new one
+ # @ingroup l3_hypos_quad
+ def Reduced(self, UseExisting=0):
+ return self.QuadrangleParameters(QUAD_REDUCED,UseExisting=UseExisting)
- ## Defines "QuadrangleParams" hypothesis
+ ## Defines "QuadrangleParams" hypothesis with QUAD_STANDARD type of quadrangulation
# @param vertex: vertex of a trilateral geometrical face, around which triangles
# will be created while other elements will be quadrangles.
# Vertex can be either a GEOM_Object or a vertex ID within the
# shape to mesh
# @param UseExisting: if ==true - searches for the existing hypothesis created with
# the same parameters, else (default) - creates a new one
- #
- # @ingroup l3_hypos_additi
+ # @ingroup l3_hypos_quad
def TriangleVertex(self, vertex, UseExisting=0):
- vertexID = vertex
- if isinstance( vertexID, geompyDC.GEOM._objref_GEOM_Object ):
- vertexID = self.mesh.geompyD.GetSubShapeID( self.mesh.geom, vertex )
- hyp = self.Hypothesis("QuadrangleParams", [vertexID], UseExisting = UseExisting,
- CompareMethod=lambda hyp,args: hyp.GetTriaVertex()==args[0])
- hyp.SetTriaVertex( vertexID )
- return hyp
+ return self.QuadrangleParameters(QUAD_STANDARD,vertex,UseExisting)
# Public class: Mesh_Tetrahedron
reverse( myEdgeLength );
reverse( myIsUniform );
}
- myNormPar[nbEdges-1]=1.;
- myPoints.clear();
- myFalsePoints.clear();
+ if ( nbEdges > 0 )
+ {
+ myNormPar[nbEdges-1]=1.;
+ myPoints.clear();
+ myFalsePoints.clear();
+ }
}
//================================================================================
*/
//================================================================================
- class SMDS_EXPORT Q2TAdaptor_Triangle : public SMDS_MeshFace
+ class STDMESHERS_EXPORT Q2TAdaptor_Triangle : public SMDS_MeshFace
{
const SMDS_MeshNode* _nodes[3];
public:
// Check angle between normals
double angle = nI.Angle( nJ );
- bool tooClose = ( angle < 10 * PI180 );
+ bool tooClose = ( angle < 15 * PI180 );
// Check if pyramids collide
bool isOutI, isOutJ;
}
}
if ( !mergedPyrams.empty() )
- for (TIDSortedElemSet::iterator prm = mergedPyrams.begin(); prm != mergedPyrams.end(); ++prm)
+ {
+ TIDSortedElemSet::iterator prm;
+// for (prm = mergedPyrams.begin(); prm != mergedPyrams.end(); ++prm)
+// MergeAdjacent( *prm, mesh, nodesToMove );
+
+ for (prm = adjacentPyrams.begin(); prm != adjacentPyrams.end(); ++prm)
MergeAdjacent( *prm, mesh, nodesToMove );
+ }
}
}
//
// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
//
-
// SMESH SMESH : implementaion of SMESH idl descriptions
// File : StdMeshers_QuadrangleParams.cxx
// Author : Sergey KUUL, OCC
// Module : SMESH
-//
+
#include "StdMeshers_QuadrangleParams.hxx"
#include "SMESH_Algo.hxx"
//=============================================================================
/*!
- *
+ *
*/
//=============================================================================
-
StdMeshers_QuadrangleParams::StdMeshers_QuadrangleParams(int hypId, int studyId,
SMESH_Gen * gen)
- :SMESH_Hypothesis(hypId, studyId, gen)
+ : SMESH_Hypothesis(hypId, studyId, gen)
{
_name = "QuadrangleParams";
_param_algo_dim = 2;
_triaVertexID = -1;
+ _quadType = QUAD_STANDARD;
}
//=============================================================================
/*!
- *
+ *
*/
//=============================================================================
-
StdMeshers_QuadrangleParams::~StdMeshers_QuadrangleParams()
{
}
//=============================================================================
/*!
- *
+ *
*/
//=============================================================================
-
-void StdMeshers_QuadrangleParams::SetTriaVertex(int id)
+void StdMeshers_QuadrangleParams::SetTriaVertex (int id)
{
- if ( id != _triaVertexID ) {
+ if (id != _triaVertexID) {
_triaVertexID = id;
NotifySubMeshesHypothesisModification();
}
//=============================================================================
/*!
- *
+ *
*/
//=============================================================================
+void StdMeshers_QuadrangleParams::SetQuadType (StdMeshers_QuadType type)
+{
+ if (type != _quadType) {
+ _quadType = type;
+ NotifySubMeshesHypothesisModification();
+ }
+}
+//=============================================================================
+/*!
+ *
+ */
+//=============================================================================
ostream & StdMeshers_QuadrangleParams::SaveTo(ostream & save)
{
- save << _triaVertexID << " " << _objEntry;
+ if (_objEntry.size() == 0)
+ save << _triaVertexID << " UNDEFINED " << int(_quadType);
+ else
+ save << _triaVertexID << " " << _objEntry << " " << int(_quadType);
return save;
}
//=============================================================================
/*!
- *
+ *
*/
//=============================================================================
-
istream & StdMeshers_QuadrangleParams::LoadFrom(istream & load)
{
bool isOK = true;
load.clear(ios::badbit | load.rdstate());
isOK = (load >> _objEntry);
+ if (!isOK)
+ load.clear(ios::badbit | load.rdstate());
+
+ int type;
+ isOK = (load >> type);
+ if (isOK)
+ _quadType = StdMeshers_QuadType(type);
return load;
}
//=============================================================================
/*!
- *
+ *
*/
//=============================================================================
-
ostream & operator <<(ostream & save, StdMeshers_QuadrangleParams & hyp)
{
return hyp.SaveTo( save );
//=============================================================================
/*!
- *
+ *
*/
//=============================================================================
-
istream & operator >>(istream & load, StdMeshers_QuadrangleParams & hyp)
{
return hyp.LoadFrom( load );
* \retval bool - true if parameter values have been successfully defined
*/
//================================================================================
-
bool StdMeshers_QuadrangleParams::SetParametersByMesh(const SMESH_Mesh* theMesh,
const TopoDS_Shape& theShape)
{
* \retval bool - true if parameter values have been successfully defined
*/
//================================================================================
-
bool StdMeshers_QuadrangleParams::SetParametersByDefaults(const TDefaults& dflts,
const SMESH_Mesh* /*mesh*/)
{
return true;
}
-
//
// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
//
-
// SMESH SMESH : implementaion of SMESH idl descriptions
// File : StdMeshers_QuadrangleParams.hxx
// Author : Sergey KUUL, OCC
// Module : SMESH
-//
+
#ifndef _SMESH_QUADRANGLEPARAMS_HXX_
#define _SMESH_QUADRANGLEPARAMS_HXX_
-
-
#include "SMESH_StdMeshers.hxx"
#include "SMESH_Hypothesis.hxx"
#include "Utils_SALOME_Exception.hxx"
+enum StdMeshers_QuadType
+ {
+ QUAD_STANDARD,
+ QUAD_TRIANGLE_PREF,
+ QUAD_QUADRANGLE_PREF,
+ QUAD_QUADRANGLE_PREF_REVERSED,
+ QUAD_REDUCED,
+ QUAD_NB_TYPES
+ };
+
class STDMESHERS_EXPORT StdMeshers_QuadrangleParams:
public SMESH_Hypothesis
{
StdMeshers_QuadrangleParams(int hypId, int studyId, SMESH_Gen* gen);
virtual ~StdMeshers_QuadrangleParams();
- void SetTriaVertex(int id);
-
- void SetObjectEntry( const char* entry ) { _objEntry = entry; }
+ void SetTriaVertex (int id);
+ int GetTriaVertex() const { return _triaVertexID; }
+ void SetObjectEntry (const char* entry) { _objEntry = entry; }
const char* GetObjectEntry() { return _objEntry.c_str(); }
- int GetTriaVertex() const { return _triaVertexID; }
+ void SetQuadType (StdMeshers_QuadType type);
+ StdMeshers_QuadType GetQuadType() const { return _quadType; }
virtual std::ostream & SaveTo(std::ostream & save);
virtual std::istream & LoadFrom(std::istream & load);
const SMESH_Mesh* theMesh=0);
protected:
- int _triaVertexID;
- std::string _objEntry;
+ int _triaVertexID;
+ std::string _objEntry;
+ StdMeshers_QuadType _quadType;
};
#endif
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
-//
-// SMESH SMESH : implementaion of SMESH idl descriptions
// File : StdMeshers_Quadrangle_2D.cxx
-// Moved here from SMESH_Quadrangle_2D.cxx
// Author : Paul RASCLE, EDF
// Module : SMESH
-//
+
#include "StdMeshers_Quadrangle_2D.hxx"
#include "StdMeshers_FaceSide.hxx"
#include <NCollection_DefineArray2.hxx>
#include <Precision.hxx>
#include <TColStd_SequenceOfReal.hxx>
+#include <TColStd_SequenceOfInteger.hxx>
#include <TColgp_SequenceOfXY.hxx>
#include <TopExp.hxx>
#include <TopExp_Explorer.hxx>
bool isOk = true;
aStatus = SMESH_Hypothesis::HYP_OK;
- const list <const SMESHDS_Hypothesis * >&hyps =
+ const list <const SMESHDS_Hypothesis * >& hyps =
GetUsedHypothesis(aMesh, aShape, false);
- const SMESHDS_Hypothesis *theHyp = 0;
-
- if( hyps.size() == 1 ) {
- myTriaVertexID = -1;
- theHyp = hyps.front();
- if(strcmp("QuadrangleParams", theHyp->GetName()) == 0) {
- const StdMeshers_QuadrangleParams* theHyp1 =
- (const StdMeshers_QuadrangleParams*)theHyp;
- myTriaVertexID = theHyp1->GetTriaVertex();
- myQuadranglePreference= false;
- myTrianglePreference= false;
- }
- if(strcmp("QuadranglePreference", theHyp->GetName()) == 0) {
- myQuadranglePreference= true;
- myTrianglePreference= false;
- myTriaVertexID = -1;
- }
- else if(strcmp("TrianglePreference", theHyp->GetName()) == 0){
- myQuadranglePreference= false;
- myTrianglePreference= true;
- myTriaVertexID = -1;
+ const SMESHDS_Hypothesis * aHyp = 0;
+
+ myTriaVertexID = -1;
+ myQuadType = QUAD_STANDARD;
+ myQuadranglePreference = false;
+ myTrianglePreference = false;
+
+ bool isFirstParams = true;
+
+ // First assigned hypothesis (if any) is processed now
+ if (hyps.size() > 0) {
+ aHyp = hyps.front();
+ if (strcmp("QuadrangleParams", aHyp->GetName()) == 0) {
+ const StdMeshers_QuadrangleParams* aHyp1 =
+ (const StdMeshers_QuadrangleParams*)aHyp;
+ myTriaVertexID = aHyp1->GetTriaVertex();
+ myQuadType = aHyp1->GetQuadType();
+ if (myQuadType == QUAD_QUADRANGLE_PREF ||
+ myQuadType == QUAD_QUADRANGLE_PREF_REVERSED)
+ myQuadranglePreference = true;
+ else if (myQuadType == QUAD_TRIANGLE_PREF)
+ myTrianglePreference = true;
+ }
+ else if (strcmp("QuadranglePreference", aHyp->GetName()) == 0) {
+ isFirstParams = false;
+ myQuadranglePreference = true;
+ }
+ else if (strcmp("TrianglePreference", aHyp->GetName()) == 0){
+ isFirstParams = false;
+ myTrianglePreference = true;
+ }
+ else {
+ isFirstParams = false;
}
}
- else if( hyps.size() > 1 ) {
- theHyp = hyps.front();
- if(strcmp("QuadrangleParams", theHyp->GetName()) == 0) {
- const StdMeshers_QuadrangleParams* theHyp1 =
- (const StdMeshers_QuadrangleParams*)theHyp;
- myTriaVertexID = theHyp1->GetTriaVertex();
- theHyp = hyps.back();
- if(strcmp("QuadranglePreference", theHyp->GetName()) == 0) {
- myQuadranglePreference= true;
- myTrianglePreference= false;
+ // Second(last) assigned hypothesis (if any) is processed now
+ if (hyps.size() > 1) {
+ aHyp = hyps.back();
+ if (isFirstParams) {
+ if (strcmp("QuadranglePreference", aHyp->GetName()) == 0) {
+ myQuadranglePreference = true;
+ myTrianglePreference = false;
+ myQuadType = QUAD_STANDARD;
}
- else if(strcmp("TrianglePreference", theHyp->GetName()) == 0){
- myQuadranglePreference= false;
- myTrianglePreference= true;
+ else if (strcmp("TrianglePreference", aHyp->GetName()) == 0){
+ myQuadranglePreference = false;
+ myTrianglePreference = true;
+ myQuadType = QUAD_STANDARD;
}
}
else {
- if(strcmp("QuadranglePreference", theHyp->GetName()) == 0) {
- myQuadranglePreference= true;
- myTrianglePreference= false;
+ const StdMeshers_QuadrangleParams* aHyp2 =
+ (const StdMeshers_QuadrangleParams*)aHyp;
+ myTriaVertexID = aHyp2->GetTriaVertex();
+
+ if (!myQuadranglePreference && !myTrianglePreference) { // priority of hypos
+ myQuadType = aHyp2->GetQuadType();
+ if (myQuadType == QUAD_QUADRANGLE_PREF ||
+ myQuadType == QUAD_QUADRANGLE_PREF_REVERSED)
+ myQuadranglePreference = true;
+ else if (myQuadType == QUAD_TRIANGLE_PREF)
+ myTrianglePreference = true;
}
- else if(strcmp("TrianglePreference", theHyp->GetName()) == 0){
- myQuadranglePreference= false;
- myTrianglePreference= true;
- }
- const StdMeshers_QuadrangleParams* theHyp2 =
- (const StdMeshers_QuadrangleParams*)hyps.back();
- myTriaVertexID = theHyp2->GetTriaVertex();
}
}
- else {
- myQuadranglePreference = false;
- myTrianglePreference = false;
- myTriaVertexID = -1;
- }
-
return isOk;
}
SMESHDS_Mesh * meshDS = aMesh.GetMeshDS();
aMesh.GetSubMesh(aShape);
- SMESH_MesherHelper helper(aMesh);
+ SMESH_MesherHelper helper (aMesh);
myTool = &helper;
_quadraticMesh = myTool->IsQuadraticSubMesh(aShape);
- FaceQuadStruct *quad = CheckNbEdges( aMesh, aShape );
- std::auto_ptr<FaceQuadStruct> quadDeleter( quad ); // to delete quad at exit from Compute()
+ FaceQuadStruct *quad = CheckNbEdges(aMesh, aShape);
+ std::auto_ptr<FaceQuadStruct> quadDeleter (quad); // to delete quad at exit from Compute()
if (!quad)
return false;
- if(myQuadranglePreference) {
+ if (myQuadranglePreference) {
int n1 = quad->side[0]->NbPoints();
int n2 = quad->side[1]->NbPoints();
int n3 = quad->side[2]->NbPoints();
int nfull = n1+n2+n3+n4;
int ntmp = nfull/2;
ntmp = ntmp*2;
- if( nfull==ntmp && ( (n1!=n3) || (n2!=n4) ) ) {
+ if (nfull == ntmp && ((n1 != n3) || (n2 != n4))) {
// special path for using only quandrangle faces
bool ok = ComputeQuadPref(aMesh, aShape, quad);
return ok;
}
}
+ else if (myQuadType == QUAD_REDUCED) {
+ int n1 = quad->side[0]->NbPoints();
+ int n2 = quad->side[1]->NbPoints();
+ int n3 = quad->side[2]->NbPoints();
+ int n4 = quad->side[3]->NbPoints();
+ int n13 = n1 - n3;
+ int n24 = n2 - n4;
+ int n13tmp = n13/2; n13tmp = n13tmp*2;
+ int n24tmp = n24/2; n24tmp = n24tmp*2;
+ if ((n1 == n3 && n2 != n4 && n24tmp == n24) ||
+ (n2 == n4 && n1 != n3 && n13tmp == n13)) {
+ bool ok = ComputeReduced(aMesh, aShape, quad);
+ return ok;
+ }
+ }
// set normalized grid on unit square in parametric domain
Handle(Geom_Surface) S = BRep_Tool::Surface(F);
// internal mesh nodes
- int i, j, geomFaceID = meshDS->ShapeToIndex( F );
+ int i, j, geomFaceID = meshDS->ShapeToIndex(F);
for (i = 1; i < nbhoriz - 1; i++) {
for (j = 1; j < nbvertic - 1; j++) {
int ij = j * nbhoriz + i;
c = quad->uv_grid[(j + 1) * nbhoriz + i + 1].node;
d = quad->uv_grid[(j + 1) * nbhoriz + i].node;
SMDS_MeshFace* face = myTool->AddFace(a, b, c, d);
- if(face) {
+ if (face) {
meshDS->SetMeshElementOnShape(face, geomFaceID);
}
}
}
- const vector<UVPtStruct>& uv_e0 = quad->side[0]->GetUVPtStruct(true,0 );
+ const vector<UVPtStruct>& uv_e0 = quad->side[0]->GetUVPtStruct(true,0);
const vector<UVPtStruct>& uv_e1 = quad->side[1]->GetUVPtStruct(false,1);
- const vector<UVPtStruct>& uv_e2 = quad->side[2]->GetUVPtStruct(true,1 );
+ const vector<UVPtStruct>& uv_e2 = quad->side[2]->GetUVPtStruct(true,1);
const vector<UVPtStruct>& uv_e3 = quad->side[3]->GetUVPtStruct(false,0);
- if ( uv_e0.empty() || uv_e1.empty() || uv_e2.empty() || uv_e3.empty() )
- return error( COMPERR_BAD_INPUT_MESH );
+ if (uv_e0.empty() || uv_e1.empty() || uv_e2.empty() || uv_e3.empty())
+ return error(COMPERR_BAD_INPUT_MESH);
double eps = Precision::Confusion();
if (near == g) { // make triangle
SMDS_MeshFace* face = myTool->AddFace(a, b, c);
- if(face) meshDS->SetMeshElementOnShape(face, geomFaceID);
+ if (face) meshDS->SetMeshElementOnShape(face, geomFaceID);
}
else { // make quadrangle
if (near - 1 < ilow)
d = quad->uv_grid[nbhoriz + near - 1].node;
//SMDS_MeshFace* face = meshDS->AddFace(a, b, c, d);
- if(!myTrianglePreference){
+ if (!myTrianglePreference){
SMDS_MeshFace* face = myTool->AddFace(a, b, c, d);
- if(face) meshDS->SetMeshElementOnShape(face, geomFaceID);
+ if (face) meshDS->SetMeshElementOnShape(face, geomFaceID);
}
else {
SplitQuad(meshDS, geomFaceID, a, b, c, d);
else
d = quad->uv_grid[nbhoriz + k - 1].node;
SMDS_MeshFace* face = myTool->AddFace(a, c, d);
- if(face) meshDS->SetMeshElementOnShape(face, geomFaceID);
+ if (face) meshDS->SetMeshElementOnShape(face, geomFaceID);
}
}
g = near;
if (near == g) { // make triangle
SMDS_MeshFace* face = myTool->AddFace(a, b, c);
- if(face) meshDS->SetMeshElementOnShape(face, geomFaceID);
+ if (face) meshDS->SetMeshElementOnShape(face, geomFaceID);
}
else { // make quadrangle
if (near + 1 > iup)
else
d = quad->uv_grid[nbhoriz*(nbvertic - 2) + near + 1].node;
//SMDS_MeshFace* face = meshDS->AddFace(a, b, c, d);
- if(!myTrianglePreference){
+ if (!myTrianglePreference){
SMDS_MeshFace* face = myTool->AddFace(a, b, c, d);
- if(face) meshDS->SetMeshElementOnShape(face, geomFaceID);
+ if (face) meshDS->SetMeshElementOnShape(face, geomFaceID);
}
else {
SplitQuad(meshDS, geomFaceID, a, b, c, d);
else
d = quad->uv_grid[nbhoriz*(nbvertic - 2) + k + 1].node;
SMDS_MeshFace* face = myTool->AddFace(a, c, d);
- if(face) meshDS->SetMeshElementOnShape(face, geomFaceID);
+ if (face) meshDS->SetMeshElementOnShape(face, geomFaceID);
}
}
g = near;
if (near == g) { // make triangle
SMDS_MeshFace* face = myTool->AddFace(a, b, c);
- if(face) meshDS->SetMeshElementOnShape(face, geomFaceID);
+ if (face) meshDS->SetMeshElementOnShape(face, geomFaceID);
}
else { // make quadrangle
if (near - 1 < jlow)
d = quad->uv_grid[nbhoriz*near - 2].node;
//SMDS_MeshFace* face = meshDS->AddFace(a, b, c, d);
- if(!myTrianglePreference){
+ if (!myTrianglePreference){
SMDS_MeshFace* face = myTool->AddFace(a, b, c, d);
- if(face) meshDS->SetMeshElementOnShape(face, geomFaceID);
+ if (face) meshDS->SetMeshElementOnShape(face, geomFaceID);
}
else {
SplitQuad(meshDS, geomFaceID, a, b, c, d);
else
d = quad->uv_grid[nbhoriz*k - 2].node;
SMDS_MeshFace* face = myTool->AddFace(a, c, d);
- if(face) meshDS->SetMeshElementOnShape(face, geomFaceID);
+ if (face) meshDS->SetMeshElementOnShape(face, geomFaceID);
}
}
g = near;
if (near == g) { // make triangle
SMDS_MeshFace* face = myTool->AddFace(a, b, c);
- if(face) meshDS->SetMeshElementOnShape(face, geomFaceID);
+ if (face) meshDS->SetMeshElementOnShape(face, geomFaceID);
}
else { // make quadrangle
if (near + 1 > jup)
else
d = quad->uv_grid[nbhoriz*(near + 1) + 1].node;
//SMDS_MeshFace* face = meshDS->AddFace(a, b, c, d);
- if(!myTrianglePreference){
+ if (!myTrianglePreference){
SMDS_MeshFace* face = myTool->AddFace(a, b, c, d);
- if(face) meshDS->SetMeshElementOnShape(face, geomFaceID);
+ if (face) meshDS->SetMeshElementOnShape(face, geomFaceID);
}
else {
SplitQuad(meshDS, geomFaceID, a, b, c, d);
else
d = quad->uv_grid[nbhoriz*(k + 1) + 1].node;
SMDS_MeshFace* face = myTool->AddFace(a, c, d);
- if(face) meshDS->SetMeshElementOnShape(face, geomFaceID);
+ if (face) meshDS->SetMeshElementOnShape(face, geomFaceID);
}
}
g = near;
std::vector<int> aNbNodes(4);
bool IsQuadratic = false;
- if( !CheckNbEdgesForEvaluate( aMesh, aShape, aResMap, aNbNodes, IsQuadratic ) ) {
+ if (!CheckNbEdgesForEvaluate(aMesh, aShape, aResMap, aNbNodes, IsQuadratic)) {
std::vector<int> aResVec(SMDSEntity_Last);
- for(int i=SMDSEntity_Node; i<SMDSEntity_Last; i++) aResVec[i] = 0;
+ for (int i=SMDSEntity_Node; i<SMDSEntity_Last; i++) aResVec[i] = 0;
SMESH_subMesh * sm = aMesh.GetSubMesh(aShape);
aResMap.insert(std::make_pair(sm,aResVec));
SMESH_ComputeErrorPtr& smError = sm->GetComputeError();
- smError.reset( new SMESH_ComputeError(COMPERR_ALGO_FAILED,"Submesh can not be evaluated",this));
+ smError.reset(new SMESH_ComputeError(COMPERR_ALGO_FAILED,"Submesh can not be evaluated",this));
return false;
}
- if(myQuadranglePreference) {
+ if (myQuadranglePreference) {
int n1 = aNbNodes[0];
int n2 = aNbNodes[1];
int n3 = aNbNodes[2];
int nfull = n1+n2+n3+n4;
int ntmp = nfull/2;
ntmp = ntmp*2;
- if( nfull==ntmp && ( (n1!=n3) || (n2!=n4) ) ) {
+ if (nfull==ntmp && ((n1!=n3) || (n2!=n4))) {
// special path for using only quandrangle faces
return EvaluateQuadPref(aMesh, aShape, aNbNodes, aResMap, IsQuadratic);
//return true;
int dv = Max(nbright, nbleft) - nbvertic;
//int kdh = 0;
- //if(dh>0) kdh = 1;
+ //if (dh>0) kdh = 1;
//int kdv = 0;
- //if(dv>0) kdv = 1;
+ //if (dv>0) kdv = 1;
int nbNodes = (nbhoriz-2)*(nbvertic-2);
//int nbFaces3 = dh + dv + kdh*(nbvertic-1)*2 + kdv*(nbhoriz-1)*2;
int nbFaces3 = dh + dv;
- //if( kdh==1 && kdv==1 ) nbFaces3 -= 2;
- //if( dh>0 && dv>0 ) nbFaces3 -= 2;
+ //if (kdh==1 && kdv==1) nbFaces3 -= 2;
+ //if (dh>0 && dv>0) nbFaces3 -= 2;
//int nbFaces4 = (nbhoriz-1-kdh)*(nbvertic-1-kdv);
int nbFaces4 = (nbhoriz-1)*(nbvertic-1);
std::vector<int> aVec(SMDSEntity_Last);
- for(int i=SMDSEntity_Node; i<SMDSEntity_Last; i++) aVec[i] = 0;
- if(IsQuadratic) {
+ for (int i=SMDSEntity_Node; i<SMDSEntity_Last; i++) aVec[i] = 0;
+ if (IsQuadratic) {
aVec[SMDSEntity_Quad_Triangle] = nbFaces3;
aVec[SMDSEntity_Quad_Quadrangle] = nbFaces4;
int nbbndedges = nbdown + nbup + nbright + nbleft -4;
- int nbintedges = ( nbFaces4*4 + nbFaces3*3 - nbbndedges ) / 2;
+ int nbintedges = (nbFaces4*4 + nbFaces3*3 - nbbndedges) / 2;
aVec[SMDSEntity_Node] = nbNodes + nbintedges;
- if( aNbNodes.size()==5 ) {
+ if (aNbNodes.size()==5) {
aVec[SMDSEntity_Quad_Triangle] = nbFaces3 + aNbNodes[3] -1;
aVec[SMDSEntity_Quad_Quadrangle] = nbFaces4 - aNbNodes[3] +1;
}
aVec[SMDSEntity_Node] = nbNodes;
aVec[SMDSEntity_Triangle] = nbFaces3;
aVec[SMDSEntity_Quadrangle] = nbFaces4;
- if( aNbNodes.size()==5 ) {
+ if (aNbNodes.size()==5) {
aVec[SMDSEntity_Triangle] = nbFaces3 + aNbNodes[3] - 1;
aVec[SMDSEntity_Quadrangle] = nbFaces4 - aNbNodes[3] + 1;
}
SMESH_Mesh & mesh)
{
TopoDS_Vertex v;
- if ( !TopExp::CommonVertex( e1, e2, v ))
+ if (!TopExp::CommonVertex(e1, e2, v))
return false;
- TopTools_ListIteratorOfListOfShape ancestIt( mesh.GetAncestors( v ));
- for ( ; ancestIt.More() ; ancestIt.Next() )
- if ( ancestIt.Value().ShapeType() == TopAbs_EDGE )
- if ( !e1.IsSame( ancestIt.Value() ) && !e2.IsSame( ancestIt.Value() ))
+ TopTools_ListIteratorOfListOfShape ancestIt(mesh.GetAncestors(v));
+ for (; ancestIt.More() ; ancestIt.Next())
+ if (ancestIt.Value().ShapeType() == TopAbs_EDGE)
+ if (!e1.IsSame(ancestIt.Value()) && !e2.IsSame(ancestIt.Value()))
return false;
return true;
}
int nbSides = 0;
list< TopoDS_Edge >::iterator edgeIt = edges.begin();
- if ( nbEdgesInWire.front() == 3 ) // exactly 3 edges
+ if (nbEdgesInWire.front() == 3) // exactly 3 edges
{
SMESH_Comment comment;
SMESHDS_Mesh* meshDS = aMesh.GetMeshDS();
- if ( myTriaVertexID == -1)
+ if (myTriaVertexID == -1)
{
comment << "No Base vertex parameter provided for a trilateral geometrical face";
}
else
{
TopoDS_Vertex V = TopoDS::Vertex(meshDS->IndexToShape(myTriaVertexID));
- if ( !V.IsNull() ) {
+ if (!V.IsNull()) {
TopoDS_Edge E1,E2,E3;
- for(; edgeIt != edges.end(); ++edgeIt) {
+ for (; edgeIt != edges.end(); ++edgeIt) {
TopoDS_Edge E = *edgeIt;
TopoDS_Vertex VF, VL;
TopExp::Vertices(E, VF, VL, true);
- if( VF.IsSame(V) )
+ if (VF.IsSame(V))
E1 = E;
- else if( VL.IsSame(V) )
+ else if (VL.IsSame(V))
E3 = E;
else
E2 = E;
}
- if ( !E1.IsNull() && !E2.IsNull() && !E3.IsNull() )
+ if (!E1.IsNull() && !E2.IsNull() && !E3.IsNull())
{
- quad->side.push_back( new StdMeshers_FaceSide(F, E1, &aMesh, true, ignoreMediumNodes));
- quad->side.push_back( new StdMeshers_FaceSide(F, E2, &aMesh, true, ignoreMediumNodes));
- quad->side.push_back( new StdMeshers_FaceSide(F, E3, &aMesh, false,ignoreMediumNodes));
+ quad->side.push_back(new StdMeshers_FaceSide(F, E1, &aMesh, true, ignoreMediumNodes));
+ quad->side.push_back(new StdMeshers_FaceSide(F, E2, &aMesh, true, ignoreMediumNodes));
+ quad->side.push_back(new StdMeshers_FaceSide(F, E3, &aMesh, false,ignoreMediumNodes));
const vector<UVPtStruct>& UVPSleft = quad->side[0]->GetUVPtStruct(true,0);
/* vector<UVPtStruct>& UVPStop = */quad->side[1]->GetUVPtStruct(false,1);
/* vector<UVPtStruct>& UVPSright = */quad->side[2]->GetUVPtStruct(true,1);
const SMDS_MeshNode* aNode = UVPSleft[0].node;
- gp_Pnt2d aPnt2d( UVPSleft[0].u, UVPSleft[0].v );
- quad->side.push_back( new StdMeshers_FaceSide(aNode, aPnt2d, quad->side[1]));
+ gp_Pnt2d aPnt2d(UVPSleft[0].u, UVPSleft[0].v);
+ quad->side.push_back(new StdMeshers_FaceSide(aNode, aPnt2d, quad->side[1]));
return quad;
}
}
comment << "Invalid Base vertex parameter: " << myTriaVertexID << " is not among [";
TopTools_MapOfShape vMap;
- for ( TopExp_Explorer v( aShape, TopAbs_VERTEX ); v.More(); v.Next())
- if ( vMap.Add( v.Current() ))
- comment << meshDS->ShapeToIndex( v.Current() ) << ( vMap.Extent()==3 ? "]" : ", ");
+ for (TopExp_Explorer v(aShape, TopAbs_VERTEX); v.More(); v.Next())
+ if (vMap.Add(v.Current()))
+ comment << meshDS->ShapeToIndex(v.Current()) << (vMap.Extent()==3 ? "]" : ", ");
}
- error( comment );
+ error(comment);
delete quad;
return quad = 0;
}
- else if ( nbEdgesInWire.front() == 4 ) { // exactly 4 edges
- for ( ; edgeIt != edges.end(); ++edgeIt, nbSides++ )
- quad->side.push_back( new StdMeshers_FaceSide(F, *edgeIt, &aMesh,
+ else if (nbEdgesInWire.front() == 4) { // exactly 4 edges
+ for (; edgeIt != edges.end(); ++edgeIt, nbSides++)
+ quad->side.push_back(new StdMeshers_FaceSide(F, *edgeIt, &aMesh,
nbSides<TOP_SIDE, ignoreMediumNodes));
}
- else if ( nbEdgesInWire.front() > 4 ) { // more than 4 edges - try to unite some
+ else if (nbEdgesInWire.front() > 4) { // more than 4 edges - try to unite some
list< TopoDS_Edge > sideEdges;
- while ( !edges.empty()) {
+ while (!edges.empty()) {
sideEdges.clear();
- sideEdges.splice( sideEdges.end(), edges, edges.begin()); // edges.front() -> sideEdges.end()
+ sideEdges.splice(sideEdges.end(), edges, edges.begin()); // edges.front() -> sideEdges.end()
bool sameSide = true;
- while ( !edges.empty() && sameSide ) {
- sameSide = SMESH_Algo::IsContinuous( sideEdges.back(), edges.front() );
- if ( sameSide )
- sideEdges.splice( sideEdges.end(), edges, edges.begin());
+ while (!edges.empty() && sameSide) {
+ sameSide = SMESH_Algo::IsContinuous(sideEdges.back(), edges.front());
+ if (sameSide)
+ sideEdges.splice(sideEdges.end(), edges, edges.begin());
}
- if ( nbSides == 0 ) { // go backward from the first edge
+ if (nbSides == 0) { // go backward from the first edge
sameSide = true;
- while ( !edges.empty() && sameSide ) {
- sameSide = SMESH_Algo::IsContinuous( sideEdges.front(), edges.back() );
- if ( sameSide )
- sideEdges.splice( sideEdges.begin(), edges, --edges.end());
+ while (!edges.empty() && sameSide) {
+ sameSide = SMESH_Algo::IsContinuous(sideEdges.front(), edges.back());
+ if (sameSide)
+ sideEdges.splice(sideEdges.begin(), edges, --edges.end());
}
}
- quad->side.push_back( new StdMeshers_FaceSide(F, sideEdges, &aMesh,
+ quad->side.push_back(new StdMeshers_FaceSide(F, sideEdges, &aMesh,
nbSides<TOP_SIDE, ignoreMediumNodes));
++nbSides;
}
// issue 20222. Try to unite only edges shared by two same faces
if (nbSides < 4) {
// delete found sides
- { FaceQuadStruct cleaner( *quad ); }
+ { FaceQuadStruct cleaner(*quad); }
quad->side.clear();
quad->side.reserve(nbEdgesInWire.front());
nbSides = 0;
SMESH_Block::GetOrderedEdges (F, V, edges, nbEdgesInWire);
- while ( !edges.empty()) {
+ while (!edges.empty()) {
sideEdges.clear();
- sideEdges.splice( sideEdges.end(), edges, edges.begin());
+ sideEdges.splice(sideEdges.end(), edges, edges.begin());
bool sameSide = true;
- while ( !edges.empty() && sameSide ) {
+ while (!edges.empty() && sameSide) {
sameSide =
- SMESH_Algo::IsContinuous( sideEdges.back(), edges.front() ) &&
- twoEdgesMeatAtVertex( sideEdges.back(), edges.front(), aMesh );
- if ( sameSide )
- sideEdges.splice( sideEdges.end(), edges, edges.begin());
+ SMESH_Algo::IsContinuous(sideEdges.back(), edges.front()) &&
+ twoEdgesMeatAtVertex(sideEdges.back(), edges.front(), aMesh);
+ if (sameSide)
+ sideEdges.splice(sideEdges.end(), edges, edges.begin());
}
- if ( nbSides == 0 ) { // go backward from the first edge
+ if (nbSides == 0) { // go backward from the first edge
sameSide = true;
- while ( !edges.empty() && sameSide ) {
+ while (!edges.empty() && sameSide) {
sameSide =
- SMESH_Algo::IsContinuous( sideEdges.front(), edges.back() ) &&
- twoEdgesMeatAtVertex( sideEdges.front(), edges.back(), aMesh );
- if ( sameSide )
- sideEdges.splice( sideEdges.begin(), edges, --edges.end());
+ SMESH_Algo::IsContinuous(sideEdges.front(), edges.back()) &&
+ twoEdgesMeatAtVertex(sideEdges.front(), edges.back(), aMesh);
+ if (sameSide)
+ sideEdges.splice(sideEdges.begin(), edges, --edges.end());
}
}
- quad->side.push_back( new StdMeshers_FaceSide(F, sideEdges, &aMesh,
+ quad->side.push_back(new StdMeshers_FaceSide(F, sideEdges, &aMesh,
nbSides<TOP_SIDE, ignoreMediumNodes));
++nbSides;
}
}
if (nbSides != 4) {
#ifdef _DEBUG_
- MESSAGE ( "StdMeshers_Quadrangle_2D. Edge IDs of " << nbSides << " sides:\n" );
- for ( int i = 0; i < nbSides; ++i ) {
- MESSAGE ( " ( " );
- for ( int e = 0; e < quad->side[i]->NbEdges(); ++e )
- MESSAGE ( myTool->GetMeshDS()->ShapeToIndex( quad->side[i]->Edge( e )) << " " );
- MESSAGE ( ")\n" );
+ MESSAGE ("StdMeshers_Quadrangle_2D. Edge IDs of " << nbSides << " sides:\n");
+ for (int i = 0; i < nbSides; ++i) {
+ MESSAGE (" (");
+ for (int e = 0; e < quad->side[i]->NbEdges(); ++e)
+ MESSAGE (myTool->GetMeshDS()->ShapeToIndex(quad->side[i]->Edge(e)) << " ");
+ MESSAGE (")\n");
}
//cout << endl;
#endif
- if ( !nbSides )
+ if (!nbSides)
nbSides = nbEdgesInWire.front();
error(COMPERR_BAD_SHAPE, TComm("Face must have 4 sides but not ") << nbSides);
delete quad;
int nbSides = 0;
list< TopoDS_Edge >::iterator edgeIt = edges.begin();
- SMESH_subMesh * sm = aMesh.GetSubMesh( *edgeIt );
+ SMESH_subMesh * sm = aMesh.GetSubMesh(*edgeIt);
MapShapeNbElemsItr anIt = aResMap.find(sm);
- if(anIt==aResMap.end()) {
+ if (anIt==aResMap.end()) {
return false;
}
std::vector<int> aVec = (*anIt).second;
IsQuadratic = (aVec[SMDSEntity_Quad_Edge] > aVec[SMDSEntity_Edge]);
- if ( nbEdgesInWire.front() == 3 ) { // exactly 3 edges
- if(myTriaVertexID>0) {
+ if (nbEdgesInWire.front() == 3) { // exactly 3 edges
+ if (myTriaVertexID>0) {
SMESHDS_Mesh* meshDS = aMesh.GetMeshDS();
TopoDS_Vertex V = TopoDS::Vertex(meshDS->IndexToShape(myTriaVertexID));
- if(!V.IsNull()) {
+ if (!V.IsNull()) {
TopoDS_Edge E1,E2,E3;
- for(; edgeIt != edges.end(); ++edgeIt) {
+ for (; edgeIt != edges.end(); ++edgeIt) {
TopoDS_Edge E = TopoDS::Edge(*edgeIt);
TopoDS_Vertex VF, VL;
TopExp::Vertices(E, VF, VL, true);
- if( VF.IsSame(V) )
+ if (VF.IsSame(V))
E1 = E;
- else if( VL.IsSame(V) )
+ else if (VL.IsSame(V))
E3 = E;
else
E2 = E;
}
SMESH_subMesh * sm = aMesh.GetSubMesh(E1);
MapShapeNbElemsItr anIt = aResMap.find(sm);
- if(anIt==aResMap.end()) return false;
+ if (anIt==aResMap.end()) return false;
std::vector<int> aVec = (*anIt).second;
- if(IsQuadratic)
+ if (IsQuadratic)
aNbNodes[0] = (aVec[SMDSEntity_Node]-1)/2 + 2;
else
aNbNodes[0] = aVec[SMDSEntity_Node] + 2;
sm = aMesh.GetSubMesh(E2);
anIt = aResMap.find(sm);
- if(anIt==aResMap.end()) return false;
+ if (anIt==aResMap.end()) return false;
aVec = (*anIt).second;
- if(IsQuadratic)
+ if (IsQuadratic)
aNbNodes[1] = (aVec[SMDSEntity_Node]-1)/2 + 2;
else
aNbNodes[1] = aVec[SMDSEntity_Node] + 2;
sm = aMesh.GetSubMesh(E3);
anIt = aResMap.find(sm);
- if(anIt==aResMap.end()) return false;
+ if (anIt==aResMap.end()) return false;
aVec = (*anIt).second;
- if(IsQuadratic)
+ if (IsQuadratic)
aNbNodes[2] = (aVec[SMDSEntity_Node]-1)/2 + 2;
else
aNbNodes[2] = aVec[SMDSEntity_Node] + 2;
}
}
}
- if ( nbEdgesInWire.front() == 4 ) { // exactly 4 edges
- for(; edgeIt != edges.end(); edgeIt++) {
- SMESH_subMesh * sm = aMesh.GetSubMesh( *edgeIt );
+ if (nbEdgesInWire.front() == 4) { // exactly 4 edges
+ for (; edgeIt != edges.end(); edgeIt++) {
+ SMESH_subMesh * sm = aMesh.GetSubMesh(*edgeIt);
MapShapeNbElemsItr anIt = aResMap.find(sm);
- if(anIt==aResMap.end()) {
+ if (anIt==aResMap.end()) {
return false;
}
std::vector<int> aVec = (*anIt).second;
- if(IsQuadratic)
+ if (IsQuadratic)
aNbNodes[nbSides] = (aVec[SMDSEntity_Node]-1)/2 + 2;
else
aNbNodes[nbSides] = aVec[SMDSEntity_Node] + 2;
nbSides++;
}
}
- else if ( nbEdgesInWire.front() > 4 ) { // more than 4 edges - try to unite some
+ else if (nbEdgesInWire.front() > 4) { // more than 4 edges - try to unite some
list< TopoDS_Edge > sideEdges;
- while ( !edges.empty()) {
+ while (!edges.empty()) {
sideEdges.clear();
- sideEdges.splice( sideEdges.end(), edges, edges.begin()); // edges.front() -> sideEdges.end()
+ sideEdges.splice(sideEdges.end(), edges, edges.begin()); // edges.front() -> sideEdges.end()
bool sameSide = true;
- while ( !edges.empty() && sameSide ) {
- sameSide = SMESH_Algo::IsContinuous( sideEdges.back(), edges.front() );
- if ( sameSide )
- sideEdges.splice( sideEdges.end(), edges, edges.begin());
+ while (!edges.empty() && sameSide) {
+ sameSide = SMESH_Algo::IsContinuous(sideEdges.back(), edges.front());
+ if (sameSide)
+ sideEdges.splice(sideEdges.end(), edges, edges.begin());
}
- if ( nbSides == 0 ) { // go backward from the first edge
+ if (nbSides == 0) { // go backward from the first edge
sameSide = true;
- while ( !edges.empty() && sameSide ) {
- sameSide = SMESH_Algo::IsContinuous( sideEdges.front(), edges.back() );
- if ( sameSide )
- sideEdges.splice( sideEdges.begin(), edges, --edges.end());
+ while (!edges.empty() && sameSide) {
+ sameSide = SMESH_Algo::IsContinuous(sideEdges.front(), edges.back());
+ if (sameSide)
+ sideEdges.splice(sideEdges.begin(), edges, --edges.end());
}
}
list<TopoDS_Edge>::iterator ite = sideEdges.begin();
aNbNodes[nbSides] = 1;
- for(; ite!=sideEdges.end(); ite++) {
- SMESH_subMesh * sm = aMesh.GetSubMesh( *ite );
+ for (; ite!=sideEdges.end(); ite++) {
+ SMESH_subMesh * sm = aMesh.GetSubMesh(*ite);
MapShapeNbElemsItr anIt = aResMap.find(sm);
- if(anIt==aResMap.end()) {
+ if (anIt==aResMap.end()) {
return false;
}
std::vector<int> aVec = (*anIt).second;
- if(IsQuadratic)
+ if (IsQuadratic)
aNbNodes[nbSides] += (aVec[SMDSEntity_Node]-1)/2 + 1;
else
aNbNodes[nbSides] += aVec[SMDSEntity_Node] + 1;
if (nbSides < 4) {
nbSides = 0;
SMESH_Block::GetOrderedEdges (F, V, edges, nbEdgesInWire);
- while ( !edges.empty()) {
+ while (!edges.empty()) {
sideEdges.clear();
- sideEdges.splice( sideEdges.end(), edges, edges.begin());
+ sideEdges.splice(sideEdges.end(), edges, edges.begin());
bool sameSide = true;
- while ( !edges.empty() && sameSide ) {
+ while (!edges.empty() && sameSide) {
sameSide =
- SMESH_Algo::IsContinuous( sideEdges.back(), edges.front() ) &&
- twoEdgesMeatAtVertex( sideEdges.back(), edges.front(), aMesh );
- if ( sameSide )
- sideEdges.splice( sideEdges.end(), edges, edges.begin());
+ SMESH_Algo::IsContinuous(sideEdges.back(), edges.front()) &&
+ twoEdgesMeatAtVertex(sideEdges.back(), edges.front(), aMesh);
+ if (sameSide)
+ sideEdges.splice(sideEdges.end(), edges, edges.begin());
}
- if ( nbSides == 0 ) { // go backward from the first edge
+ if (nbSides == 0) { // go backward from the first edge
sameSide = true;
- while ( !edges.empty() && sameSide ) {
+ while (!edges.empty() && sameSide) {
sameSide =
- SMESH_Algo::IsContinuous( sideEdges.front(), edges.back() ) &&
- twoEdgesMeatAtVertex( sideEdges.front(), edges.back(), aMesh );
- if ( sameSide )
- sideEdges.splice( sideEdges.begin(), edges, --edges.end());
+ SMESH_Algo::IsContinuous(sideEdges.front(), edges.back()) &&
+ twoEdgesMeatAtVertex(sideEdges.front(), edges.back(), aMesh);
+ if (sameSide)
+ sideEdges.splice(sideEdges.begin(), edges, --edges.end());
}
}
list<TopoDS_Edge>::iterator ite = sideEdges.begin();
aNbNodes[nbSides] = 1;
- for(; ite!=sideEdges.end(); ite++) {
- SMESH_subMesh * sm = aMesh.GetSubMesh( *ite );
+ for (; ite!=sideEdges.end(); ite++) {
+ SMESH_subMesh * sm = aMesh.GetSubMesh(*ite);
MapShapeNbElemsItr anIt = aResMap.find(sm);
- if(anIt==aResMap.end()) {
+ if (anIt==aResMap.end()) {
return false;
}
std::vector<int> aVec = (*anIt).second;
- if(IsQuadratic)
+ if (IsQuadratic)
aNbNodes[nbSides] += (aVec[SMDSEntity_Node]-1)/2 + 1;
else
aNbNodes[nbSides] += aVec[SMDSEntity_Node] + 1;
}
}
if (nbSides != 4) {
- if ( !nbSides )
+ if (!nbSides)
nbSides = nbEdgesInWire.front();
error(COMPERR_BAD_SHAPE, TComm("Face must have 4 sides but not ") << nbSides);
return false;
FaceQuadStruct *quad = CheckNbEdges(aMesh, aShape);
- if(!quad) return 0;
+ if (!quad) return 0;
// set normalized grid on unit square in parametric domain
bool stat = SetNormalizedGrid(aMesh, aShape, quad);
- if(!stat) {
- if(!quad)
- delete quad;
+ if (!stat) {
+ if (quad) delete quad;
quad = 0;
}
namespace {
inline const vector<UVPtStruct>& GetUVPtStructIn(FaceQuadStruct* quad, int i, int nbSeg)
{
- bool isXConst = ( i == BOTTOM_SIDE || i == TOP_SIDE );
- double constValue = ( i == BOTTOM_SIDE || i == LEFT_SIDE ) ? 0 : 1;
+ bool isXConst = (i == BOTTOM_SIDE || i == TOP_SIDE);
+ double constValue = (i == BOTTOM_SIDE || i == LEFT_SIDE) ? 0 : 1;
return
quad->isEdgeOut[i] ?
quad->side[i]->SimulateUVPtStruct(nbSeg,isXConst,constValue) :
quad->side[i]->GetUVPtStruct(isXConst,constValue);
}
+ inline gp_UV CalcUV(double x, double y,
+ const gp_UV& a0,const gp_UV& a1,const gp_UV& a2,const gp_UV& a3,
+ const gp_UV& p0,const gp_UV& p1,const gp_UV& p2,const gp_UV& p3)
+ {
+ return
+ ((1 - y) * p0 + x * p1 + y * p2 + (1 - x) * p3 ) -
+ ((1 - x) * (1 - y) * a0 + x * (1 - y) * a1 + x * y * a2 + (1 - x) * y * a3);
+ }
}
//=============================================================================
UVPtStruct *uv_grid = quad->uv_grid = new UVPtStruct[nbvertic * nbhoriz];
- const vector<UVPtStruct>& uv_e0 = GetUVPtStructIn( quad, 0, nbhoriz - 1 );
- const vector<UVPtStruct>& uv_e1 = GetUVPtStructIn( quad, 1, nbvertic - 1 );
- const vector<UVPtStruct>& uv_e2 = GetUVPtStructIn( quad, 2, nbhoriz - 1 );
- const vector<UVPtStruct>& uv_e3 = GetUVPtStructIn( quad, 3, nbvertic - 1 );
+ const vector<UVPtStruct>& uv_e0 = GetUVPtStructIn(quad, 0, nbhoriz - 1);
+ const vector<UVPtStruct>& uv_e1 = GetUVPtStructIn(quad, 1, nbvertic - 1);
+ const vector<UVPtStruct>& uv_e2 = GetUVPtStructIn(quad, 2, nbhoriz - 1);
+ const vector<UVPtStruct>& uv_e3 = GetUVPtStructIn(quad, 3, nbvertic - 1);
- if ( uv_e0.empty() || uv_e1.empty() || uv_e2.empty() || uv_e3.empty() )
- //return error( "Can't find nodes on sides");
- return error( COMPERR_BAD_INPUT_MESH );
+ if (uv_e0.empty() || uv_e1.empty() || uv_e2.empty() || uv_e3.empty())
+ //return error("Can't find nodes on sides");
+ return error(COMPERR_BAD_INPUT_MESH);
// nodes Id on "in" edges
if (! quad->isEdgeOut[0]) {
}
// 4 --- projection on 2d domain (u,v)
- gp_UV a0( uv_e0.front().u, uv_e0.front().v );
- gp_UV a1( uv_e0.back().u, uv_e0.back().v );
- gp_UV a2( uv_e2.back().u, uv_e2.back().v );
- gp_UV a3( uv_e2.front().u, uv_e2.front().v );
+ gp_UV a0(uv_e0.front().u, uv_e0.front().v);
+ gp_UV a1(uv_e0.back().u, uv_e0.back().v);
+ gp_UV a2(uv_e2.back().u, uv_e2.back().v);
+ gp_UV a3(uv_e2.front().u, uv_e2.front().v);
for (int i = 0; i < nbhoriz; i++) {
for (int j = 0; j < nbvertic; j++) {
gp_UV p2 = quad->side[2]->Value2d(param_2).XY();
gp_UV p3 = quad->side[3]->Value2d(param_3).XY();
- gp_UV uv = (1 - y) * p0 + x * p1 + y * p2 + (1 - x) * p3;
- uv -= (1 - x) * (1 - y) * a0 + x * (1 - y) * a1 + x * y * a2 + (1 - x) * y * a3;
+ gp_UV uv = CalcUV(x,y, a0,a1,a2,a3, p0,p1,p2,p3);
uv_grid[ij].u = uv.X();
uv_grid[ij].v = uv.Y();
static void ShiftQuad(FaceQuadStruct* quad, const int num, bool)
{
StdMeshers_FaceSide* side[4] = { quad->side[0], quad->side[1], quad->side[2], quad->side[3] };
- for (int i = BOTTOM_SIDE; i < NB_SIDES; ++i ) {
- int id = ( i + num ) % NB_SIDES;
- bool wasForward = ( i < TOP_SIDE );
- bool newForward = ( id < TOP_SIDE );
- if ( wasForward != newForward )
+ for (int i = BOTTOM_SIDE; i < NB_SIDES; ++i) {
+ int id = (i + num) % NB_SIDES;
+ bool wasForward = (i < TOP_SIDE);
+ bool newForward = (id < TOP_SIDE);
+ if (wasForward != newForward)
side[ i ]->Reverse();
quad->side[ id ] = side[ i ];
}
const gp_UV& a0, const gp_UV& a1,
const gp_UV& a2, const gp_UV& a3)
{
- const vector<UVPtStruct>& uv_eb = quad->side[0]->GetUVPtStruct(true,0 );
+ const vector<UVPtStruct>& uv_eb = quad->side[0]->GetUVPtStruct(true,0);
const vector<UVPtStruct>& uv_er = quad->side[1]->GetUVPtStruct(false,1);
- const vector<UVPtStruct>& uv_et = quad->side[2]->GetUVPtStruct(true,1 );
+ const vector<UVPtStruct>& uv_et = quad->side[2]->GetUVPtStruct(true,1);
const vector<UVPtStruct>& uv_el = quad->side[3]->GetUVPtStruct(false,0);
double x = (x0 + y0 * (x1 - x0)) / (1 - (y1 - y0) * (x1 - x0));
gp_UV p2 = quad->side[TOP_SIDE ]->Value2d(param_t).XY();
gp_UV p3 = quad->side[LEFT_SIDE ]->Value2d(param_l).XY();
- gp_UV uv = p0 * (1 - y) + p1 * x + p2 * y + p3 * (1 - x);
-
- uv -= (1 - x) * (1 - y) * a0 + x * (1 - y) * a1 + x * y * a2 + (1 - x) * y * a3;
+ gp_UV uv = CalcUV(x,y, a0,a1,a2,a3, p0,p1,p2,p3);
return uv;
}
const gp_UV& a0, const gp_UV& a1,
const gp_UV& a2, const gp_UV& a3)
{
- const vector<UVPtStruct>& uv_eb = quad->side[0]->GetUVPtStruct(true,0 );
- const vector<UVPtStruct>& uv_er = quad->side[1]->GetUVPtStruct(false,1);
- const vector<UVPtStruct>& uv_et = quad->side[2]->GetUVPtStruct(true,1 );
- const vector<UVPtStruct>& uv_el = quad->side[3]->GetUVPtStruct(false,0);
-
- //double x = (x0 + y0 * (x1 - x0)) / (1 - (y1 - y0) * (x1 - x0));
- //double y = y0 + x * (y1 - y0);
-
- double param_b = uv_eb[0].normParam + x * (uv_eb.back().normParam - uv_eb[0].normParam);
- double param_t = uv_et[0].normParam + x * (uv_et.back().normParam - uv_et[0].normParam);
- double param_r = uv_er[0].normParam + y * (uv_er.back().normParam - uv_er[0].normParam);
- double param_l = uv_el[0].normParam + y * (uv_el.back().normParam - uv_el[0].normParam);
-
- gp_UV p0 = quad->side[BOTTOM_SIDE]->Value2d(param_b).XY();
- gp_UV p1 = quad->side[RIGHT_SIDE ]->Value2d(param_r).XY();
- gp_UV p2 = quad->side[TOP_SIDE ]->Value2d(param_t).XY();
- gp_UV p3 = quad->side[LEFT_SIDE ]->Value2d(param_l).XY();
-
- gp_UV uv = p0 * (1 - y) + p1 * x + p2 * y + p3 * (1 - x);
+ gp_UV p0 = quad->side[BOTTOM_SIDE]->Value2d(x).XY();
+ gp_UV p1 = quad->side[RIGHT_SIDE ]->Value2d(y).XY();
+ gp_UV p2 = quad->side[TOP_SIDE ]->Value2d(x).XY();
+ gp_UV p3 = quad->side[LEFT_SIDE ]->Value2d(y).XY();
- uv -= (1 - x) * (1 - y) * a0 + x * (1 - y) * a1 + x * y * a2 + (1 - x) * y * a3;
+ gp_UV uv = CalcUV(x,y, a0,a1,a2,a3, p0,p1,p2,p3);
return uv;
}
// of meshing after implementation new variant
// for bug 0016220 from Mantis.
bool OldVersion = false;
+ if (myQuadType == QUAD_QUADRANGLE_PREF_REVERSED)
+ OldVersion = true;
SMESHDS_Mesh * meshDS = aMesh.GetMeshDS();
const TopoDS_Face& F = TopoDS::Face(aShape);
Handle(Geom_Surface) S = BRep_Tool::Surface(F);
-// const TopoDS_Wire& W = BRepTools::OuterWire(F);
bool WisF = true;
-// if(W.Orientation()==TopAbs_FORWARD)
-// WisF = true;
- //if(WisF) cout<<"W is FORWARD"<<endl;
- //else cout<<"W is REVERSED"<<endl;
-// bool FisF = (F.Orientation()==TopAbs_FORWARD);
-// if(!FisF) WisF = !WisF;
-// WisF = FisF;
- int i,j,geomFaceID = meshDS->ShapeToIndex( F );
+ int i,j,geomFaceID = meshDS->ShapeToIndex(F);
int nb = quad->side[0]->NbPoints();
int nr = quad->side[1]->NbPoints();
int dh = abs(nb-nt);
int dv = abs(nr-nl);
- if( dh>=dv ) {
- if( nt>nb ) {
+ if (dh>=dv) {
+ if (nt>nb) {
// it is a base case => not shift quad but me be replacement is need
ShiftQuad(quad,0,WisF);
}
}
}
else {
- if( nr>nl ) {
+ if (nr>nl) {
// we have to shift quad on 1
ShiftQuad(quad,1,WisF);
}
// 0------------0
// 0 bottom 1
- if(dh>dv) {
+ if (dh>dv) {
addv = (dh-dv)/2;
nbv = nbv + addv;
}
nbh = nbh + addh;
}
- const vector<UVPtStruct>& uv_eb = quad->side[0]->GetUVPtStruct(true,0 );
+ const vector<UVPtStruct>& uv_eb = quad->side[0]->GetUVPtStruct(true,0);
const vector<UVPtStruct>& uv_er = quad->side[1]->GetUVPtStruct(false,1);
- const vector<UVPtStruct>& uv_et = quad->side[2]->GetUVPtStruct(true,1 );
+ const vector<UVPtStruct>& uv_et = quad->side[2]->GetUVPtStruct(true,1);
const vector<UVPtStruct>& uv_el = quad->side[3]->GetUVPtStruct(false,0);
- if ( uv_eb.size() != nb || uv_er.size() != nr || uv_et.size() != nt || uv_el.size() != nl )
- return error( COMPERR_BAD_INPUT_MESH );
+ if (uv_eb.size() != nb || uv_er.size() != nr || uv_et.size() != nt || uv_el.size() != nl)
+ return error(COMPERR_BAD_INPUT_MESH);
// arrays for normalized params
//cout<<"Dump B:"<<endl;
TColStd_SequenceOfReal npb, npr, npt, npl;
- for(i=0; i<nb; i++) {
+ for (i=0; i<nb; i++) {
npb.Append(uv_eb[i].normParam);
//cout<<"i="<<i<<" par="<<uv_eb[i].normParam<<" npar="<<uv_eb[i].normParam;
//const SMDS_MeshNode* N = uv_eb[i].node;
//cout<<" node("<<N->X()<<","<<N->Y()<<","<<N->Z()<<")"<<endl;
}
- for(i=0; i<nr; i++) {
+ for (i=0; i<nr; i++) {
npr.Append(uv_er[i].normParam);
}
- for(i=0; i<nt; i++) {
+ for (i=0; i<nt; i++) {
npt.Append(uv_et[i].normParam);
}
- for(i=0; i<nl; i++) {
+ for (i=0; i<nl; i++) {
npl.Append(uv_el[i].normParam);
}
int dl,dr;
- if(OldVersion) {
+ if (OldVersion) {
// add some params to right and left after the first param
// insert to right
dr = nbv - nr;
double dpr = (npr.Value(2) - npr.Value(1))/(dr+1);
- for(i=1; i<=dr; i++) {
+ for (i=1; i<=dr; i++) {
npr.InsertAfter(1,npr.Value(2)-dpr);
}
// insert to left
dl = nbv - nl;
dpr = (npl.Value(2) - npl.Value(1))/(dl+1);
- for(i=1; i<=dl; i++) {
+ for (i=1; i<=dl; i++) {
npl.InsertAfter(1,npl.Value(2)-dpr);
}
}
//cout<<"npb:";
- //for(i=1; i<=npb.Length(); i++) {
+ //for (i=1; i<=npb.Length(); i++) {
// cout<<" "<<npb.Value(i);
//}
//cout<<endl;
- gp_XY a0( uv_eb.front().u, uv_eb.front().v );
- gp_XY a1( uv_eb.back().u, uv_eb.back().v );
- gp_XY a2( uv_et.back().u, uv_et.back().v );
- gp_XY a3( uv_et.front().u, uv_et.front().v );
+ gp_XY a0(uv_eb.front().u, uv_eb.front().v);
+ gp_XY a1(uv_eb.back().u, uv_eb.back().v);
+ gp_XY a2(uv_et.back().u, uv_et.back().v);
+ gp_XY a3(uv_et.front().u, uv_et.front().v);
//cout<<" a0("<<a0.X()<<","<<a0.Y()<<")"<<" a1("<<a1.X()<<","<<a1.Y()<<")"
// <<" a2("<<a2.X()<<","<<a2.Y()<<")"<<" a3("<<a3.X()<<","<<a3.Y()<<")"<<endl;
int nnn = Min(nr,nl);
// auxilary sequence of XY for creation nodes
// in the bottom part of central domain
- // it's length must be == nbv-nnn-1
- TColgp_SequenceOfXY UVL;
- TColgp_SequenceOfXY UVR;
+ // Length of UVL and UVR must be == nbv-nnn
+ TColgp_SequenceOfXY UVL, UVR, UVT;
- if(OldVersion) {
+ if (OldVersion) {
// step1: create faces for left domain
StdMeshers_Array2OfNode NodesL(1,dl+1,1,nl);
// add left nodes
- for(j=1; j<=nl; j++)
+ for (j=1; j<=nl; j++)
NodesL.SetValue(1,j,uv_el[j-1].node);
- if(dl>0) {
+ if (dl>0) {
// add top nodes
- for(i=1; i<=dl; i++)
+ for (i=1; i<=dl; i++)
NodesL.SetValue(i+1,nl,uv_et[i].node);
// create and add needed nodes
TColgp_SequenceOfXY UVtmp;
- for(i=1; i<=dl; i++) {
+ for (i=1; i<=dl; i++) {
double x0 = npt.Value(i+1);
double x1 = x0;
// diagonal node
SMDS_MeshNode * N = meshDS->AddNode(P.X(), P.Y(), P.Z());
meshDS->SetNodeOnFace(N, geomFaceID, UV.X(), UV.Y());
NodesL.SetValue(i+1,1,N);
- if(UVL.Length()<nbv-nnn-1) UVL.Append(UV);
+ if (UVL.Length()<nbv-nnn) UVL.Append(UV);
// internal nodes
- for(j=2; j<nl; j++) {
+ for (j=2; j<nl; j++) {
double y0 = npl.Value(dl+j);
double y1 = npr.Value(dl+j);
gp_UV UV = CalcUV(x0, x1, y0, y1, quad, a0, a1, a2, a3);
SMDS_MeshNode* N = meshDS->AddNode(P.X(), P.Y(), P.Z());
meshDS->SetNodeOnFace(N, geomFaceID, UV.X(), UV.Y());
NodesL.SetValue(i+1,j,N);
- if( i==dl ) UVtmp.Append(UV);
+ if (i==dl) UVtmp.Append(UV);
}
}
- for(i=1; i<=UVtmp.Length() && UVL.Length()<nbv-nnn-1; i++) {
+ for (i=1; i<=UVtmp.Length() && UVL.Length()<nbv-nnn; i++) {
UVL.Append(UVtmp.Value(i));
}
//cout<<"Dump NodesL:"<<endl;
- //for(i=1; i<=dl+1; i++) {
+ //for (i=1; i<=dl+1; i++) {
// cout<<"i="<<i;
- // for(j=1; j<=nl; j++) {
+ // for (j=1; j<=nl; j++) {
// cout<<" ("<<NodesL.Value(i,j)->X()<<","<<NodesL.Value(i,j)->Y()<<","<<NodesL.Value(i,j)->Z()<<")";
// }
// cout<<endl;
//}
// create faces
- for(i=1; i<=dl; i++) {
- for(j=1; j<nl; j++) {
- if(WisF) {
+ for (i=1; i<=dl; i++) {
+ for (j=1; j<nl; j++) {
+ if (WisF) {
SMDS_MeshFace* F =
myTool->AddFace(NodesL.Value(i,j), NodesL.Value(i+1,j),
NodesL.Value(i+1,j+1), NodesL.Value(i,j+1));
- if(F) meshDS->SetMeshElementOnShape(F, geomFaceID);
+ if (F) meshDS->SetMeshElementOnShape(F, geomFaceID);
}
else {
SMDS_MeshFace* F =
myTool->AddFace(NodesL.Value(i,j), NodesL.Value(i,j+1),
NodesL.Value(i+1,j+1), NodesL.Value(i+1,j));
- if(F) meshDS->SetMeshElementOnShape(F, geomFaceID);
+ if (F) meshDS->SetMeshElementOnShape(F, geomFaceID);
}
}
}
}
else {
// fill UVL using c2d
- for(i=1; i<npl.Length() && UVL.Length()<nbv-nnn-1; i++) {
- UVL.Append( gp_UV ( uv_el[i].u, uv_el[i].v ));
+ for (i=1; i<npl.Length() && UVL.Length()<nbv-nnn; i++) {
+ UVL.Append(gp_UV (uv_el[i].u, uv_el[i].v));
}
}
// step2: create faces for right domain
StdMeshers_Array2OfNode NodesR(1,dr+1,1,nr);
// add right nodes
- for(j=1; j<=nr; j++)
+ for (j=1; j<=nr; j++)
NodesR.SetValue(1,j,uv_er[nr-j].node);
- if(dr>0) {
+ if (dr>0) {
// add top nodes
- for(i=1; i<=dr; i++)
+ for (i=1; i<=dr; i++)
NodesR.SetValue(i+1,1,uv_et[nt-1-i].node);
// create and add needed nodes
TColgp_SequenceOfXY UVtmp;
- for(i=1; i<=dr; i++) {
+ for (i=1; i<=dr; i++) {
double x0 = npt.Value(nt-i);
double x1 = x0;
// diagonal node
SMDS_MeshNode * N = meshDS->AddNode(P.X(), P.Y(), P.Z());
meshDS->SetNodeOnFace(N, geomFaceID, UV.X(), UV.Y());
NodesR.SetValue(i+1,nr,N);
- if(UVR.Length()<nbv-nnn-1) UVR.Append(UV);
+ if (UVR.Length()<nbv-nnn) UVR.Append(UV);
// internal nodes
- for(j=2; j<nr; j++) {
+ for (j=2; j<nr; j++) {
double y0 = npl.Value(nbv-j+1);
double y1 = npr.Value(nbv-j+1);
gp_UV UV = CalcUV(x0, x1, y0, y1, quad, a0, a1, a2, a3);
SMDS_MeshNode* N = meshDS->AddNode(P.X(), P.Y(), P.Z());
meshDS->SetNodeOnFace(N, geomFaceID, UV.X(), UV.Y());
NodesR.SetValue(i+1,j,N);
- if( i==dr ) UVtmp.Prepend(UV);
+ if (i==dr) UVtmp.Prepend(UV);
}
}
- for(i=1; i<=UVtmp.Length() && UVR.Length()<nbv-nnn-1; i++) {
+ for (i=1; i<=UVtmp.Length() && UVR.Length()<nbv-nnn; i++) {
UVR.Append(UVtmp.Value(i));
}
// create faces
- for(i=1; i<=dr; i++) {
- for(j=1; j<nr; j++) {
- if(WisF) {
+ for (i=1; i<=dr; i++) {
+ for (j=1; j<nr; j++) {
+ if (WisF) {
SMDS_MeshFace* F =
myTool->AddFace(NodesR.Value(i,j), NodesR.Value(i+1,j),
NodesR.Value(i+1,j+1), NodesR.Value(i,j+1));
- if(F) meshDS->SetMeshElementOnShape(F, geomFaceID);
+ if (F) meshDS->SetMeshElementOnShape(F, geomFaceID);
}
else {
SMDS_MeshFace* F =
myTool->AddFace(NodesR.Value(i,j), NodesR.Value(i,j+1),
NodesR.Value(i+1,j+1), NodesR.Value(i+1,j));
- if(F) meshDS->SetMeshElementOnShape(F, geomFaceID);
+ if (F) meshDS->SetMeshElementOnShape(F, geomFaceID);
}
}
}
}
else {
// fill UVR using c2d
- for(i=1; i<npr.Length() && UVR.Length()<nbv-nnn-1; i++) {
- UVR.Append( gp_UV( uv_er[i].u, uv_er[i].v ));
+ for (i=1; i<npr.Length() && UVR.Length()<nbv-nnn; i++) {
+ UVR.Append(gp_UV(uv_er[i].u, uv_er[i].v));
}
}
// step3: create faces for central domain
StdMeshers_Array2OfNode NodesC(1,nb,1,nbv);
- // add first string using NodesL
- for(i=1; i<=dl+1; i++)
+ // add first line using NodesL
+ for (i=1; i<=dl+1; i++)
NodesC.SetValue(1,i,NodesL(i,1));
- for(i=2; i<=nl; i++)
+ for (i=2; i<=nl; i++)
NodesC.SetValue(1,dl+i,NodesL(dl+1,i));
- // add last string using NodesR
- for(i=1; i<=dr+1; i++)
+ // add last line using NodesR
+ for (i=1; i<=dr+1; i++)
NodesC.SetValue(nb,i,NodesR(i,nr));
- for(i=1; i<nr; i++)
+ for (i=1; i<nr; i++)
NodesC.SetValue(nb,dr+i+1,NodesR(dr+1,nr-i));
// add top nodes (last columns)
- for(i=dl+2; i<nbh-dr; i++)
+ for (i=dl+2; i<nbh-dr; i++)
NodesC.SetValue(i-dl,nbv,uv_et[i-1].node);
// add bottom nodes (first columns)
- for(i=2; i<nb; i++)
+ for (i=2; i<nb; i++)
NodesC.SetValue(i,1,uv_eb[i-1].node);
// create and add needed nodes
// add linear layers
- for(i=2; i<nb; i++) {
+ for (i=2; i<nb; i++) {
double x0 = npt.Value(dl+i);
double x1 = x0;
- for(j=1; j<nnn; j++) {
+ for (j=1; j<nnn; j++) {
double y0 = npl.Value(nbv-nnn+j);
double y1 = npr.Value(nbv-nnn+j);
gp_UV UV = CalcUV(x0, x1, y0, y1, quad, a0, a1, a2, a3);
SMDS_MeshNode* N = meshDS->AddNode(P.X(), P.Y(), P.Z());
meshDS->SetNodeOnFace(N, geomFaceID, UV.X(), UV.Y());
NodesC.SetValue(i,nbv-nnn+j,N);
+ if ( j==1 )
+ UVT.Append( UV );
}
}
// add diagonal layers
//cout<<"UVL.Length()="<<UVL.Length()<<" UVR.Length()="<<UVR.Length()<<endl;
//cout<<"Dump UVL:"<<endl;
- //for(i=1; i<=UVL.Length(); i++) {
+ //for (i=1; i<=UVL.Length(); i++) {
// cout<<" ("<<UVL.Value(i).X()<<","<<UVL.Value(i).Y()<<")";
//}
//cout<<endl;
- for(i=1; i<nbv-nnn; i++) {
- double du = UVR.Value(i).X() - UVL.Value(i).X();
- double dv = UVR.Value(i).Y() - UVL.Value(i).Y();
- for(j=2; j<nb; j++) {
- double u = UVL.Value(i).X() + du*npb.Value(j);
- double v = UVL.Value(i).Y() + dv*npb.Value(j);
- gp_Pnt P = S->Value(u,v);
+ gp_UV A2 = UVR.Value(nbv-nnn);
+ gp_UV A3 = UVL.Value(nbv-nnn);
+ for (i=1; i<nbv-nnn; i++) {
+ gp_UV p1 = UVR.Value(i);
+ gp_UV p3 = UVL.Value(i);
+ double y = i / double(nbv-nnn);
+ for (j=2; j<nb; j++) {
+ double x = npb.Value(j);
+ gp_UV p0( uv_eb[j-1].u, uv_eb[j-1].v );
+ gp_UV p2 = UVT.Value( j-1 );
+ gp_UV UV = CalcUV(x, y, a0, a1, A2, A3, p0,p1,p2,p3 );
+ gp_Pnt P = S->Value(UV.X(),UV.Y());
SMDS_MeshNode* N = meshDS->AddNode(P.X(), P.Y(), P.Z());
- meshDS->SetNodeOnFace(N, geomFaceID, u, v);
+ meshDS->SetNodeOnFace(N, geomFaceID, UV.X(),UV.Y());
NodesC.SetValue(j,i+1,N);
}
}
// create faces
- for(i=1; i<nb; i++) {
- for(j=1; j<nbv; j++) {
- if(WisF) {
+ for (i=1; i<nb; i++) {
+ for (j=1; j<nbv; j++) {
+ if (WisF) {
SMDS_MeshFace* F =
myTool->AddFace(NodesC.Value(i,j), NodesC.Value(i+1,j),
NodesC.Value(i+1,j+1), NodesC.Value(i,j+1));
- if(F) meshDS->SetMeshElementOnShape(F, geomFaceID);
+ if (F) meshDS->SetMeshElementOnShape(F, geomFaceID);
}
else {
SMDS_MeshFace* F =
myTool->AddFace(NodesC.Value(i,j), NodesC.Value(i,j+1),
NodesC.Value(i+1,j+1), NodesC.Value(i+1,j));
- if(F) meshDS->SetMeshElementOnShape(F, geomFaceID);
+ if (F) meshDS->SetMeshElementOnShape(F, geomFaceID);
}
}
}
// step1: create faces for bottom rectangle domain
StdMeshers_Array2OfNode NodesBRD(1,nb,1,nnn-1);
// fill UVL and UVR using c2d
- for(j=0; j<nb; j++) {
+ for (j=0; j<nb; j++) {
NodesBRD.SetValue(j+1,1,uv_eb[j].node);
}
- for(i=1; i<nnn-1; i++) {
+ for (i=1; i<nnn-1; i++) {
NodesBRD.SetValue(1,i+1,uv_el[i].node);
NodesBRD.SetValue(nb,i+1,uv_er[i].node);
- double du = uv_er[i].u - uv_el[i].u;
- double dv = uv_er[i].v - uv_el[i].v;
- for(j=2; j<nb; j++) {
- double u = uv_el[i].u + du*npb.Value(j);
- double v = uv_el[i].v + dv*npb.Value(j);
- gp_Pnt P = S->Value(u,v);
+ for (j=2; j<nb; j++) {
+ double x = npb.Value(j);
+ double y = (1-x) * npl.Value(i+1) + x * npr.Value(i+1);
+ gp_UV UV = CalcUV2(x, y, quad, a0, a1, a2, a3);
+ gp_Pnt P = S->Value(UV.X(),UV.Y());
SMDS_MeshNode* N = meshDS->AddNode(P.X(), P.Y(), P.Z());
- meshDS->SetNodeOnFace(N, geomFaceID, u, v);
+ meshDS->SetNodeOnFace(N, geomFaceID, UV.X(),UV.Y());
NodesBRD.SetValue(j,i+1,N);
-
}
}
- int nbf=0;
- for(j=1; j<nnn-1; j++) {
- for(i=1; i<nb; i++) {
- nbf++;
- if(WisF) {
+ for (j=1; j<nnn-1; j++) {
+ for (i=1; i<nb; i++) {
+ if (WisF) {
SMDS_MeshFace* F =
myTool->AddFace(NodesBRD.Value(i,j), NodesBRD.Value(i+1,j),
NodesBRD.Value(i+1,j+1), NodesBRD.Value(i,j+1));
- if(F) meshDS->SetMeshElementOnShape(F, geomFaceID);
+ if (F) meshDS->SetMeshElementOnShape(F, geomFaceID);
}
else {
SMDS_MeshFace* F =
myTool->AddFace(NodesBRD.Value(i,j), NodesBRD.Value(i,j+1),
NodesBRD.Value(i+1,j+1), NodesBRD.Value(i+1,j));
- if(F) meshDS->SetMeshElementOnShape(F, geomFaceID);
+ if (F) meshDS->SetMeshElementOnShape(F, geomFaceID);
}
}
}
// create faces for region C
StdMeshers_Array2OfNode NodesC(1,nb,1,drl+1+addv);
// add nodes from previous region
- for(j=1; j<=nb; j++) {
+ for (j=1; j<=nb; j++) {
NodesC.SetValue(j,1,NodesBRD.Value(j,nnn-1));
}
- if( (drl+addv) > 0 ) {
+ if ((drl+addv) > 0) {
int n1,n2;
- if(nr>nl) {
+ if (nr>nl) {
n1 = 1;
n2 = drl + 1;
TColgp_SequenceOfXY UVtmp;
double drparam = npr.Value(nr) - npr.Value(nnn-1);
double dlparam = npl.Value(nnn) - npl.Value(nnn-1);
double y0,y1;
- for(i=1; i<=drl; i++) {
+ for (i=1; i<=drl; i++) {
// add existed nodes from right edge
NodesC.SetValue(nb,i+1,uv_er[nnn+i-2].node);
//double dtparam = npt.Value(i+1);
double dpar = (y1 - npr.Value(nnn-1))/drparam;
y0 = npl.Value(nnn-1) + dpar*dlparam; // param on left edge
double dy = y1 - y0;
- for(j=1; j<nb; j++) {
+ for (j=1; j<nb; j++) {
double x = npt.Value(i+1) + npb.Value(j)*(1-npt.Value(i+1));
double y = y0 + dy*x;
gp_UV UV = CalcUV2(x, y, quad, a0, a1, a2, a3);
}
double dy0 = (1-y0)/(addv+1);
double dy1 = (1-y1)/(addv+1);
- for(i=1; i<=addv; i++) {
+ for (i=1; i<=addv; i++) {
double yy0 = y0 + dy0*i;
double yy1 = y1 + dy1*i;
double dyy = yy1 - yy0;
- for(j=1; j<=nb; j++) {
+ for (j=1; j<=nb; j++) {
double x = npt.Value(i+1+drl) +
- npb.Value(j) * ( npt.Value(nt-i) - npt.Value(i+1+drl) );
+ npb.Value(j) * (npt.Value(nt-i) - npt.Value(i+1+drl));
double y = yy0 + dyy*x;
gp_UV UV = CalcUV2(x, y, quad, a0, a1, a2, a3);
gp_Pnt P = S->Value(UV.X(),UV.Y());
double drparam = npr.Value(nnn) - npr.Value(nnn-1);
double y0 = npl.Value(nnn-1);
double y1 = npr.Value(nnn-1);
- for(i=1; i<=drl; i++) {
+ for (i=1; i<=drl; i++) {
// add existed nodes from right edge
NodesC.SetValue(1,i+1,uv_el[nnn+i-2].node);
y0 = npl.Value(nnn+i-1); // param on left edge
double dpar = (y0 - npl.Value(nnn-1))/dlparam;
y1 = npr.Value(nnn-1) + dpar*drparam; // param on right edge
double dy = y1 - y0;
- for(j=2; j<=nb; j++) {
+ for (j=2; j<=nb; j++) {
double x = npb.Value(j)*npt.Value(nt-i);
double y = y0 + dy*x;
gp_UV UV = CalcUV2(x, y, quad, a0, a1, a2, a3);
}
double dy0 = (1-y0)/(addv+1);
double dy1 = (1-y1)/(addv+1);
- for(i=1; i<=addv; i++) {
+ for (i=1; i<=addv; i++) {
double yy0 = y0 + dy0*i;
double yy1 = y1 + dy1*i;
double dyy = yy1 - yy0;
- for(j=1; j<=nb; j++) {
+ for (j=1; j<=nb; j++) {
double x = npt.Value(i+1) +
- npb.Value(j) * ( npt.Value(nt-i-drl) - npt.Value(i+1) );
+ npb.Value(j) * (npt.Value(nt-i-drl) - npt.Value(i+1));
double y = yy0 + dyy*x;
gp_UV UV = CalcUV2(x, y, quad, a0, a1, a2, a3);
gp_Pnt P = S->Value(UV.X(),UV.Y());
}
}
// create faces
- for(j=1; j<=drl+addv; j++) {
- for(i=1; i<nb; i++) {
- nbf++;
- if(WisF) {
+ for (j=1; j<=drl+addv; j++) {
+ for (i=1; i<nb; i++) {
+ if (WisF) {
SMDS_MeshFace* F =
myTool->AddFace(NodesC.Value(i,j), NodesC.Value(i+1,j),
NodesC.Value(i+1,j+1), NodesC.Value(i,j+1));
- if(F) meshDS->SetMeshElementOnShape(F, geomFaceID);
+ if (F) meshDS->SetMeshElementOnShape(F, geomFaceID);
}
else {
SMDS_MeshFace* F =
myTool->AddFace(NodesC.Value(i,j), NodesC.Value(i,j+1),
NodesC.Value(i+1,j+1), NodesC.Value(i+1,j));
- if(F) meshDS->SetMeshElementOnShape(F, geomFaceID);
+ if (F) meshDS->SetMeshElementOnShape(F, geomFaceID);
}
}
} // end nr<nl
StdMeshers_Array2OfNode NodesLast(1,nt,1,2);
- for(i=1; i<=nt; i++) {
+ for (i=1; i<=nt; i++) {
NodesLast.SetValue(i,2,uv_et[i-1].node);
}
int nnn=0;
- for(i=n1; i<drl+addv+1; i++) {
+ for (i=n1; i<drl+addv+1; i++) {
nnn++;
NodesLast.SetValue(nnn,1,NodesC.Value(1,i));
}
- for(i=1; i<=nb; i++) {
+ for (i=1; i<=nb; i++) {
nnn++;
NodesLast.SetValue(nnn,1,NodesC.Value(i,drl+addv+1));
}
- for(i=drl+addv; i>=n2; i--) {
+ for (i=drl+addv; i>=n2; i--) {
nnn++;
NodesLast.SetValue(nnn,1,NodesC.Value(nb,i));
}
- for(i=1; i<nt; i++) {
- nbf++;
- if(WisF) {
+ for (i=1; i<nt; i++) {
+ if (WisF) {
SMDS_MeshFace* F =
myTool->AddFace(NodesLast.Value(i,1), NodesLast.Value(i+1,1),
NodesLast.Value(i+1,2), NodesLast.Value(i,2));
- if(F) meshDS->SetMeshElementOnShape(F, geomFaceID);
+ if (F) meshDS->SetMeshElementOnShape(F, geomFaceID);
}
else {
SMDS_MeshFace* F =
myTool->AddFace(NodesLast.Value(i,1), NodesLast.Value(i,2),
NodesLast.Value(i+1,2), NodesLast.Value(i+1,2));
- if(F) meshDS->SetMeshElementOnShape(F, geomFaceID);
+ if (F) meshDS->SetMeshElementOnShape(F, geomFaceID);
}
}
- } // if( (drl+addv) > 0 )
+ } // if ((drl+addv) > 0)
} // end new version implementation
// of meshing after implementation new variant
// for bug 0016220 from Mantis.
bool OldVersion = false;
+ if (myQuadType == QUAD_QUADRANGLE_PREF_REVERSED)
+ OldVersion = true;
const TopoDS_Face& F = TopoDS::Face(aShape);
Handle(Geom_Surface) S = BRep_Tool::Surface(F);
int dh = abs(nb-nt);
int dv = abs(nr-nl);
- if( dh>=dv ) {
- if( nt>nb ) {
+ if (dh>=dv) {
+ if (nt>nb) {
// it is a base case => not shift
}
else {
}
}
else {
- if( nr>nl ) {
+ if (nr>nl) {
// we have to shift quad on 1
nb = aNbNodes[3];
nr = aNbNodes[0];
int addh = 0;
int addv = 0;
- if(dh>dv) {
+ if (dh>dv) {
addv = (dh-dv)/2;
nbv = nbv + addv;
}
}
int dl,dr;
- if(OldVersion) {
+ if (OldVersion) {
// add some params to right and left after the first param
// insert to right
dr = nbv - nr;
int nbNodes = 0;
int nbFaces = 0;
- if(OldVersion) {
+ if (OldVersion) {
// step1: create faces for left domain
- if(dl>0) {
+ if (dl>0) {
nbNodes += dl*(nl-1);
nbFaces += dl*(nl-1);
}
// step2: create faces for right domain
- if(dr>0) {
+ if (dr>0) {
nbNodes += dr*(nr-1);
nbFaces += dr*(nr-1);
}
} // end new version implementation
std::vector<int> aVec(SMDSEntity_Last);
- for(int i=SMDSEntity_Node; i<SMDSEntity_Last; i++) aVec[i] = 0;
- if(IsQuadratic) {
+ for (int i=SMDSEntity_Node; i<SMDSEntity_Last; i++) aVec[i] = 0;
+ if (IsQuadratic) {
aVec[SMDSEntity_Quad_Quadrangle] = nbFaces;
aVec[SMDSEntity_Node] = nbNodes + nbFaces*4;
- if( aNbNodes.size()==5 ) {
+ if (aNbNodes.size()==5) {
aVec[SMDSEntity_Quad_Triangle] = aNbNodes[3] - 1;
aVec[SMDSEntity_Quad_Quadrangle] = nbFaces - aNbNodes[3] + 1;
}
else {
aVec[SMDSEntity_Node] = nbNodes;
aVec[SMDSEntity_Quadrangle] = nbFaces;
- if( aNbNodes.size()==5 ) {
+ if (aNbNodes.size()==5) {
aVec[SMDSEntity_Triangle] = aNbNodes[3] - 1;
aVec[SMDSEntity_Quadrangle] = nbFaces - aNbNodes[3] + 1;
}
gp_Pnt c(theNode3->X(),theNode3->Y(),theNode3->Z());
gp_Pnt d(theNode4->X(),theNode4->Y(),theNode4->Z());
SMDS_MeshFace* face;
- if(a.Distance(c) > b.Distance(d)){
+ if (a.Distance(c) > b.Distance(d)){
face = myTool->AddFace(theNode2, theNode4 , theNode1);
- if(face) theMeshDS->SetMeshElementOnShape(face, theFaceID );
+ if (face) theMeshDS->SetMeshElementOnShape(face, theFaceID);
face = myTool->AddFace(theNode2, theNode3, theNode4);
- if(face) theMeshDS->SetMeshElementOnShape(face, theFaceID );
+ if (face) theMeshDS->SetMeshElementOnShape(face, theFaceID);
}
else{
face = myTool->AddFace(theNode1, theNode2 ,theNode3);
- if(face) theMeshDS->SetMeshElementOnShape(face, theFaceID );
+ if (face) theMeshDS->SetMeshElementOnShape(face, theFaceID);
face = myTool->AddFace(theNode1, theNode3, theNode4);
- if(face) theMeshDS->SetMeshElementOnShape(face, theFaceID );
+ if (face) theMeshDS->SetMeshElementOnShape(face, theFaceID);
}
}
+//=======================================================================
+/*!
+ * Implementation of Reduced algorithm (meshing with quadrangles only)
+ */
+//=======================================================================
+bool StdMeshers_Quadrangle_2D::ComputeReduced (SMESH_Mesh & aMesh,
+ const TopoDS_Shape& aShape,
+ FaceQuadStruct* quad)
+{
+ SMESHDS_Mesh * meshDS = aMesh.GetMeshDS();
+ const TopoDS_Face& F = TopoDS::Face(aShape);
+ Handle(Geom_Surface) S = BRep_Tool::Surface(F);
+ int i,j,geomFaceID = meshDS->ShapeToIndex(F);
+
+ int nb = quad->side[0]->NbPoints();
+ int nr = quad->side[1]->NbPoints();
+ int nt = quad->side[2]->NbPoints();
+ int nl = quad->side[3]->NbPoints();
+
+ // Simple Reduce 8->6->4->2 (3 steps) Multiple Reduce 8->2 (1 step)
+ //
+ // .-----.-----.-----.-----. .-----.-----.-----.-----.
+ // | / \ | / \ | | / \ | / \ |
+ // | / .--.--. \ | | / \ | / \ |
+ // | / / | \ \ | | / .----.----. \ |
+ // .---.---.---.---.---.---. | / / \ | / \ \ |
+ // | / / \ | / \ \ | | / / \ | / \ \ |
+ // | / / .-.-. \ \ | | / / .---.---. \ \ |
+ // | / / / | \ \ \ | | / / / \ | / \ \ \ |
+ // .--.--.--.--.--.--.--.--. | / / / \ | / \ \ \ |
+ // | / / / \ | / \ \ \ | | / / / .-.-. \ \ \ |
+ // | / / / .-.-. \ \ \ | | / / / / | \ \ \ \ |
+ // | / / / / | \ \ \ \ | | / / / / | \ \ \ \ |
+ // .-.-.-.--.--.--.--.-.-.-. .-.-.-.--.--.--.--.-.-.-.
+
+ bool MultipleReduce = false;
+ {
+ int nb1 = nb;
+ int nr1 = nr;
+ int nt1 = nt;
+ int nl1 = nl;
+
+ if (nr == nl) {
+ if (nb < nt) {
+ nt1 = nb;
+ nb1 = nt;
+ }
+ }
+ else if (nb == nt) {
+ nl1 = nb; // and == nt
+ nr1 = nb; // and == nt
+ if (nl < nr) {
+ nt1 = nl;
+ nb1 = nr;
+ }
+ else {
+ nt1 = nr;
+ nb1 = nl;
+ }
+ }
+ else {
+ return false;
+ }
+
+ // number of rows and columns
+ int nrows = nr1 - 1; // and also == nl1 - 1
+ int ncol_top = nt1 - 1;
+ int ncol_bot = nb1 - 1;
+ int npair_top = ncol_top / 2;
+ // maximum number of bottom elements for "linear" simple reduce
+ //int max_lin = ncol_top + npair_top * 2 * nrows;
+ // maximum number of bottom elements for "tree" simple reduce
+ int max_tree = npair_top * pow(2.0, nrows + 1);
+ if (ncol_top > npair_top * 2) {
+ int delta = ncol_bot - max_tree;
+ for (int irow = 1; irow < nrows; irow++) {
+ int nfour = delta / 4;
+ delta -= nfour*2;
+ }
+ if (delta <= (ncol_top - npair_top * 2))
+ max_tree = ncol_bot;
+ }
+
+ if (ncol_bot > max_tree)
+ MultipleReduce = true;
+ }
+
+ if (MultipleReduce) { // == ComputeQuadPref QUAD_QUADRANGLE_PREF_REVERSED
+ //==================================================
+ int dh = abs(nb-nt);
+ int dv = abs(nr-nl);
+ if (dh >= dv) {
+ if (nt > nb) {
+ // it is a base case => not shift quad but may be replacement is need
+ ShiftQuad(quad,0,true);
+ }
+ else {
+ // we have to shift quad on 2
+ ShiftQuad(quad,2,true);
+ }
+ }
+ else {
+ if (nr > nl) {
+ // we have to shift quad on 1
+ ShiftQuad(quad,1,true);
+ }
+ else {
+ // we have to shift quad on 3
+ ShiftQuad(quad,3,true);
+ }
+ }
+
+ nb = quad->side[0]->NbPoints();
+ nr = quad->side[1]->NbPoints();
+ nt = quad->side[2]->NbPoints();
+ nl = quad->side[3]->NbPoints();
+ dh = abs(nb-nt);
+ dv = abs(nr-nl);
+ int nbh = Max(nb,nt);
+ int nbv = Max(nr,nl);
+ int addh = 0;
+ int addv = 0;
+
+ if (dh>dv) {
+ addv = (dh-dv)/2;
+ nbv = nbv + addv;
+ }
+ else { // dv>=dh
+ addh = (dv-dh)/2;
+ nbh = nbh + addh;
+ }
+
+ const vector<UVPtStruct>& uv_eb = quad->side[0]->GetUVPtStruct(true,0);
+ const vector<UVPtStruct>& uv_er = quad->side[1]->GetUVPtStruct(false,1);
+ const vector<UVPtStruct>& uv_et = quad->side[2]->GetUVPtStruct(true,1);
+ const vector<UVPtStruct>& uv_el = quad->side[3]->GetUVPtStruct(false,0);
+
+ if (uv_eb.size() != nb || uv_er.size() != nr || uv_et.size() != nt || uv_el.size() != nl)
+ return error(COMPERR_BAD_INPUT_MESH);
+
+ // arrays for normalized params
+ TColStd_SequenceOfReal npb, npr, npt, npl;
+ for (j = 0; j < nb; j++) {
+ npb.Append(uv_eb[j].normParam);
+ }
+ for (i = 0; i < nr; i++) {
+ npr.Append(uv_er[i].normParam);
+ }
+ for (j = 0; j < nt; j++) {
+ npt.Append(uv_et[j].normParam);
+ }
+ for (i = 0; i < nl; i++) {
+ npl.Append(uv_el[i].normParam);
+ }
+
+ int dl,dr;
+ // orientation of face and 3 main domain for future faces
+ // 0 top 1
+ // 1------------1
+ // | | | |
+ // | | | |
+ // | L | | R |
+ // left | | | | rigth
+ // | / \ |
+ // | / C \ |
+ // |/ \|
+ // 0------------0
+ // 0 bottom 1
+
+ // add some params to right and left after the first param
+ // insert to right
+ dr = nbv - nr;
+ double dpr = (npr.Value(2) - npr.Value(1))/(dr+1);
+ for (i=1; i<=dr; i++) {
+ npr.InsertAfter(1,npr.Value(2)-dpr);
+ }
+ // insert to left
+ dl = nbv - nl;
+ dpr = (npl.Value(2) - npl.Value(1))/(dl+1);
+ for (i=1; i<=dl; i++) {
+ npl.InsertAfter(1,npl.Value(2)-dpr);
+ }
+
+ gp_XY a0 (uv_eb.front().u, uv_eb.front().v);
+ gp_XY a1 (uv_eb.back().u, uv_eb.back().v);
+ gp_XY a2 (uv_et.back().u, uv_et.back().v);
+ gp_XY a3 (uv_et.front().u, uv_et.front().v);
+
+ int nnn = Min(nr,nl);
+ // auxilary sequence of XY for creation nodes
+ // in the bottom part of central domain
+ // it's length must be == nbv-nnn-1
+ TColgp_SequenceOfXY UVL;
+ TColgp_SequenceOfXY UVR;
+ //==================================================
+
+ // step1: create faces for left domain
+ StdMeshers_Array2OfNode NodesL(1,dl+1,1,nl);
+ // add left nodes
+ for (j=1; j<=nl; j++)
+ NodesL.SetValue(1,j,uv_el[j-1].node);
+ if (dl>0) {
+ // add top nodes
+ for (i=1; i<=dl; i++)
+ NodesL.SetValue(i+1,nl,uv_et[i].node);
+ // create and add needed nodes
+ TColgp_SequenceOfXY UVtmp;
+ for (i=1; i<=dl; i++) {
+ double x0 = npt.Value(i+1);
+ double x1 = x0;
+ // diagonal node
+ double y0 = npl.Value(i+1);
+ double y1 = npr.Value(i+1);
+ gp_UV UV = CalcUV(x0, x1, y0, y1, quad, a0, a1, a2, a3);
+ gp_Pnt P = S->Value(UV.X(),UV.Y());
+ SMDS_MeshNode * N = meshDS->AddNode(P.X(), P.Y(), P.Z());
+ meshDS->SetNodeOnFace(N, geomFaceID, UV.X(), UV.Y());
+ NodesL.SetValue(i+1,1,N);
+ if (UVL.Length()<nbv-nnn-1) UVL.Append(UV);
+ // internal nodes
+ for (j=2; j<nl; j++) {
+ double y0 = npl.Value(dl+j);
+ double y1 = npr.Value(dl+j);
+ gp_UV UV = CalcUV(x0, x1, y0, y1, quad, a0, a1, a2, a3);
+ gp_Pnt P = S->Value(UV.X(),UV.Y());
+ SMDS_MeshNode* N = meshDS->AddNode(P.X(), P.Y(), P.Z());
+ meshDS->SetNodeOnFace(N, geomFaceID, UV.X(), UV.Y());
+ NodesL.SetValue(i+1,j,N);
+ if (i==dl) UVtmp.Append(UV);
+ }
+ }
+ for (i=1; i<=UVtmp.Length() && UVL.Length()<nbv-nnn-1; i++) {
+ UVL.Append(UVtmp.Value(i));
+ }
+ // create faces
+ for (i=1; i<=dl; i++) {
+ for (j=1; j<nl; j++) {
+ SMDS_MeshFace* F =
+ myTool->AddFace(NodesL.Value(i,j), NodesL.Value(i+1,j),
+ NodesL.Value(i+1,j+1), NodesL.Value(i,j+1));
+ if (F) meshDS->SetMeshElementOnShape(F, geomFaceID);
+ }
+ }
+ }
+ else {
+ // fill UVL using c2d
+ for (i=1; i<npl.Length() && UVL.Length()<nbv-nnn-1; i++) {
+ UVL.Append(gp_UV (uv_el[i].u, uv_el[i].v));
+ }
+ }
+
+ // step2: create faces for right domain
+ StdMeshers_Array2OfNode NodesR(1,dr+1,1,nr);
+ // add right nodes
+ for (j=1; j<=nr; j++)
+ NodesR.SetValue(1,j,uv_er[nr-j].node);
+ if (dr>0) {
+ // add top nodes
+ for (i=1; i<=dr; i++)
+ NodesR.SetValue(i+1,1,uv_et[nt-1-i].node);
+ // create and add needed nodes
+ TColgp_SequenceOfXY UVtmp;
+ for (i=1; i<=dr; i++) {
+ double x0 = npt.Value(nt-i);
+ double x1 = x0;
+ // diagonal node
+ double y0 = npl.Value(i+1);
+ double y1 = npr.Value(i+1);
+ gp_UV UV = CalcUV(x0, x1, y0, y1, quad, a0, a1, a2, a3);
+ gp_Pnt P = S->Value(UV.X(),UV.Y());
+ SMDS_MeshNode * N = meshDS->AddNode(P.X(), P.Y(), P.Z());
+ meshDS->SetNodeOnFace(N, geomFaceID, UV.X(), UV.Y());
+ NodesR.SetValue(i+1,nr,N);
+ if (UVR.Length()<nbv-nnn-1) UVR.Append(UV);
+ // internal nodes
+ for (j=2; j<nr; j++) {
+ double y0 = npl.Value(nbv-j+1);
+ double y1 = npr.Value(nbv-j+1);
+ gp_UV UV = CalcUV(x0, x1, y0, y1, quad, a0, a1, a2, a3);
+ gp_Pnt P = S->Value(UV.X(),UV.Y());
+ SMDS_MeshNode* N = meshDS->AddNode(P.X(), P.Y(), P.Z());
+ meshDS->SetNodeOnFace(N, geomFaceID, UV.X(), UV.Y());
+ NodesR.SetValue(i+1,j,N);
+ if (i==dr) UVtmp.Prepend(UV);
+ }
+ }
+ for (i=1; i<=UVtmp.Length() && UVR.Length()<nbv-nnn-1; i++) {
+ UVR.Append(UVtmp.Value(i));
+ }
+ // create faces
+ for (i=1; i<=dr; i++) {
+ for (j=1; j<nr; j++) {
+ SMDS_MeshFace* F =
+ myTool->AddFace(NodesR.Value(i,j), NodesR.Value(i+1,j),
+ NodesR.Value(i+1,j+1), NodesR.Value(i,j+1));
+ if (F) meshDS->SetMeshElementOnShape(F, geomFaceID);
+ }
+ }
+ }
+ else {
+ // fill UVR using c2d
+ for (i=1; i<npr.Length() && UVR.Length()<nbv-nnn-1; i++) {
+ UVR.Append(gp_UV(uv_er[i].u, uv_er[i].v));
+ }
+ }
+
+ // step3: create faces for central domain
+ StdMeshers_Array2OfNode NodesC(1,nb,1,nbv);
+ // add first line using NodesL
+ for (i=1; i<=dl+1; i++)
+ NodesC.SetValue(1,i,NodesL(i,1));
+ for (i=2; i<=nl; i++)
+ NodesC.SetValue(1,dl+i,NodesL(dl+1,i));
+ // add last line using NodesR
+ for (i=1; i<=dr+1; i++)
+ NodesC.SetValue(nb,i,NodesR(i,nr));
+ for (i=1; i<nr; i++)
+ NodesC.SetValue(nb,dr+i+1,NodesR(dr+1,nr-i));
+ // add top nodes (last columns)
+ for (i=dl+2; i<nbh-dr; i++)
+ NodesC.SetValue(i-dl,nbv,uv_et[i-1].node);
+ // add bottom nodes (first columns)
+ for (i=2; i<nb; i++)
+ NodesC.SetValue(i,1,uv_eb[i-1].node);
+
+ // create and add needed nodes
+ // add linear layers
+ for (i=2; i<nb; i++) {
+ double x0 = npt.Value(dl+i);
+ double x1 = x0;
+ for (j=1; j<nnn; j++) {
+ double y0 = npl.Value(nbv-nnn+j);
+ double y1 = npr.Value(nbv-nnn+j);
+ gp_UV UV = CalcUV(x0, x1, y0, y1, quad, a0, a1, a2, a3);
+ gp_Pnt P = S->Value(UV.X(),UV.Y());
+ SMDS_MeshNode* N = meshDS->AddNode(P.X(), P.Y(), P.Z());
+ meshDS->SetNodeOnFace(N, geomFaceID, UV.X(), UV.Y());
+ NodesC.SetValue(i,nbv-nnn+j,N);
+ }
+ }
+ // add diagonal layers
+ for (i=1; i<nbv-nnn; i++) {
+ double du = UVR.Value(i).X() - UVL.Value(i).X();
+ double dv = UVR.Value(i).Y() - UVL.Value(i).Y();
+ for (j=2; j<nb; j++) {
+ double u = UVL.Value(i).X() + du*npb.Value(j);
+ double v = UVL.Value(i).Y() + dv*npb.Value(j);
+ gp_Pnt P = S->Value(u,v);
+ SMDS_MeshNode* N = meshDS->AddNode(P.X(), P.Y(), P.Z());
+ meshDS->SetNodeOnFace(N, geomFaceID, u, v);
+ NodesC.SetValue(j,i+1,N);
+ }
+ }
+ // create faces
+ for (i=1; i<nb; i++) {
+ for (j=1; j<nbv; j++) {
+ SMDS_MeshFace* F =
+ myTool->AddFace(NodesC.Value(i,j), NodesC.Value(i+1,j),
+ NodesC.Value(i+1,j+1), NodesC.Value(i,j+1));
+ if (F) meshDS->SetMeshElementOnShape(F, geomFaceID);
+ }
+ }
+ // TODO ???
+ } // end Multiple Reduce implementation
+ else { // Simple Reduce (!MultipleReduce)
+ //=========================================================
+ if (nr == nl) {
+ if (nt < nb) {
+ // it is a base case => not shift quad
+ //ShiftQuad(quad,0,true);
+ }
+ else {
+ // we have to shift quad on 2
+ ShiftQuad(quad,2,true);
+ }
+ }
+ else {
+ if (nl > nr) {
+ // we have to shift quad on 1
+ ShiftQuad(quad,1,true);
+ }
+ else {
+ // we have to shift quad on 3
+ ShiftQuad(quad,3,true);
+ }
+ }
+
+ nb = quad->side[0]->NbPoints();
+ nr = quad->side[1]->NbPoints();
+ nt = quad->side[2]->NbPoints();
+ nl = quad->side[3]->NbPoints();
+
+ // number of rows and columns
+ int nrows = nr - 1; // and also == nl - 1
+ int ncol_top = nt - 1;
+ int ncol_bot = nb - 1;
+ int npair_top = ncol_top / 2;
+ // maximum number of bottom elements for "linear" simple reduce
+ int max_lin = ncol_top + npair_top * 2 * nrows;
+ // maximum number of bottom elements for "tree" simple reduce
+ //int max_tree = npair_top * pow(2, nrows + 1);
+
+ //if (ncol_bot > max_tree)
+ // MultipleReduce = true;
+
+ const vector<UVPtStruct>& uv_eb = quad->side[0]->GetUVPtStruct(true,0);
+ const vector<UVPtStruct>& uv_er = quad->side[1]->GetUVPtStruct(false,1);
+ const vector<UVPtStruct>& uv_et = quad->side[2]->GetUVPtStruct(true,1);
+ const vector<UVPtStruct>& uv_el = quad->side[3]->GetUVPtStruct(false,0);
+
+ if (uv_eb.size() != nb || uv_er.size() != nr || uv_et.size() != nt || uv_el.size() != nl)
+ return error(COMPERR_BAD_INPUT_MESH);
+
+ // arrays for normalized params
+ TColStd_SequenceOfReal npb, npr, npt, npl;
+ for (j = 0; j < nb; j++) {
+ npb.Append(uv_eb[j].normParam);
+ }
+ for (i = 0; i < nr; i++) {
+ npr.Append(uv_er[i].normParam);
+ }
+ for (j = 0; j < nt; j++) {
+ npt.Append(uv_et[j].normParam);
+ }
+ for (i = 0; i < nl; i++) {
+ npl.Append(uv_el[i].normParam);
+ }
+
+ // We will ajust new points to this grid
+ if (!SetNormalizedGrid(aMesh, aShape, quad))
+ return false;
+
+ // TODO ???
+ gp_XY a0 (uv_eb.front().u, uv_eb.front().v);
+ gp_XY a1 (uv_eb.back().u, uv_eb.back().v);
+ gp_XY a2 (uv_et.back().u, uv_et.back().v);
+ gp_XY a3 (uv_et.front().u, uv_et.front().v);
+ //=========================================================
+
+ TColStd_SequenceOfInteger curr_base, next_base;
+ TColStd_SequenceOfReal curr_par_u, curr_par_v;
+ TColStd_SequenceOfReal next_par_u, next_par_v;
+ StdMeshers_Array2OfNode NodesBRD (1,nb, 1,nr);
+ for (j = 1; j <= nb; j++) {
+ NodesBRD.SetValue(j, 1, uv_eb[j - 1].node); // bottom
+ curr_base.Append(j);
+ next_base.Append(-1);
+ curr_par_u.Append(uv_eb[j-1].u);
+ curr_par_v.Append(uv_eb[j-1].v);
+ next_par_u.Append(0.);
+ next_par_v.Append(0.);
+ }
+ for (j = 1; j <= nt; j++) {
+ NodesBRD.SetValue(j, nr, uv_et[j - 1].node); // top
+ }
+
+ int curr_base_len = nb;
+ int next_base_len = 0;
+
+ if (ncol_bot > max_lin) {
+ // "tree" simple reduce 2->4->8->16->32->...
+ //
+ // .---------------.---------------.---------------.---------------. nr
+ // | \ | / | \ | / |
+ // | \ .-------.-------. / | \ .-------.-------. / |
+ // | | | | | | | | |
+ // .-------.-------.-------.-------.-------.-------.-------.-------.
+ // |\ | /|\ | /|\ | /|\ | /|
+ // | \.---.---./ | \.---.---./ | \.---.---./ | \.---.---./ | i
+ // | | | | | | | | | | | | | | | | |
+ // .---.---.---.---.---.---.---.---.---.---.---.---.---.---.---.---.
+ // |\ | /|\ | /|\ | /|\ | /|\ | /|\ | /|\ | /|\ | /|
+ // | .-.-. | .-.-. | .-.-. | .-.-. | .-.-. | .-.-. | .-.-. | .-.-. |
+ // | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
+ // .-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-. 1
+ // 1 j nb
+
+ for (i = 1; i < nr; i++) { // layer by layer
+ // left
+ NodesBRD.SetValue(1, i+1, uv_el[i].node);
+ next_base.SetValue(++next_base_len, 1);
+ // right
+ NodesBRD.SetValue(nb, i+1, uv_er[i].node);
+
+ next_par_u.SetValue(next_base_len, uv_el[i].u);
+ next_par_v.SetValue(next_base_len, uv_el[i].v);
+
+ // to stop reducing, if number of nodes reaches nt
+ int delta = curr_base_len - nt;
+
+ //double du = uv_er[i].u - uv_el[i].u;
+ //double dv = uv_er[i].v - uv_el[i].v;
+
+ // to calculate normalized parameter, we must know number of points in next layer
+ int nb_four = (curr_base_len - 1) / 4;
+ int nb_next = nb_four*2 + (curr_base_len - nb_four*4);
+ if (nb_next < nt) nb_next = nt;
+
+ for (j = 1; j + 4 <= curr_base_len && delta > 0; j += 4, delta -= 2) {
+ // add one "HH": nodes a,b,c,d,e and faces 1,2,3,4,5,6
+ //
+ // .-----a-----b i + 1
+ // |\ 5 | 6 /|
+ // | \ | / |
+ // | c--d--e |
+ // |1 |2 |3 |4 |
+ // | | | | |
+ // .--.--.--.--. i
+ //
+ // j j+2 j+4
+
+ double u,v;
+
+ // a (i + 1, j + 2)
+ const SMDS_MeshNode* Na;
+ next_base_len++;
+ next_base.SetValue(next_base_len, curr_base.Value(j + 2));
+ if (i + 1 == nr) { // top
+ Na = uv_et[next_base_len - 1].node;
+ NodesBRD.SetValue(next_base.Value(next_base_len), i + 1, Na);
+ u = uv_et[next_base_len - 1].u;
+ v = uv_et[next_base_len - 1].v;
+ }
+ else {
+ //double norm_par = double(next_base_len - 1)/double(nb_next - 1);
+ //u = uv_el[i].u + du * norm_par;
+ //v = uv_el[i].v + dv * norm_par;
+ {
+ double rel = double(next_base_len - 1) * double(nt - 1) / double(nb_next - 1) + 1;
+ int nearest_node_j = (int)rel;
+ rel -= nearest_node_j;
+ int ij = (i + 1 - 1) * nt + (nearest_node_j - 1);
+ double u1 = quad->uv_grid[ij].u;
+ double v1 = quad->uv_grid[ij].v;
+ double u2 = quad->uv_grid[ij + 1].u;
+ double v2 = quad->uv_grid[ij + 1].v;
+ double duj = (u2 - u1) * rel;
+ double dvj = (v2 - v1) * rel;
+ u = u1 + duj;
+ v = v1 + dvj;
+ }
+ //u = uv_el[i].u + du*npb.Value(curr_base.Value(j + 2));
+ //v = uv_el[i].v + dv*npb.Value(curr_base.Value(j + 2));
+ gp_Pnt P = S->Value(u,v);
+ SMDS_MeshNode* Na1 = meshDS->AddNode(P.X(), P.Y(), P.Z());
+ meshDS->SetNodeOnFace(Na1, geomFaceID, u, v);
+ NodesBRD.SetValue(next_base.Value(next_base_len), i + 1, Na1);
+ Na = Na1;
+ }
+ next_par_u.SetValue(next_base_len, u);
+ next_par_v.SetValue(next_base_len, v);
+
+ // b (i + 1, j + 4)
+ const SMDS_MeshNode* Nb;
+ next_base_len++;
+ next_base.SetValue(next_base_len, curr_base.Value(j + 4));
+ if (i + 1 == nr) { // top
+ Nb = uv_et[next_base_len - 1].node;
+ NodesBRD.SetValue(next_base.Value(next_base_len), i + 1, Nb);
+ u = uv_et[next_base_len - 1].u;
+ v = uv_et[next_base_len - 1].v;
+ }
+ else if (j + 4 == curr_base_len) { // right
+ Nb = NodesBRD.Value(next_base.Value(next_base_len), i + 1);
+ u = uv_er[i].u;
+ v = uv_er[i].v;
+ }
+ else {
+ //double norm_par = double(next_base_len - 1)/double(nb_next - 1);
+ //u = uv_el[i].u + du * norm_par;
+ //v = uv_el[i].v + dv * norm_par;
+ {
+ double rel = double(next_base_len - 1) * double(nt - 1) / double(nb_next - 1) + 1;
+ int nearest_node_j = (int)rel;
+ rel -= nearest_node_j;
+ int ij = (i + 1 - 1) * nt + (nearest_node_j - 1);
+ double u1 = quad->uv_grid[ij].u;
+ double v1 = quad->uv_grid[ij].v;
+ double u2 = quad->uv_grid[ij + 1].u;
+ double v2 = quad->uv_grid[ij + 1].v;
+ double duj = (u2 - u1) * rel;
+ double dvj = (v2 - v1) * rel;
+ u = u1 + duj;
+ v = v1 + dvj;
+ }
+ //u = uv_el[i].u + du*npb.Value(curr_base.Value(j + 4));
+ //v = uv_el[i].v + dv*npb.Value(curr_base.Value(j + 4));
+ gp_Pnt P = S->Value(u,v);
+ SMDS_MeshNode* Nb1 = meshDS->AddNode(P.X(), P.Y(), P.Z());
+ meshDS->SetNodeOnFace(Nb1, geomFaceID, u, v);
+ NodesBRD.SetValue(next_base.Value(next_base_len), i + 1, Nb1);
+ Nb = Nb1;
+ }
+ next_par_u.SetValue(next_base_len, u);
+ next_par_v.SetValue(next_base_len, v);
+
+ // c
+ u = (curr_par_u.Value(j + 2) + next_par_u.Value(next_base_len - 2)) / 2.0;
+ v = (curr_par_v.Value(j + 2) + next_par_v.Value(next_base_len - 2)) / 2.0;
+ gp_Pnt P = S->Value(u,v);
+ SMDS_MeshNode* Nc = meshDS->AddNode(P.X(), P.Y(), P.Z());
+ meshDS->SetNodeOnFace(Nc, geomFaceID, u, v);
+
+ // d
+ u = (curr_par_u.Value(j + 2) + next_par_u.Value(next_base_len - 1)) / 2.0;
+ v = (curr_par_v.Value(j + 2) + next_par_v.Value(next_base_len - 1)) / 2.0;
+ P = S->Value(u,v);
+ SMDS_MeshNode* Nd = meshDS->AddNode(P.X(), P.Y(), P.Z());
+ meshDS->SetNodeOnFace(Nd, geomFaceID, u, v);
+
+ // e
+ u = (curr_par_u.Value(j + 2) + next_par_u.Value(next_base_len)) / 2.0;
+ v = (curr_par_v.Value(j + 2) + next_par_v.Value(next_base_len)) / 2.0;
+ P = S->Value(u,v);
+ SMDS_MeshNode* Ne = meshDS->AddNode(P.X(), P.Y(), P.Z());
+ meshDS->SetNodeOnFace(Ne, geomFaceID, u, v);
+
+ // Faces
+ SMDS_MeshFace* F1 = myTool->AddFace(NodesBRD.Value(curr_base.Value(j + 0), i),
+ NodesBRD.Value(curr_base.Value(j + 1), i),
+ Nc,
+ NodesBRD.Value(next_base.Value(next_base_len - 2), i + 1));
+ if (F1) meshDS->SetMeshElementOnShape(F1, geomFaceID);
+
+ SMDS_MeshFace* F2 = myTool->AddFace(NodesBRD.Value(curr_base.Value(j + 1), i),
+ NodesBRD.Value(curr_base.Value(j + 2), i),
+ Nd, Nc);
+ if (F2) meshDS->SetMeshElementOnShape(F2, geomFaceID);
+
+ SMDS_MeshFace* F3 = myTool->AddFace(NodesBRD.Value(curr_base.Value(j + 2), i),
+ NodesBRD.Value(curr_base.Value(j + 3), i),
+ Ne, Nd);
+ if (F3) meshDS->SetMeshElementOnShape(F3, geomFaceID);
+
+ SMDS_MeshFace* F4 = myTool->AddFace(NodesBRD.Value(curr_base.Value(j + 3), i),
+ NodesBRD.Value(curr_base.Value(j + 4), i),
+ Nb, Ne);
+ if (F4) meshDS->SetMeshElementOnShape(F4, geomFaceID);
+
+ SMDS_MeshFace* F5 = myTool->AddFace(Nc, Nd, Na,
+ NodesBRD.Value(next_base.Value(next_base_len - 2), i + 1));
+ if (F5) meshDS->SetMeshElementOnShape(F5, geomFaceID);
+
+ SMDS_MeshFace* F6 = myTool->AddFace(Nd, Ne, Nb, Na);
+ if (F6) meshDS->SetMeshElementOnShape(F6, geomFaceID);
+ }
+
+ // not reduced side elements (if any)
+ for (; j < curr_base_len; j++) {
+ // f (i + 1, j + 1)
+ const SMDS_MeshNode* Nf;
+ double u,v;
+ next_base.SetValue(++next_base_len, curr_base.Value(j + 1));
+ if (i + 1 == nr) { // top
+ Nf = uv_et[next_base_len - 1].node;
+ NodesBRD.SetValue(next_base.Value(next_base_len), i + 1, Nf);
+ u = uv_et[next_base_len - 1].u;
+ v = uv_et[next_base_len - 1].v;
+ }
+ else if (j + 1 == curr_base_len) { // right
+ Nf = NodesBRD.Value(next_base.Value(next_base_len), i + 1);
+ u = uv_er[i].u;
+ v = uv_er[i].v;
+ }
+ else {
+ //double norm_par = double(next_base_len - 1)/double(nb_next - 1);
+ //u = uv_el[i].u + du * norm_par;
+ //v = uv_el[i].v + dv * norm_par;
+ {
+ double rel = double(next_base_len - 1) * double(nt - 1) / double(nb_next - 1) + 1;
+ int nearest_node_j = (int)rel;
+ rel -= nearest_node_j;
+ int ij = (i + 1 - 1) * nt + (nearest_node_j - 1);
+ double u1 = quad->uv_grid[ij].u;
+ double v1 = quad->uv_grid[ij].v;
+ double u2 = quad->uv_grid[ij + 1].u;
+ double v2 = quad->uv_grid[ij + 1].v;
+ double duj = (u2 - u1) * rel;
+ double dvj = (v2 - v1) * rel;
+ u = u1 + duj;
+ v = v1 + dvj;
+ }
+ //u = uv_el[i].u + du*npb.Value(curr_base.Value(j + 1));
+ //v = uv_el[i].v + dv*npb.Value(curr_base.Value(j + 1));
+ gp_Pnt P = S->Value(u,v);
+ SMDS_MeshNode* Nf1 = meshDS->AddNode(P.X(), P.Y(), P.Z());
+ meshDS->SetNodeOnFace(Nf1, geomFaceID, u, v);
+ NodesBRD.SetValue(next_base.Value(next_base_len), i + 1, Nf1);
+ Nf = Nf1;
+ }
+ next_par_u.SetValue(next_base_len, u);
+ next_par_v.SetValue(next_base_len, v);
+ SMDS_MeshFace* F1 = myTool->AddFace(NodesBRD.Value(curr_base.Value(j), i),
+ NodesBRD.Value(curr_base.Value(j + 1), i),
+ NodesBRD.Value(next_base.Value(next_base_len), i + 1),
+ NodesBRD.Value(next_base.Value(next_base_len - 1), i + 1));
+ if (F1) meshDS->SetMeshElementOnShape(F1, geomFaceID);
+ }
+
+ curr_base_len = next_base_len;
+ curr_base = next_base;
+ curr_par_u = next_par_u;
+ curr_par_v = next_par_v;
+ next_base_len = 0;
+ }
+ } // end "tree" simple reduce
+ else {
+ // "linear" simple reduce 4->8->12->16 (3 steps)
+ //
+ // .---------------.---------------.---------------.---------------. nr
+ // | \ | / | \ | / |
+ // | \ .-------.-------. / | \ .-------.-------. / |
+ // | | | | | | | | |
+ // .-------.-------.-------.-------.-------.-------.-------.-------.
+ // | / \ | / \ | / \ | / \ |
+ // | / \.----.----./ \ | / \.----.----./ \ | i
+ // | / | | | \ | / | | | \ |
+ // .-----.----.----.----.----.-----.-----.----.----.----.----.-----.
+ // | / / \ | / \ \ | / / \ | / \ \ |
+ // | / / .-.-. \ \ | / / .-.-. \ \ |
+ // | / / / | \ \ \ | / / / | \ \ \ |
+ // .---.---.---.---.---.---.---.---.---.---.---.---.---.---.---.---. 1
+ // 1 j nb
+
+ // nt = 5, nb = 7, nr = 4
+ //int delta_all = 2;
+ //int delta_one_col = 6;
+ //int nb_col = 0;
+ //int remainder = 2;
+ //if (remainder > 0) nb_col++;
+ //nb_col = 1;
+ //int free_left = 1;
+ //free_left += 2;
+ //int free_middle = 4;
+
+ int delta_all = nb - nt;
+ int delta_one_col = (nr - 1) * 2;
+ int nb_col = delta_all / delta_one_col;
+ int remainder = delta_all - nb_col * delta_one_col;
+ if (remainder > 0) {
+ nb_col++;
+ }
+ int free_left = ((nt - 1) - nb_col * 2) / 2;
+ free_left += nr - 2;
+ int free_middle = (nr - 2) * 2;
+ if (remainder > 0 && nb_col == 1) {
+ int nb_rows_short_col = remainder / 2;
+ int nb_rows_thrown = (nr - 1) - nb_rows_short_col;
+ free_left -= nb_rows_thrown;
+ }
+
+ // nt = 5, nb = 17, nr = 4
+ //int delta_all = 12;
+ //int delta_one_col = 6;
+ //int nb_col = 2;
+ //int remainder = 0;
+ //int free_left = 2;
+ //int free_middle = 4;
+
+ for (i = 1; i < nr; i++, free_middle -= 2, free_left -= 1) { // layer by layer
+ // left
+ NodesBRD.SetValue(1, i+1, uv_el[i].node);
+ next_base.SetValue(++next_base_len, 1);
+ // right
+ NodesBRD.SetValue(nb, i+1, uv_er[i].node);
+
+ // left
+ next_par_u.SetValue(next_base_len, uv_el[i].u);
+ next_par_v.SetValue(next_base_len, uv_el[i].v);
+
+ // to calculate normalized parameter, we must know number of points in next layer
+ int nb_next = curr_base_len - nb_col * 2;
+ if (remainder > 0 && i > remainder / 2)
+ // take into account short "column"
+ nb_next += 2;
+ if (nb_next < nt) nb_next = nt;
+
+ // not reduced left elements
+ for (j = 1; j <= free_left; j++) {
+ // f (i + 1, j + 1)
+ const SMDS_MeshNode* Nf;
+ double u,v;
+ next_base.SetValue(++next_base_len, curr_base.Value(j + 1));
+ if (i + 1 == nr) { // top
+ Nf = uv_et[next_base_len - 1].node;
+ NodesBRD.SetValue(next_base.Value(next_base_len), i + 1, Nf);
+ u = uv_et[next_base_len - 1].u;
+ v = uv_et[next_base_len - 1].v;
+ }
+ else {
+ {
+ double rel = double(next_base_len - 1) * double(nt - 1) / double(nb_next - 1) + 1;
+ int nearest_node_j = (int)rel;
+ rel -= nearest_node_j;
+ int ij = (i + 1 - 1) * nt + (nearest_node_j - 1);
+ double u1 = quad->uv_grid[ij].u;
+ double v1 = quad->uv_grid[ij].v;
+ double u2 = quad->uv_grid[ij + 1].u;
+ double v2 = quad->uv_grid[ij + 1].v;
+ double duj = (u2 - u1) * rel;
+ double dvj = (v2 - v1) * rel;
+ u = u1 + duj;
+ v = v1 + dvj;
+ }
+ gp_Pnt P = S->Value(u,v);
+ SMDS_MeshNode* Nf1 = meshDS->AddNode(P.X(), P.Y(), P.Z());
+ meshDS->SetNodeOnFace(Nf1, geomFaceID, u, v);
+ NodesBRD.SetValue(next_base.Value(next_base_len), i + 1, Nf1);
+ Nf = Nf1;
+ }
+ next_par_u.SetValue(next_base_len, u);
+ next_par_v.SetValue(next_base_len, v);
+ SMDS_MeshFace* F1 = myTool->AddFace(NodesBRD.Value(curr_base.Value(j), i),
+ NodesBRD.Value(curr_base.Value(j + 1), i),
+ NodesBRD.Value(next_base.Value(next_base_len), i + 1),
+ NodesBRD.Value(next_base.Value(next_base_len - 1), i + 1));
+ if (F1) meshDS->SetMeshElementOnShape(F1, geomFaceID);
+ }
+
+ for (int icol = 1; icol <= nb_col; icol++) {
+
+ if (remainder > 0 && icol == nb_col && i > remainder / 2)
+ // stop short "column"
+ break;
+
+ // add one "HH": nodes a,b,c,d,e and faces 1,2,3,4,5,6
+ //
+ // .-----a-----b i + 1
+ // |\ 5 | 6 /|
+ // | \ | / |
+ // | c--d--e |
+ // |1 |2 |3 |4 |
+ // | | | | |
+ // .--.--.--.--. i
+ //
+ // j j+2 j+4
+
+ double u,v;
+
+ // a (i + 1, j + 2)
+ const SMDS_MeshNode* Na;
+ next_base_len++;
+ next_base.SetValue(next_base_len, curr_base.Value(j + 2));
+ if (i + 1 == nr) { // top
+ Na = uv_et[next_base_len - 1].node;
+ NodesBRD.SetValue(next_base.Value(next_base_len), i + 1, Na);
+ u = uv_et[next_base_len - 1].u;
+ v = uv_et[next_base_len - 1].v;
+ }
+ else {
+ {
+ double rel = double(next_base_len - 1) * double(nt - 1) / double(nb_next - 1) + 1;
+ int nearest_node_j = (int)rel;
+ rel -= nearest_node_j;
+ int ij = (i + 1 - 1) * nt + (nearest_node_j - 1);
+ double u1 = quad->uv_grid[ij].u;
+ double v1 = quad->uv_grid[ij].v;
+ double u2 = quad->uv_grid[ij + 1].u;
+ double v2 = quad->uv_grid[ij + 1].v;
+ double duj = (u2 - u1) * rel;
+ double dvj = (v2 - v1) * rel;
+ u = u1 + duj;
+ v = v1 + dvj;
+ }
+ gp_Pnt P = S->Value(u,v);
+ SMDS_MeshNode* Na1 = meshDS->AddNode(P.X(), P.Y(), P.Z());
+ meshDS->SetNodeOnFace(Na1, geomFaceID, u, v);
+ NodesBRD.SetValue(next_base.Value(next_base_len), i + 1, Na1);
+ Na = Na1;
+ }
+ next_par_u.SetValue(next_base_len, u);
+ next_par_v.SetValue(next_base_len, v);
+
+ // b (i + 1, j + 4)
+ const SMDS_MeshNode* Nb;
+ next_base_len++;
+ next_base.SetValue(next_base_len, curr_base.Value(j + 4));
+ if (i + 1 == nr) { // top
+ Nb = uv_et[next_base_len - 1].node;
+ NodesBRD.SetValue(next_base.Value(next_base_len), i + 1, Nb);
+ u = uv_et[next_base_len - 1].u;
+ v = uv_et[next_base_len - 1].v;
+ }
+ else if (j + 4 == curr_base_len) { // right
+ Nb = NodesBRD.Value(next_base.Value(next_base_len), i + 1);
+ u = uv_er[i].u;
+ v = uv_er[i].v;
+ }
+ else {
+ {
+ double rel = double(next_base_len - 1) * double(nt - 1) / double(nb_next - 1) + 1;
+ int nearest_node_j = (int)rel;
+ rel -= nearest_node_j;
+ int ij = (i + 1 - 1) * nt + (nearest_node_j - 1);
+ double u1 = quad->uv_grid[ij].u;
+ double v1 = quad->uv_grid[ij].v;
+ double u2 = quad->uv_grid[ij + 1].u;
+ double v2 = quad->uv_grid[ij + 1].v;
+ double duj = (u2 - u1) * rel;
+ double dvj = (v2 - v1) * rel;
+ u = u1 + duj;
+ v = v1 + dvj;
+ }
+ gp_Pnt P = S->Value(u,v);
+ SMDS_MeshNode* Nb1 = meshDS->AddNode(P.X(), P.Y(), P.Z());
+ meshDS->SetNodeOnFace(Nb1, geomFaceID, u, v);
+ NodesBRD.SetValue(next_base.Value(next_base_len), i + 1, Nb1);
+ Nb = Nb1;
+ }
+ next_par_u.SetValue(next_base_len, u);
+ next_par_v.SetValue(next_base_len, v);
+
+ // c
+ u = (curr_par_u.Value(j + 2) + next_par_u.Value(next_base_len - 2)) / 2.0;
+ v = (curr_par_v.Value(j + 2) + next_par_v.Value(next_base_len - 2)) / 2.0;
+ gp_Pnt P = S->Value(u,v);
+ SMDS_MeshNode* Nc = meshDS->AddNode(P.X(), P.Y(), P.Z());
+ meshDS->SetNodeOnFace(Nc, geomFaceID, u, v);
+
+ // d
+ u = (curr_par_u.Value(j + 2) + next_par_u.Value(next_base_len - 1)) / 2.0;
+ v = (curr_par_v.Value(j + 2) + next_par_v.Value(next_base_len - 1)) / 2.0;
+ P = S->Value(u,v);
+ SMDS_MeshNode* Nd = meshDS->AddNode(P.X(), P.Y(), P.Z());
+ meshDS->SetNodeOnFace(Nd, geomFaceID, u, v);
+
+ // e
+ u = (curr_par_u.Value(j + 2) + next_par_u.Value(next_base_len)) / 2.0;
+ v = (curr_par_v.Value(j + 2) + next_par_v.Value(next_base_len)) / 2.0;
+ P = S->Value(u,v);
+ SMDS_MeshNode* Ne = meshDS->AddNode(P.X(), P.Y(), P.Z());
+ meshDS->SetNodeOnFace(Ne, geomFaceID, u, v);
+
+ // Faces
+ SMDS_MeshFace* F1 = myTool->AddFace(NodesBRD.Value(curr_base.Value(j + 0), i),
+ NodesBRD.Value(curr_base.Value(j + 1), i),
+ Nc,
+ NodesBRD.Value(next_base.Value(next_base_len - 2), i + 1));
+ if (F1) meshDS->SetMeshElementOnShape(F1, geomFaceID);
+
+ SMDS_MeshFace* F2 = myTool->AddFace(NodesBRD.Value(curr_base.Value(j + 1), i),
+ NodesBRD.Value(curr_base.Value(j + 2), i),
+ Nd, Nc);
+ if (F2) meshDS->SetMeshElementOnShape(F2, geomFaceID);
+
+ SMDS_MeshFace* F3 = myTool->AddFace(NodesBRD.Value(curr_base.Value(j + 2), i),
+ NodesBRD.Value(curr_base.Value(j + 3), i),
+ Ne, Nd);
+ if (F3) meshDS->SetMeshElementOnShape(F3, geomFaceID);
+
+ SMDS_MeshFace* F4 = myTool->AddFace(NodesBRD.Value(curr_base.Value(j + 3), i),
+ NodesBRD.Value(curr_base.Value(j + 4), i),
+ Nb, Ne);
+ if (F4) meshDS->SetMeshElementOnShape(F4, geomFaceID);
+
+ SMDS_MeshFace* F5 = myTool->AddFace(Nc, Nd, Na,
+ NodesBRD.Value(next_base.Value(next_base_len - 2), i + 1));
+ if (F5) meshDS->SetMeshElementOnShape(F5, geomFaceID);
+
+ SMDS_MeshFace* F6 = myTool->AddFace(Nd, Ne, Nb, Na);
+ if (F6) meshDS->SetMeshElementOnShape(F6, geomFaceID);
+
+ j += 4;
+
+ // not reduced middle elements
+ if (icol < nb_col) {
+ if (remainder > 0 && icol == nb_col - 1 && i > remainder / 2)
+ // pass middle elements before stopped short "column"
+ break;
+
+ int free_add = free_middle;
+ if (remainder > 0 && icol == nb_col - 1)
+ // next "column" is short
+ free_add -= (nr - 1) - (remainder / 2);
+
+ for (int imiddle = 1; imiddle <= free_add; imiddle++) {
+ // f (i + 1, j + imiddle)
+ const SMDS_MeshNode* Nf;
+ double u,v;
+ next_base.SetValue(++next_base_len, curr_base.Value(j + imiddle));
+ if (i + 1 == nr) { // top
+ Nf = uv_et[next_base_len - 1].node;
+ NodesBRD.SetValue(next_base.Value(next_base_len), i + 1, Nf);
+ u = uv_et[next_base_len - 1].u;
+ v = uv_et[next_base_len - 1].v;
+ }
+ else if (j + imiddle == curr_base_len) { // right
+ Nf = NodesBRD.Value(next_base.Value(next_base_len), i + 1);
+ u = uv_er[i].u;
+ v = uv_er[i].v;
+ }
+ else {
+ {
+ double rel = double(next_base_len - 1) * double(nt - 1) / double(nb_next - 1) + 1;
+ int nearest_node_j = (int)rel;
+ rel -= nearest_node_j;
+ int ij = (i + 1 - 1) * nt + (nearest_node_j - 1);
+ double u1 = quad->uv_grid[ij].u;
+ double v1 = quad->uv_grid[ij].v;
+ double u2 = quad->uv_grid[ij + 1].u;
+ double v2 = quad->uv_grid[ij + 1].v;
+ double duj = (u2 - u1) * rel;
+ double dvj = (v2 - v1) * rel;
+ u = u1 + duj;
+ v = v1 + dvj;
+ }
+ gp_Pnt P = S->Value(u,v);
+ SMDS_MeshNode* Nf1 = meshDS->AddNode(P.X(), P.Y(), P.Z());
+ meshDS->SetNodeOnFace(Nf1, geomFaceID, u, v);
+ NodesBRD.SetValue(next_base.Value(next_base_len), i + 1, Nf1);
+ Nf = Nf1;
+ }
+ next_par_u.SetValue(next_base_len, u);
+ next_par_v.SetValue(next_base_len, v);
+ SMDS_MeshFace* F1 = myTool->AddFace(NodesBRD.Value(curr_base.Value(j - 1 + imiddle), i),
+ NodesBRD.Value(curr_base.Value(j + imiddle), i),
+ NodesBRD.Value(next_base.Value(next_base_len), i + 1),
+ NodesBRD.Value(next_base.Value(next_base_len - 1), i + 1));
+ if (F1) meshDS->SetMeshElementOnShape(F1, geomFaceID);
+ }
+ j += free_add;
+ }
+ }
+
+ // not reduced right elements
+ for (; j < curr_base_len; j++) {
+ // f (i + 1, j + 1)
+ const SMDS_MeshNode* Nf;
+ double u,v;
+ next_base.SetValue(++next_base_len, curr_base.Value(j + 1));
+ if (i + 1 == nr) { // top
+ Nf = uv_et[next_base_len - 1].node;
+ NodesBRD.SetValue(next_base.Value(next_base_len), i + 1, Nf);
+ u = uv_et[next_base_len - 1].u;
+ v = uv_et[next_base_len - 1].v;
+ }
+ else if (j + 1 == curr_base_len) { // right
+ Nf = NodesBRD.Value(next_base.Value(next_base_len), i + 1);
+ u = uv_er[i].u;
+ v = uv_er[i].v;
+ }
+ else {
+ {
+ double rel = double(next_base_len - 1) * double(nt - 1) / double(nb_next - 1) + 1;
+ int nearest_node_j = (int)rel;
+ rel -= nearest_node_j;
+ int ij = (i + 1 - 1) * nt + (nearest_node_j - 1);
+ double u1 = quad->uv_grid[ij].u;
+ double v1 = quad->uv_grid[ij].v;
+ double u2 = quad->uv_grid[ij + 1].u;
+ double v2 = quad->uv_grid[ij + 1].v;
+ double duj = (u2 - u1) * rel;
+ double dvj = (v2 - v1) * rel;
+ u = u1 + duj;
+ v = v1 + dvj;
+ }
+ gp_Pnt P = S->Value(u,v);
+ SMDS_MeshNode* Nf1 = meshDS->AddNode(P.X(), P.Y(), P.Z());
+ meshDS->SetNodeOnFace(Nf1, geomFaceID, u, v);
+ NodesBRD.SetValue(next_base.Value(next_base_len), i + 1, Nf1);
+ Nf = Nf1;
+ }
+ next_par_u.SetValue(next_base_len, u);
+ next_par_v.SetValue(next_base_len, v);
+ SMDS_MeshFace* F1 = myTool->AddFace(NodesBRD.Value(curr_base.Value(j), i),
+ NodesBRD.Value(curr_base.Value(j + 1), i),
+ NodesBRD.Value(next_base.Value(next_base_len), i + 1),
+ NodesBRD.Value(next_base.Value(next_base_len - 1), i + 1));
+ if (F1) meshDS->SetMeshElementOnShape(F1, geomFaceID);
+ }
+
+ curr_base_len = next_base_len;
+ curr_base = next_base;
+ curr_par_u = next_par_u;
+ curr_par_v = next_par_v;
+ next_base_len = 0;
+ }
+ } // end "linear" simple reduce
+ } // end Simple Reduce implementation
+
+ bool isOk = true;
+ return isOk;
+}
//
// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
//
-
// SMESH SMESH : implementaion of SMESH idl descriptions
// File : StdMeshers_Quadrangle_2D.hxx
// Moved here from SMESH_Quadrangle_2D.hxx
// Author : Paul RASCLE, EDF
// Module : SMESH
// $Header$
-//
+
#ifndef _SMESH_QUADRANGLE_2D_HXX_
#define _SMESH_QUADRANGLE_2D_HXX_
#include "SMESH_StdMeshers.hxx"
+#include "StdMeshers_QuadrangleParams.hxx"
+
#include "SMESH_2D_Algo.hxx"
#include "Utils_SALOME_Exception.hxx"
const TopoDS_Face& F, const TopoDS_Edge& E,
double first, double last, int nb_segm);
+ bool ComputeReduced (SMESH_Mesh& aMesh,
+ const TopoDS_Shape& aShape,
+ FaceQuadStruct* quad);
+
// true if QuadranglePreference hypothesis is assigned that forces
// construction of quadrangles if the number of nodes on opposite edges
// is not the same in the case where the global number of nodes on edges
int myTriaVertexID;
+ StdMeshers_QuadType myQuadType;
+
SMESH_MesherHelper* myTool; // tool for working with quadratic elements
};
double a1 = _value[ BEG_LENGTH_IND ];
double an = _value[ END_LENGTH_IND ];
double q = ( theLength - a1 ) / ( theLength - an );
+ if ( q < theLength/1e6 || 1.01*theLength < a1 + an)
+ return error ( SMESH_Comment("Invalid segment lengths (")<<a1<<" and "<<an<<") "<<
+ "for an edge of length "<<theLength);
double U1 = theReverse ? l : f;
double Un = theReverse ? f : l;
double a1 = _value[ BEG_LENGTH_IND ];
double an = _value[ END_LENGTH_IND ];
+ if ( 1.01*theLength < a1 + an)
+ return error ( SMESH_Comment("Invalid segment lengths (")<<a1<<" and "<<an<<") "<<
+ "for an edge of length "<<theLength);
double q = ( an - a1 ) / ( 2 *theLength/( a1 + an ) - 1 );
int n = int(fabs(q) > numeric_limits<double>::min() ? ( 1+( an-a1 )/q ) : ( 1+theLength/a1 ));
if (!idFirst || !idLast)
return error( COMPERR_BAD_INPUT_MESH, "No node on vertex");
+ // remove elements created by e.g. patern mapping (PAL21999)
+ // CLEAN event is incorrectly ptopagated seemingly due to Propagation hyp
+ // so TEMPORARY solution is to clean the submesh manually
+ //theMesh.GetSubMesh(theShape)->ComputeStateEngine( SMESH_subMesh::CLEAN );
+ if (SMESHDS_SubMesh * subMeshDS = meshDS->MeshElements(theShape))
+ {
+ SMDS_ElemIteratorPtr ite = subMeshDS->GetElements();
+ while (ite->more())
+ meshDS->RemoveFreeElement(ite->next(), subMeshDS);
+ SMDS_NodeIteratorPtr itn = subMeshDS->GetNodes();
+ while (itn->more()) {
+ const SMDS_MeshNode * node = itn->next();
+ if ( node->NbInverseElements() == 0 )
+ meshDS->RemoveFreeNode(node, subMeshDS);
+ else
+ meshDS->RemoveNode(node);
+ }
+ }
+
if (!Curve.IsNull())
{
list< double > params;
parLast = f;
}
*/
-
for (list<double>::iterator itU = params.begin(); itU != params.end(); itU++) {
double param = *itU;
gp_Pnt P = Curve->Value(param);
#
# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
#
-
# SMESH StdMeshersGUI : GUI for StdMeshers plugin
# File : Makefile.in
# Author : Julia DOROVSKIKH
# Modified by : Alexander BORODIN (OCN) - autotools usage
# Module : SMESH
-#
+
include $(top_srcdir)/adm_local/unix/make_common_starter.am
# header files
StdMeshersGUI_DistrTable.h \
StdMeshersGUI_NbSegmentsCreator.h \
StdMeshersGUI_ObjectReferenceParamWdg.h \
+ StdMeshersGUI_QuadrangleParamWdg.h \
StdMeshersGUI_LayerDistributionParamWdg.h \
StdMeshersGUI_FixedPointsParamWdg.h \
StdMeshersGUI_SubShapeSelectorWdg.h
# Libraries targets
lib_LTLIBRARIES = libStdMeshersGUI.la
+
dist_libStdMeshersGUI_la_SOURCES = \
StdMeshersGUI.cxx \
StdMeshersGUI_StdHypothesisCreator.cxx \
StdMeshersGUI_DistrTable.cxx \
StdMeshersGUI_NbSegmentsCreator.cxx \
StdMeshersGUI_ObjectReferenceParamWdg.cxx \
+ StdMeshersGUI_QuadrangleParamWdg.cxx \
StdMeshersGUI_LayerDistributionParamWdg.cxx \
StdMeshersGUI_FixedPointsParamWdg.cxx \
StdMeshersGUI_SubShapeSelectorWdg.cxx
StdMeshersGUI_DistrTable_moc.cxx \
StdMeshersGUI_NbSegmentsCreator_moc.cxx \
StdMeshersGUI_ObjectReferenceParamWdg_moc.cxx \
+ StdMeshersGUI_QuadrangleParamWdg_moc.cxx \
StdMeshersGUI_LayerDistributionParamWdg_moc.cxx \
StdMeshersGUI_FixedPointsParamWdg_moc.cxx \
StdMeshersGUI_SubShapeSelectorWdg_moc.cxx
QLabel *myLScale, *myLTable, *myLExpr, *myInfo;
QGridLayout* myGroupLayout;
int myTableRow, myPreviewRow;
- QRadioButton* myCutNeg;
+ //QRadioButton* myCutNeg;
QGroupBox* myReversedEdgesBox;
StdMeshersGUI_SubShapeSelectorWdg* myDirectionWidget;
--- /dev/null
+// Copyright (C) 2007-2010 CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+// File : StdMeshersGUI_QuadrangleParamWdg.cxx
+// Author : Open CASCADE S.A.S. (jfa)
+// SMESH includes
+
+#include "StdMeshersGUI_QuadrangleParamWdg.h"
+
+#include "SMESHGUI.h"
+
+#include "SUIT_ResourceMgr.h"
+
+// Qt includes
+#include <QButtonGroup>
+#include <QRadioButton>
+#include <QLabel>
+#include <QGridLayout>
+
+// IDL includes
+#include <SALOMEconfig.h>
+#include CORBA_CLIENT_HEADER(SMESH_BasicHypothesis)
+
+#define SPACING 6
+#define MARGIN 0
+
+//================================================================================
+// function : Constructor
+// purpose :
+//================================================================================
+StdMeshersGUI_QuadrangleParamWdg::StdMeshersGUI_QuadrangleParamWdg (QWidget * parent)
+ : QWidget(parent),
+ myType(0)
+{
+ myType = new QButtonGroup (this);
+
+ QGridLayout* typeLay = new QGridLayout( this );
+
+ typeLay->setMargin(MARGIN);
+ typeLay->setSpacing(SPACING);
+
+ QString aTypeKey ("SMESH_QUAD_TYPE_%1");
+ QString aPictKey ("ICON_StdMeshers_Quadrangle_Params_%1");
+
+ int itype = 0;
+ for (; itype < int(StdMeshers::QUAD_NB_TYPES); itype++) {
+ QRadioButton* rbi = new QRadioButton (tr(aTypeKey.arg(itype).toLatin1()), this);
+ QPixmap pmi (SMESHGUI::resourceMgr()->loadPixmap("SMESH", tr(aPictKey.arg(itype).toLatin1())));
+ QLabel* pli = new QLabel (this);
+ pli->setPixmap(pmi);
+ typeLay->addWidget(rbi, itype, 0, 1, 1);
+ typeLay->addWidget(pli, itype, 1, 1, 1);
+ myType->addButton(rbi, itype);
+ }
+ myType->button(0)->setChecked(true);
+
+ setLayout(typeLay);
+ setMinimumWidth(300);
+}
+
+//================================================================================
+// function : Destructor
+// purpose :
+//================================================================================
+StdMeshersGUI_QuadrangleParamWdg::~StdMeshersGUI_QuadrangleParamWdg()
+{
+}
+
+//=================================================================================
+// function : SetType
+// purpose :
+//=================================================================================
+void StdMeshersGUI_QuadrangleParamWdg::SetType (int theType)
+{
+ myType->button(theType)->setChecked(true);
+}
+
+//=================================================================================
+// function : GetType
+// purpose :
+//=================================================================================
+int StdMeshersGUI_QuadrangleParamWdg::GetType()
+{
+ return myType->checkedId();
+}
--- /dev/null
+// Copyright (C) 2007-2010 CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+// File : StdMeshersGUI_QuadrangleParamWdg.h
+// Author : Open CASCADE S.A.S. (jfa)
+
+#ifndef STDMESHERSGUI_QUADRANGLEPARAMWDG_H
+#define STDMESHERSGUI_QUADRANGLEPARAMWDG_H
+
+// SMESH includes
+#include "SMESH_StdMeshersGUI.hxx"
+
+// Qt includes
+#include <QWidget>
+
+class QButtonGroup;
+
+class STDMESHERSGUI_EXPORT StdMeshersGUI_QuadrangleParamWdg : public QWidget
+{
+ Q_OBJECT
+
+public:
+ StdMeshersGUI_QuadrangleParamWdg (QWidget* parent = 0);
+ ~StdMeshersGUI_QuadrangleParamWdg();
+
+ void SetType (int theType);
+ int GetType ();
+
+private:
+ // Quadranle preference, Triangle preference, Reduced
+ QButtonGroup* myType;
+};
+
+#endif // STDMESHERSGUI_QUADRANGLEPARAMWDG_H
//
// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
//
+// File : StdMeshersGUI_StdHypothesisCreator.cxx
+// Author : Alexander SOLOVYOV, Open CASCADE S.A.S.
+// SMESH includes
-// File : StdMeshersGUI_StdHypothesisCreator.cxx
-// Author : Alexander SOLOVYOV, Open CASCADE S.A.S.
-// SMESH includes
-//
#include "StdMeshersGUI_StdHypothesisCreator.h"
#include <SMESHGUI.h>
#include <SMESHGUI_SpinBox.h>
#include <SMESHGUI_HypothesesUtils.h>
#include <SMESHGUI_Utils.h>
+
#include <SMESH_TypeFilter.hxx>
#include <SMESH_NumberFilter.hxx>
-#include "StdMeshersGUI_ObjectReferenceParamWdg.h"
+
+#include "StdMeshersGUI_FixedPointsParamWdg.h"
#include "StdMeshersGUI_LayerDistributionParamWdg.h"
+#include "StdMeshersGUI_ObjectReferenceParamWdg.h"
+#include "StdMeshersGUI_QuadrangleParamWdg.h"
#include "StdMeshersGUI_SubShapeSelectorWdg.h"
-#include "StdMeshersGUI_FixedPointsParamWdg.h"
+
#include <SALOMEDSClient_Study.hxx>
// SALOME GUI includes
}
else if ( hypType() == "QuadrangleParams" )
{
- StdMeshersGUI_SubShapeSelectorWdg* w =
- widget< StdMeshersGUI_SubShapeSelectorWdg >( 0 );
- ok = ( w->GetListSize() > 0 );
+ //StdMeshersGUI_SubShapeSelectorWdg* w =
+ // widget< StdMeshersGUI_SubShapeSelectorWdg >( 0 );
+ //ok = ( w->GetListSize() > 0 );
+ //StdMeshersGUI_QuadrangleParamWdg* w =
+ // widget< StdMeshersGUI_QuadrangleParamWdg >( 1 );
}
return ok;
}
{
StdMeshers::StdMeshers_QuadrangleParams_var h =
StdMeshers::StdMeshers_QuadrangleParams::_narrow( hypothesis() );
- StdMeshersGUI_SubShapeSelectorWdg* w =
+ StdMeshersGUI_SubShapeSelectorWdg* w1 =
widget< StdMeshersGUI_SubShapeSelectorWdg >( 0 );
- if (w) {
- if( w->GetListSize() > 0 ) {
- h->SetTriaVertex( w->GetListOfIDs()[0] ); // getlist must be called once
- const char * entry = w->GetMainShapeEntry();
- h->SetObjectEntry( entry );
+ StdMeshersGUI_QuadrangleParamWdg* w2 =
+ widget< StdMeshersGUI_QuadrangleParamWdg >( 1 );
+ if (w1 && w2) {
+ if (w1->GetListSize() > 0) {
+ h->SetTriaVertex(w1->GetListOfIDs()[0]); // getlist must be called once
+ const char * entry = w1->GetMainShapeEntry();
+ h->SetObjectEntry(entry);
}
+ h->SetQuadType(StdMeshers::QuadType(w2->GetType()));
}
}
}
customWidgets()->append( newObjRefParamWdg( filterForShapeOfDim( 0 ),
h->GetTargetVertex( 2 )));
}
- else if( hypType()=="QuadrangleParams" )
+ else if (hypType() == "QuadrangleParams")
{
StdMeshers::StdMeshers_QuadrangleParams_var h =
- StdMeshers::StdMeshers_QuadrangleParams::_narrow( hyp );
+ StdMeshers::StdMeshers_QuadrangleParams::_narrow(hyp);
- item.myName = tr( "SMESH_BASE_VERTEX" );
- p.append( item );
+ item.myName = tr("SMESH_BASE_VERTEX");
+ p.append(item);
StdMeshersGUI_SubShapeSelectorWdg* aDirectionWidget =
new StdMeshersGUI_SubShapeSelectorWdg();
aDirectionWidget->SetSubShType(TopAbs_VERTEX);
QString anEntry = SMESHGUI_GenericHypothesisCreator::getShapeEntry();
QString aMainEntry = SMESHGUI_GenericHypothesisCreator::getMainShapeEntry();
- if ( anEntry == "" )
+ if (anEntry == "")
anEntry = h->GetObjectEntry();
- aDirectionWidget->SetGeomShapeEntry( anEntry );
- aDirectionWidget->SetMainShapeEntry( aMainEntry );
- if ( !isCreation() ) {
+ aDirectionWidget->SetGeomShapeEntry(anEntry);
+ aDirectionWidget->SetMainShapeEntry(aMainEntry);
+ if (!isCreation()) {
SMESH::long_array_var aVec = new SMESH::long_array;
int vertID = h->GetTriaVertex();
- if(vertID>0) {
+ if (vertID > 0) {
aVec->length(1);
aVec[0] = vertID;
- aDirectionWidget->SetListOfIDs( aVec );
+ aDirectionWidget->SetListOfIDs(aVec);
}
}
- aDirectionWidget->showPreview( true );
- customWidgets()->append ( aDirectionWidget );
+ aDirectionWidget->showPreview(true);
+
+ item.myName = tr("SMESH_QUAD_TYPE");
+ p.append(item);
+
+ StdMeshersGUI_QuadrangleParamWdg* aTypeWidget =
+ new StdMeshersGUI_QuadrangleParamWdg();
+ if (!isCreation()) {
+ aTypeWidget->SetType(int(h->GetQuadType()));
+ }
+
+ customWidgets()->append(aDirectionWidget);
+ customWidgets()->append(aTypeWidget);
}
else
res = false;
param.myValue = w->GetValue();
return true;
}
+ if ( widget->inherits( "StdMeshersGUI_QuadrangleParamWdg" ))
+ {
+ //const StdMeshersGUI_QuadrangleParamWdg * w =
+ // static_cast<const StdMeshersGUI_QuadrangleParamWdg*>( widget );
+ param.myValue = "QuadType";
+ return true;
+ }
if ( widget->inherits( "StdMeshersGUI_FixedPointsParamWdg" ))
{
const StdMeshersGUI_FixedPointsParamWdg * w =
<source>ICON_DLG_PROJECTION_SOURCE_3D</source>
<translation>mesh_hypo_source_3d.png</translation>
</message>
+ <message>
+ <source>ICON_DLG_QUADRANGLE_PARAMS</source>
+ <translation>mesh_hypo_length.png</translation>
+ </message>
<message>
<source>ICON_DLG_SEGMENT_LENGTH_AROUND_VERTEX</source>
<translation>mesh_hypo_length.png</translation>
<source>ICON_SMESH_TREE_HYPO_StartEndLength</source>
<translation>mesh_tree_hypo_length.png</translation>
</message>
+ </context>
+ <context>
+ <name>StdMeshersGUI_QuadrangleParamWdg</name>
<message>
- <source>ICON_DLG_QUADRANGLE_PARAMS</source>
- <translation>mesh_hypo_length.png</translation>
+ <source>ICON_StdMeshers_Quadrangle_Params_0</source>
+ <translation>mesh_quadrangle_standard.png</translation>
+ </message>
+ <message>
+ <source>ICON_StdMeshers_Quadrangle_Params_1</source>
+ <translation>mesh_quadrangle_triapref.png</translation>
+ </message>
+ <message>
+ <source>ICON_StdMeshers_Quadrangle_Params_2</source>
+ <translation>mesh_quadrangle_quadpref.png</translation>
+ </message>
+ <message>
+ <source>ICON_StdMeshers_Quadrangle_Params_3</source>
+ <translation>mesh_quadrangle_quadpref_reversed.png</translation>
+ </message>
+ <message>
+ <source>ICON_StdMeshers_Quadrangle_Params_4</source>
+ <translation>mesh_quadrangle_reduced.png</translation>
</message>
</context>
</TS>
<source>SMESH_QUADRANGLE_PARAMS_TITLE</source>
<translation>Hypothesis Construction</translation>
</message>
+ <message>
+ <source>SMESH_QUAD_TYPE</source>
+ <translation>Type</translation>
+ </message>
+</context>
+<context>
+ <name>StdMeshersGUI_QuadrangleParamWdg</name>
+ <message>
+ <source>SMESH_QUAD_TYPE_0</source>
+ <translation>Standard</translation>
+ </message>
+ <message>
+ <source>SMESH_QUAD_TYPE_1</source>
+ <translation>Triangle preference</translation>
+ </message>
+ <message>
+ <source>SMESH_QUAD_TYPE_2</source>
+ <translation>Quadrangle preference</translation>
+ </message>
+ <message>
+ <source>SMESH_QUAD_TYPE_3</source>
+ <translation>Quadrangle preference (reversed)</translation>
+ </message>
+ <message>
+ <source>SMESH_QUAD_TYPE_4</source>
+ <translation>Reduced</translation>
+ </message>
</context>
<context>
<name>StdMeshersGUI_LayerDistributionParamWdg</name>
//
// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
//
-
// SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
// File : StdMeshers_QuadrangleParams_i.cxx
// Author : Sergey KUUL, OCC
// Module : SMESH
-// $Header$
-//
+
#include "StdMeshers_QuadrangleParams_i.hxx"
#include "SMESH_Gen_i.hxx"
#include "SMESH_Gen.hxx"
<< vertID << " )";
}
+//=============================================================================
+/*!
+ * StdMeshers_QuadrangleParams_i::GetTriaVertex
+ *
+ * Get base vertex for triangles
+ */
+//=============================================================================
+
+CORBA::Long StdMeshers_QuadrangleParams_i::GetTriaVertex()
+{
+ MESSAGE( "StdMeshers_QuadrangleParams_i::GetTriaVertex" );
+ ASSERT( myBaseImpl );
+ return this->GetImpl()->GetTriaVertex();
+}
+
//=============================================================================
/*!
* StdMeshers_QuadrangleParams_i::SetObjectEntry
//=============================================================================
/*!
- * StdMeshers_QuadrangleParams_i::GetTriaVertex
+ * StdMeshers_QuadrangleParams_i::SetQuadType
*
- * Get base vertex for triangles
+ * Set the type of quadrangulation
*/
//=============================================================================
+void StdMeshers_QuadrangleParams_i::SetQuadType(StdMeshers::QuadType type)
+{
+ //static char* quadTypes[5] = {"StdMeshers.QUAD_STANDARD",
+ // "StdMeshers.QUAD_TRIANGLE_PREF",
+ // "StdMeshers.QUAD_QUADRANGLE_PREF",
+ // "StdMeshers.QUAD_QUADRANGLE_PREF_REVERSED",
+ // "StdMeshers.QUAD_REDUCED"};
-CORBA::Long StdMeshers_QuadrangleParams_i::GetTriaVertex()
+ MESSAGE("StdMeshers_QuadrangleParams_i::SetQuadType");
+ ASSERT(myBaseImpl);
+
+ if (int(type) >= int(StdMeshers::QUAD_NB_TYPES)) {
+ THROW_SALOME_CORBA_EXCEPTION("Bad type of quadrangulation", SALOME::BAD_PARAM);
+ }
+
+ try {
+ this->GetImpl()->SetQuadType(StdMeshers_QuadType(int(type)));
+ }
+ catch (SALOME_Exception& S_ex) {
+ THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
+ }
+
+ // Update Python script
+ const char* quadType;
+ switch (type) {
+ case StdMeshers::QUAD_STANDARD:
+ quadType = "StdMeshers.QUAD_STANDARD"; break;
+ case StdMeshers::QUAD_TRIANGLE_PREF:
+ quadType = "StdMeshers.QUAD_TRIANGLE_PREF"; break;
+ case StdMeshers::QUAD_QUADRANGLE_PREF:
+ quadType = "StdMeshers.QUAD_QUADRANGLE_PREF"; break;
+ case StdMeshers::QUAD_QUADRANGLE_PREF_REVERSED:
+ quadType = "StdMeshers.QUAD_QUADRANGLE_PREF_REVERSED"; break;
+ case StdMeshers::QUAD_REDUCED:
+ quadType = "StdMeshers.QUAD_REDUCED"; break;
+ default:
+ quadType = "UNKNOWN";
+ }
+ SMESH::TPythonDump() << _this() << ".SetQuadType( " << quadType << " )";
+ //SMESH::TPythonDump() << _this() << ".SetQuadType( " << quadTypes[int(type)] << " )";
+}
+
+//=============================================================================
+/*!
+ * StdMeshers_QuadrangleParams_i::GetQuadType
+ *
+ * Get the type of quadrangulation
+ */
+//=============================================================================
+StdMeshers::QuadType StdMeshers_QuadrangleParams_i::GetQuadType()
{
- MESSAGE( "StdMeshers_QuadrangleParams_i::GetTriaVertex" );
- ASSERT( myBaseImpl );
- return this->GetImpl()->GetTriaVertex();
+ MESSAGE("StdMeshers_QuadrangleParams_i::GetQuadType");
+ ASSERT(myBaseImpl);
+ return StdMeshers::QuadType(int(this->GetImpl()->GetQuadType()));
}
//=============================================================================
{
return type == SMESH::DIM_2D;
}
-
//
// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
//
-
-// SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
+// SMESH SMESH_I : idl implementation based on 'SMESH' unit's classes
// File : StdMeshers_QuadrangleParams_i.hxx
// Author : Sergey KUUL, OCC
// Module : SMESH
// $Header$
-//
+
#ifndef _SMESH_QUADRANGLEPARAMS_I_HXX_
#define _SMESH_QUADRANGLEPARAMS_I_HXX_
{
public:
// Constructor
- StdMeshers_QuadrangleParams_i( PortableServer::POA_ptr thePOA,
+ StdMeshers_QuadrangleParams_i (PortableServer::POA_ptr thePOA,
int theStudyId,
- ::SMESH_Gen* theGenImpl );
+ ::SMESH_Gen* theGenImpl);
// Destructor
virtual ~StdMeshers_QuadrangleParams_i();
// Get length
//CORBA::Double GetLength(CORBA::Boolean theIsStart);
- //Set base vertex for triangles
- void SetTriaVertex(CORBA::Long vertID);
+ // Set base vertex for triangles
+ void SetTriaVertex (CORBA::Long vertID);
- //Get base vertex for triangles
+ // Get base vertex for triangles
CORBA::Long GetTriaVertex();
- //Set the Entry of the Object
- void SetObjectEntry(const char* theEntry);
+ // Set the Entry of the Object
+ void SetObjectEntry (const char* theEntry);
- //Get Object Entry
+ // Get Object Entry
char* GetObjectEntry();
+ // Set the type of quadrangulation
+ void SetQuadType (StdMeshers::QuadType type);
+
+ // Get the type of quadrangulation
+ StdMeshers::QuadType GetQuadType();
+
// Get implementation
::StdMeshers_QuadrangleParams* GetImpl();