-# Reorient faces by vector
+# Reorient faces
import salome
#
# FaceOrPoint - a SMESH.PointStruct structure
mesh.Reorient2D( localAlgo.GetSubMesh().GetIDs(), [10,1,0], SMESH.PointStruct(0,0,0))
+
+
+# Use Reorient2DBy3D() to orient faces of 2 geom faces to have their normal pointing inside volumes
+
+mesh3D = smesh.Mesh( box, '3D mesh')
+mesh3D.AutomaticHexahedralization(0.5)
+group0 = mesh3D.Group( faces[0] )
+group1 = mesh3D.Group( faces[1] )
+
+# pass group0 and ids of faces of group1 to inverse
+nbRev = mesh3D.Reorient2DBy3D([ group0, group1.GetIDs() ], mesh3D, theOutsideNormal=False)
+print "Nb reoriented faces:", nbRev
+
+# orient the reversed faces back
+nbRev = mesh3D.Reorient2DBy3D( mesh3D, mesh3D, theOutsideNormal=True)
+print "Nb re-reoriented faces:", nbRev
+
<br><b>Equidistant Distribution</b> - all segments will have the same
length, you define only the <b>Number of Segments</b>.
-<br><b>Scale Distribution</b> - length of segments gradually changes depending on the <b>Scale Factor</b>, which is a ratio of the first segment length to the last segment length.
+<br><b>Scale Distribution</b> - length of segments gradually changes
+depending on the <b>Scale Factor</b>, which is a ratio of the first
+segment length to the last segment length.<br>
+Length of segments changes in geometric progression with the common
+ratio (A) depending on the <b>Scale Factor</b> (S) and <b>Number of
+Segments</b> (N) as follows: <code> A = S**(1/(N-1))</code>. For an
+edge of length L, length of the first segment is
+<code>L * (1 - A)/(1 - A**N)</code>.
-\image html a-nbsegments2.png
-
-<br><b>Distribution with Table Density</b> - you input a number of
-pairs <b>t - F(t)</b>, where \b t ranges from 0 to 1, and the module computes the
-formula, which will rule the change of length of segments and shows
-the curve in the plot. You can select the <b>Conversion mode</b> from
-\b Exponent and <b>Cut negative</b>.
-\image html distributionwithtabledensity.png
+\image html a-nbsegments2.png
<br><b>Distribution with Analytic Density</b> - you input the formula,
which will rule the change of length of segments and the module shows
-the curve in the plot.
+in the plot the density function curve in red and the node
+distribution as blue crosses.
\image html distributionwithanalyticdensity.png
+<br>
+\anchor analyticdensity_anchor
+The node distribution is computed so that to have the density function
+integral on the range between two nodes equal for all segments.
+\image html analyticdensity.png
+
+<br><b>Distribution with Table Density</b> - you input a number of
+pairs <b>t - F(t)</b>, where \b t ranges from 0 to 1, and the module computes the
+formula, which will rule the change of length of segments and shows
+in the plot the density function curve in red and the node
+distribution as blue crosses. The node distribution is computed the
+same way as for
+\ref analyticdensity_anchor "Distribution with Analytic Density". You
+can select the <b>Conversion mode</b> from\b Exponent and <b>Cut
+negative</b>.
+
+\image html distributionwithtabledensity.png
+
<b>See Also</b> a sample TUI Script of a
\ref tui_deflection_1d "Defining Number of Segments" hypothesis
operation.
+
<br>
\anchor start_and_end_length_anchor
<h2>Start and End Length hypothesis</h2>
and edges, just hide the mesh to avoid this. To avoid a long wait when a
geometry with many faces (or edges) is displayed, the number of faces
(edges) shown at a time is limited by the value of "Sub-shapes
- preview chunk size" preference (in Preferences/Mesh/General tab).<br>
+ preview chunk size" preference (in Preferences/Mesh/General tab).
If faces/edges without layers are specified, the element layers are
not constructed on geometrical faces shared by several solids in 3D
possibly being internal faces/edges within the whole model.
\image html viscous_layers_on_submesh.png 2D viscous layers constructed on boundary edges of a sub-mesh on a disk face.
+ If you use \b several hypotheses to define viscous layers on faces of
+ one solid, keep in mind the following. Each hypothesis defines a set
+ of faces with viscous layers (even if you specify faces without
+ layers). The sets of faces with viscous layers defined by several
+ hypotheses should not intersect, else the module won't add an
+ hypothesis that is incompatible with another one. <br>
+ Also you can't define different number of layers on adjacent faces
+ of a solid.<br>
+ This logic is also valid for the 2D hypothesis.
</li>
</ul>
\image html createmesh-inv.png
<br>
</li>
- <li>Select <b>Mesh Type</b> in the corresponding list from <b>Any, Hexahedral, Tetrahedral, Triangular </b> and \b Quadrilateral (there can be less items for lower dimensions).
-
- Selection of a mesh type hides any algorithms that are not able to create elements of this type.</li>
-
+ <li> To filter off irrelevant meshing algorithms, you can
+ select <b>Mesh Type</b> in the corresponding list from <b>Any,
+ Hexahedral, Tetrahedral, Triangular </b> and \b Quadrilateral (there
+ can be less items for the geometry of lower dimensions).
+
+ Selection of a mesh type hides all meshing algorithms that can not
+ generate elements of this type.</li>
+
<li>Apply \subpage basic_meshing_algos_page "meshing algorithms" and
\subpage about_hypo_page "hypotheses" which will be used to compute
this mesh.
dimension of the CAD model (geometry) the algorithms listed on
this page affect and the maximal dimension of elements the algorithms
generate. For example, \b 3D page lists the algorithms that affect
- 3D geometrical objects (solids).
+ 3D geometrical objects (solids) and generate 3D mesh elements
+ (tetrahedra, hexahedra etc.)
\note
- Some page(s) can be disabled if the source geometrical
it is "Mesh_1". Then select the geometrical object you wish to
mesh in the Object Browser and click "Select" button near \b Geometry
field (if the name of the object has not yet appeared in \b Geometry field).
-
<center>
\image html image120.png
<em>"Select" button</em>
Now you can define 3D Algorithm and 3D Hypotheses, which will be
applied to the solids of your geometrical object. Click the <em>"Add
Hypothesis"</em> button to add a hypothesis.
-
<center>
\image html image121.png
<em>"Add Hypothesis" button</em>
</center>
+ Click the <em>"Plus"</em> button to enable adding more additional hypotheses.
Click the <em>"Edit Hypothesis"</em> button to change the values for the
current hypothesis.
-
<center>
\image html image122.png
<em>"Edit Hypothesis" button</em>
</center>
- Most 2D and 3D algorithms can work without hypotheses using default meshing parameters. Some algorithms do not require any hypotheses. After selection of an algorithm "Hypothesis" field of
+ Most 2D and 3D algorithms can work without hypotheses using
+ default meshing parameters. Some algorithms do not require any
+ hypotheses. After selection of an algorithm "Hypothesis" field of
the dialog can contain:
<ul>
<li> <em>\<Default\></em> if the algorithm can work using default
that any object has edges, even if their existence is not
apparent, for example, a sphere has 4 edges). Note that the
choice of hypotheses and lower dimension algorithms depends on
- the higher dimension algorithm.
+ the higher dimension algorithm.
+
+ If you wish you can select different algorithms and/or hypotheses
+ for meshing some parts of your CAD model by \ref constructing_submeshes_page.
Some algorithms generate mesh of several dimensions, while others
produce mesh of only one dimension. In the latter case there must
It contains:
<ul>
+ <li>a mesh name (<em>Mesh_mechanic</em>);
<li>a reference to the geometrical object on the basis of
- which the mesh has been constructed;</li>
+ which the mesh has been constructed (\a mechanic);</li>
<li><b>Applied hypotheses</b> folder containing the references
to the hypotheses applied at the construction of the mesh;</li>
<li><b>Applied algorithms</b> folder containing the references
\page constructing_submeshes_page Constructing sub-meshes
-Sub-mesh is a mesh on a geometrical sub-object created with algorithms
+Sub-mesh is a mesh on a geometrical sub-object created with meshing algorithms
and/or hypotheses other than the algorithms and hypotheses assigned to
the parent mesh on the parent geometrical object.
\par
It allows to define the \b Name, the parent \b Mesh and the \b
Geometry (e.g. a face if the parent mesh has been built on box) of the
-sub-mesh. You can define algorithms and hypotheses in the same way as
+sub-mesh. You can select meshing algorithms and hypotheses in the same way as
in \ref constructing_meshes_page "Create mesh" menu.
\par
\par
It contains:
<ul>
-<li>a reference to the geometrical object on the basis of which the sub-mesh has been constructed;</li>
+<li>a sub-mesh name (\a SubMeshFace1)
+<li>a reference to the geometrical object on the basis of which the
+ sub-mesh has been constructed (<em>Cylindrical Face_1</em>);</li>
<li><b>Applied hypotheses</b> folder containing the references to the
-hypotheses applied to the construction of the sub-mesh;</li>
+hypotheses selected at the construction of the sub-mesh;</li>
<li><b>Applied algorithms</b> folder containing the references to the
-algorithms applied to the construction of the sub-mesh.</li>
+algorithms selected at the construction of the sub-mesh.</li>
</ul>
<br><b>See Also</b> a sample TUI Script of a
mesh. For this, turn on the <b>Select All</b> check box. In this mode
all controls, which allow selecting the entities in other ways, are
disabled.</li>
-<li>By applying the Filter. The <b>Set filter</b> button allows to
- define the filter for selection of the elements for your group. See more
- about filters on the
- \ref selection_filter_library_page "Selection filter library" page.<br>
- If the <b>Enable manual edition</b> check box is turned off, the
- filter entirely defines the group contents. In this mode, the filter is
- applied to all elements of the mesh. If there are no entities
- corresponding to the filter, the \b Apply button is disabled.<br>
- If the <b>Enable manual edition</b> check box is turned on, the defined
- filter can be used to for selection of entities for the group.</li>
<li>By choosing entities manually with the mouse in the 3D Viewer. For
this, turn on the <b>Enable manual edition</b> check box. You can
click on an element in the 3D viewer and it will be highlighted. After
that click the \b Add button and the ID of this element will be
- added to the list.</li>
-<li>By adding entities from either a submesh or an existing
+ added to the list.<br>
+ The <b>Set filter</b> button allows to define the filter for
+ selection of the elements for your group. See more about filters on
+ the \ref selection_filter_library_page "Selection filter library"
+ page.</li>
+<li>By adding entities from either a sub-mesh or an existing
group. For this, turn on the <b>Enable manual edition</b> check
- box. <b>Select from</b> set of fields allows to select a submesh or
+ box. <b>Select from</b> set of fields allows to select a sub-mesh or
a group of the appropriate type.</li>
</ul>
In the <b>manual edition</b> mode you can
<ul>
-<li>click the \b Remove button to remove the selected elements from the list</li>
+<li>click the \b Remove button to remove the selected list items from
+ the list.</li>
<li>click the <b>Sort List</b> button to sort the list of IDs of
-mesh elements.</li>
+ mesh elements.</li>
</ul>
\image html creategroup.png
Parameters to be defined in this mode:
<ul>
- <li><b>Groups of volumes</b> (<em>mandatory</em>): list of volume
+ <li><b>Groups (faces or volumes) </b> (<em>mandatory</em>): list of mesh
groups. These groups should be disjoint, i.e. should not have shared
- volumes.</li>
+ elements.</li>
<li> If <b>Create joint elements</b> option is activated, flat
elements are created on the duplicated nodes: a triangular facet
shared by two volumes of two groups generates a flat prism, a
- quadrangular facet generates a flat hexahedron.
+ quadrangular facet generates a flat hexahedron.
+ Correspondingly 2D joint elements (null area faces) are generated
+ where edges are shared by two faces.
<br>
- The created flat volumes are stored in groups. These groups are named
+ The created flat volumes (or faces) are stored in groups. These groups are named
according to the position of the group in the list of groups: group
"j_n_p" is a group of flat elements that are built between the group \#n
and the group \#p in the group list. All the flat elements are gathered
- into the group named "joints3D". The flat element of the multiple
+ into the group named "joints3D" (correspondingly "joints2D"). The flat element of the multiple
junctions between the simple junction are stored in a group named
"jointsMultiples".</li>
- <li> If <b>On all boundaries</b> option is activated, the volumes,
- which are not included into <b>Groups of volumes</b>, are considered
+ <li> If <b>On all boundaries</b> option is activated, the volumes (or faces),
+ which are not included into <b>Groups</b> input, are considered
as another group and thus the nodes on the boundary
- between <b>Groups of volumes</b> and the remaining mesh are also
+ between <b>Groups</b> and the remaining mesh are also
duplicated.</li>
</ul>
\page editing_meshes_page Editing Meshes
-\n After you have created a mesh or submesh with definite applied
-hypotheses and algorithms you can edit your mesh by \b assigning new
-hypotheses and algorithms or \b unassigning the applied hypotheses and
-algorithms. The editing proceeds in the same way as <b>Mesh
-Creation</b>.
+\n After you have created a mesh or sub-mesh with definite applied
+meshing algorithms and hypotheses you can edit your mesh by \b assigning other
+algorithms and/or hypotheses or \b unassigning the applied hypotheses and
+algorithms. The editing proceeds in the same way as
+\ref create_mesh_anchor "Mesh Creation".
\image html createmesh-inv3.png
<br><b>See Also</b> a sample TUI Script of an
\ref tui_editing_mesh "Edit Mesh" operation.
-*/
\ No newline at end of file
+*/
<li>\subpage uniting_set_of_triangles_page "Unite several adjacent triangles".</li>
<li>\subpage changing_orientation_of_elements_page "Change orientation"
of the selected elements.</li>
-<li>\subpage reorient_faces_page "Reorient faces by vector".</li>
+<li>\subpage reorient_faces_page "Reorient faces".</li>
<li>\subpage cutting_quadrangles_page "Cut a quadrangle" into two triangles.</li>
<li>\subpage split_to_tetra_page "Split" volumic elements into tetrahedra or prisms.</li>
<li>\subpage smoothing_page "Smooth" elements, reducung distortions in
/*!
-\page reorient_faces_page Reorient faces by vector
+\page reorient_faces_page Reorient faces
-\n This operation allows changing orientation of a set of neighboring
-faces. The desired orientation is defined by a vector. Since the direction
-of face normals in the set can be even opposite, it is necessary to
-specify a control face whose normal will be compared with the vector. This
-face can be either specified explicitly or found by proximity to
-a given point.
+\n This operation allows changing orientation of faces two ways.
+<ol>
+<li> To reorient a set of neighboring faces by defining the desired
+ orientation by a vector. <br> Since the direction of face normals in
+ the set can be even opposite, it is necessary to specify a control
+ face whose normal will be compared with the vector. This face can be
+ either <ul>
+ <li> found by proximity to a given point or </li>
+ <li> specified explicitly. </li>
+</ul> </li>
+<li> To reorient faces with relation to adjacent volumes. </li>
+</ol>
Orientation of a face is changed by reverting the order of its nodes.
<em>To change orientation of faces:</em>
<ol>
-<li>In the \b Modification menu select <b>Reorient faces by
- vector</b> item or click <em>Reorient faces by
- vector</em> button in the toolbar.
+<li>In the \b Modification menu select <b>Reorient faces</b>
+ item or click <em>Reorient faces</em> button in the toolbar.
<center>
\image html reorient_faces_face.png
-<em>"Reorient faces by vector" button</em>
+<em>"Reorient faces" button</em>
</center>
The following dialog box will appear:
<center>
-\image html reorient_2d_point.png
-\image html reorient_2d_face.png
+\image html reorient_2d_point.png "First mode: to reorient adjacent faces according to a vector. The control face is found by point."
+<br>
+\image html reorient_2d_face.png "Second mode: to reorient adjacent faces according to a vector. The control face is explicitly given."
+<br>
+\image html reorient_2d_volume.png "Third mode: to reorient faces with relation to adjacent volumes."
</center>
<li>In this dialog
<ul>
-<li>Specify the way of selection of the control face: by point or
- explicitly.</li>
-<li>Select the \b Object (mesh, sub-mesh or a group of faces) containing faces to reorient in the Object Browser or in the 3D Viewer.</li>
-<li>Specify the coordinates of the \b Point by which the control face
- will be found or of the control \b Face itself. You can easy specify the \b
- Point by either picking a node in the 3D Viewer or selecting a vertex
- in the Object Browser. It is possible to pick the \b Face by mouse in
- the 3D Viewer or enter its ID.</li>
-<li>Set up the \b Direction vector to be compared with the normal of the
- control face. If you pick a node in the 3D Viewer then the \b Direction
- vector will go from the coordinate system origin to the selected node.
- If you pick two nodes (holding Shift button) then the \b Direction vector
- will go from the first to the second node.</li>
+<li>Specify either of the tree operation modes.</li>
+<li>Select the \b Object (mesh, sub-mesh or group)
+ containing faces to reorient, in the Object Browser or in the 3D
+ Viewer.</li>
+<li>To reorient according to vector: <ul>
+ <li>Specify the coordinates of the \b Point by which the control face
+ will be found or the control \b Face itself. You can easy specify the \b
+ Point by either picking a node in the 3D Viewer or selecting a vertex
+ in the Object Browser. It is possible to pick the \b Face by mouse in
+ the 3D Viewer or enter its ID.</li>
+ <li>Set up the \b Direction vector to be compared with the normal of the
+ control face. If you pick a node in the 3D Viewer then the \b Direction
+ vector will go from the coordinate system origin to the selected node.
+ If you pick two nodes (holding Shift button) then the \b Direction vector
+ will go from the first to the second node.</li> </ul> </li>
+<li>To reorient according to volumes: <ul>
+ <li>Select an object (mesh, sub-mesh or group) containing
+ reference \b Volumes, in the Object Browser or in the 3D
+ Viewer.</li>
+ <li>Specify whether face normals should point outside or inside
+ the reference volumes using <b>Face normal outside volume</b>
+ check-box.</li></ul> </li>
</ul>
</li>
</ol>
<br><b>See Also</b> a sample TUI Script of a
-\ref tui_reorient_faces "Reorient faces by vector" operation.
+\ref tui_reorient_faces "Reorient faces" operation.
*/
<br>
\anchor tui_reorient_faces
-<h3>Reorient faces by vector</h3>
+<h3>Reorient faces</h3>
\tui_script{transforming_meshes_ex13.py}
*/
in boolean byMesh)
raises ( SALOME::SALOME_Exception );
+ /*!
+ * Returns \c True if a hypothesis is assigned to a sole sub-mesh in a current Study
+ * \param [in] theHyp - the hypothesis of interest
+ * \param [out] theMesh - the sole mesh using \a theHyp
+ * \param [out] theShape - the sole geometry \a theHyp is assigned to
+ * \return boolean - \c True if \a theMesh and \a theShape are sole using \a theHyp
+ */
+ boolean GetSoleSubMeshUsingHyp( in SMESH_Hypothesis theHyp,
+ out SMESH_Mesh theMesh,
+ out GEOM::GEOM_Object theShape);
+
/*!
* Sets number of segments per diagonal of boundary box of geometry by which
* default segment length of appropriate 1D hypotheses is defined
raises ( SALOME::SALOME_Exception );
/*!
- * Return indeces of faces, edges and vertices of given sub-shapes
+ * Return indices of faces, edges and vertices of given sub-shapes
* within theMainObject
*/
long_array GetSubShapesId( in GEOM::GEOM_Object theMainObject,
/*!
* \brief Moves objects to the specified position
+ * \param what objects being moved
+ * \param where parent object where objects are moved to
+ * \param row position in the parent object's children list at which objects are moved
*
* This function is used in the drag-n-drop functionality.
- *
- * \param what objects being moved
- * \param where parent object where objects are moved to
- * \param row position in the parent object's children list at which objects are moved
*/
- void Move( in sobject_list what,
- in SALOMEDS::SObject where,
+ void Move( in sobject_list what,
+ in SALOMEDS::SObject where,
in long row );
/*!
- * Return true if algorithm can be applied
+ * Returns true if algorithm can be used to mesh a given geometry
+ * \param theAlgoType - the algorithm type
+ * \param theLibName - a name of the Plug-in library implementing the algorithm
+ * \param theShapeObject - the geometry to mesh
+ * \param toCheckAll - if \c True, returns \c True if all shapes are meshable,
+ * else, returns \c True if at least one shape is meshable
*/
boolean IsApplicable( in string theAlgoType,
in string theLibName,
typedef sequence<log_block> log_array;
struct PointStruct { double x;
- double y;
- double z; } ;
+ double y;
+ double z; } ;
typedef sequence<PointStruct> nodes_array;
struct DirStruct { PointStruct PS ; } ; // analog to OCCT gp_Vec
struct AxisStruct { double x;
- double y;
- double z;
- double vx;
- double vy;
- double vz; } ;
+ double y;
+ double z;
+ double vx;
+ double vy;
+ double vz; } ;
/*!
* Node location on a shape
*/
HYP_BAD_DIM, // bad dimension
HYP_BAD_SUBSHAPE, // shape is neither the main one, nor its sub-shape, nor a group
HYP_BAD_GEOMETRY, // geometry mismatches algorithm's expectation
- HYP_NEED_SHAPE // algorithm can work on shape only
+ HYP_NEED_SHAPE, // algorithm can work on shape only
+ HYP_INCOMPAT_HYPS // several additional hypotheses are incompatible one with other
};
/*!
* Create a group
*/
SMESH_Group CreateGroup( in ElementType elem_type,
- in string name )
+ in string name )
raises (SALOME::SALOME_Exception);
/*!
raises (SALOME::SALOME_Exception);
/*!
- * Add hypothesis to the mesh, under a particular Sub-shape
+ * Add hypothesis to the mesh, under a particular sub-shape
* (or the main shape itself)
- * The Add method is only used to prepare the build of the mesh and store
+ * This method is only used to prepare the build of the mesh and store
* the algorithms and associated parameters.
- * Actual job of mesh the shape is done by MESH_Gen.
+ * Actual job of meshing the shape is done by SMESH_Gen::Compute()
* @params
- * - aSubShape : sub-shape obtained by a shape explode in GEOM
+ * - aSubObject : sub-shape obtained by a shape explode in GEOM
* (or main shape)
- * - anHyp : hypothesis object
+ * - anHyp : an hypothesis object
* @return
- * - OK if the hypothesis is compatible with the sub-shape
- * (and all previous hypothesis on the sub-shape)
- * - NOK if the hypothesis is not compatible with the sub-shape
- * (or one previous hypothesis on the sub-shape)
- * raises exception if hypothesis has not been created
+ * - An enum item explaining what's up
+ * - anErrorText: an optional textual description of a problem (if any)
*/
Hypothesis_Status AddHypothesis(in GEOM::GEOM_Object aSubObject,
- in SMESH_Hypothesis anHyp)
+ in SMESH_Hypothesis anHyp,
+ out string anErrorText)
raises (SALOME::SALOME_Exception);
/*!
* Remove an hypothesis previouly added with AddHypothesis.
*/
Hypothesis_Status RemoveHypothesis(in GEOM::GEOM_Object aSubObject,
- in SMESH_Hypothesis anHyp)
+ in SMESH_Hypothesis anHyp)
raises (SALOME::SALOME_Exception);
/*!
* \param theFace - ID of face whose orientation is checked.
* It can be < 1 then \a thePoint is used to find a face.
* \param thePoint - is used to find a face if \a theFace < 1.
- * \return number of reoriented elements.
+ * \return number of reoriented faces.
*/
long Reorient2D(in SMESH_IDSource the2Dgroup,
in DirStruct theDirection,
in long theFace,
in PointStruct thePoint) raises (SALOME::SALOME_Exception);
+ /*!
+ * \brief Reorient faces basing on orientation of adjacent volumes.
+ * \param faces - a list of objects containing face to reorient
+ * \param volumes - an object containing volumes.
+ * \param outsideNormal - to orient faces to have their normal
+ * pointing either \a outside or \a inside the adjacent volumes.
+ * \return number of reoriented faces.
+ */
+ long Reorient2DBy3D(in ListOfIDSources faces,
+ in SMESH_IDSource volumes,
+ in boolean outsideNormal) raises (SALOME::SALOME_Exception);
/*!
* \brief Fuse neighbour triangles into quadrangles.
mesh_hypo_segment.png
mesh_hypo_volume.png
mesh_hypo_edit.png
+ mesh_plus.png
+ mesh_minus.png
mesh_info.png
advanced_mesh_info.png
standard_mesh_info.png
mesh_min_dist.png
reorient_faces_point.png
reorient_faces_face.png
+ reorient_faces_volume.png
mesh_ball.png
mesh_measure_basic_props.png
mesh_measure_length.png
</section>
<section name="windows_geometry">
- <parameter value="#00 #00 #00 #FF #00 #00 #00 #00 #FD #00 #00 #00 #02 #00 #00 #00 #00 #00 #00 #01 #00 #00 #00 #02 #44 #FC #02 #00 #00 #00 #01 #FC #00 #00 #00 #7B #00 #00 #02 #44 #00 #00 #00 #97 #01 #00 #00 #14 #FA #00 #00 #00 #00 #01 #00 #00 #00 #02 #FB #00 #00 #00 #10 #00 #77 #00 #69 #00 #6E #00 #64 #00 #6F #00 #77 #00 #5F #00 #30 #01 #00 #00 #00 #00 #FF #FF #FF #FF #00 #00 #00 #46 #00 #FF #FF #FF #FB #00 #00 #00 #10 #00 #77 #00 #69 #00 #6E #00 #64 #00 #6F #00 #77 #00 #5F #00 #33 #01 #00 #00 #00 #00 #00 #00 #01 #00 #00 #00 #00 #C0 #00 #FF #FF #FF #00 #00 #00 #03 #00 #00 #05 #40 #00 #00 #00 #53 #FC #01 #00 #00 #00 #01 #FB #00 #00 #00 #10 #00 #77 #00 #69 #00 #6E #00 #64 #00 #6F #00 #77 #00 #5F #00 #31 #01 #00 #00 #00 #00 #00 #00 #05 #40 #00 #00 #00 #46 #00 #FF #FF #FF #00 #00 #04 #38 #00 #00 #02 #44 #00 #00 #00 #04 #00 #00 #00 #04 #00 #00 #00 #08 #00 #00 #00 #08 #FC #00 #00 #00 #05 #00 #00 #00 #02 #00 #00 #00 #02 #00 #00 #00 #10 #00 #53 #00 #74 #00 #61 #00 #6E #00 #64 #00 #61 #00 #72 #00 #64 #01 #00 #00 #00 #00 #FF #FF #FF #FF #00 #00 #00 #00 #00 #00 #00 #00 #00 #00 #00 #0E #00 #4D #00 #6F #00 #64 #00 #75 #00 #6C #00 #65 #00 #73 #01 #00 #00 #00 #CE #FF #FF #FF #FF #00 #00 #00 #00 #00 #00 #00 #00 #00 #00 #00 #02 #00 #00 #00 #07 #00 #00 #00 #2A #00 #4E #00 #6F #00 #64 #00 #65 #00 #20 #00 #43 #00 #6F #00 #6E #00 #74 #00 #72 #00 #6F #00 #6C #00 #73 #00 #20 #00 #54 #00 #6F #00 #6F #00 #6C #00 #62 #00 #61 #00 #72 #00 #00 #00 #02 #01 #FF #FF #FF #FF #00 #00 #00 #00 #00 #00 #00 #00 #00 #00 #00 #2A #00 #45 #00 #64 #00 #67 #00 #65 #00 #20 #00 #43 #00 #6F #00 #6E #00 #74 #00 #72 #00 #6F #00 #6C #00 #73 #00 #20 #00 #54 #00 #6F #00 #6F #00 #6C #00 #62 #00 #61 #00 #72 #00 #00 #00 #02 #4D #FF #FF #FF #FF #00 #00 #00 #00 #00 #00 #00 #00 #00 #00 #00 #2A #00 #46 #00 #61 #00 #63 #00 #65 #00 #20 #00 #43 #00 #6F #00 #6E #00 #74 #00 #72 #00 #6F #00 #6C #00 #73 #00 #20 #00 #54 #00 #6F #00 #6F #00 #6C #00 #62 #00 #61 #00 #72 #00 #00 #00 #02 #F6 #00 #00 #02 #4A #00 #00 #00 #00 #00 #00 #00 #00 #00 #00 #00 #18 #00 #4D #00 #65 #00 #73 #00 #68 #00 #20 #00 #54 #00 #6F #00 #6F #00 #6C #00 #62 #00 #61 #00 #72 #01 #00 #00 #00 #00 #FF #FF #FF #FF #00 #00 #00 #00 #00 #00 #00 #00 #00 #00 #00 #26 #00 #41 #00 #64 #00 #64 #00 #20 #00 #45 #00 #6C #00 #65 #00 #6D #00 #65 #00 #6E #00 #74 #00 #20 #00 #54 #00 #6F #00 #6F #00 #6C #00 #62 #00 #61 #00 #72 #01 #00 #00 #01 #2B #FF #FF #FF #FF #00 #00 #00 #00 #00 #00 #00 #00 #00 #00 #00 #3C #00 #41 #00 #64 #00 #64 #00 #20 #00 #4E #00 #6F #00 #6E #00 #20 #00 #4C #00 #69 #00 #6E #00 #65 #00 #61 #00 #72 #00 #20 #00 #45 #00 #6C #00 #65 #00 #6D #00 #65 #00 #6E #00 #74 #00 #20 #00 #54 #00 #6F #00 #6F #00 #6C #00 #62 #00 #61 #00 #72 #01 #00 #00 #02 #EB #FF #FF #FF #FF #00 #00 #00 #00 #00 #00 #00 #00 #00 #00 #00 #1A #00 #47 #00 #72 #00 #6F #00 #75 #00 #70 #00 #20 #00 #54 #00 #6F #00 #6F #00 #6C #00 #62 #00 #61 #00 #72 #01 #00 #00 #04 #2F #00 #00 #01 #3E #00 #00 #00 #00 #00 #00 #00 #00 #00 #00 #00 #02 #00 #00 #00 #01 #00 #00 #00 #2E #00 #56 #00 #6F #00 #6C #00 #75 #00 #6D #00 #65 #00 #20 #00 #43 #00 #6F #00 #6E #00 #74 #00 #72 #00 #6F #00 #6C #00 #73 #00 #20 #00 #54 #00 #6F #00 #6F #00 #6C #00 #62 #00 #61 #00 #72 #00 #00 #00 #00 #00 #FF #FF #FF #FF #00 #00 #00 #00 #00 #00 #00 #00 #00 #00 #00 #02 #00 #00 #00 #00 #00 #00 #00 #02 #00 #00 #00 #07 #00 #00 #00 #1C #00 #52 #00 #65 #00 #6D #00 #6F #00 #76 #00 #65 #00 #20 #00 #54 #00 #6F #00 #6F #00 #6C #00 #62 #00 #61 #00 #72 #01 #00 #00 #00 #00 #FF #FF #FF #FF #00 #00 #00 #00 #00 #00 #00 #00 #00 #00 #00 #2C #00 #54 #00 #72 #00 #61 #00 #6E #00 #73 #00 #66 #00 #6F #00 #72 #00 #6D #00 #61 #00 #74 #00 #69 #00 #6F #00 #6E #00 #20 #00 #54 #00 #6F #00 #6F #00 #6C #00 #62 #00 #61 #00 #72 #01 #00 #00 #00 #8A #FF #FF #FF #FF #00 #00 #00 #00 #00 #00 #00 #00 #00 #00 #00 #28 #00 #4D #00 #6F #00 #64 #00 #69 #00 #66 #00 #69 #00 #63 #00 #61 #00 #74 #00 #69 #00 #6F #00 #6E #00 #20 #00 #54 #00 #6F #00 #6F #00 #6C #00 #62 #00 #61 #00 #72 #01 #00 #00 #01 #90 #FF #FF #FF #FF #00 #00 #00 #00 #00 #00 #00 #00 #00 #00 #00 #26 #00 #49 #00 #6E #00 #66 #00 #6F #00 #72 #00 #6D #00 #61 #00 #74 #00 #69 #00 #6F #00 #6E #00 #20 #00 #54 #00 #6F #00 #6F #00 #6C #00 #62 #00 #61 #00 #72 #01 #00 #00 #03 #6F #FF #FF #FF #FF #00 #00 #00 #00 #00 #00 #00 #00 #00 #00 #00 #26 #00 #52 #00 #65 #00 #6E #00 #75 #00 #6D #00 #62 #00 #65 #00 #72 #00 #69 #00 #6E #00 #67 #00 #20 #00 #54 #00 #6F #00 #6F #00 #6C #00 #62 #00 #61 #00 #72 #01 #00 #00 #03 #BB #FF #FF #FF #FF #00 #00 #00 #00 #00 #00 #00 #00 #00 #00 #00 #28 #00 #4D #00 #65 #00 #61 #00 #73 #00 #75 #00 #72 #00 #65 #00 #6D #00 #65 #00 #6E #00 #74 #00 #73 #00 #20 #00 #54 #00 #6F #00 #6F #00 #6C #00 #62 #00 #61 #00 #72 #01 #00 #00 #04 #07 #FF #FF #FF #FF #00 #00 #00 #00 #00 #00 #00 #00 #00 #00 #00 #28 #00 #44 #00 #69 #00 #73 #00 #70 #00 #6C #00 #61 #00 #79 #00 #20 #00 #4D #00 #6F #00 #64 #00 #65 #00 #20 #00 #54 #00 #6F #00 #6F #00 #6C #00 #62 #00 #61 #00 #72 #01 #00 #00 #04 #34 #00 #00 #01 #0C #00 #00 #00 #00 #00 #00 #00 #00" name="SMESH"/>
+ <parameter name="SMESH" value="#00 #00 #00 #FF #00 #00 #00 #00 #FD #00 #00 #00 #02 #00 #00 #00 #00 #00 #00 #01 #00 #00 #00 #02 #49 #FC #02 #00 #00 #00 #02 #FC #00 #00 #00 #7B #00 #00 #02 #49 #00 #00 #00 #97 #01 #00 #00 #14 #FA #00 #00 #00 #00 #01 #00 #00 #00 #02 #FB #00 #00 #00 #22 #00 #6F #00 #62 #00 #6A #00 #65 #00 #63 #00 #74 #00 #42 #00 #72 #00 #6F #00 #77 #00 #73 #00 #65 #00 #72 #00 #44 #00 #6F #00 #63 #00 #6B #01 #00 #00 #00 #00 #FF #FF #FF #FF #00 #00 #00 #46 #00 #FF #FF #FF #FB #00 #00 #00 #18 #00 #6E #00 #6F #00 #74 #00 #65 #00 #42 #00 #6F #00 #6F #00 #6B #00 #44 #00 #6F #00 #63 #00 #6B #01 #00 #00 #00 #00 #00 #00 #01 #00 #00 #00 #00 #C0 #00 #FF #FF #FF #FB #00 #00 #00 #36 #00 #67 #00 #65 #00 #6F #00 #6D #00 #43 #00 #72 #00 #65 #00 #61 #00 #74 #00 #69 #00 #6F #00 #6E #00 #49 #00 #6E #00 #66 #00 #6F #00 #72 #00 #6D #00 #61 #00 #74 #00 #69 #00 #6F #00 #6E #00 #44 #00 #6F #00 #63 #00 #6B #00 #00 #00 #02 #1F #00 #00 #00 #A5 #00 #00 #00 #00 #00 #00 #00 #00 #00 #00 #00 #03 #00 #00 #05 #40 #00 #00 #00 #53 #FC #01 #00 #00 #00 #01 #FB #00 #00 #00 #22 #00 #70 #00 #79 #00 #74 #00 #68 #00 #6F #00 #6E #00 #43 #00 #6F #00 #6E #00 #73 #00 #6F #00 #6C #00 #65 #00 #44 #00 #6F #00 #63 #00 #6B #01 #00 #00 #00 #00 #00 #00 #05 #40 #00 #00 #00 #46 #00 #FF #FF #FF #00 #00 #04 #38 #00 #00 #02 #49 #00 #00 #00 #04 #00 #00 #00 #04 #00 #00 #00 #08 #00 #00 #00 #08 #FC #00 #00 #00 #06 #00 #00 #00 #02 #00 #00 #00 #02 #00 #00 #00 #1C #00 #53 #00 #61 #00 #6C #00 #6F #00 #6D #00 #65 #00 #53 #00 #74 #00 #61 #00 #6E #00 #64 #00 #61 #00 #72 #00 #64 #01 #00 #00 #00 #00 #FF #FF #FF #FF #00 #00 #00 #00 #00 #00 #00 #00 #00 #00 #00 #1A #00 #53 #00 #61 #00 #6C #00 #6F #00 #6D #00 #65 #00 #4D #00 #6F #00 #64 #00 #75 #00 #6C #00 #65 #00 #73 #01 #00 #00 #00 #CE #FF #FF #FF #FF #00 #00 #00 #00 #00 #00 #00 #00 #00 #00 #00 #02 #00 #00 #00 #07 #00 #00 #00 #12 #00 #47 #00 #45 #00 #4F #00 #4D #00 #42 #00 #61 #00 #73 #00 #69 #00 #63 #00 #00 #00 #00 #00 #FF #FF #FF #FF #00 #00 #00 #00 #00 #00 #00 #00 #00 #00 #00 #1C #00 #47 #00 #45 #00 #4F #00 #4D #00 #50 #00 #72 #00 #69 #00 #6D #00 #69 #00 #74 #00 #69 #00 #76 #00 #65 #00 #73 #00 #00 #00 #00 #0E #FF #FF #FF #FF #00 #00 #00 #00 #00 #00 #00 #00 #00 #00 #00 #2A #00 #47 #00 #45 #00 #4F #00 #4D #00 #42 #00 #6F #00 #6F #00 #6C #00 #65 #00 #61 #00 #6E #00 #4F #00 #70 #00 #65 #00 #72 #00 #61 #00 #74 #00 #69 #00 #6F #00 #6E #00 #73 #00 #00 #00 #00 #1C #FF #FF #FF #FF #00 #00 #00 #00 #00 #00 #00 #00 #00 #00 #00 #16 #00 #54 #00 #4F #00 #4F #00 #4C #00 #5F #00 #42 #00 #4C #00 #4F #00 #43 #00 #4B #00 #53 #00 #00 #00 #00 #2A #FF #FF #FF #FF #00 #00 #00 #00 #00 #00 #00 #00 #00 #00 #00 #18 #00 #47 #00 #45 #00 #4F #00 #4D #00 #50 #00 #69 #00 #63 #00 #74 #00 #75 #00 #72 #00 #65 #00 #73 #00 #00 #00 #00 #38 #FF #FF #FF #FF #00 #00 #00 #00 #00 #00 #00 #00 #00 #00 #00 #1A #00 #54 #00 #4F #00 #4F #00 #4C #00 #5F #00 #41 #00 #44 #00 #56 #00 #41 #00 #4E #00 #43 #00 #45 #00 #44 #00 #00 #00 #00 #46 #FF #FF #FF #FF #00 #00 #00 #00 #00 #00 #00 #00 #00 #00 #00 #26 #00 #47 #00 #45 #00 #4F #00 #4D #00 #49 #00 #6D #00 #70 #00 #6F #00 #72 #00 #74 #00 #45 #00 #78 #00 #70 #00 #6F #00 #72 #00 #74 #00 #58 #00 #41 #00 #4F #00 #00 #00 #00 #54 #00 #00 #01 #69 #00 #00 #00 #00 #00 #00 #00 #00 #00 #00 #00 #02 #00 #00 #00 #05 #00 #00 #00 #24 #00 #47 #00 #45 #00 #4F #00 #4D #00 #54 #00 #72 #00 #61 #00 #6E #00 #73 #00 #66 #00 #6F #00 #72 #00 #6D #00 #61 #00 #74 #00 #69 #00 #6F #00 #6E #00 #00 #00 #00 #00 #FF #FF #FF #FF #00 #00 #00 #00 #00 #00 #00 #00 #00 #00 #00 #1C #00 #47 #00 #45 #00 #4F #00 #4D #00 #4F #00 #70 #00 #65 #00 #72 #00 #61 #00 #74 #00 #69 #00 #6F #00 #6E #00 #73 #00 #00 #00 #00 #0E #FF #FF #FF #FF #00 #00 #00 #00 #00 #00 #00 #00 #00 #00 #00 #1C #00 #47 #00 #45 #00 #4F #00 #4D #00 #47 #00 #65 #00 #6E #00 #65 #00 #72 #00 #61 #00 #74 #00 #69 #00 #6F #00 #6E #00 #00 #00 #00 #1C #FF #FF #FF #FF #00 #00 #00 #00 #00 #00 #00 #00 #00 #00 #00 #12 #00 #47 #00 #45 #00 #4F #00 #4D #00 #42 #00 #75 #00 #69 #00 #6C #00 #64 #00 #00 #00 #00 #2A #FF #FF #FF #FF #00 #00 #00 #00 #00 #00 #00 #00 #00 #00 #00 #20 #00 #47 #00 #45 #00 #4F #00 #4D #00 #4D #00 #6F #00 #64 #00 #69 #00 #66 #00 #69 #00 #63 #00 #61 #00 #74 #00 #69 #00 #6F #00 #6E #00 #00 #00 #00 #38 #00 #00 #01 #FB #00 #00 #00 #00 #00 #00 #00 #00 #00 #00 #00 #02 #00 #00 #00 #05 #00 #00 #00 #18 #00 #47 #00 #45 #00 #4F #00 #4D #00 #4D #00 #65 #00 #61 #00 #73 #00 #75 #00 #72 #00 #65 #00 #73 #00 #00 #00 #00 #00 #FF #FF #FF #FF #00 #00 #00 #00 #00 #00 #00 #00 #00 #00 #00 #20 #00 #53 #00 #4D #00 #45 #00 #53 #00 #48 #00 #4D #00 #65 #00 #73 #00 #68 #00 #54 #00 #6F #00 #6F #00 #6C #00 #62 #00 #61 #00 #72 #01 #00 #00 #00 #00 #FF #FF #FF #FF #00 #00 #00 #00 #00 #00 #00 #00 #00 #00 #00 #2C #00 #53 #00 #4D #00 #45 #00 #53 #00 #48 #00 #41 #00 #64 #00 #64 #00 #45 #00 #6C #00 #65 #00 #6D #00 #65 #00 #6E #00 #74 #00 #54 #00 #6F #00 #6F #00 #6C #00 #62 #00 #61 #00 #72 #01 #00 #00 #01 #2B #FF #FF #FF #FF #00 #00 #00 #00 #00 #00 #00 #00 #00 #00 #00 #2C #00 #53 #00 #4D #00 #45 #00 #53 #00 #48 #00 #41 #00 #64 #00 #64 #00 #45 #00 #6C #00 #65 #00 #6D #00 #65 #00 #6E #00 #74 #00 #54 #00 #6F #00 #6F #00 #6C #00 #62 #00 #61 #00 #72 #01 #00 #00 #02 #EB #FF #FF #FF #FF #00 #00 #00 #00 #00 #00 #00 #00 #00 #00 #00 #24 #00 #53 #00 #4D #00 #45 #00 #53 #00 #48 #00 #52 #00 #65 #00 #6D #00 #6F #00 #76 #00 #65 #00 #54 #00 #6F #00 #6F #00 #6C #00 #62 #00 #61 #00 #72 #01 #00 #00 #04 #2F #FF #FF #FF #FF #00 #00 #00 #00 #00 #00 #00 #00 #00 #00 #00 #02 #00 #00 #00 #07 #00 #00 #00 #2E #00 #53 #00 #4D #00 #45 #00 #53 #00 #48 #00 #49 #00 #6E #00 #66 #00 #6F #00 #72 #00 #6D #00 #61 #00 #74 #00 #69 #00 #6F #00 #6E #00 #54 #00 #6F #00 #6F #00 #6C #00 #62 #00 #61 #00 #72 #01 #00 #00 #00 #00 #FF #FF #FF #FF #00 #00 #00 #00 #00 #00 #00 #00 #00 #00 #00 #22 #00 #53 #00 #4D #00 #45 #00 #53 #00 #48 #00 #47 #00 #72 #00 #6F #00 #75 #00 #70 #00 #54 #00 #6F #00 #6F #00 #6C #00 #62 #00 #61 #00 #72 #01 #00 #00 #00 #4C #FF #FF #FF #FF #00 #00 #00 #00 #00 #00 #00 #00 #00 #00 #00 #34 #00 #53 #00 #4D #00 #45 #00 #53 #00 #48 #00 #54 #00 #72 #00 #61 #00 #6E #00 #73 #00 #66 #00 #6F #00 #72 #00 #6D #00 #61 #00 #74 #00 #69 #00 #6F #00 #6E #00 #54 #00 #6F #00 #6F #00 #6C #00 #62 #00 #61 #00 #72 #01 #00 #00 #00 #D6 #FF #FF #FF #FF #00 #00 #00 #00 #00 #00 #00 #00 #00 #00 #00 #30 #00 #53 #00 #4D #00 #45 #00 #53 #00 #48 #00 #4D #00 #6F #00 #64 #00 #69 #00 #66 #00 #69 #00 #63 #00 #61 #00 #74 #00 #69 #00 #6F #00 #6E #00 #54 #00 #6F #00 #6F #00 #6C #00 #62 #00 #61 #00 #72 #01 #00 #00 #01 #DC #FF #FF #FF #FF #00 #00 #00 #00 #00 #00 #00 #00 #00 #00 #00 #2E #00 #53 #00 #4D #00 #45 #00 #53 #00 #48 #00 #52 #00 #65 #00 #6E #00 #75 #00 #6D #00 #62 #00 #65 #00 #72 #00 #69 #00 #6E #00 #67 #00 #54 #00 #6F #00 #6F #00 #6C #00 #62 #00 #61 #00 #72 #01 #00 #00 #03 #BB #FF #FF #FF #FF #00 #00 #00 #00 #00 #00 #00 #00 #00 #00 #00 #30 #00 #53 #00 #4D #00 #45 #00 #53 #00 #48 #00 #4D #00 #65 #00 #61 #00 #73 #00 #75 #00 #72 #00 #65 #00 #6D #00 #65 #00 #6E #00 #74 #00 #73 #00 #54 #00 #6F #00 #6F #00 #6C #00 #62 #00 #61 #00 #72 #01 #00 #00 #04 #07 #FF #FF #FF #FF #00 #00 #00 #00 #00 #00 #00 #00 #00 #00 #00 #2E #00 #53 #00 #4D #00 #45 #00 #53 #00 #48 #00 #44 #00 #69 #00 #73 #00 #70 #00 #6C #00 #61 #00 #79 #00 #4D #00 #6F #00 #64 #00 #65 #00 #54 #00 #6F #00 #6F #00 #6C #00 #62 #00 #61 #00 #72 #01 #00 #00 #04 #34 #00 #00 #01 #58 #00 #00 #00 #00 #00 #00 #00 #00 #00 #00 #00 #02 #00 #00 #00 #04 #00 #00 #00 #30 #00 #53 #00 #4D #00 #45 #00 #53 #00 #48 #00 #4E #00 #6F #00 #64 #00 #65 #00 #43 #00 #6F #00 #6E #00 #74 #00 #72 #00 #6F #00 #6C #00 #73 #00 #54 #00 #6F #00 #6F #00 #6C #00 #62 #00 #61 #00 #72 #00 #00 #00 #00 #00 #FF #FF #FF #FF #00 #00 #00 #00 #00 #00 #00 #00 #00 #00 #00 #30 #00 #53 #00 #4D #00 #45 #00 #53 #00 #48 #00 #45 #00 #64 #00 #67 #00 #65 #00 #43 #00 #6F #00 #6E #00 #74 #00 #72 #00 #6F #00 #6C #00 #73 #00 #54 #00 #6F #00 #6F #00 #6C #00 #62 #00 #61 #00 #72 #00 #00 #00 #00 #00 #FF #FF #FF #FF #00 #00 #00 #00 #00 #00 #00 #00 #00 #00 #00 #30 #00 #53 #00 #4D #00 #45 #00 #53 #00 #48 #00 #46 #00 #61 #00 #63 #00 #65 #00 #43 #00 #6F #00 #6E #00 #74 #00 #72 #00 #6F #00 #6C #00 #73 #00 #54 #00 #6F #00 #6F #00 #6C #00 #62 #00 #61 #00 #72 #00 #00 #00 #00 #00 #FF #FF #FF #FF #00 #00 #00 #00 #00 #00 #00 #00 #00 #00 #00 #34 #00 #53 #00 #4D #00 #45 #00 #53 #00 #48 #00 #56 #00 #6F #00 #6C #00 #75 #00 #6D #00 #65 #00 #43 #00 #6F #00 #6E #00 #74 #00 #72 #00 #6F #00 #6C #00 #73 #00 #54 #00 #6F #00 #6F #00 #6C #00 #62 #00 #61 #00 #72 #00 #00 #00 #00 #00 #00 #00 #02 #AA #00 #00 #00 #00 #00 #00 #00 #00"/>
</section>
<section name="windows_visibility">
- <parameter value="#00 #00 #00 #00 #15 #FF #FF #FF #FF #00 #00 #00 #02 #00 #00 #00 #00 #00 #00 #01 #00 #00 #00 #02 #44 #FC #02 #00 #00 #00 #01 #FC #00 #00 #00 #7B #00 #00 #02 #44 #00 #00 #00 #97 #01 #00 #00 #14 #FA #00 #00 #00 #00 #01 #00 #00 #00 #02 #FB #00 #00 #00 #10 #00 #77 #00 #69 #00 #6E #00 #64 #00 #6F #00 #77 #00 #5F #00 #30 #01 #00 #00 #00 #00 #FF #FF #FF #FF #00 #00 #00 #46 #00 #FF #FF #FF #FB #00 #00 #00 #10 #00 #77 #00 #69 #00 #6E #00 #64 #00 #6F #00 #77 #00 #5F #00 #33 #01 #00 #00 #00 #00 #00 #00 #01 #00 #00 #00 #00 #C0 #00 #FF #FF #FF #00 #00 #00 #03 #00 #00 #05 #40 #00 #00 #00 #53 #FC #01 #00 #00 #00 #01 #FB #00 #00 #00 #10 #00 #77 #00 #69 #00 #6E #00 #64 #00 #6F #00 #77 #00 #5F #00 #31 #01 #00 #00 #00 #00 #00 #00 #05 #40 #00 #00 #00 #46 #00 #FF #FF #FF #00 #00 #04 #38 #00 #00 #02 #44 #00 #00 #00 #04 #00 #00 #00 #04 #00 #00 #00 #08 #00 #00 #00 #08 #FC #00 #00 #00 #05 #00 #00 #00 #02 #00 #00 #00 #02 #00 #00 #00 #10 #00 #53 #00 #74 #00 #61 #00 #6E #00 #64 #00 #61 #00 #72 #00 #64 #01 #00 #00 #00 #00 #FF #FF #FF #FF #00 #00 #00 #00 #00 #00 #00 #00 #00 #00 #00 #0E #00 #4D #00 #6F #00 #64 #00 #75 #00 #6C #00 #65 #00 #73 #01 #00 #00 #00 #CE #FF #FF #FF #FF #00 #00 #00 #00 #00 #00 #00 #00 #00 #00 #00 #02 #00 #00 #00 #07 #00 #00 #00 #2A #00 #4E #00 #6F #00 #64 #00 #65 #00 #20 #00 #43 #00 #6F #00 #6E #00 #74 #00 #72 #00 #6F #00 #6C #00 #73 #00 #20 #00 #54 #00 #6F #00 #6F #00 #6C #00 #62 #00 #61 #00 #72 #00 #00 #00 #02 #01 #FF #FF #FF #FF #00 #00 #00 #00 #00 #00 #00 #00 #00 #00 #00 #2A #00 #45 #00 #64 #00 #67 #00 #65 #00 #20 #00 #43 #00 #6F #00 #6E #00 #74 #00 #72 #00 #6F #00 #6C #00 #73 #00 #20 #00 #54 #00 #6F #00 #6F #00 #6C #00 #62 #00 #61 #00 #72 #00 #00 #00 #02 #4D #FF #FF #FF #FF #00 #00 #00 #00 #00 #00 #00 #00 #00 #00 #00 #2A #00 #46 #00 #61 #00 #63 #00 #65 #00 #20 #00 #43 #00 #6F #00 #6E #00 #74 #00 #72 #00 #6F #00 #6C #00 #73 #00 #20 #00 #54 #00 #6F #00 #6F #00 #6C #00 #62 #00 #61 #00 #72 #00 #00 #00 #02 #F6 #00 #00 #02 #4A #00 #00 #00 #00 #00 #00 #00 #00 #00 #00 #00 #18 #00 #4D #00 #65 #00 #73 #00 #68 #00 #20 #00 #54 #00 #6F #00 #6F #00 #6C #00 #62 #00 #61 #00 #72 #01 #00 #00 #00 #00 #00 #26 #00 #41 #00 #64 #00 #64 #00 #20 #00 #45 #00 #6C #00 #65 #00 #6D #00 #65 #00 #6E #00 #74 #00 #20 #00 #54 #00 #6F #00 #6F #00 #6C #00 #62 #00 #61 #00 #72 #01 #00 #00 #00 #3C #00 #41 #00 #64 #00 #64 #00 #20 #00 #4E #00 #6F #00 #6E #00 #20 #00 #4C #00 #69 #00 #6E #00 #65 #00 #61 #00 #72 #00 #20 #00 #45 #00 #6C #00 #65 #00 #6D #00 #65 #00 #6E #00 #74 #00 #20 #00 #54 #00 #6F #00 #6F #00 #6C #00 #62 #00 #61 #00 #72 #01 #00 #00 #00 #28 #00 #44 #00 #69 #00 #73 #00 #70 #00 #6C #00 #61 #00 #79 #00 #20 #00 #4D #00 #6F #00 #64 #00 #65 #00 #20 #00 #54 #00 #6F #00 #6F #00 #6C #00 #62 #00 #61 #00 #72 #01 #00 #00 #00 #2A #00 #45 #00 #64 #00 #67 #00 #65 #00 #20 #00 #43 #00 #6F #00 #6E #00 #74 #00 #72 #00 #6F #00 #6C #00 #73 #00 #20 #00 #54 #00 #6F #00 #6F #00 #6C #00 #62 #00 #61 #00 #72 #00 #00 #00 #00 #2A #00 #46 #00 #61 #00 #63 #00 #65 #00 #20 #00 #43 #00 #6F #00 #6E #00 #74 #00 #72 #00 #6F #00 #6C #00 #73 #00 #20 #00 #54 #00 #6F #00 #6F #00 #6C #00 #62 #00 #61 #00 #72 #00 #00 #00 #00 #1A #00 #47 #00 #72 #00 #6F #00 #75 #00 #70 #00 #20 #00 #54 #00 #6F #00 #6F #00 #6C #00 #62 #00 #61 #00 #72 #01 #00 #00 #00 #26 #00 #49 #00 #6E #00 #66 #00 #6F #00 #72 #00 #6D #00 #61 #00 #74 #00 #69 #00 #6F #00 #6E #00 #20 #00 #54 #00 #6F #00 #6F #00 #6C #00 #62 #00 #61 #00 #72 #01 #00 #00 #00 #28 #00 #4D #00 #65 #00 #61 #00 #73 #00 #75 #00 #72 #00 #65 #00 #6D #00 #65 #00 #6E #00 #74 #00 #73 #00 #20 #00 #54 #00 #6F #00 #6F #00 #6C #00 #62 #00 #61 #00 #72 #01 #00 #00 #00 #18 #00 #4D #00 #65 #00 #73 #00 #68 #00 #20 #00 #54 #00 #6F #00 #6F #00 #6C #00 #62 #00 #61 #00 #72 #01 #00 #00 #00 #28 #00 #4D #00 #6F #00 #64 #00 #69 #00 #66 #00 #69 #00 #63 #00 #61 #00 #74 #00 #69 #00 #6F #00 #6E #00 #20 #00 #54 #00 #6F #00 #6F #00 #6C #00 #62 #00 #61 #00 #72 #01 #00 #00 #00 #0E #00 #4D #00 #6F #00 #64 #00 #75 #00 #6C #00 #65 #00 #73 #01 #00 #00 #00 #2A #00 #4E #00 #6F #00 #64 #00 #65 #00 #20 #00 #43 #00 #6F #00 #6E #00 #74 #00 #72 #00 #6F #00 #6C #00 #73 #00 #20 #00 #54 #00 #6F #00 #6F #00 #6C #00 #62 #00 #61 #00 #72 #00 #00 #00 #00 #28 #00 #52 #00 #65 #00 #63 #00 #6F #00 #72 #00 #64 #00 #69 #00 #6E #00 #67 #00 #20 #00 #4F #00 #70 #00 #65 #00 #72 #00 #61 #00 #74 #00 #69 #00 #6F #00 #6E #00 #73 #01 #00 #00 #00 #1C #00 #52 #00 #65 #00 #6D #00 #6F #00 #76 #00 #65 #00 #20 #00 #54 #00 #6F #00 #6F #00 #6C #00 #62 #00 #61 #00 #72 #01 #00 #00 #00 #26 #00 #52 #00 #65 #00 #6E #00 #75 #00 #6D #00 #62 #00 #65 #00 #72 #00 #69 #00 #6E #00 #67 #00 #20 #00 #54 #00 #6F #00 #6F #00 #6C #00 #62 #00 #61 #00 #72 #01 #00 #00 #00 #10 #00 #53 #00 #74 #00 #61 #00 #6E #00 #64 #00 #61 #00 #72 #00 #64 #01 #00 #00 #00 #2C #00 #54 #00 #72 #00 #61 #00 #6E #00 #73 #00 #66 #00 #6F #00 #72 #00 #6D #00 #61 #00 #74 #00 #69 #00 #6F #00 #6E #00 #20 #00 #54 #00 #6F #00 #6F #00 #6C #00 #62 #00 #61 #00 #72 #01 #00 #00 #00 #1E #00 #56 #00 #69 #00 #65 #00 #77 #00 #20 #00 #4F #00 #70 #00 #65 #00 #72 #00 #61 #00 #74 #00 #69 #00 #6F #00 #6E #00 #73 #01 #00 #00 #00 #2E #00 #56 #00 #6F #00 #6C #00 #75 #00 #6D #00 #65 #00 #20 #00 #43 #00 #6F #00 #6E #00 #74 #00 #72 #00 #6F #00 #6C #00 #73 #00 #20 #00 #54 #00 #6F #00 #6F #00 #6C #00 #62 #00 #61 #00 #72 #00 #01 #00 #00 #00 #03 #00 #00 #00 #10 #00 #77 #00 #69 #00 #6E #00 #64 #00 #6F #00 #77 #00 #5F #00 #30 #01 #00 #00 #00 #10 #00 #77 #00 #69 #00 #6E #00 #64 #00 #6F #00 #77 #00 #5F #00 #31 #01 #00 #00 #00 #10 #00 #77 #00 #69 #00 #6E #00 #64 #00 #6F #00 #77 #00 #5F #00 #33 #01" name="SMESH"/>
+ <parameter name="SMESH" value="#00 #00 #00 #00 #35 #FF #FF #FF #FF #00 #00 #00 #02 #00 #00 #00 #00 #00 #00 #01 #00 #00 #00 #02 #44 #FC #02 #00 #00 #00 #01 #FC #00 #00 #00 #7B #00 #00 #02 #44 #00 #00 #00 #97 #01 #00 #00 #14 #FA #00 #00 #00 #00 #01 #00 #00 #00 #02 #FB #00 #00 #00 #10 #00 #77 #00 #69 #00 #6E #00 #64 #00 #6F #00 #77 #00 #5F #00 #30 #01 #00 #00 #00 #00 #FF #FF #FF #FF #00 #00 #00 #46 #00 #FF #FF #FF #FB #00 #00 #00 #10 #00 #77 #00 #69 #00 #6E #00 #64 #00 #6F #00 #77 #00 #5F #00 #33 #01 #00 #00 #00 #00 #00 #00 #01 #00 #00 #00 #00 #C0 #00 #FF #FF #FF #00 #00 #00 #03 #00 #00 #05 #40 #00 #00 #00 #53 #FC #01 #00 #00 #00 #01 #FB #00 #00 #00 #10 #00 #77 #00 #69 #00 #6E #00 #64 #00 #6F #00 #77 #00 #5F #00 #31 #01 #00 #00 #00 #00 #00 #00 #05 #40 #00 #00 #00 #46 #00 #FF #FF #FF #00 #00 #04 #38 #00 #00 #02 #44 #00 #00 #00 #04 #00 #00 #00 #04 #00 #00 #00 #08 #00 #00 #00 #08 #FC #00 #00 #00 #05 #00 #00 #00 #02 #00 #00 #00 #02 #00 #00 #00 #10 #00 #53 #00 #74 #00 #61 #00 #6E #00 #64 #00 #61 #00 #72 #00 #64 #01 #00 #00 #00 #00 #FF #FF #FF #FF #00 #00 #00 #00 #00 #00 #00 #00 #00 #00 #00 #0E #00 #4D #00 #6F #00 #64 #00 #75 #00 #6C #00 #65 #00 #73 #01 #00 #00 #00 #CE #FF #FF #FF #FF #00 #00 #00 #00 #00 #00 #00 #00 #00 #00 #00 #02 #00 #00 #00 #07 #00 #00 #00 #2A #00 #4E #00 #6F #00 #64 #00 #65 #00 #20 #00 #43 #00 #6F #00 #6E #00 #74 #00 #72 #00 #6F #00 #6C #00 #73 #00 #20 #00 #54 #00 #6F #00 #6F #00 #6C #00 #62 #00 #61 #00 #72 #00 #00 #00 #02 #01 #FF #FF #FF #FF #00 #00 #00 #00 #00 #00 #00 #00 #00 #00 #00 #2A #00 #45 #00 #64 #00 #67 #00 #65 #00 #20 #00 #43 #00 #6F #00 #6E #00 #74 #00 #72 #00 #6F #00 #6C #00 #73 #00 #20 #00 #54 #00 #6F #00 #6F #00 #6C #00 #62 #00 #61 #00 #72 #00 #00 #00 #02 #4D #FF #FF #FF #FF #00 #00 #00 #00 #00 #00 #00 #00 #00 #00 #00 #2A #00 #46 #00 #61 #00 #63 #00 #65 #00 #20 #00 #43 #00 #6F #00 #6E #00 #74 #00 #72 #00 #6F #00 #6C #00 #73 #00 #20 #00 #54 #00 #6F #00 #6F #00 #6C #00 #62 #00 #61 #00 #72 #00 #00 #00 #02 #F6 #00 #00 #02 #4A #00 #00 #00 #00 #00 #00 #00 #00 #00 #00 #00 #18 #00 #4D #00 #65 #00 #73 #00 #68 #00 #20 #00 #54 #00 #6F #00 #6F #00 #6C #00 #62 #00 #61 #00 #72 #01 #00 #00 #00 #00 #00 #26 #00 #41 #00 #64 #00 #64 #00 #20 #00 #45 #00 #6C #00 #65 #00 #6D #00 #65 #00 #6E #00 #74 #00 #20 #00 #54 #00 #6F #00 #6F #00 #6C #00 #62 #00 #61 #00 #72 #01 #00 #00 #00 #3C #00 #41 #00 #64 #00 #64 #00 #20 #00 #4E #00 #6F #00 #6E #00 #20 #00 #4C #00 #69 #00 #6E #00 #65 #00 #61 #00 #72 #00 #20 #00 #45 #00 #6C #00 #65 #00 #6D #00 #65 #00 #6E #00 #74 #00 #20 #00 #54 #00 #6F #00 #6F #00 #6C #00 #62 #00 #61 #00 #72 #01 #00 #00 #00 #28 #00 #44 #00 #69 #00 #73 #00 #70 #00 #6C #00 #61 #00 #79 #00 #20 #00 #4D #00 #6F #00 #64 #00 #65 #00 #20 #00 #54 #00 #6F #00 #6F #00 #6C #00 #62 #00 #61 #00 #72 #01 #00 #00 #00 #2A #00 #45 #00 #64 #00 #67 #00 #65 #00 #20 #00 #43 #00 #6F #00 #6E #00 #74 #00 #72 #00 #6F #00 #6C #00 #73 #00 #20 #00 #54 #00 #6F #00 #6F #00 #6C #00 #62 #00 #61 #00 #72 #00 #00 #00 #00 #2A #00 #46 #00 #61 #00 #63 #00 #65 #00 #20 #00 #43 #00 #6F #00 #6E #00 #74 #00 #72 #00 #6F #00 #6C #00 #73 #00 #20 #00 #54 #00 #6F #00 #6F #00 #6C #00 #62 #00 #61 #00 #72 #00 #00 #00 #00 #12 #00 #47 #00 #45 #00 #4F #00 #4D #00 #42 #00 #61 #00 #73 #00 #69 #00 #63 #01 #00 #00 #00 #2A #00 #47 #00 #45 #00 #4F #00 #4D #00 #42 #00 #6F #00 #6F #00 #6C #00 #65 #00 #61 #00 #6E #00 #4F #00 #70 #00 #65 #00 #72 #00 #61 #00 #74 #00 #69 #00 #6F #00 #6E #00 #73 #01 #00 #00 #00 #12 #00 #47 #00 #45 #00 #4F #00 #4D #00 #42 #00 #75 #00 #69 #00 #6C #00 #64 #01 #00 #00 #00 #1C #00 #47 #00 #45 #00 #4F #00 #4D #00 #47 #00 #65 #00 #6E #00 #65 #00 #72 #00 #61 #00 #74 #00 #69 #00 #6F #00 #6E #01 #00 #00 #00 #26 #00 #47 #00 #45 #00 #4F #00 #4D #00 #49 #00 #6D #00 #70 #00 #6F #00 #72 #00 #74 #00 #45 #00 #78 #00 #70 #00 #6F #00 #72 #00 #74 #00 #58 #00 #41 #00 #4F #01 #00 #00 #00 #18 #00 #47 #00 #45 #00 #4F #00 #4D #00 #4D #00 #65 #00 #61 #00 #73 #00 #75 #00 #72 #00 #65 #00 #73 #00 #00 #00 #00 #20 #00 #47 #00 #45 #00 #4F #00 #4D #00 #4D #00 #6F #00 #64 #00 #69 #00 #66 #00 #69 #00 #63 #00 #61 #00 #74 #00 #69 #00 #6F #00 #6E #01 #00 #00 #00 #1C #00 #47 #00 #45 #00 #4F #00 #4D #00 #4F #00 #70 #00 #65 #00 #72 #00 #61 #00 #74 #00 #69 #00 #6F #00 #6E #00 #73 #01 #00 #00 #00 #18 #00 #47 #00 #45 #00 #4F #00 #4D #00 #50 #00 #69 #00 #63 #00 #74 #00 #75 #00 #72 #00 #65 #00 #73 #01 #00 #00 #00 #1C #00 #47 #00 #45 #00 #4F #00 #4D #00 #50 #00 #72 #00 #69 #00 #6D #00 #69 #00 #74 #00 #69 #00 #76 #00 #65 #00 #73 #01 #00 #00 #00 #24 #00 #47 #00 #45 #00 #4F #00 #4D #00 #54 #00 #72 #00 #61 #00 #6E #00 #73 #00 #66 #00 #6F #00 #72 #00 #6D #00 #61 #00 #74 #00 #69 #00 #6F #00 #6E #01 #00 #00 #00 #1A #00 #47 #00 #72 #00 #6F #00 #75 #00 #70 #00 #20 #00 #54 #00 #6F #00 #6F #00 #6C #00 #62 #00 #61 #00 #72 #01 #00 #00 #00 #26 #00 #49 #00 #6E #00 #66 #00 #6F #00 #72 #00 #6D #00 #61 #00 #74 #00 #69 #00 #6F #00 #6E #00 #20 #00 #54 #00 #6F #00 #6F #00 #6C #00 #62 #00 #61 #00 #72 #01 #00 #00 #00 #28 #00 #4D #00 #65 #00 #61 #00 #73 #00 #75 #00 #72 #00 #65 #00 #6D #00 #65 #00 #6E #00 #74 #00 #73 #00 #20 #00 #54 #00 #6F #00 #6F #00 #6C #00 #62 #00 #61 #00 #72 #01 #00 #00 #00 #18 #00 #4D #00 #65 #00 #73 #00 #68 #00 #20 #00 #54 #00 #6F #00 #6F #00 #6C #00 #62 #00 #61 #00 #72 #01 #00 #00 #00 #28 #00 #4D #00 #6F #00 #64 #00 #69 #00 #66 #00 #69 #00 #63 #00 #61 #00 #74 #00 #69 #00 #6F #00 #6E #00 #20 #00 #54 #00 #6F #00 #6F #00 #6C #00 #62 #00 #61 #00 #72 #01 #00 #00 #00 #0E #00 #4D #00 #6F #00 #64 #00 #75 #00 #6C #00 #65 #00 #73 #01 #00 #00 #00 #2A #00 #4E #00 #6F #00 #64 #00 #65 #00 #20 #00 #43 #00 #6F #00 #6E #00 #74 #00 #72 #00 #6F #00 #6C #00 #73 #00 #20 #00 #54 #00 #6F #00 #6F #00 #6C #00 #62 #00 #61 #00 #72 #00 #00 #00 #00 #32 #00 #4F #00 #43 #00 #43 #00 #56 #00 #69 #00 #65 #00 #77 #00 #65 #00 #72 #00 #33 #00 #44 #00 #56 #00 #69 #00 #65 #00 #77 #00 #4F #00 #70 #00 #65 #00 #72 #00 #61 #00 #74 #00 #69 #00 #6F #00 #6E #00 #73 #01 #00 #00 #00 #28 #00 #52 #00 #65 #00 #63 #00 #6F #00 #72 #00 #64 #00 #69 #00 #6E #00 #67 #00 #20 #00 #4F #00 #70 #00 #65 #00 #72 #00 #61 #00 #74 #00 #69 #00 #6F #00 #6E #00 #73 #01 #00 #00 #00 #1C #00 #52 #00 #65 #00 #6D #00 #6F #00 #76 #00 #65 #00 #20 #00 #54 #00 #6F #00 #6F #00 #6C #00 #62 #00 #61 #00 #72 #01 #00 #00 #00 #26 #00 #52 #00 #65 #00 #6E #00 #75 #00 #6D #00 #62 #00 #65 #00 #72 #00 #69 #00 #6E #00 #67 #00 #20 #00 #54 #00 #6F #00 #6F #00 #6C #00 #62 #00 #61 #00 #72 #01 #00 #00 #00 #2C #00 #53 #00 #4D #00 #45 #00 #53 #00 #48 #00 #41 #00 #64 #00 #64 #00 #45 #00 #6C #00 #65 #00 #6D #00 #65 #00 #6E #00 #74 #00 #54 #00 #6F #00 #6F #00 #6C #00 #62 #00 #61 #00 #72 #01 #00 #00 #00 #2E #00 #53 #00 #4D #00 #45 #00 #53 #00 #48 #00 #44 #00 #69 #00 #73 #00 #70 #00 #6C #00 #61 #00 #79 #00 #4D #00 #6F #00 #64 #00 #65 #00 #54 #00 #6F #00 #6F #00 #6C #00 #62 #00 #61 #00 #72 #01 #00 #00 #00 #30 #00 #53 #00 #4D #00 #45 #00 #53 #00 #48 #00 #45 #00 #64 #00 #67 #00 #65 #00 #43 #00 #6F #00 #6E #00 #74 #00 #72 #00 #6F #00 #6C #00 #73 #00 #54 #00 #6F #00 #6F #00 #6C #00 #62 #00 #61 #00 #72 #00 #00 #00 #00 #30 #00 #53 #00 #4D #00 #45 #00 #53 #00 #48 #00 #46 #00 #61 #00 #63 #00 #65 #00 #43 #00 #6F #00 #6E #00 #74 #00 #72 #00 #6F #00 #6C #00 #73 #00 #54 #00 #6F #00 #6F #00 #6C #00 #62 #00 #61 #00 #72 #00 #00 #00 #00 #22 #00 #53 #00 #4D #00 #45 #00 #53 #00 #48 #00 #47 #00 #72 #00 #6F #00 #75 #00 #70 #00 #54 #00 #6F #00 #6F #00 #6C #00 #62 #00 #61 #00 #72 #01 #00 #00 #00 #2E #00 #53 #00 #4D #00 #45 #00 #53 #00 #48 #00 #49 #00 #6E #00 #66 #00 #6F #00 #72 #00 #6D #00 #61 #00 #74 #00 #69 #00 #6F #00 #6E #00 #54 #00 #6F #00 #6F #00 #6C #00 #62 #00 #61 #00 #72 #01 #00 #00 #00 #30 #00 #53 #00 #4D #00 #45 #00 #53 #00 #48 #00 #4D #00 #65 #00 #61 #00 #73 #00 #75 #00 #72 #00 #65 #00 #6D #00 #65 #00 #6E #00 #74 #00 #73 #00 #54 #00 #6F #00 #6F #00 #6C #00 #62 #00 #61 #00 #72 #01 #00 #00 #00 #20 #00 #53 #00 #4D #00 #45 #00 #53 #00 #48 #00 #4D #00 #65 #00 #73 #00 #68 #00 #54 #00 #6F #00 #6F #00 #6C #00 #62 #00 #61 #00 #72 #01 #00 #00 #00 #30 #00 #53 #00 #4D #00 #45 #00 #53 #00 #48 #00 #4D #00 #6F #00 #64 #00 #69 #00 #66 #00 #69 #00 #63 #00 #61 #00 #74 #00 #69 #00 #6F #00 #6E #00 #54 #00 #6F #00 #6F #00 #6C #00 #62 #00 #61 #00 #72 #01 #00 #00 #00 #30 #00 #53 #00 #4D #00 #45 #00 #53 #00 #48 #00 #4E #00 #6F #00 #64 #00 #65 #00 #43 #00 #6F #00 #6E #00 #74 #00 #72 #00 #6F #00 #6C #00 #73 #00 #54 #00 #6F #00 #6F #00 #6C #00 #62 #00 #61 #00 #72 #00 #00 #00 #00 #24 #00 #53 #00 #4D #00 #45 #00 #53 #00 #48 #00 #52 #00 #65 #00 #6D #00 #6F #00 #76 #00 #65 #00 #54 #00 #6F #00 #6F #00 #6C #00 #62 #00 #61 #00 #72 #01 #00 #00 #00 #2E #00 #53 #00 #4D #00 #45 #00 #53 #00 #48 #00 #52 #00 #65 #00 #6E #00 #75 #00 #6D #00 #62 #00 #65 #00 #72 #00 #69 #00 #6E #00 #67 #00 #54 #00 #6F #00 #6F #00 #6C #00 #62 #00 #61 #00 #72 #01 #00 #00 #00 #34 #00 #53 #00 #4D #00 #45 #00 #53 #00 #48 #00 #54 #00 #72 #00 #61 #00 #6E #00 #73 #00 #66 #00 #6F #00 #72 #00 #6D #00 #61 #00 #74 #00 #69 #00 #6F #00 #6E #00 #54 #00 #6F #00 #6F #00 #6C #00 #62 #00 #61 #00 #72 #01 #00 #00 #00 #34 #00 #53 #00 #4D #00 #45 #00 #53 #00 #48 #00 #56 #00 #6F #00 #6C #00 #75 #00 #6D #00 #65 #00 #43 #00 #6F #00 #6E #00 #74 #00 #72 #00 #6F #00 #6C #00 #73 #00 #54 #00 #6F #00 #6F #00 #6C #00 #62 #00 #61 #00 #72 #00 #00 #00 #00 #1A #00 #53 #00 #61 #00 #6C #00 #6F #00 #6D #00 #65 #00 #4D #00 #6F #00 #64 #00 #75 #00 #6C #00 #65 #00 #73 #01 #00 #00 #00 #1C #00 #53 #00 #61 #00 #6C #00 #6F #00 #6D #00 #65 #00 #53 #00 #74 #00 #61 #00 #6E #00 #64 #00 #61 #00 #72 #00 #64 #01 #00 #00 #00 #10 #00 #53 #00 #74 #00 #61 #00 #6E #00 #64 #00 #61 #00 #72 #00 #64 #01 #00 #00 #00 #1A #00 #54 #00 #4F #00 #4F #00 #4C #00 #5F #00 #41 #00 #44 #00 #56 #00 #41 #00 #4E #00 #43 #00 #45 #00 #44 #01 #00 #00 #00 #16 #00 #54 #00 #4F #00 #4F #00 #4C #00 #5F #00 #42 #00 #4C #00 #4F #00 #43 #00 #4B #00 #53 #01 #00 #00 #00 #2C #00 #54 #00 #72 #00 #61 #00 #6E #00 #73 #00 #66 #00 #6F #00 #72 #00 #6D #00 #61 #00 #74 #00 #69 #00 #6F #00 #6E #00 #20 #00 #54 #00 #6F #00 #6F #00 #6C #00 #62 #00 #61 #00 #72 #01 #00 #00 #00 #2C #00 #56 #00 #54 #00 #4B #00 #52 #00 #65 #00 #63 #00 #6F #00 #72 #00 #64 #00 #69 #00 #6E #00 #67 #00 #4F #00 #70 #00 #65 #00 #72 #00 #61 #00 #74 #00 #69 #00 #6F #00 #6E #00 #73 #01 #00 #00 #00 #2E #00 #56 #00 #54 #00 #4B #00 #56 #00 #69 #00 #65 #00 #77 #00 #65 #00 #72 #00 #56 #00 #69 #00 #65 #00 #77 #00 #4F #00 #70 #00 #65 #00 #72 #00 #61 #00 #74 #00 #69 #00 #6F #00 #6E #00 #73 #01 #00 #00 #00 #1E #00 #56 #00 #69 #00 #65 #00 #77 #00 #20 #00 #4F #00 #70 #00 #65 #00 #72 #00 #61 #00 #74 #00 #69 #00 #6F #00 #6E #00 #73 #01 #00 #00 #00 #2E #00 #56 #00 #6F #00 #6C #00 #75 #00 #6D #00 #65 #00 #20 #00 #43 #00 #6F #00 #6E #00 #74 #00 #72 #00 #6F #00 #6C #00 #73 #00 #20 #00 #54 #00 #6F #00 #6F #00 #6C #00 #62 #00 #61 #00 #72 #00 #01 #00 #00 #00 #06 #00 #00 #00 #18 #00 #6E #00 #6F #00 #74 #00 #65 #00 #42 #00 #6F #00 #6F #00 #6B #00 #44 #00 #6F #00 #63 #00 #6B #01 #00 #00 #00 #22 #00 #6F #00 #62 #00 #6A #00 #65 #00 #63 #00 #74 #00 #42 #00 #72 #00 #6F #00 #77 #00 #73 #00 #65 #00 #72 #00 #44 #00 #6F #00 #63 #00 #6B #01 #00 #00 #00 #22 #00 #70 #00 #79 #00 #74 #00 #68 #00 #6F #00 #6E #00 #43 #00 #6F #00 #6E #00 #73 #00 #6F #00 #6C #00 #65 #00 #44 #00 #6F #00 #63 #00 #6B #01 #00 #00 #00 #10 #00 #77 #00 #69 #00 #6E #00 #64 #00 #6F #00 #77 #00 #5F #00 #30 #01 #00 #00 #00 #10 #00 #77 #00 #69 #00 #6E #00 #64 #00 #6F #00 #77 #00 #5F #00 #31 #01 #00 #00 #00 #10 #00 #77 #00 #69 #00 #6E #00 #64 #00 #6F #00 #77 #00 #5F #00 #33 #01"/>
</section>
</document>
${CAS_TKernel}
${CAS_TKTopAlgo}
SMESHDS
+ SMESHUtils
)
# --- headers ---
#include "SMESHDS_Group.hxx"
#include "SMESHDS_Mesh.hxx"
#include "SMESH_Comment.hxx"
+#include "SMESH_TypeDefs.hxx"
#include <gp_XYZ.hxx>
}
bool IsStructured() const { return ( _type == CGNS_ENUMV( Structured )); }
int IndexSize() const { return IsStructured() ? _meshDim : 1; }
- string ReadZonesConnection(int file, int base, const map< string, TZoneData >& zonesByName);
+ string ReadZonesConnection(int file, int base,
+ const map< string, TZoneData >& zonesByName,
+ SMESHDS_Mesh* mesh);
void ReplaceNodes( cgsize_t* ids, int nbIds, int idShift = 0 ) const;
// Methods for a structured zone
//gp_XYZ End() const { return gp_XYZ( _end[0]-1, _end[1]-1, _end[2]-1 ); }
};
+ //================================================================================
+ /*!
+ * \brief Checks if the two arrays of node IDs describe nodes with equal coordinates
+ */
+ //================================================================================
+
+ bool isEqualNodes( const int* nIds1, const int* nIds2, int nbNodes, SMESHDS_Mesh* mesh )
+ {
+ if ( nbNodes > 0 )
+ {
+ SMESH_TNodeXYZ nn1[2], nn2[2];
+ nn1[0] = mesh->FindNode( nIds1[0] );
+ nn2[0] = mesh->FindNode( nIds2[0] );
+ if ( !nn1[0]._node || !nn2[0]._node )
+ return false;
+ double dist1 = ( nn1[0] - nn2[0] ).Modulus();
+ double dist2 = 0, tol = 1e-7;
+ if ( nbNodes > 1 )
+ {
+ nn1[1] = mesh->FindNode( nIds1[1] );
+ nn2[1] = mesh->FindNode( nIds2[1] );
+ if ( !nn1[1]._node || !nn2[1]._node )
+ return false;
+ dist2 = ( nn1[1] - nn2[1] ).Modulus();
+ tol = 1e-5 * ( nn1[0] - nn1[1] ).Modulus();
+ }
+ return ( dist1 < tol & dist2 < tol );
+ }
+ return false;
+ }
+
//================================================================================
/*!
* \brief Reads zone interface connectivity
string TZoneData::ReadZonesConnection( int file,
int base,
- const map< string, TZoneData >& zonesByName)
+ const map< string, TZoneData >& zonesByName,
+ SMESHDS_Mesh* mesh)
{
string error;
continue; // this interface already read
}
}
+ // check if range and donorRange describe the same nodes
+ {
+ int ids1[2], ids2[2], nbN = 0;
+ TPointRangeIterator rangeIt1bis( range, _meshDim );
+ index1 = rangeIt1bis.Next();
+ index2 = T * ( index1 - begin1 ) + begin2;
+ ids1[0] = NodeID( index1 );
+ ids2[0] = zone2.NodeID( index2 );
+ ++nbN;
+ if ( rangeIt1bis.More() )
+ {
+ index1 = rangeIt1bis.Next();
+ index2 = T * ( index1 - begin1 ) + begin2;
+ ids1[1] = NodeID( index1 );
+ ids2[1] = zone2.NodeID( index2 );
+ ++nbN;
+ }
+ if ( !isEqualNodes( &ids1[0], &ids2[0], nbN, mesh ))
+ continue;
+ }
while ( rangeIt1.More() )
{
index1 = rangeIt1.Next();
{
for ( int isThisZone = 0; isThisZone < 2; ++isThisZone )
{
- const TZoneData& zone = isThisZone ? *this : zone2;
+ const TZoneData& zone = isThisZone ? *this : zone2;
CGNS_ENUMT(PointSetType_t) type = isThisZone ? ptype : donorPtype;
vector< cgsize_t >& points = isThisZone ? ids : donorIds;
if ( type == CGNS_ENUMV( PointRange ))
points[i] += zone._nodeIdShift;
}
}
- for ( size_t i = 0; i < ids.size() && i < donorIds.size(); ++i )
- _nodeReplacementMap.insert( make_pair( ids[i], donorIds[i] ));
+ size_t nbN = std::min( ids.size(), donorIds.size());
+ if ( isEqualNodes( &ids[0], &donorIds[0], nbN, mesh ))
+ for ( size_t i = 0; i < nbN; ++i )
+ _nodeReplacementMap.insert( make_pair( ids[i], donorIds[i] ));
}
else
{
// Read connectivity between zones. Nodes of the zone interface will be
// replaced withing the zones read later
- string err = zone.ReadZonesConnection( _fn, cgnsBase, zonesByName );
+ string err = zone.ReadZonesConnection( _fn, cgnsBase, zonesByName, myMesh );
if ( !err.empty() )
addMessage( err );
//=============================================================================
DriverMED_FamilyPtrList
DriverMED_Family
-::MakeFamilies(const SMESHDS_SubMeshPtrMap& theSubMeshes,
+::MakeFamilies(SMESHDS_SubMeshIteratorPtr theSubMeshes,
const SMESHDS_GroupBasePtrList& theGroups,
const bool doGroupOfNodes,
const bool doGroupOfEdges,
int aElemFamId = FIRST_ELEM_FAMILY;
// Process sub-meshes
- SMESHDS_SubMeshPtrMap::const_iterator aSMIter = theSubMeshes.begin();
- for (; aSMIter != theSubMeshes.end(); aSMIter++)
+ while ( theSubMeshes->more() )
{
- const int anId = aSMIter->first;
- SMESHDS_SubMesh* aSubMesh = aSMIter->second;
+ SMESHDS_SubMesh* aSubMesh = const_cast< SMESHDS_SubMesh* >( theSubMeshes->next() );
+ const int anId = aSubMesh->GetID();
if ( aSubMesh->IsComplexSubmesh() )
continue; // submesh containing other submeshs
DriverMED_FamilyPtrList aSMFams = SplitByType(aSubMesh,anId);
*/
static
DriverMED_FamilyPtrList
- MakeFamilies (const SMESHDS_SubMeshPtrMap& theSubMeshes,
+ MakeFamilies (SMESHDS_SubMeshIteratorPtr theSubMeshes,
const SMESHDS_GroupBasePtrList& theGroups,
const bool doGroupOfNodes,
const bool doGroupOfEdges,
void DriverMED_W_SMESHDS_Mesh::AddSubMesh(SMESHDS_SubMesh* theSubMesh, int theID)
{
- mySubMeshes[theID] = theSubMesh;
+ mySubMeshes.push_back( theSubMesh );
}
void DriverMED_W_SMESHDS_Mesh::AddGroupOfNodes()
// return elem_famNum->second;
return aDefaultFamilyId;
}
+
+ //================================================================================
+ /*!
+ * \brief Returns iterator on sub-meshes
+ */
+ //================================================================================
+
+ SMESHDS_SubMeshIteratorPtr getIterator( std::vector<SMESHDS_SubMesh*>& mySubMeshes )
+ {
+ return SMESHDS_SubMeshIteratorPtr
+ ( new SMDS_SetIterator
+ < const SMESHDS_SubMesh*, std::vector< SMESHDS_SubMesh* >::iterator >( mySubMeshes.begin(),
+ mySubMeshes.end() ));
+ }
}
Driver_Mesh::Status DriverMED_W_SMESHDS_Mesh::Perform()
myDoGroupOfBalls && nbBalls);
} else {
aFamilies = DriverMED_Family::MakeFamilies
- (mySubMeshes, myGroups,
+ (getIterator( mySubMeshes ), myGroups,
myDoGroupOfNodes && nbNodes,
myDoGroupOfEdges && nbEdges,
myDoGroupOfFaces && nbFaces,
MED::EVersion myMedVersion;
std::list<SMESHDS_GroupBase*> myGroups;
bool myAllSubMeshes;
- std::map<int,SMESHDS_SubMesh*> mySubMeshes;
+ std::vector<SMESHDS_SubMesh*> mySubMeshes;
bool myDoGroupOfNodes;
bool myDoGroupOfEdges;
bool myDoGroupOfFaces;
// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
//
-#include <fstream>
-#include <stdio.h>
+#include <fstream>
+#include <cstdio>
#include "UNV2411_Structure.hxx"
#include "UNV_Utilities.hxx"
exp_coord_sys_num(1),
disp_coord_sys_num(1),
color(11)//(0) - 0019936: EDF 794 SMESH : Export UNV : Node color and group id
-{}
+{
+ coord[1] = coord[2] = 0.0; // prepare to e.g. 2D mesh
+}
void UNV2411::Read(std::ifstream& in_stream, TDataSet& theDataSet)
{
* always 3 coordinates in the UNV file, no matter
* which dimensionality libMesh is in
*/
+ int dim = 3;
std::string num_buf;
+
+ // Issue 22638. Find out space dimension to read a 2D mesh from a file
+ // generated by SIMAIL from Simulog
+ if ( !in_stream.eof() )
+ {
+ int where = in_stream.tellg();
+
+ TRecord aRec;
+ in_stream >> aRec.label ;
+ if ( aRec.label == -1 ) return; // dataset end
+
+ dim = 0;
+ num_buf = read_line( in_stream );
+ for ( size_t i = 0; i < num_buf.size(); )
+ {
+ // skip spaces
+ while ( i < num_buf.size() && num_buf[i] == ' ' )
+ ++i;
+
+ dim += ( i < num_buf.size() );
+
+ // skip non-spaces
+ while ( i < num_buf.size() && num_buf[i] != ' ' )
+ ++i;
+ }
+ if ( dim == 0 )
+ return;
+
+ in_stream.seekg( where, in_stream.beg );
+ }
+
+ // read the rest records
while ( !in_stream.eof() )
{
TRecord aRec;
* take care of the
* floating-point data
*/
- for(int d = 0; d < 3; d++){
+ for(int d = 0; d < dim; d++){
in_stream>>num_buf;
aRec.coord[d] = D_to_e(num_buf);
}
const SMDS_MeshNode * n4,
int ID)
{
- //MESSAGE("AddVolumeWithID " << ID);
+ //MESSAGE("AddVolumeWithID " << ID);
SMDS_MeshVolume* volume = 0;
if ( !n1 || !n2 || !n3 || !n4) return volume;
if ( NbVolumes() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
}
else {
// --- retrieve nodes ID
- vector<vtkIdType> nodeIds;
- nodeIds.clear();
- nodeIds.push_back(n1->getVtkId());
- nodeIds.push_back(n3->getVtkId()); // order SMDS-->VTK
- nodeIds.push_back(n2->getVtkId());
- nodeIds.push_back(n4->getVtkId());
+ myNodeIds.resize(4);
+ myNodeIds[0] = n1->getVtkId();
+ myNodeIds[1] = n3->getVtkId(); // order SMDS-->VTK
+ myNodeIds[2] = n2->getVtkId();
+ myNodeIds[3] = n4->getVtkId();
SMDS_VtkVolume *volvtk = myVolumePool->getNew();
- volvtk->init(nodeIds, this);
+ volvtk->init(myNodeIds, this);
if (!this->registerElement(ID,volvtk))
- {
- this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL);
- myVolumePool->destroy(volvtk);
- return 0;
- }
+ {
+ this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL);
+ myVolumePool->destroy(volvtk);
+ return 0;
+ }
volume = volvtk;
adjustmyCellsCapacity(ID);
myCells[ID] = volume;
myInfo.myNbTetras++;
}
-// if (!registerElement(ID, volume)) {
-// RemoveElement(volume, false);
-// volume = NULL;
-// }
+ // if (!registerElement(ID, volume)) {
+ // RemoveElement(volume, false);
+ // volume = NULL;
+ // }
return volume;
}
const SMDS_MeshNode * n5,
int ID)
{
- //MESSAGE("AddVolumeWithID " << ID);
+ //MESSAGE("AddVolumeWithID " << ID);
SMDS_MeshVolume* volume = 0;
if ( !n1 || !n2 || !n3 || !n4 || !n5) return volume;
if ( NbVolumes() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
}
else {
// --- retrieve nodes ID
- vector<vtkIdType> nodeIds;
- nodeIds.clear();
- nodeIds.push_back(n1->getVtkId());
- nodeIds.push_back(n4->getVtkId());
- nodeIds.push_back(n3->getVtkId());
- nodeIds.push_back(n2->getVtkId());
- nodeIds.push_back(n5->getVtkId());
+ myNodeIds.resize(5);
+ myNodeIds[0] = n1->getVtkId();
+ myNodeIds[1] = n4->getVtkId();
+ myNodeIds[2] = n3->getVtkId();
+ myNodeIds[3] = n2->getVtkId();
+ myNodeIds[4] = n5->getVtkId();
SMDS_VtkVolume *volvtk = myVolumePool->getNew();
- volvtk->init(nodeIds, this);
+ volvtk->init(myNodeIds, this);
if (!this->registerElement(ID,volvtk))
- {
- this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL);
- myVolumePool->destroy(volvtk);
- return 0;
- }
+ {
+ this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL);
+ myVolumePool->destroy(volvtk);
+ return 0;
+ }
volume = volvtk;
adjustmyCellsCapacity(ID);
myCells[ID] = volume;
myInfo.myNbPyramids++;
}
-// if (!registerElement(ID, volume)) {
-// RemoveElement(volume, false);
-// volume = NULL;
-// }
+ // if (!registerElement(ID, volume)) {
+ // RemoveElement(volume, false);
+ // volume = NULL;
+ // }
return volume;
}
const SMDS_MeshNode * n6,
int ID)
{
- //MESSAGE("AddVolumeWithID " << ID);
+ //MESSAGE("AddVolumeWithID " << ID);
SMDS_MeshVolume* volume = 0;
if ( !n1 || !n2 || !n3 || !n4 || !n5 || !n6) return volume;
if ( NbVolumes() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
}
else {
// --- retrieve nodes ID
- vector<vtkIdType> nodeIds;
- nodeIds.clear();
- nodeIds.push_back(n1->getVtkId());
- nodeIds.push_back(n2->getVtkId());
- nodeIds.push_back(n3->getVtkId());
- nodeIds.push_back(n4->getVtkId());
- nodeIds.push_back(n5->getVtkId());
- nodeIds.push_back(n6->getVtkId());
+ myNodeIds.resize(6);
+ myNodeIds[0] = n1->getVtkId();
+ myNodeIds[1] = n2->getVtkId();
+ myNodeIds[2] = n3->getVtkId();
+ myNodeIds[3] = n4->getVtkId();
+ myNodeIds[4] = n5->getVtkId();
+ myNodeIds[5] = n6->getVtkId();
SMDS_VtkVolume *volvtk = myVolumePool->getNew();
- volvtk->init(nodeIds, this);
+ volvtk->init(myNodeIds, this);
if (!this->registerElement(ID,volvtk))
- {
- this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL);
- myVolumePool->destroy(volvtk);
- return 0;
- }
+ {
+ this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL);
+ myVolumePool->destroy(volvtk);
+ return 0;
+ }
volume = volvtk;
adjustmyCellsCapacity(ID);
myCells[ID] = volume;
myInfo.myNbPrisms++;
}
-// if (!registerElement(ID, volume)) {
-// RemoveElement(volume, false);
-// volume = NULL;
-// }
+ // if (!registerElement(ID, volume)) {
+ // RemoveElement(volume, false);
+ // volume = NULL;
+ // }
return volume;
}
}
else {
// --- retrieve nodes ID
- vector<vtkIdType> nodeIds;
- nodeIds.push_back(n1->getVtkId());
- nodeIds.push_back(n6->getVtkId());
- nodeIds.push_back(n5->getVtkId());
- nodeIds.push_back(n4->getVtkId());
- nodeIds.push_back(n3->getVtkId());
- nodeIds.push_back(n2->getVtkId());
-
- nodeIds.push_back(n7->getVtkId());
- nodeIds.push_back(n12->getVtkId());
- nodeIds.push_back(n11->getVtkId());
- nodeIds.push_back(n10->getVtkId());
- nodeIds.push_back(n9->getVtkId());
- nodeIds.push_back(n8->getVtkId());
+ myNodeIds.resize(12);
+ myNodeIds[0] = n1->getVtkId();
+ myNodeIds[1] = n6->getVtkId();
+ myNodeIds[2] = n5->getVtkId();
+ myNodeIds[3] = n4->getVtkId();
+ myNodeIds[4] = n3->getVtkId();
+ myNodeIds[5] = n2->getVtkId();
+
+ myNodeIds[6] = n7->getVtkId();
+ myNodeIds[7] = n12->getVtkId();
+ myNodeIds[8] = n11->getVtkId();
+ myNodeIds[9] = n10->getVtkId();
+ myNodeIds[10] = n9->getVtkId();
+ myNodeIds[11] = n8->getVtkId();
SMDS_VtkVolume *volvtk = myVolumePool->getNew();
- volvtk->init(nodeIds, this);
+ volvtk->init(myNodeIds, this);
if (!this->registerElement(ID,volvtk))
- {
- this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL);
- myVolumePool->destroy(volvtk);
- return 0;
- }
+ {
+ this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL);
+ myVolumePool->destroy(volvtk);
+ return 0;
+ }
volume = volvtk;
adjustmyCellsCapacity(ID);
myCells[ID] = volume;
}
else {
// --- retrieve nodes ID
- vector<vtkIdType> nodeIds;
- nodeIds.clear();
- nodeIds.push_back(n1->getVtkId());
- nodeIds.push_back(n4->getVtkId());
- nodeIds.push_back(n3->getVtkId());
- nodeIds.push_back(n2->getVtkId());
- nodeIds.push_back(n5->getVtkId());
- nodeIds.push_back(n8->getVtkId());
- nodeIds.push_back(n7->getVtkId());
- nodeIds.push_back(n6->getVtkId());
+ myNodeIds.resize(8);
+ myNodeIds[0] = n1->getVtkId();
+ myNodeIds[1] = n4->getVtkId();
+ myNodeIds[2] = n3->getVtkId();
+ myNodeIds[3] = n2->getVtkId();
+ myNodeIds[4] = n5->getVtkId();
+ myNodeIds[5] = n8->getVtkId();
+ myNodeIds[6] = n7->getVtkId();
+ myNodeIds[7] = n6->getVtkId();
SMDS_VtkVolume *volvtk = myVolumePool->getNew();
- volvtk->init(nodeIds, this);
+ volvtk->init(myNodeIds, this);
if (!this->registerElement(ID,volvtk))
- {
- this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL);
- myVolumePool->destroy(volvtk);
- return 0;
- }
+ {
+ this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL);
+ myVolumePool->destroy(volvtk);
+ return 0;
+ }
volume = volvtk;
adjustmyCellsCapacity(ID);
myCells[ID] = volume;
myInfo.myNbHexas++;
}
-
-// if (!registerElement(ID, volume)) {
-// RemoveElement(volume, false);
-// volume = NULL;
-// }
+
+ // if (!registerElement(ID, volume)) {
+ // RemoveElement(volume, false);
+ // volume = NULL;
+ // }
return volume;
}
/// Add a polygon defined by its nodes
///////////////////////////////////////////////////////////////////////////////
-SMDS_MeshFace* SMDS_Mesh::AddPolygonalFaceWithID
- (const vector<const SMDS_MeshNode*> & nodes,
- const int ID)
+SMDS_MeshFace*
+SMDS_Mesh::AddPolygonalFaceWithID (const vector<const SMDS_MeshNode*> & nodes,
+ const int ID)
{
SMDS_MeshFace * face;
if ( NbFaces() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
if (hasConstructionEdges())
- {
- MESSAGE("Error : Not implemented");
- return NULL;
- }
+ {
+ MESSAGE("Error : Not implemented");
+ return NULL;
+ }
else
- {
-//#ifdef VTK_HAVE_POLYHEDRON
+ {
+ //#ifdef VTK_HAVE_POLYHEDRON
//MESSAGE("AddPolygonalFaceWithID vtk " << ID);
- vector<vtkIdType> nodeIds;
- nodeIds.clear();
- vector<const SMDS_MeshNode*>::const_iterator it = nodes.begin();
- for ( ; it != nodes.end(); ++it)
- nodeIds.push_back((*it)->getVtkId());
+ myNodeIds.resize( nodes.size() );
+ for ( size_t i = 0; i < nodes.size(); ++i )
+ myNodeIds[i] = nodes[i]->getVtkId();
SMDS_VtkFace *facevtk = myFacePool->getNew();
- facevtk->initPoly(nodeIds, this);
+ facevtk->initPoly(myNodeIds, this);
if (!this->registerElement(ID,facevtk))
- {
- this->myGrid->GetCellTypesArray()->SetValue(facevtk->getVtkId(), VTK_EMPTY_CELL);
- myFacePool->destroy(facevtk);
- return 0;
- }
- face = facevtk;
-//#else
-// MESSAGE("AddPolygonalFaceWithID smds " << ID);
-// for ( int i = 0; i < nodes.size(); ++i )
-// if ( !nodes[ i ] ) return 0;
-// face = new SMDS_PolygonalFaceOfNodes(nodes);
-//#endif
- adjustmyCellsCapacity(ID);
- myCells[ID] = face;
- myInfo.myNbPolygons++;
+ {
+ this->myGrid->GetCellTypesArray()->SetValue(facevtk->getVtkId(), VTK_EMPTY_CELL);
+ myFacePool->destroy(facevtk);
+ return 0;
}
+ face = facevtk;
+ //#else
+ // MESSAGE("AddPolygonalFaceWithID smds " << ID);
+ // for ( int i = 0; i < nodes.size(); ++i )
+ // if ( !nodes[ i ] ) return 0;
+ // face = new SMDS_PolygonalFaceOfNodes(nodes);
+ //#endif
+ adjustmyCellsCapacity(ID);
+ myCells[ID] = face;
+ myInfo.myNbPolygons++;
+ }
-//#ifndef VTK_HAVE_POLYHEDRON
-// if (!registerElement(ID, face))
-// {
-// registerElement(myElementIDFactory->GetFreeID(), face);
-// //RemoveElement(face, false);
-// //face = NULL;
-// }
-//#endif
- return face;
+ //#ifndef VTK_HAVE_POLYHEDRON
+ // if (!registerElement(ID, face))
+ // {
+ // registerElement(myElementIDFactory->GetFreeID(), face);
+ // //RemoveElement(face, false);
+ // //face = NULL;
+ // }
+ //#endif
+ return face;
}
///////////////////////////////////////////////////////////////////////////////
/// @return The created volume
///////////////////////////////////////////////////////////////////////////////
-SMDS_MeshVolume* SMDS_Mesh::AddPolyhedralVolumeWithID
- (const vector<const SMDS_MeshNode*>& nodes,
- const vector<int> & quantities,
- const int ID)
+SMDS_MeshVolume*
+SMDS_Mesh::AddPolyhedralVolumeWithID (const vector<const SMDS_MeshNode*>& nodes,
+ const vector<int> & quantities,
+ const int ID)
{
SMDS_MeshVolume* volume = 0;
if ( nodes.empty() || quantities.empty() )
return NULL;
if ( NbVolumes() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
if (hasConstructionFaces())
- {
- MESSAGE("Error : Not implemented");
- return NULL;
- }
+ {
+ MESSAGE("Error : Not implemented");
+ return NULL;
+ }
else if (hasConstructionEdges())
- {
- MESSAGE("Error : Not implemented");
- return NULL;
- }
+ {
+ MESSAGE("Error : Not implemented");
+ return NULL;
+ }
else
+ {
+ //#ifdef VTK_HAVE_POLYHEDRON
+ //MESSAGE("AddPolyhedralVolumeWithID vtk " << ID);
+ myNodeIds.resize( nodes.size() );
+ for ( size_t i = 0; i < nodes.size(); ++i )
+ myNodeIds[i] = nodes[i]->getVtkId();
+
+ SMDS_VtkVolume *volvtk = myVolumePool->getNew();
+ volvtk->initPoly(myNodeIds, quantities, this);
+ if (!this->registerElement(ID, volvtk))
{
-//#ifdef VTK_HAVE_POLYHEDRON
- //MESSAGE("AddPolyhedralVolumeWithID vtk " << ID);
- vector<vtkIdType> nodeIds;
- nodeIds.clear();
- vector<const SMDS_MeshNode*>::const_iterator it = nodes.begin();
- for (; it != nodes.end(); ++it)
- nodeIds.push_back((*it)->getVtkId());
-
- SMDS_VtkVolume *volvtk = myVolumePool->getNew();
- volvtk->initPoly(nodeIds, quantities, this);
- if (!this->registerElement(ID, volvtk))
- {
- this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL);
- myVolumePool->destroy(volvtk);
- return 0;
- }
- volume = volvtk;
-//#else
-// MESSAGE("AddPolyhedralVolumeWithID smds " << ID);
-// for ( int i = 0; i < nodes.size(); ++i )
-// if ( !nodes[ i ] ) return 0;
-// volume = new SMDS_PolyhedralVolumeOfNodes(nodes, quantities);
-//#endif
- adjustmyCellsCapacity(ID);
- myCells[ID] = volume;
- myInfo.myNbPolyhedrons++;
+ this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL);
+ myVolumePool->destroy(volvtk);
+ return 0;
}
+ volume = volvtk;
+ //#else
+ // MESSAGE("AddPolyhedralVolumeWithID smds " << ID);
+ // for ( int i = 0; i < nodes.size(); ++i )
+ // if ( !nodes[ i ] ) return 0;
+ // volume = new SMDS_PolyhedralVolumeOfNodes(nodes, quantities);
+ //#endif
+ adjustmyCellsCapacity(ID);
+ myCells[ID] = volume;
+ myInfo.myNbPolyhedrons++;
+ }
-//#ifndef VTK_HAVE_POLYHEDRON
-// if (!registerElement(ID, volume))
-// {
-// registerElement(myElementIDFactory->GetFreeID(), volume);
-// //RemoveElement(volume, false);
-// //volume = NULL;
-// }
-//#endif
+ //#ifndef VTK_HAVE_POLYHEDRON
+ // if (!registerElement(ID, volume))
+ // {
+ // registerElement(myElementIDFactory->GetFreeID(), volume);
+ // //RemoveElement(volume, false);
+ // //volume = NULL;
+ // }
+ //#endif
return volume;
}
else
{
// --- retrieve nodes ID
- vector<vtkIdType> nodeIds;
- nodeIds.clear();
- nodeIds.push_back(node1->getVtkId());
- nodeIds.push_back(node2->getVtkId());
- nodeIds.push_back(node3->getVtkId());
+ myNodeIds.resize(3);
+ myNodeIds[0] = node1->getVtkId();
+ myNodeIds[1] = node2->getVtkId();
+ myNodeIds[2] = node3->getVtkId();
SMDS_MeshFace * face = 0;
SMDS_VtkFace *facevtk = myFacePool->getNew();
- facevtk->init(nodeIds, this); // put in vtkUnstructuredGrid
+ facevtk->init(myNodeIds, this); // put in vtkUnstructuredGrid
if (!this->registerElement(ID,facevtk))
- {
- this->myGrid->GetCellTypesArray()->SetValue(facevtk->getVtkId(), VTK_EMPTY_CELL);
- myFacePool->destroy(facevtk);
- return 0;
- }
+ {
+ this->myGrid->GetCellTypesArray()->SetValue(facevtk->getVtkId(), VTK_EMPTY_CELL);
+ myFacePool->destroy(facevtk);
+ return 0;
+ }
face = facevtk;
adjustmyCellsCapacity(ID);
myCells[ID] = face;
if ( NbFaces() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
if(hasConstructionEdges())
{
- //MESSAGE("createQuadrangle hasConstructionEdges "<< ID);
+ //MESSAGE("createQuadrangle hasConstructionEdges "<< ID);
SMDS_MeshEdge *edge1, *edge2, *edge3, *edge4;
edge1=FindEdgeOrCreate(node1,node2);
edge2=FindEdgeOrCreate(node2,node3);
else
{
// --- retrieve nodes ID
- vector<vtkIdType> nodeIds;
- nodeIds.clear();
- nodeIds.push_back(node1->getVtkId());
- nodeIds.push_back(node2->getVtkId());
- nodeIds.push_back(node3->getVtkId());
- nodeIds.push_back(node4->getVtkId());
+ myNodeIds.resize(4);
+ myNodeIds[0] = node1->getVtkId();
+ myNodeIds[1] = node2->getVtkId();
+ myNodeIds[2] = node3->getVtkId();
+ myNodeIds[3] = node4->getVtkId();
SMDS_MeshFace * face = 0;
SMDS_VtkFace *facevtk = myFacePool->getNew();
- facevtk->init(nodeIds, this);
+ facevtk->init(myNodeIds, this);
if (!this->registerElement(ID,facevtk))
- {
- this->myGrid->GetCellTypesArray()->SetValue(facevtk->getVtkId(), VTK_EMPTY_CELL);
- myFacePool->destroy(facevtk);
- return 0;
- }
+ {
+ this->myGrid->GetCellTypesArray()->SetValue(facevtk->getVtkId(), VTK_EMPTY_CELL);
+ myFacePool->destroy(facevtk);
+ return 0;
+ }
face = facevtk;
adjustmyCellsCapacity(ID);
myCells[ID] = face;
if ( NbEdges() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
int ID = myElementIDFactory->GetFreeID(); // -PR- voir si on range cet element
adjustmyCellsCapacity(ID);
- vector<vtkIdType> nodeIds;
- nodeIds.clear();
- nodeIds.push_back(node1->getVtkId());
- nodeIds.push_back(node2->getVtkId());
+ myNodeIds.resize(2);
+ myNodeIds[0] = node1->getVtkId();
+ myNodeIds[1] = node2->getVtkId();
SMDS_VtkEdge *edgevtk = myEdgePool->getNew();
- edgevtk->init(nodeIds, this);
+ edgevtk->init(myNodeIds, this);
if (!this->registerElement(ID,edgevtk))
- {
- this->myGrid->GetCellTypesArray()->SetValue(edgevtk->getVtkId(), VTK_EMPTY_CELL);
- myEdgePool->destroy(edgevtk);
- return 0;
- }
+ {
+ this->myGrid->GetCellTypesArray()->SetValue(edgevtk->getVtkId(), VTK_EMPTY_CELL);
+ myEdgePool->destroy(edgevtk);
+ return 0;
+ }
toReturn = edgevtk;
myCells[ID] = toReturn;
myInfo.myNbEdges++;
if ( !n1 || !n2 || !n12 ) return 0;
// --- retrieve nodes ID
- vector<vtkIdType> nodeIds;
- nodeIds.clear();
- nodeIds.push_back(n1->getVtkId());
- nodeIds.push_back(n2->getVtkId());
- nodeIds.push_back(n12->getVtkId());
+ myNodeIds.resize(3);
+ myNodeIds[0] = n1->getVtkId();
+ myNodeIds[1] = n2->getVtkId();
+ myNodeIds[2] = n12->getVtkId();
SMDS_MeshEdge * edge = 0;
SMDS_VtkEdge *edgevtk = myEdgePool->getNew();
- edgevtk->init(nodeIds, this);
+ edgevtk->init(myNodeIds, this);
if (!this->registerElement(ID,edgevtk))
- {
- this->myGrid->GetCellTypesArray()->SetValue(edgevtk->getVtkId(), VTK_EMPTY_CELL);
- myEdgePool->destroy(edgevtk);
- return 0;
- }
+ {
+ this->myGrid->GetCellTypesArray()->SetValue(edgevtk->getVtkId(), VTK_EMPTY_CELL);
+ myEdgePool->destroy(edgevtk);
+ return 0;
+ }
edge = edgevtk;
adjustmyCellsCapacity(ID);
myCells[ID] = edge;
myInfo.myNbQuadEdges++;
-// if (!registerElement(ID, edge)) {
-// RemoveElement(edge, false);
-// edge = NULL;
-// }
+ // if (!registerElement(ID, edge)) {
+ // RemoveElement(edge, false);
+ // edge = NULL;
+ // }
return edge;
}
else
{
// --- retrieve nodes ID
- vector<vtkIdType> nodeIds;
- nodeIds.clear();
- nodeIds.push_back(n1->getVtkId());
- nodeIds.push_back(n2->getVtkId());
- nodeIds.push_back(n3->getVtkId());
- nodeIds.push_back(n12->getVtkId());
- nodeIds.push_back(n23->getVtkId());
- nodeIds.push_back(n31->getVtkId());
+ myNodeIds.resize(6);
+ myNodeIds[0] = n1->getVtkId();
+ myNodeIds[1] = n2->getVtkId();
+ myNodeIds[2] = n3->getVtkId();
+ myNodeIds[3] = n12->getVtkId();
+ myNodeIds[4] = n23->getVtkId();
+ myNodeIds[5] = n31->getVtkId();
SMDS_MeshFace * face = 0;
SMDS_VtkFace *facevtk = myFacePool->getNew();
- facevtk->init(nodeIds, this);
+ facevtk->init(myNodeIds, this);
if (!this->registerElement(ID,facevtk))
- {
- this->myGrid->GetCellTypesArray()->SetValue(facevtk->getVtkId(), VTK_EMPTY_CELL);
- myFacePool->destroy(facevtk);
- return 0;
- }
+ {
+ this->myGrid->GetCellTypesArray()->SetValue(facevtk->getVtkId(), VTK_EMPTY_CELL);
+ myFacePool->destroy(facevtk);
+ return 0;
+ }
face = facevtk;
adjustmyCellsCapacity(ID);
myCells[ID] = face;
myInfo.myNbQuadTriangles++;
-// if (!registerElement(ID, face)) {
-// RemoveElement(face, false);
-// face = NULL;
-// }
+ // if (!registerElement(ID, face)) {
+ // RemoveElement(face, false);
+ // face = NULL;
+ // }
return face;
}
}
else
{
// --- retrieve nodes ID
- vector<vtkIdType> nodeIds;
- nodeIds.clear();
- nodeIds.push_back(n1->getVtkId());
- nodeIds.push_back(n2->getVtkId());
- nodeIds.push_back(n3->getVtkId());
- nodeIds.push_back(n12->getVtkId());
- nodeIds.push_back(n23->getVtkId());
- nodeIds.push_back(n31->getVtkId());
- nodeIds.push_back(nCenter->getVtkId());
+ myNodeIds.resize(7);
+ myNodeIds[0] = n1->getVtkId();
+ myNodeIds[1] = n2->getVtkId();
+ myNodeIds[2] = n3->getVtkId();
+ myNodeIds[3] = n12->getVtkId();
+ myNodeIds[4] = n23->getVtkId();
+ myNodeIds[5] = n31->getVtkId();
+ myNodeIds[6] = nCenter->getVtkId();
SMDS_MeshFace * face = 0;
SMDS_VtkFace *facevtk = myFacePool->getNew();
- facevtk->init(nodeIds, this);
+ facevtk->init(myNodeIds, this);
if (!this->registerElement(ID,facevtk))
- {
- this->myGrid->GetCellTypesArray()->SetValue(facevtk->getVtkId(), VTK_EMPTY_CELL);
- myFacePool->destroy(facevtk);
- return 0;
- }
+ {
+ this->myGrid->GetCellTypesArray()->SetValue(facevtk->getVtkId(), VTK_EMPTY_CELL);
+ myFacePool->destroy(facevtk);
+ return 0;
+ }
face = facevtk;
adjustmyCellsCapacity(ID);
myCells[ID] = face;
myInfo.myNbBiQuadTriangles++;
-// if (!registerElement(ID, face)) {
-// RemoveElement(face, false);
-// face = NULL;
-// }
+ // if (!registerElement(ID, face)) {
+ // RemoveElement(face, false);
+ // face = NULL;
+ // }
return face;
}
}
if ( !n1 || !n2 || !n3 || !n4 || !n12 || !n23 || !n34 || !n41) return 0;
if(hasConstructionEdges()) {
// creation quadratic edges - not implemented
- return 0;
+ return 0;
}
else
{
// --- retrieve nodes ID
- vector<vtkIdType> nodeIds;
- nodeIds.clear();
- nodeIds.push_back(n1->getVtkId());
- nodeIds.push_back(n2->getVtkId());
- nodeIds.push_back(n3->getVtkId());
- nodeIds.push_back(n4->getVtkId());
- nodeIds.push_back(n12->getVtkId());
- nodeIds.push_back(n23->getVtkId());
- nodeIds.push_back(n34->getVtkId());
- nodeIds.push_back(n41->getVtkId());
+ myNodeIds.resize(8);
+ myNodeIds[0] = n1->getVtkId();
+ myNodeIds[1] = n2->getVtkId();
+ myNodeIds[2] = n3->getVtkId();
+ myNodeIds[3] = n4->getVtkId();
+ myNodeIds[4] = n12->getVtkId();
+ myNodeIds[5] = n23->getVtkId();
+ myNodeIds[6] = n34->getVtkId();
+ myNodeIds[7] = n41->getVtkId();
SMDS_MeshFace * face = 0;
SMDS_VtkFace *facevtk = myFacePool->getNew();
- facevtk->init(nodeIds, this);
+ facevtk->init(myNodeIds, this);
if (!this->registerElement(ID,facevtk))
- {
- this->myGrid->GetCellTypesArray()->SetValue(facevtk->getVtkId(), VTK_EMPTY_CELL);
- myFacePool->destroy(facevtk);
- return 0;
- }
+ {
+ this->myGrid->GetCellTypesArray()->SetValue(facevtk->getVtkId(), VTK_EMPTY_CELL);
+ myFacePool->destroy(facevtk);
+ return 0;
+ }
face = facevtk;
adjustmyCellsCapacity(ID);
myCells[ID] = face;
myInfo.myNbQuadQuadrangles++;
-// if (!registerElement(ID, face)) {
-// RemoveElement(face, false);
-// face = NULL;
-// }
+ // if (!registerElement(ID, face)) {
+ // RemoveElement(face, false);
+ // face = NULL;
+ // }
return face;
}
}
if ( !n1 || !n2 || !n3 || !n4 || !n12 || !n23 || !n34 || !n41 || !nCenter) return 0;
if(hasConstructionEdges()) {
// creation quadratic edges - not implemented
- return 0;
+ return 0;
}
else
{
// --- retrieve nodes ID
- vector<vtkIdType> nodeIds;
- nodeIds.clear();
- nodeIds.push_back(n1->getVtkId());
- nodeIds.push_back(n2->getVtkId());
- nodeIds.push_back(n3->getVtkId());
- nodeIds.push_back(n4->getVtkId());
- nodeIds.push_back(n12->getVtkId());
- nodeIds.push_back(n23->getVtkId());
- nodeIds.push_back(n34->getVtkId());
- nodeIds.push_back(n41->getVtkId());
- nodeIds.push_back(nCenter->getVtkId());
+ myNodeIds.resize(9);
+ myNodeIds[0] = n1->getVtkId();
+ myNodeIds[1] = n2->getVtkId();
+ myNodeIds[2] = n3->getVtkId();
+ myNodeIds[3] = n4->getVtkId();
+ myNodeIds[4] = n12->getVtkId();
+ myNodeIds[5] = n23->getVtkId();
+ myNodeIds[6] = n34->getVtkId();
+ myNodeIds[7] = n41->getVtkId();
+ myNodeIds[8] = nCenter->getVtkId();
SMDS_MeshFace * face = 0;
SMDS_VtkFace *facevtk = myFacePool->getNew();
- facevtk->init(nodeIds, this);
+ facevtk->init(myNodeIds, this);
if (!this->registerElement(ID,facevtk))
- {
- this->myGrid->GetCellTypesArray()->SetValue(facevtk->getVtkId(), VTK_EMPTY_CELL);
- myFacePool->destroy(facevtk);
- return 0;
- }
+ {
+ this->myGrid->GetCellTypesArray()->SetValue(facevtk->getVtkId(), VTK_EMPTY_CELL);
+ myFacePool->destroy(facevtk);
+ return 0;
+ }
face = facevtk;
adjustmyCellsCapacity(ID);
myCells[ID] = face;
myInfo.myNbBiQuadQuadrangles++;
-// if (!registerElement(ID, face)) {
-// RemoveElement(face, false);
-// face = NULL;
-// }
+ // if (!registerElement(ID, face)) {
+ // RemoveElement(face, false);
+ // face = NULL;
+ // }
return face;
}
}
return 0;
}
// --- retrieve nodes ID
- vector<vtkIdType> nodeIds;
- nodeIds.clear();
- nodeIds.push_back(n1->getVtkId());
- nodeIds.push_back(n3->getVtkId());
- nodeIds.push_back(n2->getVtkId());
- nodeIds.push_back(n4->getVtkId());
+ myNodeIds.resize(10);
+ myNodeIds[0] = n1->getVtkId();
+ myNodeIds[1] = n3->getVtkId();
+ myNodeIds[2] = n2->getVtkId();
+ myNodeIds[3] = n4->getVtkId();
- nodeIds.push_back(n31->getVtkId());
- nodeIds.push_back(n23->getVtkId());
- nodeIds.push_back(n12->getVtkId());
+ myNodeIds[4] = n31->getVtkId();
+ myNodeIds[5] = n23->getVtkId();
+ myNodeIds[6] = n12->getVtkId();
- nodeIds.push_back(n14->getVtkId());
- nodeIds.push_back(n34->getVtkId());
- nodeIds.push_back(n24->getVtkId());
+ myNodeIds[7] = n14->getVtkId();
+ myNodeIds[8] = n34->getVtkId();
+ myNodeIds[9] = n24->getVtkId();
SMDS_VtkVolume *volvtk = myVolumePool->getNew();
- volvtk->init(nodeIds, this);
+ volvtk->init(myNodeIds, this);
if (!this->registerElement(ID,volvtk))
- {
- this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL);
- myVolumePool->destroy(volvtk);
- return 0;
- }
+ {
+ this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL);
+ myVolumePool->destroy(volvtk);
+ return 0;
+ }
adjustmyCellsCapacity(ID);
myCells[ID] = volvtk;
myInfo.myNbQuadTetras++;
-// if (!registerElement(ID, volvtk)) {
-// RemoveElement(volvtk, false);
-// volvtk = NULL;
-// }
+ // if (!registerElement(ID, volvtk)) {
+ // RemoveElement(volvtk, false);
+ // volvtk = NULL;
+ // }
return volvtk;
}
return 0;
}
// --- retrieve nodes ID
- vector<vtkIdType> nodeIds;
- nodeIds.clear();
- nodeIds.push_back(n1->getVtkId());
- nodeIds.push_back(n4->getVtkId());
- nodeIds.push_back(n3->getVtkId());
- nodeIds.push_back(n2->getVtkId());
- nodeIds.push_back(n5->getVtkId());
-
- nodeIds.push_back(n41->getVtkId());
- nodeIds.push_back(n34->getVtkId());
- nodeIds.push_back(n23->getVtkId());
- nodeIds.push_back(n12->getVtkId());
-
- nodeIds.push_back(n15->getVtkId());
- nodeIds.push_back(n45->getVtkId());
- nodeIds.push_back(n35->getVtkId());
- nodeIds.push_back(n25->getVtkId());
+ myNodeIds.resize(13);
+ myNodeIds[0] = n1->getVtkId();
+ myNodeIds[1] = n4->getVtkId();
+ myNodeIds[2] = n3->getVtkId();
+ myNodeIds[3] = n2->getVtkId();
+ myNodeIds[4] = n5->getVtkId();
+
+ myNodeIds[5] = n41->getVtkId();
+ myNodeIds[6] = n34->getVtkId();
+ myNodeIds[7] = n23->getVtkId();
+ myNodeIds[8] = n12->getVtkId();
+
+ myNodeIds[9] = n15->getVtkId();
+ myNodeIds[10] = n45->getVtkId();
+ myNodeIds[11] = n35->getVtkId();
+ myNodeIds[12] = n25->getVtkId();
SMDS_VtkVolume *volvtk = myVolumePool->getNew();
- volvtk->init(nodeIds, this);
+ volvtk->init(myNodeIds, this);
if (!this->registerElement(ID,volvtk))
- {
- this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL);
- myVolumePool->destroy(volvtk);
- return 0;
- }
+ {
+ this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL);
+ myVolumePool->destroy(volvtk);
+ return 0;
+ }
adjustmyCellsCapacity(ID);
myCells[ID] = volvtk;
myInfo.myNbQuadPyramids++;
-// if (!registerElement(ID, volvtk)) {
-// RemoveElement(volvtk, false);
-// volvtk = NULL;
-// }
+ // if (!registerElement(ID, volvtk)) {
+ // RemoveElement(volvtk, false);
+ // volvtk = NULL;
+ // }
return volvtk;
}
return 0;
}
// --- retrieve nodes ID
- vector<vtkIdType> nodeIds;
- nodeIds.clear();
- nodeIds.push_back(n1->getVtkId());
- nodeIds.push_back(n2->getVtkId());
- nodeIds.push_back(n3->getVtkId());
+ myNodeIds.resize(15);
+ myNodeIds[0] = n1->getVtkId();
+ myNodeIds[1] = n2->getVtkId();
+ myNodeIds[2] = n3->getVtkId();
- nodeIds.push_back(n4->getVtkId());
- nodeIds.push_back(n5->getVtkId());
- nodeIds.push_back(n6->getVtkId());
+ myNodeIds[3] = n4->getVtkId();
+ myNodeIds[4] = n5->getVtkId();
+ myNodeIds[5] = n6->getVtkId();
- nodeIds.push_back(n12->getVtkId());
- nodeIds.push_back(n23->getVtkId());
- nodeIds.push_back(n31->getVtkId());
+ myNodeIds[6] = n12->getVtkId();
+ myNodeIds[7] = n23->getVtkId();
+ myNodeIds[8] = n31->getVtkId();
- nodeIds.push_back(n45->getVtkId());
- nodeIds.push_back(n56->getVtkId());
- nodeIds.push_back(n64->getVtkId());
+ myNodeIds[9] = n45->getVtkId();
+ myNodeIds[10] = n56->getVtkId();
+ myNodeIds[11] = n64->getVtkId();
- nodeIds.push_back(n14->getVtkId());
- nodeIds.push_back(n25->getVtkId());
- nodeIds.push_back(n36->getVtkId());
+ myNodeIds[12] = n14->getVtkId();
+ myNodeIds[13] = n25->getVtkId();
+ myNodeIds[14] = n36->getVtkId();
SMDS_VtkVolume *volvtk = myVolumePool->getNew();
- volvtk->init(nodeIds, this);
+ volvtk->init(myNodeIds, this);
if (!this->registerElement(ID,volvtk))
- {
- this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL);
- myVolumePool->destroy(volvtk);
- return 0;
- }
+ {
+ this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL);
+ myVolumePool->destroy(volvtk);
+ return 0;
+ }
adjustmyCellsCapacity(ID);
myCells[ID] = volvtk;
myInfo.myNbQuadPrisms++;
-// if (!registerElement(ID, volvtk)) {
-// RemoveElement(volvtk, false);
-// volvtk = NULL;
-// }
+ // if (!registerElement(ID, volvtk)) {
+ // RemoveElement(volvtk, false);
+ // volvtk = NULL;
+ // }
return volvtk;
}
// creation quadratic faces - not implemented
}
// --- retrieve nodes ID
- vector<vtkIdType> nodeIds;
- nodeIds.clear();
- nodeIds.push_back(n1->getVtkId());
- nodeIds.push_back(n4->getVtkId());
- nodeIds.push_back(n3->getVtkId());
- nodeIds.push_back(n2->getVtkId());
-
- nodeIds.push_back(n5->getVtkId());
- nodeIds.push_back(n8->getVtkId());
- nodeIds.push_back(n7->getVtkId());
- nodeIds.push_back(n6->getVtkId());
-
- nodeIds.push_back(n41->getVtkId());
- nodeIds.push_back(n34->getVtkId());
- nodeIds.push_back(n23->getVtkId());
- nodeIds.push_back(n12->getVtkId());
-
- nodeIds.push_back(n85->getVtkId());
- nodeIds.push_back(n78->getVtkId());
- nodeIds.push_back(n67->getVtkId());
- nodeIds.push_back(n56->getVtkId());
-
- nodeIds.push_back(n15->getVtkId());
- nodeIds.push_back(n48->getVtkId());
- nodeIds.push_back(n37->getVtkId());
- nodeIds.push_back(n26->getVtkId());
+ myNodeIds.resize(20);
+ myNodeIds[0] = n1->getVtkId();
+ myNodeIds[1] = n4->getVtkId();
+ myNodeIds[2] = n3->getVtkId();
+ myNodeIds[3] = n2->getVtkId();
+
+ myNodeIds[4] = n5->getVtkId();
+ myNodeIds[5] = n8->getVtkId();
+ myNodeIds[6] = n7->getVtkId();
+ myNodeIds[7] = n6->getVtkId();
+
+ myNodeIds[8] = n41->getVtkId();
+ myNodeIds[9] = n34->getVtkId();
+ myNodeIds[10] = n23->getVtkId();
+ myNodeIds[11] = n12->getVtkId();
+
+ myNodeIds[12] = n85->getVtkId();
+ myNodeIds[13] = n78->getVtkId();
+ myNodeIds[14] = n67->getVtkId();
+ myNodeIds[15] = n56->getVtkId();
+
+ myNodeIds[16] = n15->getVtkId();
+ myNodeIds[17] = n48->getVtkId();
+ myNodeIds[18] = n37->getVtkId();
+ myNodeIds[19] = n26->getVtkId();
SMDS_VtkVolume *volvtk = myVolumePool->getNew();
- volvtk->init(nodeIds, this);
+ volvtk->init(myNodeIds, this);
if (!this->registerElement(ID,volvtk))
- {
- this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL);
- myVolumePool->destroy(volvtk);
- return 0;
- }
+ {
+ this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL);
+ myVolumePool->destroy(volvtk);
+ return 0;
+ }
adjustmyCellsCapacity(ID);
myCells[ID] = volvtk;
myInfo.myNbQuadHexas++;
-// if (!registerElement(ID, volvtk)) {
-// RemoveElement(volvtk, false);
-// volvtk = NULL;
-// }
+ // if (!registerElement(ID, volvtk)) {
+ // RemoveElement(volvtk, false);
+ // volvtk = NULL;
+ // }
return volvtk;
}
// creation quadratic faces - not implemented
}
// --- retrieve nodes ID
- vector<vtkIdType> nodeIds;
- nodeIds.clear();
- nodeIds.push_back(n1->getVtkId());
- nodeIds.push_back(n4->getVtkId());
- nodeIds.push_back(n3->getVtkId());
- nodeIds.push_back(n2->getVtkId());
-
- nodeIds.push_back(n5->getVtkId());
- nodeIds.push_back(n8->getVtkId());
- nodeIds.push_back(n7->getVtkId());
- nodeIds.push_back(n6->getVtkId());
-
- nodeIds.push_back(n41->getVtkId());
- nodeIds.push_back(n34->getVtkId());
- nodeIds.push_back(n23->getVtkId());
- nodeIds.push_back(n12->getVtkId());
-
- nodeIds.push_back(n85->getVtkId());
- nodeIds.push_back(n78->getVtkId());
- nodeIds.push_back(n67->getVtkId());
- nodeIds.push_back(n56->getVtkId());
-
- nodeIds.push_back(n15->getVtkId());
- nodeIds.push_back(n48->getVtkId());
- nodeIds.push_back(n37->getVtkId());
- nodeIds.push_back(n26->getVtkId());
-
- nodeIds.push_back(n1256->getVtkId());
- nodeIds.push_back(n3478->getVtkId());
- nodeIds.push_back(n1458->getVtkId());
- nodeIds.push_back(n2367->getVtkId());
- nodeIds.push_back(n1234->getVtkId());
- nodeIds.push_back(n5678->getVtkId());
- nodeIds.push_back(nCenter->getVtkId());
+ myNodeIds.resize(27);
+ myNodeIds[0] = n1->getVtkId();
+ myNodeIds[1] = n4->getVtkId();
+ myNodeIds[2] = n3->getVtkId();
+ myNodeIds[3] = n2->getVtkId();
+
+ myNodeIds[4] = n5->getVtkId();
+ myNodeIds[5] = n8->getVtkId();
+ myNodeIds[6] = n7->getVtkId();
+ myNodeIds[7] = n6->getVtkId();
+
+ myNodeIds[8] = n41->getVtkId();
+ myNodeIds[9] = n34->getVtkId();
+ myNodeIds[10] = n23->getVtkId();
+ myNodeIds[11] = n12->getVtkId();
+
+ myNodeIds[12] = n85->getVtkId();
+ myNodeIds[13] = n78->getVtkId();
+ myNodeIds[14] = n67->getVtkId();
+ myNodeIds[15] = n56->getVtkId();
+
+ myNodeIds[16] = n15->getVtkId();
+ myNodeIds[17] = n48->getVtkId();
+ myNodeIds[18] = n37->getVtkId();
+ myNodeIds[19] = n26->getVtkId();
+
+ myNodeIds[20] = n1256->getVtkId();
+ myNodeIds[21] = n3478->getVtkId();
+ myNodeIds[22] = n1458->getVtkId();
+ myNodeIds[23] = n2367->getVtkId();
+ myNodeIds[24] = n1234->getVtkId();
+ myNodeIds[25] = n5678->getVtkId();
+ myNodeIds[26] = nCenter->getVtkId();
SMDS_VtkVolume *volvtk = myVolumePool->getNew();
- volvtk->init(nodeIds, this);
+ volvtk->init(myNodeIds, this);
if (!this->registerElement(ID,volvtk))
- {
- this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL);
- myVolumePool->destroy(volvtk);
- return 0;
- }
+ {
+ this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL);
+ myVolumePool->destroy(volvtk);
+ return 0;
+ }
adjustmyCellsCapacity(ID);
myCells[ID] = volvtk;
myInfo.myNbTriQuadHexas++;
myNodeMin = 0;
if (myNodes.size() == 0)
{
- myNodeMax=0;
- return;
+ myNodeMax=0;
+ return;
}
while (!myNodes[myNodeMin] && (myNodeMin<myNodes.size()))
myNodeMin++;
bool registerElement(int ID, SMDS_MeshElement * element);
void addChildrenWithNodes(std::set<const SMDS_MeshElement*>& setOfChildren,
- const SMDS_MeshElement * element,
+ const SMDS_MeshElement * element,
std::set<const SMDS_MeshElement*>& nodes);
inline void adjustmyCellsCapacity(int ID)
//! SMDS_MeshCells refer to vtk cells (vtk id != index in myCells),store reference to this mesh, and sub-shape
SetOfCells myCells;
- //! for cells only: index = ID for SMDS users, value = ID in vtkUnstructuredGrid
- //std::vector<int> myCellIdSmdsToVtk;
+ //! a buffer to speed up elements addition by excluding some memory allocation
+ std::vector<vtkIdType> myNodeIds;
//! for cells only: index = ID in vtkUnstructuredGrid, value = ID for SMDS users
std::vector<int> myCellIdVtkToSmds;
SMESH_Algo::SMESH_Algo (int hypId, int studyId, SMESH_Gen * gen)
: SMESH_Hypothesis(hypId, studyId, gen)
{
+ _compatibleAllHypFilter = _compatibleNoAuxHypFilter = NULL;
_onlyUnaryInput = _requireDiscreteBoundary = _requireShape = true;
_quadraticMesh = _supportSubmeshes = false;
_error = COMPERR_OK;
SMESH_Algo::~SMESH_Algo()
{
+ delete _compatibleNoAuxHypFilter;
+ // delete _compatibleAllHypFilter; -- _compatibleNoAuxHypFilter does it!!!
}
//=============================================================================
{
SMESH_Algo* me = const_cast< SMESH_Algo* >( this );
me->_usedHypList.clear();
- SMESH_HypoFilter filter;
- if ( InitCompatibleHypoFilter( filter, ignoreAuxiliary ))
+ if ( const SMESH_HypoFilter* filter = GetCompatibleHypoFilter( ignoreAuxiliary ))
{
- aMesh.GetHypotheses( aShape, filter, me->_usedHypList, true );
+ aMesh.GetHypotheses( aShape, *filter, me->_usedHypList, true );
if ( ignoreAuxiliary && _usedHypList.size() > 1 )
me->_usedHypList.clear(); //only one compatible hypothesis allowed
}
{
SMESH_Algo* me = const_cast< SMESH_Algo* >( this );
me->_appliedHypList.clear();
- SMESH_HypoFilter filter;
- if ( InitCompatibleHypoFilter( filter, ignoreAuxiliary ))
- aMesh.GetHypotheses( aShape, filter, me->_appliedHypList, false );
+ if ( const SMESH_HypoFilter* filter = GetCompatibleHypoFilter( ignoreAuxiliary ))
+ aMesh.GetHypotheses( aShape, *filter, me->_appliedHypList, false );
return _appliedHypList;
}
return false;
SMESHDS_SubMesh * eSubMesh = theMesh->MeshElements( theEdge );
- if ( !eSubMesh || ( eSubMesh->NbElements()==0 && eSubMesh->NbNodes() == 0))
+ if ( !eSubMesh || ( eSubMesh->NbElements()==0 && eSubMesh->NbNodes() == 0))
return false; // edge is not meshed
int nbNodes = 0;
//================================================================================
/*!
- * \brief Make filter recognize only compatible hypotheses
- * \param theFilter - the filter to initialize
- * \param ignoreAuxiliary - make filter ignore compatible auxiliary hypotheses
+ * \brief Returns the filter recognizing only compatible hypotheses
+ * \param ignoreAuxiliary - make filter ignore auxiliary hypotheses
+ * \retval SMESH_HypoFilter* - the filter that can be NULL
*/
//================================================================================
-bool SMESH_Algo::InitCompatibleHypoFilter( SMESH_HypoFilter & theFilter,
- const bool ignoreAuxiliary) const
+const SMESH_HypoFilter*
+SMESH_Algo::GetCompatibleHypoFilter(const bool ignoreAuxiliary) const
{
if ( !_compatibleHypothesis.empty() )
{
- theFilter.Init( theFilter.HasName( _compatibleHypothesis[0] ));
- for ( int i = 1; i < _compatibleHypothesis.size(); ++i )
- theFilter.Or( theFilter.HasName( _compatibleHypothesis[ i ] ));
-
- if ( ignoreAuxiliary )
- theFilter.AndNot( theFilter.IsAuxiliary() );
-
- return true;
+ if ( !_compatibleAllHypFilter )
+ {
+ SMESH_HypoFilter* filter = new SMESH_HypoFilter();
+ filter->Init( filter->HasName( _compatibleHypothesis[0] ));
+ for ( int i = 1; i < _compatibleHypothesis.size(); ++i )
+ filter->Or( filter->HasName( _compatibleHypothesis[ i ] ));
+
+ SMESH_HypoFilter* filterNoAux = new SMESH_HypoFilter( filter );
+ filterNoAux->AndNot( filterNoAux->IsAuxiliary() );
+
+ // _compatibleNoAuxHypFilter will detele _compatibleAllHypFilter!!!
+ SMESH_Algo* me = const_cast< SMESH_Algo* >( this );
+ me->_compatibleAllHypFilter = filter;
+ me->_compatibleNoAuxHypFilter = filterNoAux;
+ }
+ return ignoreAuxiliary ? _compatibleNoAuxHypFilter : _compatibleAllHypFilter;
}
- return false;
+ return 0;
}
//================================================================================
* \param V - the vertex
* \param meshDS - mesh
* \retval const SMDS_MeshNode* - found node or NULL
+ * \sa SMESH_MesherHelper::GetSubShapeByNode( const SMDS_MeshNode*, SMESHDS_Mesh* )
*/
//================================================================================
* \param aShape - the shape
* \param aStatus - check result
* \retval bool - true if hypothesis is well defined
+ *
+ * Textual description of a problem can be stored in _comment field.
*/
virtual bool CheckHypothesis(SMESH_Mesh& aMesh,
const TopoDS_Shape& aShape,
const TopoDS_Shape & aShape,
const bool ignoreAuxiliary=true) const;
/*!
- * \brief Make the filter recognize only compatible hypotheses
- * \param theFilter - the filter to initialize
- * \param ignoreAuxiliary - make filter ignore compatible auxiliary hypotheses
- * \retval bool - true if the algo has compatible hypotheses
+ * \brief Returns the filter recognizing only compatible hypotheses
+ * \param ignoreAuxiliary - make filter ignore compatible auxiliary hypotheses
+ * \retval SMESH_HypoFilter* - the filter that can be NULL
*/
- bool InitCompatibleHypoFilter( SMESH_HypoFilter & theFilter,
- const bool ignoreAuxiliary) const;
+ const SMESH_HypoFilter* GetCompatibleHypoFilter(const bool ignoreAuxiliary) const;
+
/*!
* \brief Just return false as the algorithm does not hold parameters values
*/
protected:
+ const SMESH_HypoFilter * _compatibleAllHypFilter;
+ const SMESH_HypoFilter * _compatibleNoAuxHypFilter;
std::vector<std::string> _compatibleHypothesis;
std::list<const SMESHDS_Hypothesis *> _appliedHypList;
std::list<const SMESHDS_Hypothesis *> _usedHypList;
+
// Algo features influencing which Compute() and how is called:
// in what turn and with what input shape.
if ( aShapesId && aShapeDim > (int)aDim )
continue;
- SMESH_Algo* algo = GetAlgo( aMesh, aSubShape, &algoShape );
+ SMESH_Algo* algo = GetAlgo( smToCompute, &algoShape );
if ( algo && !algo->NeedDiscreteBoundary() )
{
if ( algo->SupportSubmeshes() )
// Apply all-dimensional algorithms supporing sub-meshes
// ======================================================
+ std::vector< SMESH_subMesh* > smVec;
for ( aShapeDim = 0; aShapeDim < 4; ++aShapeDim )
{
// ------------------------------------------------
// sort list of sub-meshes according to mesh order
// ------------------------------------------------
- aMesh.SortByMeshOrder( smWithAlgoSupportingSubmeshes[ aShapeDim ] );
+ smVec.assign( smWithAlgoSupportingSubmeshes[ aShapeDim ].begin(),
+ smWithAlgoSupportingSubmeshes[ aShapeDim ].end() );
+ aMesh.SortByMeshOrder( smVec );
// ------------------------------------------------------------
// compute sub-meshes with local uni-dimensional algos under
// sub-meshes with all-dimensional algos
// ------------------------------------------------------------
- list< SMESH_subMesh* >::iterator subIt, subEnd;
- subIt = smWithAlgoSupportingSubmeshes[ aShapeDim ].begin();
- subEnd = smWithAlgoSupportingSubmeshes[ aShapeDim ].end();
// start from lower shapes
- for ( ; subIt != subEnd; ++subIt )
+ for ( size_t i = 0; i < smVec.size(); ++i )
{
- sm = *subIt;
+ sm = smVec[i];
// get a shape the algo is assigned to
- if ( !GetAlgo( aMesh, sm->GetSubShape(), & algoShape ))
+ if ( !GetAlgo( sm, & algoShape ))
continue; // strange...
// look for more local algos
.And( SMESH_HypoFilter::IsApplicableTo( aSubShape ))
.And( SMESH_HypoFilter::IsMoreLocalThan( algoShape, aMesh ));
- if ( SMESH_Algo* subAlgo = (SMESH_Algo*) aMesh.GetHypothesis( aSubShape, filter, true )) {
+ if ( SMESH_Algo* subAlgo = (SMESH_Algo*) aMesh.GetHypothesis( smToCompute, filter, true))
+ {
if ( ! subAlgo->NeedDiscreteBoundary() ) continue;
SMESH_Hypothesis::Hypothesis_Status status;
if ( subAlgo->CheckHypothesis( aMesh, aSubShape, status ))
// --------------------------------
// apply the all-dimensional algos
// --------------------------------
- subIt = smWithAlgoSupportingSubmeshes[ aShapeDim ].begin();
- for ( ; subIt != subEnd; ++subIt )
+ for ( size_t i = 0; i < smVec.size(); ++i )
{
- sm = *subIt;
+ sm = smVec[i];
if ( sm->GetComputeState() == SMESH_subMesh::READY_TO_COMPUTE)
{
const TopAbs_ShapeEnum shapeType = sm->GetSubShape().ShapeType();
const int aShapeDim = GetShapeDim( aSubShape );
if ( aShapeDim < 1 ) break;
- SMESH_Algo* algo = GetAlgo( aMesh, aSubShape );
+ SMESH_Algo* algo = GetAlgo( smToCompute );
if ( algo && !algo->NeedDiscreteBoundary() ) {
if ( algo->SupportSubmeshes() ) {
smWithAlgoSupportingSubmeshes.push_front( smToCompute );
// ------------------------------------------------------------
// sort list of meshes according to mesh order
// ------------------------------------------------------------
- aMesh.SortByMeshOrder( smWithAlgoSupportingSubmeshes );
+ std::vector< SMESH_subMesh* > smVec( smWithAlgoSupportingSubmeshes.begin(),
+ smWithAlgoSupportingSubmeshes.end() );
+ aMesh.SortByMeshOrder( smVec );
// ------------------------------------------------------------
// compute sub-meshes under shapes with algos that DO NOT require
// Discreteized boundaries and DO support sub-meshes
// ------------------------------------------------------------
- list< SMESH_subMesh* >::iterator subIt, subEnd;
- subIt = smWithAlgoSupportingSubmeshes.begin();
- subEnd = smWithAlgoSupportingSubmeshes.end();
// start from lower shapes
- for ( ; subIt != subEnd; ++subIt ) {
- sm = *subIt;
+ for ( size_t i = 0; i < smVec.size(); ++i )
+ {
+ sm = smVec[i];
// get a shape the algo is assigned to
TopoDS_Shape algoShape;
- if ( !GetAlgo( aMesh, sm->GetSubShape(), & algoShape ))
+ if ( !GetAlgo( sm, & algoShape ))
continue; // strange...
// look for more local algos
.And( SMESH_HypoFilter::IsApplicableTo( aSubShape ))
.And( SMESH_HypoFilter::IsMoreLocalThan( algoShape, aMesh ));
- if ( SMESH_Algo* subAlgo = (SMESH_Algo*) aMesh.GetHypothesis( aSubShape, filter, true )) {
+ if ( SMESH_Algo* subAlgo = (SMESH_Algo*) aMesh.GetHypothesis( smToCompute, filter, true ))
+ {
if ( ! subAlgo->NeedDiscreteBoundary() ) continue;
SMESH_Hypothesis::Hypothesis_Status status;
if ( subAlgo->CheckHypothesis( aMesh, aSubShape, status ))
// ----------------------------------------------------------
// apply the algos that do not require Discreteized boundaries
// ----------------------------------------------------------
- for ( subIt = smWithAlgoSupportingSubmeshes.begin(); subIt != subEnd; ++subIt )
+ for ( size_t i = 0; i < smVec.size(); ++i )
{
- sm = *subIt;
+ sm = smVec[i];
sm->Evaluate(aResMap);
if ( aShapesId )
aShapesId->insert( sm->GetId() );
const TopoDS_Shape & aShape,
TopoDS_Shape* assignedTo)
{
+ return GetAlgo( aMesh.GetSubMesh( aShape ), assignedTo );
+}
+
+//=============================================================================
+/*!
+ * Finds algo to mesh a sub-mesh. Optionally returns a shape the found algo is bound to
+ */
+//=============================================================================
+
+SMESH_Algo *SMESH_Gen::GetAlgo(SMESH_subMesh * aSubMesh,
+ TopoDS_Shape* assignedTo)
+{
+ if ( !aSubMesh ) return 0;
+
+ const TopoDS_Shape & aShape = aSubMesh->GetSubShape();
+ SMESH_Mesh& aMesh = *aSubMesh->GetFather();
+
SMESH_HypoFilter filter( SMESH_HypoFilter::IsAlgo() );
filter.And( filter.IsApplicableTo( aShape ));
TopoDS_Shape assignedToShape;
SMESH_Algo* algo =
- (SMESH_Algo*) aMesh.GetHypothesis( aShape, filter, true, &assignedToShape );
+ (SMESH_Algo*) aMesh.GetHypothesis( aSubMesh, filter, true, &assignedToShape );
if ( algo &&
aShape.ShapeType() == TopAbs_FACE &&
filter.AndNot( filter.Is( algo ));
TopoDS_Shape assignedToShape2;
SMESH_Algo* algo2 =
- (SMESH_Algo*) aMesh.GetHypothesis( aShape, filter, true, &assignedToShape2 );
+ (SMESH_Algo*) aMesh.GetHypothesis( aSubMesh, filter, true, &assignedToShape2 );
if ( algo2 && // algo found
!assignedToShape2.IsSame( aMesh.GetShapeToMesh() ) && // algo is local
( SMESH_MesherHelper::GetGroupType( assignedToShape2 ) == // algo of the same level
{ return GetShapeDim( aShape.ShapeType() ); }
SMESH_Algo* GetAlgo(SMESH_Mesh & aMesh, const TopoDS_Shape & aShape, TopoDS_Shape* assignedTo=0);
+ SMESH_Algo* GetAlgo(SMESH_subMesh * aSubMesh, TopoDS_Shape* assignedTo=0);
static bool IsGlobalHypothesis(const SMESH_Hypothesis* theHyp, SMESH_Mesh& aMesh);
//=======================================================================
SMESH_HypoFilter::SMESH_HypoFilter()
+ : myNbPredicates(0)
{
}
//=======================================================================
SMESH_HypoFilter::SMESH_HypoFilter( SMESH_HypoPredicate* aPredicate, bool notNegate )
+ : myNbPredicates(0)
{
add( notNegate ? AND : AND_NOT, aPredicate );
}
bool SMESH_HypoFilter::IsOk (const SMESH_Hypothesis* aHyp,
const TopoDS_Shape& aShape) const
{
- if ( myPredicates.empty() )
+ if ( IsEmpty() )
return true;
- bool ok = ( myPredicates.front()->_logical_op <= AND_NOT );
- list<SMESH_HypoPredicate*>::const_iterator pred = myPredicates.begin();
- for ( ; pred != myPredicates.end(); ++pred )
+ bool ok = ( myPredicates[0]->_logical_op <= AND_NOT );
+ for ( int i = 0; i < myNbPredicates; ++i )
{
- bool ok2 = (*pred)->IsOk( aHyp, aShape );
- switch ( (*pred)->_logical_op ) {
+ bool ok2 = myPredicates[i]->IsOk( aHyp, aShape );
+ switch ( myPredicates[i]->_logical_op ) {
case AND: ok = ok && ok2; break;
case AND_NOT: ok = ok && !ok2; break;
case OR: ok = ok || ok2; break;
SMESH_HypoFilter & SMESH_HypoFilter::Init ( SMESH_HypoPredicate* aPredicate, bool notNegate )
{
- list<SMESH_HypoPredicate*>::const_iterator pred = myPredicates.begin();
- for ( ; pred != myPredicates.end(); ++pred )
+ SMESH_HypoPredicate** pred = &myPredicates[0];
+ SMESH_HypoPredicate** end = &myPredicates[myNbPredicates];
+ for ( ; pred != end; ++pred )
delete *pred;
- myPredicates.clear();
+ myNbPredicates = 0;
add( notNegate ? AND : AND_NOT, aPredicate );
return *this;
SMESH_HypoFilter::~SMESH_HypoFilter()
{
- Init(0);
+ SMESH_HypoPredicate** pred = &myPredicates[0];
+ SMESH_HypoPredicate** end = &myPredicates[myNbPredicates];
+ for ( ; pred != end; ++pred )
+ delete *pred;
+ myNbPredicates = 0;
}
// Create and add predicates.
// Added predicates will be destroyed by filter when it dies
SMESH_HypoFilter();
- SMESH_HypoFilter( SMESH_HypoPredicate* aPredicate, bool notNegate = true );
+ explicit SMESH_HypoFilter( SMESH_HypoPredicate* aPredicate, bool notNegate = true );
// notNegate==false means !aPredicate->IsOk()
SMESH_HypoFilter & Init ( SMESH_HypoPredicate* aPredicate, bool notNegate = true );
SMESH_HypoFilter & And ( SMESH_HypoPredicate* aPredicate );
static SMESH_HypoPredicate* HasDim(const int theDim);
static SMESH_HypoPredicate* HasType(const int theHypType);
- bool IsEmpty() const { return myPredicates.empty(); }
+ bool IsEmpty() const { return myNbPredicates == 0; }
/*!
* \brief check aHyp or/and aShape it is assigned to
/*!
* \brief return true if contains no predicates
*/
- bool IsAny() const { return myPredicates.empty(); }
+ bool IsAny() const { return myNbPredicates > 0; }
~SMESH_HypoFilter();
protected:
// fields
- std::list<SMESH_HypoPredicate*> myPredicates;
+ //std::list<SMESH_HypoPredicate*> myPredicates;
+ SMESH_HypoPredicate* myPredicates[100];
+ int myNbPredicates;
// private methods
{
if ( pred ) {
pred->_logical_op = bool_op;
- myPredicates.push_back( pred );
+ myPredicates[ myNbPredicates++ ] = pred;
}
}
HYP_BAD_DIM, // bad dimension
HYP_BAD_SUBSHAPE, // shape is neither the main one, nor its sub-shape, nor a group
HYP_BAD_GEOMETRY, // shape geometry mismatches algorithm's expectation
- HYP_NEED_SHAPE // algorithm can work on shape only
+ HYP_NEED_SHAPE, // algorithm can work on shape only
+ HYP_INCOMPAT_HYPS // several additional hypotheses are incompatible one with other
};
static bool IsStatusFatal(Hypothesis_Status theStatus)
{ return theStatus >= HYP_UNKNOWN_FATAL; }
//
#include "SMESH_Mesh.hxx"
#include "SMESH_MesherHelper.hxx"
-#include "SMESH_subMesh.hxx"
+#include "SMDS_MeshVolume.hxx"
+#include "SMDS_SetIterator.hxx"
+#include "SMESHDS_Document.hxx"
+#include "SMESHDS_Group.hxx"
+#include "SMESHDS_GroupOnGeom.hxx"
+#include "SMESHDS_Script.hxx"
+#include "SMESHDS_TSubMeshHolder.hxx"
#include "SMESH_Gen.hxx"
-#include "SMESH_Hypothesis.hxx"
#include "SMESH_Group.hxx"
#include "SMESH_HypoFilter.hxx"
-#include "SMESHDS_Group.hxx"
-#include "SMESHDS_Script.hxx"
-#include "SMESHDS_GroupOnGeom.hxx"
-#include "SMESHDS_Document.hxx"
-#include "SMDS_MeshVolume.hxx"
-#include "SMDS_SetIterator.hxx"
+#include "SMESH_Hypothesis.hxx"
+#include "SMESH_subMesh.hxx"
#include "utilities.h"
typedef SMESH_HypoFilter THypType;
+class SMESH_Mesh::SubMeshHolder : public SMESHDS_TSubMeshHolder< SMESH_subMesh >
+{
+};
+
//=============================================================================
/*!
*
_shapeDiagonal = 0.0;
_callUp = NULL;
_myMeshDS->ShapeToMesh( PseudoShape() );
+ _subMeshHolder = new SubMeshHolder;
}
//================================================================================
_shapeDiagonal( 0.0 ),
_callUp( 0 )
{
+ _subMeshHolder = new SubMeshHolder;
}
namespace
_mapGroup.clear();
// delete sub-meshes
- map <int, SMESH_subMesh*>::iterator sm = _mapSubMesh.begin();
- for ( ; sm != _mapSubMesh.end(); ++sm )
- {
- delete sm->second;
- sm->second = 0;
- }
- _mapSubMesh.clear();
+ delete _subMeshHolder;
if ( _callUp) delete _callUp;
_callUp = 0;
{
// removal of a shape to mesh, delete objects referring to sub-shapes:
// - sub-meshes
- map <int, SMESH_subMesh *>::iterator i_sm = _mapSubMesh.begin();
- for ( ; i_sm != _mapSubMesh.end(); ++i_sm )
- delete i_sm->second;
- _mapSubMesh.clear();
+ _subMeshHolder->DeleteAll();
// - groups on geometry
map <int, SMESH_Group *>::iterator i_gr = _mapGroup.begin();
while ( i_gr != _mapGroup.end() ) {
//=============================================================================
SMESH_Hypothesis::Hypothesis_Status
- SMESH_Mesh::AddHypothesis(const TopoDS_Shape & aSubShape,
- int anHypId ) throw(SALOME_Exception)
+SMESH_Mesh::AddHypothesis(const TopoDS_Shape & aSubShape,
+ int anHypId,
+ std::string* anError ) throw(SALOME_Exception)
{
Unexpect aCatch(SalomeException);
if(MYDEBUG) MESSAGE("SMESH_Mesh::AddHypothesis");
+ if ( anError )
+ anError->clear();
+
SMESH_subMesh *subMesh = GetSubMesh(aSubShape);
if ( !subMesh || !subMesh->GetId())
return SMESH_Hypothesis::HYP_BAD_SUBSHAPE;
}
}
- // shape
+ // shape
- bool isAlgo = ( !anHyp->GetType() == SMESHDS_Hypothesis::PARAM_ALGO );
- int event = isAlgo ? SMESH_subMesh::ADD_ALGO : SMESH_subMesh::ADD_HYP;
+ bool isAlgo = ( anHyp->GetType() != SMESHDS_Hypothesis::PARAM_ALGO );
+ int event = isAlgo ? SMESH_subMesh::ADD_ALGO : SMESH_subMesh::ADD_HYP;
SMESH_Hypothesis::Hypothesis_Status ret = subMesh->AlgoStateEngine(event, anHyp);
+ if ( anError && SMESH_Hypothesis::IsStatusFatal(ret) && subMesh->GetComputeError() )
+ *anError = subMesh->GetComputeError()->myComment;
+
// sub-shapes
- if (!SMESH_Hypothesis::IsStatusFatal(ret) &&
- anHyp->GetDim() <= SMESH_Gen::GetShapeDim(aSubShape)) // is added on father
+ if ( !SMESH_Hypothesis::IsStatusFatal(ret) &&
+ anHyp->GetDim() <= SMESH_Gen::GetShapeDim(aSubShape)) // is added on father
{
event = isAlgo ? SMESH_subMesh::ADD_FATHER_ALGO : SMESH_subMesh::ADD_FATHER_HYP;
SMESH_Hypothesis::Hypothesis_Status ret2 =
- subMesh->SubMeshesAlgoStateEngine(event, anHyp);
+ subMesh->SubMeshesAlgoStateEngine(event, anHyp, /*exitOnFatal=*/true);
if (ret2 > ret)
+ {
ret = ret2;
+ if ( SMESH_Hypothesis::IsStatusFatal( ret ))
+ {
+ if ( anError && subMesh->GetComputeError() )
+ *anError = subMesh->GetComputeError()->myComment;
+ // remove anHyp
+ event = isAlgo ? SMESH_subMesh::REMOVE_ALGO : SMESH_subMesh::REMOVE_HYP;
+ subMesh->AlgoStateEngine(event, anHyp);
+ }
+ }
// check concurent hypotheses on ancestors
if (ret < SMESH_Hypothesis::HYP_CONCURENT && !isGlobalHyp )
SMESH_Mesh::GetHypothesisList(const TopoDS_Shape & aSubShape) const
throw(SALOME_Exception)
{
- Unexpect aCatch(SalomeException);
return _myMeshDS->GetHypothesis(aSubShape);
}
const bool andAncestors,
TopoDS_Shape* assignedTo) const
{
+ return GetHypothesis( const_cast< SMESH_Mesh* >(this)->GetSubMesh( aSubShape ),
+ aFilter, andAncestors, assignedTo );
+}
+
+//=======================================================================
+/*!
+ * \brief Return the hypothesis assigned to the shape of a sub-mesh
+ * \param aSubMesh - the sub-mesh to check
+ * \param aFilter - the hypothesis filter
+ * \param andAncestors - flag to check hypos assigned to ancestors of the shape
+ * \param assignedTo - to return the shape the found hypo is assigned to
+ * \retval SMESH_Hypothesis* - the first hypo passed through aFilter
+ */
+//=======================================================================
+
+const SMESH_Hypothesis * SMESH_Mesh::GetHypothesis(const SMESH_subMesh * aSubMesh,
+ const SMESH_HypoFilter& aFilter,
+ const bool andAncestors,
+ TopoDS_Shape* assignedTo) const
+{
+ if ( !aSubMesh ) return 0;
+
{
+ const TopoDS_Shape & aSubShape = aSubMesh->GetSubShape();
const list<const SMESHDS_Hypothesis*>& hypList = _myMeshDS->GetHypothesis(aSubShape);
list<const SMESHDS_Hypothesis*>::const_iterator hyp = hypList.begin();
for ( ; hyp != hypList.end(); hyp++ ) {
if ( andAncestors )
{
// user sorted submeshes of ancestors, according to stored submesh priority
- const list<SMESH_subMesh*> smList = getAncestorsSubMeshes( aSubShape );
- list<SMESH_subMesh*>::const_iterator smIt = smList.begin();
- for ( ; smIt != smList.end(); smIt++ )
+ std::vector< SMESH_subMesh * > & ancestors =
+ const_cast< std::vector< SMESH_subMesh * > & > ( aSubMesh->GetAncestors() );
+ SortByMeshOrder( ancestors );
+
+ vector<SMESH_subMesh*>::const_iterator smIt = ancestors.begin();
+ for ( ; smIt != ancestors.end(); smIt++ )
{
const TopoDS_Shape& curSh = (*smIt)->GetSubShape();
const list<const SMESHDS_Hypothesis*>& hypList = _myMeshDS->GetHypothesis(curSh);
//================================================================================
/*!
- * \brief Return hypothesis assigned to the shape
+ * \brief Return hypotheses assigned to the shape
* \param aSubShape - the shape to check
* \param aFilter - the hypothesis filter
* \param aHypList - the list of the found hypotheses
const bool andAncestors,
list< TopoDS_Shape > * assignedTo/*=0*/) const
{
+ return GetHypotheses( const_cast< SMESH_Mesh* >(this)->GetSubMesh( aSubShape ),
+ aFilter, aHypList, andAncestors, assignedTo );
+}
+
+//================================================================================
+/*!
+ * \brief Return hypotheses assigned to the shape of a sub-mesh
+ * \param aSubShape - the sub-mesh to check
+ * \param aFilter - the hypothesis filter
+ * \param aHypList - the list of the found hypotheses
+ * \param andAncestors - flag to check hypos assigned to ancestors of the shape
+ * \retval int - number of unique hypos in aHypList
+ */
+//================================================================================
+
+int SMESH_Mesh::GetHypotheses(const SMESH_subMesh * aSubMesh,
+ const SMESH_HypoFilter& aFilter,
+ list <const SMESHDS_Hypothesis * >& aHypList,
+ const bool andAncestors,
+ list< TopoDS_Shape > * assignedTo/*=0*/) const
+{
+ if ( !aSubMesh ) return 0;
+
set<string> hypTypes; // to exclude same type hypos from the result list
int nbHyps = 0;
// get hypos from aSubShape
{
+ const TopoDS_Shape & aSubShape = aSubMesh->GetSubShape();
const list<const SMESHDS_Hypothesis*>& hypList = _myMeshDS->GetHypothesis(aSubShape);
for ( hyp = hypList.begin(); hyp != hypList.end(); hyp++ )
- if ( aFilter.IsOk (cSMESH_Hyp( *hyp ), aSubShape) &&
- ( cSMESH_Hyp(*hyp)->IsAuxiliary() || !mainHypFound ) &&
- hypTypes.insert( (*hyp)->GetName() ).second )
+ {
+ const SMESH_Hypothesis* h = cSMESH_Hyp( *hyp );
+ if (( aFilter.IsOk( h, aSubShape )) &&
+ ( h->IsAuxiliary() || !mainHypFound ) &&
+ ( h->IsAuxiliary() || hypTypes.insert( h->GetName() ).second ))
{
aHypList.push_back( *hyp );
nbHyps++;
- if ( !cSMESH_Hyp(*hyp)->IsAuxiliary() )
+ if ( !h->IsAuxiliary() )
mainHypFound = true;
if ( assignedTo ) assignedTo->push_back( aSubShape );
}
+ }
}
// get hypos from ancestors of aSubShape
if ( andAncestors )
{
- TopTools_MapOfShape map;
-
// user sorted submeshes of ancestors, according to stored submesh priority
- const list<SMESH_subMesh*> smList = getAncestorsSubMeshes( aSubShape );
- list<SMESH_subMesh*>::const_iterator smIt = smList.begin();
- for ( ; smIt != smList.end(); smIt++ )
+ std::vector< SMESH_subMesh * > & ancestors =
+ const_cast< std::vector< SMESH_subMesh * > & > ( aSubMesh->GetAncestors() );
+ SortByMeshOrder( ancestors );
+
+ vector<SMESH_subMesh*>::const_iterator smIt = ancestors.begin();
+ for ( ; smIt != ancestors.end(); smIt++ )
{
const TopoDS_Shape& curSh = (*smIt)->GetSubShape();
- if ( !map.Add( curSh ))
- continue;
const list<const SMESHDS_Hypothesis*>& hypList = _myMeshDS->GetHypothesis(curSh);
for ( hyp = hypList.begin(); hyp != hypList.end(); hyp++ )
- if (aFilter.IsOk( cSMESH_Hyp( *hyp ), curSh ) &&
- ( cSMESH_Hyp(*hyp)->IsAuxiliary() || !mainHypFound ) &&
- hypTypes.insert( (*hyp)->GetName() ).second )
+ {
+ const SMESH_Hypothesis* h = cSMESH_Hyp( *hyp );
+ if (( aFilter.IsOk( h, curSh )) &&
+ ( h->IsAuxiliary() || !mainHypFound ) &&
+ ( h->IsAuxiliary() || hypTypes.insert( h->GetName() ).second ))
{
aHypList.push_back( *hyp );
nbHyps++;
- if ( !cSMESH_Hyp(*hyp)->IsAuxiliary() )
+ if ( !h->IsAuxiliary() )
mainHypFound = true;
if ( assignedTo ) assignedTo->push_back( curSh );
}
+ }
}
}
return nbHyps;
SMESH_subMesh *SMESH_Mesh::GetSubMesh(const TopoDS_Shape & aSubShape)
throw(SALOME_Exception)
{
- Unexpect aCatch(SalomeException);
- SMESH_subMesh *aSubMesh;
int index = _myMeshDS->ShapeToIndex(aSubShape);
+ if ( !index && aSubShape.IsNull() )
+ return 0;
// for submeshes on GEOM Group
if (( !index || index > _nbSubShapes ) && aSubShape.ShapeType() == TopAbs_COMPOUND ) {
fillAncestorsMap( _myMeshDS->IndexToShape( ++_nbSubShapes ));
}
}
-// if ( !index )
-// return NULL; // neither sub-shape nor a group
+ // if ( !index )
+ // return NULL; // neither sub-shape nor a group
- map <int, SMESH_subMesh *>::iterator i_sm = _mapSubMesh.find(index);
- if ( i_sm != _mapSubMesh.end())
- {
- aSubMesh = i_sm->second;
- }
- else
+ SMESH_subMesh* aSubMesh = _subMeshHolder->Get( index );
+ if ( !aSubMesh )
{
aSubMesh = new SMESH_subMesh(index, this, _myMeshDS, aSubShape);
- _mapSubMesh[index] = aSubMesh;
+ _subMeshHolder->Add( index, aSubMesh );
+
+ // include non-computable sub-meshes in SMESH_subMesh::_ancestors of sub-submeshes
+ switch ( aSubShape.ShapeType() ) {
+ case TopAbs_COMPOUND:
+ case TopAbs_WIRE:
+ case TopAbs_SHELL:
+ for ( TopoDS_Iterator subIt( aSubShape ); subIt.More(); subIt.Next() )
+ {
+ SMESH_subMesh* sm = GetSubMesh( subIt.Value() );
+ SMESH_subMeshIteratorPtr smIt = sm->getDependsOnIterator(/*inclideSelf=*/true);
+ while ( smIt->more() )
+ smIt->next()->ClearAncestors();
+ }
+ default:;
+ }
}
return aSubMesh;
}
SMESH_subMesh *SMESH_Mesh::GetSubMeshContaining(const TopoDS_Shape & aSubShape) const
throw(SALOME_Exception)
{
- Unexpect aCatch(SalomeException);
- SMESH_subMesh *aSubMesh = NULL;
-
int index = _myMeshDS->ShapeToIndex(aSubShape);
-
- map <int, SMESH_subMesh *>::const_iterator i_sm = _mapSubMesh.find(index);
- if ( i_sm != _mapSubMesh.end())
- aSubMesh = i_sm->second;
-
- return aSubMesh;
+ return GetSubMeshContaining( index );
}
+
//=============================================================================
/*!
* Get the SMESH_subMesh object implementation. Dont create it, return null
SMESH_subMesh *SMESH_Mesh::GetSubMeshContaining(const int aShapeID) const
throw(SALOME_Exception)
{
- Unexpect aCatch(SalomeException);
-
- map <int, SMESH_subMesh *>::const_iterator i_sm = _mapSubMesh.find(aShapeID);
- if (i_sm == _mapSubMesh.end())
- return NULL;
- return i_sm->second;
+ SMESH_subMesh *aSubMesh = _subMeshHolder->Get( aShapeID );
+
+ return aSubMesh;
}
+
//================================================================================
/*!
* \brief Return submeshes of groups containing the given sub-shape
SMESH_Mesh::GetGroupSubMeshesContaining(const TopoDS_Shape & aSubShape) const
throw(SALOME_Exception)
{
- Unexpect aCatch(SalomeException);
list<SMESH_subMesh*> found;
SMESH_subMesh * subMesh = GetSubMeshContaining(aSubShape);
return found;
// submeshes of groups have max IDs, so search from the map end
- map<int, SMESH_subMesh *>::const_reverse_iterator i_sm;
- for ( i_sm = _mapSubMesh.rbegin(); i_sm != _mapSubMesh.rend(); ++i_sm) {
- SMESHDS_SubMesh * ds = i_sm->second->GetSubMeshDS();
+SMESH_subMeshIteratorPtr smIt( _subMeshHolder->GetIterator( /*reverse=*/true ) );
+ while ( smIt->more() ) {
+ SMESH_subMesh* sm = smIt->next();
+ SMESHDS_SubMesh * ds = sm->GetSubMeshDS();
if ( ds && ds->IsComplexSubmesh() ) {
- if ( SMESH_MesherHelper::IsSubShape( aSubShape, i_sm->second->GetSubShape() ))
+ if ( SMESH_MesherHelper::IsSubShape( aSubShape, sm->GetSubShape() ))
{
- found.push_back( i_sm->second );
+ found.push_back( sm );
//break;
}
} else {
if ( found.empty() ) // maybe the main shape is a COMPOUND (issue 0021530)
{
- if ( SMESH_subMesh * mainSM = GetSubMeshContaining(1))
+ if ( SMESH_subMesh * mainSM = GetSubMeshContaining(1) )
if ( mainSM->GetSubShape().ShapeType() == TopAbs_COMPOUND )
{
TopoDS_Iterator it( mainSM->GetSubShape() );
if ( !aSubMesh || !aSubMesh->IsApplicableHypotesis( hyp ))
return false;
- const TopoDS_Shape & aSubShape = const_cast<SMESH_subMesh*>( aSubMesh )->GetSubShape();
-
- SMESH_Algo *algo = _gen->GetAlgo(*this, aSubShape );
+ SMESH_Algo *algo = aSubMesh->GetAlgo();
// algorithm
if (anHyp->GetType() > SMESHDS_Hypothesis::PARAM_ALGO)
if (algo)
{
// look trough hypotheses used by algo
- SMESH_HypoFilter hypoKind;
- if ( algo->InitCompatibleHypoFilter( hypoKind, !hyp->IsAuxiliary() )) {
+ const SMESH_HypoFilter* hypoKind;
+ if (( hypoKind = algo->GetCompatibleHypoFilter( !hyp->IsAuxiliary() ))) {
list <const SMESHDS_Hypothesis * > usedHyps;
- if ( GetHypotheses( aSubShape, hypoKind, usedHyps, true ))
+ if ( GetHypotheses( aSubMesh, *hypoKind, usedHyps, true ))
return ( find( usedHyps.begin(), usedHyps.end(), anHyp ) != usedHyps.end() );
}
}
- // look through all assigned hypotheses
- //SMESH_HypoFilter filter( SMESH_HypoFilter::Is( hyp ));
- return false; //GetHypothesis( aSubShape, filter, true );
+ return false;
}
//=============================================================================
*/
//=============================================================================
-const list < SMESH_subMesh * >&
-SMESH_Mesh::GetSubMeshUsingHypothesis(SMESHDS_Hypothesis * anHyp)
- throw(SALOME_Exception)
-{
- Unexpect aCatch(SalomeException);
- if(MYDEBUG) MESSAGE("SMESH_Mesh::GetSubMeshUsingHypothesis");
- map < int, SMESH_subMesh * >::iterator itsm;
- _subMeshesUsingHypothesisList.clear();
- for (itsm = _mapSubMesh.begin(); itsm != _mapSubMesh.end(); itsm++)
- {
- SMESH_subMesh *aSubMesh = (*itsm).second;
- if ( IsUsedHypothesis ( anHyp, aSubMesh ))
- _subMeshesUsingHypothesisList.push_back(aSubMesh);
- }
- return _subMeshesUsingHypothesisList;
-}
+// const list < SMESH_subMesh * >&
+// SMESH_Mesh::GetSubMeshUsingHypothesis(SMESHDS_Hypothesis * anHyp)
+// throw(SALOME_Exception)
+// {
+// _subMeshesUsingHypothesisList.clear();
+// SMESH_subMeshIteratorPtr smIt( _subMeshHolder->GetIterator() );
+// while ( smIt->more() )
+// {
+// SMESH_subMesh* aSubMesh = smIt->next();
+// if ( IsUsedHypothesis ( anHyp, aSubMesh ))
+// _subMeshesUsingHypothesisList.push_back( aSubMesh );
+// }
+// return _subMeshesUsingHypothesisList;
+// }
//=======================================================================
//function : NotifySubMeshesHypothesisModification
if (_callUp)
_callUp->HypothesisModified();
- const SMESH_Algo *foundAlgo = 0;
- SMESH_HypoFilter algoKind, compatibleHypoKind;
+ SMESH_Algo *algo;
+ const SMESH_HypoFilter* compatibleHypoKind;
list <const SMESHDS_Hypothesis * > usedHyps;
+ // keep sub-meshes not to miss ones whose state can change due to notifying others
+ vector< SMESH_subMesh* > smToNotify;
- map < int, SMESH_subMesh * >::iterator itsm;
- for (itsm = _mapSubMesh.begin(); itsm != _mapSubMesh.end(); itsm++)
+ SMESH_subMeshIteratorPtr smIt( _subMeshHolder->GetIterator() );
+ while ( smIt->more() )
{
- SMESH_subMesh *aSubMesh = (*itsm).second;
- if ( aSubMesh->IsApplicableHypotesis( hyp ))
+ SMESH_subMesh* aSubMesh = smIt->next();
+
+ // if aSubMesh meshing depends on hyp,
+ // we call aSubMesh->AlgoStateEngine( MODIF_HYP, hyp ) that causes either
+ // 1) clearing of already computed aSubMesh or
+ // 2) changing algo_state from MISSING_HYP to HYP_OK when parameters of hyp becomes valid,
+ // other possible changes are not interesting. (IPAL0052457 - assigning hyp performance pb)
+ if ( aSubMesh->GetComputeState() != SMESH_subMesh::COMPUTE_OK &&
+ aSubMesh->GetComputeState() != SMESH_subMesh::FAILED_TO_COMPUTE &&
+ aSubMesh->GetAlgoState() != SMESH_subMesh::MISSING_HYP )
+ continue;
+
+ const TopoDS_Shape & aSubShape = aSubMesh->GetSubShape();
+
+ if (( aSubMesh->IsApplicableHypotesis( hyp )) &&
+ ( algo = aSubMesh->GetAlgo() ) &&
+ ( compatibleHypoKind = algo->GetCompatibleHypoFilter( !hyp->IsAuxiliary() )) &&
+ ( compatibleHypoKind->IsOk( hyp, aSubShape )))
{
- const TopoDS_Shape & aSubShape = aSubMesh->GetSubShape();
-
- if ( !foundAlgo ) // init filter for algo search
- algoKind.Init( THypType::IsAlgo() ).And( THypType::IsApplicableTo( aSubShape ));
-
- const SMESH_Algo *algo = static_cast<const SMESH_Algo*>
- ( GetHypothesis( aSubShape, algoKind, true ));
-
- if ( algo )
+ // check if hyp is used by algo
+ usedHyps.clear();
+ if ( GetHypotheses( aSubMesh, *compatibleHypoKind, usedHyps, true ) &&
+ find( usedHyps.begin(), usedHyps.end(), hyp ) != usedHyps.end() )
{
- bool sameAlgo = ( algo == foundAlgo );
- if ( !sameAlgo && foundAlgo )
- sameAlgo = ( strcmp( algo->GetName(), foundAlgo->GetName() ) == 0);
-
- if ( !sameAlgo ) { // init filter for used hypos search
- if ( !algo->InitCompatibleHypoFilter( compatibleHypoKind, !hyp->IsAuxiliary() ))
- continue; // algo does not use any hypothesis
- foundAlgo = algo;
- }
-
- // check if hyp is used by algo
- usedHyps.clear();
- if ( GetHypotheses( aSubShape, compatibleHypoKind, usedHyps, true ) &&
- find( usedHyps.begin(), usedHyps.end(), hyp ) != usedHyps.end() )
- {
- aSubMesh->AlgoStateEngine(SMESH_subMesh::MODIF_HYP,
- const_cast< SMESH_Hypothesis*>( hyp ));
- }
+ smToNotify.push_back( aSubMesh );
}
}
}
+
+ for ( size_t i = 0; i < smToNotify.size(); ++i )
+ {
+ smToNotify[i]->AlgoStateEngine(SMESH_subMesh::MODIF_HYP,
+ const_cast< SMESH_Hypothesis*>( hyp ));
+ }
+
HasModificationsToDiscard(); // to reset _isModified flag if mesh becomes empty
GetMeshDS()->Modified();
}
// return true if the next Compute() will be partial and
// existing but changed elements may prevent successful re-compute
bool hasComputed = false, hasNotComputed = false;
- map <int, SMESH_subMesh*>::const_iterator i_sm = _mapSubMesh.begin();
- for ( ; i_sm != _mapSubMesh.end() ; ++i_sm )
- switch ( i_sm->second->GetSubShape().ShapeType() )
+SMESH_subMeshIteratorPtr smIt( _subMeshHolder->GetIterator() );
+ while ( smIt->more() )
+ {
+ const SMESH_subMesh* aSubMesh = smIt->next();
+ switch ( aSubMesh->GetSubShape().ShapeType() )
{
case TopAbs_EDGE:
case TopAbs_FACE:
case TopAbs_SOLID:
- if ( i_sm->second->IsMeshComputed() )
+ if ( aSubMesh->IsMeshComputed() )
hasComputed = true;
else
hasNotComputed = true;
if ( hasComputed && hasNotComputed)
return true;
}
-
+ }
if ( NbNodes() < 1 )
const_cast<SMESH_Mesh*>(this)->_isModified = false;
void SMESH_Mesh::fillAncestorsMap(const TopoDS_Shape& theShape)
{
-
int desType, ancType;
if ( !theShape.IsSame( GetShapeToMesh()) && theShape.ShapeType() == TopAbs_COMPOUND )
{
ancList.InsertBefore( theShape, ancIt );
}
}
+ else // else added for 52457: Addition of hypotheses is 8 time longer than meshing
{
for ( desType = TopAbs_VERTEX; desType > TopAbs_COMPOUND; desType-- )
for ( ancType = desType - 1; ancType >= TopAbs_COMPOUND; ancType-- )
// visit COMPOUNDs inside a COMPOUND that are not reachable by TopExp_Explorer
if ( theShape.ShapeType() == TopAbs_COMPOUND )
{
- for ( TopoDS_Iterator sIt(theShape); sIt.More(); sIt.Next() )
- if ( sIt.Value().ShapeType() == TopAbs_COMPOUND )
- fillAncestorsMap( sIt.Value() );
+ TopoDS_Iterator sIt(theShape);
+ if ( sIt.More() && sIt.Value().ShapeType() == TopAbs_COMPOUND )
+ for ( ; sIt.More(); sIt.Next() )
+ if ( sIt.Value().ShapeType() == TopAbs_COMPOUND )
+ fillAncestorsMap( sIt.Value() );
}
}
*/
//=============================================================================
-bool SMESH_Mesh::SortByMeshOrder(list<SMESH_subMesh*>& theListToSort) const
+ bool SMESH_Mesh::SortByMeshOrder(std::vector<SMESH_subMesh*>& theListToSort) const
{
if ( !_mySubMeshOrder.size() || theListToSort.size() < 2)
return true;
bool res = false;
- list<SMESH_subMesh*> onlyOrderedList;
+ vector<SMESH_subMesh*> onlyOrderedList;
// collect all ordered submeshes in one list as pointers
// and get their positions within theListToSort
- typedef list<SMESH_subMesh*>::iterator TPosInList;
+ typedef vector<SMESH_subMesh*>::iterator TPosInList;
map< int, TPosInList > sortedPos;
TPosInList smBeg = theListToSort.begin(), smEnd = theListToSort.end();
TListOfListOfInt::const_iterator listIdsIt = _mySubMeshOrder.begin();
- for( ; listIdsIt != _mySubMeshOrder.end(); listIdsIt++) {
+ for( ; listIdsIt != _mySubMeshOrder.end(); listIdsIt++)
+ {
const TListOfInt& listOfId = *listIdsIt;
+ // convert sm ids to sm's
+ vector<SMESH_subMesh*> smVec;
TListOfInt::const_iterator idIt = listOfId.begin();
for ( ; idIt != listOfId.end(); idIt++ ) {
if ( SMESH_subMesh * sm = GetSubMeshContaining( *idIt )) {
- TPosInList smPos = find( smBeg, smEnd, sm );
- if ( smPos != smEnd ) {
- onlyOrderedList.push_back( sm );
- sortedPos[ distance( smBeg, smPos )] = smPos;
+ if ( sm->GetSubMeshDS() && sm->GetSubMeshDS()->IsComplexSubmesh() )
+ {
+ SMESHDS_SubMeshIteratorPtr smdsIt = sm->GetSubMeshDS()->GetSubMeshIterator();
+ while ( smdsIt->more() )
+ {
+ const SMESHDS_SubMesh* smDS = smdsIt->next();
+ if (( sm = GetSubMeshContaining( smDS->GetID() )))
+ smVec.push_back( sm );
+ }
+ }
+ else
+ {
+ smVec.push_back( sm );
}
}
}
+ // find smVec items in theListToSort
+ for ( size_t i = 0; i < smVec.size(); ++i )
+ {
+ TPosInList smPos = find( smBeg, smEnd, smVec[i] );
+ if ( smPos != smEnd ) {
+ onlyOrderedList.push_back( smVec[i] );
+ sortedPos[ distance( smBeg, smPos )] = smPos;
+ }
+ }
}
if (onlyOrderedList.size() < 2)
return res;
res = true;
- list<SMESH_subMesh*>::iterator onlyBIt = onlyOrderedList.begin();
- list<SMESH_subMesh*>::iterator onlyEIt = onlyOrderedList.end();
+ vector<SMESH_subMesh*>::iterator onlyBIt = onlyOrderedList.begin();
+ vector<SMESH_subMesh*>::iterator onlyEIt = onlyOrderedList.end();
// iterate on ordered submeshes and insert them in detected positions
map< int, TPosInList >::iterator i_pos = sortedPos.begin();
*/
//=============================================================================
-list<SMESH_subMesh*>
-SMESH_Mesh::getAncestorsSubMeshes (const TopoDS_Shape& theSubShape) const
+void SMESH_Mesh::getAncestorsSubMeshes (const TopoDS_Shape& theSubShape,
+ std::vector< SMESH_subMesh* >& theSubMeshes) const
{
- list<SMESH_subMesh*> listOfSubMesh;
+ theSubMeshes.clear();
TopTools_ListIteratorOfListOfShape it( GetAncestors( theSubShape ));
for (; it.More(); it.Next() )
if ( SMESH_subMesh* sm = GetSubMeshContaining( it.Value() ))
- listOfSubMesh.push_back(sm);
+ theSubMeshes.push_back(sm);
// sort submeshes according to stored mesh order
- SortByMeshOrder( listOfSubMesh );
-
- return listOfSubMesh;
+ SortByMeshOrder( theSubMeshes );
}
bool theMakeRequiredGroups = true );
SMESH_Hypothesis::Hypothesis_Status
- AddHypothesis(const TopoDS_Shape & aSubShape, int anHypId)
+ AddHypothesis(const TopoDS_Shape & aSubShape, int anHypId, std::string* error=0)
throw(SALOME_Exception);
SMESH_Hypothesis::Hypothesis_Status
const bool andAncestors,
std::list< TopoDS_Shape > * assignedTo=0) const;
+ const SMESH_Hypothesis * GetHypothesis(const SMESH_subMesh * aSubMesh,
+ const SMESH_HypoFilter& aFilter,
+ const bool andAncestors,
+ TopoDS_Shape* assignedTo=0) const;
+
+ int GetHypotheses(const SMESH_subMesh * aSubMesh,
+ const SMESH_HypoFilter& aFilter,
+ std::list< const SMESHDS_Hypothesis * >& aHypList,
+ const bool andAncestors,
+ std::list< TopoDS_Shape > * assignedTo=0) const;
+
SMESH_Hypothesis * GetHypothesis(const int aHypID) const;
const std::list<SMESHDS_Command*> & GetLog() throw(SALOME_Exception);
*/
void NotifySubMeshesHypothesisModification(const SMESH_Hypothesis* theChangedHyp);
- const std::list < SMESH_subMesh * >&
- GetSubMeshUsingHypothesis(SMESHDS_Hypothesis * anHyp) throw(SALOME_Exception);
+ // const std::list < SMESH_subMesh * >&
+ // GetSubMeshUsingHypothesis(SMESHDS_Hypothesis * anHyp) throw(SALOME_Exception);
/*!
* \brief Return True if anHyp is used to mesh aSubShape
*/
const TListOfListOfInt& GetMeshOrder() const;
// sort submeshes according to stored mesh order
- bool SortByMeshOrder(std::list<SMESH_subMesh*>& theListToSort) const;
+ bool SortByMeshOrder(std::vector<SMESH_subMesh*>& theListToSort) const;
// return true if given order of sub-meshes is OK
bool IsOrderOK( const SMESH_subMesh* smBefore,
private:
void fillAncestorsMap(const TopoDS_Shape& theShape);
- std::list<SMESH_subMesh*> getAncestorsSubMeshes
- (const TopoDS_Shape& theSubShape) const;
+ void getAncestorsSubMeshes(const TopoDS_Shape& theSubShape,
+ std::vector< SMESH_subMesh* >& theSubMeshes) const;
protected:
int _id; // id given by creator (unique within the creator instance)
int _groupId; // id generator for group objects
int _nbSubShapes; // initial nb of subshapes in the shape to mesh
bool _isShapeToMesh;// set to true when a shape is given (only once)
- std::list <SMESH_subMesh*> _subMeshesUsingHypothesisList;
+ //std::list <SMESH_subMesh*> _subMeshesUsingHypothesisList;
SMESHDS_Document * _myDocument;
SMESHDS_Mesh * _myMeshDS;
SMESH_Gen * _gen;
- std::map <int, SMESH_subMesh*> _mapSubMesh;
- std::map <int, SMESH_Group*> _mapGroup;
+ std::map <int, SMESH_Group*> _mapGroup;
+
+ class SubMeshHolder;
+ SubMeshHolder* _subMeshHolder;
bool _isAutoColor;
bool _isModified; //!< modified since last total re-compute, issue 0020693
TopTools_IndexedDataMapOfShapeListOfShape _mapAncestors;
+ mutable std::vector<SMESH_subMesh*> _ancestorSubMeshes; // to speed up GetHypothes[ei]s()
+
TListOfListOfInt _mySubMeshOrder;
// Struct calling methods at CORBA API implementation level, used to
- // 1) make an upper level be consistent with a lower one when group removal
- // is invoked by hyp modification (issue 0020918)
+ // 1) make an upper level (SMESH_I) be consistent with a lower one (SMESH)
+ // when group removal is invoked by hyp modification (issue 0020918)
// 2) to forget not loaded mesh data at hyp modification
TCallUp* _callUp;
}
else
{
- const map<int,SMESHDS_SubMesh*>& id2sm = GetMeshDS()->SubMeshes();
- map<int,SMESHDS_SubMesh*>::const_iterator id_sm = id2sm.begin();
- for ( ; id_sm != id2sm.end(); ++id_sm )
- if ( id_sm->second->Contains( theElem ))
- return id_sm->first;
+ SMESHDS_SubMeshIteratorPtr smIt = GetMeshDS()->SubMeshes();
+ while ( const SMESHDS_SubMesh* sm = smIt->next() )
+ if ( sm->Contains( theElem ))
+ return sm->GetID();
}
- //MESSAGE ("::FindShape() - SHAPE NOT FOUND")
return 0;
}
return nbReori;
}
+//================================================================================
+/*!
+ * \brief Reorient faces basing on orientation of adjacent volumes.
+ * \param theFaces - faces to reorient. If empty, all mesh faces are treated.
+ * \param theVolumes - reference volumes.
+ * \param theOutsideNormal - to orient faces to have their normal
+ * pointing either \a outside or \a inside the adjacent volumes.
+ * \return number of reoriented faces.
+ */
+//================================================================================
+
+int SMESH_MeshEditor::Reorient2DBy3D (TIDSortedElemSet & theFaces,
+ TIDSortedElemSet & theVolumes,
+ const bool theOutsideNormal)
+{
+ int nbReori = 0;
+
+ SMDS_ElemIteratorPtr faceIt;
+ if ( theFaces.empty() )
+ faceIt = GetMeshDS()->elementsIterator( SMDSAbs_Face );
+ else
+ faceIt = elemSetIterator( theFaces );
+
+ vector< const SMDS_MeshNode* > faceNodes;
+ TIDSortedElemSet checkedVolumes;
+ set< const SMDS_MeshNode* > faceNodesSet;
+ SMDS_VolumeTool volumeTool;
+
+ while ( faceIt->more() ) // loop on given faces
+ {
+ const SMDS_MeshElement* face = faceIt->next();
+ if ( face->GetType() != SMDSAbs_Face )
+ continue;
+
+ const int nbCornersNodes = face->NbCornerNodes();
+ faceNodes.assign( face->begin_nodes(), face->end_nodes() );
+
+ checkedVolumes.clear();
+ SMDS_ElemIteratorPtr vIt = faceNodes[ 0 ]->GetInverseElementIterator( SMDSAbs_Volume );
+ while ( vIt->more() )
+ {
+ const SMDS_MeshElement* volume = vIt->next();
+
+ if ( !checkedVolumes.insert( volume ).second )
+ continue;
+ if ( !theVolumes.empty() && !theVolumes.count( volume ))
+ continue;
+
+ // is volume adjacent?
+ bool allNodesCommon = true;
+ for ( int iN = 1; iN < nbCornersNodes && allNodesCommon; ++iN )
+ allNodesCommon = ( volume->GetNodeIndex( faceNodes[ iN ]) > -1 );
+ if ( !allNodesCommon )
+ continue;
+
+ // get nodes of a corresponding volume facet
+ faceNodesSet.clear();
+ faceNodesSet.insert( faceNodes.begin(), faceNodes.end() );
+ volumeTool.Set( volume );
+ int facetID = volumeTool.GetFaceIndex( faceNodesSet );
+ if ( facetID < 0 ) continue;
+ volumeTool.SetExternalNormal();
+ const SMDS_MeshNode** facetNodes = volumeTool.GetFaceNodes( facetID );
+
+ // compare order of faceNodes and facetNodes
+ const int iQ = 1 + ( nbCornersNodes < faceNodes.size() );
+ int iNN[2];
+ for ( int i = 0; i < 2; ++i )
+ {
+ const SMDS_MeshNode* n = facetNodes[ i*iQ ];
+ for ( int iN = 0; iN < nbCornersNodes; ++iN )
+ if ( faceNodes[ iN ] == n )
+ {
+ iNN[ i ] = iN;
+ break;
+ }
+ }
+ bool isOutside = Abs( iNN[0]-iNN[1] ) == 1 ? iNN[0] < iNN[1] : iNN[0] > iNN[1];
+ if ( isOutside != theOutsideNormal )
+ nbReori += Reorient( face );
+ }
+ } // loop on given faces
+
+ return nbReori;
+}
+
//=======================================================================
//function : getBadRate
//purpose :
if ( ( theMakeGroups && theCopy ) ||
( theMakeGroups && theTargetMesh ) )
- newGroupIDs = generateGroups( srcNodes, srcElems, groupPostfix, theTargetMesh );
+ newGroupIDs = generateGroups( srcNodes, srcElems, groupPostfix, theTargetMesh, false );
return newGroupIDs;
}
//=======================================================================
/*!
* \brief Create groups of elements made during transformation
- * \param nodeGens - nodes making corresponding myLastCreatedNodes
- * \param elemGens - elements making corresponding myLastCreatedElems
- * \param postfix - to append to names of new groups
+ * \param nodeGens - nodes making corresponding myLastCreatedNodes
+ * \param elemGens - elements making corresponding myLastCreatedElems
+ * \param postfix - to append to names of new groups
+ * \param targetMesh - mesh to create groups in
+ * \param topPresent - is there "top" elements that are created by sweeping
*/
//=======================================================================
SMESH_MeshEditor::generateGroups(const SMESH_SequenceOfElemPtr& nodeGens,
const SMESH_SequenceOfElemPtr& elemGens,
const std::string& postfix,
- SMESH_Mesh* targetMesh)
+ SMESH_Mesh* targetMesh,
+ const bool topPresent)
{
PGroupIDs newGroupIDs( new list<int> );
SMESH_Mesh* mesh = targetMesh ? targetMesh : GetMesh();
// Sort existing groups by types and collect their names
- // to store an old group and a generated new ones
+ // containers to store an old group and generated new ones;
+ // 1st new group is for result elems of different type than a source one;
+ // 2nd new group is for same type result elems ("top" group at extrusion)
using boost::tuple;
using boost::make_tuple;
typedef tuple< SMESHDS_GroupBase*, SMESHDS_Group*, SMESHDS_Group* > TOldNewGroup;
// Loop on nodes and elements to add them in new groups
+ vector< const SMDS_MeshElement* > resultElems;
for ( int isNodes = 0; isNodes < 2; ++isNodes )
{
const SMESH_SequenceOfElemPtr& gens = isNodes ? nodeGens : elemGens;
continue;
}
// collect all elements made by the iElem-th sourceElem
- list< const SMDS_MeshElement* > resultElems;
+ resultElems.clear();
if ( const SMDS_MeshElement* resElem = elems( iElem ))
if ( resElem != sourceElem )
resultElems.push_back( resElem );
if ( resElem != sourceElem )
resultElems.push_back( resElem );
- // there must be a top element
const SMDS_MeshElement* topElem = 0;
- if ( isNodes )
+ if ( isNodes ) // there must be a top element
{
topElem = resultElems.back();
resultElems.pop_back();
}
else
{
- list< const SMDS_MeshElement* >::reverse_iterator resElemIt = resultElems.rbegin();
+ vector< const SMDS_MeshElement* >::reverse_iterator resElemIt = resultElems.rbegin();
for ( ; resElemIt != resultElems.rend() ; ++resElemIt )
if ( (*resElemIt)->GetType() == sourceElem->GetType() )
{
topElem = *resElemIt;
- resultElems.erase( --(resElemIt.base()) ); // erase *resElemIt
+ *resElemIt = 0; // erase *resElemIt
break;
}
}
-
// add resultElems to groups originted from ones the sourceElem belongs to
list< TOldNewGroup >::iterator gOldNew, gLast = groupsOldNew.end();
for ( gOldNew = groupsOldNew.begin(); gOldNew != gLast; ++gOldNew )
{
// fill in a new group
SMDS_MeshGroup & newGroup = gOldNew->get<1>()->SMDSGroup();
- list< const SMDS_MeshElement* >::iterator resLast = resultElems.end(), resElemIt;
+ vector< const SMDS_MeshElement* >::iterator resLast = resultElems.end(), resElemIt;
for ( resElemIt = resultElems.begin(); resElemIt != resLast; ++resElemIt )
- newGroup.Add( *resElemIt );
+ if ( *resElemIt )
+ newGroup.Add( *resElemIt );
// fill a "top" group
if ( topElem )
{
SMDS_MeshGroup & newTopGroup = gOldNew->get<2>()->SMDSGroup();
newTopGroup.Add( topElem );
- }
+ }
}
}
} // loop on created elements
SMESHDS_GroupBase* oldGroupDS = orderedOldNewGroups[i]->get<0>();
SMESHDS_Group* newGroups[2] = { orderedOldNewGroups[i]->get<1>(),
orderedOldNewGroups[i]->get<2>() };
- const int nbNewGroups = !newGroups[0]->IsEmpty() + !newGroups[1]->IsEmpty();
for ( int is2nd = 0; is2nd < 2; ++is2nd )
{
SMESHDS_Group* newGroupDS = newGroups[ is2nd ];
newGroupDS->SetType( newGroupDS->GetElements()->next()->GetType() );
// make a name
- const bool isTop = ( nbNewGroups == 2 &&
+ const bool isTop = ( topPresent &&
newGroupDS->GetType() == oldGroupDS->GetType() &&
is2nd );
string name = oldGroupDS->GetStoreName();
+ { // remove trailing whitespaces (issue 22599)
+ size_t size = name.size();
+ while ( size > 1 && isspace( name[ size-1 ]))
+ --size;
+ if ( size != name.size() )
+ {
+ name.resize( size );
+ oldGroupDS->SetStoreName( name.c_str() );
+ }
+ }
if ( !targetMesh ) {
string suffix = ( isTop ? "top": postfix.c_str() );
name += "_";
// Reverse theFaces whose orientation to be same as that of theFace
// oriented according to theDirection. Return nb of reoriented faces
+ int Reorient2DBy3D (TIDSortedElemSet & theFaces,
+ TIDSortedElemSet & theVolumes,
+ const bool theOutsideNormal);
+ // Reorient faces basing on orientation of adjacent volumes.
+ // Return nb of reoriented faces
+
/*!
* \brief Fuse neighbour triangles into quadrangles.
* \param theElems - The triangles to be fused.
* \param nodeGens - nodes making corresponding myLastCreatedNodes
* \param elemGens - elements making corresponding myLastCreatedElems
* \param postfix - to append to names of new groups
+ * \param targetMesh - mesh to create groups in
+ * \param topPresent - is there "top" elements that are created by sweeping
*/
PGroupIDs generateGroups(const SMESH_SequenceOfElemPtr& nodeGens,
const SMESH_SequenceOfElemPtr& elemGens,
const std::string& postfix,
- SMESH_Mesh* targetMesh=0);
+ SMESH_Mesh* targetMesh=0,
+ const bool topPresent=true);
/*!
* \brief Create elements by sweeping an element
* \param elem - element to sweep
*/
//================================================================================
-void SMESH_MesherHelper::AddTLinks(const SMDS_MeshEdge* edge)
+bool SMESH_MesherHelper::AddTLinks(const SMDS_MeshEdge* edge)
{
- if ( edge->IsQuadratic() )
+ if ( edge && edge->IsQuadratic() )
AddTLinkNode(edge->GetNode(0), edge->GetNode(1), edge->GetNode(2));
+ else
+ return false;
+ return true;
}
//================================================================================
*/
//================================================================================
-void SMESH_MesherHelper::AddTLinks(const SMDS_MeshFace* f)
+bool SMESH_MesherHelper::AddTLinks(const SMDS_MeshFace* f)
{
+ bool isQuad = true;
if ( !f->IsPoly() )
switch ( f->NbNodes() ) {
case 7:
AddTLinkNode(f->GetNode(2),f->GetNode(3),f->GetNode(6));
AddTLinkNode(f->GetNode(3),f->GetNode(0),f->GetNode(7)); break;
default:;
+ isQuad = false;
}
+ return isQuad;
}
//================================================================================
*/
//================================================================================
-void SMESH_MesherHelper::AddTLinks(const SMDS_MeshVolume* volume)
+bool SMESH_MesherHelper::AddTLinks(const SMDS_MeshVolume* volume)
{
if ( volume->IsQuadratic() )
{
nFCenter ));
}
}
+ return true;
}
+ return false;
}
//================================================================================
while ( ++u_n != sortedBaseNN.end() && !isNodeInSubMesh( u_n->second, faceSubMesh ));
sortedBaseNN.erase( sortedBaseNN.begin(), u_n );
}
- if ( u_n = --sortedBaseNN.end(), !isNodeInSubMesh( u_n->second, faceSubMesh ))
- {
- while ( u_n != sortedBaseNN.begin() && !isNodeInSubMesh( (--u_n)->second, faceSubMesh ));
- sortedBaseNN.erase( ++u_n, sortedBaseNN.end() );
- }
+ if ( !sortedBaseNN.empty() )
+ if ( u_n = --sortedBaseNN.end(), !isNodeInSubMesh( u_n->second, faceSubMesh ))
+ {
+ while ( u_n != sortedBaseNN.begin() && !isNodeInSubMesh( (--u_n)->second, faceSubMesh ));
+ sortedBaseNN.erase( ++u_n, sortedBaseNN.end() );
+ }
if ( sortedBaseNN.empty() ) continue;
}
u2nn->second.push_back( u_n->second );
}
}
- if ( theParam2ColumnMap.empty() )
+ if ( theParam2ColumnMap.size() < 2 )
return false;
}
*/
//================================================================================
-double SMESH_MesherHelper::GetAngle( const TopoDS_Edge & theE1,
- const TopoDS_Edge & theE2,
- const TopoDS_Face & theFace,
- gp_Vec* theFaceNormal)
+double SMESH_MesherHelper::GetAngle( const TopoDS_Edge & theE1,
+ const TopoDS_Edge & theE2,
+ const TopoDS_Face & theFace,
+ const TopoDS_Vertex & theCommonV,
+ gp_Vec* theFaceNormal)
{
double angle = 1e100;
try
{
- TopoDS_Vertex vCommon;
- if ( !TopExp::CommonVertex( theE1, theE2, vCommon ))
- return angle;
double f,l;
Handle(Geom_Curve) c1 = BRep_Tool::Curve( theE1, f,l );
Handle(Geom_Curve) c2 = BRep_Tool::Curve( theE2, f,l );
Handle(Geom2d_Curve) c2d1 = BRep_Tool::CurveOnSurface( theE1, theFace, f,l );
Handle(Geom_Surface) surf = BRep_Tool::Surface( theFace );
- double p1 = BRep_Tool::Parameter( vCommon, theE1 );
- double p2 = BRep_Tool::Parameter( vCommon, theE2 );
+ double p1 = BRep_Tool::Parameter( theCommonV, theE1 );
+ double p2 = BRep_Tool::Parameter( theCommonV, theE2 );
if ( c1.IsNull() || c2.IsNull() )
return angle;
gp_XY uv = c2d1->Value( p1 ).XY();
gp_Vec vec1, vec2, vecRef = du ^ dv;
int nbLoops = 0;
double p1tmp = p1;
- while ( vecRef.SquareMagnitude() < std::numeric_limits<double>::min() )
+ while ( vecRef.SquareMagnitude() < 1e-25 )
{
double dp = ( l - f ) / 1000.;
- p1tmp += dp * (( Abs( p1 - f ) > Abs( p1 - l )) ? +1. : -1.);
+ p1tmp += dp * (( Abs( p1 - f ) > Abs( p1 - l )) ? -1. : +1.);
uv = c2d1->Value( p1tmp ).XY();
surf->D1( uv.X(), uv.Y(), p, du, dv );
vecRef = du ^ dv;
* \param node - the node
* \param meshDS - mesh DS
* \retval TopoDS_Shape - found support shape
+ * \sa SMESH_Algo::VertexNode( const TopoDS_Vertex&, SMESHDS_Mesh* )
*/
static TopoDS_Shape GetSubShapeByNode(const SMDS_MeshNode* node,
const SMESHDS_Mesh* meshDS);
static double MaxTolerance( const TopoDS_Shape& shape );
static double GetAngle( const TopoDS_Edge & E1, const TopoDS_Edge & E2,
- const TopoDS_Face & F, gp_Vec* faceNormal=0);
+ const TopoDS_Face & F, const TopoDS_Vertex & V,
+ gp_Vec* faceNormal=0);
static bool IsClosedEdge( const TopoDS_Edge& anEdge );
{ return IsRealSeam( GetMeshDS()->ShapeToIndex( subShape)); }
/*!
* \brief Check if the shape set through IsQuadraticSubMesh() or SetSubShape()
- * has a seam edge
- * \retval bool - true if it has
+ * has a seam edge, i.e. an edge that has two parametric representations
+ * on a surface
+ * \retval bool - true if it has
*/
bool HasSeam() const { return !mySeamShapeIds.empty(); }
+ /*!
+ * \brief Check if the shape set through IsQuadraticSubMesh() or SetSubShape()
+ * has a seam edge that encounters twice in a wire
+ * \retval bool - true if it has
+ */
+ bool HasRealSeam() const { return HasSeam() && ( *mySeamShapeIds.begin() < 0 ); }
/*!
* \brief Return index of periodic parametric direction of a closed face
- * \retval int - 1 for U, 2 for V direction
+ * \retval int - 1 for U, 2 for V direction
*/
int GetPeriodicIndex() const { return myParIndex; }
/*!
void AddTLinkNodeMap(const TLinkNodeMap& aMap)
{ myTLinkNodeMap.insert(aMap.begin(), aMap.end()); }
- void AddTLinks(const SMDS_MeshEdge* edge);
- void AddTLinks(const SMDS_MeshFace* face);
- void AddTLinks(const SMDS_MeshVolume* vol);
+ bool AddTLinks(const SMDS_MeshEdge* edge);
+ bool AddTLinks(const SMDS_MeshFace* face);
+ bool AddTLinks(const SMDS_MeshVolume* vol);
/**
* Returns myTLinkNodeMap
#define smdsNode( elem ) static_cast<const SMDS_MeshNode*>( elem )
-//=======================================================================
-//function : SMESH_Pattern
-//purpose :
-//=======================================================================
-
-SMESH_Pattern::SMESH_Pattern ()
+namespace
{
-}
+
//=======================================================================
//function : getInt
//purpose :
//=======================================================================
-static inline int getInt( const char * theSring )
+inline int getInt( const char * theSring )
{
if ( *theSring < '0' || *theSring > '9' )
return -1;
//purpose :
//=======================================================================
-static inline double getDouble( const char * theSring )
+inline double getDouble( const char * theSring )
{
char *ptr;
return strtod( theSring, &ptr );
// Return the number of the found tokens
//=======================================================================
-static int readLine (list <const char*> & theFields,
- const char* & theLineBeg,
- const bool theClearFields )
+int readLine (list <const char*> & theFields,
+ const char* & theLineBeg,
+ const bool theClearFields )
{
if ( theClearFields )
theFields.clear();
return nbRead;
}
+//=======================================================================
+//function : isRealSeam
+//purpose : return true if an EDGE encounters twice in a FACE
+//=======================================================================
+
+// bool isRealSeam( const TopoDS_Edge& e, const TopoDS_Face& f )
+// {
+// if ( BRep_Tool::IsClosed( e, f ))
+// {
+// int nb = 0;
+// for (TopExp_Explorer exp( f, TopAbs_EDGE ); exp.More(); exp.Next())
+// if ( exp.Current().IsSame( e ))
+// if ( ++nb == 2 )
+// return true;
+// }
+// return false;
+// }
+
+//=======================================================================
+//function : loadVE
+//purpose : load VERTEXes and EDGEs in a map. Return nb loaded VERTEXes
+//=======================================================================
+
+int loadVE( const list< TopoDS_Edge > & eList,
+ TopTools_IndexedMapOfOrientedShape & map )
+{
+ list< TopoDS_Edge >::const_iterator eIt = eList.begin();
+ // vertices
+ int nbV;
+ for ( eIt = eList.begin(); eIt != eList.end(); eIt++ )
+ {
+ nbV = map.Extent();
+ map.Add( TopExp::FirstVertex( *eIt, true ));
+ bool added = ( nbV < map.Extent() );
+ if ( !added ) { // vertex encountered twice
+ // a seam vertex have two corresponding key points
+ map.Add( TopExp::FirstVertex( *eIt, true ).Reversed());
+ }
+ }
+ nbV = map.Extent();
+
+ // edges
+ for ( eIt = eList.begin(); eIt != eList.end(); eIt++ )
+ map.Add( *eIt );
+
+ return nbV;
+}
+
+} // namespace
+
+//=======================================================================
+//function : SMESH_Pattern
+//purpose :
+//=======================================================================
+
+SMESH_Pattern::SMESH_Pattern ()
+{
+}
+
//=======================================================================
//function : Load
//purpose : Load a pattern from <theFile>
// Load shapes in the consequent order and count nb of points
- // vertices
- for ( elIt = eList.begin(); elIt != eList.end(); elIt++ ) {
- int nbV = myShapeIDMap.Extent();
- myShapeIDMap.Add( TopExp::FirstVertex( *elIt, true ));
- bool added = ( nbV < myShapeIDMap.Extent() );
- if ( !added ) { // vertex encountered twice
- // a seam vertex have two corresponding key points
- myShapeIDMap.Add( TopExp::FirstVertex( *elIt, true ).Reversed());
- ++nbNodes;
- }
+ loadVE( eList, myShapeIDMap );
+ myShapeIDMap.Add( face );
+
+ nbNodes += myShapeIDMap.Extent() - 1;
+
+ for ( elIt = eList.begin(); elIt != eList.end(); elIt++ )
if ( SMESHDS_SubMesh * eSubMesh = aMeshDS->MeshElements( *elIt ))
nbNodes += eSubMesh->NbNodes() + 1;
- }
- // edges
- for ( elIt = eList.begin(); elIt != eList.end(); elIt++ )
- myShapeIDMap.Add( *elIt );
- // the face
- myShapeIDMap.Add( face );
myPoints.resize( nbNodes );
// Load U of points on edges
- for ( elIt = eList.begin(); elIt != eList.end(); elIt++ )
+ list<int>::iterator nbEinW = myNbKeyPntInBoundary.begin();
+ int iE = 0;
+ vector< TopoDS_Edge > eVec;
+ for ( elIt = eList.begin(); elIt != eList.end(); elIt++, iE++ )
{
+ if ( isClosed && ( iE == 0 || iE == *nbEinW ))
+ {
+ // new wire begins; put EDGEs in eVec
+ list<TopoDS_Edge>::iterator eEnd = elIt;
+ std::advance( eEnd, *nbEinW );
+ eVec.assign( elIt, eEnd );
+ if ( iE > 0 )
+ ++nbEinW;
+ iE = 0;
+ }
TopoDS_Edge & edge = *elIt;
list< TPoint* > & ePoints = getShapePoints( edge );
double f, l;
TopoDS_Shape & v = is2 ? v2 : v1;
if ( helper.IsRealSeam( v ) ) {
// reverse or not depending on orientation of adjacent seam
- TopoDS_Edge seam;
- list<TopoDS_Edge>::iterator eIt2 = elIt;
- if ( is2 )
- seam = ( ++eIt2 == eList.end() ? eList.front() : *eIt2 );
- else
- seam = ( eIt2 == eList.begin() ? eList.back() : *(--eIt2) );
- if ( seam.Orientation() == TopAbs_REVERSED )
+ int iSeam = helper.WrapIndex( iE + ( is2 ? +1 : -1 ), eVec.size() );
+ if ( eVec[ iSeam ].Orientation() == TopAbs_REVERSED )
v.Reverse();
}
}
BRep_Tool::CurveOnSurface( theEdge, TopoDS::Face( myShape ), f, l );
ePoints.back()->myInitU = 1.0;
+ //ePoints.front()->myInitU = 0.0; //myUV = C2d->Value( isForward ? f : l ).XY();
list< TPoint* >::const_iterator pIt = ePoints.begin();
for ( pIt++; pIt != ePoints.end(); pIt++ )
{
}
// here shapes get IDs, for the outer wire IDs are OK
- list<TopoDS_Edge>::iterator elIt = eList.begin();
- for ( ; elIt != eList.end(); elIt++ ) {
- myShapeIDMap.Add( TopExp::FirstVertex( *elIt, true ));
- bool isClosed1 = BRep_Tool::IsClosed( *elIt, theFace );
- // BEGIN: jfa for bug 0019943
- if (isClosed1) {
- isClosed1 = false;
- for (TopExp_Explorer expw (theFace, TopAbs_WIRE); expw.More() && !isClosed1; expw.Next()) {
- const TopoDS_Wire& wire = TopoDS::Wire(expw.Current());
- int nbe = 0;
- for (BRepTools_WireExplorer we (wire, theFace); we.More() && !isClosed1; we.Next()) {
- if (we.Current().IsSame(*elIt)) {
- nbe++;
- if (nbe == 2) isClosed1 = true;
- }
- }
- }
- }
- // END: jfa for bug 0019943
- if (isClosed1)
- myShapeIDMap.Add( TopExp::LastVertex( *elIt, true ));// vertex orienation is REVERSED
- }
- int nbVertices = myShapeIDMap.Extent();
-
- for ( elIt = eList.begin(); elIt != eList.end(); elIt++ )
- myShapeIDMap.Add( *elIt );
-
+ int nbVertices = loadVE( eList, myShapeIDMap );
myShapeIDMap.Add( face );
if ( myShapeIDToPointsMap.size() != myShapeIDMap.Extent() ) {
list< list< TPoint* > > edgesPointsList;
edgesPointsList.push_back( list< TPoint* >() );
list< TPoint* > * edgesPoints = & edgesPointsList.back();
- list< TPoint* >::iterator pIt;
+ list< TPoint* >::iterator pIt, pEnd;
// compute UV of points on the outer wire
int iE, nbEdgesInOuterWire = nbVertexInWires.front();
+ list< TopoDS_Edge >::iterator elIt;
for (iE = 0, elIt = eList.begin();
iE < nbEdgesInOuterWire && elIt != eList.end();
iE++, elIt++ )
// re-fill myShapeIDMap - all shapes get good IDs
myShapeIDMap.Clear();
- for ( elIt = eList.begin(); elIt != eList.end(); elIt++ )
- myShapeIDMap.Add( TopExp::FirstVertex( *elIt, true ));
- for ( elIt = eList.begin(); elIt != eList.end(); elIt++ )
- myShapeIDMap.Add( *elIt );
+ nbVertices = loadVE( eList, myShapeIDMap );
myShapeIDMap.Add( face );
} // there are inner wires
+ // Set XYZ of on-vertex points
+
+ // for ( int iV = 1; iV <= nbVertices; ++iV )
+ // {
+ // const TopoDS_Vertex& V = TopoDS::Vertex( myShapeIDMap( iV ));
+ // list< TPoint* > & vPoints = getShapePoints( iV );
+ // if ( !vPoints.empty() )
+ // {
+ // //vPoints.front()->myUV = BRep_Tool::Parameters( V, theFace ).XY();
+ // vPoints.front()->myXYZ = BRep_Tool::Pnt( V );
+ // }
+ // }
+
// Compute XYZ of on-edge points
TopLoc_Location loc;
{
BRepAdaptor_Curve C3d( *elIt );
list< TPoint* > & ePoints = getShapePoints( iE++ );
- pIt = ePoints.begin();
- for ( pIt++; pIt != ePoints.end(); pIt++ )
+ for ( pIt = ++ePoints.begin(), pEnd = ePoints.end(); pIt != pEnd; pIt++ )
{
TPoint* point = *pIt;
point->myXYZ = C3d.Value( point->myU );
}
}
+//=======================================================================
+//function : findExistingNodes
+//purpose : fills nodes vector with nodes existing on a given shape (IMP 22368)
+// Returns true if all nodes for all points on S are found
+//=======================================================================
+
+bool SMESH_Pattern::findExistingNodes( SMESH_Mesh* mesh,
+ const TopoDS_Shape& S,
+ const std::list< TPoint* > & points,
+ vector< const SMDS_MeshNode* > & nodesVector)
+{
+ if ( S.IsNull() || points.empty() )
+ return false;
+
+ SMESHDS_Mesh* aMeshDS = mesh->GetMeshDS();
+
+ switch ( S.ShapeType() )
+ {
+ case TopAbs_VERTEX:
+ {
+ int pIndex = points.back() - &myPoints[0];
+ if ( !nodesVector[ pIndex ] )
+ nodesVector[ pIndex ] = SMESH_Algo::VertexNode( TopoDS::Vertex( S ), aMeshDS );
+ return nodesVector[ pIndex ];
+ }
+ case TopAbs_EDGE:
+ {
+ const TopoDS_Edge& edge = TopoDS::Edge( S );
+ map< double, const SMDS_MeshNode* > paramsOfNodes;
+ if ( !SMESH_Algo::GetSortedNodesOnEdge( aMeshDS, edge,
+ /*ignoreMediumNodes=*/false,
+ paramsOfNodes )
+ || paramsOfNodes.size() < 3 )
+ break;
+ // points on VERTEXes are included with wrong myU
+ list< TPoint* >::const_reverse_iterator pItR = ++points.rbegin();
+ list< TPoint* >::const_iterator pItF = ++points.begin();
+ const bool isForward = ( (*pItF)->myU < (*pItR)->myU );
+ map< double, const SMDS_MeshNode* >::iterator u2n = ++paramsOfNodes.begin();
+ map< double, const SMDS_MeshNode* >::iterator u2nEnd = --paramsOfNodes.end();
+ TPoint* p;
+ if ( paramsOfNodes.size() == points.size() )
+ {
+ for ( ; u2n != u2nEnd; ++u2n )
+ {
+ p = ( isForward ? *pItF : *pItR );
+ int pIndex = p - &myPoints[0];
+ if ( !nodesVector [ pIndex ] )
+ nodesVector [ pIndex ] = u2n->second;
+ ++pItF;
+ ++pItR;
+ }
+ return true;
+ }
+ else
+ {
+ const double tolFact = 0.05;
+ while ( u2n != u2nEnd && pItF != points.end() )
+ {
+ const double u = u2n->first;
+ const SMDS_MeshNode* n = u2n->second;
+ const double tol = ( (++u2n)->first - u ) * tolFact;
+ do
+ {
+ p = ( isForward ? *pItF : *pItR );
+ if ( Abs( u - p->myU ) < tol )
+ {
+ int pIndex = p - &myPoints[0];
+ if ( !nodesVector [ pIndex ] )
+ nodesVector [ pIndex ] = n;
+ ++pItF;
+ ++pItR;
+ break;
+ }
+ }
+ while ( p->myU < u && ( ++pItF, ++pItR != points.rend() ));
+ }
+ }
+ break;
+ } // case TopAbs_EDGE:
+
+ default:;
+ } // switch ( S.ShapeType() )
+
+ return false;
+}
+
//=======================================================================
//function : MakeMesh
//purpose : Create nodes and elements in <theMesh> using nodes
// coordinates computed by either of Apply...() methods
-// WARNING : StdMeshers_Projection_... relies on MakeMesh() behavior: that
-// it does not care of nodes and elements already existing on
-// sub-shapes. DO NOT MERGE them or modify also StdMeshers_Projection_..
//=======================================================================
bool SMESH_Pattern::MakeMesh(SMESH_Mesh* theMesh,
{
nodesVector.resize( myPoints.size(), 0 );
- // find existing nodes on EDGEs and VERTEXes (IMP 22368)
- map< int, list< TPoint* > >::iterator idPointIt = myShapeIDToPointsMap.begin();
- if ( !myShapeIDMap.IsEmpty() && aMeshDS->NbNodes() > 0 )
-
- for ( ; idPointIt != myShapeIDToPointsMap.end(); idPointIt++ )
- {
- const TopoDS_Shape& S = myShapeIDMap( idPointIt->first );
- list< TPoint* > & points = idPointIt->second;
- if ( points.empty() )
- continue;
-
- switch ( S.ShapeType() )
- {
- case TopAbs_VERTEX:
- {
- int pIndex = points.back() - &myPoints[0];
- if ( !nodesVector[ pIndex ] )
- nodesVector[ pIndex ] = SMESH_Algo::VertexNode( TopoDS::Vertex( S ), aMeshDS );
- break;
- }
- case TopAbs_EDGE:
- {
- const TopoDS_Edge& edge = TopoDS::Edge( S );
- map< double, const SMDS_MeshNode* > paramsOfNodes;
- if ( !SMESH_Algo::GetSortedNodesOnEdge( aMeshDS, edge,
- /*ignoreMediumNodes=*/false,
- paramsOfNodes )
- || paramsOfNodes.size() < 3 )
- break;
- // points on VERTEXes are included with wrong myU
- list< TPoint* >::reverse_iterator pItR = ++points.rbegin();
- list< TPoint* >::iterator pItF = ++points.begin();
- const bool isForward = ( (*pItF)->myU < (*pItR)->myU );
- map< double, const SMDS_MeshNode* >::iterator u2n = ++paramsOfNodes.begin();
- map< double, const SMDS_MeshNode* >::iterator u2nEnd = --paramsOfNodes.end();
- TPoint* p;
- const double tolFact = ( paramsOfNodes.size() == points.size() ) ? 0.3 : 0.05;
- while ( u2n != u2nEnd && pItF != points.end() )
- {
- const double u = u2n->first;
- const SMDS_MeshNode* n = u2n->second;
- const double tol = ( (++u2n)->first - u ) * tolFact;
- do
- {
- p = ( isForward ? *pItF : *pItR );
- if ( Abs( u - p->myU ) < tol )
- {
- int pIndex = p - &myPoints[0];
- if ( !nodesVector [ pIndex ] )
- nodesVector [ pIndex ] = n;
- ++pItF;
- ++pItR;
- break;
- }
- }
- while ( p->myU < u && ( ++pItF, ++pItR != points.rend() ));
- }
- break;
- }
- default:;
- }
- } // end of "find existing nodes on EDGEs and VERTEXes"
-
// loop on sub-shapes of myShape: create nodes
- idPointIt = myShapeIDToPointsMap.begin();
+ map< int, list< TPoint* > >::iterator idPointIt = myShapeIDToPointsMap.begin();
for ( ; idPointIt != myShapeIDToPointsMap.end(); idPointIt++ )
{
+ list< TPoint* > & points = idPointIt->second;
TopoDS_Shape S;
- if ( !myShapeIDMap.IsEmpty() ) {
+ if ( !myShapeIDMap.IsEmpty() )
S = myShapeIDMap( idPointIt->first );
- }
- list< TPoint* > & points = idPointIt->second;
+
+ // find existing nodes on EDGEs and VERTEXes
+ if ( findExistingNodes( theMesh, S, points, nodesVector ))
+ continue;
+
list< TPoint* >::iterator pIt = points.begin();
for ( ; pIt != points.end(); pIt++ )
{
TPoint* point = *pIt;
- //int pIndex = pointIndex[ point ];
int pIndex = point - &myPoints[0];
if ( nodesVector [ pIndex ] )
continue;
point->myXYZ.Z());
nodesVector [ pIndex ] = node;
- if ( !S.IsNull() /*subMeshDS*/ ) {
- // !!!!! do not merge new nodes with ones existing on submeshes (see method comment)
+ if ( !S.IsNull() ) {
+
switch ( S.ShapeType() ) {
case TopAbs_VERTEX: {
aMeshDS->SetNodeOnVertex( node, TopoDS::Vertex( S )); break;
TopTools_MapOfShape seamVertices;
TopoDS_Face face = TopoDS::Face( theShape );
TopExp_Explorer eExp( theShape, TopAbs_EDGE );
- for ( ; eExp.More() && nbNodeOnSeamEdge == 0; eExp.Next() ) {
+ for ( ; eExp.More() /*&& nbNodeOnSeamEdge == 0*/; eExp.Next() ) {
const TopoDS_Edge& ee = TopoDS::Edge(eExp.Current());
if ( BRep_Tool::IsClosed(ee, face) ) {
// seam edge and vertices encounter twice in theFace
void clearMesh(SMESH_Mesh* theMesh) const;
// clear mesh elements existing on myShape in theMesh
+ bool findExistingNodes( SMESH_Mesh* mesh,
+ const TopoDS_Shape& S,
+ const std::list< TPoint* > & points,
+ std::vector< const SMDS_MeshNode* > & nodes);
+ // fills nodes vector with nodes existing on a given shape
+
static SMESHDS_SubMesh * getSubmeshWithElements(SMESH_Mesh* theMesh,
const TopoDS_Shape& theShape);
// return submesh containing elements bound to theShape in theMesh
#include <BRep_Builder.hxx>
#include <BRep_Tool.hxx>
#include <TopExp.hxx>
+#include <TopExp_Explorer.hxx>
#include <TopTools_IndexedMapOfShape.hxx>
#include <TopTools_ListIteratorOfListOfShape.hxx>
+#include <TopTools_ListOfShape.hxx>
#include <TopoDS.hxx>
#include <TopoDS_Compound.hxx>
-#include <gp_Pnt.hxx>
-#include <TopExp_Explorer.hxx>
#include <TopoDS_Iterator.hxx>
+#include <gp_Pnt.hxx>
#include <Standard_OutOfMemory.hxx>
#include <Standard_ErrorHandler.hxx>
SMESH_Algo* SMESH_subMesh::GetAlgo() const
{
if ( !_algo )
- ((SMESH_subMesh*)this)->_algo = _father->GetGen()->GetAlgo(*_father, _subShape);
+ {
+ SMESH_subMesh* me = const_cast< SMESH_subMesh* >( this );
+ me->_algo = _father->GetGen()->GetAlgo( me );
+ }
return _algo;
}
return false;
}
-//=============================================================================
+//================================================================================
/*!
- *
+ * \brief Treats modification of hypotheses definition
+ * \param [in] event - what happens
+ * \param [in] anHyp - a hypothesis
+ * \return SMESH_Hypothesis::Hypothesis_Status - a treatment result.
+ *
+ * Optional description of a problematic situation (if any) can be retrieved
+ * via GetComputeError().
*/
-//=============================================================================
+//================================================================================
SMESH_Hypothesis::Hypothesis_Status
SMESH_subMesh::AlgoStateEngine(int event, SMESH_Hypothesis * anHyp)
SMESH_HypoFilter filter( SMESH_HypoFilter::HasType( algo->GetType() ));
filter.Or( SMESH_HypoFilter::HasType( algo->GetType()+1 ));
filter.Or( SMESH_HypoFilter::HasType( algo->GetType()+2 ));
- if ( SMESH_Algo * curAlgo = (SMESH_Algo*)_father->GetHypothesis(_subShape, filter, true ))
+ if ( SMESH_Algo * curAlgo = (SMESH_Algo*)_father->GetHypothesis( this, filter, true ))
if ( !curAlgo->NeedDiscreteBoundary() )
algoRequiringCleaning = curAlgo;
}
if ( ! CanAddHypothesis( anHyp )) // check dimension
return SMESH_Hypothesis::HYP_BAD_DIM;
- if ( /*!anHyp->IsAuxiliary() &&*/ getSimilarAttached( _subShape, anHyp ) )
+ if ( !anHyp->IsAuxiliary() && getSimilarAttached( _subShape, anHyp ) )
return SMESH_Hypothesis::HYP_ALREADY_EXIST;
if ( !meshDS->AddHypothesis(_subShape, anHyp))
if (!isApplicableHyp)
return ret; // not applicable hypotheses do not change algo state
+ if (( algo = GetAlgo()))
+ algo->InitComputeError();
+
switch (_algoState)
{
// ret should be fatal: anHyp was not added
ret = SMESH_Hypothesis::HYP_INCOMPATIBLE;
}
- else if (!_father->IsUsedHypothesis( anHyp, this ))
+ else if (!_father->IsUsedHypothesis( anHyp, this ))
ret = SMESH_Hypothesis::HYP_INCOMPATIBLE;
if (SMESH_Hypothesis::IsStatusFatal( ret ))
f.Init( SMESH_HypoFilter::IsAlgo() );
f.And( SMESH_HypoFilter::IsApplicableTo( _subShape ));
f.AndNot( SMESH_HypoFilter::Is( algo ));
- const SMESH_Hypothesis * prevAlgo = _father->GetHypothesis( _subShape, f, true );
+ const SMESH_Hypothesis * prevAlgo = _father->GetHypothesis( this, f, true );
if (prevAlgo &&
string(algo->GetName()) != string(prevAlgo->GetName()) )
modifiedHyp = true;
f.Init( SMESH_HypoFilter::IsAlgo() );
f.And( SMESH_HypoFilter::IsApplicableTo( _subShape ));
f.AndNot( SMESH_HypoFilter::Is( algo ));
- const SMESH_Hypothesis* prevAlgo = _father->GetHypothesis( _subShape, f, true );
+ const SMESH_Hypothesis* prevAlgo = _father->GetHypothesis( this, f, true );
if (prevAlgo &&
string(algo->GetName()) != string(prevAlgo->GetName()) )
modifiedHyp = true;
{
// is algo hidden?
SMESH_Gen* gen = _father->GetGen();
- TopTools_ListIteratorOfListOfShape it( _father->GetAncestors( _subShape ));
- for ( ; ( ret == SMESH_Hypothesis::HYP_OK && it.More()); it.Next() ) {
- if ( SMESH_Algo* upperAlgo = gen->GetAlgo( *_father, it.Value() ))
+ const std::vector< SMESH_subMesh * > & ancestors = GetAncestors();
+ for ( size_t iA = 0; ( ret == SMESH_Hypothesis::HYP_OK && iA < ancestors.size()); ++iA ) {
+ if ( SMESH_Algo* upperAlgo = ancestors[ iA ]->GetAlgo() )
if ( !upperAlgo->NeedDiscreteBoundary() && !upperAlgo->SupportSubmeshes())
ret = SMESH_Hypothesis::HYP_HIDDEN_ALGO;
}
// is algo hiding?
if ( ret == SMESH_Hypothesis::HYP_OK &&
!algo->NeedDiscreteBoundary() &&
- !algo->SupportSubmeshes()) {
+ !algo->SupportSubmeshes())
+ {
TopoDS_Shape algoAssignedTo, otherAssignedTo;
- gen->GetAlgo( *_father, _subShape, &algoAssignedTo );
+ gen->GetAlgo( this, &algoAssignedTo );
map<int, SMESH_subMesh*>::reverse_iterator i_sm = _mapDepend.rbegin();
for ( ; ( ret == SMESH_Hypothesis::HYP_OK && i_sm != _mapDepend.rend()) ; ++i_sm )
- if ( gen->GetAlgo( *_father, i_sm->second->_subShape, &otherAssignedTo ) &&
+ if ( gen->GetAlgo( i_sm->second, &otherAssignedTo ) &&
SMESH_MesherHelper::IsSubShape( /*sub=*/otherAssignedTo, /*main=*/algoAssignedTo ))
ret = SMESH_Hypothesis::HYP_HIDING_ALGO;
}
}
+ if ( _algo ) { // get an error description set by _algo->CheckHypothesis()
+ _computeError = _algo->GetComputeError();
+ _algo->InitComputeError();
+ }
+
bool stateChange = ( _algoState != oldAlgoState );
if ( stateChange && _algoState == HYP_OK ) // hyp becomes OK
ComputeSubMeshStateEngine( CHECK_COMPUTE_STATE );
}
- if (stateChange || modifiedHyp)
- ComputeStateEngine(MODIF_ALGO_STATE);
+ if ( stateChange || modifiedHyp )
+ ComputeStateEngine( MODIF_ALGO_STATE );
_realComputeCost = ( _algoState == HYP_OK ) ? computeCost() : 0;
for (; itsub.More(); itsub.Next())
{
// loop on adjacent subShapes
- TopTools_ListIteratorOfListOfShape it( _father->GetAncestors( itsub.Value() ));
- for (; it.More(); it.Next())
+ const std::vector< SMESH_subMesh * > & ancestors = GetAncestors();
+ for ( size_t iA = 0; iA < ancestors.size(); ++iA )
{
- const TopoDS_Shape& adjacent = it.Value();
+ const TopoDS_Shape& adjacent = ancestors[ iA ]->GetSubShape();
if ( _subShape.IsSame( adjacent )) continue;
if ( adjacent.ShapeType() != _subShape.ShapeType())
break;
// check algo attached to smAdjacent
- SMESH_Algo * algo = gen->GetAlgo((*_father), adjacent);
+ SMESH_Algo * algo = ancestors[ iA ]->GetAlgo();
if (algo &&
!algo->NeedDiscreteBoundary() &&
algo->OnlyUnaryInput())
_algoState = state;
}
-//=============================================================================
+//================================================================================
/*!
+ * \brief Send an event to sub-meshes
+ * \param [in] event - the event
+ * \param [in] anHyp - an hypothesis
+ * \param [in] exitOnFatal - to stop iteration on sub-meshes if a sub-mesh
+ * reports a fatal result
+ * \return SMESH_Hypothesis::Hypothesis_Status - the worst result
*
+ * Optional description of a problematic situation (if any) can be retrieved
+ * via GetComputeError().
*/
-//=============================================================================
+//================================================================================
+
SMESH_Hypothesis::Hypothesis_Status
- SMESH_subMesh::SubMeshesAlgoStateEngine(int event,
- SMESH_Hypothesis * anHyp)
+ SMESH_subMesh::SubMeshesAlgoStateEngine(int event,
+ SMESH_Hypothesis * anHyp,
+ bool exitOnFatal)
{
SMESH_Hypothesis::Hypothesis_Status ret = SMESH_Hypothesis::HYP_OK;
//EAP: a wire (dim==1) should notify edges (dim==1)
{
SMESH_subMeshIteratorPtr smIt = getDependsOnIterator(false,false);
while ( smIt->more() ) {
- SMESH_Hypothesis::Hypothesis_Status ret2 =
- smIt->next()->AlgoStateEngine(event, anHyp);
+ SMESH_subMesh* sm = smIt->next();
+ SMESH_Hypothesis::Hypothesis_Status ret2 = sm->AlgoStateEngine(event, anHyp);
if ( ret2 > ret )
+ {
ret = ret2;
+ _computeError = sm->_computeError;
+ sm->_computeError.reset();
+ if ( exitOnFatal && SMESH_Hypothesis::IsStatusFatal( ret ))
+ break;
+ }
}
}
return ret;
if ( !algo->NeedDiscreteBoundary() && !subFailed )
_computeError =
SMESH_ComputeError::New(COMPERR_BAD_INPUT_MESH,
- "Unexpected computed submesh",algo);
+ "Unexpected computed sub-mesh",algo);
break; // goto exit
}
}
{
ret = algo->Compute((*_father), shape);
}
- if ( !_computeError || (/* !ret && */_computeError->IsOK() ) ) // algo can set _computeError of submesh
- _computeError = algo->GetComputeError();
+ // algo can set _computeError of submesh
+ _computeError = SMESH_ComputeError::Worst( _computeError, algo->GetComputeError() );
}
catch ( ::SMESH_ComputeError& comperr ) {
cout << " SMESH_ComputeError caught" << endl;
case CHECK_COMPUTE_STATE:
if ( IsMeshComputed() )
_computeState = COMPUTE_OK;
+ else if ( _computeError && _computeError->IsKO() )
+ _computeState = FAILED_TO_COMPUTE;
break;
default:
ASSERT(0);
void SMESH_subMesh::updateDependantsState(const compute_event theEvent)
{
- TopTools_ListIteratorOfListOfShape it( _father->GetAncestors( _subShape ));
- for (; it.More(); it.Next())
+ const std::vector< SMESH_subMesh * > & ancestors = GetAncestors();
+ for ( size_t iA = 0; iA < ancestors.size(); ++iA )
{
- const TopoDS_Shape& ancestor = it.Value();
- if ( SMESH_subMesh *aSubMesh = _father->GetSubMeshContaining(ancestor))
- aSubMesh->ComputeStateEngine( theEvent );
+ ancestors[ iA ]->ComputeStateEngine( theEvent );
}
}
{
int dimToClean = SMESH_Gen::GetShapeDim( _subShape ) + 1;
- TopTools_ListIteratorOfListOfShape it( _father->GetAncestors( _subShape ));
- for (; it.More(); it.Next())
+ const std::vector< SMESH_subMesh * > & ancestors = GetAncestors();
+ for ( size_t iA = 0; iA < ancestors.size(); ++iA )
{
- const TopoDS_Shape& ancestor = it.Value();
- if ( SMESH_Gen::GetShapeDim( ancestor ) == dimToClean ) {
+ const TopoDS_Shape& ancestor = ancestors[ iA ]->GetSubShape();
+ if ( SMESH_Gen::GetShapeDim( ancestor ) == dimToClean )
+ {
// PAL8021. do not go upper than SOLID, else ComputeStateEngine(CLEAN)
// will erase mesh on other shapes in a compound
- if ( ancestor.ShapeType() >= TopAbs_SOLID ) {
- SMESH_subMesh *aSubMesh = _father->GetSubMeshContaining(ancestor);
- if (aSubMesh &&
- !aSubMesh->IsEmpty() ) // prevent infinite CLEAN via event lesteners
- aSubMesh->ComputeStateEngine(CLEAN);
- }
+ if ( ancestor.ShapeType() >= TopAbs_SOLID &&
+ !ancestors[ iA ]->IsEmpty() ) // prevent infinite CLEAN via event lesteners
+ ancestors[ iA ]->ComputeStateEngine(CLEAN);
}
}
}
}
else if ( subMesh->GetComputeState() == READY_TO_COMPUTE )
{
- SMESH_Algo* anAlgo = theGen->GetAlgo( *_father, S );
+ SMESH_Algo* anAlgo = theGen->GetAlgo( subMesh );
if (strcmp( anAlgo->GetName(), theAlgo->GetName()) == 0 && // same algo
anAlgo->GetUsedHypothesis( *_father, S, ignoreAuxiliaryHyps ) == aUsedHyp) // same hyps
aBuilder.Add( aCompound, S );
/*!
* \brief Return an event listener data
* \param listener - the listener whose data is
+ * \param myOwn - if \c true, returns a listener set by this sub-mesh,
+ * else returns a listener listening to events of this sub-mesh
* \retval EventListenerData* - found data, maybe NULL
*/
//================================================================================
-EventListenerData* SMESH_subMesh::GetEventListenerData(EventListener* listener) const
+EventListenerData* SMESH_subMesh::GetEventListenerData(EventListener* listener,
+ const bool myOwn) const
{
- map< EventListener*, EventListenerData* >::const_iterator l_d =
- _eventListeners.find( listener );
- if ( l_d != _eventListeners.end() )
- return l_d->second;
+ if ( myOwn )
+ {
+ list< OwnListenerData >::const_iterator d;
+ for ( d = _ownListeners.begin(); d != _ownListeners.end(); ++d )
+ {
+ if ( d->myListener == listener && _father->MeshExists( d->myMeshID ))
+ return d->mySubMesh->GetEventListenerData( listener, !myOwn );
+ }
+ }
+ else
+ {
+ map< EventListener*, EventListenerData* >::const_iterator l_d =
+ _eventListeners.find( listener );
+ if ( l_d != _eventListeners.end() )
+ return l_d->second;
+ }
return 0;
}
/*!
* \brief Return an event listener data
* \param listenerName - the listener name
+ * \param myOwn - if \c true, returns a listener set by this sub-mesh,
+ * else returns a listener listening to events of this sub-mesh
* \retval EventListenerData* - found data, maybe NULL
*/
//================================================================================
-EventListenerData* SMESH_subMesh::GetEventListenerData(const string& listenerName) const
+EventListenerData* SMESH_subMesh::GetEventListenerData(const string& listenerName,
+ const bool myOwn) const
{
- map< EventListener*, EventListenerData* >::const_iterator l_d = _eventListeners.begin();
- for ( ; l_d != _eventListeners.end(); ++l_d )
- if ( listenerName == l_d->first->GetName() )
- return l_d->second;
+ if ( myOwn )
+ {
+ list< OwnListenerData >::const_iterator d;
+ for ( d = _ownListeners.begin(); d != _ownListeners.end(); ++d )
+ {
+ if ( _father->MeshExists( d->myMeshID ) && listenerName == d->myListener->GetName())
+ return d->mySubMesh->GetEventListenerData( listenerName, !myOwn );
+ }
+ }
+ else
+ {
+ map< EventListener*, EventListenerData* >::const_iterator l_d = _eventListeners.begin();
+ for ( ; l_d != _eventListeners.end(); ++l_d )
+ if ( listenerName == l_d->first->GetName() )
+ return l_d->second;
+ }
return 0;
}
}
}
+//================================================================================
+/*!
+ * \brief Returns ancestor sub-meshes. Finds them if not yet found.
+ */
+//================================================================================
+
+const std::vector< SMESH_subMesh * > & SMESH_subMesh::GetAncestors() const
+{
+ if ( _ancestors.empty() &&
+ !_subShape.IsSame( _father->GetShapeToMesh() ))
+ {
+ const TopTools_ListOfShape& ancShapes = _father->GetAncestors( _subShape );
+
+ SMESH_subMesh* me = const_cast< SMESH_subMesh* >( this );
+ me->_ancestors.reserve( ancShapes.Extent() );
+
+ TopTools_MapOfShape map;
+
+ for ( TopTools_ListIteratorOfListOfShape it( ancShapes ); it.More(); it.Next() )
+ if ( SMESH_subMesh* sm = _father->GetSubMeshContaining( it.Value() ))
+ if ( map.Add( it.Value() ))
+ me->_ancestors.push_back( sm );
+ }
+
+ return _ancestors;
+}
+
+//================================================================================
+/*!
+ * \brief Clears the vector of ancestor sub-meshes
+ */
+//================================================================================
+
+void SMESH_subMesh::ClearAncestors()
+{
+ _ancestors.clear();
+}
+
//================================================================================
/*!
* \brief Find common submeshes (based on shared sub-shapes with other
SMESH_subMeshIteratorPtr getDependsOnIterator(const bool includeSelf,
const bool complexShapeFirst=false) const;
+ const std::vector< SMESH_subMesh * > & GetAncestors() const;
+ void ClearAncestors();
+
const TopoDS_Shape & GetSubShape() const;
enum compute_state
/*!
* \brief Return an event listener data
* \param listener - the listener whose data is
+ * \param myOwn - if \c true, returns a listener set by this sub-mesh,
+ * else returns a listener listening to events of this sub-mesh
* \retval EventListenerData* - found data, maybe NULL
*/
- EventListenerData* GetEventListenerData(EventListener* listener) const;
+ EventListenerData* GetEventListenerData(EventListener* listener,
+ const bool myOwn=false) const;
/*!
* \brief Return an event listener data
* \param listenerName - the listener name
+ * \param myOwn - if \c true, returns a listener set by this sub-mesh,
+ * else returns a listener listening to events of this sub-mesh
* \retval EventListenerData* - found data, maybe NULL
*/
- EventListenerData* GetEventListenerData(const std::string& listenerName) const;
+ EventListenerData* GetEventListenerData(const std::string& listenerName,
+ const bool myOwn=false) const;
/*!
* \brief Unregister the listener and delete it and it's data
AlgoStateEngine(int event, SMESH_Hypothesis * anHyp);
SMESH_Hypothesis::Hypothesis_Status
- SubMeshesAlgoStateEngine(int event, SMESH_Hypothesis * anHyp);
+ SubMeshesAlgoStateEngine(int event, SMESH_Hypothesis * anHyp, bool exitOnFatal=false);
algo_state GetAlgoState() const { return _algoState; }
- compute_state GetComputeState() const { return _computeState; };
+ compute_state GetComputeState() const { return _computeState; }
SMESH_ComputeErrorPtr& GetComputeError() { return _computeError; }
void DumpAlgoState(bool isMain);
std::map < int, SMESH_subMesh * >_mapDepend;
bool _dependenceAnalysed;
+ std::vector< SMESH_subMesh * > _ancestors;
SMESH_Algo * _algo; // the algorithm found by last *StateEngine() call
algo_state _algoState;
((SMESHDS_Hypothesis*)&other)->SaveTo(otherSave);
return mySave.str() == otherSave.str();
}
+
+//================================================================================
+/*!
+ * \brief Compare types of hypotheses
+ */
+//================================================================================
+
+bool SMESHDS_Hypothesis::IsSameName( const SMESHDS_Hypothesis& other) const
+{
+ return _name == other._name;
+}
virtual std::ostream & SaveTo(std::ostream & save)=0;
virtual std::istream & LoadFrom(std::istream & load)=0;
+ bool IsSameName( const SMESHDS_Hypothesis& other) const;
virtual bool operator==(const SMESHDS_Hypothesis& other) const;
bool operator!=(const SMESHDS_Hypothesis& other) const { return !(*this==other); }
//
#include "SMESHDS_Mesh.hxx"
-#include "SMESHDS_Group.hxx"
-#include "SMDS_VertexPosition.hxx"
+#include "SMDS_Downward.hxx"
#include "SMDS_EdgePosition.hxx"
#include "SMDS_FacePosition.hxx"
#include "SMDS_SpacePosition.hxx"
-#include "SMDS_Downward.hxx"
+#include "SMDS_VertexPosition.hxx"
+#include "SMESHDS_Group.hxx"
#include "SMESHDS_GroupOnGeom.hxx"
#include "SMESHDS_Script.hxx"
+#include "SMESHDS_TSubMeshHolder.hxx"
#include <Standard_ErrorHandler.hxx>
#include <Standard_OutOfRange.hxx>
using namespace std;
+class SMESHDS_Mesh::SubMeshHolder : public SMESHDS_TSubMeshHolder< const SMESHDS_SubMesh >
+{
+};
+
//=======================================================================
//function : Create
//purpose :
//=======================================================================
SMESHDS_Mesh::SMESHDS_Mesh(int theMeshID, bool theIsEmbeddedMode):
myMeshID(theMeshID),
- myIsEmbeddedMode(theIsEmbeddedMode),
- myCurSubID(-1)
+ mySubMeshHolder( new SubMeshHolder ),
+ myIsEmbeddedMode(theIsEmbeddedMode)
{
myScript = new SMESHDS_Script(theIsEmbeddedMode);
- myCurSubMesh = 0;
SetPersistentId(theMeshID);
}
// - hypotheses
myShapeToHypothesis.Clear();
// - shape indices in SMDS_Position of nodes
- map<int,SMESHDS_SubMesh*>::iterator i_sub = myShapeIndexToSubMesh.begin();
- for ( ; i_sub != myShapeIndexToSubMesh.end(); i_sub++ ) {
- if ( !i_sub->second->IsComplexSubmesh() ) {
- SMDS_NodeIteratorPtr nIt = i_sub->second->GetNodes();
+ SMESHDS_SubMeshIteratorPtr smIt = SubMeshes();
+ while ( SMESHDS_SubMesh* sm = const_cast< SMESHDS_SubMesh* >( smIt->next() )) {
+ if ( !sm->IsComplexSubmesh() ) {
+ SMDS_NodeIteratorPtr nIt = sm->GetNodes();
while ( nIt->more() )
- i_sub->second->RemoveNode(nIt->next(), false);
+ sm->RemoveNode(nIt->next(), false);
}
}
// - sub-meshes
- TShapeIndexToSubMesh::iterator i_sm = myShapeIndexToSubMesh.begin();
- for ( ; i_sm != myShapeIndexToSubMesh.end(); ++i_sm )
- delete i_sm->second;
- myShapeIndexToSubMesh.clear();
+ mySubMeshHolder->DeleteAll();
+
myIndexToShape.Clear();
// - groups on geometry
set<SMESHDS_GroupBase*>::iterator gr = myGroups.begin();
bool SMESHDS_Mesh::AddHypothesis(const TopoDS_Shape & SS,
const SMESHDS_Hypothesis * H)
{
- if (!myShapeToHypothesis.IsBound(SS.Oriented(TopAbs_FORWARD))) {
+ if (!myShapeToHypothesis.IsBound(SS/*.Oriented(TopAbs_FORWARD)*/)) {
list<const SMESHDS_Hypothesis *> aList;
- myShapeToHypothesis.Bind(SS.Oriented(TopAbs_FORWARD), aList);
+ myShapeToHypothesis.Bind(SS/*.Oriented(TopAbs_FORWARD)*/, aList);
}
list<const SMESHDS_Hypothesis *>& alist =
- myShapeToHypothesis(SS.Oriented(TopAbs_FORWARD)); // ignore orientation of SS
+ myShapeToHypothesis(SS/*.Oriented(TopAbs_FORWARD)*/); // ignore orientation of SS
//Check if the Hypothesis is still present
list<const SMESHDS_Hypothesis*>::iterator ith = find(alist.begin(),alist.end(), H );
bool SMESHDS_Mesh::RemoveHypothesis(const TopoDS_Shape & S,
const SMESHDS_Hypothesis * H)
{
- if( myShapeToHypothesis.IsBound( S.Oriented(TopAbs_FORWARD) ) )
+ if( myShapeToHypothesis.IsBound( S/*.Oriented(TopAbs_FORWARD)*/ ) )
{
- list<const SMESHDS_Hypothesis *>& alist=myShapeToHypothesis.ChangeFind( S.Oriented(TopAbs_FORWARD) );
+ list<const SMESHDS_Hypothesis *>& alist=myShapeToHypothesis.ChangeFind( S/*.Oriented(TopAbs_FORWARD)*/ );
list<const SMESHDS_Hypothesis*>::iterator ith=find(alist.begin(),alist.end(), H );
if (ith != alist.end())
{
//purpose :
//=======================================================================
-static void removeFromContainers (map<int,SMESHDS_SubMesh*>& theSubMeshes,
+static void removeFromContainers (SMESHDS_Mesh* theMesh,
set<SMESHDS_GroupBase*>& theGroups,
list<const SMDS_MeshElement*>& theElems,
const bool isNode)
// Rm from sub-meshes
// Element should belong to only one sub-mesh
- if ( !theSubMeshes.empty() )
+ if ( theMesh->SubMeshes()->more() )
{
- SMESHDS_Mesh* mesh = theSubMeshes.begin()->second->GetParent();
list<const SMDS_MeshElement *>::iterator elIt = theElems.begin();
if ( isNode ) {
for ( ; elIt != theElems.end(); ++elIt )
- if ( SMESHDS_SubMesh* sm = mesh->MeshElements( (*elIt)->getshapeId() ))
+ if ( SMESHDS_SubMesh* sm = theMesh->MeshElements( (*elIt)->getshapeId() ))
sm->RemoveNode( static_cast<const SMDS_MeshNode*> (*elIt), deleted );
}
else {
for ( ; elIt != theElems.end(); ++elIt )
- if ( SMESHDS_SubMesh* sm = mesh->MeshElements( (*elIt)->getshapeId() ))
+ if ( SMESHDS_SubMesh* sm = theMesh->MeshElements( (*elIt)->getshapeId() ))
sm->RemoveElement( *elIt, deleted );
}
}
//=======================================================================
//function : RemoveNode
-//purpose :
+//purpose :
//=======================================================================
void SMESHDS_Mesh::RemoveNode(const SMDS_MeshNode * n)
{
if ( n->NbInverseElements() == 0 && !(hasConstructionEdges() || hasConstructionFaces()))
{
- SMESHDS_SubMesh* subMesh=0;
- map<int,SMESHDS_SubMesh*>::iterator SubIt =
- myShapeIndexToSubMesh.find( n->getshapeId() );
- if ( SubIt != myShapeIndexToSubMesh.end() )
- subMesh = SubIt->second;
- else
- SubIt = myShapeIndexToSubMesh.begin();
- for ( ; !subMesh && SubIt != myShapeIndexToSubMesh.end(); SubIt++ )
- if (!SubIt->second->IsComplexSubmesh() && SubIt->second->Contains( n ))
- subMesh = SubIt->second;
-
+ SMESHDS_SubMesh* subMesh = MeshElements( n->getshapeId() );
+ SMESHDS_SubMeshIteratorPtr subIt;
+ if ( !subMesh )
+ subIt = SubMeshes();
+ for ( ; !subMesh && subIt->more(); ) {
+ subMesh = const_cast< SMESHDS_SubMesh* >( subIt->next() );
+ if ( subMesh->IsComplexSubmesh() || !subMesh->Contains( n ))
+ subMesh = 0;
+ }
RemoveFreeNode( n, subMesh, true);
return;
}
-
+
myScript->RemoveNode(n->GetID());
-
+
list<const SMDS_MeshElement *> removedElems;
list<const SMDS_MeshElement *> removedNodes;
SMDS_Mesh::RemoveElement( n, removedElems, removedNodes, true );
- removeFromContainers( myShapeIndexToSubMesh, myGroups, removedElems, false );
- removeFromContainers( myShapeIndexToSubMesh, myGroups, removedNodes, true );
+ removeFromContainers( this, myGroups, removedElems, false );
+ removeFromContainers( this, myGroups, removedNodes, true );
}
//=======================================================================
{
SMESHDS_SubMesh* subMesh=0;
if ( elt->getshapeId() > 0 )
- {
- map<int,SMESHDS_SubMesh*>::iterator SubIt = myShapeIndexToSubMesh.find( elt->getshapeId() );
- if ( SubIt != myShapeIndexToSubMesh.end() )
- subMesh = SubIt->second;
- }
+ subMesh = MeshElements( elt->getshapeId() );
+
RemoveFreeElement( elt, subMesh, true);
return;
}
SMDS_Mesh::RemoveElement(elt, removedElems, removedNodes, false);
- removeFromContainers( myShapeIndexToSubMesh, myGroups, removedElems, false );
+ removeFromContainers( this, myGroups, removedElems, false );
}
//=======================================================================
SMDS_Mesh::Clear();
// clear submeshes
- map<int,SMESHDS_SubMesh*>::iterator sub, subEnd = myShapeIndexToSubMesh.end();
- for ( sub = myShapeIndexToSubMesh.begin(); sub != subEnd; ++sub )
- sub->second->Clear();
+ SMESHDS_SubMeshIteratorPtr smIt = SubMeshes();
+ while ( SMESHDS_SubMesh* sm = const_cast< SMESHDS_SubMesh* >( smIt->next() ))
+ sm->Clear();
// clear groups
TGroups::iterator group, groupEnd = myGroups.end();
* \brief return submesh by shape
* \param shape - the sub-shape
* \retval SMESHDS_SubMesh* - the found submesh
- *
- * search of submeshes is optimized
*/
//================================================================================
if ( shape.IsNull() )
return 0;
- if ( !myCurSubShape.IsNull() && shape.IsSame( myCurSubShape ))
- return myCurSubMesh;
-
- getSubmesh( ShapeToIndex( shape ));
- myCurSubShape = shape;
- return myCurSubMesh;
-}
-
-//================================================================================
-/*!
- * \brief return submesh by sub-shape index
- * \param Index - the sub-shape index
- * \retval SMESHDS_SubMesh* - the found submesh
- * search of submeshes is optimized
- */
-//================================================================================
-
-SMESHDS_SubMesh* SMESHDS_Mesh::getSubmesh( const int Index )
-{
- //Update or build submesh
- if ( Index != myCurSubID ) {
- map<int,SMESHDS_SubMesh*>::iterator it = myShapeIndexToSubMesh.find( Index );
- if ( it == myShapeIndexToSubMesh.end() )
- it = myShapeIndexToSubMesh.insert( make_pair(Index, new SMESHDS_SubMesh(this, Index) )).first;
- myCurSubMesh = it->second;
- myCurSubID = Index;
- myCurSubShape.Nullify(); // myCurSubShape no more corresponds to submesh
- }
- return myCurSubMesh;
+ return NewSubMesh( ShapeToIndex( shape ));
}
//================================================================================
void SMESHDS_Mesh::UnSetNodeOnShape(const SMDS_MeshNode* aNode)
{
int shapeId = aNode->getshapeId();
- if (shapeId >= 0)
- {
- map<int, SMESHDS_SubMesh*>::iterator it = myShapeIndexToSubMesh.find(shapeId);
- if (it != myShapeIndexToSubMesh.end())
- it->second->RemoveNode(aNode, /*deleted=*/false);
- }
+ if (shapeId > 0)
+ if ( SMESHDS_SubMesh* sm = MeshElements( shapeId ))
+ sm->RemoveNode(aNode, /*deleted=*/false);
}
//=======================================================================
void SMESHDS_Mesh::UnSetMeshElementOnShape(const SMDS_MeshElement * elem,
const TopoDS_Shape & S)
{
- int Index = myIndexToShape.FindIndex(S);
-
- map<int,SMESHDS_SubMesh*>::iterator it = myShapeIndexToSubMesh.find( Index );
- if ( it != myShapeIndexToSubMesh.end() )
- {
- if (elem->GetType() == SMDSAbs_Node)
- it->second->RemoveNode(static_cast<const SMDS_MeshNode*> (elem), /*deleted=*/false);
- else
- it->second->RemoveElement(elem, /*deleted=*/false);
- }
+ if ( SMESHDS_SubMesh* sm = MeshElements( S ))
+ {
+ if (elem->GetType() == SMDSAbs_Node)
+ sm->RemoveNode(static_cast<const SMDS_MeshNode*> (elem), /*deleted=*/false);
+ else
+ sm->RemoveElement(elem, /*deleted=*/false);
+ }
}
//=======================================================================
//=======================================================================
TopoDS_Shape SMESHDS_Mesh::ShapeToMesh() const
{
- return myShape;
+ return myShape;
}
//=======================================================================
SMESHDS_SubMesh * SMESHDS_Mesh::MeshElements(const TopoDS_Shape & S) const
{
int Index = ShapeToIndex(S);
- TShapeIndexToSubMesh::const_iterator anIter = myShapeIndexToSubMesh.find(Index);
- if (anIter != myShapeIndexToSubMesh.end())
- return anIter->second;
- else
- return NULL;
+ return (SMESHDS_SubMesh *) ( Index ? mySubMeshHolder->Get( Index ) : 0 );
}
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
SMESHDS_SubMesh * SMESHDS_Mesh::MeshElements(const int Index) const
{
- TShapeIndexToSubMesh::const_iterator anIter = myShapeIndexToSubMesh.find(Index);
- if (anIter != myShapeIndexToSubMesh.end())
- return anIter->second;
- else
- return NULL;
+ return const_cast< SMESHDS_SubMesh* >( mySubMeshHolder->Get( Index ));
}
//=======================================================================
list<int> SMESHDS_Mesh::SubMeshIndices() const
{
list<int> anIndices;
- std::map<int,SMESHDS_SubMesh*>::const_iterator anIter = myShapeIndexToSubMesh.begin();
- for (; anIter != myShapeIndexToSubMesh.end(); anIter++) {
- anIndices.push_back((*anIter).first);
- }
+ SMESHDS_SubMeshIteratorPtr smIt = SubMeshes();
+ while ( const SMESHDS_SubMesh* sm = smIt->next() )
+ anIndices.push_back( sm->GetID() );
+
return anIndices;
}
+//=======================================================================
+//function : SubMeshes
+//purpose :
+//=======================================================================
+
+SMESHDS_SubMeshIteratorPtr SMESHDS_Mesh::SubMeshes() const
+{
+ return SMESHDS_SubMeshIteratorPtr( mySubMeshHolder->GetIterator() );
+}
+
//=======================================================================
//function : GetHypothesis
//purpose :
const list<const SMESHDS_Hypothesis*>&
SMESHDS_Mesh::GetHypothesis(const TopoDS_Shape & S) const
{
- if ( myShapeToHypothesis.IsBound( S.Oriented(TopAbs_FORWARD) ) ) // ignore orientation of S
- return myShapeToHypothesis.Find( S.Oriented(TopAbs_FORWARD) );
+ if ( myShapeToHypothesis.IsBound( S/*.Oriented(TopAbs_FORWARD)*/ ) ) // ignore orientation of S
+ return myShapeToHypothesis.Find( S/*.Oriented(TopAbs_FORWARD)*/ );
static list<const SMESHDS_Hypothesis*> empty;
return empty;
//=======================================================================
bool SMESHDS_Mesh::HasMeshElements(const TopoDS_Shape & S) const
{
- if (myShape.IsNull()) MESSAGE("myShape is NULL");
- int Index = myIndexToShape.FindIndex(S);
- return myShapeIndexToSubMesh.find(Index)!=myShapeIndexToSubMesh.end();
+ int Index = myIndexToShape.FindIndex(S);
+ return mySubMeshHolder->Get( Index );
}
//=======================================================================
//=======================================================================
bool SMESHDS_Mesh::HasHypothesis(const TopoDS_Shape & S)
{
- return myShapeToHypothesis.IsBound(S.Oriented(TopAbs_FORWARD));
+ return myShapeToHypothesis.IsBound(S/*.Oriented(TopAbs_FORWARD)*/);
}
//=======================================================================
//=======================================================================
SMESHDS_SubMesh * SMESHDS_Mesh::NewSubMesh(int Index)
{
- SMESHDS_SubMesh* SM = 0;
- TShapeIndexToSubMesh::iterator anIter = myShapeIndexToSubMesh.find(Index);
- if (anIter == myShapeIndexToSubMesh.end())
+ SMESHDS_SubMesh* SM = MeshElements( Index );
+ if ( !SM )
{
SM = new SMESHDS_SubMesh(this, Index);
- myShapeIndexToSubMesh[Index]=SM;
+ mySubMeshHolder->Add( Index, SM );
}
- else
- SM = anIter->second;
return SM;
}
int SMESHDS_Mesh::MaxSubMeshIndex() const
{
- return myShapeIndexToSubMesh.empty() ? 0 : myShapeIndexToSubMesh.rbegin()->first;
+ return mySubMeshHolder->GetMaxID();
}
//=======================================================================
//=======================================================================
void SMESHDS_Mesh::SetNodeInVolume(const SMDS_MeshNode* aNode, int Index)
{
- //add(aNode, getSubmesh(Index));
- if ( add( aNode, getSubmesh( Index )))
+ if ( add( aNode, NewSubMesh( Index )))
((SMDS_MeshNode*) aNode)->SetPosition( SMDS_SpacePosition::originSpacePosition());
}
void SMESHDS_Mesh::SetNodeOnFace(const SMDS_MeshNode* aNode, int Index, double u, double v)
{
//Set Position on Node
- if ( add( aNode, getSubmesh( Index )))
+ if ( add( aNode, NewSubMesh( Index )))
const_cast< SMDS_MeshNode* >
( aNode )->SetPosition(SMDS_PositionPtr(new SMDS_FacePosition( u, v)));
}
double u)
{
//Set Position on Node
- if ( add( aNode, getSubmesh( Index )))
+ if ( add( aNode, NewSubMesh( Index )))
const_cast< SMDS_MeshNode* >
( aNode )->SetPosition(SMDS_PositionPtr(new SMDS_EdgePosition(u)));
}
void SMESHDS_Mesh::SetNodeOnVertex(const SMDS_MeshNode* aNode, int Index)
{
//Set Position on Node
- if ( add( aNode, getSubmesh( Index )))
+ if ( add( aNode, NewSubMesh( Index )))
const_cast< SMDS_MeshNode* >
( aNode )->SetPosition(SMDS_PositionPtr(new SMDS_VertexPosition()));
}
void SMESHDS_Mesh::SetMeshElementOnShape(const SMDS_MeshElement* anElement,
int Index)
{
- add( anElement, getSubmesh( Index ));
+ add( anElement, NewSubMesh( Index ));
}
//=======================================================================
// myScript
delete myScript;
// submeshes
- TShapeIndexToSubMesh::iterator i_sm = myShapeIndexToSubMesh.begin();
- for ( ; i_sm != myShapeIndexToSubMesh.end(); ++i_sm )
- delete i_sm->second;
+ delete mySubMeshHolder;
}
int myCellsSize = myCells.size();
int newSmdsId = 0;
for (int i = 0; i < myCellsSize; i++)
+ {
+ if (myCells[i])
{
- if (myCells[i])
- {
- newSmdsId++; // SMDS id start to 1
- assert(newSmdsId <= newCellSize);
- newCells[newSmdsId] = myCells[i];
- newCells[newSmdsId]->setId(newSmdsId);
- //MESSAGE("myCells["<< i << "] --> newCells[" << newSmdsId << "]");
- int idvtk = myCells[i]->getVtkId();
- //newSmdsToVtk[newSmdsId] = idvtk;
- assert(idvtk < newCellSize);
- newVtkToSmds[idvtk] = newSmdsId;
- }
+ newSmdsId++; // SMDS id start to 1
+ assert(newSmdsId <= newCellSize);
+ newCells[newSmdsId] = myCells[i];
+ newCells[newSmdsId]->setId(newSmdsId);
+ //MESSAGE("myCells["<< i << "] --> newCells[" << newSmdsId << "]");
+ int idvtk = myCells[i]->getVtkId();
+ //newSmdsToVtk[newSmdsId] = idvtk;
+ assert(idvtk < newCellSize);
+ newVtkToSmds[idvtk] = newSmdsId;
}
+ }
myCells.swap(newCells);
//myCellIdSmdsToVtk.swap(newSmdsToVtk);
// --- compact list myNodes and myElements in submeshes
- map<int,SMESHDS_SubMesh*>::iterator it = myShapeIndexToSubMesh.begin();
- for(; it != myShapeIndexToSubMesh.end(); ++it)
- {
- (*it).second->compactList();
- }
-
+ SMESHDS_SubMeshIteratorPtr smIt = SubMeshes();
+ while ( SMESHDS_SubMesh* sm = const_cast< SMESHDS_SubMesh* >( smIt->next() ))
+ sm->compactList();
}
void SMESHDS_Mesh::CleanDownWardConnectivity()
#include <TopTools_IndexedMapOfShape.hxx>
#include <TopoDS_Shape.hxx>
+#include <map>
+
class TopoDS_Solid ;
class TopoDS_Shell ;
class TopoDS_Face ;
class SMDS_Mesh0DElement;
class SMDS_BallElement;
-#include <map>
-
/*
* Using of native hash_map isn't portable and don't work on WIN32 platform.
* So this functionality implement on new NCollection_DataMap technology
SMESHDS_SubMesh * MeshElements(const TopoDS_Shape & S) const;
SMESHDS_SubMesh * MeshElements(const int Index) const;
std::list<int> SubMeshIndices() const;
- const std::map<int,SMESHDS_SubMesh*>& SubMeshes() const
- { return myShapeIndexToSubMesh; }
- const TopoDS_Shape& GetCurrentSubShape() const { return myCurSubShape; }
+ SMESHDS_SubMeshIteratorPtr SubMeshes() const;
bool HasHypothesis(const TopoDS_Shape & S);
const std::list<const SMESHDS_Hypothesis*>& GetHypothesis(const TopoDS_Shape & S) const;
~SMESHDS_Mesh();
private:
- void addNodeToSubmesh( const SMDS_MeshNode* aNode, int Index )
- {
- //Update or build submesh
- std::map<int,SMESHDS_SubMesh*>::iterator it = myShapeIndexToSubMesh.find( Index );
- if ( it == myShapeIndexToSubMesh.end() )
- it = myShapeIndexToSubMesh.insert( std::make_pair(Index, new SMESHDS_SubMesh(this, Index) )).first;
- it->second->AddNode( aNode ); // add aNode to submesh
- }
-
+
ShapeToHypothesis myShapeToHypothesis;
int myMeshID, myPersistentID;
TopoDS_Shape myShape;
- typedef std::map<int,SMESHDS_SubMesh*> TShapeIndexToSubMesh;
- TShapeIndexToSubMesh myShapeIndexToSubMesh;
+ class SubMeshHolder;
+ SubMeshHolder* mySubMeshHolder;
TopTools_IndexedMapOfShape myIndexToShape;
SMESHDS_Script* myScript;
bool myIsEmbeddedMode;
- // optimize addition of nodes/elements to submeshes by, SetNodeInVolume() etc:
- // avoid search of submeshes in maps
bool add( const SMDS_MeshElement* elem, SMESHDS_SubMesh* subMesh );
SMESHDS_SubMesh* getSubmesh( const TopoDS_Shape & shape);
- SMESHDS_SubMesh* getSubmesh( const int Index );
- int myCurSubID;
- TopoDS_Shape myCurSubShape;
- SMESHDS_SubMesh* myCurSubMesh;
};
--- /dev/null
+// Copyright (C) 2007-2014 CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// 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, or (at your option) any later version.
+//
+// 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
+//
+#ifndef __SMESHDS_SubMeshHolder_HXX__
+#define __SMESHDS_SubMeshHolder_HXX__
+
+#include <vector>
+#include <map>
+
+//=======================================================================
+/*!
+ * \brief A binder of a sub-mesh to its ID which can be negative. Provides fast
+ * access to a sub-mesh by its ID.
+ *
+ * Issue 52457: Addition of hypotheses is 8 time longer than meshing.
+ */
+//=======================================================================
+
+template <class SUBMESH>
+class SMESHDS_TSubMeshHolder
+{
+ std::vector< SUBMESH* > myVec; // for ID >= 0
+ std::map< int, SUBMESH* > myMap; // for ID < 0
+
+public:
+
+ ~SMESHDS_TSubMeshHolder()
+ {
+ DeleteAll();
+ }
+ void Add( int id, SUBMESH* sm )
+ {
+ if ( id < 0 )
+ {
+ myMap[ id ] = sm;
+ }
+ else
+ {
+ if ( myVec.size() <= id )
+ myVec.resize( id+1, (SUBMESH*) NULL );
+ myVec[ id ] = sm;
+ }
+ }
+ SUBMESH* Get( int id ) const
+ {
+ if ( id < 0 )
+ {
+ typename std::map< int, SUBMESH* >::const_iterator i2sm = myMap.find( id );
+ return (SUBMESH*) ( i2sm == myMap.end() ? NULL : i2sm->second );
+ }
+ else
+ {
+ return (SUBMESH*) ( id >= myVec.size() ? NULL : myVec[ id ]);
+ }
+ }
+ void DeleteAll()
+ {
+ for ( size_t i = 0; i < myVec.size(); ++i )
+ if ( SUBMESH* sm = myVec[i] )
+ {
+ myVec[i] = 0; // avoid access via Get(i)
+ delete sm;
+ }
+ myVec.clear();
+
+ typename std::map< int, SUBMESH* >::iterator i2sm = myMap.begin();
+ for ( ; i2sm != myMap.end(); ++i2sm )
+ if ( SUBMESH* sm = i2sm->second )
+ {
+ i2sm->second = 0; // avoid access via Get(i)
+ delete sm;
+ }
+ myMap.clear();
+ }
+ int GetMinID() const
+ {
+ return myMap.empty() ? 0 : myMap.begin()->first;
+ }
+ int GetMaxID() const
+ {
+ return myVec.empty() ? ( myMap.empty() ? 0 : myMap.rbegin()->first ) : myVec.size();
+ }
+
+ //-----------------------------------------------------------------------
+ struct Iterator : public SMDS_Iterator< SUBMESH* >
+ {
+ const SMESHDS_TSubMeshHolder<SUBMESH>* myHolder;
+ SUBMESH* myNext;
+ int myCurID, myEndID, myIDDelta;
+
+ void init( const SMESHDS_TSubMeshHolder<SUBMESH>* holder,
+ int firstID, int endID, int delta )
+ {
+ myHolder = holder;
+ myNext = 0;
+ myCurID = firstID;
+ myEndID = endID;
+ myIDDelta = delta;
+
+ next();
+ }
+
+ bool more()
+ {
+ return myNext;
+ }
+
+ SUBMESH* next()
+ {
+ SUBMESH* res = myNext;
+ myNext = 0;
+ while ( !myNext && myCurID != myEndID )
+ {
+ myNext = myHolder->Get( myCurID );
+ myCurID += myIDDelta;
+ }
+ return res;
+ }
+ virtual ~Iterator() {}
+ };
+ //-----------------------------------------------------------------------
+
+ SMDS_Iterator< SUBMESH* >* GetIterator(const bool reverse=false) const
+ {
+ Iterator* iter = new Iterator;
+ if ( reverse ) iter->init( this, GetMaxID(), GetMinID()-1, -1 );
+ else iter->init( this, GetMinID(), GetMaxID()+1, +1 );
+ return iter;
+ }
+};
+
+
+#endif
# header files / no moc processing
SET(_other_HEADERS
+ SMESHGUI_Operations.h
SMESHGUI_Utils.h
SMESHGUI_HypothesesUtils.h
SMESHGUI_Selection.h
#include "SMESHGUI_MeshPatternDlg.h"
#include "SMESHGUI_MultiEditDlg.h"
#include "SMESHGUI_NodesDlg.h"
+#include "SMESHGUI_Operations.h"
#include "SMESHGUI_Preferences_ScalarBarDlg.h"
#include "SMESHGUI_PropertiesDlg.h"
#include "SMESHGUI_RemoveElementsDlg.h"
#include "SMESHGUI_TransparencyDlg.h"
#include "SMESHGUI_FilterUtils.h"
+#include "SMESHGUI_GEOMGenUtils.h"
#include "SMESHGUI_GroupUtils.h"
#include "SMESHGUI_HypothesesUtils.h"
#include "SMESHGUI_MeshUtils.h"
QStringList filter;
std::string myExtension;
- if ( theCommandID == 113 ) {
+ if ( theCommandID == SMESHOp::OpImportMED ) {
filter.append( QObject::tr( "MED_FILES_FILTER" ) + " (*.*med)" );
filter.append( QObject::tr( "ALL_FILES_FILTER" ) + " (*)" );
}
- else if ( theCommandID == 112 ) {
+ else if ( theCommandID == SMESHOp::OpImportUNV ) {
filter.append( QObject::tr( "IDEAS_FILES_FILTER" ) + " (*.unv)" );
}
- else if ( theCommandID == 111 ) {
+ else if ( theCommandID == SMESHOp::OpImportDAT ) {
filter.append( QObject::tr( "DAT_FILES_FILTER" ) + " (*.dat)" );
}
- else if ( theCommandID == 115 ) {
+ else if ( theCommandID == SMESHOp::OpImportSTL ) {
filter.append( QObject::tr( "STL_FILES_FILTER" ) + " (*.stl)" );
}
- else if ( theCommandID == 116 ) {
+ #ifdef WITH_CGNS
+ else if ( theCommandID == SMESHOp::OpImportCGNS ) {
filter.append( QObject::tr( "CGNS_FILES_FILTER" ) + " (*.cgns)" );
}
- else if ( theCommandID == 117 ) {
+ #endif
+ else if ( theCommandID == SMESHOp::OpImportSAUV ) {
filter.append( QObject::tr( "SAUV files (*.sauv*)" ) );
filter.append( QObject::tr( "All files (*)" ) );
}
- else if ( theCommandID == 118 ) {
+ else if ( theCommandID == SMESHOp::OpImportGMF ) {
filter.append( QObject::tr( "GMF_ASCII_FILES_FILTER" ) + " (*.mesh)" );
filter.append( QObject::tr( "GMF_BINARY_FILES_FILTER") + " (*.meshb)" );
}
QStringList filenames;
bool toCreateGroups = true;
- // if ( theCommandID == 118 ) { // GMF
+ // if ( theCommandID == SMESHOp::OpImportGMF ) { // GMF
// SalomeApp_CheckFileDlg* fd = new SalomeApp_CheckFileDlg
// ( SMESHGUI::desktop(), true, QObject::tr("SMESH_REQUIRED_GROUPS"), true, true );
// fd->setWindowTitle( QObject::tr( "SMESH_IMPORT_MESH" ) );
SMESH::mesh_array_var aMeshes = new SMESH::mesh_array;
try {
switch ( theCommandID ) {
- case 111:
+ case SMESHOp::OpImportDAT:
{
// DAT format (currently unsupported)
errors.append( QString( "%1 :\n\t%2" ).arg( filename ).
arg( QObject::tr( "SMESH_ERR_NOT_SUPPORTED_FORMAT" ) ) );
break;
}
- case 112:
+ case SMESHOp::OpImportUNV:
{
// UNV format
aMeshes->length( 1 );
arg( QObject::tr( "SMESH_ERR_UNKNOWN_IMPORT_ERROR" ) ) );
break;
}
- case 113:
+ case SMESHOp::OpImportMED:
{
// MED format
SMESH::DriverMED_ReadStatus res;
}
break;
}
- case 115:
+ case SMESHOp::OpImportSTL:
{
// STL format
aMeshes->length( 1 );
}
break;
}
- case 116:
+ #ifdef WITH_CGNS
+ case SMESHOp::OpImportCGNS:
{
// CGNS format
SMESH::DriverMED_ReadStatus res;
}
break;
}
- case 117:
+ #endif
+ case SMESHOp::OpImportSAUV:
{
// SAUV format
SMESH::DriverMED_ReadStatus res;
}
break;
}
- case 118:
+ case SMESHOp::OpImportGMF:
{
// GMF format
SMESH::ComputeError_var res;
_PTR(StudyBuilder) aBuilder = aStudy->NewBuilder();
_PTR(AttributePixMap) aPixmap = aBuilder->FindOrCreateAttribute( aMeshSO, "AttributePixMap" );
aPixmap->SetPixMap( "ICON_SMESH_TREE_MESH_IMPORTED" );
- if ( theCommandID == 112 ) // mesh names aren't taken from the file for UNV import
+ if ( theCommandID == SMESHOp::OpImportUNV ) // mesh names aren't taken from the file for UNV import
SMESH::SetName( aMeshSO, QFileInfo(filename).fileName() );
anEntryList.append( aMeshSO->GetID().c_str() );
if( aSel )
aSel->selectedObjects( selected );
- const bool isMED = ( theCommandID == 122 || theCommandID == 125 );
- const bool isDAT = ( theCommandID == 121 || theCommandID == 124 );
- const bool isUNV = ( theCommandID == 123 || theCommandID == 126 );
- const bool isSTL = ( theCommandID == 140 || theCommandID == 141 );
- const bool isCGNS= ( theCommandID == 142 || theCommandID == 143 );
- const bool isSAUV= ( theCommandID == 144 || theCommandID == 145 );
- const bool isGMF = ( theCommandID == 146 || theCommandID == 147 );
+ const bool isDAT = ( theCommandID == SMESHOp::OpExportDAT || theCommandID == SMESHOp::OpPopupExportDAT );
+ const bool isMED = ( theCommandID == SMESHOp::OpExportMED || theCommandID == SMESHOp::OpPopupExportMED );
+ const bool isUNV = ( theCommandID == SMESHOp::OpExportUNV || theCommandID == SMESHOp::OpPopupExportUNV );
+ const bool isSTL = ( theCommandID == SMESHOp::OpExportSTL || theCommandID == SMESHOp::OpPopupExportSTL );
+ #ifdef WITH_CGNS
+ const bool isCGNS= ( theCommandID == SMESHOp::OpExportCGNS || theCommandID == SMESHOp::OpPopupExportCGNS );
+ #else
+ const bool isCGNS= false;
+ #endif
+ const bool isSAUV= ( theCommandID == SMESHOp::OpExportSAUV || theCommandID == SMESHOp::OpPopupExportSAUV );
+ const bool isGMF = ( theCommandID == SMESHOp::OpExportGMF || theCommandID == SMESHOp::OpPopupExportGMF );
// actually, the following condition can't be met (added for insurance)
if( selected.Extent() == 0 ||
if(SMESH_Actor *anActor = SMESH::FindActorByEntry(IObject->getEntry())){
unsigned int aMode = anActor->GetEntityMode();
switch(theCommandID){
- case 222:
- InverseEntityMode(aMode,SMESH_Actor::eBallElem);
- break;
- case 216:
+ case SMESHOp::OpDE0DElements:
InverseEntityMode(aMode,SMESH_Actor::e0DElements);
break;
- case 217:
+ case SMESHOp::OpDEEdges:
InverseEntityMode(aMode,SMESH_Actor::eEdges);
break;
- case 218:
+ case SMESHOp::OpDEFaces:
InverseEntityMode(aMode,SMESH_Actor::eFaces);
break;
- case 219:
+ case SMESHOp::OpDEVolumes:
InverseEntityMode(aMode,SMESH_Actor::eVolumes);
break;
- case 220:
+ case SMESHOp::OpDEBalls:
+ InverseEntityMode(aMode,SMESH_Actor::eBallElem);
+ break;
+ case SMESHOp::OpDEAllEntity:
aMode = SMESH_Actor::eAllEntity;
break;
}
if( !aSel || !appStudy )
return;
- if( theCommandID == 1134 ) { // Clipping dialog can be activated without selection
+ if( theCommandID == SMESHOp::OpClipping ) { // Clipping dialog can be activated without selection
if( SMESHGUI* aModule = SMESHGUI::GetSMESHGUI() ) {
aModule->EmitSignalDeactivateDialog();
if( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( aModule ) )
if(selected.Extent() >= 1){
switch(theCommandID){
- case 1133:{
+ case SMESHOp::OpTransparency:{
SMESHGUI::GetSMESHGUI()->EmitSignalDeactivateDialog();
(new SMESHGUI_TransparencyDlg( SMESHGUI::GetSMESHGUI() ))->show();
return;
}
- case 1132: {
+ case SMESHOp::OpProperties: {
double color[3];
QColor faceColor, edgeColor, nodeColor, elem0dColor, ballColor;
QColor orientationColor, outlineColor, volumeColor;
SMESH::RepaintCurrentView();
} // if ( dlg.exec() )
return;
- } // case 1132:
+ } // case SMESHOp::OpProperties:
} // switch(theCommandID)
SALOME_ListIteratorOfListIO It( selected );
for( ; It.More(); It.Next()){
if(IObject->hasEntry()){
if(SMESH_Actor *anActor = SMESH::FindActorByEntry(IObject->getEntry())){
switch(theCommandID){
- case 211:
+ case SMESHOp::OpDMWireframe:
anActor->SetRepresentation(SMESH_Actor::eEdge);
break;
- case 212:
+ case SMESHOp::OpDMShading:
anActor->SetRepresentation(SMESH_Actor::eSurface);
break;
- case 213:
+ case SMESHOp::OpDMShrink:
if(anActor->IsShrunk())
anActor->UnShrink();
else
anActor->SetShrink();
break;
- case 215:
+ case SMESHOp::OpDMNodes:
anActor->SetRepresentation(SMESH_Actor::ePoint);
break;
- case 231:
+ case SMESHOp::OpRepresentationLines:
if(anActor->GetQuadratic2DRepresentation() != SMESH_Actor::eLines)
anActor->SetQuadratic2DRepresentation(SMESH_Actor::eLines);
break;
- case 232:
+ case SMESHOp::OpRepresentationArcs:
if(anActor->GetQuadratic2DRepresentation() != SMESH_Actor::eArcs)
anActor->SetQuadratic2DRepresentation(SMESH_Actor::eArcs);
break;
SMESH_Actor::eControl aControl = SMESH_Actor::eNone;
if(SMESH_Actor *anActor = SMESH::FindActorByEntry(anIO->getEntry())) {
switch ( theCommandID ){
- case 6001:
- aControl = SMESH_Actor::eLength;
+ case SMESHOp::OpFreeNode:
+ aControl = SMESH_Actor::eFreeNodes;
break;
- case 6018:
- aControl = SMESH_Actor::eLength2D;
+ case SMESHOp::OpEqualNode:
+ aControl = SMESH_Actor::eCoincidentNodes;
break;
- case 6002:
+ case SMESHOp::OpFreeEdge:
aControl = SMESH_Actor::eFreeEdges;
break;
- case 6003:
+ case SMESHOp::OpFreeBorder:
aControl = SMESH_Actor::eFreeBorders;
break;
- case 6004:
+ case SMESHOp::OpLength:
+ aControl = SMESH_Actor::eLength;
+ break;
+ case SMESHOp::OpConnection:
aControl = SMESH_Actor::eMultiConnection;
break;
- case 6005:
- aControl = SMESH_Actor::eFreeNodes;
+ case SMESHOp::OpEqualEdge:
+ aControl = SMESH_Actor::eCoincidentElems1D;
+ break;
+ case SMESHOp::OpFreeFace:
+ aControl = SMESH_Actor::eFreeFaces;
+ break;
+ case SMESHOp::OpBareBorderFace:
+ aControl = SMESH_Actor::eBareBorderFace;
+ break;
+ case SMESHOp::OpOverConstrainedFace:
+ aControl = SMESH_Actor::eOverConstrainedFace;
+ break;
+ case SMESHOp::OpLength2D:
+ aControl = SMESH_Actor::eLength2D;
break;
- case 6019:
+ case SMESHOp::OpConnection2D:
aControl = SMESH_Actor::eMultiConnection2D;
break;
- case 6011:
+ case SMESHOp::OpArea:
aControl = SMESH_Actor::eArea;
break;
- case 6012:
+ case SMESHOp::OpTaper:
aControl = SMESH_Actor::eTaper;
break;
- case 6013:
+ case SMESHOp::OpAspectRatio:
aControl = SMESH_Actor::eAspectRatio;
break;
- case 6017:
- aControl = SMESH_Actor::eAspectRatio3D;
- break;
- case 6014:
+ case SMESHOp::OpMinimumAngle:
aControl = SMESH_Actor::eMinimumAngle;
break;
- case 6015:
+ case SMESHOp::OpWarpingAngle:
aControl = SMESH_Actor::eWarping;
break;
- case 6016:
+ case SMESHOp::OpSkew:
aControl = SMESH_Actor::eSkew;
break;
- case 6009:
- aControl = SMESH_Actor::eVolume3D;
+ case SMESHOp::OpMaxElementLength2D:
+ aControl = SMESH_Actor::eMaxElementLength2D;
break;
- case 6021:
- aControl = SMESH_Actor::eFreeFaces;
+ case SMESHOp::OpEqualFace:
+ aControl = SMESH_Actor:: eCoincidentElems2D;
break;
- case 6022:
- aControl = SMESH_Actor::eMaxElementLength2D;
+ case SMESHOp::OpAspectRatio3D:
+ aControl = SMESH_Actor::eAspectRatio3D;
+ break;
+ case SMESHOp::OpVolume:
+ aControl = SMESH_Actor::eVolume3D;
break;
- case 6023:
+ case SMESHOp::OpMaxElementLength3D:
aControl = SMESH_Actor::eMaxElementLength3D;
break;
- case 6024:
+ case SMESHOp::OpBareBorderVolume:
aControl = SMESH_Actor::eBareBorderVolume;
break;
- case 6025:
- aControl = SMESH_Actor::eBareBorderFace;
- break;
- case 6026:
+ case SMESHOp::OpOverConstrainedVolume:
aControl = SMESH_Actor::eOverConstrainedVolume;
break;
- case 6027:
- aControl = SMESH_Actor::eOverConstrainedFace;
- break;
- case 6028:
- aControl = SMESH_Actor::eCoincidentNodes;
- break;
- case 6029:
- aControl = SMESH_Actor::eCoincidentElems1D;
- break;
- case 6030:
- aControl = SMESH_Actor:: eCoincidentElems2D;
- break;
- case 6031:
+ case SMESHOp::OpEqualVolume:
aControl = SMESH_Actor::eCoincidentElems3D;
break;
}
//QAction* act = action( theCommandID );
switch (theCommandID) {
- case 33: // DELETE
+ case SMESHOp::OpDelete:
if(checkLock(aStudy)) break;
OnEditDelete();
break;
-
- case 116:
- case 115:
- case 117:
- case 118:
- case 113:
- case 112:
- case 111: // IMPORT
+ case SMESHOp::OpImportDAT:
+ case SMESHOp::OpImportUNV:
+ case SMESHOp::OpImportMED:
+ case SMESHOp::OpImportSTL:
+#ifdef WITH_CGNS
+ case SMESHOp::OpImportCGNS:
+#endif
+ case SMESHOp::OpImportSAUV:
+ case SMESHOp::OpImportGMF:
{
if(checkLock(aStudy)) break;
::ImportMeshesFromFile(GetSMESHGen(),theCommandID);
break;
}
- case 150: //MED FILE INFORMATION
+ case SMESHOp::OpFileInformation:
{
SALOME_ListIO selected;
LightApp_SelectionMgr *aSel = SMESHGUI::selectionMgr();
}
break;
}
-
- case 122: // EXPORT MED
- case 121:
- case 123:
- case 124:
- case 125:
- case 126:
- case 140:
- case 141:
- case 142:
- case 143:
- case 144:
- case 145:
- case 146:
- case 147:
+ case SMESHOp::OpExportDAT:
+ case SMESHOp::OpExportMED:
+ case SMESHOp::OpExportUNV:
+ case SMESHOp::OpExportSTL:
+#ifdef WITH_CGNS
+ case SMESHOp::OpExportCGNS:
+#endif
+ case SMESHOp::OpExportSAUV:
+ case SMESHOp::OpExportGMF:
+ case SMESHOp::OpPopupExportDAT:
+ case SMESHOp::OpPopupExportMED:
+ case SMESHOp::OpPopupExportUNV:
+ case SMESHOp::OpPopupExportSTL:
+#ifdef WITH_CGNS
+ case SMESHOp::OpPopupExportCGNS:
+#endif
+ case SMESHOp::OpPopupExportSAUV:
+ case SMESHOp::OpPopupExportGMF:
{
::ExportMeshToFile(theCommandID);
break;
}
- case 200: // SCALAR BAR
+ case SMESHOp::OpReset: // SCALAR BAR
{
LightApp_SelectionMgr *aSel = SMESHGUI::selectionMgr();
SALOME_ListIO selected;
}
break;
}
- case 201:
+ case SMESHOp::OpScalarBarProperties:
{
SMESHGUI_Preferences_ScalarBarDlg::ScalarBarProperties( this );
break;
}
- case 2021:
+ case SMESHOp::OpSaveDistribution:
{
// dump control distribution data to the text file
::SaveDistribution();
break;
}
- case 2022:
+ case SMESHOp::OpShowDistribution:
{
// show/ distribution
::ShowDistribution();
}
#ifndef DISABLE_PLOT2DVIEWER
- case 2023:
+ case SMESHOp::OpPlotDistribution:
{
// plot distribution
::PlotDistribution();
#endif
// Auto-color
- case 1136:
+ case SMESHOp::OpAutoColor:
::AutoColor();
break;
- case 1137:
+ case SMESHOp::OpDisableAutoColor:
::DisableAutoColor();
break;
- case 1134: // Clipping
- case 1133: // Tranparency
- case 1132: // Display preferences (colors, shrink size, line width, ...)
+ case SMESHOp::OpClipping:
+ case SMESHOp::OpTransparency:
+ case SMESHOp::OpProperties: // Display preferences (colors, shrink size, line width, ...)
// Display Mode
- case 215: // Nodes
- case 213: // Nodes
- case 212: // Nodes
- case 211: // Nodes
+ case SMESHOp::OpDMWireframe:
+ case SMESHOp::OpDMShading:
+ case SMESHOp::OpDMNodes:
+ case SMESHOp::OpDMShrink:
::SetDisplayMode(theCommandID, myMarkerMap);
break;
//2D quadratic representation
- case 231:
- case 232:
+ case SMESHOp::OpRepresentationLines:
+ case SMESHOp::OpRepresentationArcs:
::SetDisplayMode(theCommandID, myMarkerMap);
break;
// Display Entity
- case 216: // 0D elements
- case 217: // Edges
- case 218: // Faces
- case 219: // Volumes
- case 220: // All Entity
- case 222: // Balls
+ case SMESHOp::OpDE0DElements:
+ case SMESHOp::OpDEEdges:
+ case SMESHOp::OpDEFaces:
+ case SMESHOp::OpDEVolumes:
+ case SMESHOp::OpDEBalls:
+ case SMESHOp::OpDEAllEntity:
::SetDisplayEntity(theCommandID);
break;
- case 221: // Orientation of faces
+ case SMESHOp::OpOrientationOnFaces:
{
LightApp_SelectionMgr* mgr = selectionMgr();
SALOME_ListIO selected; mgr->selectedObjects( selected );
break;
}
- case 214: // UPDATE
+ case SMESHOp::OpUpdate:
{
if(checkLock(aStudy)) break;
SUIT_OverrideCursor wc;
break;
}
- case 300: // ERASE
- case 301: // DISPLAY
- case 302: // DISPLAY ONLY
+ case SMESHOp::OpHide:
+ case SMESHOp::OpShow:
+ case SMESHOp::OpShowOnly:
{
SMESH::EDisplaing anAction;
switch (theCommandID) {
- case 300: anAction = SMESH::eErase; break;
- case 301: anAction = SMESH::eDisplay; break;
- case 302: anAction = SMESH::eDisplayOnly; break;
+ case SMESHOp::OpHide: anAction = SMESH::eErase; break;
+ case SMESHOp::OpShow: anAction = SMESH::eDisplay; break;
+ case SMESHOp::OpShowOnly: anAction = SMESH::eDisplayOnly; break;
}
LightApp_SelectionMgr *aSel = SMESHGUI::selectionMgr();
if (aSel)
aSel->selectedObjects( sel_objects );
- if( theCommandID==302 )
+ if( theCommandID==SMESHOp::OpShowOnly )
{
MESSAGE("anAction = SMESH::eDisplayOnly");
startOperation( myEraseAll );
}
// PAL13338 + PAL15161 -->
- if ( ( theCommandID==301 || theCommandID==302 ) && !checkLock(aStudy)) {
+ if ( ( theCommandID==SMESHOp::OpShow || theCommandID==SMESHOp::OpShowOnly ) && !checkLock(aStudy)) {
MESSAGE("anAction = SMESH::eDisplayOnly");
SMESH::UpdateView();
SMESHGUI::GetSMESHGUI()->EmitSignalVisibilityChanged();
break;
}
- case 4000: // NODES
+ case SMESHOp::OpNode:
{
if(checkLock(aStudy)) break;
break;
}
- case 2151: // FILTER
- {
- if ( vtkwnd )
- {
- EmitSignalDeactivateDialog();
- ( new SMESHGUI_FilterDlg( this, SMESH::EDGE ) )->show();
- }
- break;
- }
-
- case 701: // COMPUTE MESH
- case 711: // PRECOMPUTE MESH
- case 712: // EVALUATE MESH
- case 713: // MESH ORDER
- case 702: // Create mesh
- case 703: // Create sub-mesh
- case 704: // Edit mesh/sub-mesh
+ case SMESHOp::OpCreateMesh:
+ case SMESHOp::OpCreateSubMesh:
+ case SMESHOp::OpEditMeshOrSubMesh:
+ case SMESHOp::OpCompute:
+ case SMESHOp::OpPreCompute:
+ case SMESHOp::OpEvaluate:
+ case SMESHOp::OpMeshOrder:
startOperation( theCommandID );
break;
- case 705: // copy mesh
+ case SMESHOp::OpCopyMesh:
{
if (checkLock(aStudy)) break;
EmitSignalDeactivateDialog();
( new SMESHGUI_CopyMeshDlg( this ) )->show();
}
break;
- case 710: // Build compound mesh
+ case SMESHOp::OpBuildCompoundMesh:
{
if (checkLock(aStudy)) break;
EmitSignalDeactivateDialog();
}
break;
- case 407: // DIAGONAL INVERSION
- case 408: // Delete diagonal
+ case SMESHOp::OpDiagonalInversion:
+ case SMESHOp::OpUnionOfTwoTriangle:
{
if ( !vtkwnd )
{
}
*/
EmitSignalDeactivateDialog();
- if ( theCommandID == 407 )
+ if ( theCommandID == SMESHOp::OpDiagonalInversion )
( new SMESHGUI_TrianglesInversionDlg( this ) )->show();
else
( new SMESHGUI_UnionOfTwoTrianglesDlg( this ) )->show();
break;
}
- case 409: // Change orientation
- case 410: // Union of triangles
- case 411: // Cutting of quadrangles
- case 419: // Splitting volumes into tetrahedra
+ case SMESHOp::OpOrientation:
+ case SMESHOp::OpUnionOfTriangles:
+ case SMESHOp::OpCuttingOfQuadrangles:
+ case SMESHOp::OpSplitVolumes:
{
if ( !vtkwnd )
{
EmitSignalDeactivateDialog();
SMESHGUI_MultiEditDlg* aDlg = NULL;
- if ( theCommandID == 409 )
+ if ( theCommandID == SMESHOp::OpOrientation )
aDlg = new SMESHGUI_ChangeOrientationDlg(this);
- else if ( theCommandID == 410 )
+ else if ( theCommandID == SMESHOp::OpUnionOfTriangles )
aDlg = new SMESHGUI_UnionOfTrianglesDlg(this);
- else if ( theCommandID == 419 )
+ else if ( theCommandID == SMESHOp::OpSplitVolumes )
aDlg = new SMESHGUI_SplitVolumesDlg(this);
else
aDlg = new SMESHGUI_CuttingOfQuadsDlg(this);
aDlg->show();
break;
}
- case 412: // Smoothing
+ case SMESHOp::OpSmoothing:
{
if(checkLock(aStudy)) break;
if( vtkwnd ) {
}
break;
}
- case 413: // Extrusion
+ case SMESHOp::OpExtrusion:
{
if (checkLock(aStudy)) break;
if (vtkwnd) {
}
break;
}
- case 414: // Revolution
+ case SMESHOp::OpExtrusionAlongAPath:
+ {
+ if (checkLock(aStudy)) break;
+ if (vtkwnd) {
+ EmitSignalDeactivateDialog();
+ ( new SMESHGUI_ExtrusionAlongPathDlg( this ) )->show();
+ } else {
+ SUIT_MessageBox::warning(desktop(),
+ tr("SMESH_WRN_WARNING"), tr("SMESH_WRN_VIEWER_VTK"));
+ }
+ break;
+ }
+ case SMESHOp::OpRevolution:
{
if(checkLock(aStudy)) break;
if( vtkwnd ) {
}
break;
}
- case 415: // Pattern mapping
+ case SMESHOp::OpPatternMapping:
{
if ( checkLock( aStudy ) )
break;
}
break;
}
- case 416: // Extrusion along a path
- {
- if (checkLock(aStudy)) break;
- if (vtkwnd) {
- EmitSignalDeactivateDialog();
- ( new SMESHGUI_ExtrusionAlongPathDlg( this ) )->show();
- } else {
- SUIT_MessageBox::warning(desktop(),
- tr("SMESH_WRN_WARNING"), tr("SMESH_WRN_VIEWER_VTK"));
- }
- break;
- }
- case 417: // Convert mesh to quadratic
- case 418: // create 2D mesh from 3D
- case 420: // Reorient faces
- case 806: // CREATE GEO GROUP
+ case SMESHOp::OpConvertMeshToQuadratic:
+ case SMESHOp::OpCreateBoundaryElements: // create 2D mesh from 3D
+ case SMESHOp::OpReorientFaces:
+ case SMESHOp::OpCreateGeometryGroup:
{
startOperation( theCommandID );
break;
}
- case 801: // CREATE GROUP
+ case SMESHOp::OpCreateGroup:
{
if ( !vtkwnd )
{
break;
}
- case 802: // CONSTRUCT GROUP
+ case SMESHOp::OpConstructGroup:
{
if ( !vtkwnd )
{
break;
}
- case 803: // EDIT GROUP
+ case SMESHOp::OpEditGroup:
{
if ( !vtkwnd )
{
break;
}
- case 804: // Add elements to group
+ case SMESHOp::OpAddElemGroupPopup: // Add elements to group
{
if(checkLock(aStudy)) break;
if (myState == 800) {
break;
}
- case 805: // Remove elements from group
+ case SMESHOp::OpRemoveElemGroupPopup: // Remove elements from group
{
if(checkLock(aStudy)) break;
if (myState == 800) {
break;
}
- case 815: // Edit GEOM GROUP as standalone
+ case SMESHOp::OpEditGeomGroupAsGroup:
{
if ( !vtkwnd )
{
break;
}
- case 810: // Union Groups
- case 811: // Intersect groups
- case 812: // Cut groups
+ case SMESHOp::OpUnionGroups:
+ case SMESHOp::OpIntersectGroups:
+ case SMESHOp::OpCutGroups:
{
if ( !vtkwnd )
{
EmitSignalDeactivateDialog();
SMESHGUI_GroupOpDlg* aDlg = 0;
- if ( theCommandID == 810 )
+ if ( theCommandID == SMESHOp::OpUnionGroups )
aDlg = new SMESHGUI_UnionGroupsDlg( this );
- else if ( theCommandID == 811 )
+ else if ( theCommandID == SMESHOp::OpIntersectGroups )
aDlg = new SMESHGUI_IntersectGroupsDlg( this );
else
aDlg = new SMESHGUI_CutGroupsDlg( this );
break;
}
- case 814: // Create groups of entities from existing groups of superior dimensions
+ case SMESHOp::OpGroupUnderlyingElem: // Create groups of entities from existing groups of superior dimensions
{
if ( checkLock( aStudy ) )
break;
break;
}
- case 813: // Delete groups with their contents
+ case SMESHOp::OpDeleteGroup: // Delete groups with their contents
{
if ( !vtkwnd )
{
break;
}
- case 900: // MESH INFOS
- case 903: // WHAT IS
+ case SMESHOp::OpMeshInformation:
+ case SMESHOp::OpWhatIs:
{
- int page = theCommandID == 900 ? SMESHGUI_MeshInfoDlg::BaseInfo : SMESHGUI_MeshInfoDlg::ElemInfo;
+ int page = theCommandID == SMESHOp::OpMeshInformation ? SMESHGUI_MeshInfoDlg::BaseInfo : SMESHGUI_MeshInfoDlg::ElemInfo;
EmitSignalDeactivateDialog();
LightApp_SelectionMgr *aSel = SMESHGUI::selectionMgr();
SALOME_ListIO selected;
break;
}
- case 904: // FIND ELEM
+ case SMESHOp::OpFindElementByPoint:
{
startOperation( theCommandID );
break;
}
- case 1100: // EDIT HYPOTHESIS
+ case SMESHOp::OpEditHypothesis:
{
if(checkLock(aStudy)) break;
Handle(SALOME_InteractiveObject) anIObject = selected.First();
SMESH::SMESH_Hypothesis_var aHypothesis = SMESH::IObjectToInterface<SMESH::SMESH_Hypothesis>(anIObject);
- /* Look for all mesh objects that have this hypothesis affected in order to flag as ModifiedMesh */
- /* At end below '...->updateObjBrowser(true)' will change icon of mesh objects */
- /* Warning : however by internal mechanism all subMeshes icons are changed ! */
if ( !aHypothesis->_is_nil() )
{
- // BUG 0020378
- //SMESHGUI_GenericHypothesisCreator* aCreator = SMESH::GetHypothesisCreator(aHypothesis->GetName());
- SMESHGUI_GenericHypothesisCreator* aCreator = SMESH::GetHypothesisCreator(aHypothesis->GetName());
- if (aCreator) {
+ SMESHGUI_GenericHypothesisCreator* aCreator =
+ SMESH::GetHypothesisCreator( SMESH::toQStr( aHypothesis->GetName() ));
+ if (aCreator)
+ {
+ // set geometry of mesh and sub-mesh to aCreator
+ aSel->selectedObjects( selected, "", /*convertReferences=*/false);
+ if ( selected.Extent() == 1 )
+ {
+ QString subGeomID, meshGeomID;
+ Handle(SALOME_InteractiveObject) hypIO = selected.First();
+ if ( SMESH::GetGeomEntries( hypIO, subGeomID, meshGeomID ))
+ {
+ if ( subGeomID.isEmpty() ) subGeomID = meshGeomID;
+ aCreator->setShapeEntry( subGeomID );
+ aCreator->setMainShapeEntry( meshGeomID );
+ }
+ }
+
aCreator->edit( aHypothesis.in(), anIObject->getName(), desktop(), this, SLOT( onHypothesisEdit( int ) ) );
}
else
}
break;
}
- case 1102: // REMOVE HYPOTHESIS / ALGORITHMS
+ case SMESHOp::OpUnassign: // REMOVE HYPOTHESIS / ALGORITHMS
{
if(checkLock(aStudy)) break;
SUIT_OverrideCursor wc;
break;
}
- case 4008: // BALL
- case 4009: // ELEM0D
- case 4010: // EDGE
- case 4021: // TRIANGLE
- case 4022: // QUAD
- case 4023: // POLYGON
- case 4031: // TETRA
- case 4032: // HEXA
- case 4133: // PENTA
- case 4134: // PYRAMID
- case 4135: // OCTA12
+ case SMESHOp::OpElem0D:
+ case SMESHOp::OpBall:
+ case SMESHOp::OpEdge:
+ case SMESHOp::OpTriangle:
+ case SMESHOp::OpQuadrangle:
+ case SMESHOp::OpPolygon:
+ case SMESHOp::OpTetrahedron:
+ case SMESHOp::OpHexahedron:
+ case SMESHOp::OpPentahedron:
+ case SMESHOp::OpPyramid:
+ case SMESHOp::OpHexagonalPrism:
{
if(checkLock(aStudy)) break;
if ( vtkwnd ) {
EmitSignalDeactivateDialog();
SMDSAbs_EntityType type = SMDSEntity_Edge;
switch (theCommandID) {
- case 4008: type = SMDSEntity_Ball; break;
- case 4009: type = SMDSEntity_0D; break;
- case 4021: type = SMDSEntity_Triangle; break;
- case 4022: type = SMDSEntity_Quadrangle; break;
- case 4031: type = SMDSEntity_Tetra; break;
- case 4023: type = SMDSEntity_Polygon; break;
- case 4032: type = SMDSEntity_Hexa; break;
- case 4133: type = SMDSEntity_Penta; break;
- case 4134: type = SMDSEntity_Pyramid; break;
- case 4135: type = SMDSEntity_Hexagonal_Prism; break;
+ case SMESHOp::OpElem0D: type = SMDSEntity_0D; break;
+ case SMESHOp::OpBall: type = SMDSEntity_Ball; break;
+ case SMESHOp::OpTriangle: type = SMDSEntity_Triangle; break;
+ case SMESHOp::OpQuadrangle: type = SMDSEntity_Quadrangle; break;
+ case SMESHOp::OpTetrahedron: type = SMDSEntity_Tetra; break;
+ case SMESHOp::OpPolygon: type = SMDSEntity_Polygon; break;
+ case SMESHOp::OpHexahedron: type = SMDSEntity_Hexa; break;
+ case SMESHOp::OpPentahedron: type = SMDSEntity_Penta; break;
+ case SMESHOp::OpPyramid: type = SMDSEntity_Pyramid; break;
+ case SMESHOp::OpHexagonalPrism: type = SMDSEntity_Hexagonal_Prism; break;
default:;
}
( new SMESHGUI_AddMeshElementDlg( this, type ) )->show();
}
break;
}
- case 4033: // POLYHEDRON
+ case SMESHOp::OpPolyhedron:
{
if(checkLock(aStudy)) break;
if ( vtkwnd ) {
}
break;
}
- case 4034: // QUADRATIC EDGE
- case 4035: // QUADRATIC TRIANGLE
- case 4036: // QUADRATIC QUADRANGLE
- case 4136: // BIQUADRATIC QUADRANGLE
- case 4137: // BIQUADRATIC TRIANGLE
- case 4037: // QUADRATIC TETRAHEDRON
- case 4038: // QUADRATIC PYRAMID
- case 4039: // QUADRATIC PENTAHEDRON
- case 4040: // QUADRATIC HEXAHEDRON
- case 4140: // TRIQUADRATIC HEXAHEDRON
+ case SMESHOp::OpQuadraticEdge:
+ case SMESHOp::OpQuadraticTriangle:
+ case SMESHOp::OpBiQuadraticTriangle:
+ case SMESHOp::OpQuadraticQuadrangle:
+ case SMESHOp::OpBiQuadraticQuadrangle:
+ case SMESHOp::OpQuadraticTetrahedron:
+ case SMESHOp::OpQuadraticPyramid:
+ case SMESHOp::OpQuadraticPentahedron:
+ case SMESHOp::OpQuadraticHexahedron:
+ case SMESHOp::OpTriQuadraticHexahedron:
{
if(checkLock(aStudy)) break;
if ( vtkwnd ) {
SMDSAbs_EntityType type = SMDSEntity_Last;
switch (theCommandID) {
- case 4034: type = SMDSEntity_Quad_Edge; break;
- case 4035: type = SMDSEntity_Quad_Triangle; break;
- case 4036: type = SMDSEntity_Quad_Quadrangle; break;
- case 4136: type = SMDSEntity_BiQuad_Quadrangle; break;
- case 4137: type = SMDSEntity_BiQuad_Triangle; break;
- case 4037: type = SMDSEntity_Quad_Tetra; break;
- case 4038: type = SMDSEntity_Quad_Pyramid; break;
- case 4039: type = SMDSEntity_Quad_Penta; break;
- case 4040: type = SMDSEntity_Quad_Hexa; break;
- case 4140: type = SMDSEntity_TriQuad_Hexa; break;
+ case SMESHOp::OpQuadraticEdge: type = SMDSEntity_Quad_Edge; break;
+ case SMESHOp::OpQuadraticTriangle: type = SMDSEntity_Quad_Triangle; break;
+ case SMESHOp::OpBiQuadraticTriangle: type = SMDSEntity_BiQuad_Triangle; break;
+ case SMESHOp::OpQuadraticQuadrangle: type = SMDSEntity_Quad_Quadrangle; break;
+ case SMESHOp::OpBiQuadraticQuadrangle: type = SMDSEntity_BiQuad_Quadrangle; break;
+ case SMESHOp::OpQuadraticTetrahedron: type = SMDSEntity_Quad_Tetra; break;
+ case SMESHOp::OpQuadraticPyramid: type = SMDSEntity_Quad_Pyramid; break;
+ case SMESHOp::OpQuadraticPentahedron: type = SMDSEntity_Quad_Penta; break;
+ case SMESHOp::OpQuadraticHexahedron: type = SMDSEntity_Quad_Hexa; break;
+ case SMESHOp::OpTriQuadraticHexahedron: type = SMDSEntity_TriQuad_Hexa; break;
default: break;
}
if ( type != SMDSEntity_Last )
}
break;
}
- case 4041: // REMOVES NODES
+ case SMESHOp::OpRemoveNodes:
{
if(checkLock(aStudy)) break;
if ( vtkwnd ) {
}
break;
}
- case 4042: // REMOVES ELEMENTS
+ case SMESHOp::OpRemoveElements: // REMOVES ELEMENTS
{
if(checkLock(aStudy)) break;
if( vtkwnd ) {
}
break;
}
- case 4043: { // CLEAR_MESH
+ case SMESHOp::OpClearMesh: {
if(checkLock(aStudy)) break;
updateObjBrowser();
break;
}
- case 4044: // REMOVE ORPHAN NODES
+ case SMESHOp::OpRemoveOrphanNodes:
{
if(checkLock(aStudy)) break;
SALOME_ListIO selected;
}
break;
}
- case 4051: // RENUMBERING NODES
+ case SMESHOp::OpRenumberingNodes:
{
if(checkLock(aStudy)) break;
if( vtkwnd ) {
}
break;
}
- case 4052: // RENUMBERING ELEMENTS
+ case SMESHOp::OpRenumberingElements:
{
if(checkLock(aStudy)) break;
if ( vtkwnd ) {
}
break;
}
- case 4061: // TRANSLATION
+ case SMESHOp::OpTranslation:
{
if(checkLock(aStudy)) break;
if ( vtkwnd ) {
}
break;
}
- case 4062: // ROTATION
+ case SMESHOp::OpRotation:
{
if(checkLock(aStudy)) break;
if( vtkwnd ) {
}
break;
}
- case 4063: // SYMMETRY
+ case SMESHOp::OpSymmetry:
{
if(checkLock(aStudy)) break;
if(vtkwnd) {
}
break;
}
- case 4064: // SEWING
+ case SMESHOp::OpScale:
+ {
+ if(checkLock(aStudy)) break;
+ if ( vtkwnd ) {
+ EmitSignalDeactivateDialog();
+ ( new SMESHGUI_ScaleDlg( this ) )->show();
+ }
+ else {
+ SUIT_MessageBox::warning(SMESHGUI::desktop(),
+ tr("SMESH_WRN_WARNING"), tr("SMESH_WRN_VIEWER_VTK"));
+ }
+ break;
+ }
+
+ case SMESHOp::OpSewing:
{
if(checkLock(aStudy)) break;
if(vtkwnd) {
}
break;
}
- case 4065: // MERGE NODES
+ case SMESHOp::OpMergeNodes:
{
if(checkLock(aStudy)) break;
if(vtkwnd) {
}
break;
}
- case 4066: // MERGE EQUAL ELEMENTS
+ case SMESHOp::OpMergeElements:
{
if (checkLock(aStudy)) break;
if (vtkwnd) {
break;
}
- case 4067: // MAKE MESH PASS THROUGH POINT
- startOperation( 4067 );
+ case SMESHOp::OpMoveNode: // MAKE MESH PASS THROUGH POINT
+ startOperation( SMESHOp::OpMoveNode );
break;
- case 4068: // SCALE
- {
- if(checkLock(aStudy)) break;
- if ( vtkwnd ) {
- EmitSignalDeactivateDialog();
- ( new SMESHGUI_ScaleDlg( this ) )->show();
- }
- else {
- SUIT_MessageBox::warning(SMESHGUI::desktop(),
- tr("SMESH_WRN_WARNING"), tr("SMESH_WRN_VIEWER_VTK"));
- }
- break;
- }
-
- case 4069: // DUPLICATE NODES
+ case SMESHOp::OpDuplicateNodes:
{
if(checkLock(aStudy)) break;
if ( vtkwnd ) {
break;
}
- case 4070: // 0D_ON_ALL_NODES
- startOperation( 4070 );
+ case SMESHOp::OpElem0DOnElemNodes: // 0D_ON_ALL_NODES
+ startOperation( SMESHOp::OpElem0DOnElemNodes );
break;
- case 5105: // Library of selection filters
+ case SMESHOp::OpSelectFiltersLibrary: // Library of selection filters
{
static QList<int> aTypes;
if ( aTypes.isEmpty() )
myFilterLibraryDlg->raise();
}
break;
-
- case 6017: // CONTROLS
- case 6016:
- case 6015:
- case 6014:
- case 6013:
- case 6012:
- case 6011:
- case 6001:
- case 6018:
- case 6019:
- case 6002:
- case 6003:
- case 6004:
- case 6005:
- case 6009:
- case 6021:
- case 6022:
- case 6023:
- case 6024:
- case 6025:
- case 6026:
- case 6027:
- case 6028:
- case 6029:
- case 6030:
- case 6031:
+ // CONTROLS
+ case SMESHOp::OpFreeNode:
+ case SMESHOp::OpEqualNode:
+ case SMESHOp::OpFreeEdge:
+ case SMESHOp::OpFreeBorder:
+ case SMESHOp::OpLength:
+ case SMESHOp::OpConnection:
+ case SMESHOp::OpEqualEdge:
+ case SMESHOp::OpFreeFace:
+ case SMESHOp::OpBareBorderFace:
+ case SMESHOp::OpOverConstrainedFace:
+ case SMESHOp::OpLength2D:
+ case SMESHOp::OpConnection2D:
+ case SMESHOp::OpArea:
+ case SMESHOp::OpTaper:
+ case SMESHOp::OpAspectRatio:
+ case SMESHOp::OpMinimumAngle:
+ case SMESHOp::OpWarpingAngle:
+ case SMESHOp::OpSkew:
+ case SMESHOp::OpMaxElementLength2D:
+ case SMESHOp::OpEqualFace:
+ case SMESHOp::OpAspectRatio3D:
+ case SMESHOp::OpVolume:
+ case SMESHOp::OpMaxElementLength3D:
+ case SMESHOp::OpBareBorderVolume:
+ case SMESHOp::OpOverConstrainedVolume:
+ case SMESHOp::OpEqualVolume:
if ( vtkwnd ) {
LightApp_SelectionMgr* mgr = selectionMgr();
tr( "NOT_A_VTK_VIEWER" ) );
}
break;
- case 6032:
+ case SMESHOp::OpOverallMeshQuality:
OverallMeshQuality();
break;
- case 9010:
+ case SMESHOp::OpNumberingNodes:
{
SUIT_OverrideCursor wc;
LightApp_SelectionMgr* mgr = selectionMgr();
}
break;
}
- case 9011:
+ case SMESHOp::OpNumberingElements:
{
SUIT_OverrideCursor wc;
LightApp_SelectionMgr* mgr = selectionMgr();
}
break;
}
- case 501:
- case 502:
- case 503:
- case 504:
- case 505:
+ case SMESHOp::OpPropertiesLength:
+ case SMESHOp::OpPropertiesArea:
+ case SMESHOp::OpPropertiesVolume:
+ case SMESHOp::OpMinimumDistance:
+ case SMESHOp::OpBoundingBox:
{
int page = SMESHGUI_MeasureDlg::MinDistance;
- if ( theCommandID == 502 )
+ if ( theCommandID == SMESHOp::OpBoundingBox )
page = SMESHGUI_MeasureDlg::BoundingBox;
- else if ( theCommandID == 503 )
+ else if ( theCommandID == SMESHOp::OpPropertiesLength )
page = SMESHGUI_MeasureDlg::Length;
- else if ( theCommandID == 504 )
+ else if ( theCommandID == SMESHOp::OpPropertiesArea )
page = SMESHGUI_MeasureDlg::Area;
- else if ( theCommandID == 505 )
+ else if ( theCommandID == SMESHOp::OpPropertiesVolume )
page = SMESHGUI_MeasureDlg::Volume;
EmitSignalDeactivateDialog();
dlg->show();
break;
}
- case 41:
+ case SMESHOp::OpSortChild:
::sortChildren();
break;
// ----- create actions --------------
- //createSMESHAction( 111, "IMPORT_DAT", "", (Qt::CTRL+Qt::Key_B) );
- createSMESHAction( 112, "IMPORT_UNV", "", (Qt::CTRL+Qt::Key_U) );
- createSMESHAction( 113, "IMPORT_MED", "", (Qt::CTRL+Qt::Key_M) );
- createSMESHAction( 114, "NUM" );
- createSMESHAction( 115, "IMPORT_STL" );
- createSMESHAction( 116, "IMPORT_CGNS" );
- createSMESHAction( 117, "IMPORT_SAUV" );
- createSMESHAction( 118, "IMPORT_GMF" );
- createSMESHAction( 121, "DAT" );
- createSMESHAction( 122, "MED" );
- createSMESHAction( 123, "UNV" );
- createSMESHAction( 140, "STL" );
- createSMESHAction( 142, "CGNS");
- createSMESHAction( 144, "SAUV");
- createSMESHAction( 146, "GMF" );
- createSMESHAction( 124, "DAT" );
- createSMESHAction( 125, "MED" );
- createSMESHAction( 126, "UNV" );
- createSMESHAction( 141, "STL" );
- createSMESHAction( 143, "CGNS");
- createSMESHAction( 145, "SAUV");
- createSMESHAction( 147, "GMF" );
- createSMESHAction( 150, "FILE_INFO" );
- createSMESHAction( 33, "DELETE", "ICON_DELETE", Qt::Key_Delete );
- createSMESHAction( 5105, "SEL_FILTER_LIB" );
- createSMESHAction( 701, "COMPUTE", "ICON_COMPUTE" );
- createSMESHAction( 702, "CREATE_MESH", "ICON_DLG_INIT_MESH" );
- createSMESHAction( 703, "CREATE_SUBMESH", "ICON_DLG_ADD_SUBMESH" );
- createSMESHAction( 704, "EDIT_MESHSUBMESH","ICON_DLG_EDIT_MESH" );
- createSMESHAction( 705, "COPY_MESH", "ICON_COPY_MESH" );
- createSMESHAction( 710, "BUILD_COMPOUND", "ICON_BUILD_COMPOUND" );
- createSMESHAction( 711, "PRECOMPUTE", "ICON_PRECOMPUTE" );
- createSMESHAction( 712, "EVALUATE", "ICON_COMPUTE" );
- createSMESHAction( 713, "MESH_ORDER", "ICON_COMPUTE" );
- createSMESHAction( 806, "CREATE_GEO_GROUP","ICON_CREATE_GEO_GROUP" );
- createSMESHAction( 801, "CREATE_GROUP", "ICON_CREATE_GROUP" );
- createSMESHAction( 802, "CONSTRUCT_GROUP", "ICON_CONSTRUCT_GROUP" );
- createSMESHAction( 803, "EDIT_GROUP", "ICON_EDIT_GROUP" );
- createSMESHAction( 815, "EDIT_GEOMGROUP_AS_GROUP", "ICON_EDIT_GROUP" );
- createSMESHAction( 804, "ADD" );
- createSMESHAction( 805, "REMOVE" );
- createSMESHAction( 810, "UN_GROUP", "ICON_UNION" );
- createSMESHAction( 811, "INT_GROUP", "ICON_INTERSECT" );
- createSMESHAction( 812, "CUT_GROUP", "ICON_CUT" );
- createSMESHAction( 814, "UNDERLYING_ELEMS","ICON_UNDERLYING_ELEMS" );
- createSMESHAction( 813, "DEL_GROUP", "ICON_DEL_GROUP" );
- createSMESHAction( 900, "ADV_INFO", "ICON_ADV_INFO" );
- //createSMESHAction( 902, "STD_INFO", "ICON_STD_INFO" );
- //createSMESHAction( 903, "WHAT_IS", "ICON_WHAT_IS" ); // VSR: issue #0021242 (eliminate "Mesh Element Information" command)
- createSMESHAction( 904, "FIND_ELEM", "ICON_FIND_ELEM" );
- createSMESHAction( 6001, "LENGTH", "ICON_LENGTH", 0, true );
- createSMESHAction( 6002, "FREE_EDGE", "ICON_FREE_EDGE", 0, true );
- createSMESHAction( 6021, "FREE_FACES", "ICON_FREE_FACES", 0, true );
- createSMESHAction( 6022, "MAX_ELEMENT_LENGTH_2D", "ICON_MAX_ELEMENT_LENGTH_2D", 0, true );
- createSMESHAction( 6023, "MAX_ELEMENT_LENGTH_3D", "ICON_MAX_ELEMENT_LENGTH_3D", 0, true );
- createSMESHAction( 6024, "BARE_BORDER_VOLUME", "ICON_BARE_BORDER_VOLUME", 0, true );
- createSMESHAction( 6025, "BARE_BORDER_FACE", "ICON_BARE_BORDER_FACE", 0, true );
- createSMESHAction( 6026, "OVER_CONSTRAINED_VOLUME","ICON_OVER_CONSTRAINED_VOLUME", 0, true );
- createSMESHAction( 6027, "OVER_CONSTRAINED_FACE", "ICON_OVER_CONSTRAINED_FACE", 0, true );
- createSMESHAction( 6028, "EQUAL_NODE", "ICON_EQUAL_NODE", 0, true );
- createSMESHAction( 6029, "EQUAL_EDGE", "ICON_EQUAL_EDGE", 0, true );
- createSMESHAction( 6030, "EQUAL_FACE", "ICON_EQUAL_FACE", 0, true );
- createSMESHAction( 6031, "EQUAL_VOLUME", "ICON_EQUAL_VOLUME", 0, true );
- createSMESHAction( 6032, "OVERALL_MESH_QUALITY" );
- createSMESHAction( 6003, "FREE_BORDER", "ICON_FREE_EDGE_2D", 0, true );
- createSMESHAction( 6004, "CONNECTION", "ICON_CONNECTION", 0, true );
- createSMESHAction( 6005, "FREE_NODE", "ICON_FREE_NODE", 0, true );
- createSMESHAction( 6011, "AREA", "ICON_AREA", 0, true );
- createSMESHAction( 6012, "TAPER", "ICON_TAPER", 0, true );
- createSMESHAction( 6013, "ASPECT", "ICON_ASPECT", 0, true );
- createSMESHAction( 6014, "MIN_ANG", "ICON_ANGLE", 0, true );
- createSMESHAction( 6015, "WARP", "ICON_WARP", 0, true );
- createSMESHAction( 6016, "SKEW", "ICON_SKEW", 0, true );
- createSMESHAction( 6017, "ASPECT_3D", "ICON_ASPECT_3D", 0, true );
- createSMESHAction( 6018, "LENGTH_2D", "ICON_LENGTH_2D", 0, true );
- createSMESHAction( 6019, "CONNECTION_2D", "ICON_CONNECTION_2D", 0, true );
- createSMESHAction( 6009, "VOLUME_3D", "ICON_VOLUME_3D", 0, true );
- createSMESHAction( 4000, "NODE", "ICON_DLG_NODE" );
- createSMESHAction( 4009, "ELEM0D", "ICON_DLG_ELEM0D" );
- createSMESHAction( 4008, "BALL", "ICON_DLG_BALL" );
- createSMESHAction( 4010, "EDGE", "ICON_DLG_EDGE" );
- createSMESHAction( 4021, "TRIANGLE", "ICON_DLG_TRIANGLE" );
- createSMESHAction( 4022, "QUAD", "ICON_DLG_QUADRANGLE" );
- createSMESHAction( 4023, "POLYGON", "ICON_DLG_POLYGON" );
- createSMESHAction( 4031, "TETRA", "ICON_DLG_TETRAS" );
- createSMESHAction( 4032, "HEXA", "ICON_DLG_HEXAS" );
- createSMESHAction( 4133, "PENTA", "ICON_DLG_PENTA" );
- createSMESHAction( 4134, "PYRAMID", "ICON_DLG_PYRAMID" );
- createSMESHAction( 4135, "OCTA", "ICON_DLG_OCTA" );
- createSMESHAction( 4033, "POLYHEDRON", "ICON_DLG_POLYHEDRON" );
- createSMESHAction( 4034, "QUADRATIC_EDGE", "ICON_DLG_QUADRATIC_EDGE" );
- createSMESHAction( 4035, "QUADRATIC_TRIANGLE", "ICON_DLG_QUADRATIC_TRIANGLE" );
- createSMESHAction( 4036, "QUADRATIC_QUADRANGLE", "ICON_DLG_QUADRATIC_QUADRANGLE" );
- createSMESHAction( 4136, "BIQUADRATIC_QUADRANGLE", "ICON_DLG_BIQUADRATIC_QUADRANGLE" );
- createSMESHAction( 4137, "BIQUADRATIC_TRIANGLE", "ICON_DLG_BIQUADRATIC_TRIANGLE" );
- createSMESHAction( 4037, "QUADRATIC_TETRAHEDRON", "ICON_DLG_QUADRATIC_TETRAHEDRON" );
- createSMESHAction( 4038, "QUADRATIC_PYRAMID", "ICON_DLG_QUADRATIC_PYRAMID" );
- createSMESHAction( 4039, "QUADRATIC_PENTAHEDRON", "ICON_DLG_QUADRATIC_PENTAHEDRON" );
- createSMESHAction( 4040, "QUADRATIC_HEXAHEDRON", "ICON_DLG_QUADRATIC_HEXAHEDRON" );
- createSMESHAction( 4140, "TRIQUADRATIC_HEXAHEDRON", "ICON_DLG_TRIQUADRATIC_HEXAHEDRON" );
- createSMESHAction( 4041, "REMOVE_NODES", "ICON_DLG_REM_NODE" );
- createSMESHAction( 4042, "REMOVE_ELEMENTS", "ICON_DLG_REM_ELEMENT" );
- createSMESHAction( 4044, "REMOVE_ORPHAN_NODES", "ICON_DLG_REM_ORPHAN_NODES" );
- createSMESHAction( 4043, "CLEAR_MESH" , "ICON_CLEAR_MESH" );
- createSMESHAction( 4051, "RENUM_NODES", "ICON_DLG_RENUMBERING_NODES" );
- createSMESHAction( 4052, "RENUM_ELEMENTS", "ICON_DLG_RENUMBERING_ELEMENTS" );
- createSMESHAction( 4061, "TRANS", "ICON_SMESH_TRANSLATION_VECTOR" );
- createSMESHAction( 4062, "ROT", "ICON_DLG_MESH_ROTATION" );
- createSMESHAction( 4063, "SYM", "ICON_SMESH_SYMMETRY_PLANE" );
- createSMESHAction( 4064, "SEW", "ICON_SMESH_SEWING_FREEBORDERS" );
- createSMESHAction( 4065, "MERGE", "ICON_SMESH_MERGE_NODES" );
- createSMESHAction( 4066, "MERGE_ELEMENTS", "ICON_DLG_MERGE_ELEMENTS" );
- createSMESHAction( 4067, "MESH_THROU_POINT","ICON_DLG_MOVE_NODE" );
- createSMESHAction( 4068, "SCALE", "ICON_DLG_MESH_SCALE" );
- createSMESHAction( 4069, "DUPLICATE_NODES", "ICON_SMESH_DUPLICATE_NODES" );
- createSMESHAction( 4070, "0D_ON_ALL_NODES", "ICON_0D_ON_ALL_NODES" );
- createSMESHAction( 407, "INV", "ICON_DLG_MESH_DIAGONAL" );
- createSMESHAction( 408, "UNION2", "ICON_UNION2TRI" );
- createSMESHAction( 409, "ORIENT", "ICON_DLG_MESH_ORIENTATION" );
- createSMESHAction( 410, "UNION", "ICON_UNIONTRI" );
- createSMESHAction( 411, "CUT", "ICON_CUTQUAD" );
- createSMESHAction( 412, "SMOOTH", "ICON_DLG_SMOOTHING" );
- createSMESHAction( 413, "EXTRUSION", "ICON_EXTRUSION" );
- createSMESHAction( 414, "REVOLUTION", "ICON_REVOLUTION" );
- createSMESHAction( 415, "MAP", "ICON_MAP" );
- createSMESHAction( 416, "EXTRUSION_ALONG", "ICON_EXTRUSION_ALONG" );
- createSMESHAction( 417, "CONV_TO_QUAD", "ICON_CONV_TO_QUAD" );
- createSMESHAction( 418, "2D_FROM_3D", "ICON_2D_FROM_3D" );
- createSMESHAction( 419, "SPLIT_TO_TETRA", "ICON_SPLIT_TO_TETRA" );
- createSMESHAction( 420, "REORIENT_2D", "ICON_REORIENT_2D" );
- createSMESHAction( 200, "RESET" );
- createSMESHAction( 201, "SCALAR_BAR_PROP" );
- createSMESHAction( 2021, "SAVE_DISTRIBUTION" );
- createSMESHAction( 2022, "SHOW_DISTRIBUTION","",0, true );
+ //createSMESHAction( SMESHOp::OpImportDAT, "IMPORT_DAT", "", (Qt::CTRL+Qt::Key_B) );
+ createSMESHAction( SMESHOp::OpImportUNV, "IMPORT_UNV", "", (Qt::CTRL+Qt::Key_U) );
+ createSMESHAction( SMESHOp::OpImportMED, "IMPORT_MED", "", (Qt::CTRL+Qt::Key_M) );
+ //createSMESHAction( 114, "NUM" );
+ createSMESHAction( SMESHOp::OpImportSTL, "IMPORT_STL" );
+#ifdef WITH_CGNS
+ createSMESHAction( SMESHOp::OpImportCGNS, "IMPORT_CGNS" );
+#endif
+ createSMESHAction( SMESHOp::OpImportSAUV, "IMPORT_SAUV" );
+ createSMESHAction( SMESHOp::OpImportGMF, "IMPORT_GMF" );
+ createSMESHAction( SMESHOp::OpExportDAT, "DAT" );
+ createSMESHAction( SMESHOp::OpExportMED, "MED" );
+ createSMESHAction( SMESHOp::OpExportUNV, "UNV" );
+ createSMESHAction( SMESHOp::OpExportSTL, "STL" );
+#ifdef WITH_CGNS
+ createSMESHAction( SMESHOp::OpExportCGNS, "CGNS");
+#endif
+ createSMESHAction( SMESHOp::OpExportSAUV, "SAUV");
+ createSMESHAction( SMESHOp::OpExportGMF, "GMF" );
+ createSMESHAction( SMESHOp::OpPopupExportDAT, "DAT" );
+ createSMESHAction( SMESHOp::OpPopupExportMED, "MED" );
+ createSMESHAction( SMESHOp::OpPopupExportUNV, "UNV" );
+ createSMESHAction( SMESHOp::OpPopupExportSTL, "STL" );
+#ifdef WITH_CGNS
+ createSMESHAction( SMESHOp::OpPopupExportCGNS, "CGNS");
+#endif
+ createSMESHAction( SMESHOp::OpPopupExportSAUV, "SAUV");
+ createSMESHAction( SMESHOp::OpPopupExportGMF, "GMF" );
+ createSMESHAction( SMESHOp::OpFileInformation, "FILE_INFO" );
+ createSMESHAction( SMESHOp::OpDelete, "DELETE", "ICON_DELETE", Qt::Key_Delete );
+ createSMESHAction( SMESHOp::OpSelectFiltersLibrary, "SEL_FILTER_LIB" );
+ createSMESHAction( SMESHOp::OpCreateMesh, "CREATE_MESH", "ICON_DLG_INIT_MESH" );
+ createSMESHAction( SMESHOp::OpCreateSubMesh, "CREATE_SUBMESH", "ICON_DLG_ADD_SUBMESH" );
+ createSMESHAction( SMESHOp::OpEditMeshOrSubMesh, "EDIT_MESHSUBMESH", "ICON_DLG_EDIT_MESH" );
+ createSMESHAction( SMESHOp::OpBuildCompoundMesh, "BUILD_COMPOUND", "ICON_BUILD_COMPOUND" );
+ createSMESHAction( SMESHOp::OpCopyMesh, "COPY_MESH", "ICON_COPY_MESH" );
+ createSMESHAction( SMESHOp::OpCompute, "COMPUTE", "ICON_COMPUTE" );
+ createSMESHAction( SMESHOp::OpPreCompute, "PRECOMPUTE", "ICON_PRECOMPUTE" );
+ createSMESHAction( SMESHOp::OpEvaluate, "EVALUATE", "ICON_COMPUTE" );
+ createSMESHAction( SMESHOp::OpMeshOrder, "MESH_ORDER", "ICON_COMPUTE" );
+ createSMESHAction( SMESHOp::OpCreateGroup, "CREATE_GROUP", "ICON_CREATE_GROUP" );
+ createSMESHAction( SMESHOp::OpCreateGeometryGroup, "CREATE_GEO_GROUP", "ICON_CREATE_GEO_GROUP" );
+ createSMESHAction( SMESHOp::OpConstructGroup, "CONSTRUCT_GROUP", "ICON_CONSTRUCT_GROUP" );
+ createSMESHAction( SMESHOp::OpEditGroup, "EDIT_GROUP", "ICON_EDIT_GROUP" );
+ createSMESHAction( SMESHOp::OpEditGeomGroupAsGroup, "EDIT_GEOMGROUP_AS_GROUP", "ICON_EDIT_GROUP" );
+ createSMESHAction( SMESHOp::OpUnionGroups, "UN_GROUP", "ICON_UNION" );
+ createSMESHAction( SMESHOp::OpIntersectGroups, "INT_GROUP", "ICON_INTERSECT" );
+ createSMESHAction( SMESHOp::OpCutGroups, "CUT_GROUP", "ICON_CUT" );
+ createSMESHAction( SMESHOp::OpGroupUnderlyingElem, "UNDERLYING_ELEMS", "ICON_UNDERLYING_ELEMS" );
+ createSMESHAction( SMESHOp::OpAddElemGroupPopup, "ADD" );
+ createSMESHAction( SMESHOp::OpRemoveElemGroupPopup, "REMOVE" );
+ createSMESHAction( SMESHOp::OpDeleteGroup, "DEL_GROUP", "ICON_DEL_GROUP" );
+ createSMESHAction( SMESHOp::OpMeshInformation , "ADV_INFO", "ICON_ADV_INFO" );
+ //createSMESHAction( SMESHOp::OpStdInfo, "STD_INFO", "ICON_STD_INFO" );
+ //createSMESHAction( SMESHOp::OpWhatIs, "WHAT_IS", "ICON_WHAT_IS" ); // VSR: issue #0021242 (eliminate "Mesh Element Information" command)
+ createSMESHAction( SMESHOp::OpFindElementByPoint, "FIND_ELEM", "ICON_FIND_ELEM" );
+ //update
+ createSMESHAction( SMESHOp::OpFreeNode, "FREE_NODE", "ICON_FREE_NODE", 0, true );
+ createSMESHAction( SMESHOp::OpEqualNode, "EQUAL_NODE", "ICON_EQUAL_NODE", 0, true );
+ createSMESHAction( SMESHOp::OpFreeEdge, "FREE_EDGE", "ICON_FREE_EDGE", 0, true );
+ createSMESHAction( SMESHOp::OpFreeBorder, "FREE_BORDER", "ICON_FREE_EDGE_2D", 0, true );
+ createSMESHAction( SMESHOp::OpLength, "LENGTH", "ICON_LENGTH", 0, true );
+ createSMESHAction( SMESHOp::OpConnection, "CONNECTION", "ICON_CONNECTION", 0, true );
+ createSMESHAction( SMESHOp::OpEqualEdge, "EQUAL_EDGE", "ICON_EQUAL_EDGE", 0, true );
+ createSMESHAction( SMESHOp::OpFreeFace, "FREE_FACES", "ICON_FREE_FACES", 0, true );
+ createSMESHAction( SMESHOp::OpBareBorderFace, "BARE_BORDER_FACE", "ICON_BARE_BORDER_FACE", 0, true );
+ createSMESHAction( SMESHOp::OpOverConstrainedFace, "OVER_CONSTRAINED_FACE", "ICON_OVER_CONSTRAINED_FACE", 0, true );
+ createSMESHAction( SMESHOp::OpLength2D, "LENGTH_2D", "ICON_LENGTH_2D", 0, true );
+ createSMESHAction( SMESHOp::OpConnection2D, "CONNECTION_2D", "ICON_CONNECTION_2D", 0, true );
+ createSMESHAction( SMESHOp::OpArea, "AREA", "ICON_AREA", 0, true );
+ createSMESHAction( SMESHOp::OpTaper, "TAPER", "ICON_TAPER", 0, true );
+ createSMESHAction( SMESHOp::OpAspectRatio, "ASPECT", "ICON_ASPECT", 0, true );
+ createSMESHAction( SMESHOp::OpMinimumAngle, "MIN_ANG", "ICON_ANGLE", 0, true );
+ createSMESHAction( SMESHOp::OpWarpingAngle, "WARP", "ICON_WARP", 0, true );
+ createSMESHAction( SMESHOp::OpSkew, "SKEW", "ICON_SKEW", 0, true );
+ createSMESHAction( SMESHOp::OpMaxElementLength2D, "MAX_ELEMENT_LENGTH_2D", "ICON_MAX_ELEMENT_LENGTH_2D", 0, true );
+ createSMESHAction( SMESHOp::OpEqualFace, "EQUAL_FACE", "ICON_EQUAL_FACE", 0, true );
+ createSMESHAction( SMESHOp::OpAspectRatio3D, "ASPECT_3D", "ICON_ASPECT_3D", 0, true );
+ createSMESHAction( SMESHOp::OpVolume, "VOLUME_3D", "ICON_VOLUME_3D", 0, true );
+ createSMESHAction( SMESHOp::OpMaxElementLength3D, "MAX_ELEMENT_LENGTH_3D", "ICON_MAX_ELEMENT_LENGTH_3D", 0, true );
+ createSMESHAction( SMESHOp::OpBareBorderVolume, "BARE_BORDER_VOLUME", "ICON_BARE_BORDER_VOLUME", 0, true );
+ createSMESHAction( SMESHOp::OpOverConstrainedVolume, "OVER_CONSTRAINED_VOLUME", "ICON_OVER_CONSTRAINED_VOLUME", 0, true );
+ createSMESHAction( SMESHOp::OpEqualVolume, "EQUAL_VOLUME", "ICON_EQUAL_VOLUME", 0, true );
+ createSMESHAction( SMESHOp::OpOverallMeshQuality, "OVERALL_MESH_QUALITY" );
+
+ createSMESHAction( SMESHOp::OpNode, "NODE", "ICON_DLG_NODE" );
+ createSMESHAction( SMESHOp::OpElem0D, "ELEM0D", "ICON_DLG_ELEM0D" );
+ createSMESHAction( SMESHOp::OpElem0DOnElemNodes, "0D_ON_ALL_NODES", "ICON_0D_ON_ALL_NODES" );
+ createSMESHAction( SMESHOp::OpBall, "BALL", "ICON_DLG_BALL" );
+ createSMESHAction( SMESHOp::OpEdge, "EDGE", "ICON_DLG_EDGE" );
+ createSMESHAction( SMESHOp::OpTriangle, "TRIANGLE", "ICON_DLG_TRIANGLE" );
+ createSMESHAction( SMESHOp::OpQuadrangle, "QUAD", "ICON_DLG_QUADRANGLE" );
+ createSMESHAction( SMESHOp::OpPolygon, "POLYGON", "ICON_DLG_POLYGON" );
+ createSMESHAction( SMESHOp::OpTetrahedron, "TETRA", "ICON_DLG_TETRAS" );
+ createSMESHAction( SMESHOp::OpHexahedron, "HEXA", "ICON_DLG_HEXAS" );
+ createSMESHAction( SMESHOp::OpPentahedron, "PENTA", "ICON_DLG_PENTA" );
+ createSMESHAction( SMESHOp::OpPyramid , "PYRAMID", "ICON_DLG_PYRAMID" );
+ createSMESHAction( SMESHOp::OpHexagonalPrism, "OCTA", "ICON_DLG_OCTA" );
+ createSMESHAction( SMESHOp::OpPolyhedron, "POLYHEDRON", "ICON_DLG_POLYHEDRON" );
+ createSMESHAction( SMESHOp::OpQuadraticEdge, "QUADRATIC_EDGE", "ICON_DLG_QUADRATIC_EDGE" );
+ createSMESHAction( SMESHOp::OpQuadraticTriangle, "QUADRATIC_TRIANGLE", "ICON_DLG_QUADRATIC_TRIANGLE" );
+ createSMESHAction( SMESHOp::OpBiQuadraticTriangle, "BIQUADRATIC_TRIANGLE", "ICON_DLG_BIQUADRATIC_TRIANGLE" );
+ createSMESHAction( SMESHOp::OpQuadraticQuadrangle, "QUADRATIC_QUADRANGLE", "ICON_DLG_QUADRATIC_QUADRANGLE" );
+ createSMESHAction( SMESHOp::OpBiQuadraticQuadrangle, "BIQUADRATIC_QUADRANGLE", "ICON_DLG_BIQUADRATIC_QUADRANGLE" );
+ createSMESHAction( SMESHOp::OpQuadraticTetrahedron, "QUADRATIC_TETRAHEDRON", "ICON_DLG_QUADRATIC_TETRAHEDRON" );
+ createSMESHAction( SMESHOp::OpQuadraticPyramid, "QUADRATIC_PYRAMID", "ICON_DLG_QUADRATIC_PYRAMID" );
+ createSMESHAction( SMESHOp::OpQuadraticPentahedron, "QUADRATIC_PENTAHEDRON", "ICON_DLG_QUADRATIC_PENTAHEDRON" );
+ createSMESHAction( SMESHOp::OpQuadraticHexahedron, "QUADRATIC_HEXAHEDRON", "ICON_DLG_QUADRATIC_HEXAHEDRON" );
+ createSMESHAction( SMESHOp::OpTriQuadraticHexahedron, "TRIQUADRATIC_HEXAHEDRON", "ICON_DLG_TRIQUADRATIC_HEXAHEDRON" );
+
+ createSMESHAction( SMESHOp::OpRemoveNodes, "REMOVE_NODES", "ICON_DLG_REM_NODE" );
+ createSMESHAction( SMESHOp::OpRemoveElements, "REMOVE_ELEMENTS", "ICON_DLG_REM_ELEMENT" );
+ createSMESHAction( SMESHOp::OpRemoveOrphanNodes, "REMOVE_ORPHAN_NODES", "ICON_DLG_REM_ORPHAN_NODES" );
+ createSMESHAction( SMESHOp::OpClearMesh, "CLEAR_MESH", "ICON_CLEAR_MESH" );
+
+ createSMESHAction( SMESHOp::OpRenumberingNodes, "RENUM_NODES", "ICON_DLG_RENUMBERING_NODES" );
+ createSMESHAction( SMESHOp::OpRenumberingElements, "RENUM_ELEMENTS", "ICON_DLG_RENUMBERING_ELEMENTS" );
+
+ createSMESHAction( SMESHOp::OpTranslation, "TRANS", "ICON_SMESH_TRANSLATION_VECTOR" );
+ createSMESHAction( SMESHOp::OpRotation, "ROT", "ICON_DLG_MESH_ROTATION" );
+ createSMESHAction( SMESHOp::OpSymmetry, "SYM", "ICON_SMESH_SYMMETRY_PLANE" );
+ createSMESHAction( SMESHOp::OpScale, "SCALE", "ICON_DLG_MESH_SCALE" );
+ createSMESHAction( SMESHOp::OpSewing, "SEW", "ICON_SMESH_SEWING_FREEBORDERS" );
+ createSMESHAction( SMESHOp::OpMergeNodes, "MERGE", "ICON_SMESH_MERGE_NODES" );
+ createSMESHAction( SMESHOp::OpMergeElements, "MERGE_ELEMENTS", "ICON_DLG_MERGE_ELEMENTS" );
+ createSMESHAction( SMESHOp::OpMoveNode, "MESH_THROU_POINT","ICON_DLG_MOVE_NODE" );
+ createSMESHAction( SMESHOp::OpDuplicateNodes, "DUPLICATE_NODES", "ICON_SMESH_DUPLICATE_NODES" );
+ createSMESHAction( SMESHOp::OpDiagonalInversion, "INV", "ICON_DLG_MESH_DIAGONAL" );
+ createSMESHAction( SMESHOp::OpUnionOfTwoTriangle, "UNION2", "ICON_UNION2TRI" );
+ createSMESHAction( SMESHOp::OpOrientation, "ORIENT", "ICON_DLG_MESH_ORIENTATION" );
+ createSMESHAction( SMESHOp::OpReorientFaces, "REORIENT_2D", "ICON_REORIENT_2D" );
+ createSMESHAction( SMESHOp::OpUnionOfTriangles, "UNION", "ICON_UNIONTRI" );
+ createSMESHAction( SMESHOp::OpCuttingOfQuadrangles, "CUT", "ICON_CUTQUAD" );
+ createSMESHAction( SMESHOp::OpSplitVolumes, "SPLIT_TO_TETRA", "ICON_SPLIT_TO_TETRA" );
+ createSMESHAction( SMESHOp::OpSmoothing, "SMOOTH", "ICON_DLG_SMOOTHING" );
+ createSMESHAction( SMESHOp::OpExtrusion, "EXTRUSION", "ICON_EXTRUSION" );
+ createSMESHAction( SMESHOp::OpExtrusionAlongAPath, "EXTRUSION_ALONG", "ICON_EXTRUSION_ALONG" );
+ createSMESHAction( SMESHOp::OpRevolution, "REVOLUTION", "ICON_REVOLUTION" );
+ createSMESHAction( SMESHOp::OpPatternMapping, "MAP", "ICON_MAP" );
+ createSMESHAction( SMESHOp::OpConvertMeshToQuadratic, "CONV_TO_QUAD", "ICON_CONV_TO_QUAD" );
+ createSMESHAction( SMESHOp::OpCreateBoundaryElements, "2D_FROM_3D", "ICON_2D_FROM_3D" );
+
+ createSMESHAction( SMESHOp::OpReset, "RESET" );
+ createSMESHAction( SMESHOp::OpScalarBarProperties, "SCALAR_BAR_PROP" );
+ createSMESHAction( SMESHOp::OpSaveDistribution, "SAVE_DISTRIBUTION" );
+ createSMESHAction( SMESHOp::OpShowDistribution, "SHOW_DISTRIBUTION","",0, true );
#ifndef DISABLE_PLOT2DVIEWER
- createSMESHAction( 2023, "PLOT_DISTRIBUTION" );
+ createSMESHAction( SMESHOp::OpPlotDistribution, "PLOT_DISTRIBUTION" );
#endif
- createSMESHAction( 211, "WIRE", "ICON_WIRE", 0, true );
- createSMESHAction( 212, "SHADE", "ICON_SHADE", 0, true );
- createSMESHAction( 213, "SHRINK", "ICON_SHRINK", 0, true );
- createSMESHAction( 214, "UPDATE", "ICON_UPDATE" );
- createSMESHAction( 215, "NODES", "ICON_POINTS", 0, true );
- createSMESHAction( 222, "BALLS", "ICON_DLG_BALL", 0, true );
- createSMESHAction( 216, "ELEMS0D", "ICON_DLG_ELEM0D", 0, true );
- createSMESHAction( 217, "EDGES", "ICON_DLG_EDGE", 0, true );
- createSMESHAction( 218, "FACES", "ICON_DLG_TRIANGLE", 0, true );
- createSMESHAction( 219, "VOLUMES", "ICON_DLG_TETRAS", 0, true );
- createSMESHAction( 220, "ALL" );
- createSMESHAction( 221, "FACE_ORIENTATION", "", 0, true );
-
- createSMESHAction( 231, "LINE_REPRESENTATION", "", 0, true );
- createSMESHAction( 232, "ARC_REPRESENTATION", "", 0, true );
-
- createSMESHAction( 1100, "EDIT_HYPO" );
- createSMESHAction( 1102, "UNASSIGN" );
- createSMESHAction( 9010, "NUM_NODES", "", 0, true );
- createSMESHAction( 9011, "NUM_ELEMENTS", "", 0, true );
- createSMESHAction( 1131, "DISPMODE" );
- createSMESHAction( 1132, "COLORS" );
- createSMESHAction( 1133, "TRANSP" );
- createSMESHAction( 1134, "CLIP" );
- createSMESHAction( 1135, "DISP_ENT" );
- createSMESHAction( 1136, "AUTO_COLOR" );
- createSMESHAction( 1137, "DISABLE_AUTO_COLOR" );
- createSMESHAction( 2000, "CTRL" );
-
- createSMESHAction( 501, "MEASURE_MIN_DIST", "ICON_MEASURE_MIN_DIST" );
- createSMESHAction( 502, "MEASURE_BND_BOX", "ICON_MEASURE_BND_BOX" );
- createSMESHAction( 503, "MEASURE_LENGTH", "ICON_MEASURE_LENGTH" );
- createSMESHAction( 504, "MEASURE_AREA", "ICON_MEASURE_AREA" );
- createSMESHAction( 505, "MEASURE_VOLUME", "ICON_MEASURE_VOLUME" );
-
- createSMESHAction( 300, "HIDE" );
- createSMESHAction( 301, "SHOW" );
- createSMESHAction( 302, "DISPLAY_ONLY" );
-
- createSMESHAction( 41, "SORT_CHILD_ITEMS" );
+ createSMESHAction( SMESHOp::OpDMWireframe, "WIRE", "ICON_WIRE", 0, true );
+ createSMESHAction( SMESHOp::OpDMShading, "SHADE", "ICON_SHADE", 0, true );
+ createSMESHAction( SMESHOp::OpDMNodes, "NODES", "ICON_POINTS", 0, true );
+ createSMESHAction( SMESHOp::OpDMShrink, "SHRINK", "ICON_SHRINK", 0, true );
+ createSMESHAction( SMESHOp::OpUpdate, "UPDATE", "ICON_UPDATE" );
+ createSMESHAction( SMESHOp::OpDE0DElements, "ELEMS0D", "ICON_DLG_ELEM0D", 0, true );
+ createSMESHAction( SMESHOp::OpDEEdges, "EDGES", "ICON_DLG_EDGE", 0, true );
+ createSMESHAction( SMESHOp::OpDEFaces, "FACES", "ICON_DLG_TRIANGLE", 0, true );
+ createSMESHAction( SMESHOp::OpDEVolumes, "VOLUMES", "ICON_DLG_TETRAS", 0, true );
+ createSMESHAction( SMESHOp::OpDEBalls, "BALLS", "ICON_DLG_BALL", 0, true );
+ createSMESHAction( SMESHOp::OpDEAllEntity, "ALL" );
+ createSMESHAction( SMESHOp::OpOrientationOnFaces, "FACE_ORIENTATION", "", 0, true );
+
+ createSMESHAction( SMESHOp::OpRepresentationLines, "LINE_REPRESENTATION", "", 0, true );
+ createSMESHAction( SMESHOp::OpRepresentationArcs, "ARC_REPRESENTATION", "", 0, true );
+
+ createSMESHAction( SMESHOp::OpEditHypothesis, "EDIT_HYPO" );
+ createSMESHAction( SMESHOp::OpUnassign, "UNASSIGN" );
+ createSMESHAction( SMESHOp::OpNumberingNodes, "NUM_NODES", "", 0, true );
+ createSMESHAction( SMESHOp::OpNumberingElements, "NUM_ELEMENTS", "", 0, true );
+ createSMESHAction( SMESHOp::OpProperties, "COLORS" );
+ createSMESHAction( SMESHOp::OpTransparency, "TRANSP" );
+ createSMESHAction( SMESHOp::OpClipping, "CLIP" );
+ createSMESHAction( SMESHOp::OpAutoColor, "AUTO_COLOR" );
+ createSMESHAction( SMESHOp::OpDisableAutoColor, "DISABLE_AUTO_COLOR" );
+
+ createSMESHAction( SMESHOp::OpMinimumDistance, "MEASURE_MIN_DIST", "ICON_MEASURE_MIN_DIST" );
+ createSMESHAction( SMESHOp::OpBoundingBox, "MEASURE_BND_BOX", "ICON_MEASURE_BND_BOX" );
+ createSMESHAction( SMESHOp::OpPropertiesLength, "MEASURE_LENGTH", "ICON_MEASURE_LENGTH" );
+ createSMESHAction( SMESHOp::OpPropertiesArea, "MEASURE_AREA", "ICON_MEASURE_AREA" );
+ createSMESHAction( SMESHOp::OpPropertiesVolume, "MEASURE_VOLUME", "ICON_MEASURE_VOLUME" );
+
+ createSMESHAction( SMESHOp::OpHide, "HIDE" );
+ createSMESHAction( SMESHOp::OpShow, "SHOW" );
+ createSMESHAction( SMESHOp::OpShowOnly, "DISPLAY_ONLY" );
+
+ createSMESHAction( SMESHOp::OpSortChild, "SORT_CHILD_ITEMS" );
// ----- create menu --------------
int fileId = createMenu( tr( "MEN_FILE" ), -1, 1 ),
transfId = createMenu( tr( "MEN_TRANSF" ), modifyId, 405 ),
basicPropId = createMenu( tr( "MEN_BASIC_PROPERTIES" ), measureId, -1, 10 );
- //createMenu( 111, importId, -1 );
- createMenu( 112, importId, -1 );
- createMenu( 113, importId, -1 );
- createMenu( 115, importId, -1 );
+ //createMenu( SMESHOp::OpImportDAT, importId, -1 );
+ createMenu( SMESHOp::OpImportUNV, importId, -1 );
+ createMenu( SMESHOp::OpImportMED, importId, -1 );
+ createMenu( SMESHOp::OpImportSTL, importId, -1 );
#ifdef WITH_CGNS
- createMenu( 116, importId, -1 );
+ createMenu( SMESHOp::OpImportCGNS, importId, -1 );
#endif
- createMenu( 117, importId, -1 );
- createMenu( 118, importId, -1 );
- createMenu( 121, exportId, -1 );
- createMenu( 122, exportId, -1 );
- createMenu( 123, exportId, -1 );
- createMenu( 140, exportId, -1 ); // export to STL
+ createMenu( SMESHOp::OpImportSAUV, importId, -1 );
+ createMenu( SMESHOp::OpImportGMF, importId, -1 );
+ createMenu( SMESHOp::OpExportDAT, exportId, -1 );
+ createMenu( SMESHOp::OpExportMED, exportId, -1 );
+ createMenu( SMESHOp::OpExportUNV, exportId, -1 );
+ createMenu( SMESHOp::OpExportSTL, exportId, -1 );
#ifdef WITH_CGNS
- createMenu( 142, exportId, -1 ); // export to CGNS
+ createMenu( SMESHOp::OpExportCGNS, exportId, -1 );
#endif
- createMenu( 144, exportId, -1 ); // export to SAUV
- createMenu( 146, exportId, -1 ); // export to GMF
+ createMenu( SMESHOp::OpExportSAUV, exportId, -1 );
+ createMenu( SMESHOp::OpExportGMF, exportId, -1 );
createMenu( separator(), fileId, 10 );
- createMenu( 33, editId, -1 );
-
- createMenu( 5105, toolsId, -1 );
-
- createMenu( 702, meshId, -1 ); // "Mesh" menu
- createMenu( 703, meshId, -1 );
- createMenu( 704, meshId, -1 );
- createMenu( 710, meshId, -1 );
- createMenu( 705, meshId, -1 );
- createMenu( separator(), meshId, -1 );
- createMenu( 701, meshId, -1 );
- createMenu( 711, meshId, -1 );
- createMenu( 712, meshId, -1 );
- createMenu( 713, meshId, -1 );
- createMenu( separator(), meshId, -1 );
- createMenu( 801, meshId, -1 );
- createMenu( 806, meshId, -1 );
- createMenu( 802, meshId, -1 );
- createMenu( 803, meshId, -1 );
- createMenu( 815, meshId, -1 );
- createMenu( separator(), meshId, -1 );
- createMenu( 810, meshId, -1 );
- createMenu( 811, meshId, -1 );
- createMenu( 812, meshId, -1 );
- createMenu( separator(), meshId, -1 );
- createMenu( 814, meshId, -1 );
- createMenu( separator(), meshId, -1 );
- createMenu( 900, meshId, -1 );
- //createMenu( 902, meshId, -1 );
- //createMenu( 903, meshId, -1 ); // VSR: issue #0021242 (eliminate "Mesh Element Information" command)
- createMenu( 904, meshId, -1 );
- createMenu( separator(), meshId, -1 );
-
- createMenu( 6005, nodeId, -1 );
- createMenu( 6028, nodeId, -1 );
- createMenu( 6002, edgeId, -1 );
- createMenu( 6003, edgeId, -1 );
- createMenu( 6001, edgeId, -1 );
- createMenu( 6004, edgeId, -1 );
- createMenu( 6029, edgeId, -1 );
- createMenu( 6021, faceId, -1 );
- createMenu( 6025, faceId, -1 );
- createMenu( 6027, faceId, -1 );
- createMenu( 6018, faceId, -1 );
- createMenu( 6019, faceId, -1 );
- createMenu( 6011, faceId, -1 );
- createMenu( 6012, faceId, -1 );
- createMenu( 6013, faceId, -1 );
- createMenu( 6014, faceId, -1 );
- createMenu( 6015, faceId, -1 );
- createMenu( 6016, faceId, -1 );
- createMenu( 6022, faceId, -1 );
- createMenu( 6030, faceId, -1 );
- createMenu( 6017, volumeId, -1 );
- createMenu( 6009, volumeId, -1 );
- createMenu( 6023, volumeId, -1 );
- createMenu( 6024, volumeId, -1 );
- createMenu( 6026, volumeId, -1 );
- createMenu( 6031, volumeId, -1 );
- createMenu( separator(), ctrlId, -1 );
- createMenu( 6032, ctrlId, -1 );
-
- createMenu( 4000, addId, -1 );
- createMenu( 4009, addId, -1 );
- createMenu( 4070, addId, -1 );
- createMenu( 4008, addId, -1 );
- createMenu( 4010, addId, -1 );
- createMenu( 4021, addId, -1 );
- createMenu( 4022, addId, -1 );
- createMenu( 4023, addId, -1 );
- createMenu( 4031, addId, -1 );
- createMenu( 4032, addId, -1 );
- createMenu( 4133, addId, -1 );
- createMenu( 4134, addId, -1 );
- createMenu( 4135, addId, -1 );
- createMenu( 4033, addId, -1 );
- createMenu( separator(), addId, -1 );
- createMenu( 4034, addId, -1 );
- createMenu( 4035, addId, -1 );
- createMenu( 4137, addId, -1 );
- createMenu( 4036, addId, -1 );
- createMenu( 4136, addId, -1 );
- createMenu( 4037, addId, -1 );
- createMenu( 4038, addId, -1 );
- createMenu( 4039, addId, -1 );
- createMenu( 4040, addId, -1 );
- createMenu( 4140, addId, -1 );
-
- createMenu( 4041, removeId, -1 );
- createMenu( 4042, removeId, -1 );
- createMenu( 4044, removeId, -1 );
- createMenu( separator(), removeId, -1 );
- createMenu( 813, removeId, -1 );
- createMenu( separator(), removeId, -1 );
- createMenu( 4043, removeId, -1 );
-
- createMenu( 4051, renumId, -1 );
- createMenu( 4052, renumId, -1 );
-
- createMenu( 4061, transfId, -1 );
- createMenu( 4062, transfId, -1 );
- createMenu( 4063, transfId, -1 );
- createMenu( 4068, transfId, -1 );
- createMenu( 4064, transfId, -1 );
- createMenu( 4065, transfId, -1 );
- createMenu( 4066, transfId, -1 );
- createMenu( 4069, transfId, -1 );
-
- createMenu( 4067,modifyId, -1 );
- createMenu( 407, modifyId, -1 );
- createMenu( 408, modifyId, -1 );
- createMenu( 409, modifyId, -1 );
- createMenu( 420, modifyId, -1 );
- createMenu( 410, modifyId, -1 );
- createMenu( 411, modifyId, -1 );
- createMenu( 419, modifyId, -1 );
- createMenu( 412, modifyId, -1 );
- createMenu( 413, modifyId, -1 );
- createMenu( 416, modifyId, -1 );
- createMenu( 414, modifyId, -1 );
- createMenu( 415, modifyId, -1 );
- createMenu( 417, modifyId, -1 );
- createMenu( 418, modifyId, -1 );
-
- createMenu( 501, measureId, -1 );
- createMenu( 502, measureId, -1 );
- createMenu( 503, basicPropId, -1 );
- createMenu( 504, basicPropId, -1 );
- createMenu( 505, basicPropId, -1 );
- createMenu( 214, viewId, -1 );
+ createMenu( SMESHOp::OpDelete, editId, -1 );
+
+ createMenu( SMESHOp::OpSelectFiltersLibrary, toolsId, -1 );
+
+ createMenu( SMESHOp::OpCreateMesh, meshId, -1 ); // "Mesh" menu
+ createMenu( SMESHOp::OpCreateSubMesh, meshId, -1 );
+ createMenu( SMESHOp::OpEditMeshOrSubMesh, meshId, -1 );
+ createMenu( SMESHOp::OpBuildCompoundMesh, meshId, -1 );
+ createMenu( SMESHOp::OpCopyMesh, meshId, -1 );
+ createMenu( separator(), meshId, -1 );
+ createMenu( SMESHOp::OpCompute, meshId, -1 );
+ createMenu( SMESHOp::OpPreCompute, meshId, -1 );
+ createMenu( SMESHOp::OpEvaluate, meshId, -1 );
+ createMenu( SMESHOp::OpMeshOrder, meshId, -1 );
+ createMenu( separator(), meshId, -1 );
+ createMenu( SMESHOp::OpCreateGroup, meshId, -1 );
+ createMenu( SMESHOp::OpCreateGeometryGroup, meshId, -1 );
+ createMenu( SMESHOp::OpConstructGroup, meshId, -1 );
+ createMenu( SMESHOp::OpEditGroup, meshId, -1 );
+ createMenu( SMESHOp::OpEditGeomGroupAsGroup, meshId, -1 );
+ createMenu( separator(), meshId, -1 );
+ createMenu( SMESHOp::OpUnionGroups, meshId, -1 );
+ createMenu( SMESHOp::OpIntersectGroups, meshId, -1 );
+ createMenu( SMESHOp::OpCutGroups, meshId, -1 );
+ createMenu( separator(), meshId, -1 );
+ createMenu( SMESHOp::OpGroupUnderlyingElem, meshId, -1 );
+ createMenu( separator(), meshId, -1 );
+ createMenu( SMESHOp::OpMeshInformation, meshId, -1 );
+ //createMenu( SMESHOp::OpStdInfo, meshId, -1 );
+ //createMenu( SMESHOp::OpWhatIs, meshId, -1 ); // VSR: issue #0021242 (eliminate "Mesh Element Information" command)
+ createMenu( SMESHOp::OpFindElementByPoint, meshId, -1 );
+ createMenu( separator(), meshId, -1 );
+
+ createMenu( SMESHOp::OpFreeNode, nodeId, -1 );
+ createMenu( SMESHOp::OpEqualNode, nodeId, -1 );
+ createMenu( SMESHOp::OpFreeEdge, edgeId, -1 );
+ createMenu( SMESHOp::OpFreeBorder, edgeId, -1 );
+ createMenu( SMESHOp::OpLength, edgeId, -1 );
+ createMenu( SMESHOp::OpConnection, edgeId, -1 );
+ createMenu( SMESHOp::OpEqualEdge, edgeId, -1 );
+ createMenu( SMESHOp::OpFreeFace, faceId, -1 );
+ createMenu( SMESHOp::OpBareBorderFace, faceId, -1 );
+ createMenu( SMESHOp::OpOverConstrainedFace, faceId, -1 );
+ createMenu( SMESHOp::OpLength2D, faceId, -1 );
+ createMenu( SMESHOp::OpConnection2D, faceId, -1 );
+ createMenu( SMESHOp::OpArea, faceId, -1 );
+ createMenu( SMESHOp::OpTaper, faceId, -1 );
+ createMenu( SMESHOp::OpAspectRatio, faceId, -1 );
+ createMenu( SMESHOp::OpMinimumAngle, faceId, -1 );
+ createMenu( SMESHOp::OpWarpingAngle, faceId, -1 );
+ createMenu( SMESHOp::OpSkew, faceId, -1 );
+ createMenu( SMESHOp::OpMaxElementLength2D, faceId, -1 );
+ createMenu( SMESHOp::OpEqualFace, faceId, -1 );
+ createMenu( SMESHOp::OpAspectRatio3D, volumeId, -1 );
+ createMenu( SMESHOp::OpVolume, volumeId, -1 );
+ createMenu( SMESHOp::OpMaxElementLength3D, volumeId, -1 );
+ createMenu( SMESHOp::OpBareBorderVolume, volumeId, -1 );
+ createMenu( SMESHOp::OpOverConstrainedVolume, volumeId, -1 );
+ createMenu( SMESHOp::OpEqualVolume, volumeId, -1 );
+ createMenu( separator(), ctrlId, -1 );
+ createMenu( SMESHOp::OpOverallMeshQuality, ctrlId, -1 );
+
+ createMenu( SMESHOp::OpNode, addId, -1 );
+ createMenu( SMESHOp::OpElem0D, addId, -1 );
+ createMenu( SMESHOp::OpElem0DOnElemNodes, addId, -1 );
+ createMenu( SMESHOp::OpBall, addId, -1 );
+ createMenu( SMESHOp::OpEdge, addId, -1 );
+ createMenu( SMESHOp::OpTriangle, addId, -1 );
+ createMenu( SMESHOp::OpQuadrangle, addId, -1 );
+ createMenu( SMESHOp::OpPolygon, addId, -1 );
+ createMenu( SMESHOp::OpTetrahedron, addId, -1 );
+ createMenu( SMESHOp::OpHexahedron, addId, -1 );
+ createMenu( SMESHOp::OpPentahedron, addId, -1 );
+ createMenu( SMESHOp::OpPyramid, addId, -1 );
+ createMenu( SMESHOp::OpHexagonalPrism, addId, -1 );
+ createMenu( SMESHOp::OpPolyhedron, addId, -1 );
+ createMenu( separator(), addId, -1 );
+ createMenu( SMESHOp::OpQuadraticEdge, addId, -1 );
+ createMenu( SMESHOp::OpQuadraticTriangle, addId, -1 );
+ createMenu( SMESHOp::OpBiQuadraticTriangle , addId, -1 );
+ createMenu( SMESHOp::OpQuadraticQuadrangle, addId, -1 );
+ createMenu( SMESHOp::OpBiQuadraticQuadrangle, addId, -1 );
+ createMenu( SMESHOp::OpQuadraticTetrahedron, addId, -1 );
+ createMenu( SMESHOp::OpQuadraticPyramid, addId, -1 );
+ createMenu( SMESHOp::OpQuadraticPentahedron, addId, -1 );
+ createMenu( SMESHOp::OpQuadraticHexahedron, addId, -1 );
+ createMenu( SMESHOp::OpTriQuadraticHexahedron, addId, -1 );
+
+ createMenu( SMESHOp::OpRemoveNodes, removeId, -1 );
+ createMenu( SMESHOp::OpRemoveElements, removeId, -1 );
+ createMenu( SMESHOp::OpRemoveOrphanNodes, removeId, -1 );
+ createMenu( separator(), removeId, -1 );
+ createMenu( SMESHOp::OpDeleteGroup, removeId, -1 );
+ createMenu( separator(), removeId, -1 );
+ createMenu( SMESHOp::OpClearMesh, removeId, -1 );
+
+ createMenu( SMESHOp::OpRenumberingNodes, renumId, -1 );
+ createMenu( SMESHOp::OpRenumberingElements, renumId, -1 );
+
+ createMenu( SMESHOp::OpTranslation, transfId, -1 );
+ createMenu( SMESHOp::OpRotation, transfId, -1 );
+ createMenu( SMESHOp::OpSymmetry, transfId, -1 );
+ createMenu( SMESHOp::OpScale, transfId, -1 );
+ createMenu( SMESHOp::OpSewing, transfId, -1 );
+ createMenu( SMESHOp::OpMergeNodes, transfId, -1 );
+ createMenu( SMESHOp::OpMergeElements, transfId, -1 );
+ createMenu( SMESHOp::OpDuplicateNodes, transfId, -1 );
+
+ createMenu( SMESHOp::OpMoveNode, modifyId, -1 );
+ createMenu( SMESHOp::OpDiagonalInversion, modifyId, -1 );
+ createMenu( SMESHOp::OpUnionOfTwoTriangle, modifyId, -1 );
+ createMenu( SMESHOp::OpOrientation, modifyId, -1 );
+ createMenu( SMESHOp::OpReorientFaces, modifyId, -1 );
+ createMenu( SMESHOp::OpUnionOfTriangles, modifyId, -1 );
+ createMenu( SMESHOp::OpCuttingOfQuadrangles, modifyId, -1 );
+ createMenu( SMESHOp::OpSplitVolumes, modifyId, -1 );
+ createMenu( SMESHOp::OpSmoothing, modifyId, -1 );
+ createMenu( SMESHOp::OpExtrusion, modifyId, -1 );
+ createMenu( SMESHOp::OpExtrusionAlongAPath , modifyId, -1 );
+ createMenu( SMESHOp::OpRevolution, modifyId, -1 );
+ createMenu( SMESHOp::OpPatternMapping, modifyId, -1 );
+ createMenu( SMESHOp::OpConvertMeshToQuadratic, modifyId, -1 );
+ createMenu( SMESHOp::OpCreateBoundaryElements, modifyId, -1 );
+
+ createMenu( SMESHOp::OpMinimumDistance, measureId, -1 );
+ createMenu( SMESHOp::OpBoundingBox, measureId, -1 );
+ createMenu( SMESHOp::OpPropertiesLength, basicPropId, -1 );
+ createMenu( SMESHOp::OpPropertiesArea, basicPropId, -1 );
+ createMenu( SMESHOp::OpPropertiesVolume, basicPropId, -1 );
+ createMenu( SMESHOp::OpUpdate, viewId, -1 );
// ----- create toolbars --------------
- int meshTb = createTool( tr( "TB_MESH" ) ),
- info = createTool( tr( "TB_INFO" ) ),
- groupTb = createTool( tr( "TB_GROUP" ) ),
- ctrl0dTb = createTool( tr( "TB_CTRL0D" ) ),
- ctrl1dTb = createTool( tr( "TB_CTRL1D" ) ),
- ctrl2dTb = createTool( tr( "TB_CTRL2D" ) ),
- ctrl3dTb = createTool( tr( "TB_CTRL3D" ) ),
- addElemTb = createTool( tr( "TB_ADD" ) ),
- addNonElemTb = createTool( tr( "TB_ADDNON" ) ),
- remTb = createTool( tr( "TB_REM" ) ),
- renumbTb = createTool( tr( "TB_RENUMBER" ) ),
- transformTb = createTool( tr( "TB_TRANSFORM" ) ),
- modifyTb = createTool( tr( "TB_MODIFY" ) ),
- measuremTb = createTool( tr( "TB_MEASUREM" ) ),
- dispModeTb = createTool( tr( "TB_DISP_MODE" ) );
-
- createTool( 702, meshTb );
- createTool( 703, meshTb );
- createTool( 704, meshTb );
- createTool( 710, meshTb );
- createTool( 705, meshTb );
- createTool( separator(), meshTb );
- createTool( 701, meshTb );
- createTool( 711, meshTb );
- createTool( 712, meshTb );
- createTool( 713, meshTb );
-
- createTool( 801, groupTb );
- createTool( 806, groupTb );
- createTool( 802, groupTb );
- createTool( 803, groupTb );
-
- createTool( 900, info );
- //createTool( 902, meshTb );
- //createTool( 903, meshTb ); // VSR: issue #0021242 (eliminate "Mesh Element Information" command)
- createTool( 904, info );
-
- createTool( 6005, ctrl0dTb );
- createTool( 6028, ctrl0dTb );
-
- createTool( 6002, ctrl1dTb );
- createTool( 6003, ctrl1dTb );
- createTool( 6001, ctrl1dTb );
- createTool( 6004, ctrl1dTb );
- createTool( 6029, ctrl1dTb );
-
- createTool( 6021, ctrl2dTb );
- createTool( 6025, ctrl2dTb );
- createTool( 6027, ctrl2dTb );
- createTool( 6018, ctrl2dTb );
- createTool( 6019, ctrl2dTb );
- createTool( 6011, ctrl2dTb );
- createTool( 6012, ctrl2dTb );
- createTool( 6013, ctrl2dTb );
- createTool( 6014, ctrl2dTb );
- createTool( 6015, ctrl2dTb );
- createTool( 6016, ctrl2dTb );
- createTool( 6022, ctrl2dTb );
- createTool( 6030, ctrl2dTb );
-
- createTool( 6017, ctrl3dTb );
- createTool( 6009, ctrl3dTb );
- createTool( 6023, ctrl3dTb );
- createTool( 6024, ctrl3dTb );
- createTool( 6026, ctrl3dTb );
- createTool( 6031, ctrl3dTb );
-
- createTool( 4000, addElemTb );
- createTool( 4009, addElemTb );
- createTool( 4070, addElemTb );
- createTool( 4008, addElemTb );
- createTool( 4010, addElemTb );
- createTool( 4021, addElemTb );
- createTool( 4022, addElemTb );
- createTool( 4023, addElemTb );
- createTool( 4031, addElemTb );
- createTool( 4032, addElemTb );
- createTool( 4133, addElemTb );
- createTool( 4134, addElemTb );
- createTool( 4135, addElemTb );
- createTool( 4033, addElemTb );
-
- createTool( 4034, addNonElemTb );
- createTool( 4035, addNonElemTb );
- createTool( 4137, addNonElemTb );
- createTool( 4036, addNonElemTb );
- createTool( 4136, addNonElemTb );
- createTool( 4037, addNonElemTb );
- createTool( 4038, addNonElemTb );
- createTool( 4039, addNonElemTb );
- createTool( 4040, addNonElemTb );
- createTool( 4140, addNonElemTb );
-
- createTool( 4041, remTb );
- createTool( 4042, remTb );
- createTool( 4044, remTb );
- createTool( 4043, remTb );
-
- createTool( 4051, renumbTb );
- createTool( 4052, renumbTb );
-
-
- createTool( 4061, transformTb );
- createTool( 4062, transformTb );
- createTool( 4063, transformTb );
- createTool( 4068, transformTb );
- createTool( 4064, transformTb );
- createTool( 4065, transformTb );
- createTool( 4066, transformTb );
- createTool( 4069, transformTb );
-
- createTool( 4067,modifyTb );
- createTool( 407, modifyTb );
- createTool( 408, modifyTb );
- createTool( 409, modifyTb );
- createTool( 420, modifyTb );
- createTool( 410, modifyTb );
- createTool( 411, modifyTb );
- createTool( 419, modifyTb );
- createTool( 412, modifyTb );
- createTool( 413, modifyTb );
- createTool( 416, modifyTb );
- createTool( 414, modifyTb );
- createTool( 415, modifyTb );
- createTool( 417, modifyTb );
- createTool( 418, modifyTb );
-
- createTool( 501, measuremTb );
-
- createTool( 214, dispModeTb );
+ int meshTb = createTool( tr( "TB_MESH" ), QString( "SMESHMeshToolbar" ) ),
+ info = createTool( tr( "TB_INFO" ), QString( "SMESHInformationToolbar" ) ),
+ groupTb = createTool( tr( "TB_GROUP" ), QString( "SMESHGroupToolbar" ) ),
+ ctrl0dTb = createTool( tr( "TB_CTRL0D" ), QString( "SMESHNodeControlsToolbar" ) ),
+ ctrl1dTb = createTool( tr( "TB_CTRL1D" ), QString( "SMESHEdgeControlsToolbar" ) ),
+ ctrl2dTb = createTool( tr( "TB_CTRL2D" ), QString( "SMESHFaceControlsToolbar" ) ),
+ ctrl3dTb = createTool( tr( "TB_CTRL3D" ), QString( "SMESHVolumeControlsToolbar" ) ),
+ addElemTb = createTool( tr( "TB_ADD" ), QString( "SMESHAddElementToolbar" ) ),
+ addNonElemTb = createTool( tr( "TB_ADDNON" ), QString( "SMESHAddElementToolbar" ) ),
+ remTb = createTool( tr( "TB_REM" ), QString( "SMESHRemoveToolbar" ) ),
+ renumbTb = createTool( tr( "TB_RENUMBER" ), QString( "SMESHRenumberingToolbar" ) ),
+ transformTb = createTool( tr( "TB_TRANSFORM" ), QString( "SMESHTransformationToolbar" ) ),
+ modifyTb = createTool( tr( "TB_MODIFY" ), QString( "SMESHModificationToolbar" ) ),
+ measuremTb = createTool( tr( "TB_MEASUREM" ), QString( "SMESHMeasurementsToolbar" ) ),
+ dispModeTb = createTool( tr( "TB_DISP_MODE" ), QString( "SMESHDisplayModeToolbar" ) );
+
+ createTool( SMESHOp::OpCreateMesh, meshTb );
+ createTool( SMESHOp::OpCreateSubMesh, meshTb );
+ createTool( SMESHOp::OpEditMeshOrSubMesh, meshTb );
+ createTool( SMESHOp::OpBuildCompoundMesh, meshTb );
+ createTool( SMESHOp::OpCopyMesh, meshTb );
+ createTool( separator(), meshTb );
+ createTool( SMESHOp::OpCompute, meshTb );
+ createTool( SMESHOp::OpPreCompute, meshTb );
+ createTool( SMESHOp::OpEvaluate, meshTb );
+ createTool( SMESHOp::OpMeshOrder, meshTb );
+
+ createTool( SMESHOp::OpCreateGroup, groupTb );
+ createTool( SMESHOp::OpCreateGeometryGroup, groupTb );
+ createTool( SMESHOp::OpConstructGroup, groupTb );
+ createTool( SMESHOp::OpEditGroup, groupTb );
+
+ createTool( SMESHOp::OpMeshInformation, info );
+ //createTool( SMESHOp::OpStdInfo, meshTb );
+ //createTool( SMESHOp::OpWhatIs, meshTb ); // VSR: issue #0021242 (eliminate "Mesh Element Information" command)
+ createTool( SMESHOp::OpFindElementByPoint, info );
+
+ createTool( SMESHOp::OpFreeNode, ctrl0dTb );
+ createTool( SMESHOp::OpEqualNode, ctrl0dTb );
+
+ createTool( SMESHOp::OpFreeEdge, ctrl1dTb );
+ createTool( SMESHOp::OpFreeBorder, ctrl1dTb );
+ createTool( SMESHOp::OpLength, ctrl1dTb );
+ createTool( SMESHOp::OpConnection, ctrl1dTb );
+ createTool( SMESHOp::OpEqualEdge, ctrl1dTb );
+
+ createTool( SMESHOp::OpFreeFace, ctrl2dTb );
+ createTool( SMESHOp::OpBareBorderFace, ctrl2dTb );
+ createTool( SMESHOp::OpOverConstrainedFace, ctrl2dTb );
+ createTool( SMESHOp::OpLength2D, ctrl2dTb );
+ createTool( SMESHOp::OpConnection2D, ctrl2dTb );
+ createTool( SMESHOp::OpArea, ctrl2dTb );
+ createTool( SMESHOp::OpTaper, ctrl2dTb );
+ createTool( SMESHOp::OpAspectRatio, ctrl2dTb );
+ createTool( SMESHOp::OpMinimumAngle, ctrl2dTb );
+ createTool( SMESHOp::OpWarpingAngle, ctrl2dTb );
+ createTool( SMESHOp::OpSkew, ctrl2dTb );
+ createTool( SMESHOp::OpMaxElementLength2D, ctrl2dTb );
+ createTool( SMESHOp::OpEqualFace, ctrl2dTb );
+
+ createTool( SMESHOp::OpAspectRatio3D, ctrl3dTb );
+ createTool( SMESHOp::OpVolume, ctrl3dTb );
+ createTool( SMESHOp::OpMaxElementLength3D, ctrl3dTb );
+ createTool( SMESHOp::OpBareBorderVolume, ctrl3dTb );
+ createTool( SMESHOp::OpOverConstrainedVolume, ctrl3dTb );
+ createTool( SMESHOp::OpEqualVolume, ctrl3dTb );
+
+ createTool( SMESHOp::OpNode, addElemTb );
+ createTool( SMESHOp::OpElem0D, addElemTb );
+ createTool( SMESHOp::OpElem0DOnElemNodes, addElemTb );
+ createTool( SMESHOp::OpBall, addElemTb );
+ createTool( SMESHOp::OpEdge, addElemTb );
+ createTool( SMESHOp::OpTriangle, addElemTb );
+ createTool( SMESHOp::OpQuadrangle, addElemTb );
+ createTool( SMESHOp::OpPolygon, addElemTb );
+ createTool( SMESHOp::OpTetrahedron, addElemTb );
+ createTool( SMESHOp::OpHexahedron, addElemTb );
+ createTool( SMESHOp::OpPentahedron, addElemTb );
+ createTool( SMESHOp::OpPyramid, addElemTb );
+ createTool( SMESHOp::OpHexagonalPrism, addElemTb );
+ createTool( SMESHOp::OpPolyhedron, addElemTb );
+
+ createTool( SMESHOp::OpQuadraticEdge, addNonElemTb );
+ createTool( SMESHOp::OpQuadraticTriangle, addNonElemTb );
+ createTool( SMESHOp::OpBiQuadraticTriangle, addNonElemTb );
+ createTool( SMESHOp::OpQuadraticQuadrangle, addNonElemTb );
+ createTool( SMESHOp::OpBiQuadraticQuadrangle, addNonElemTb );
+ createTool( SMESHOp::OpQuadraticTetrahedron, addNonElemTb );
+ createTool( SMESHOp::OpQuadraticPyramid, addNonElemTb );
+ createTool( SMESHOp::OpQuadraticPentahedron, addNonElemTb );
+ createTool( SMESHOp::OpQuadraticHexahedron, addNonElemTb );
+ createTool( SMESHOp::OpTriQuadraticHexahedron, addNonElemTb );
+
+ createTool( SMESHOp::OpRemoveNodes, remTb );
+ createTool( SMESHOp::OpRemoveElements, remTb );
+ createTool( SMESHOp::OpRemoveOrphanNodes, remTb );
+ createTool( SMESHOp::OpClearMesh, remTb );
+
+ createTool( SMESHOp::OpRenumberingNodes, renumbTb );
+ createTool( SMESHOp::OpRenumberingElements, renumbTb );
+
+ createTool( SMESHOp::OpTranslation, transformTb );
+ createTool( SMESHOp::OpRotation, transformTb );
+ createTool( SMESHOp::OpSymmetry, transformTb );
+ createTool( SMESHOp::OpScale, transformTb );
+ createTool( SMESHOp::OpSewing, transformTb );
+ createTool( SMESHOp::OpMergeNodes, transformTb );
+ createTool( SMESHOp::OpMergeElements, transformTb );
+ createTool( SMESHOp::OpDuplicateNodes, transformTb );
+
+ createTool( SMESHOp::OpMoveNode, modifyTb );
+ createTool( SMESHOp::OpDiagonalInversion, modifyTb );
+ createTool( SMESHOp::OpUnionOfTwoTriangle, modifyTb );
+ createTool( SMESHOp::OpOrientation, modifyTb );
+ createTool( SMESHOp::OpReorientFaces, modifyTb );
+ createTool( SMESHOp::OpUnionOfTriangles, modifyTb );
+ createTool( SMESHOp::OpCuttingOfQuadrangles, modifyTb );
+ createTool( SMESHOp::OpSplitVolumes, modifyTb );
+ createTool( SMESHOp::OpSmoothing, modifyTb );
+ createTool( SMESHOp::OpExtrusion, modifyTb );
+ createTool( SMESHOp::OpExtrusionAlongAPath, modifyTb );
+ createTool( SMESHOp::OpRevolution, modifyTb );
+ createTool( SMESHOp::OpPatternMapping, modifyTb );
+ createTool( SMESHOp::OpConvertMeshToQuadratic, modifyTb );
+ createTool( SMESHOp::OpCreateBoundaryElements, modifyTb );
+
+ createTool( SMESHOp::OpMinimumDistance, measuremTb );
+
+ createTool( SMESHOp::OpUpdate, dispModeTb );
QString lc = "$"; // VSR : instead of QtxPopupSelection::defEquality();
QString dc = "selcount"; // VSR : instead of QtxPopupSelection::defSelCountParam()
hasFaces("({'Face'} in elemTypes)"),
hasVolumes("({'Volume'} in elemTypes)");
- createPopupItem( 150, OB, mesh, "&& selcount=1 && isImported" ); // FILE INFORMATION
- createPopupItem( 703, OB, mesh, "&& isComputable"); // CREATE_SUBMESH
- createPopupItem( 704, OB, mesh, "&& isComputable"); // EDIT_MESHSUBMESH
- createPopupItem( 704, OB, subMesh, "&& isComputable" ); // EDIT_MESHSUBMESH
- createPopupItem( 803, OB, group ); // EDIT_GROUP
- createPopupItem( 815, OB, group, "&& groupType != 'Group'" ); // EDIT AS STANDALONE
+ createPopupItem( SMESHOp::OpFileInformation, OB, mesh, "&& selcount=1 && isImported" );
+ createPopupItem( SMESHOp::OpCreateSubMesh, OB, mesh, "&& isComputable");
+ createPopupItem( SMESHOp::OpEditMeshOrSubMesh, OB, mesh, "&& isComputable");
+ createPopupItem( SMESHOp::OpEditMeshOrSubMesh, OB, subMesh, "&& isComputable" );
+ createPopupItem( SMESHOp::OpEditGroup, OB, group );
+ createPopupItem( SMESHOp::OpEditGeomGroupAsGroup, OB, group, "&& groupType != 'Group'" );
popupMgr()->insert( separator(), -1, 0 );
- createPopupItem( 701, OB, mesh, "&& isComputable" ); // COMPUTE
- createPopupItem( 711, OB, mesh, "&& isComputable && isPreComputable" ); // PRECOMPUTE
- createPopupItem( 712, OB, mesh, "&& isComputable" ); // EVALUATE
- createPopupItem( 713, OB, mesh, "&& isComputable" ); // MESH ORDER
- createPopupItem( 214, OB, mesh_part ); // UPDATE
- createPopupItem( 900, OB, mesh_part ); // ADV_INFO
- createPopupItem( 904, OB, mesh_group ); // FIND_ELEM
- createPopupItem( 6032, OB, mesh_part ); // CTRL_INFO
+ createPopupItem( SMESHOp::OpCompute, OB, mesh, "&& isComputable" );
+ createPopupItem( SMESHOp::OpPreCompute, OB, mesh, "&& isComputable && isPreComputable" );
+ createPopupItem( SMESHOp::OpEvaluate, OB, mesh, "&& isComputable" );
+ createPopupItem( SMESHOp::OpMeshOrder, OB, mesh, "&& isComputable" );
+ createPopupItem( SMESHOp::OpUpdate, OB, mesh_part );
+ createPopupItem( SMESHOp::OpMeshInformation, OB, mesh_part );
+ createPopupItem( SMESHOp::OpFindElementByPoint, OB, mesh_group );
+ createPopupItem( SMESHOp::OpOverallMeshQuality, OB, mesh_part );
popupMgr()->insert( separator(), -1, 0 );
- createPopupItem( 801, OB, mesh ); // CREATE_GROUP
- createPopupItem( 806, OB, mesh ); // CREATE_GEO_GROUP
- createPopupItem( 802, OB, subMesh ); // CONSTRUCT_GROUP
+ createPopupItem( SMESHOp::OpCreateGroup, OB, mesh );
+ createPopupItem( SMESHOp::OpCreateGeometryGroup, OB, mesh );
+ createPopupItem( SMESHOp::OpConstructGroup, OB, subMesh );
popupMgr()->insert( separator(), -1, 0 );
- createPopupItem( 1100, OB, hypo); // EDIT HYPOTHESIS
- createPopupItem( 1102, OB, hyp_alg ); // REMOVE HYPOTHESIS / ALGORITHMS
+ createPopupItem( SMESHOp::OpEditHypothesis, OB, hypo);
+ createPopupItem( SMESHOp::OpUnassign, OB, hyp_alg ); // REMOVE HYPOTHESIS / ALGORITHMS
popupMgr()->insert( separator(), -1, 0 );
- createPopupItem( 4043, OB, mesh ); // CLEAR_MESH
+ createPopupItem( SMESHOp::OpClearMesh, OB, mesh );
popupMgr()->insert( separator(), -1, 0 );
- createPopupItem( 417, OB, mesh + " " + subMesh ); // convert to quadratic
- createPopupItem( 418, OB, mesh + " " + group, // create 2D mesh from 3D
+ createPopupItem( SMESHOp::OpConvertMeshToQuadratic, OB, mesh + " " + subMesh ); // convert to quadratic
+ createPopupItem( SMESHOp::OpCreateBoundaryElements, OB, mesh + " " + group, // create 2D mesh from 3D
"&& dim>=2");
popupMgr()->insert( separator(), -1, 0 );
QString only_one_2D = only_one_non_empty + " && dim>1";
int anId = popupMgr()->insert( tr( "MEN_EXPORT" ), -1, -1 ); // EXPORT submenu
- createPopupItem( 125, OB, mesh_group, multiple_non_empty, anId ); // EXPORT_MED
- createPopupItem( 126, OB, mesh_group, only_one_non_empty, anId ); // EXPORT_UNV
- createPopupItem( 141, OB, mesh_group, only_one_2D, anId ); // EXPORT_STL
+ createPopupItem( SMESHOp::OpPopupExportMED, OB, mesh_group, multiple_non_empty, anId );
+ createPopupItem( SMESHOp::OpPopupExportUNV, OB, mesh_group, only_one_non_empty, anId );
+ createPopupItem( SMESHOp::OpPopupExportSTL, OB, mesh_group, only_one_2D, anId );
#ifdef WITH_CGNS
- createPopupItem( 143, OB, mesh_group, multiple_non_empty, anId ); // EXPORT_CGNS
+ createPopupItem( SMESHOp::OpPopupExportCGNS, OB, mesh_group, multiple_non_empty, anId );
#endif
- createPopupItem( 145, OB, mesh_group, multiple_non_empty, anId ); // EXPORT_SAUV
- createPopupItem( 147, OB, mesh_group, multiple_non_empty, anId ); // EXPORT_GMF
- createPopupItem( 124, OB, mesh_group, multiple_non_empty, anId ); // EXPORT_DAT
- createPopupItem( 33, OB, mesh_part + " " + hyp_alg ); // DELETE
- createPopupItem( 813, OB, group ); // DEL_GROUP with contents
+ createPopupItem( SMESHOp::OpPopupExportSAUV, OB, mesh_group, multiple_non_empty, anId );
+ createPopupItem( SMESHOp::OpPopupExportGMF, OB, mesh_group, multiple_non_empty, anId );
+ createPopupItem( SMESHOp::OpPopupExportDAT, OB, mesh_group, multiple_non_empty, anId );
+ createPopupItem( SMESHOp::OpDelete, OB, mesh_part + " " + hyp_alg );
+ createPopupItem( SMESHOp::OpDeleteGroup, OB, group );
popupMgr()->insert( separator(), -1, 0 );
// popup for viewer
- createPopupItem( 803, View, group ); // EDIT_GROUP
- createPopupItem( 804, View, elems ); // ADD
- createPopupItem( 805, View, elems ); // REMOVE
+ createPopupItem( SMESHOp::OpEditGroup, View, group );
+ createPopupItem( SMESHOp::OpAddElemGroupPopup, View, elems );
+ createPopupItem( SMESHOp::OpRemoveElemGroupPopup, View, elems );
popupMgr()->insert( separator(), -1, 0 );
- createPopupItem( 214, View, mesh_part ); // UPDATE
- createPopupItem( 900, View, mesh_part ); // ADV_INFO
- createPopupItem( 6032,View, mesh_part ); // CTRL_INFO
- createPopupItem( 904, View, mesh ); // FIND_ELEM
+ createPopupItem( SMESHOp::OpUpdate, View, mesh_part );
+ createPopupItem( SMESHOp::OpMeshInformation, View, mesh_part );
+ createPopupItem( SMESHOp::OpOverallMeshQuality, View, mesh_part );
+ createPopupItem( SMESHOp::OpFindElementByPoint, View, mesh );
popupMgr()->insert( separator(), -1, 0 );
- createPopupItem( 1136, OB + " " + View, mesh, "&& (not isAutoColor)" ); // AUTO_COLOR
- createPopupItem( 1137, OB + " " + View, mesh, "&& isAutoColor" ); // DISABLE_AUTO_COLOR
+ createPopupItem( SMESHOp::OpAutoColor, OB + " " + View, mesh, "&& (not isAutoColor)" );
+ createPopupItem( SMESHOp::OpDisableAutoColor, OB + " " + View, mesh, "&& isAutoColor" );
popupMgr()->insert( separator(), -1, 0 );
QString aClient = QString( "%1client in {%2}" ).arg( lc ).arg( "'VTKViewer'" );
//-------------------------------------------------
anId = popupMgr()->insert( tr( "MEN_NUM" ), -1, -1 );
- popupMgr()->insert( action( 9010 ), anId, -1 );
- popupMgr()->setRule( action( 9010 ), aMeshInVTK + "&& isVisible &&" + hasNodes, QtxPopupMgr::VisibleRule );
- popupMgr()->setRule( action( 9010 ), "{'Point'} in labeledTypes", QtxPopupMgr::ToggleRule );
+ popupMgr()->insert( action( SMESHOp::OpNumberingNodes ), anId, -1 );
+ popupMgr()->setRule( action( SMESHOp::OpNumberingNodes ), aMeshInVTK + "&& isVisible &&" + hasNodes, QtxPopupMgr::VisibleRule );
+ popupMgr()->setRule( action( SMESHOp::OpNumberingNodes ), "{'Point'} in labeledTypes", QtxPopupMgr::ToggleRule );
- popupMgr()->insert( action( 9011 ), anId, -1 );
- popupMgr()->setRule( action( 9011 ), aMeshInVTK + "&& isVisible &&" + hasElems, QtxPopupMgr::VisibleRule );
- popupMgr()->setRule( action( 9011 ), "{'Cell'} in labeledTypes", QtxPopupMgr::ToggleRule );
+ popupMgr()->insert( action( SMESHOp::OpNumberingElements ), anId, -1 );
+ popupMgr()->setRule( action( SMESHOp::OpNumberingElements ), aMeshInVTK + "&& isVisible &&" + hasElems, QtxPopupMgr::VisibleRule );
+ popupMgr()->setRule( action( SMESHOp::OpNumberingElements ), "{'Cell'} in labeledTypes", QtxPopupMgr::ToggleRule );
popupMgr()->insert( separator(), -1, -1 );
//-------------------------------------------------
anId = popupMgr()->insert( tr( "MEN_DISPMODE" ), -1, -1 );
- popupMgr()->insert( action( 211 ), anId, -1 ); // WIRE
- popupMgr()->setRule( action( 211 ), aMeshInVTK + "&&" + hasElems, QtxPopupMgr::VisibleRule );
- popupMgr()->setRule( action( 211 ), "displayMode = 'eEdge'", QtxPopupMgr::ToggleRule );
+ popupMgr()->insert( action( SMESHOp::OpDMWireframe ), anId, -1 );
+ popupMgr()->setRule( action( SMESHOp::OpDMWireframe ), aMeshInVTK + "&&" + hasElems, QtxPopupMgr::VisibleRule );
+ popupMgr()->setRule( action( SMESHOp::OpDMWireframe ), "displayMode = 'eEdge'", QtxPopupMgr::ToggleRule );
- popupMgr()->insert( action( 212 ), anId, -1 ); // SHADE
- popupMgr()->setRule( action( 212 ),aMeshInVTK+ "&& (" + hasFaces + "||" + hasVolumes + ")", QtxPopupMgr::VisibleRule);
- popupMgr()->setRule( action( 212 ), "displayMode = 'eSurface'", QtxPopupMgr::ToggleRule );
+ popupMgr()->insert( action( SMESHOp::OpDMShading ), anId, -1 );
+ popupMgr()->setRule( action( SMESHOp::OpDMShading ),aMeshInVTK+ "&& (" + hasFaces + "||" + hasVolumes + ")", QtxPopupMgr::VisibleRule);
+ popupMgr()->setRule( action( SMESHOp::OpDMShading ), "displayMode = 'eSurface'", QtxPopupMgr::ToggleRule );
- popupMgr()->insert( action( 215 ), anId, -1 ); // POINTS
- popupMgr()->setRule( action( 215 ), aMeshInVTK + "&&" + hasNodes, QtxPopupMgr::VisibleRule );
- popupMgr()->setRule( action( 215 ), "displayMode = 'ePoint'", QtxPopupMgr::ToggleRule );
+ popupMgr()->insert( action( SMESHOp::OpDMNodes ), anId, -1 );
+ popupMgr()->setRule( action( SMESHOp::OpDMNodes ), aMeshInVTK + "&&" + hasNodes, QtxPopupMgr::VisibleRule );
+ popupMgr()->setRule( action( SMESHOp::OpDMNodes ), "displayMode = 'ePoint'", QtxPopupMgr::ToggleRule );
popupMgr()->insert( separator(), anId, -1 );
- popupMgr()->insert( action( 213 ), anId, -1 ); // SHRINK
- popupMgr()->setRule( action( 213 ), aMeshInVTK + "&& shrinkMode <> 'IsNotShrinkable' && displayMode <> 'ePoint'", QtxPopupMgr::VisibleRule);
- popupMgr()->setRule( action( 213 ), "shrinkMode = 'IsShrunk'", QtxPopupMgr::ToggleRule );
+ popupMgr()->insert( action( SMESHOp::OpDMShrink ), anId, -1 );
+ popupMgr()->setRule( action( SMESHOp::OpDMShrink ), aMeshInVTK + "&& shrinkMode <> 'IsNotShrinkable' && displayMode <> 'ePoint'", QtxPopupMgr::VisibleRule);
+ popupMgr()->setRule( action( SMESHOp::OpDMShrink ), "shrinkMode = 'IsShrunk'", QtxPopupMgr::ToggleRule );
//-------------------------------------------------
// Display Entity
anId = popupMgr()->insert( tr( "MEN_DISP_ENT" ), -1, -1 );
- popupMgr()->insert( action(216), anId, -1 ); // ELEMS 0D
- popupMgr()->setRule(action(216), aDiffElemsInVTK + "&& isVisible &&" + hasElems0d, QtxPopupMgr::VisibleRule);
- popupMgr()->setRule(action(216), "{'Elem0d'} in entityMode", QtxPopupMgr::ToggleRule);
+ popupMgr()->insert( action( SMESHOp::OpDE0DElements ), anId, -1 );
+ popupMgr()->setRule( action( SMESHOp::OpDE0DElements ), aDiffElemsInVTK + "&& isVisible &&" + hasElems0d, QtxPopupMgr::VisibleRule);
+ popupMgr()->setRule( action( SMESHOp::OpDE0DElements ), "{'Elem0d'} in entityMode", QtxPopupMgr::ToggleRule);
- popupMgr()->insert( action( 217 ), anId, -1 ); // EDGES
- popupMgr()->setRule( action( 217 ), aDiffElemsInVTK + "&& isVisible &&" + hasEdges, QtxPopupMgr::VisibleRule );
- popupMgr()->setRule( action( 217 ), "{'Edge'} in entityMode", QtxPopupMgr::ToggleRule );
+ popupMgr()->insert( action( SMESHOp::OpDEEdges ), anId, -1 );
+ popupMgr()->setRule( action( SMESHOp::OpDEEdges ), aDiffElemsInVTK + "&& isVisible &&" + hasEdges, QtxPopupMgr::VisibleRule );
+ popupMgr()->setRule( action( SMESHOp::OpDEEdges ), "{'Edge'} in entityMode", QtxPopupMgr::ToggleRule );
- popupMgr()->insert( action( 218 ), anId, -1 ); // FACES
- popupMgr()->setRule( action( 218 ), aDiffElemsInVTK + "&& isVisible &&" + hasFaces, QtxPopupMgr::VisibleRule );
- popupMgr()->setRule( action( 218 ), "{'Face'} in entityMode", QtxPopupMgr::ToggleRule );
+ popupMgr()->insert( action( SMESHOp::OpDEFaces ), anId, -1 );
+ popupMgr()->setRule( action( SMESHOp::OpDEFaces ), aDiffElemsInVTK + "&& isVisible &&" + hasFaces, QtxPopupMgr::VisibleRule );
+ popupMgr()->setRule( action( SMESHOp::OpDEFaces ), "{'Face'} in entityMode", QtxPopupMgr::ToggleRule );
- popupMgr()->insert( action( 219 ), anId, -1 ); // VOLUMES
- popupMgr()->setRule( action( 219 ), aDiffElemsInVTK + "&& isVisible &&" + hasVolumes, QtxPopupMgr::VisibleRule );
- popupMgr()->setRule( action( 219 ), "{'Volume'} in entityMode", QtxPopupMgr::ToggleRule );
+ popupMgr()->insert( action( SMESHOp::OpDEVolumes ), anId, -1 );
+ popupMgr()->setRule( action( SMESHOp::OpDEVolumes ), aDiffElemsInVTK + "&& isVisible &&" + hasVolumes, QtxPopupMgr::VisibleRule );
+ popupMgr()->setRule( action( SMESHOp::OpDEVolumes ), "{'Volume'} in entityMode", QtxPopupMgr::ToggleRule );
- popupMgr()->insert( action( 222 ), anId, -1 ); // BALLS
- popupMgr()->setRule( action( 222 ), aDiffElemsInVTK + "&& isVisible &&" + hasBalls, QtxPopupMgr::VisibleRule );
- popupMgr()->setRule( action( 222 ), "{'BallElem'} in entityMode", QtxPopupMgr::ToggleRule );
+ popupMgr()->insert( action( SMESHOp::OpDEBalls ), anId, -1 );
+ popupMgr()->setRule( action( SMESHOp::OpDEBalls ), aDiffElemsInVTK + "&& isVisible &&" + hasBalls, QtxPopupMgr::VisibleRule );
+ popupMgr()->setRule( action( SMESHOp::OpDEBalls ), "{'BallElem'} in entityMode", QtxPopupMgr::ToggleRule );
popupMgr()->insert( separator(), anId, -1 );
- popupMgr()->insert( action( 220 ), anId, -1 ); // ALL
- popupMgr()->setRule( action( 220 ), aDiffElemsInVTK + "&& isVisible && not( elemTypes in entityMode )", QtxPopupMgr::VisibleRule );
+ popupMgr()->insert( action( SMESHOp::OpDEAllEntity ), anId, -1 );
+ popupMgr()->setRule( action( SMESHOp::OpDEAllEntity ), aDiffElemsInVTK + "&& isVisible && not( elemTypes in entityMode )", QtxPopupMgr::VisibleRule );
//-------------------------------------------------
// Representation of the 2D Quadratic elements
//-------------------------------------------------
anId = popupMgr()->insert( tr( "MEN_QUADRATIC_REPRESENT" ), -1, -1 );
- popupMgr()->insert( action( 231 ), anId, -1 ); // LINE REPRESENTATION
- popupMgr()->setRule( action( 231 ), aMeshInVTK + "and isVisible",QtxPopupMgr::VisibleRule );
- popupMgr()->setRule( action( 231 ), "quadratic2DMode = 'eLines'", QtxPopupMgr::ToggleRule );
+ popupMgr()->insert( action( SMESHOp::OpRepresentationLines ), anId, -1 );
+ popupMgr()->setRule( action( SMESHOp::OpRepresentationLines ), aMeshInVTK + "and isVisible",QtxPopupMgr::VisibleRule );
+ popupMgr()->setRule( action( SMESHOp::OpRepresentationLines ), "quadratic2DMode = 'eLines'", QtxPopupMgr::ToggleRule );
- popupMgr()->insert( action( 232 ), anId, -1 ); // ARC REPRESENTATION
- popupMgr()->setRule( action( 232 ), aMeshInVTK + "and isVisible", QtxPopupMgr::VisibleRule );
- popupMgr()->setRule( action( 232 ), "quadratic2DMode = 'eArcs'", QtxPopupMgr::ToggleRule );
+ popupMgr()->insert( action( SMESHOp::OpRepresentationArcs ), anId, -1 );
+ popupMgr()->setRule( action( SMESHOp::OpRepresentationArcs ), aMeshInVTK + "and isVisible", QtxPopupMgr::VisibleRule );
+ popupMgr()->setRule( action( SMESHOp::OpRepresentationArcs ), "quadratic2DMode = 'eArcs'", QtxPopupMgr::ToggleRule );
//-------------------------------------------------
// Orientation of faces
//-------------------------------------------------
- popupMgr()->insert( action( 221 ), -1, -1 );
- popupMgr()->setRule( action( 221 ), aMeshInVTK + "&& isVisible", QtxPopupMgr::VisibleRule);
- popupMgr()->setRule( action( 221 ), "facesOrientationMode = 'IsOriented'", QtxPopupMgr::ToggleRule );
+ popupMgr()->insert( action( SMESHOp::OpOrientationOnFaces ), -1, -1 );
+ popupMgr()->setRule( action( SMESHOp::OpOrientationOnFaces ), aMeshInVTK + "&& isVisible", QtxPopupMgr::VisibleRule);
+ popupMgr()->setRule( action( SMESHOp::OpOrientationOnFaces ), "facesOrientationMode = 'IsOriented'", QtxPopupMgr::ToggleRule );
//-------------------------------------------------
// Color / Size
//-------------------------------------------------
- popupMgr()->insert( action( 1132 ), -1, -1 );
- popupMgr()->setRule( action( 1132 ), aMeshInVTK + "&& isVisible", QtxPopupMgr::VisibleRule );
+ popupMgr()->insert( action( SMESHOp::OpProperties ), -1, -1 );
+ popupMgr()->setRule( action( SMESHOp::OpProperties ), aMeshInVTK + "&& isVisible", QtxPopupMgr::VisibleRule );
//-------------------------------------------------
// Transparency
//-------------------------------------------------
- popupMgr()->insert( action( 1133 ), -1, -1 );
- popupMgr()->setRule( action( 1133 ), aMeshInVTK + "&& isVisible", QtxPopupMgr::VisibleRule );
+ popupMgr()->insert( action( SMESHOp::OpTransparency ), -1, -1 );
+ popupMgr()->setRule( action( SMESHOp::OpTransparency ), aMeshInVTK + "&& isVisible", QtxPopupMgr::VisibleRule );
//-------------------------------------------------
// Controls
anId = popupMgr()->insert( tr( "MEN_CTRL" ), -1, -1 );
- popupMgr()->insert( action( 200 ), anId, -1 ); // RESET
- popupMgr()->setRule( action( 200 ), aMeshInVTK + "&& controlMode <> 'eNone'", QtxPopupMgr::VisibleRule );
+ popupMgr()->insert( action( SMESHOp::OpReset ), anId, -1 ); // RESET
+ popupMgr()->setRule( action( SMESHOp::OpReset ), aMeshInVTK + "&& controlMode <> 'eNone'", QtxPopupMgr::VisibleRule );
popupMgr()->insert( separator(), anId, -1 );
int aSubId = popupMgr()->insert( tr( "MEN_NODE_CTRL" ), anId, -1 ); // NODE CONTROLS
- popupMgr()->insert( action( 6005 ), aSubId, -1 ); // FREE_NODE
- popupMgr()->setRule( action( 6005 ), aMeshInVtkHasNodes, QtxPopupMgr::VisibleRule );
- popupMgr()->setRule( action( 6005 ), "controlMode = 'eFreeNodes'", QtxPopupMgr::ToggleRule );
+ popupMgr()->insert( action( SMESHOp::OpFreeNode ), aSubId, -1 );
+ popupMgr()->setRule( action( SMESHOp::OpFreeNode ), aMeshInVtkHasNodes, QtxPopupMgr::VisibleRule );
+ popupMgr()->setRule( action( SMESHOp::OpFreeNode ), "controlMode = 'eFreeNodes'", QtxPopupMgr::ToggleRule );
- popupMgr()->insert ( action( 6028 ), aSubId, -1 ); // EQUAL_NODE
- popupMgr()->setRule( action( 6028 ), aMeshInVtkHasNodes, QtxPopupMgr::VisibleRule );
- popupMgr()->setRule( action( 6028 ), "controlMode = 'eCoincidentNodes'", QtxPopupMgr::ToggleRule);
+ popupMgr()->insert ( action( SMESHOp::OpEqualNode ), aSubId, -1 );
+ popupMgr()->setRule( action( SMESHOp::OpEqualNode ), aMeshInVtkHasNodes, QtxPopupMgr::VisibleRule );
+ popupMgr()->setRule( action( SMESHOp::OpEqualNode ), "controlMode = 'eCoincidentNodes'", QtxPopupMgr::ToggleRule);
aSubId = popupMgr()->insert( tr( "MEN_EDGE_CTRL" ), anId, -1 ); // EDGE CONTROLS
- popupMgr()->insert( action( 6002 ), aSubId, -1 ); // FREE_EDGE
- popupMgr()->setRule( action( 6002 ), aMeshInVtkHasEdges, QtxPopupMgr::VisibleRule );
- popupMgr()->setRule( action( 6002 ), "controlMode = 'eFreeEdges'", QtxPopupMgr::ToggleRule );
+ popupMgr()->insert( action( SMESHOp::OpFreeEdge ), aSubId, -1 );
+ popupMgr()->setRule( action( SMESHOp::OpFreeEdge ), aMeshInVtkHasEdges, QtxPopupMgr::VisibleRule );
+ popupMgr()->setRule( action( SMESHOp::OpFreeEdge ), "controlMode = 'eFreeEdges'", QtxPopupMgr::ToggleRule );
- popupMgr()->insert( action( 6003 ), aSubId, -1 ); // FREE_BORDER
- popupMgr()->setRule( action( 6003 ), aMeshInVtkHasEdges, QtxPopupMgr::VisibleRule );
- popupMgr()->setRule( action( 6003 ), "controlMode = 'eFreeBorders'", QtxPopupMgr::ToggleRule );
+ popupMgr()->insert( action( SMESHOp::OpFreeBorder ), aSubId, -1 );
+ popupMgr()->setRule( action( SMESHOp::OpFreeBorder ), aMeshInVtkHasEdges, QtxPopupMgr::VisibleRule );
+ popupMgr()->setRule( action( SMESHOp::OpFreeBorder ), "controlMode = 'eFreeBorders'", QtxPopupMgr::ToggleRule );
- popupMgr()->insert( action( 6001 ), aSubId, -1 ); // LENGTH
- popupMgr()->setRule( action( 6001 ), aMeshInVtkHasEdges, QtxPopupMgr::VisibleRule );
- popupMgr()->setRule( action( 6001 ), "controlMode = 'eLength'", QtxPopupMgr::ToggleRule );
+ popupMgr()->insert( action( SMESHOp::OpLength ), aSubId, -1 );
+ popupMgr()->setRule( action( SMESHOp::OpLength ), aMeshInVtkHasEdges, QtxPopupMgr::VisibleRule );
+ popupMgr()->setRule( action( SMESHOp::OpLength ), "controlMode = 'eLength'", QtxPopupMgr::ToggleRule );
- popupMgr()->insert( action( 6004 ), aSubId, -1 ); // CONNECTION
- popupMgr()->setRule( action( 6004 ), aMeshInVtkHasEdges, QtxPopupMgr::VisibleRule );
- popupMgr()->setRule( action( 6004 ), "controlMode = 'eMultiConnection'", QtxPopupMgr::ToggleRule );
- popupMgr()->insert ( action( 6029 ), aSubId, -1 ); // EQUAL_EDGE
- popupMgr()->setRule( action( 6029 ), aMeshInVtkHasEdges, QtxPopupMgr::VisibleRule );
- popupMgr()->setRule( action( 6029 ), "controlMode = 'eCoincidentElems1D'", QtxPopupMgr::ToggleRule);
+ popupMgr()->insert( action( SMESHOp::OpConnection ), aSubId, -1 );
+ popupMgr()->setRule( action( SMESHOp::OpConnection ), aMeshInVtkHasEdges, QtxPopupMgr::VisibleRule );
+ popupMgr()->setRule( action( SMESHOp::OpConnection ), "controlMode = 'eMultiConnection'", QtxPopupMgr::ToggleRule );
+ popupMgr()->insert ( action( SMESHOp::OpEqualEdge ), aSubId, -1 ); // EQUAL_EDGE
+ popupMgr()->setRule( action( SMESHOp::OpEqualEdge ), aMeshInVtkHasEdges, QtxPopupMgr::VisibleRule );
+ popupMgr()->setRule( action( SMESHOp::OpEqualEdge ), "controlMode = 'eCoincidentElems1D'", QtxPopupMgr::ToggleRule);
aSubId = popupMgr()->insert( tr( "MEN_FACE_CTRL" ), anId, -1 ); // FACE CONTROLS
- popupMgr()->insert ( action( 6021 ), aSubId, -1 ); // FREE_FACE
- popupMgr()->setRule( action( 6021 ), aMeshInVtkHasFaces /*aMeshInVtkHasVolumes*/,
+ popupMgr()->insert ( action( SMESHOp::OpFreeFace ), aSubId, -1 );
+ popupMgr()->setRule( action( SMESHOp::OpFreeFace ), aMeshInVtkHasFaces /*aMeshInVtkHasVolumes*/,
QtxPopupMgr::VisibleRule );
- popupMgr()->setRule( action( 6021 ), "controlMode = 'eFreeFaces'", QtxPopupMgr::ToggleRule );
+ popupMgr()->setRule( action( SMESHOp::OpFreeFace ), "controlMode = 'eFreeFaces'", QtxPopupMgr::ToggleRule );
- popupMgr()->insert ( action( 6018 ), aSubId, -1 ); // LENGTH_2D
- popupMgr()->setRule( action( 6018 ), aMeshInVtkHasFaces, QtxPopupMgr::VisibleRule );
- popupMgr()->setRule( action( 6018 ), "controlMode = 'eLength2D'", QtxPopupMgr::ToggleRule );
+ popupMgr()->insert ( action( SMESHOp::OpLength2D ), aSubId, -1 );
+ popupMgr()->setRule( action( SMESHOp::OpLength2D ), aMeshInVtkHasFaces, QtxPopupMgr::VisibleRule );
+ popupMgr()->setRule( action( SMESHOp::OpLength2D ), "controlMode = 'eLength2D'", QtxPopupMgr::ToggleRule );
- popupMgr()->insert ( action( 6019 ), aSubId, -1 ); // CONNECTION_2D
- popupMgr()->setRule( action( 6019 ), aMeshInVtkHasFaces, QtxPopupMgr::VisibleRule );
- popupMgr()->setRule( action( 6019 ), "controlMode = 'eMultiConnection2D'", QtxPopupMgr::ToggleRule );
+ popupMgr()->insert ( action( SMESHOp::OpConnection2D ), aSubId, -1 );
+ popupMgr()->setRule( action( SMESHOp::OpConnection2D ), aMeshInVtkHasFaces, QtxPopupMgr::VisibleRule );
+ popupMgr()->setRule( action( SMESHOp::OpConnection2D ), "controlMode = 'eMultiConnection2D'", QtxPopupMgr::ToggleRule );
- popupMgr()->insert ( action( 6011 ), aSubId, -1 ); // AREA
- popupMgr()->setRule( action( 6011 ), aMeshInVtkHasFaces, QtxPopupMgr::VisibleRule );
- popupMgr()->setRule( action( 6011 ), "controlMode = 'eArea'", QtxPopupMgr::ToggleRule );
+ popupMgr()->insert ( action( SMESHOp::OpArea ), aSubId, -1 );
+ popupMgr()->setRule( action( SMESHOp::OpArea ), aMeshInVtkHasFaces, QtxPopupMgr::VisibleRule );
+ popupMgr()->setRule( action( SMESHOp::OpArea ), "controlMode = 'eArea'", QtxPopupMgr::ToggleRule );
- popupMgr()->insert ( action( 6012 ), aSubId, -1 ); // TAPER
- popupMgr()->setRule( action( 6012 ), aMeshInVtkHasFaces, QtxPopupMgr::VisibleRule );
- popupMgr()->setRule( action( 6012 ), "controlMode = 'eTaper'", QtxPopupMgr::ToggleRule );
+ popupMgr()->insert ( action( SMESHOp::OpTaper ), aSubId, -1 );
+ popupMgr()->setRule( action( SMESHOp::OpTaper ), aMeshInVtkHasFaces, QtxPopupMgr::VisibleRule );
+ popupMgr()->setRule( action( SMESHOp::OpTaper ), "controlMode = 'eTaper'", QtxPopupMgr::ToggleRule );
- popupMgr()->insert ( action( 6013 ), aSubId, -1 ); // ASPECT
- popupMgr()->setRule( action( 6013 ), aMeshInVtkHasFaces, QtxPopupMgr::VisibleRule );
- popupMgr()->setRule( action( 6013 ), "controlMode = 'eAspectRatio'", QtxPopupMgr::ToggleRule );
+ popupMgr()->insert ( action( SMESHOp::OpAspectRatio ), aSubId, -1 );
+ popupMgr()->setRule( action( SMESHOp::OpAspectRatio ), aMeshInVtkHasFaces, QtxPopupMgr::VisibleRule );
+ popupMgr()->setRule( action( SMESHOp::OpAspectRatio ), "controlMode = 'eAspectRatio'", QtxPopupMgr::ToggleRule );
- popupMgr()->insert ( action( 6014 ), aSubId, -1 ); // MIN_ANG
- popupMgr()->setRule( action( 6014 ), aMeshInVtkHasFaces, QtxPopupMgr::VisibleRule );
- popupMgr()->setRule( action( 6014 ), "controlMode = 'eMinimumAngle'", QtxPopupMgr::ToggleRule );
+ popupMgr()->insert ( action( SMESHOp::OpMinimumAngle ), aSubId, -1 );
+ popupMgr()->setRule( action( SMESHOp::OpMinimumAngle ), aMeshInVtkHasFaces, QtxPopupMgr::VisibleRule );
+ popupMgr()->setRule( action( SMESHOp::OpMinimumAngle ), "controlMode = 'eMinimumAngle'", QtxPopupMgr::ToggleRule );
- popupMgr()->insert ( action( 6015 ), aSubId, -1 ); // WARP
- popupMgr()->setRule( action( 6015 ), aMeshInVtkHasFaces, QtxPopupMgr::VisibleRule );
- popupMgr()->setRule( action( 6015 ), "controlMode = 'eWarping'", QtxPopupMgr::ToggleRule );
+ popupMgr()->insert ( action( SMESHOp::OpWarpingAngle ), aSubId, -1 );
+ popupMgr()->setRule( action( SMESHOp::OpWarpingAngle ), aMeshInVtkHasFaces, QtxPopupMgr::VisibleRule );
+ popupMgr()->setRule( action( SMESHOp::OpWarpingAngle ), "controlMode = 'eWarping'", QtxPopupMgr::ToggleRule );
- popupMgr()->insert ( action( 6016 ), aSubId, -1 ); // SKEW
- popupMgr()->setRule( action( 6016 ), aMeshInVtkHasFaces, QtxPopupMgr::VisibleRule );
- popupMgr()->setRule( action( 6016 ), "controlMode = 'eSkew'", QtxPopupMgr::ToggleRule );
+ popupMgr()->insert ( action( SMESHOp::OpSkew ), aSubId, -1 );
+ popupMgr()->setRule( action( SMESHOp::OpSkew ), aMeshInVtkHasFaces, QtxPopupMgr::VisibleRule );
+ popupMgr()->setRule( action( SMESHOp::OpSkew ), "controlMode = 'eSkew'", QtxPopupMgr::ToggleRule );
- popupMgr()->insert ( action( 6022 ), aSubId, -1 ); // MAX_ELEMENT_LENGTH_2D
- popupMgr()->setRule( action( 6022 ), aMeshInVtkHasFaces, QtxPopupMgr::VisibleRule );
- popupMgr()->setRule( action( 6022 ), "controlMode = 'eMaxElementLength2D'", QtxPopupMgr::ToggleRule );
+ popupMgr()->insert ( action( SMESHOp::OpMaxElementLength2D ), aSubId, -1 );
+ popupMgr()->setRule( action( SMESHOp::OpMaxElementLength2D ), aMeshInVtkHasFaces, QtxPopupMgr::VisibleRule );
+ popupMgr()->setRule( action( SMESHOp::OpMaxElementLength2D ), "controlMode = 'eMaxElementLength2D'", QtxPopupMgr::ToggleRule );
- popupMgr()->insert ( action( 6025 ), aSubId, -1 ); // BARE_BORDER_FACE
- popupMgr()->setRule( action( 6025 ), aMeshInVtkHasFaces, QtxPopupMgr::VisibleRule );
- popupMgr()->setRule( action( 6025 ), "controlMode = 'eBareBorderFace'", QtxPopupMgr::ToggleRule );
+ popupMgr()->insert ( action( SMESHOp::OpBareBorderFace ), aSubId, -1 );
+ popupMgr()->setRule( action( SMESHOp::OpBareBorderFace ), aMeshInVtkHasFaces, QtxPopupMgr::VisibleRule );
+ popupMgr()->setRule( action( SMESHOp::OpBareBorderFace ), "controlMode = 'eBareBorderFace'", QtxPopupMgr::ToggleRule );
- popupMgr()->insert ( action( 6027 ), aSubId, -1 ); // OVER_CONSTRAINED_FACE
- popupMgr()->setRule( action( 6027 ), aMeshInVtkHasFaces, QtxPopupMgr::VisibleRule );
- popupMgr()->setRule( action( 6027 ), "controlMode = 'eOverConstrainedFace'", QtxPopupMgr::ToggleRule );
- popupMgr()->insert ( action( 6030 ), aSubId, -1 ); // EQUAL_FACE
- popupMgr()->setRule( action( 6030 ), aMeshInVtkHasFaces, QtxPopupMgr::VisibleRule );
- popupMgr()->setRule( action( 6030 ), "controlMode = 'eCoincidentElems2D'", QtxPopupMgr::ToggleRule );
+ popupMgr()->insert ( action( SMESHOp::OpOverConstrainedFace ), aSubId, -1 );
+ popupMgr()->setRule( action( SMESHOp::OpOverConstrainedFace ), aMeshInVtkHasFaces, QtxPopupMgr::VisibleRule );
+ popupMgr()->setRule( action( SMESHOp::OpOverConstrainedFace ), "controlMode = 'eOverConstrainedFace'", QtxPopupMgr::ToggleRule );
+ popupMgr()->insert ( action( SMESHOp::OpEqualFace ), aSubId, -1 );
+ popupMgr()->setRule( action( SMESHOp::OpEqualFace ), aMeshInVtkHasFaces, QtxPopupMgr::VisibleRule );
+ popupMgr()->setRule( action( SMESHOp::OpEqualFace ), "controlMode = 'eCoincidentElems2D'", QtxPopupMgr::ToggleRule );
aSubId = popupMgr()->insert( tr( "MEN_VOLUME_CTRL" ), anId, -1 ); // VOLUME CONTROLS
- popupMgr()->insert ( action( 6017 ), aSubId, -1 ); // ASPECT_3D
- popupMgr()->setRule( action( 6017 ), aMeshInVtkHasVolumes, QtxPopupMgr::VisibleRule );
- popupMgr()->setRule( action( 6017 ), "controlMode = 'eAspectRatio3D'", QtxPopupMgr::ToggleRule );
+ popupMgr()->insert ( action( SMESHOp::OpAspectRatio3D ), aSubId, -1 );
+ popupMgr()->setRule( action( SMESHOp::OpAspectRatio3D ), aMeshInVtkHasVolumes, QtxPopupMgr::VisibleRule );
+ popupMgr()->setRule( action( SMESHOp::OpAspectRatio3D ), "controlMode = 'eAspectRatio3D'", QtxPopupMgr::ToggleRule );
- popupMgr()->insert ( action( 6009 ), aSubId, -1 ); // VOLUME_3D
- popupMgr()->setRule( action( 6009 ), aMeshInVtkHasVolumes, QtxPopupMgr::VisibleRule );
- popupMgr()->setRule( action( 6009 ), "controlMode = 'eVolume3D'", QtxPopupMgr::ToggleRule );
+ popupMgr()->insert ( action( SMESHOp::OpVolume ), aSubId, -1 );
+ popupMgr()->setRule( action( SMESHOp::OpVolume ), aMeshInVtkHasVolumes, QtxPopupMgr::VisibleRule );
+ popupMgr()->setRule( action( SMESHOp::OpVolume ), "controlMode = 'eVolume3D'", QtxPopupMgr::ToggleRule );
- popupMgr()->insert ( action( 6023 ), aSubId, -1 ); // MAX_ELEMENT_LENGTH_3D
- popupMgr()->setRule( action( 6023 ), aMeshInVtkHasVolumes, QtxPopupMgr::VisibleRule );
- popupMgr()->setRule( action( 6023 ), "controlMode = 'eMaxElementLength3D'", QtxPopupMgr::ToggleRule );
+ popupMgr()->insert ( action( SMESHOp::OpMaxElementLength3D ), aSubId, -1 );
+ popupMgr()->setRule( action( SMESHOp::OpMaxElementLength3D ), aMeshInVtkHasVolumes, QtxPopupMgr::VisibleRule );
+ popupMgr()->setRule( action( SMESHOp::OpMaxElementLength3D ), "controlMode = 'eMaxElementLength3D'", QtxPopupMgr::ToggleRule );
- popupMgr()->insert ( action( 6024 ), aSubId, -1 ); // BARE_BORDER_VOLUME
- popupMgr()->setRule( action( 6024 ), aMeshInVtkHasVolumes, QtxPopupMgr::VisibleRule );
- popupMgr()->setRule( action( 6024 ), "controlMode = 'eBareBorderVolume'", QtxPopupMgr::ToggleRule );
+ popupMgr()->insert ( action( SMESHOp::OpBareBorderVolume ), aSubId, -1 );
+ popupMgr()->setRule( action( SMESHOp::OpBareBorderVolume ), aMeshInVtkHasVolumes, QtxPopupMgr::VisibleRule );
+ popupMgr()->setRule( action( SMESHOp::OpBareBorderVolume ), "controlMode = 'eBareBorderVolume'", QtxPopupMgr::ToggleRule );
- popupMgr()->insert ( action( 6026 ), aSubId, -1 ); // OVER_CONSTRAINED_VOLUME
- popupMgr()->setRule( action( 6026 ), aMeshInVtkHasVolumes, QtxPopupMgr::VisibleRule );
- popupMgr()->setRule( action( 6026 ), "controlMode = 'eOverConstrainedVolume'", QtxPopupMgr::ToggleRule );
+ popupMgr()->insert ( action( SMESHOp::OpOverConstrainedVolume ), aSubId, -1 );
+ popupMgr()->setRule( action( SMESHOp::OpOverConstrainedVolume ), aMeshInVtkHasVolumes, QtxPopupMgr::VisibleRule );
+ popupMgr()->setRule( action( SMESHOp::OpOverConstrainedVolume ), "controlMode = 'eOverConstrainedVolume'", QtxPopupMgr::ToggleRule );
- popupMgr()->insert ( action( 6031 ), aSubId, -1 ); // EQUAL_VOLUME
- popupMgr()->setRule( action( 6031 ), aMeshInVtkHasVolumes, QtxPopupMgr::VisibleRule );
- popupMgr()->setRule( action( 6031 ), "controlMode = 'eCoincidentElems3D'", QtxPopupMgr::ToggleRule );
+ popupMgr()->insert ( action( SMESHOp::OpEqualVolume ), aSubId, -1 );
+ popupMgr()->setRule( action( SMESHOp::OpEqualVolume ), aMeshInVtkHasVolumes, QtxPopupMgr::VisibleRule );
+ popupMgr()->setRule( action( SMESHOp::OpEqualVolume ), "controlMode = 'eCoincidentElems3D'", QtxPopupMgr::ToggleRule );
popupMgr()->insert( separator(), anId, -1 );
- popupMgr()->insert( action( 201 ), anId, -1 ); // SCALAR_BAR_PROP
- popupMgr()->setRule( action( 201 ), aMeshInVTK + "&& controlMode <> 'eNone'", QtxPopupMgr::VisibleRule );
+ popupMgr()->insert( action( SMESHOp::OpScalarBarProperties ), anId, -1 );
+ popupMgr()->setRule( action( SMESHOp::OpScalarBarProperties ), aMeshInVTK + "&& controlMode <> 'eNone'", QtxPopupMgr::VisibleRule );
popupMgr()->insert( separator(), anId, -1 );
aSubId = popupMgr()->insert( tr( "MEN_DISTRIBUTION_CTRL" ), anId, -1 ); // NODE CONTROLS
- popupMgr()->insert( action( 2021 ), aSubId, -1 ); // SAVE_DISTRIBUTION
- popupMgr()->setRule( action( 2021 ), aMeshInVTK + "&& isNumFunctor", QtxPopupMgr::VisibleRule );
+ popupMgr()->insert( action( SMESHOp::OpSaveDistribution ), aSubId, -1 );
+ popupMgr()->setRule( action( SMESHOp::OpSaveDistribution ), aMeshInVTK + "&& isNumFunctor", QtxPopupMgr::VisibleRule );
- popupMgr()->insert( action( 2022 ), aSubId, -1 ); // SHOW_DISTRIBUTION
- popupMgr()->setRule( action( 2022 ), aMeshInVTK + "&& isNumFunctor", QtxPopupMgr::VisibleRule );
- popupMgr()->setRule( action( 2022 ), aMeshInVTK + "&& isNumFunctor && isDistributionVisible", QtxPopupMgr::ToggleRule);
+ popupMgr()->insert( action( SMESHOp::OpShowDistribution ), aSubId, -1 );
+ popupMgr()->setRule( action( SMESHOp::OpShowDistribution ), aMeshInVTK + "&& isNumFunctor", QtxPopupMgr::VisibleRule );
+ popupMgr()->setRule( action( SMESHOp::OpShowDistribution ), aMeshInVTK + "&& isNumFunctor && isDistributionVisible", QtxPopupMgr::ToggleRule);
#ifndef DISABLE_PLOT2DVIEWER
- popupMgr()->insert( action( 2023 ), aSubId, -1 ); // PLOT_DISTRIBUTION
- popupMgr()->setRule( action( 2023 ), aMeshInVTK + "&& isNumFunctor", QtxPopupMgr::VisibleRule );
+ popupMgr()->insert( action( SMESHOp::OpPlotDistribution ), aSubId, -1 );
+ popupMgr()->setRule( action( SMESHOp::OpPlotDistribution ), aMeshInVTK + "&& isNumFunctor", QtxPopupMgr::VisibleRule );
#endif
//-------------------------------------------------
- // Display / Erase
+ // Show / Hide
//-------------------------------------------------
popupMgr()->insert( separator(), -1, -1 );
QString aRule = "$component={'SMESH'} and ( type='Component' or (" + aClient + " and " +
aType + " and " + aSelCount + " and " + anActiveVTK + " and " + isNotEmpty + " %1 ) )";
- popupMgr()->insert( action( 301 ), -1, -1 ); // DISPLAY
- popupMgr()->setRule( action( 301 ), aRule.arg( "and (not isVisible)" ), QtxPopupMgr::VisibleRule );
+ popupMgr()->insert( action( SMESHOp::OpShow ), -1, -1 );
+ popupMgr()->setRule( action( SMESHOp::OpShow ), aRule.arg( "and (not isVisible)" ), QtxPopupMgr::VisibleRule );
- popupMgr()->insert( action( 300 ), -1, -1 ); // ERASE
- popupMgr()->setRule( action( 300 ), aRule.arg( "and isVisible" ), QtxPopupMgr::VisibleRule );
+ popupMgr()->insert( action( SMESHOp::OpHide ), -1, -1 );
+ popupMgr()->setRule( action( SMESHOp::OpHide ), aRule.arg( "and isVisible" ), QtxPopupMgr::VisibleRule );
- popupMgr()->insert( action( 302 ), -1, -1 ); // DISPLAY_ONLY
- popupMgr()->setRule( action( 302 ), aRule.arg( "" ), QtxPopupMgr::VisibleRule );
+ popupMgr()->insert( action( SMESHOp::OpShowOnly ), -1, -1 );
+ popupMgr()->setRule( action( SMESHOp::OpShowOnly ), aRule.arg( "" ), QtxPopupMgr::VisibleRule );
popupMgr()->insert( separator(), -1, -1 );
//-------------------------------------------------
// Clipping
//-------------------------------------------------
- popupMgr()->insert( action( 1134 ), -1, -1 );
- popupMgr()->setRule( action( 1134 ), "client='VTKViewer'", QtxPopupMgr::VisibleRule );
+ popupMgr()->insert( action( SMESHOp::OpClipping ), -1, -1 );
+ popupMgr()->setRule( action( SMESHOp::OpClipping ), "client='VTKViewer'", QtxPopupMgr::VisibleRule );
popupMgr()->insert( separator(), -1, -1 );
- popupMgr()->insert( action( 41 ), -1, -1 );
- popupMgr()->setRule( action( 41 ), "$component={'SMESH'} and client='ObjectBrowser' and isContainer and nbChildren>1", QtxPopupMgr::VisibleRule );
+ popupMgr()->insert( action( SMESHOp::OpSortChild ), -1, -1 );
+ popupMgr()->setRule( action( SMESHOp::OpSortChild ), "$component={'SMESH'} and client='ObjectBrowser' and isContainer and nbChildren>1", QtxPopupMgr::VisibleRule );
popupMgr()->insert( separator(), -1, -1 );
connect( application(), SIGNAL( viewManagerActivated( SUIT_ViewManager* ) ),
bool SMESHGUI::reusableOperation( const int id )
{
// compute, evaluate and precompute are not reusable operations
- return ( id == 701 || id == 711 || id == 712 ) ? false : SalomeApp_Module::reusableOperation( id );
+ return ( id == SMESHOp::OpCompute || id == SMESHOp::OpPreCompute || id == SMESHOp::OpEvaluate ) ? false : SalomeApp_Module::reusableOperation( id );
}
bool SMESHGUI::activateModule( SUIT_Study* study )
// end of SMESH plugins loading
// Reset actions accelerator keys
- //action(111)->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_B)); // Import DAT
- action(112)->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_U)); // Import UNV
- action(113)->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_M)); // Import MED
+ //action(SMESHOp::OpImportDAT)->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_B));
+ action(SMESHOp::OpImportUNV)->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_U));
+ action(SMESHOp::OpImportMED)->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_M));
- action( 33)->setEnabled(true); // Delete: Key_Delete
+ action(SMESHOp::OpDelete)->setEnabled(true); // Delete: Key_Delete
// 0020210. Make SMESH_Gen update meshes at switching GEOM->SMESH
GetSMESHGen()->SetCurrentStudy(SALOMEDS::Study::_nil());
EmitSignalCloseAllDialogs();
// Unset actions accelerator keys
- //action(111)->setShortcut(QKeySequence()); // Import DAT
- action(112)->setShortcut(QKeySequence()); // Import UNV
- action(113)->setShortcut(QKeySequence()); // Import MED
+ //action(SMESHOp::OpImportDAT)->setShortcut(QKeySequence());
+ action(SMESHOp::OpImportUNV)->setShortcut(QKeySequence());
+ action(SMESHOp::OpImportMED)->setShortcut(QKeySequence());
- action( 33)->setEnabled(false); // Delete: Key_Delete
+ action(SMESHOp::OpDelete)->setEnabled(false); // Delete: Key_Delete
return SalomeApp_Module::deactivateModule( study );
}
_PTR(Study) study = appStudy->studyDS();
_PTR(SObject) obj = study->FindObjectID( io->getEntry() );
if ( obj ) {
- QString aName = QString( obj->GetName().c_str() );
+ QString aName = QString( QString::fromUtf8(obj->GetName().c_str()) );
while ( aName.at( aName.length() - 1 ) == ' ' ) // Remove extraspaces in Name of Popup
aName.remove( (aName.length() - 1), 1 );
title = aName;
// to do : create operation here
switch( id )
{
- case 417: //convert to quadratic
+ case SMESHOp::OpConvertMeshToQuadratic:
op = new SMESHGUI_ConvToQuadOp();
break;
- case 418: // create 2D mesh as boundary on 3D
+ case SMESHOp::OpCreateBoundaryElements: // create 2D mesh as boundary on 3D
op = new SMESHGUI_Make2DFrom3DOp();
break;
- case 420: // Reorient faces
+ case SMESHOp::OpReorientFaces:
op = new SMESHGUI_ReorientFacesOp();
break;
- case 701: // Compute mesh
- op = new SMESHGUI_ComputeOp();
- break;
- case 702: // Create mesh
+ case SMESHOp::OpCreateMesh:
op = new SMESHGUI_MeshOp( true, true );
break;
- case 703: // Create sub-mesh
+ case SMESHOp::OpCreateSubMesh:
op = new SMESHGUI_MeshOp( true, false );
break;
- case 704: // Edit mesh/sub-mesh
+ case SMESHOp::OpEditMeshOrSubMesh:
op = new SMESHGUI_MeshOp( false );
break;
- case 711: // Precompute mesh
+ case SMESHOp::OpCompute:
+ op = new SMESHGUI_ComputeOp();
+ break;
+ case SMESHOp::OpPreCompute:
op = new SMESHGUI_PrecomputeOp();
break;
- case 712: // Evaluate mesh
+ case SMESHOp::OpEvaluate:
op = new SMESHGUI_EvaluateOp();
break;
- case 713: // Evaluate mesh
+ case SMESHOp::OpMeshOrder:
op = new SMESHGUI_MeshOrderOp();
break;
- case 806: // Create group on geom
+ case SMESHOp::OpCreateGeometryGroup:
op = new SMESHGUI_GroupOnShapeOp();
break;
- case 904: // Find element
+ case SMESHOp::OpFindElementByPoint:
op = new SMESHGUI_FindElemByPointOp();
break;
- case 4067: // Make mesh pass through point
+ case SMESHOp::OpMoveNode: // Make mesh pass through point
op = new SMESHGUI_MakeNodeAtPointOp();
break;
- case 4070: // Create 0D elements on all nodes
+ case SMESHOp::OpElem0DOnElemNodes: // Create 0D elements on all nodes
op = new SMESHGUI_Add0DElemsOnAllNodesOp();
break;
default:
_PTR(SObject) obj = study->FindObjectID( entry.toLatin1().constData() );
QString name;
if ( obj )
- name = obj->GetName().c_str();
+ name = QString::fromUtf8(obj->GetName().c_str());
if ( name.isEmpty() )
return;
long nbElements = 0;
if ( !memoryLack )
{
- // List of objects that will be updated automatically
+ // List of objects that will be updated automatically
QList< QPair< SMESH::SMESH_IDSource_var, _PTR(SObject) > > aListToUpdate;
SMESH::SMESH_IDSource_var aMeshObj = SMESH::SObjectToInterface<SMESH::SMESH_IDSource>( aMeshSObj );
// put Mesh into list
// update mesh, sub-mesh and groups, if it's possible
QList< QPair< SMESH::SMESH_IDSource_var, _PTR(SObject) > >::iterator anIter;
for( anIter = aListToUpdate.begin(); anIter != aListToUpdate.end(); anIter++ ) {
- SMESH::SMESH_Mesh_var aMesh = SMESH::SMESH_Mesh::_narrow( SMESH::SObjectToObject( (*anIter).second ));
- if ( getSMESHGUI()->automaticUpdate( (*anIter).first, &entities, &limitExceeded, &hidden, &nbElements ) )
- {
- try {
+ SMESH::SMESH_Mesh_var aMesh = SMESH::SMESH_Mesh::_narrow( SMESH::SObjectToObject( (*anIter).second ));
+ if ( getSMESHGUI()->automaticUpdate( (*anIter).first, &entities, &limitExceeded, &hidden, &nbElements ) )
+ {
+ try {
#if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
- OCC_CATCH_SIGNALS;
+ OCC_CATCH_SIGNALS;
#endif
- bool toDisplay = false;
-
- if ( !aMesh->_is_nil() ) { // display a mesh only
- toDisplay = true;
- SMESH_Actor *anActor = SMESH::FindActorByObject( aMesh );
- if ( !anActor ) anActor = SMESH::CreateActor( (*anIter).second->GetStudy(), (*anIter).second->GetID().c_str(), true );
- if ( anActor ) // actor is not created for an empty mesh
- {
- anActor->SetEntityMode( entities );
- SMESH::DisplayActor( SMESH::GetActiveWindow(), anActor );
- }
- }
- Handle(SALOME_InteractiveObject) anIO = new SALOME_InteractiveObject
- ( (*anIter).second->GetID().c_str(), "SMESH", (*anIter).second->GetName().c_str() );
- SMESH::Update(anIO, toDisplay);
-
- if ( limitExceeded && !aMesh->_is_nil() )
- {
- QStringList hiddenMsg;
- if ( hidden & SMESH_Actor::e0DElements ) hiddenMsg << tr( "SMESH_ELEMS0D" );
- if ( hidden & SMESH_Actor::eEdges ) hiddenMsg << tr( "SMESH_EDGES" );
- if ( hidden & SMESH_Actor::eFaces ) hiddenMsg << tr( "SMESH_FACES" );
- if ( hidden & SMESH_Actor::eVolumes ) hiddenMsg << tr( "SMESH_VOLUMES" );
- if ( hidden & SMESH_Actor::eBallElem ) hiddenMsg << tr( "SMESH_BALLS" );
- SUIT_MessageBox::warning( desktop(),
- tr( "SMESH_WRN_WARNING" ),
- tr( "SMESH_WRN_SIZE_INC_LIMIT_EXCEEDED" ).arg( nbElements ).arg( limitSize ).arg( hiddenMsg.join(", ") ) );
- }
- }
- catch (...) {
+ bool toDisplay = false;
+
+ if ( !aMesh->_is_nil() ) { // display a mesh only
+ toDisplay = true;
+ SMESH_Actor *anActor = SMESH::FindActorByObject( aMesh );
+ if ( !anActor ) anActor = SMESH::CreateActor( (*anIter).second->GetStudy(), (*anIter).second->GetID().c_str(), true );
+ if ( anActor ) // actor is not created for an empty mesh
+ {
+ anActor->SetEntityMode( entities );
+ SMESH::DisplayActor( SMESH::GetActiveWindow(), anActor );
+ }
+ }
+ Handle(SALOME_InteractiveObject) anIO = new SALOME_InteractiveObject
+ ( (*anIter).second->GetID().c_str(), "SMESH", (*anIter).second->GetName().c_str() );
+ SMESH::Update(anIO, toDisplay);
+
+ if ( limitExceeded && !aMesh->_is_nil() )
+ {
+ QStringList hiddenMsg;
+ if ( hidden & SMESH_Actor::e0DElements ) hiddenMsg << tr( "SMESH_ELEMS0D" );
+ if ( hidden & SMESH_Actor::eEdges ) hiddenMsg << tr( "SMESH_EDGES" );
+ if ( hidden & SMESH_Actor::eFaces ) hiddenMsg << tr( "SMESH_FACES" );
+ if ( hidden & SMESH_Actor::eVolumes ) hiddenMsg << tr( "SMESH_VOLUMES" );
+ if ( hidden & SMESH_Actor::eBallElem ) hiddenMsg << tr( "SMESH_BALLS" );
+ SUIT_MessageBox::warning( desktop(),
+ tr( "SMESH_WRN_WARNING" ),
+ tr( "SMESH_WRN_SIZE_INC_LIMIT_EXCEEDED" ).arg( nbElements ).arg( limitSize ).arg( hiddenMsg.join(", ") ) );
+ }
+ }
+ 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;
- }
- }
- }
- else if ( limitExceeded && !aMesh->_is_nil() )
- {
- SUIT_MessageBox::warning( desktop(),
- tr( "SMESH_WRN_WARNING" ),
- tr( "SMESH_WRN_SIZE_LIMIT_EXCEEDED" ).arg( nbElements ).arg( limitSize ) );
- }
+ if ( SMDS_Mesh::CheckMemory(true) ) { // has memory to show warning?
+ SMESH::OnVisuException();
+ }
+ else {
+ memoryLack = true;
+ }
+ }
+ }
+ else if ( limitExceeded && !aMesh->_is_nil() )
+ {
+ SUIT_MessageBox::warning( desktop(),
+ tr( "SMESH_WRN_WARNING" ),
+ tr( "SMESH_WRN_SIZE_LIMIT_EXCEEDED" ).arg( nbElements ).arg( limitSize ) );
+ }
}
}
LightApp_SelectionMgr *Sel = selectionMgr();
ok = ( aGroupType != SMESH::NODE );
break;
case 3:
- ok = ( aGroupType == SMESH::VOLUME );
+ ok = ( aGroupType == SMESH::VOLUME ||
+ aGroupType == SMESH::FACE );
break;
}
}
: QDialog( SMESH::GetDesktop( theModule ) ),
mySMESHGUI( theModule ),
mySelectionMgr( SMESH::GetSelectionMgr( theModule ) ),
- myInitSourceWgOnApply( true )
+ myInitSourceWgOnApply( true ),
+ myInsertEnabled( true ),
+ myDiffSourcesEnabled( true )
{
if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
mySelector = aViewWindow->GetSelector();
: QDialog( SMESH::GetDesktop( theModule ) ),
mySMESHGUI( theModule ),
mySelectionMgr( SMESH::GetSelectionMgr( theModule ) ),
- myInitSourceWgOnApply( true )
+ myInitSourceWgOnApply( true ),
+ myInsertEnabled( true ),
+ myDiffSourcesEnabled( true )
{
if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
mySelector = aViewWindow->GetSelector();
int rows = aLay->rowCount();
int cols = aLay->columnCount();
+ // This line looks strange when all additional parameters and mySetInViewer are hidden
QFrame* aLine = new QFrame(aGrp);
aLine->setFrameStyle(QFrame::HLine | QFrame::Sunken);
aLay->addWidget(aLine, rows++, 0, 1, cols);
myInitSourceWgOnApply = initOnApply;
}
+//=======================================================================
+//function : EnableFiltering
+//purpose : Enables "Insert filter in the viewer"
+// and different "Source"s (Mesh, Initial Selection, Current Group)
+//=======================================================================
+
+void SMESHGUI_FilterDlg::SetEnabled( bool setInViewer, bool diffSources )
+{
+ myInsertEnabled = setInViewer;
+ myDiffSourcesEnabled = diffSources;
+
+ mySetInViewer->setVisible( myInsertEnabled );
+ mySourceGrp->button(0)->parentWidget()->setVisible( myDiffSourcesEnabled );
+}
+
//=======================================================================
// name : SMESHGUI_FilterDlg::SetMesh
// Purpose : Set mesh
SMESH::ElementType anEntType = (SMESH::ElementType)myTable->GetType();
if (myFilter[ myTable->GetType() ]->_is_nil() ||
- myFilter[ myTable->GetType() ]->GetPredicate()->_is_nil() ||
- !mySetInViewer->isChecked()) {
+ myFilter[ myTable->GetType() ]->GetPredicate()->_is_nil() ||
+ !mySetInViewer->isChecked() ||
+ !myInsertEnabled )
+ {
SMESH::RemoveFilter(getFilterId(anEntType), aSelector);
}
else {
int aSourceId = mySourceGrp->checkedId();
- if (aSourceId == Mesh)
+ if (aSourceId == Mesh || !myDiffSourcesEnabled )
{
if (myMesh->_is_nil())
return;
void SetSelection();
void SetMesh (SMESH::SMESH_Mesh_var);
void SetSourceWg( QWidget*, const bool initOnApply = true );
+ void SetEnabled( bool setInViewer, bool diffSources );
static SMESH::Filter::Criterion createCriterion();
SVTK_Selector* mySelector;
SMESH::SMESH_Mesh_var myMesh;
bool myInitSourceWgOnApply;
+ bool myInsertEnabled;
+ bool myDiffSourcesEnabled;
QWidget* mySourceWg;
SALOME_DataMapOfIOMapOfInteger myIObjects;
//
#include "SMESHGUI_GEOMGenUtils.h"
#include "SMESHGUI_Utils.h"
+#include "SMESHGUI.h"
// SALOME GEOM includes
#include <GeometryGUI.h>
#include <SALOMEconfig.h>
#include CORBA_CLIENT_HEADER(SMESH_Mesh)
+#include <QString>
+
namespace SMESH
{
GEOM::GEOM_Gen_var GetGEOMGen()
GEOM::GEOM_Object_wrap subShape = aShapesOp->GetSubShape (theMainShape,theID);
return subShape._retn();
}
+
+ //================================================================================
+ /*!
+ * \brief Return entries of sub-mesh geometry and mesh geometry by an IO of assigned
+ * hypothesis
+ * \param [in] hypIO - IO of hyp which is a reference SO to a hyp SO
+ * \param [out] subGeom - found entry of a sub-mesh if any
+ * \param [out] meshGeom - found entry of a mesh
+ * \return bool - \c true if any geometry has been found
+ */
+ //================================================================================
+
+ bool GetGeomEntries( Handle(SALOME_InteractiveObject)& hypIO,
+ QString& subGeom,
+ QString& meshGeom )
+ {
+ subGeom.clear();
+ meshGeom.clear();
+ if ( hypIO.IsNull() ) return false;
+
+ _PTR(Study) aStudy = SMESH::GetActiveStudyDocument();
+ if ( !aStudy ) return false;
+
+ _PTR(SObject) hypSO = aStudy->FindObjectID( hypIO->getEntry() );
+ if ( !hypSO ) return false;
+
+ // Depth() is a number of fathers
+ if ( hypSO->Depth() == 4 ) // hypSO is not a reference to a hyp but a hyp it-self
+ {
+ SMESH::SMESH_Hypothesis_var hyp =
+ SMESH::SObjectToInterface< SMESH::SMESH_Hypothesis >( hypSO );
+ SMESH::SMESH_Mesh_var mesh;
+ GEOM::GEOM_Object_var geom;
+ SMESH::SMESH_Gen_var gen = SMESHGUI::GetSMESHGUI()->GetSMESHGen();
+ if ( !gen || !gen->GetSoleSubMeshUsingHyp( hyp, mesh.out(), geom.out() ))
+ return false;
+
+ subGeom = toQStr( geom->GetStudyEntry() );
+
+ geom = mesh->GetShapeToMesh();
+ if ( geom->_is_nil() )
+ return false;
+ meshGeom = toQStr( geom->GetStudyEntry() );
+ }
+ else
+ {
+ _PTR(SObject) appliedSO = hypSO->GetFather(); // "Applied hypotheses" folder
+ if ( !appliedSO ) return false;
+
+ _PTR(SObject) subOrMeshSO = appliedSO->GetFather(); // mesh or sub-mesh SO
+ if ( !subOrMeshSO ) return false;
+
+ bool isMesh;
+ GEOM::GEOM_Object_var geom = GetShapeOnMeshOrSubMesh( subOrMeshSO, &isMesh );
+ if ( geom->_is_nil() )
+ return false;
+
+ if ( isMesh )
+ {
+ meshGeom = toQStr( geom->GetStudyEntry() );
+ return !meshGeom.isEmpty();
+ }
+
+ subGeom = toQStr( geom->GetStudyEntry() );
+
+ _PTR(SObject) subFolderSO = subOrMeshSO->GetFather(); // "SubMeshes on ..." folder
+ if ( !subFolderSO ) return false;
+
+ _PTR(SObject) meshSO = subFolderSO->GetFather(); // mesh SO
+ if ( !meshSO ) return false;
+
+ geom = GetShapeOnMeshOrSubMesh( meshSO );
+ if ( geom->_is_nil() )
+ return false;
+
+ meshGeom = toQStr( geom->GetStudyEntry() );
+ }
+
+ return !meshGeom.isEmpty() && !subGeom.isEmpty();
+ }
+
+
} // end of namespace SMESH
#include CORBA_SERVER_HEADER(GEOM_Gen)
class SALOMEDSClient_SObject;
+class Handle_SALOME_InteractiveObject;
+class QString;
namespace SMESH
{
SMESHGUI_EXPORT char* GetGeomName( _PTR(SObject) smeshSO );
SMESHGUI_EXPORT GEOM::GEOM_Object_ptr GetSubShape( GEOM::GEOM_Object_ptr, long );
+
+ SMESHGUI_EXPORT bool GetGeomEntries( Handle_SALOME_InteractiveObject& hypIO,
+ QString& subGeom, QString& meshGeom);
}
#endif // SMESHGUI_GEOMGENUTILS_H
#include <SUIT_ResourceMgr.h>
#include <SUIT_Session.h>
#include <SUIT_MessageBox.h>
+#include <SUIT_OverrideCursor.h>
#include <SalomeApp_Tools.h>
#include <SalomeApp_Application.h>
mySMESHGUI->SetActiveDialogBox(this);
mySMESHGUI->SetState(800);
+ SalomeApp_Study* aStudy = dynamic_cast<SalomeApp_Study*>( mySMESHGUI->application()->activeStudy() );
mySelectionMode = grpNoSelection;
- myMeshFilter = new SMESH_TypeFilter(SMESH::MESH);
+
+ myMeshFilter = new SMESH_TypeFilter(SMESH::MESH);
mySubMeshFilter = new SMESH_LogicalFilter(QList<SUIT_SelectionFilter*>(),
SMESH_LogicalFilter::LO_OR,
/*takeOwnership=*/true);
- myGroupFilter = new SMESH_LogicalFilter(QList<SUIT_SelectionFilter*>(),
- SMESH_LogicalFilter::LO_OR,
- /*takeOwnership=*/true);
- SalomeApp_Study* aStudy = dynamic_cast<SalomeApp_Study*>( mySMESHGUI->application()->activeStudy() );
- myGeomFilter = new GEOM_SelectionFilter( aStudy, true );
+ myGroupFilter = new SMESH_LogicalFilter(QList<SUIT_SelectionFilter*>(),
+ SMESH_LogicalFilter::LO_OR,
+ /*takeOwnership=*/true);
+ myGeomFilter = new GEOM_SelectionFilter( aStudy, true );
connect(mySMESHGUI, SIGNAL(SignalDeactivateActiveDialog()), this, SLOT(onDeactivate()));
connect(mySMESHGUI, SIGNAL(SignalCloseAllDialogs()), this, SLOT(reject()));
bool isUnique = false;
while (!isUnique) {
aName = theOperation + "_" + QString::number(++aNumber);
- isUnique = (aSet.count(aName.toLatin1().data()) == 0);
+ isUnique = (aSet.count(aName.toUtf8().data()) == 0);
}
return aName;
do
{
aResName = aPrefix + QString::number( i++ );
- anObj = aStudy->FindObject( aResName.toLatin1().data() );
+ anObj = aStudy->FindObject( aResName.toUtf8().data() );
}
while ( anObj );
myName->setText(aResName);
if( !aList.IsEmpty() )
{
QString aName = aList.First()->getName();
- myMeshGroupLine->setText(aName);
+ myMeshGroupLine->setText(aName);//??????
myMeshGroupLine->home( false );
}
myNameChanged = true;
myName->blockSignals(true);
- myName->setText(theGroup->GetName());
+ myName->setText(QString::fromUtf8(theGroup->GetName()));
myName->blockSignals(false);
myName->home(false);
SALOMEDS::Color aColor = theGroup->GetColor();
setGroupColor( aColor );
- myMeshGroupLine->setText(theGroup->GetName());
+ myMeshGroupLine->setText(QString::fromUtf8(theGroup->GetName()));
int aType = 0;
switch(theGroup->GetType()) {
{
myNameChanged = true;
myName->blockSignals(true);
- myName->setText(theGroup->GetName());
+ myName->setText(QString::fromUtf8(theGroup->GetName()));
myName->blockSignals(false);
}
SMESH::SMESH_GroupBase_var resultGroup;
bool isCreation, isConversion = false;
+ SUIT_OverrideCursor wc;
+
if (myGrpTypeId == 0) // standalone
{
if (!mySelectAll->isChecked() && !myElements->count() && myAllowElemsModif->isChecked())
if (myGeomObjects->length() == 1) {
myGroupOnGeom = myMesh->CreateGroupFromGEOM(aType,
- myName->text().toLatin1().data(),
+ myName->text().toUtf8().data(),
myGeomObjects[0]);
}
else {
aNewGeomGroupName += myName->text();
SALOMEDS::SObject_var aNewGroupSO =
geomGen->AddInStudy(aSMESHGen->GetCurrentStudy(), aGroupVar,
- aNewGeomGroupName.toLatin1().data(), aMeshShape);
+ aNewGeomGroupName.toUtf8().data(), aMeshShape);
}
myGroupOnGeom = myMesh->CreateGroupFromGEOM(aType,
- myName->text().toLatin1().data(),
+ myName->text().toUtf8().data(),
aGroupVar);
}
resultGroup = SMESH::SMESH_GroupBase::_narrow( myGroupOnGeom );
return false;
myGroupOnFilter = myMesh->CreateGroupFromFilter(aType,
- myName->text().toLatin1().data(),
+ myName->text().toUtf8().data(),
myFilter);
resultGroup = SMESH::SMESH_GroupBase::_narrow( myGroupOnFilter );
}
else
{
- resultGroup->SetName(myName->text().toLatin1().data());
+ resultGroup->SetName(myName->text().toUtf8().data());
if ( aMeshGroupSO )
{
- if(SMESH_Actor *anActor = SMESH::FindActorByEntry(aMeshGroupSO->GetID().c_str())) {
+ if ( SMESH_Actor *anActor = SMESH::FindActorByEntry(aMeshGroupSO->GetID().c_str()))
+ {
+ Handle(SALOME_InteractiveObject) anIO = anActor->getIO();
if ( isConversion ) { // need to reset TVisualObj and actor
- Handle(SALOME_InteractiveObject) anIO = anActor->getIO();
SMESH::RemoveVisualObjectWithActors( anIO->getEntry(), true );
SMESH::Update( anIO,true);
myActorsList.clear();
if ( !anActor ) return false;
myActorsList.append( anActor );
}
- anActor->setName(myName->text().toLatin1().data());
+ anActor->setName(myName->text().toUtf8().data());
QColor c;
int delta;
switch ( myTypeId ) {
anActor->SetSufaceColor( aColor.R, aColor.G, aColor.B, delta ); break;
break;
}
+ // update a visible group accoding to a changed contents
+ if ( !isConversion && anActor->GetVisibility() )
+ SMESH::Update( anIO, true );
}
}
}
SMESHGUI::Modified();
mySMESHGUI->updateObjBrowser(true);
- SMESH::UpdateView(); // asv: fix of BUG PAL5515
mySelectionMgr->clearSelected();
if( LightApp_Application* anApp =
//=================================================================================
// function : (onSelectGeomGroup)
-// purpose : Called when group type changed. on == "on group" or "on filter"
+// purpose : Called when group type changed. on == "on geometry" or "on filter"
//=================================================================================
void SMESHGUI_GroupDlg::onSelectGeomGroup(bool on)
{
else if (mySelectGroup->isChecked()) {
mySelectGroup->setChecked(false);
}
- if ( myGrpTypeId == 1 ) { // on group
+ if ( myGrpTypeId == 1 ) { // on geometry
myCurrentLineEdit = myGeomGroupLine;
updateGeomPopup();
}
myFilterDlg->Init( aType );
}
+ bool isStandalone = ( sender() == myFilterBtn );
+ myFilterDlg->SetEnabled( /*setInViewer=*/isStandalone,
+ /*diffSources=*/isStandalone );
myFilterDlg->SetMesh( myMesh );
myFilterDlg->SetSelection();
myFilterDlg->SetSourceWg( myElements, false );
+
myFilterDlg->show();
}
SMESH::SMESH_Group_var aGroup;
try {
if ( !theMesh->_is_nil() )
- aGroup = theMesh->CreateGroup( theType, theGroupName.toLatin1().data() );
+ aGroup = theMesh->CreateGroup( theType, theGroupName.toUtf8().data() );
}
catch( const SALOME::SALOME_Exception& S_ex ) {
SalomeApp_Tools::QtCatchCorbaException( S_ex );
QList<HypothesesSet*> myListOfHypothesesSets;
- void processHypothesisStatus(const int theHypStatus,
+ void processHypothesisStatus(const int theHypStatus,
SMESH::SMESH_Hypothesis_ptr theHyp,
- const bool theIsAddition)
+ const bool theIsAddition,
+ const char* theError = 0)
{
if (theHypStatus > SMESH::HYP_OK) {
// get Hyp name
QString aHypName ("NULL Hypothesis");
if (!CORBA::is_nil(theHyp)) {
_PTR(SObject) Shyp = SMESH::FindSObject(theHyp);
- if (Shyp)
+ if (Shyp) {
// name in study
aHypName = Shyp->GetName().c_str();
- else
+ }
+ else {
// label in xml file
- aHypName = GetHypothesisData(theHyp->GetName())->Label;
+ CORBA::String_var hypType = theHyp->GetName();
+ aHypName = GetHypothesisData( hypType.in() )->Label;
+ }
}
// message
else
aMsg = (isFatal ? "SMESH_CANT_RM_HYP" : "SMESH_RM_HYP_WRN");
- aMsg = QObject::tr(aMsg.toLatin1().data()).arg(aHypName) +
- QObject::tr(QString("SMESH_HYP_%1").arg(theHypStatus).toLatin1().data());
+ aMsg = QObject::tr(aMsg.toLatin1().data()).arg(aHypName);
- if ( theHypStatus == SMESH::HYP_HIDDEN_ALGO ) // PAL18501
- aMsg = aMsg.arg( GetHypothesisData(theHyp->GetName())->Dim[0] );
+ if ( theError && theError[0] )
+ {
+ aMsg += theError;
+ }
+ else
+ {
+ aMsg += QObject::tr(QString("SMESH_HYP_%1").arg(theHypStatus).toLatin1().data());
+ if ( theHypStatus == SMESH::HYP_HIDDEN_ALGO ) { // PAL18501
+ CORBA::String_var hypType = theHyp->GetName();
+ if ( HypothesisData* hd = GetHypothesisData( hypType.in() ))
+ aMsg = aMsg.arg( hd->Dim[0] );
+ }
+ }
SUIT_MessageBox::warning(SMESHGUI::desktop(),
QObject::tr("SMESH_WRN_WARNING"),
aMsg);
_PTR(SObject) SM = SMESH::FindSObject(aMesh);
GEOM::GEOM_Object_var aShapeObject = SMESH::GetShapeOnMeshOrSubMesh(SM);
try {
- res = aMesh->AddHypothesis(aShapeObject, aHyp);
+ CORBA::String_var error;
+ res = aMesh->AddHypothesis(aShapeObject, aHyp, error.out());
if (res < SMESH::HYP_UNKNOWN_FATAL) {
_PTR(SObject) aSH = SMESH::FindSObject(aHyp);
if (SM && aSH) {
}
if (res > SMESH::HYP_OK) {
wc.suspend();
- processHypothesisStatus(res, aHyp, true);
+ processHypothesisStatus(res, aHyp, true, error.in() );
wc.resume();
}
}
SMESH::SMESH_Mesh_var aMesh = aSubMesh->GetFather();
_PTR(SObject) SsubM = SMESH::FindSObject(aSubMesh);
GEOM::GEOM_Object_var aShapeObject = SMESH::GetShapeOnMeshOrSubMesh(SsubM);
- if (!aMesh->_is_nil() && SsubM && !aShapeObject->_is_nil()) {
- res = aMesh->AddHypothesis(aShapeObject, aHyp);
+ if (!aMesh->_is_nil() && SsubM && !aShapeObject->_is_nil())
+ {
+ CORBA::String_var error;
+ res = aMesh->AddHypothesis( aShapeObject, aHyp, error.out() );
if (res < SMESH::HYP_UNKNOWN_FATAL) {
_PTR(SObject) meshSO = SMESH::FindSObject(aMesh);
if (meshSO)
}
if (res > SMESH::HYP_OK) {
wc.suspend();
- processHypothesisStatus(res, aHyp, true);
+ processHypothesisStatus( res, aHyp, true, error.in() );
wc.resume();
}
}
#include <SUIT_ResourceMgr.h>
// Qt includes
-#include <QVBoxLayout>
+#include <QComboBox>
+#include <QCursor>
#include <QGridLayout>
-#include <QLabel>
-#include <QTabWidget>
#include <QGroupBox>
-#include <QToolButton>
-#include <QComboBox>
+#include <QLabel>
+#include <QListWidget>
#include <QMenu>
-#include <QCursor>
#include <QPushButton>
+#include <QTabWidget>
+#include <QToolButton>
+#include <QVBoxLayout>
+
+#include <Standard_Integer.hxx>
#define SPACING 6
#define MARGIN 11
SUIT_ResourceMgr* aResMgr = SUIT_Session::session()->resourceMgr();
QIcon aCreateIcon( aResMgr->loadPixmap( "SMESH", tr( "ICON_HYPO" ) ) );
QIcon aEditIcon( aResMgr->loadPixmap( "SMESH", tr( "ICON_HYPO_EDIT" ) ) );
+ QIcon aPlusIcon( aResMgr->loadPixmap( "SMESH", tr( "ICON_PLUS" ) ) );
+ QIcon aMinusIcon( aResMgr->loadPixmap( "SMESH", tr( "ICON_MINUS" ) ) );
// Algorifm
QLabel* anAlgoLbl = new QLabel( tr( "ALGORITHM" ), this );
- myHyp[ Algo ] = new QComboBox( this );
+ myHypCombo[ Algo ] = new QComboBox( this );
// Hypothesis
QLabel* aHypLbl = new QLabel( tr( "HYPOTHESIS" ), this );
- myHyp[ MainHyp ] = new QComboBox( this );
- myHyp[ MainHyp ]->setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed );
- myCreateHyp[ MainHyp ] = new QToolButton( this );
- myCreateHyp[ MainHyp ]->setIcon( aCreateIcon );
- myEditHyp[ MainHyp ] = new QToolButton( this );
- myEditHyp[ MainHyp ]->setIcon( aEditIcon );
-
+ myHypCombo[ MainHyp ] = new QComboBox( this );
+ myHypCombo[ MainHyp ]->setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed );
+ myCreateHypBtn[ MainHyp ] = new QToolButton( this );
+ myCreateHypBtn[ MainHyp ]->setIcon( aCreateIcon );
+ myEditHypBtn[ MainHyp ] = new QToolButton( this );
+ myEditHypBtn[ MainHyp ]->setIcon( aEditIcon );
+
// Line
QFrame* aLine = new QFrame( this );
aLine->setFrameStyle( QFrame::HLine | QFrame::Sunken );
-
+
// Add. hypothesis
QLabel* anAddHypLbl = new QLabel( tr( "ADD_HYPOTHESIS" ), this );
- myHyp[ AddHyp ] = new QComboBox( this );
- myHyp[ AddHyp ]->setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed );
- myCreateHyp[ AddHyp ] = new QToolButton( this );
- myCreateHyp[ AddHyp ]->setIcon( aCreateIcon );
- myEditHyp[ AddHyp ] = new QToolButton( this );
- myEditHyp[ AddHyp ]->setIcon( aEditIcon );
-
+ myHypCombo[ AddHyp ] = new QComboBox( this );
+ myHypCombo[ AddHyp ]->setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed );
+ myCreateHypBtn[ AddHyp ] = new QToolButton( this );
+ myCreateHypBtn[ AddHyp ]->setIcon( aCreateIcon );
+ myEditHypBtn[ AddHyp ] = new QToolButton( this );
+ myEditHypBtn[ AddHyp ]->setIcon( aEditIcon );
+ myEditHypBtn[ MoreAddHyp ] = new QToolButton( this );
+ myEditHypBtn[ MoreAddHyp ]->setIcon( aEditIcon );
+
+ myAddHypList = new QListWidget( this );
+ myMoreAddHypBtn = new QToolButton( this );
+ myMoreAddHypBtn->setIcon( aPlusIcon );
+ myLessAddHypBtn = new QToolButton( this );
+ myLessAddHypBtn->setIcon( aMinusIcon );
+
// Fill layout
QGridLayout* aLay = new QGridLayout( this );
aLay->setMargin( MARGIN );
aLay->setSpacing( SPACING );
aLay->addWidget( anAlgoLbl, 0, 0 );
- aLay->addWidget( myHyp[ Algo ], 0, 1 );
+ aLay->addWidget( myHypCombo[ Algo ], 0, 1 );
aLay->addWidget( aHypLbl, 1, 0 );
- aLay->addWidget( myHyp[ MainHyp ], 1, 1 );
- aLay->addWidget( myCreateHyp[ MainHyp ], 1, 2 );
- aLay->addWidget( myEditHyp[ MainHyp ], 1, 3 );
+ aLay->addWidget( myHypCombo[ MainHyp ], 1, 1 );
+ aLay->addWidget( myCreateHypBtn[ MainHyp ], 1, 2 );
+ aLay->addWidget( myEditHypBtn[ MainHyp ], 1, 3 );
aLay->addWidget( aLine, 2, 0, 1, 4 );
aLay->addWidget( anAddHypLbl, 3, 0 );
- aLay->addWidget( myHyp[ AddHyp ], 3, 1 );
- aLay->addWidget( myCreateHyp[ AddHyp ], 3, 2 );
- aLay->addWidget( myEditHyp[ AddHyp ], 3, 3 );
- aLay->addItem( new QSpacerItem( 0, 0, QSizePolicy::Fixed, QSizePolicy::Expanding ), 4, 0 );
-
+ aLay->addWidget( myHypCombo[ AddHyp ], 3, 1 );
+ aLay->addWidget( myCreateHypBtn[ AddHyp ], 3, 2 );
+ aLay->addWidget( myEditHypBtn[ AddHyp ], 3, 3 );
+ aLay->addWidget( myAddHypList, 4, 1, 2, 1 );
+ aLay->addWidget( myMoreAddHypBtn, 4, 2 );
+ aLay->addWidget( myEditHypBtn[ MoreAddHyp ], 4, 3 );
+ aLay->addWidget( myLessAddHypBtn, 5, 2 );
+ aLay->addItem( new QSpacerItem( 0, 0, QSizePolicy::Fixed, QSizePolicy::Expanding ), 6, 0 );
+
// Connect signals and slots
for ( int i = MainHyp; i <= AddHyp; i++ )
{
- connect( myCreateHyp[ i ], SIGNAL( clicked() ) , SLOT( onCreateHyp() ) );
- connect( myEditHyp[ i ] , SIGNAL( clicked() ) , SLOT( onEditHyp() ) );
- connect( myHyp[ i ] , SIGNAL( activated( int ) ), SLOT( onHyp( int ) ) );
+ connect( myCreateHypBtn[ i ], SIGNAL( clicked() ) , SLOT( onCreateHyp() ) );
+ connect( myEditHypBtn[ i ] , SIGNAL( clicked() ) , SLOT( onEditHyp() ) );
+ connect( myHypCombo[ i ] , SIGNAL( activated( int ) ), SLOT( onHyp( int ) ) );
}
- connect( myHyp[ Algo ], SIGNAL( activated( int ) ), SLOT( onHyp( int ) ) );
-
+ connect( myHypCombo[ Algo ], SIGNAL( activated( int ) ), SLOT( onHyp( int ) ) );
+
+ connect( myAddHypList, SIGNAL( currentRowChanged( int ) ), SLOT( onHyp( int ) ) );
+ connect( myEditHypBtn[ MoreAddHyp ], SIGNAL( clicked() ), SLOT( onEditHyp() ) );
+ connect( myMoreAddHypBtn, SIGNAL( clicked() ), SLOT( onMoreAddHyp() ));
+ connect( myLessAddHypBtn, SIGNAL( clicked() ), SLOT( onLessAddHyp() ));
+
// Initialize controls
-
+
setAvailableHyps( Algo, QStringList() );
setAvailableHyps( MainHyp, QStringList() );
setAvailableHyps( AddHyp, QStringList() );
{
}
+//================================================================================
+/*!
+ * \brief Adds an item in a control corresponding to \a type
+ * \param [in] txt - item text
+ * \param [in] type - HypType
+ * \param [in] index - index of item in a list of items
+ */
+//================================================================================
+
+void SMESHGUI_MeshTab::addItem( const QString& txt, const int type, const int index )
+{
+ if ( type <= AddHyp )
+ {
+ myHypCombo[ type ]->addItem( txt, QVariant( index ));
+ }
+ else
+ {
+ QListWidgetItem* item = new QListWidgetItem( txt, myAddHypList );
+ item->setData( Qt::UserRole, QVariant( index ));
+ }
+}
+
+//================================================================================
+/*!
+ * \brief Returns index of hyp of a given type
+ */
+//================================================================================
+
+int SMESHGUI_MeshTab::getCurrentIndex( const int type, const bool curByType ) const
+{
+ if ( type <= AddHyp )
+ {
+ return myHypCombo[ type ]->itemData( myHypCombo[ type ]->currentIndex() ).toInt();
+ }
+ else
+ {
+ int row = curByType ? ( type - AddHyp - 1 ) : myAddHypList->currentRow();
+ if ( QListWidgetItem* item = myAddHypList->item( row ))
+ return item->data( Qt::UserRole ).toInt();
+ }
+ return -1;
+}
+
//================================================================================
/*!
* \brief Sets available hypothesis or algorithms
//================================================================================
void SMESHGUI_MeshTab::setAvailableHyps( const int theId, const QStringList& theHyps )
{
- myAvailableHyps[ theId ] = theHyps;
+ myAvailableHypTypes[ theId ] = theHyps;
bool enable = ! theHyps.isEmpty();
if ( theId == Algo ) // fill list of algos
{
- myHyp[ Algo ]->clear();
+ myHypCombo[ Algo ]->clear();
if ( enable )
{
- myHyp[ Algo ]->addItem( tr( "NONE" ) );
- myHyp[ Algo ]->addItems( theHyps );
- myHyp[ Algo ]->setCurrentIndex( 0 );
+ addItem( tr( "NONE"), Algo, 0 );
+ for ( int i = 0, nbHyp = theHyps.count(); i < nbHyp; ++i )
+ addItem( theHyps[i], Algo, i+1 );
+ myHypCombo[ Algo ]->setCurrentIndex( 0 );
}
}
else // enable buttons
{
- myCreateHyp[ theId ]->setEnabled( enable );
- myEditHyp [ theId ]->setEnabled( false );
+ myCreateHypBtn[ theId ]->setEnabled( enable );
+ myEditHypBtn [ theId ]->setEnabled( false );
}
- myHyp[ theId ]->setEnabled( enable );
+ myHypCombo[ theId ]->setEnabled( enable );
}
//================================================================================
* \brief Sets existing hypothesis
* \param theId - identifier of hypothesis (main or additional, see HypType enumeration)
* \param theHyps - list of available hypothesis names
- * \param theDefaultAvlbl - \c true means that the algorithm can with w/o hypothesis
+ * \param theDefaultAvlbl - \c true means that the algorithm can work w/o hypothesis
* with some default parameters
*
* Sets existing main or additional hypothesis for this tab
{
if ( theId != Algo )
{
- bool enable = ! myAvailableHyps[ theId ].isEmpty();
- myHyp[ theId ]->clear();
+ bool enable = ! myAvailableHypTypes[ theId ].isEmpty();
+ myHypCombo[ theId ]->clear();
if ( enable )
{
QString none = tr( theDefaultAvlbl ? "DEFAULT" : ( theId == AddHyp ) ? "NONE" : "NONE" );
- myHyp[ theId ]->addItem( none );
- myHyp[ theId ]->addItems( theHyps );
- myHyp[ theId ]->setCurrentIndex( 0 );
+ addItem( none, theId, 0 );
+ for ( int i = 0, nbHyp = theHyps.count(); i < nbHyp; ++i )
+ addItem( theHyps[i], theId, i+1 );
+ myHypCombo[ theId ]->setCurrentIndex( 0 );
+ }
+ myHypCombo [ theId ]->setEnabled( enable );
+ myEditHypBtn[ theId ]->setEnabled( false );
+ if ( theId == AddHyp )
+ {
+ myAddHypList->clear();
+ myEditHypBtn[ MoreAddHyp ]->setEnabled( false );
+ myMoreAddHypBtn->setEnabled( false );
+ myLessAddHypBtn->setEnabled( false );
}
- myHyp [ theId ]->setEnabled( enable );
- myEditHyp[ theId ]->setEnabled( false );
}
}
//================================================================================
void SMESHGUI_MeshTab::addHyp( const int theId, const QString& theHyp )
{
- myHyp[ theId ]->addItem( theHyp );
- myHyp[ theId ]->setCurrentIndex( myHyp[ theId ]->count() - 1 );
- myEditHyp[ theId ]->setEnabled( true );
- myHyp[ theId ]->setEnabled( true );
+ int index = myHypCombo[ theId ]->count();
+ if ( theId == AddHyp )
+ index += myAddHypList->count();
+ addItem( theHyp, theId, index );
+ myHypCombo[ theId ]->setCurrentIndex( myHypCombo[ theId ]->count() - 1 );
+ myEditHypBtn[ theId ]->setEnabled( true );
+ myHypCombo[ theId ]->setEnabled( true );
+ if ( theId == AddHyp )
+ myMoreAddHypBtn->setEnabled( true );
}
//================================================================================
/*!
* \brief Renames hypothesis
- * \param theId - identifier of hypothesis (main or additional, see HypType enumeration)
- * \param theIndex - index of hypothesis to be renamed
- * \param theNewName - new name of hypothesis to be renamed
- *
+ * \param theId - identifier of hypothesis (main or additional, see HypType enumeration)
+ * \param theIndex - index of hypothesis to be renamed
+ * \param theNewName - new name of hypothesis to be renamed
+ *
* Renames hypothesis
*/
//================================================================================
-void SMESHGUI_MeshTab::renameHyp( const int theId,
- const int theIndex,
- const QString& theNewName )
-{
- if ( theIndex > 0 && theIndex < myHyp[ theId ]->count() )
- myHyp[ theId ]->setItemText( theIndex, theNewName );
-}
+// void SMESHGUI_MeshTab::renameHyp( const int theId,
+// const int theIndex,
+// const QString& theNewName )
+// {
+// if ( theIndex > 0 && theIndex < myHypCombo[ theId ]->count() )
+// myHypCombo[ theId ]->setItemText( theIndex, theNewName );
+// }
//================================================================================
/*!
- * \brief Sets current hypothesis
- * \param theId - identifier of hypothesis (main or additional, see HypType enumeration)
- * \param theIndex - index of hypothesis to be set as current
- *
- * Sets current hypothesis
+ * \brief Sets current hypothesis
+ * \param theId - identifier of hypothesis (main or additional, see HypType enumeration)
+ * \param theIndex - index of hypothesis to be set as current
+ *
+ * Sets current hypothesis
*/
//================================================================================
void SMESHGUI_MeshTab::setCurrentHyp( const int theId, const int theIndex )
{
- if ( theIndex >= 0 && theIndex < myHyp[ theId ]->count() )
+ if ( theId <= AddHyp )
{
- myHyp[ theId ]->setCurrentIndex( theIndex );
- if ( myEditHyp[ theId ] )
- myEditHyp[ theId ]->setEnabled( theIndex > 0 );
+ if ( theIndex >= 0 && theIndex < myHypCombo[ theId ]->count() )
+ {
+ myHypCombo[ theId ]->setCurrentIndex( theIndex );
+ if ( myEditHypBtn[ theId ] )
+ myEditHypBtn[ theId ]->setEnabled( theIndex > 0 );
+ if ( theId == AddHyp )
+ myMoreAddHypBtn ->setEnabled( theIndex > 0 );
+ }
+ }
+ else // more than one additional hyp assigned
+ {
+ // move a hyp from myHypCombo[ AddHyp ] to myAddHypList
+ for ( int i = 1, nb = myHypCombo[ AddHyp ]->count(); i < nb; ++i )
+ {
+ int curIndex = myHypCombo[ AddHyp ]->itemData( i ).toInt();
+ if ( theIndex == curIndex )
+ {
+ addItem( myHypCombo[ AddHyp ]->itemText( i ), theId, theIndex );
+ myHypCombo[ AddHyp ]->removeItem( i );
+ break;
+ }
+ }
}
}
* \retval int - index of current hypothesis
*
* Gets current hypothesis
+ * Use theId > AddHyp to get more than selected addetional hyps (see nbAddHypTypes()).
*/
//================================================================================
int SMESHGUI_MeshTab::currentHyp( const int theId ) const
{
- return myHyp[ theId ]->currentIndex();
+ return getCurrentIndex( theId, /*curByType=*/true );
+}
+
+//================================================================================
+/*!
+ * \brief Returns nb of selected supplementary additional hypotheses
+ *
+ * Access to their indices is via currentHyp( AddHyp + i ) where i is within the
+ * range 0 <= i < this->nbAddHypTypes()
+ */
+//================================================================================
+
+int SMESHGUI_MeshTab::nbAddHypTypes() const
+{
+ return myAddHypList->count();
}
//================================================================================
//================================================================================
void SMESHGUI_MeshTab::onCreateHyp()
{
- bool isMainHyp = sender() == myCreateHyp[ MainHyp ];
+ bool isMainHyp = ( sender() == myCreateHypBtn[ MainHyp ]);
QMenu aPopup( this );
QStringList aHypNames = isMainHyp ?
- myAvailableHyps[ MainHyp ] : myAvailableHyps[ AddHyp ];
+ myAvailableHypTypes[ MainHyp ] : myAvailableHypTypes[ AddHyp ];
QList<QAction*> actions;
for ( int i = 0, n = aHypNames.count(); i < n; i++ )
void SMESHGUI_MeshTab::onEditHyp()
{
const QObject* aSender = sender();
- int aHypType = aSender == myEditHyp[ MainHyp ] ? MainHyp : AddHyp;
- emit editHyp( aHypType, myHyp[ aHypType ]->currentIndex() - 1 ); // - 1 because there is NONE on the top
+ int aHypType = MainHyp;
+ for ( ; aHypType <= MoreAddHyp; ++aHypType )
+ if ( aSender == myEditHypBtn[ aHypType ])
+ break;
+ emit editHyp( Min( aHypType, AddHyp ),
+ getCurrentIndex( aHypType ) - 1 ); // - 1 because there is NONE on the top
}
//================================================================================
void SMESHGUI_MeshTab::onHyp( int theIndex )
{
const QObject* aSender = sender();
- if ( aSender == myHyp[ Algo ] )
+ if ( aSender == myHypCombo[ Algo ] )
+ {
emit selectAlgo( theIndex - 1 ); // - 1 because there is NONE on the top
- else {
- int anIndex = aSender == myHyp[ MainHyp ] ? MainHyp : AddHyp;
- myEditHyp[ anIndex ]->setEnabled( theIndex > 0 );
+ }
+ else if ( aSender == myAddHypList )
+ {
+ myEditHypBtn[ MoreAddHyp ]->setEnabled( theIndex >= 0 );
+ myLessAddHypBtn ->setEnabled( theIndex >= 0 );
+ }
+ else
+ {
+ int type = ( aSender == myHypCombo[ MainHyp ] ? MainHyp : AddHyp );
+ myEditHypBtn[ type ]->setEnabled( theIndex > 0 );
+
+ if ( type == AddHyp )
+ myMoreAddHypBtn ->setEnabled( theIndex > 0 );
+ }
+}
+
+//================================================================================
+/*!
+ * \brief Adds a current additional hyp to myAddHypList
+ *
+ * SLOT called when myMoreAddHypBtn ("plus") clicked
+ */
+//================================================================================
+
+void SMESHGUI_MeshTab::onMoreAddHyp()
+{
+ int hypIndex = currentHyp( AddHyp );
+ if ( hypIndex > 0 )
+ {
+ // move a hyp from myHypCombo[ AddHyp ] to myAddHypList
+ int comboIndex = myHypCombo[ AddHyp ]->currentIndex();
+ addItem( myHypCombo[ AddHyp ]->itemText( comboIndex ), MoreAddHyp, hypIndex );
+
+ myHypCombo[ AddHyp ]->removeItem( comboIndex );
+ myHypCombo[ AddHyp ]->setCurrentIndex( 0 );
+
+ myMoreAddHypBtn->setEnabled( false );
+ myEditHypBtn[ AddHyp ]->setEnabled( false );
+ }
+}
+
+//================================================================================
+/*!
+ * \brief Removes a current additional hyp from myAddHypList
+ *
+ * SLOT called when myLessAddHypBtn ("minus") clicked
+ */
+//================================================================================
+
+void SMESHGUI_MeshTab::onLessAddHyp()
+{
+ if ( QListWidgetItem * item = myAddHypList->currentItem() )
+ {
+ // move a hyp from myAddHypList to myHypCombo[ AddHyp ]
+ int hypIndex = item->data( Qt::UserRole ).toInt();
+ addItem( item->text(), AddHyp, hypIndex );
+ delete item;//myAddHypList->takeItem( myAddHypList->currentRow() );
}
}
*
* Resets all tab fields
*/
-//================================================================================
+//================================================================================
void SMESHGUI_MeshTab::reset()
{
for ( int i = Algo; i <= AddHyp; i++ )
{
- myHyp[ i ]->setCurrentIndex( 0 );
- if ( myEditHyp[ i ] )
- myEditHyp[ i ]->setEnabled( false );
+ myHypCombo[ i ]->setCurrentIndex( 0 );
+ if ( myEditHypBtn[ i ] )
+ myEditHypBtn[ i ]->setEnabled( false );
}
}
#include <QMap>
class SMESHGUI_MeshTab;
-class QTabWidget;
+class QAction;
class QComboBox;
-class QToolButton;
+class QListWidget;
class QMenu;
-class QAction;
+class QTabWidget;
+class QToolButton;
/*!
* \brief Dialog for mech creation or editing
void onGeomSelectionButton( bool );
void onChangedMeshType( const int );
-private:
+ private:
QMap<int, SMESHGUI_MeshTab*> myTabs;
QTabWidget* myTabWg;
QToolButton* myHypoSetButton;
};
/*!
- * \brief Tab for tab widget containing controls for definition of
+ * \brief Tab for tab widget containing controls for definition of
* algorithms and hypotheses
-*/
+ */
class SMESHGUI_EXPORT SMESHGUI_MeshTab : public QFrame
{
Q_OBJECT
-
-public:
+
+ public:
/*! To differ main algorithms, hypotheses and additional ones*/
enum HypType
- {
+ {
Algo = 0, //!< algorithms
MainHyp, //!< main hypothesis
- AddHyp //!< additional hypothesis
- };
-
+ AddHyp, //!< additional hypothesis
+ MoreAddHyp //! since several additional hypothesis are possible, the 2-nd, 3-d etc
+ // additional hypotheses are coded as being of HypType (AddHyp + 1), (AddHyp + 2) etc.
+ // Nb of HypType's after MainHyp is returned by SMESHGUI_MeshTab::nbAddHypTypes()
+ };
+
public:
SMESHGUI_MeshTab( QWidget* );
virtual ~SMESHGUI_MeshTab();
void setAvailableHyps( const int, const QStringList& );
void setExistingHyps( const int, const QStringList&, bool=false);
void addHyp( const int, const QString& );
- void renameHyp( const int, const int, const QString& );
+ //void renameHyp( const int, const int, const QString& );
void setCurrentHyp( const int, const int );
int currentHyp( const int ) const;
+ int nbAddHypTypes() const;
void reset();
signals:
void onCreateHyp();
void onEditHyp();
void onHyp( int );
-
-private:
- QMap<int, QComboBox*> myHyp;
- QMap<int, QToolButton*> myCreateHyp;
- QMap<int, QToolButton*> myEditHyp;
-
- QMap<int, QStringList> myAvailableHyps;
- QMap<int, QStringList> myExistingHyps;
+ void onMoreAddHyp();
+ void onLessAddHyp();
+
+private:
+
+ void addItem( const QString& txt, const int type, const int index );
+ int getCurrentIndex( const int type, const bool curByType=false) const;
+
+ QMap<int, QStringList> myAvailableHypTypes;
+
+ QMap<int, QComboBox*> myHypCombo;
+ QMap<int, QToolButton*> myCreateHypBtn;
+ QMap<int, QToolButton*> myEditHypBtn;
+
+ QToolButton* myMoreAddHypBtn;
+ QToolButton* myLessAddHypBtn;
+ QListWidget* myAddHypList; // 2-nd, etc. additional hyps
+
};
#endif // SMESHGUI_MESHDLG_H
THypList algoList;
existingHyps(3, Algo, pMesh, algoNames, algoList);
if (!algoList.empty()) {
- HypothesisData* algo = SMESH::GetHypothesisData( algoList[0].first->GetName() );
+ HypothesisData* algo =
+ SMESH::GetHypothesisData( SMESH::toQStr( algoList[0].first->GetName() ));
if ( algo &&
algo->InputTypes.empty() && // builds all dimensions it-self
!algo->IsSupportSubmeshes )
// if ( !geom->_is_nil() && geom->GetShapeType() >= GEOM::FACE ) { // WIRE, EDGE as well
existingHyps(2, Algo, pMesh, algoNames, algoList);
if (!algoList.empty()) {
- HypothesisData* algo = SMESH::GetHypothesisData( algoList[0].first->GetName() );
+ HypothesisData* algo =
+ SMESH::GetHypothesisData( SMESH::toQStr( algoList[0].first->GetName() ));
if ( algo &&
algo->InputTypes.empty() && // builds all dimensions it-self
!algo->IsSupportSubmeshes )
myDlg->objectWg( SMESHGUI_MeshDlg::Geom, SMESHGUI_MeshDlg::Btn )->hide();
myDlg->updateGeometry();
myDlg->adjustSize();
- readMesh();
myIsMesh = submeshVar->_is_nil();
+ readMesh();
}
else
myDlg->reset();
* \param theAlgoData - to select hypos able to be used by this algo (optional)
*
* Gets existing (i.e. already created) hypotheses or algorithm in accordance with
- * input parameters
+ * input parameters.
+ *
+ * WARNING: when using this method to get hyps existing in Mesh component,
+ * call availableHyps() before in order to get only hyps of available types
+ * that was filtered by availableHyps()
*/
//================================================================================
void SMESHGUI_MeshOp::existingHyps( const int theDim,
_PTR(SObject) theFather,
QStringList& theHyps,
THypList& theHypList,
- HypothesisData* theAlgoData)
+ HypothesisData* theAlgoData) const
{
// Clear hypoheses list
theHyps.clear();
if ( !theFather )
return;
- const bool isAux = ( theHypType == AddHyp );
-
_PTR(SObject) aHypRoot;
_PTR(GenericAttribute) anAttr;
_PTR(AttributeName) aName;
_PTR(AttributeIOR) anIOR;
- bool isMesh = !_CAST( SComponent, theFather );
+ const bool isMesh = !_CAST( SComponent, theFather );
int aPart = -1;
if ( isMesh )
aPart = theHypType == Algo ? SMESH::Tag_RefOnAppliedAlgorithms : SMESH::Tag_RefOnAppliedHypothesis;
else
aPart = theHypType == Algo ? SMESH::Tag_AlgorithmsRoot : SMESH::Tag_HypothesisRoot;
+ const bool isAux = ( theHypType == AddHyp );
+ const bool allHyps = ( !isMesh && theHypType != Algo && theDim > -1);
+
if ( theFather->FindSubObject( aPart, aHypRoot ) )
{
_PTR(ChildIterator) anIter =
CORBA::String_var hypType = aHypVar->GetName();
HypothesisData* aData = SMESH::GetHypothesisData( hypType.in() );
if ( !aData) continue;
- if ( ( theDim == -1 || aData->Dim.contains( theDim ) ) &&
- ( isCompatible ( theAlgoData, aData, theHypType )) &&
- ( theHypType == Algo || isAux == aData->IsAuxOrNeedHyp ))
+ if (( theDim == -1 || aData->Dim.contains( theDim ) ) &&
+ ( isCompatible ( theAlgoData, aData, theHypType )) &&
+ ( theHypType == Algo || isAux == aData->IsAuxOrNeedHyp ) &&
+ ( !allHyps || myAvailableHypData[theDim][theHypType].count(aData) ))
{
std::string aHypName = aName->Value();
theHyps.append( aHypName.c_str() );
return hyp;
}
+//================================================================================
+/*!
+ * \brief initialize a hypothesis creator
+ */
+//================================================================================
+
+void SMESHGUI_MeshOp::initHypCreator( SMESHGUI_GenericHypothesisCreator* theCreator )
+{
+ if ( !theCreator ) return;
+
+ // Set shapes, of mesh and sub-mesh if any
+
+ // get Entry of the Geom object
+ QString aGeomEntry = "";
+ QString aMeshEntry = "";
+ QString anObjEntry = "";
+ aGeomEntry = myDlg->selectedObject( SMESHGUI_MeshDlg::Geom );
+ aMeshEntry = myDlg->selectedObject( SMESHGUI_MeshDlg::Mesh );
+ anObjEntry = myDlg->selectedObject( SMESHGUI_MeshDlg::Obj );
+
+ if ( myToCreate && myIsMesh )
+ aMeshEntry = aGeomEntry;
+
+ if ( aMeshEntry != aGeomEntry ) { // Get Geom object from Mesh of a sub-mesh being edited
+ _PTR(SObject) pObj = studyDS()->FindObjectID( aMeshEntry.toLatin1().data() );
+ GEOM::GEOM_Object_var aGeomVar = SMESH::GetShapeOnMeshOrSubMesh( pObj );
+ aMeshEntry = ( aGeomVar->_is_nil() ) ? QString() : SMESH::toQStr( aGeomVar->GetStudyEntry() );
+ }
+
+ if ( aMeshEntry == "" && aGeomEntry == "" ) { // get geom of an object being edited
+ _PTR(SObject) pObj = studyDS()->FindObjectID( anObjEntry.toLatin1().data() );
+ bool isMesh;
+ GEOM::GEOM_Object_var aGeomVar = SMESH::GetShapeOnMeshOrSubMesh( pObj, &isMesh );
+ if ( !aGeomVar->_is_nil() )
+ {
+ aGeomEntry = SMESH::toQStr( aGeomVar->GetStudyEntry() );
+ if ( isMesh )
+ aMeshEntry = aGeomEntry;
+ }
+ }
+
+ if ( anObjEntry != "" && aGeomEntry != "" && aMeshEntry == "" ) {
+ // take geometry from submesh being created
+ _PTR(SObject) pObj = studyDS()->FindObjectID( anObjEntry.toLatin1().data() );
+ if ( pObj ) {
+ // if current object is sub-mesh
+ SMESH::SMESH_subMesh_var aSubMeshVar =
+ SMESH::SMESH_subMesh::_narrow( _CAST( SObject,pObj )->GetObject() );
+ if ( !aSubMeshVar->_is_nil() ) {
+ SMESH::SMESH_Mesh_var aMeshVar = aSubMeshVar->GetFather();
+ if ( !aMeshVar->_is_nil() ) {
+ _PTR(SObject) aMeshSO = SMESH::FindSObject( aMeshVar );
+ GEOM::GEOM_Object_var aGeomVar = SMESH::GetShapeOnMeshOrSubMesh( aMeshSO );
+ if ( !aGeomVar->_is_nil() )
+ aMeshEntry = SMESH::toQStr( aGeomVar->GetStudyEntry() );
+ }
+ }
+ }
+ }
+
+ theCreator->setShapeEntry( aGeomEntry );
+ if ( aMeshEntry != "" )
+ theCreator->setMainShapeEntry( aMeshEntry );
+}
+
//================================================================================
/*!
* \Brief Returns tab dimention
myDim = theDim;
myType = theType;
+
+ // get a unique hyp name
QStringList aHypNames;
TDim2Type2HypList::const_iterator aDimIter = myExistingHyps.begin();
for ( ; aDimIter != myExistingHyps.end(); aDimIter++) {
SMESHGUI_GenericHypothesisCreator* aCreator = SMESH::GetHypothesisCreator(theTypeName);
// Create hypothesis
- if (aCreator) {
+ if (aCreator)
+ {
// Get parameters appropriate to initialize a new hypothesis
SMESH::SMESH_Hypothesis_var initParamHyp =
getInitParamsHypothesis(theTypeName, aData->ServerLibName);
removeCustomFilters(); // Issue 0020170
- // Get Entry of the Geom object
- QString aGeomEntry = "";
- QString aMeshEntry = "";
- QString anObjEntry = "";
- aGeomEntry = myDlg->selectedObject( SMESHGUI_MeshDlg::Geom );
- aMeshEntry = myDlg->selectedObject( SMESHGUI_MeshDlg::Mesh );
- anObjEntry = myDlg->selectedObject( SMESHGUI_MeshDlg::Obj );
-
- if ( myToCreate && myIsMesh )
- aMeshEntry = aGeomEntry;
-
- if ( aMeshEntry != aGeomEntry ) { // Get Geom object from Mesh of a sub-mesh being edited
- _PTR(SObject) pObj = studyDS()->FindObjectID( aMeshEntry.toLatin1().data() );
- GEOM::GEOM_Object_var aGeomVar = SMESH::GetShapeOnMeshOrSubMesh( pObj );
- aMeshEntry = ( aGeomVar->_is_nil() ) ? "" : aMeshEntry = aGeomVar->GetStudyEntry();
- }
-
- if ( aMeshEntry == "" && aGeomEntry == "" ) { // get geom of an object being edited
- _PTR(SObject) pObj = studyDS()->FindObjectID( anObjEntry.toLatin1().data() );
- bool isMesh;
- GEOM::GEOM_Object_var aGeomVar = SMESH::GetShapeOnMeshOrSubMesh( pObj, &isMesh );
- if ( !aGeomVar->_is_nil() )
- {
- aGeomEntry = aGeomVar->GetStudyEntry();
- if ( isMesh )
- aMeshEntry = aGeomEntry;
- }
- }
-
- if ( anObjEntry != "" && aGeomEntry != "" && aMeshEntry == "" ) {
- // take geometry from submesh being created
- _PTR(SObject) pObj = studyDS()->FindObjectID( anObjEntry.toLatin1().data() );
- if ( pObj ) {
- // if current object is sub-mesh
- SMESH::SMESH_subMesh_var aSubMeshVar =
- SMESH::SMESH_subMesh::_narrow( _CAST( SObject,pObj )->GetObject() );
- if ( !aSubMeshVar->_is_nil() ) {
- SMESH::SMESH_Mesh_var aMeshVar = aSubMeshVar->GetFather();
- if ( !aMeshVar->_is_nil() ) {
- _PTR(SObject) aMeshSO = SMESH::FindSObject( aMeshVar );
- GEOM::GEOM_Object_var aGeomVar = SMESH::GetShapeOnMeshOrSubMesh( aMeshSO );
- if ( !aGeomVar->_is_nil() )
- aMeshEntry = aGeomVar->GetStudyEntry();
- }
- }
- }
- }
+ // set shapes, of mesh and sub-mesh if any
+ initHypCreator( aCreator );
- aCreator->setShapeEntry( aGeomEntry );
- if ( aMeshEntry != "" )
- aCreator->setMainShapeEntry( aMeshEntry );
myDlg->setEnabled( false );
aCreator->create(initParamHyp, aHypName, myDlg, this, SLOT( onHypoCreated( int ) ) );
dialog = true;
if ( aHyp->_is_nil() )
return;
- SMESHGUI_GenericHypothesisCreator* aCreator = SMESH::GetHypothesisCreator(aHyp->GetName());
+ SMESHGUI_GenericHypothesisCreator* aCreator =
+ SMESH::GetHypothesisCreator( SMESH::toQStr( aHyp->GetName() ));
if ( aCreator )
{
- // Get initial parameters
+ // set initial parameters
SMESH::SMESH_Hypothesis_var initParamHyp =
- getInitParamsHypothesis( aHyp->GetName(), aHyp->GetLibName());
+ getInitParamsHypothesis( SMESH::toQStr( aHyp->GetName() ),
+ SMESH::toQStr( aHyp->GetLibName() ));
aCreator->setInitParamsHypothesis( initParamHyp );
- // Get Entry of the Geom object
- QString aGeomEntry = "";
- QString aMeshEntry = "";
- QString anObjEntry = "";
- aGeomEntry = myDlg->selectedObject( SMESHGUI_MeshDlg::Geom );
- aMeshEntry = myDlg->selectedObject( SMESHGUI_MeshDlg::Mesh );
- anObjEntry = myDlg->selectedObject( SMESHGUI_MeshDlg::Obj );
-
- if ( myToCreate && myIsMesh )
- aMeshEntry = aGeomEntry;
+ // set shapes, of mesh and sub-mesh if any
+ initHypCreator( aCreator );
- if ( aMeshEntry != aGeomEntry ) { // Get Geom object from Mesh of a sub-mesh being edited
- _PTR(SObject) pObj = studyDS()->FindObjectID( aMeshEntry.toLatin1().data() );
- GEOM::GEOM_Object_var aGeomVar = SMESH::GetShapeOnMeshOrSubMesh( pObj );
- aMeshEntry = ( aGeomVar->_is_nil() ) ? "" : aMeshEntry = aGeomVar->GetStudyEntry();
- }
-
- if ( aMeshEntry == "" && aGeomEntry == "" ) { // get geom of an object being edited
- _PTR(SObject) pObj = studyDS()->FindObjectID( anObjEntry.toLatin1().data() );
- bool isMesh;
- GEOM::GEOM_Object_var aGeomVar = SMESH::GetShapeOnMeshOrSubMesh( pObj, &isMesh );
- if ( !aGeomVar->_is_nil() )
- {
- aGeomEntry = aGeomVar->GetStudyEntry();
- if ( isMesh )
- aMeshEntry = aGeomEntry;
- }
- }
-
- if ( anObjEntry != "" && aGeomEntry != "" && aMeshEntry == "" ) {
- // take geometry from submesh being created
- _PTR(SObject) pObj = studyDS()->FindObjectID( anObjEntry.toLatin1().data() );
- if ( pObj ) {
- // if current object is sub-mesh
- SMESH::SMESH_subMesh_var aSubMeshVar =
- SMESH::SMESH_subMesh::_narrow( _CAST( SObject,pObj )->GetObject() );
- if ( !aSubMeshVar->_is_nil() ) {
- SMESH::SMESH_Mesh_var aMeshVar = aSubMeshVar->GetFather();
- if ( !aMeshVar->_is_nil() ) {
- _PTR(SObject) aMeshSO = SMESH::FindSObject( aMeshVar );
- GEOM::GEOM_Object_var aGeomVar = SMESH::GetShapeOnMeshOrSubMesh( aMeshSO );
- if ( !aGeomVar->_is_nil() )
- aMeshEntry = aGeomVar->GetStudyEntry();
- }
- }
- }
- }
-
- aCreator->setShapeEntry( aGeomEntry );
- if ( aMeshEntry != "" )
- aCreator->setMainShapeEntry( aMeshEntry );
removeCustomFilters(); // Issue 0020170
myDlg->setEnabled( false );
+
aCreator->edit( aHyp.in(), aHypItem.second, dlg(), this, SLOT( onHypoEdited( int ) ) );
}
}
const bool isSubmesh = ( myToCreate ? !myIsMesh : myDlg->isObjectShown( SMESHGUI_MeshDlg::Mesh ));
- // if ( aDim >= SMESH::DIM_2D ) myAvailableHypData[ aDim ][ Algo ] = myFilteredAlgoData[aDim];
HypothesisData* algoData = hypData( aDim, Algo, theIndex );
HypothesisData* algoByDim[4];
algoByDim[ aDim ] = algoData;
{
if ( !isAccessibleDim( dim ))
continue;
- for ( int type = MainHyp; type < NbHypTypes; type++ )
+ for ( int dlgType = MainHyp; dlgType < nbDlgHypTypes(dim); dlgType++ )
{
+ const int type = Min( dlgType, AddHyp );
myAvailableHypData[ dim ][ type ].clear();
QStringList anAvailable, anExisting;
HypothesisData* curAlgo = algoByDim[ dim ];
- int hypIndex = currentHyp( dim, type );
+ int hypIndex = currentHyp( dim, dlgType );
SMESH::SMESH_Hypothesis_var curHyp;
if ( hypIndex >= 0 && hypIndex < myExistingHyps[ dim ][ type ].count() )
if ( !myToCreate && !curAlgo && !curHyp->_is_nil() ) { // edition, algo not selected
// try to find algo by selected hypothesis in order to keep it selected
bool algoDeselectedByUser = ( theDim < 0 && aDim == dim );
- CORBA::String_var curHypType = curHyp->GetName();
+ QString curHypType = SMESH::toQStr( curHyp->GetName() );
if ( !algoDeselectedByUser &&
- myObjHyps[ dim ][ type ].count() > 0 &&
- !strcmp( curHypType, myObjHyps[ dim ][ type ].first().first->GetName()) )
+ myObjHyps[ dim ][ type ].count() > 0 &&
+ curHypType == SMESH::toQStr( myObjHyps[ dim ][ type ].first().first->GetName()) )
{
HypothesisData* hypData = SMESH::GetHypothesisData( curHyp->GetName() );
for (int i = 0; i < myAvailableHypData[ dim ][ Algo ].count(); ++i) {
if ( !isCompatible( curAlgo, hypData, type ))
curHyp = SMESH::SMESH_Hypothesis::_nil();
}
- existingHyps( dim, type, pObj, anExisting, myExistingHyps[ dim ][ type ], curAlgo);
availableHyps( dim, type, anAvailable, myAvailableHypData[ dim ][ type ], curAlgo);
+ existingHyps( dim, type, pObj, anExisting, myExistingHyps[ dim ][ type ], curAlgo);
defaulHypAvlbl = (type == MainHyp && !curAlgo->IsAuxOrNeedHyp );
}
// set list of hypotheses
SMESH::SetName( aMeshSO, myDlg->objectText( SMESHGUI_MeshDlg::Obj ) );
}
- for ( int aDim = SMESH::DIM_0D; aDim <= SMESH::DIM_3D; aDim++ ) {
+ for ( int aDim = SMESH::DIM_0D; aDim <= SMESH::DIM_3D; aDim++ )
+ {
if ( !isAccessibleDim( aDim )) continue;
// assign hypotheses
- for ( int aHypType = MainHyp; aHypType <= AddHyp; aHypType++ ) {
- int aHypIndex = currentHyp( aDim, aHypType );
- if ( aHypIndex >= 0 && aHypIndex < myExistingHyps[ aDim ][ aHypType ].count() ) {
- SMESH::SMESH_Hypothesis_var aHypVar = myExistingHyps[ aDim ][ aHypType ][ aHypIndex ].first;
+ for ( int dlgType = MainHyp; dlgType < nbDlgHypTypes(aDim); dlgType++ )
+ {
+ const int aHypIndex = currentHyp( aDim, dlgType );
+ const int aHypType = Min( dlgType, AddHyp );
+ if ( aHypIndex >= 0 && aHypIndex < myExistingHyps[ aDim ][ aHypType ].count() )
+ {
+ SMESH::SMESH_Hypothesis_var aHypVar =
+ myExistingHyps[ aDim ][ aHypType ][ aHypIndex ].first;
if ( !aHypVar->_is_nil() )
SMESH::AddHypothesisOnMesh( aMeshVar, aHypVar );
}
if ( !anAlgoVar->_is_nil() )
SMESH::AddHypothesisOnSubMesh( aSubMeshVar, anAlgoVar );
// assign hypotheses
- for ( int aHypType = MainHyp; aHypType <= AddHyp; aHypType++ )
+ for ( int dlgType = MainHyp; dlgType < nbDlgHypTypes(aDim); dlgType++ )
{
- int aHypIndex = currentHyp( aDim, aHypType );
+ const int aHypIndex = currentHyp( aDim, dlgType );
+ const int aHypType = Min( dlgType, AddHyp );
if ( aHypIndex >= 0 && aHypIndex < myExistingHyps[ aDim ][ aHypType ].count() )
{
SMESH::SMESH_Hypothesis_var aHypVar =
return myDlg->tab( theDim )->currentHyp( theHypType ) - 1;
}
+//================================================================================
+/*!
+ * \brief Checks if a hypothesis is selected
+ */
+//================================================================================
+
+bool SMESHGUI_MeshOp::isSelectedHyp( int theDim, int theHypType, int theIndex) const
+{
+ if ( theHypType < AddHyp ) // only one hyp can be selected
+ return currentHyp( theDim, theHypType ) == theIndex;
+
+ for ( int dlgHypType = AddHyp; dlgHypType < nbDlgHypTypes( theDim ); ++dlgHypType )
+ if ( currentHyp( theDim, dlgHypType ) == theIndex )
+ return true;
+
+ return false;
+}
+
+//================================================================================
+/*!
+ * \brief Returns nb of HypType's taking into account possible several
+ * selected additional hypotheses which are coded as additional HypType's.
+ */
+//================================================================================
+
+int SMESHGUI_MeshOp::nbDlgHypTypes( const int dim ) const
+{
+ return NbHypTypes + myDlg->tab( dim )->nbAddHypTypes();
+}
+
//================================================================================
/*!
* \brief Returns true if hypotheses of given dim can be assigned
for ( ; anIter != aHypVarList.end(); anIter++)
{
SMESH::SMESH_Hypothesis_var aHypVar = (*anIter).first;
- CORBA::String_var aName = aHypVar->GetName();
- if ( !aHypVar->_is_nil() && !strcmp(aHypName.toLatin1().data(), aName) )
+ if ( !aHypVar->_is_nil() && aHypName == SMESH::toQStr( aHypVar->GetName() ))
{
anAlgoVar = aHypVar;
break;
for ( anIter = aNewHypVarList.begin(); anIter != aNewHypVarList.end(); ++anIter )
{
SMESH::SMESH_Hypothesis_var aHypVar = (*anIter).first;
- CORBA::String_var aName = aHypVar->GetName();
- if ( !aHypVar->_is_nil() && !strcmp(aHypName.toLatin1().data(), aName) )
+ if ( !aHypVar->_is_nil() && aHypName == SMESH::toQStr( aHypVar->GetName() ))
{
anAlgoVar = aHypVar;
break;
SMESH::SMESH_Hypothesis_var aVar = myObjHyps[ dim ][ Algo ].first().first;
HypothesisData* algoData = SMESH::GetHypothesisData( aVar->GetName() );
aHypIndex = myAvailableHypData[ dim ][ Algo ].indexOf ( algoData );
-// if ( aHypIndex < 0 && algoData ) {
-// // assigned algo is incompatible with other algorithms
-// myAvailableHypData[ dim ][ Algo ].push_back( algoData );
-// aHypIndex = myAvailableHypData[ dim ][ hypType ].count() - 1;
-// }
+ // if ( aHypIndex < 0 && algoData ) {
+ // // assigned algo is incompatible with other algorithms
+ // myAvailableHypData[ dim ][ Algo ].push_back( algoData );
+ // aHypIndex = myAvailableHypData[ dim ][ hypType ].count() - 1;
+ // }
algoFound = ( aHypIndex > -1 );
}
setCurrentHyp( dim, Algo, aHypIndex );
{
// get hypotheses
existingHyps( dim, hypType, pObj, anExisting, myObjHyps[ dim ][ hypType ] );
- // find index of requered hypothesis among existing ones for this dimension and type
- int aHypIndex = -1;
- if ( myObjHyps[ dim ][ hypType ].count() > 0 ) {
- aHypIndex = find( myObjHyps[ dim ][ hypType ].first().first,
- myExistingHyps[ dim ][ hypType ] );
+ for ( int i = 0, nb = myObjHyps[ dim ][ hypType ].count(); i < nb; ++i )
+ {
+ // find index of required hypothesis among existing ones for this dimension and type
+ int aHypIndex = find( myObjHyps[ dim ][ hypType ][ i ].first,
+ myExistingHyps[ dim ][ hypType ] );
if ( aHypIndex < 0 ) {
// assigned hypothesis is incompatible with the algorithm
if ( currentHyp( dim, Algo ) < 0 )
{ // none algo selected; it is edition for sure, of submesh maybe
hypWithoutAlgo = true;
- myExistingHyps[ dim ][ hypType ].push_back( myObjHyps[ dim ][ hypType ].first() );
+ myExistingHyps[ dim ][ hypType ].push_back( myObjHyps[ dim ][ hypType ][ i ] );
+ anExisting.push_back( myObjHyps[ dim ][ hypType ][ i ].second );
aHypIndex = myExistingHyps[ dim ][ hypType ].count() - 1;
myDlg->tab( dim )->setExistingHyps( hypType, anExisting );
}
}
+ setCurrentHyp( dim, hypType + i, aHypIndex );
+
+ if ( hypType == MainHyp ) break; // only one main hyp allowed
}
- setCurrentHyp( dim, hypType, aHypIndex );
}
}
// make available other hyps of same type as one without algo
//================================================================================
/*!
* \brief Gets name of object
- * \param theSO - SObject
- * \retval QString - name of object
+ * \param theSO - SObject
+ * \retval QString - name of object
*
* Gets name of object
*/
myObjHyps[ dim ][ Algo ].append( THypItem( anAlgoVar, aName) );
}
- // assign hypotheses
+ // remove deselected hypotheses
for ( int hypType = MainHyp; hypType <= AddHyp; hypType++ )
{
- int aNewHypIndex = currentHyp( dim, hypType );
- int anOldHypIndex = -1;
-
- // remove old hypotheses
- if ( myObjHyps[ dim ][ hypType ].count() > 0 )
+ for ( int i = 0, nb = myObjHyps[ dim ][ hypType ].count(); i < nb; ++i )
{
- anOldHypIndex = find( myObjHyps[ dim ][ hypType ].first().first,
- myExistingHyps[ dim ][ hypType ] );
- if ( aNewHypIndex != anOldHypIndex || // different hyps
- anOldHypIndex == -1 ) // hyps of different algos
+ SMESH::SMESH_Hypothesis_var hyp = myObjHyps[ dim ][ hypType ][ i ].first;
+ int hypIndex = this->find( hyp, myExistingHyps[ dim ][ hypType ]);
+ if ( !isSelectedHyp( dim, hypType, hypIndex ) && !hyp->_is_nil() )
{
- SMESH::RemoveHypothesisOrAlgorithmOnMesh
- ( pObj, myObjHyps[ dim ][ hypType ].first().first );
- myObjHyps[ dim ][ hypType ].clear();
+ SMESH::RemoveHypothesisOrAlgorithmOnMesh( pObj, hyp );
}
}
-
- // assign new hypotheses
- if ( aNewHypIndex != anOldHypIndex && aNewHypIndex > -1 )
+ }
+ // assign newly selected hypotheses
+ for ( int dlgType = MainHyp; dlgType < nbDlgHypTypes(dim); dlgType++ )
+ {
+ const int curIndex = currentHyp( dim, dlgType );
+ const int hypType = Min( dlgType, AddHyp );
+ if ( curIndex >= 0 && curIndex < myExistingHyps[ dim ][ hypType ].count() )
{
- if ( isMesh )
- SMESH::AddHypothesisOnMesh
- (aMeshVar, myExistingHyps[ dim ][ hypType ][ aNewHypIndex ].first );
- else if ( !aSubMeshVar->_is_nil() )
- SMESH::AddHypothesisOnSubMesh
- ( aSubMeshVar, myExistingHyps[ dim ][ hypType ][ aNewHypIndex ].first );
+ SMESH::SMESH_Hypothesis_var hyp = myExistingHyps[ dim ][ hypType ][ curIndex ].first;
+
+ bool isAssigned = ( this->find( hyp, myObjHyps[ dim ][ hypType ]) >= 0 );
+ if ( !isAssigned )
+ {
+ if ( isMesh )
+ SMESH::AddHypothesisOnMesh (aMeshVar, hyp );
+ else if ( !aSubMeshVar->_is_nil() )
+ SMESH::AddHypothesisOnSubMesh ( aSubMeshVar, hyp );
+ }
}
- // reread all hypotheses of mesh if necessary
+ // reread all hypotheses of mesh
QStringList anExisting;
existingHyps( dim, hypType, pObj, anExisting, myObjHyps[ dim ][ hypType ] );
}
GEOM::GEOM_Object_var aGeomVar = myShapeByMeshOp->GetShape();
if ( !aGeomVar->_is_nil() )
{
- QString ID = aGeomVar->GetStudyEntry();
+ QString ID = SMESH::toQStr( aGeomVar->GetStudyEntry() );
if ( _PTR(SObject) aGeomSO = studyDS()->FindObjectID( ID.toLatin1().data() )) {
selectObject( aGeomSO );
selectionDone();
if ( anCompareType == "ANY" )
{
- for ( int dim = SMESH::DIM_2D; dim <= SMESH::DIM_3D; dim++ )
+ for ( int dim = SMESH::DIM_3D; dim >= SMESH::DIM_2D; dim-- )
{
isNone = currentHyp( dim, Algo ) < 0;
isAvailableChoiceAlgo = false;
}
myAvailableHypData[dim][Algo].clear();
anAvailableAlgs.clear();
- for (int i = 0 ; i < anAvailableAlgsData.count(); i++)
+ if ( dim != SMESH::DIM_2D || currentHyp( SMESH::DIM_3D, Algo ) < 0 ||
+ myAvailableHypData[SMESH::DIM_3D][Algo].empty() ||
+ !myAvailableHypData[SMESH::DIM_3D][Algo].at( currentHyp( SMESH::DIM_3D, Algo ) )->InputTypes.isEmpty() )
{
- HypothesisData* curAlgo = anAvailableAlgsData.at(i);
- if ( aGeomVar->_is_nil() ||
- SMESH::IsApplicable( curAlgo->TypeName, aGeomVar, toCheckIsApplicableToAll ))
+ for (int i = 0 ; i < anAvailableAlgsData.count(); i++)
{
- anAvailableAlgs.append( curAlgo->Label );
- myAvailableHypData[dim][Algo].append( curAlgo );
+ HypothesisData* curAlgo = anAvailableAlgsData.at(i);
+ if ( aGeomVar->_is_nil() ||
+ SMESH::IsApplicable( curAlgo->TypeName, aGeomVar, toCheckIsApplicableToAll ))
+ {
+ anAvailableAlgs.append( curAlgo->Label );
+ myAvailableHypData[dim][Algo].append( curAlgo );
+ }
}
- }
- if ( !isNone && algoCur ) {
- for (int i = 0 ; i < myAvailableHypData[dim][Algo].count(); i++)
- {
- HypothesisData* algoAny = myAvailableHypData[dim][Algo].at(i);
- if ( algoAny->Label == algoCur->Label ){
- isAvailableChoiceAlgo = true;
- anCurrentAvailableAlgo = i;
- break;
+ if ( !isNone && algoCur ) {
+ for (int i = 0 ; i < myAvailableHypData[dim][Algo].count(); i++)
+ {
+ HypothesisData* algoAny = myAvailableHypData[dim][Algo].at(i);
+ if ( algoAny->Label == algoCur->Label ){
+ isAvailableChoiceAlgo = true;
+ anCurrentAvailableAlgo = i;
+ break;
+ }
}
}
- }
- else if ( !isNone ) {
- isAvailableChoiceAlgo = true;
- anCurrentAvailableAlgo = currentHyp( dim, Algo );
+ else if ( !isNone ) {
+ isAvailableChoiceAlgo = true;
+ anCurrentAvailableAlgo = currentHyp( dim, Algo );
+ }
}
myDlg->tab( dim )->setAvailableHyps( Algo, anAvailableAlgs );
if ( isAvailableChoiceAlgo )
{
for (int i = SMESH::DIM_0D; i <= myMaxShapeDim; i++)
{
- for (int j = 0; j < myAvailableHypData[i][Algo].count(); ++j) {
- HypothesisData* aCurAlgo = hypData( i, Algo, j );
- if ( aCurAlgo->Label == algoDataIn->Label ){
- isAvailable = true;
- break;
+ if ( myAvailableHypData[i][Algo].count() == 0 ) {
+ availableHyps( i, Algo, anAvailableAlgs, anAvailableAlgsData );
+ for ( int j = 0 ; j < anAvailableAlgsData.count(); j++ )
+ {
+ HypothesisData* aCurAlgo = anAvailableAlgsData.at( j );
+ if ( aCurAlgo->Label == algoDataIn->Label ){
+ isAvailable = true;
+ break;
+ }
+ }
+ }
+ else {
+ for (int j = 0; j < myAvailableHypData[i][Algo].count(); ++j) {
+ HypothesisData* aCurAlgo = hypData( i, Algo, j );
+ if ( aCurAlgo->Label == algoDataIn->Label ){
+ isAvailable = true;
+ break;
+ }
}
}
if ( isAvailable ) break;
class SMESHGUI_MeshDlg;
class SMESHGUI_ShapeByMeshOp;
class HypothesisData;
+class SMESHGUI_GenericHypothesisCreator;
/*!
* \brief Operation for mech creation or editing
QStringList&,
THypDataList&,
HypothesisData* = 0 ) const;
- static void existingHyps( const int,
+ void existingHyps( const int,
const int,
_PTR(SObject),
QStringList&,
THypList&,
- HypothesisData* = 0 );
+ HypothesisData* = 0 ) const;
HypothesisData* hypData( const int,
const int,
const int ); // access to myAvailableHypData
bool askUser=false);
int currentHyp( const int, const int ) const;
+ bool isSelectedHyp( int, int, int ) const;
+ int nbDlgHypTypes( const int ) const;
bool isAccessibleDim( const int ) const;
void setCurrentHyp( const int, const int, const int );
void setDefaultName( const QString& prefix="" ) const;
const THypList& ) const;
SMESH::SMESH_Hypothesis_var getInitParamsHypothesis( const QString&,
const QString& ) const;
+ void initHypCreator( SMESHGUI_GenericHypothesisCreator* aCreator );
bool isSubshapeOk() const;
char* isSubmeshIgnored() const;
_PTR(SObject) getSubmeshByGeom() const;
void createMeshTypeList( QStringList& );
void setAvailableMeshType( const QStringList& );
void setFilteredAlgoData( const int, const int );
+
private:
+
SMESHGUI_MeshDlg* myDlg;
SMESHGUI_ShapeByMeshOp* myShapeByMeshOp;
bool myToCreate;
--- /dev/null
+// Copyright (C) 2007-2014 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, or (at your option) any later version.
+//
+// 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 : SMESHGUI_Operations.h
+// Author : IVAN MECHETIN, Open CASCADE S.A.S. (ivan.mechetin@opencascade.com)
+
+#ifndef SMESHGUI_OPERATIONS_H
+#define SMESHGUI_OPERATIONS_H
+
+namespace SMESHOp {
+ enum {
+ // Tools --------------------------//--------------------------------
+ OpDelete = 1000, // DELETE
+ OpSelectFiltersLibrary = 1010, // MENU TOOLS - SELECTION FILTERS LIBRARY
+ OpReset = 1020, // RESET
+ OpScalarBarProperties = 1021, // SCALAR BAR PROPERTIES
+ OpSaveDistribution = 1030, // SAVE DISTRIBUTION
+ OpShowDistribution = 1031, // SHOW DISTRIBUTION
+#ifndef DISABLE_PLOT2DVIEWER
+ OpPlotDistribution = 1032, // PLOT DISTRIBUTION
+#endif
+ OpFileInformation = 1040, // POPUP MENU - FILE INFORMATION
+ // Import -------------------------//--------------------------------
+ OpImportDAT = 1100, // MENU FILE - IMPORT - DAT FILE
+ OpImportUNV = 1101, // MENU FILE - IMPORT - UNV FILE
+ OpImportMED = 1102, // MENU FILE - IMPORT - MED FILE
+ OpImportSTL = 1103, // MENU FILE - IMPORT - STL FILE
+#ifdef WITH_CGNS
+ OpImportCGNS = 1104, // MENU FILE - IMPORT - CGNS FILE
+#endif
+ OpImportSAUV = 1105, // MENU FILE - IMPORT - SAUV FILE
+ OpImportGMF = 1106, // MENU FILE - IMPORT - GMF FILE
+ // Export -------------------------//--------------------------------
+ OpExportDAT = 1200, // MENU FILE - EXPORT - DAT FILE
+ OpExportMED = 1201, // MENU FILE - EXPORT - MED FILE
+ OpExportUNV = 1202, // MENU FILE - EXPORT - UNV FILE
+ OpExportSTL = 1203, // MENU FILE - EXPORT - STL FILE
+#ifdef WITH_CGNS
+ OpExportCGNS = 1204, // MENU FILE - EXPORT - CGNS FILE
+#endif
+ OpExportSAUV = 1205, // MENU FILE - EXPORT - SAUV FILE
+ OpExportGMF = 1206, // MENU FILE - EXPORT - GMF FILE
+ OpPopupExportDAT = 1210, // POPUP MENU - EXPORT - DAT FILE
+ OpPopupExportMED = 1211, // POPUP MENU - EXPORT - MED FILE
+ OpPopupExportUNV = 1212, // POPUP MENU - EXPORT - UNV FILE
+ OpPopupExportSTL = 1213, // POPUP MENU - EXPORT - STL FILE
+#ifdef WITH_CGNS
+ OpPopupExportCGNS = 1214, // POPUP MENU - EXPORT - CGNS FILE
+#endif
+ OpPopupExportSAUV = 1215, // POPUP MENU - EXPORT - SAUV FILE
+ OpPopupExportGMF = 1216, // POPUP MENU - EXPORT - GMF FILE
+ // Mesh ---------------------------//--------------------------------
+ OpCreateMesh = 2030, // MENU MESH - CREATE MESH
+ OpCreateSubMesh = 2031, // MENU MESH - CREATE SUBMESH
+ OpEditMeshOrSubMesh = 2032, // MENU MESH - EDIT MESH/SUBMESH
+ OpBuildCompoundMesh = 2033, // MENU MESH - BUILD COMPOUND
+ OpCopyMesh = 2034, // MENU MESH - COPY MESH
+ OpCompute = 2040, // MENU MESH - COMPUTE
+ OpPreCompute = 2041, // MENU MESH - PREVIEW
+ OpEvaluate = 2042, // MENU MESH - EVALUATE
+ OpMeshOrder = 2043, // MENU MESH - CHANGE SUBMESH PRIORITY
+ OpCreateGroup = 2050, // MENU MESH - CREATE GROUP
+ OpCreateGeometryGroup = 2051, // MENU MESH - CREATE GROUPS FROM GEOMETRY
+ OpConstructGroup = 2052, // MENU MESH - CONSTRUCT GROUP
+ OpEditGroup = 2053, // MENU MESH - EDIT GROUP
+ OpEditGeomGroupAsGroup = 2054, // MENU MESH - EDIT GROUP AS STANDALONE
+ OpUnionGroups = 2060, // MENU MESH - UNION GROUPS
+ OpIntersectGroups = 2061, // MENU MESH - INTERSECT GROUPS
+ OpCutGroups = 2062, // MENU MESH - CUT GROUPS
+ OpGroupUnderlyingElem = 2070, // MENU MESH - GROUP OF UNDERLYING ENTITIES
+ OpEditGroupPopup = 2080, // POPUP MENU - EDIT GROUP
+ OpAddElemGroupPopup = 2081, // POPUP MENU - ADD ELEMENTS TO GROUP
+ OpRemoveElemGroupPopup = 2082, // POPUP MENU - REMOVE ELEMENTS FROM GROUP
+ OpMeshInformation = 2100, // MENU MESH - MESH INFORMATION
+ OpWhatIs = 2101, // MENU MESH - MESH ELEMENT INFORMATION
+ OpStdInfo = 2102, // MENU MESH - MESH STANDART INFORMATION
+ OpFindElementByPoint = 2103, // MENU MESH - FIND ELEMENT BY POINT
+ OpUpdate = 2200, // POPUP MENU - UPDATE
+ // Controls -----------------------//--------------------------------
+ OpFreeNode = 3000, // MENU CONTROLS - FREE NODES
+ OpEqualNode = 3001, // MENU CONTROLS - DOUBLE NODES
+ OpFreeEdge = 3100, // MENU CONTROLS - FREE EDGES
+ OpFreeBorder = 3101, // MENU CONTROLS - FREE BORDERS
+ OpLength = 3102, // MENU CONTROLS - LENGTH
+ OpConnection = 3103, // MENU CONTROLS - DOUBLE NODES
+ OpEqualEdge = 3104, // MENU CONTROLS - BORDERS AT MULTICONNECTION
+ OpFreeFace = 3200, // MENU CONTROLS - FREE FACES
+ OpBareBorderFace = 3201, // MENU CONTROLS - FACES WITH BARE BORDER
+ OpOverConstrainedFace = 3202, // MENU CONTROLS - OVERCONSTRAINED FACES
+ OpLength2D = 3203, // MENU CONTROLS - LENGTH 2D
+ OpConnection2D = 3204, // MENU CONTROLS - BORDERS ON MULTICONNECTION 2D
+ OpArea = 3205, // MENU CONTROLS - AREA
+ OpTaper = 3206, // MENU CONTROLS - TAPER
+ OpAspectRatio = 3207, // MENU CONTROLS - ASPECT RATIO
+ OpMinimumAngle = 3208, // MENU CONTROLS - MINIMUM ANGLE
+ OpWarpingAngle = 3209, // MENU CONTROLS - WARPING ANGLE
+ OpSkew = 3210, // MENU CONTROLS - SKEW
+ OpMaxElementLength2D = 3211, // MENU CONTROLS - ELEMENT DIAMETER 2D
+ OpEqualFace = 3212, // MENU CONTROLS - DOUBLE FACES
+ OpAspectRatio3D = 3300, // MENU CONTROLS - ASPECT RATIO 3D
+ OpVolume = 3301, // MENU CONTROLS - VOLUME
+ OpMaxElementLength3D = 3302, // MENU CONTROLS - ELEMENT DIAMETER 3D
+ OpBareBorderVolume = 3303, // MENU CONTROLS - VOLUMES WITH BARE BORDER
+ OpOverConstrainedVolume = 3304, // MENU CONTROLS - OVERCONSTRAINED VOLUMES
+ OpEqualVolume = 3305, // MENU CONTROLS - DOUBLE VOLUMES
+ OpOverallMeshQuality = 3400, // MENU CONTROLS - OVERALL MESH QUALITY
+ // Modification -------------------//--------------------------------
+ OpNode = 4000, // MENU MODIFICATION - ADD - NODE
+ OpElem0D = 4001, // MENU MODIFICATION - ADD - 0D ELEMENT
+ OpElem0DOnElemNodes = 4002, // MENU MODIFICATION - ADD - 0D ELEMENTS ON ELEMENT NODES
+ OpBall = 4003, // MENU MODIFICATION - ADD - BALL
+ OpEdge = 4004, // MENU MODIFICATION - ADD - EDGE
+ OpTriangle = 4005, // MENU MODIFICATION - ADD - TRIANGLE
+ OpQuadrangle = 4006, // MENU MODIFICATION - ADD - QUADRANGLE
+ OpPolygon = 4007, // MENU MODIFICATION - ADD - POLYGON
+ OpTetrahedron = 4008, // MENU MODIFICATION - ADD - TETRAHEDRON
+ OpHexahedron = 4009, // MENU MODIFICATION - ADD - HEXAHEDRON
+ OpPentahedron = 4010, // MENU MODIFICATION - ADD - PENTAHEDRON
+ OpPyramid = 4011, // MENU MODIFICATION - ADD - PYRAMID
+ OpHexagonalPrism = 4012, // MENU MODIFICATION - ADD - HEXAGONAL PRISM
+ OpPolyhedron = 4013, // MENU MODIFICATION - ADD - POLYHEDRON
+ OpQuadraticEdge = 4100, // MENU MODIFICATION - ADD - QUADRATIC EDGE
+ OpQuadraticTriangle = 4101, // MENU MODIFICATION - ADD - QUADRATIC TRIANGLE
+ OpBiQuadraticTriangle = 4102, // MENU MODIFICATION - ADD - BIQUADRATIC TRIANGLE
+ OpQuadraticQuadrangle = 4103, // MENU MODIFICATION - ADD - QUADRATIC QUADRANGLE
+ OpBiQuadraticQuadrangle = 4104, // MENU MODIFICATION - ADD - BIQUADRATIC QUADRANGLE
+ OpQuadraticTetrahedron = 4105, // MENU MODIFICATION - ADD - QUADRATIC TETRAHEDRON
+ OpQuadraticPyramid = 4106, // MENU MODIFICATION - ADD - QUADRATIC PYRAMID
+ OpQuadraticPentahedron = 4107, // MENU MODIFICATION - ADD - QUADRATIC PENTAHEDRON
+ OpQuadraticHexahedron = 4108, // MENU MODIFICATION - ADD - QUADRATIC HEXAHEDRON
+ OpTriQuadraticHexahedron = 4109, // MENU MODIFICATION - ADD - TRIQUADRATIC HEXAHEDRON
+ OpRemoveNodes = 4200, // MENU MODIFICATION - REMOVE - NODE
+ OpRemoveElements = 4201, // MENU MODIFICATION - REMOVE - ELEMENTS
+ OpRemoveOrphanNodes = 4202, // MENU MODIFICATION - REMOVE - ORPHAN NODES
+ OpDeleteGroup = 4210, // MENU MODIFICATION - REMOVE - DELETE GROUPS WITH CONTENTS
+ OpClearMesh = 4220, // MENU MODIFICATION - REMOVE - CLEAR MESH DATA
+ OpRenumberingNodes = 4300, // MENU MODIFICATION - RENUMBERING - NODES
+ OpRenumberingElements = 4301, // MENU MODIFICATION - RENUMBERING - ELEMENTS
+ OpTranslation = 4400, // MENU MODIFICATION - TRANSFORMATION - TRANSLATION
+ OpRotation = 4401, // MENU MODIFICATION - TRANSFORMATION - ROTATION
+ OpSymmetry = 4402, // MENU MODIFICATION - TRANSFORMATION - SYMMETRY
+ OpScale = 4403, // MENU MODIFICATION - TRANSFORMATION - SCALE TRANSFORM
+ OpSewing = 4404, // MENU MODIFICATION - TRANSFORMATION - SEWING
+ OpMergeNodes = 4405, // MENU MODIFICATION - TRANSFORMATION - MERGE NODES
+ OpMergeElements = 4406, // MENU MODIFICATION - TRANSFORMATION - MERGE ELEMENTS
+ OpDuplicateNodes = 4407, // MENU MODIFICATION - TRANSFORMATION - DUPLICATE NODES OR/AND ELEMENTS
+ OpMoveNode = 4500, // MENU MODIFICATION - MOVE NODE
+ OpDiagonalInversion = 4501, // MENU MODIFICATION - DIAGONAL INVERSION
+ OpUnionOfTwoTriangle = 4502, // MENU MODIFICATION - UNION OF TWO TRIANGLE
+ OpOrientation = 4503, // MENU MODIFICATION - ORIENTATION
+ OpReorientFaces = 4504, // MENU MODIFICATION - REORIENT FACES BY VECTOR
+ OpUnionOfTriangles = 4505, // MENU MODIFICATION - UNION OF TRIANGLES
+ OpCuttingOfQuadrangles = 4506, // MENU MODIFICATION - CUTTING OF QUADRANGLES
+ OpSplitVolumes = 4507, // MENU MODIFICATION - SPLIT VOLUMES
+ OpSmoothing = 4508, // MENU MODIFICATION - SMOOTHING
+ OpExtrusion = 4509, // MENU MODIFICATION - EXTRUSION
+ OpExtrusionAlongAPath = 4510, // MENU MODIFICATION - EXTRUSION ALONG A PATH
+ OpRevolution = 4511, // MENU MODIFICATION - REVOLUTION
+ OpPatternMapping = 4512, // MENU MODIFICATION - PATTERN MAPPING
+ OpConvertMeshToQuadratic = 4513, // MENU MODIFICATION - CONVERT TO/FROM QUADRATIC
+ OpCreateBoundaryElements = 4514, // MENU MODIFICATION - CREATE BOUNDARY ELEMENTS
+ // Measurements -------------------//--------------------------------
+ OpPropertiesLength = 5000, // MENU MEASUREMENTS - BASIC PROPERTIES - LENGTH
+ OpPropertiesArea = 5001, // MENU MEASUREMENTS - BASIC PROPERTIES - AREA
+ OpPropertiesVolume = 5002, // MENU MEASUREMENTS - BASIC PROPERTIES - VOLUME
+ OpMinimumDistance = 5003, // MENU MEASUREMENTS - MINIMUM DISTANCE
+ OpBoundingBox = 5004, // MENU MEASUREMENTS - BOUNDING BOX
+ // Hypothesis ---------------------//--------------------------------
+ OpEditHypothesis = 6000, // POPUP MENU - EDIT HYPOTHESIS
+ OpUnassign = 6001, // POPUP MENU - UNASSIGN
+ // Numbering ----------------------//--------------------------------
+ OpNumberingNodes = 6010, // POPUP MENU - NUMBERING - DISPLAY NODES
+ OpNumberingElements = 6011, // POPUP MENU - NUMBERING - DISPLAY ELEMENTS
+ // AutoColor ----------------------//--------------------------------
+ OpAutoColor = 6020, // POPUP MENU - AUTO COLOR
+ OpDisableAutoColor = 6021, // POPUP MENU - DISABLE AUTO COLOR
+ // DisplayMode --------------------//--------------------------------
+ OpDMWireframe = 6030, // POPUP MENU - DISPLAY MODE - WIREFRAME
+ OpDMShading = 6031, // POPUP MENU - DISPLAY MODE - SHADING
+ OpDMNodes = 6032, // POPUP MENU - DISPLAY MODE - NODES
+ OpDMShrink = 6033, // POPUP MENU - DISPLAY MODE - SHRINK
+ // DisplayEntity ------------------//--------------------------------
+ OpDE0DElements = 6040, // POPUP MENU - DISPLAY ENTITY - 0D ELEMENTS
+ OpDEEdges = 6041, // POPUP MENU - DISPLAY ENTITY - EDGES
+ OpDEFaces = 6042, // POPUP MENU - DISPLAY ENTITY - FACES
+ OpDEVolumes = 6043, // POPUP MENU - DISPLAY ENTITY - VOLUMES
+ OpDEBalls = 6044, // POPUP MENU - DISPLAY ENTITY - BALLS
+ OpDEAllEntity = 6045, // POPUP MENU - DISPLAY ENTITY - ALL ENTITY
+ // Representation -----------------//--------------------------------
+ OpRepresentationLines = 6050, // POPUP MENU - 2D QUADRATIC - LINES
+ OpRepresentationArcs = 6051, // POPUP MENU - 2D QUADRATIC - ARCS
+ // OrientationOnFaces -------------//--------------------------------
+ OpOrientationOnFaces = 6060, // POPUP MENU - ORIENTATION ON FACES
+ // PropertiesGUI ------------------//--------------------------------
+ OpProperties = 6070, // POPUP MENU - PROPERTIES
+ // Transparency -------------------//--------------------------------
+ OpTransparency = 6080, // POPUP MENU - TRANSPARENCY
+ // Display ------------------------//--------------------------------
+ OpShow = 6090, // POPUP MENU - SHOW
+ OpHide = 6091, // POPUP MENU - HIDE
+ OpShowOnly = 6092, // POPUP MENU - SHOW ONLY
+ // Clipping -----------------------//--------------------------------
+ OpClipping = 6100, // POPUP MENU - CLIPPING
+ // SortChild ----------------------//--------------------------------
+ OpSortChild = 6110, // POPUP MENU - SORT CHILDREN
+ // Advanced -----------------------//--------------------------------
+ OpAdvancedNoOp = 10000, // NO OPERATION (advanced operations base)
+ //@@ insert new functions before this line @@ do not remove this line @@//
+ OpLastOperationID = 20000 // DO NOT USE OPERATION IDs MORE THAN 20000 !!!
+ };
+}
+
+#endif // SMESHGUI_OPERATIONS_H
#define SPACING 6
#define MARGIN 11
-enum { CONSTRUCTOR_POINT=0, CONSTRUCTOR_FACE,
- EObject, EPoint, EFace, EDirection };
+enum { CONSTRUCTOR_POINT=0, CONSTRUCTOR_FACE, CONSTRUCTOR_VOLUME,
+ EObject, EPoint, EFace, EDirection, EVolumes };
//=======================================================================
/*!
QPixmap iconReoriPoint (resMgr()->loadPixmap("SMESH", tr("ICON_DLG_REORIENT2D_POINT")));
QPixmap iconReoriFace (resMgr()->loadPixmap("SMESH", tr("ICON_DLG_REORIENT2D_FACE")));
+ QPixmap iconReoriVolum (resMgr()->loadPixmap("SMESH", tr("ICON_DLG_REORIENT2D_VOLUME")));
QGroupBox* aConstructorBox = new QGroupBox(tr("REORIENT_FACES"), aFrame);
myConstructorGrp = new QButtonGroup(aConstructorBox);
aConstructorGrpLayout->addWidget(aFaceBut);
myConstructorGrp->addButton(aFaceBut, CONSTRUCTOR_FACE);
+ QRadioButton* aVolBut= new QRadioButton(aConstructorBox);
+ aVolBut->setIcon(iconReoriVolum);
+ aConstructorGrpLayout->addWidget(aVolBut);
+ myConstructorGrp->addButton(aVolBut, CONSTRUCTOR_VOLUME);
+
// Create other controls
setObjectPixmap( "SMESH", tr( "ICON_SELECT" ) );
createObject( tr("POINT") , aFrame, EPoint );
createObject( tr("FACE") , aFrame, EFace );
createObject( tr("DIRECTION"), aFrame, EDirection );
+ createObject( tr("VOLUMES"), aFrame, EVolumes );
setNameIndication( EObject, OneName );
setNameIndication( EFace, OneName );
setReadOnly( EFace, false );
if ( QLineEdit* le = qobject_cast<QLineEdit*>( objectWg( EFace, Control ) ))
le->setValidator( new SMESHGUI_IdValidator( this,1 ));
- const int width = aFaceBut->fontMetrics().width( tr("DIRECTION"));
+ int width = aFaceBut->fontMetrics().width( tr("DIRECTION"));
objectWg( EDirection, Label )->setFixedWidth( width );
objectWg( EObject , Label )->setFixedWidth( width );
objectWg( EPoint , Label )->setFixedWidth( width );
objectWg( EFace , Label )->setFixedWidth( width );
+ objectWg( EVolumes , Label )->setFixedWidth( width );
+
+ myOutsideChk = new QCheckBox( tr("OUTSIDE_VOLUME_NORMAL"), aFrame);
+ myOutsideChk->setChecked( true );
QLabel* aXLabel = new QLabel(tr("SMESH_X"), aFrame);
myX = new SMESHGUI_SpinBox(aFrame);
myDY->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, "length_precision");
myDZ->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, "length_precision");
+ width = Max( aFaceBut->fontMetrics().width( tr("SMESH_X")),
+ aFaceBut->fontMetrics().width( tr("SMESH_DX")));
+ aXLabel->setFixedWidth( width );
+ aYLabel->setFixedWidth( width );
+ aZLabel->setFixedWidth( width );
+ aDXLabel->setFixedWidth( width );
+ aDYLabel->setFixedWidth( width );
+ aDZLabel->setFixedWidth( width );
+
// Layouting
QGroupBox* anObjectGrp = new QGroupBox(tr("FACES"), aFrame);
objectWg( EPoint, Control )->hide();
aPointGrpLayout->addWidget( objectWg( EPoint, Label ) );
aPointGrpLayout->addWidget( objectWg( EPoint, Btn ) );
- aPointGrpLayout->addWidget( aXLabel );
- aPointGrpLayout->addWidget( myX );
- aPointGrpLayout->addWidget( aYLabel );
- aPointGrpLayout->addWidget( myY );
- aPointGrpLayout->addWidget( aZLabel );
- aPointGrpLayout->addWidget( myZ );
+ aPointGrpLayout->addWidget( aXLabel, 0 );
+ aPointGrpLayout->addWidget( myX, 1 );
+ aPointGrpLayout->addWidget( aYLabel, 0 );
+ aPointGrpLayout->addWidget( myY, 1 );
+ aPointGrpLayout->addWidget( aZLabel, 0 );
+ aPointGrpLayout->addWidget( myZ, 1 );
myFaceFrm = new QFrame(aFrame);
QHBoxLayout* aFaceGrpLayout = new QHBoxLayout(myFaceFrm);
aFaceGrpLayout->addWidget( objectWg( EFace, Btn ) );
aFaceGrpLayout->addWidget( objectWg( EFace, Control ) );
- QFrame* aDirectFrm = new QFrame(aFrame);
- QHBoxLayout* aDirectGrpLayout = new QHBoxLayout(aDirectFrm);
+ myVolumFrm = new QFrame(aFrame);
+ QGridLayout* aVolumGrpLayout = new QGridLayout(myVolumFrm);
+ aVolumGrpLayout->setMargin(0);
+ aVolumGrpLayout->setSpacing(SPACING);
+ aVolumGrpLayout->addWidget( objectWg( EVolumes, Label ), 0, 0 );
+ aVolumGrpLayout->addWidget( objectWg( EVolumes, Btn ), 0, 1 );
+ aVolumGrpLayout->addWidget( objectWg( EVolumes, Control ), 0, 2 );
+ aVolumGrpLayout->addWidget( myOutsideChk, 1, 0, 1, 3 );
+
+ myDirFrm = new QFrame(aFrame);
+ QHBoxLayout* aDirectGrpLayout = new QHBoxLayout(myDirFrm);
aDirectGrpLayout->setMargin(0);
objectWg( EDirection, Control )->hide();
aDirectGrpLayout->addWidget( objectWg( EDirection, Label ) );
aDirectGrpLayout->addWidget( objectWg( EDirection, Btn ) );
- aDirectGrpLayout->addWidget(aDXLabel );
- aDirectGrpLayout->addWidget(myDX );
- aDirectGrpLayout->addWidget(aDYLabel );
- aDirectGrpLayout->addWidget(myDY );
- aDirectGrpLayout->addWidget(aDZLabel );
- aDirectGrpLayout->addWidget(myDZ );
+ aDirectGrpLayout->addWidget( aDXLabel, 0 );
+ aDirectGrpLayout->addWidget( myDX, 1 );
+ aDirectGrpLayout->addWidget( aDYLabel, 0 );
+ aDirectGrpLayout->addWidget( myDY, 1 );
+ aDirectGrpLayout->addWidget( aDZLabel, 0 );
+ aDirectGrpLayout->addWidget( myDZ, 1 );
QGroupBox* anOrientGrp = new QGroupBox(tr("ORIENTATION"), aFrame);
QVBoxLayout* anOrientGrpLayout = new QVBoxLayout ( anOrientGrp );
anOrientGrpLayout->addWidget(myPointFrm);
anOrientGrpLayout->addWidget(myFaceFrm);
- anOrientGrpLayout->addWidget(aDirectFrm);
+ anOrientGrpLayout->addWidget(myVolumFrm);
+ anOrientGrpLayout->addWidget(myDirFrm);
QVBoxLayout* aLay = new QVBoxLayout(aFrame);
if ( id == CONSTRUCTOR_FACE )
{
myPointFrm->hide();
+ myVolumFrm->hide();
myFaceFrm->show();
+ myDirFrm->show();
activateObject( EFace );
}
- else
+ else if ( id == CONSTRUCTOR_POINT )
{
myFaceFrm->hide();
+ myVolumFrm->hide();
myPointFrm->show();
+ myDirFrm->show();
activateObject( EPoint );
}
+ else // CONSTRUCTOR_VOLUME
+ {
+ myFaceFrm->hide();
+ myPointFrm->hide();
+ myDirFrm->hide();
+ myVolumFrm->show();
+ activateObject( EVolumes );
+ }
}
//================================================================================
SMESH::SetPickable();
break;
case EObject:
+ case EVolumes:
SMESH::SetPointRepresentation(false);
setSelectionMode( ActorSelection );
break;
filters.append( new SMESH_TypeFilter( SMESH::GROUP_FACE ));
return new SMESH_LogicalFilter( filters, SMESH_LogicalFilter::LO_OR );
}
+ case EVolumes:
+ {
+ QList<SUIT_SelectionFilter*> filters;
+ filters.append( new SMESH_TypeFilter( SMESH::MESH ));
+ filters.append( new SMESH_TypeFilter( SMESH::SUBMESH_SOLID ));
+ filters.append( new SMESH_TypeFilter( SMESH::GROUP_VOLUME ));
+ return new SMESH_LogicalFilter( filters, SMESH_LogicalFilter::LO_OR );
+ }
case EPoint:
{
QList<SUIT_SelectionFilter*> filters;
if ( !myDlg->isVisible() || !myDlg->isEnabled() )
return;
+ if ( mySelectionMode == EVolumes )
+ {
+ SMESHGUI_SelectionOp::selectionDone();
+ return;
+ }
+
myDlg->clearSelection( mySelectionMode );
SALOME_ListIO aList;
try {
SUIT_OverrideCursor wc;
+
SMESH::SMESH_Mesh_var aMesh = myObject->GetMesh();
if ( aMesh->_is_nil() ) return false;
- SMESH::DirStruct direction;
- direction.PS.x = myDlg->myDX->GetValue();
- direction.PS.y = myDlg->myDY->GetValue();
- direction.PS.z = myDlg->myDZ->GetValue();
+ SMESH::SMESH_MeshEditor_var aMeshEditor = aMesh->GetMeshEditor();
+ if (aMeshEditor->_is_nil()) return false;
- long face = myDlg->objectText( EFace ).toInt();
- if ( myDlg->myConstructorGrp->checkedId() == CONSTRUCTOR_POINT )
- face = -1;
+ int aResult = 0;
+ if ( myDlg->myConstructorGrp->checkedId() == CONSTRUCTOR_VOLUME )
+ {
+ SMESH::ListOfIDSources_var faceGroups = new SMESH::ListOfIDSources;
+ faceGroups->length(1);
+ faceGroups[0] = myObject;
- SMESH::PointStruct point;
- point.x = myDlg->myX->GetValue();
- point.y = myDlg->myY->GetValue();
- point.z = myDlg->myZ->GetValue();
+ bool outsideNormal = myDlg->myOutsideChk->isChecked();
- SMESH::SMESH_MeshEditor_var aMeshEditor = aMesh->GetMeshEditor();
- if (aMeshEditor->_is_nil()) return false;
+ aResult = aMeshEditor->Reorient2DBy3D( faceGroups, myVolumeObj, outsideNormal );
+ }
+ else
+ {
+ SMESH::DirStruct direction;
+ direction.PS.x = myDlg->myDX->GetValue();
+ direction.PS.y = myDlg->myDY->GetValue();
+ direction.PS.z = myDlg->myDZ->GetValue();
+
+ long face = myDlg->objectText( EFace ).toInt();
+ if ( myDlg->myConstructorGrp->checkedId() == CONSTRUCTOR_POINT )
+ face = -1;
+
+ SMESH::PointStruct point;
+ point.x = myDlg->myX->GetValue();
+ point.y = myDlg->myY->GetValue();
+ point.z = myDlg->myZ->GetValue();
+
+ aMesh->SetParameters( aParameters.join(":").toLatin1().constData() );
- aMesh->SetParameters( aParameters.join(":").toLatin1().constData() );
+ aResult = aMeshEditor->Reorient2D( myObject, direction, face, point );
+ }
- int aResult = aMeshEditor->Reorient2D( myObject, direction, face, point );
if (aResult)
{
SALOME_ListIO aList;
return false;
}
+ // check volume object
+ if ( myDlg->myConstructorGrp->checkedId() == CONSTRUCTOR_VOLUME )
+ {
+ objectEntry = myDlg->selectedObject( EVolumes );
+ _PTR(SObject) pSObject = studyDS()->FindObjectID( objectEntry.toLatin1().data() );
+ myVolumeObj = SMESH::SObjectToInterface< SMESH::SMESH_IDSource>( pSObject );
+ if ( myVolumeObj->_is_nil() )
+ {
+ msg = tr("NO_VOLUME_OBJECT_SELECTED");
+ return false;
+ }
+ bool hasVolumes = false;
+ types = myVolumeObj->GetTypes();
+ for ( size_t i = 0; i < types->length() && !hasVolumes; ++i )
+ hasVolumes = ( types[i] == SMESH::VOLUME );
+ if ( !hasVolumes )
+ {
+ msg = tr("NO_VOLUMES");
+ return false;
+ }
+ }
// check vector
gp_Vec vec( myDlg->myDX->GetValue(),
myDlg->myDY->GetValue(),
#include "SMESHGUI_SelectionOp.h"
class QButtonGroup;
+class QCheckBox;
class QLineEdit;
class SMESHGUI_SpinBox;
class SMESHGUI_ReorientFacesDlg;
/*!
- * \brief Operation to reorient faces acoording to vector
+ * \brief Operation to reorient faces acoording to some criterion
*/
class SMESHGUI_EXPORT SMESHGUI_ReorientFacesOp: public SMESHGUI_SelectionOp
{
int mySelectionMode;
SMESH::SMESH_IDSource_var myObject;
+ SMESH::SMESH_IDSource_var myVolumeObj;
};
/*!
QButtonGroup* myConstructorGrp;
QFrame* myFaceFrm;
QFrame* myPointFrm;
+ QFrame* myDirFrm;
+ QFrame* myVolumFrm;
+ QCheckBox* myOutsideChk;
SMESHGUI_SpinBox* myX;
SMESHGUI_SpinBox* myY;
SMESHGUI_SpinBox* myZ;
// type to use instead of SMESH_IDSource_var for automatic UnRegister()
typedef SALOME::GenericObj_wrap<SMESH_IDSource> SMESH_IDSource_wrap;
+ /*!
+ * \brief Class usefull to convert a string returned from a CORBA call
+ * to other string types w/o memory leak.
+ *
+ * Usage (of instantiations): QString s = toQStr( objVar->GetName() );
+ * std::string ss = toStdStr( objVar->GetName() );
+ */
+ template < class _STRING >
+ class toStrT : public _STRING {
+ CORBA::String_var myStr;
+ public:
+ toStrT( char* s ): myStr(s), _STRING( s )
+ {}
+ operator const char*() const
+ { return myStr.in(); }
+ };
+ // Instantiations:
+ struct toQStr : public toStrT< QString > {
+ toQStr( char* s ): toStrT< QString >(s) {}
+ };
+ class toStdStr : public toStrT< std::string > {
+ toStdStr( char* s ): toStrT< std::string >(s) {}
+ };
+
}
#endif // SMESHGUI_UTILS_H
<source>ICON_HYPO_EDIT</source>
<translation>mesh_hypo_edit.png</translation>
</message>
+ <message>
+ <source>ICON_PLUS</source>
+ <translation>mesh_plus.png</translation>
+ </message>
+ <message>
+ <source>ICON_MINUS</source>
+ <translation>mesh_minus.png</translation>
+ </message>
<message>
<source>ICON_INTERSECT</source>
<translation>mesh_intersectGroups.png</translation>
<source>ICON_DLG_REORIENT2D_FACE</source>
<translation>reorient_faces_face.png</translation>
</message>
+ <message>
+ <source>ICON_DLG_REORIENT2D_VOLUME</source>
+ <translation>reorient_faces_volume.png</translation>
+ </message>
<message>
<source>ICON_REORIENT_2D</source>
<translation>reorient_faces_face.png</translation>
</message>
<message>
<source>TOP_REORIENT_2D</source>
- <translation>Reorient faces by vector</translation>
+ <translation>Reorient faces</translation>
</message>
<message>
<source>MEN_REORIENT_2D</source>
- <translation>Reorient faces by vector</translation>
+ <translation>Reorient faces</translation>
</message>
<message>
<source>STB_REORIENT_2D</source>
- <translation>Reorient faces by vector</translation>
+ <translation>Reorient faces</translation>
</message>
<message>
<source>TOP_FIND_ELEM</source>
</message>
<message>
<source>GROUP_VOLUME_GROUPS</source>
- <translation>Groups of volumes</translation>
+ <translation>Groups (faces or volumes)</translation>
</message>
<message>
<source>CONSTRUCT_NEW_GROUP_NODES</source>
<name>SMESHGUI_ReorientFacesDlg</name>
<message>
<source>CAPTION</source>
- <translation>Reorient faces by vector</translation>
+ <translation>Reorient faces</translation>
</message>
<message>
<source>REORIENT_FACES</source>
<source>ORIENTATION</source>
<translation>Orientation</translation>
</message>
+ <message>
+ <source>VOLUMES</source>
+ <translation>Volumes</translation>
+ </message>
+ <message>
+ <source>OUTSIDE_VOLUME_NORMAL</source>
+ <translation>Face normal outside volume</translation>
+ </message>
</context>
<context>
<name>SMESHGUI_ReorientFacesOp</name>
<source>NO_OBJECT_SELECTED</source>
<translation>No object selected</translation>
</message>
+ <message>
+ <source>NO_VOLUME_OBJECT_SELECTED</source>
+ <translation>No volume object selected</translation>
+ </message>
<message>
<source>NO_FACES</source>
<translation>Object includes no faces</translation>
</message>
+ <message>
+ <source>NO_VOLUMES</source>
+ <translation>Volume object includes no volumes</translation>
+ </message>
<message>
<source>ZERO_SIZE_VECTOR</source>
<translation>Zero size vector</translation>
<source>GROUP_ELEMS_TO_REPLACE</source>
<translation>Groupe des éléments dont les nœuds sont à remplacer</translation>
</message>
+ <message>
+ <source>GROUP_VOLUME_GROUPS</source>
+ <translation>Groupes (faces ou volumes)</translation>
+ </message>
<message>
<source>CONSTRUCT_NEW_GROUP_NODES</source>
<translation>Construire un groupe avec les nœuds nouvellement créés</translation>
</message>
<message>
<source>MEN_COMPUTE</source>
- <translation>計算します。</translation>
+ <translation>メッシュを作成</translation>
</message>
<message>
<source>MEN_PRECOMPUTE</source>
</message>
<message>
<source>MEN_CONV_TO_QUAD</source>
- <translation>2次要素の追加</translation>
+ <translation>2次/1次要素への変換</translation>
</message>
<message>
<source>MEN_2D_FROM_3D</source>
</message>
<message>
<source>SMESH_BUT_OVERWRITE</source>
- <translation>書換え(&w)</translation>
+ <translation>上書き(&w)</translation>
</message>
<message>
<source>SMESH_BUT_APPLY_AND_CLOSE</source>
</message>
<message>
<source>STB_COMPUTE</source>
- <translation>計算します。</translation>
+ <translation>メッシュを作成します。</translation>
</message>
<message>
<source>STB_PRECOMPUTE</source>
</message>
<message>
<source>TOP_COMPUTE</source>
- <translation>計算します。</translation>
+ <translation>メッシュを作成</translation>
</message>
<message>
<source>TOP_PRECOMPUTE</source>
<name>SMESHGUI_ConvToQuadDlg</name>
<message>
<source>CAPTION</source>
- <translation>2次要素の追加</translation>
+ <translation>2次/1次要素への変換</translation>
</message>
<message>
<source>MEDIUMNDS</source>
/*!
* \brief Return number of wires and a list of oredered edges.
* \param theFace - the face to process
- * \param theEdges - all ordered edges of theFace (outer edges goes first).
+ * \param theEdges - all ordered edges of theFace (outer edges go first).
* \param theNbEdgesInWires - nb of edges (== nb of vertices in closed wire) in each wire
* \param theFirstVertex - the vertex of the outer wire to set first in the returned
* list ( theFirstVertex may be NULL )
// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
//
-// File : SMESH_Hypothesis.hxx
+// File : SMESH_ComputeError.hxx
// Author : Edward AGAPOV (eap)
// Module : SMESH
//
#ifndef SMESH_ComputeError_HeaderFile
#define SMESH_ComputeError_HeaderFile
+#include "SMESH_Utils.hxx"
+
#include <string>
#include <list>
#include <boost/shared_ptr.hpp>
*/
// =============================================================
-struct SMESH_ComputeError
+struct SMESHUtils_EXPORT SMESH_ComputeError
{
int myName; //!< SMESH_ComputeErrorName or anything algo specific
std::string myComment;
bool IsKO() const { return myName != COMPERR_OK && myName != COMPERR_WARNING; }
bool IsCommon() const { return myName < 0 && myName > COMPERR_LAST_ALGO_ERROR; }
bool HasBadElems() const { return !myBadElements.empty(); }
- inline std::string CommonName() const;
-};
+ // not inline methods are implemented in src/SMESHUtils/SMESH_TryCatch.cxx
-#define _case2char(err) case err: return #err;
+ // Return myName as text, to be used to dump errors in terminal
+ std::string CommonName() const;
-// Return myName as text, to be used to dump errors in terminal
-std::string SMESH_ComputeError::CommonName() const
-{
- switch( myName ) {
- _case2char(COMPERR_OK );
- _case2char(COMPERR_BAD_INPUT_MESH );
- _case2char(COMPERR_STD_EXCEPTION );
- _case2char(COMPERR_OCC_EXCEPTION );
- _case2char(COMPERR_SLM_EXCEPTION );
- _case2char(COMPERR_EXCEPTION );
- _case2char(COMPERR_MEMORY_PB );
- _case2char(COMPERR_ALGO_FAILED );
- _case2char(COMPERR_BAD_SHAPE );
- _case2char(COMPERR_WARNING );
- _case2char(COMPERR_CANCELED );
- _case2char(COMPERR_NO_MESH_ON_SHAPE);
- _case2char(COMPERR_BAD_PARMETERS );
- default:;
- }
- return "";
-}
+ // Return the most severe error
+ static SMESH_ComputeErrorPtr Worst( SMESH_ComputeErrorPtr er1,
+ SMESH_ComputeErrorPtr er2 );
+};
#endif
// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
//
+// ------------------------------------------------------------------
#include "SMESH_TryCatch.hxx"
void SMESH::throwSalomeEx(const char* txt)
{
MESSAGE( txt << " " << __FILE__ << ": " << __LINE__ );
}
+// ------------------------------------------------------------------
+#include "SMESH_ComputeError.hxx"
+#define _case2char(err) case err: return #err;
+
+// Return SMESH_ComputeError::myName as text, to be used to dump errors in terminal
+std::string SMESH_ComputeError::CommonName() const
+{
+ switch( myName ) {
+ _case2char(COMPERR_OK );
+ _case2char(COMPERR_BAD_INPUT_MESH );
+ _case2char(COMPERR_STD_EXCEPTION );
+ _case2char(COMPERR_OCC_EXCEPTION );
+ _case2char(COMPERR_SLM_EXCEPTION );
+ _case2char(COMPERR_EXCEPTION );
+ _case2char(COMPERR_MEMORY_PB );
+ _case2char(COMPERR_ALGO_FAILED );
+ _case2char(COMPERR_BAD_SHAPE );
+ _case2char(COMPERR_WARNING );
+ _case2char(COMPERR_CANCELED );
+ _case2char(COMPERR_NO_MESH_ON_SHAPE);
+ _case2char(COMPERR_BAD_PARMETERS );
+ default:;
+ }
+ return "";
+}
+
+// Return the most severe error
+SMESH_ComputeErrorPtr SMESH_ComputeError::Worst( SMESH_ComputeErrorPtr er1,
+ SMESH_ComputeErrorPtr er2 )
+{
+ if ( !er1 ) return er2;
+ if ( !er2 ) return er1;
+ // both not NULL
+ if ( er1->IsOK() ) return er2;
+ if ( er2->IsOK() ) return er1;
+ // both not OK
+ if ( !er1->IsKO() ) return er2;
+ if ( !er2->IsKO() ) return er1;
+ // both KO
+ bool hasInfo1 = er1->myComment.size() || !er1->myBadElements.empty();
+ bool hasInfo2 = er2->myComment.size() || !er2->myBadElements.empty();
+ if ( er1->myName == er2->myName ||
+ hasInfo1 != hasInfo2 )
+ return hasInfo1 < hasInfo2 ? er2 : er1;
+
+ return er1->myName == COMPERR_CANCELED ? er2 : er1;
+}
typedef const SMDS_MeshElement* SMDS_MeshElementPtr;
-DEFINE_BASECOLLECTION (SMESH_BaseCollectionElemPtr, SMDS_MeshElementPtr)
DEFINE_SEQUENCE (SMESH_SequenceOfElemPtr, SMESH_BaseCollectionElemPtr, SMDS_MeshElementPtr)
// class SMESH_SequenceOfNode
typedef const SMDS_MeshNode* SMDS_MeshNodePtr;
-DEFINE_BASECOLLECTION (SMESH_BaseCollectionNodePtr, SMDS_MeshNodePtr)
DEFINE_SEQUENCE(SMESH_SequenceOfNode,
SMESH_BaseCollectionNodePtr, SMDS_MeshNodePtr)
"AddNode","Add0DElement","AddEdge","AddFace","AddPolygonalFace","AddBall",
"AddVolume","AddPolyhedralVolume","AddPolyhedralVolumeByFaces",
"MoveNode", "MoveClosestNodeToPoint",
- "InverseDiag","DeleteDiag","Reorient","ReorientObject",
+ "InverseDiag","DeleteDiag","Reorient","ReorientObject","Reorient2DBy3D",
"TriToQuad","TriToQuadObject", "QuadTo4Tri", "SplitQuad","SplitQuadObject",
"BestSplit","Smooth","SmoothObject","SmoothParametric","SmoothParametricObject",
"ConvertToQuadratic","ConvertFromQuadratic","RenumberNodes","RenumberElements",
void _pyComplexParamHypo::Flush()
{
+ list < Handle(_pyCommand) >::iterator cmd;
if ( IsWrapped() )
{
- list < Handle(_pyCommand) >::iterator cmd = myUnusedCommands.begin();
- for ( ; cmd != myUnusedCommands.end(); ++cmd )
+ for ( cmd = myUnusedCommands.begin(); cmd != myUnusedCommands.end(); ++cmd )
if ((*cmd)->GetMethod() == "SetObjectEntry" )
(*cmd)->Clear();
-
- if ( GetAlgoType() == "Cartesian_3D" )
- {
- _pyID algo = myCreationCmd->GetObject();
- for ( cmd = myProcessedCmds.begin(); cmd != myProcessedCmds.end(); ++cmd )
- {
- StructToList( *cmd, /*checkMethod=*/false );
- (*cmd)->SetObject( algo );
- }
- }
}
+
+ // if ( GetAlgoType() == "Cartesian_3D" )
+ // {
+ // _pyID algo = myCreationCmd->GetObject();
+ // for ( cmd = myProcessedCmds.begin(); cmd != myProcessedCmds.end(); ++cmd )
+ // {
+ // if ( IsWrapped() )
+ // {
+ // StructToList( *cmd, /*checkMethod=*/false );
+ // const _AString & method = (*cmd)->GetMethod();
+ // if ( method == "SetFixedPoint" )
+ // (*cmd)->SetObject( algo );
+ // }
+ // }
+ // }
}
//================================================================================
if ( theNames.IsBound( anEntry ))
{
aGUIName = theNames.Find(anEntry);
+ aGUIName.RemoveAll('\''); // remove a quote from a name (issue 22360)
setNamePart += nt + aSMESHGen + ".SetName(" + aName;
if ( anEntry2AccessorMethod.IsBound( anEntry ) )
setNamePart += helper + "." + anEntry2AccessorMethod( anEntry );
SMESH::DownCast< SMESH::Filter_i* >( object ))
{
elemIt = SMESH_Mesh_i::GetElements( object, GetElementType() );
+ if ( !elemIt ) return histogram._retn();
}
else
{
SMESH::Predicate_ptr aPrevPredicate = SMESH::Predicate::_nil();
int aPrevBinary = SMESH::FT_Undefined;
+ aBinaries.back() = SMESH::FT_Undefined;
for ( aPredIter = aPredicates.begin(), aBinaryIter = aBinaries.begin();
aPredIter != aPredicates.end() && aBinaryIter != aBinaries.end();
PortableServer::ObjectId* contId,
const char* instanceName,
const char* interfaceName )
- : Engines_Component_i( orb, poa, contId, instanceName, interfaceName )
+ : Engines_Component_i( orb, poa, contId, instanceName, interfaceName )
{
MESSAGE( "SMESH_Gen_i::SMESH_Gen_i : standard constructor" );
// create a new hypothesis object, store its ref. in studyContext
if(MYDEBUG) MESSAGE("Create Hypothesis " << theHypName);
myHypothesis_i =
- myHypCreatorMap[string(theHypName)]->Create(myPoa, GetCurrentStudyID(), &myGen);
+ myHypCreatorMap[string(theHypName)]->Create(myPoa, GetCurrentStudyID(), &myGen);
myHypothesis_i->SetLibName(aPlatformLibName.c_str()); // for persistency assurance
if (!myHypothesis_i)
*/
//=============================================================================
SMESH::SMESH_Mesh_ptr SMESH_Gen_i::createMesh()
- throw ( SALOME::SALOME_Exception )
+ throw ( SALOME::SALOME_Exception )
{
Unexpect aCatch(SALOME_SalomeException);
if(MYDEBUG) MESSAGE( "SMESH_Gen_i::createMesh" );
StudyContext* SMESH_Gen_i::GetCurrentStudyContext()
{
if ( !CORBA::is_nil( myCurrentStudy ) &&
- myStudyContextMap.find( GetCurrentStudyID() ) != myStudyContextMap.end() )
+ myStudyContextMap.find( GetCurrentStudyID() ) != myStudyContextMap.end() )
return myStudyContextMap[ myCurrentStudy->StudyId() ];
else
return 0;
SMESH::SMESH_Hypothesis_ptr SMESH_Gen_i::CreateHypothesis( const char* theHypName,
const char* theLibName )
- throw ( SALOME::SALOME_Exception )
+ throw ( SALOME::SALOME_Exception )
{
Unexpect aCatch(SALOME_SalomeException);
// Create hypothesis/algorithm
return SMESH::SMESH_Hypothesis::_nil();
}
+//=============================================================================
+/*!
+ * Returns \c True if a hypothesis is assigned to a sole sub-mesh in a current Study
+ * \param [in] theHyp - the hypothesis of interest
+ * \param [out] theMesh - the sole mesh using \a theHyp
+ * \param [out] theShape - the sole geometry \a theHyp is assigned to
+ * \return boolean - \c True if \a theMesh and \a theShape are sole using \a theHyp
+ *
+ * If two meshes on same shape have theHyp assigned to the same sub-shape, they are
+ * considered as SAME sub-mesh => result is \c true.
+ * This method ids used to initialize SMESHGUI_GenericHypothesisCreator with
+ * a shape to which an hyp being edited is assigned.
+ */
+//=============================================================================
+
+CORBA::Boolean SMESH_Gen_i::GetSoleSubMeshUsingHyp( SMESH::SMESH_Hypothesis_ptr theHyp,
+ SMESH::SMESH_Mesh_out theMesh,
+ GEOM::GEOM_Object_out theShape)
+{
+ if ( GetCurrentStudyID() < 0 || CORBA::is_nil( theHyp ))
+ return false;
+
+ // get Mesh component SO
+ CORBA::String_var compDataType = ComponentDataType();
+ SALOMEDS::SComponent_wrap comp = myCurrentStudy->FindComponent( compDataType.in() );
+ if ( CORBA::is_nil( comp ))
+ return false;
+
+ // look for child SO of meshes
+ SMESH::SMESH_Mesh_var foundMesh;
+ TopoDS_Shape foundShape;
+ bool isSole = true;
+ SALOMEDS::ChildIterator_wrap meshIter = myCurrentStudy->NewChildIterator( comp );
+ for ( ; meshIter->More() && isSole; meshIter->Next() )
+ {
+ SALOMEDS::SObject_wrap curSO = meshIter->Value();
+ CORBA::Object_var obj = SObjectToObject( curSO );
+ SMESH_Mesh_i* mesh_i = SMESH::DownCast< SMESH_Mesh_i* >( obj );
+ if ( ! mesh_i )
+ continue;
+
+ // look for a sole shape where theHyp is assigned
+ bool isHypFound = false;
+ const ShapeToHypothesis & s2hyps = mesh_i->GetImpl().GetMeshDS()->GetHypotheses();
+ ShapeToHypothesis::Iterator s2hypsIt( s2hyps );
+ for ( ; s2hypsIt.More() && isSole; s2hypsIt.Next() )
+ {
+ const THypList& hyps = s2hypsIt.Value();
+ THypList::const_iterator h = hyps.begin();
+ for ( ; h != hyps.end(); ++h )
+ if ( (*h)->GetID() == theHyp->GetId() )
+ break;
+ if ( h != hyps.end()) // theHyp found
+ {
+ isHypFound = true;
+ if ( ! foundShape.IsNull() &&
+ ! foundShape.IsSame( s2hypsIt.Key() )) // not a sole sub-shape
+ {
+ foundShape.Nullify();
+ isSole = false;
+ break;
+ }
+ foundShape = s2hypsIt.Key();
+ }
+ } // loop on assigned hyps
+
+ if ( isHypFound && !foundShape.IsNull() ) // a mesh using theHyp is found
+ {
+ if ( !foundMesh->_is_nil() ) // not a sole mesh
+ {
+ GEOM::GEOM_Object_var s1 = mesh_i ->GetShapeToMesh();
+ GEOM::GEOM_Object_var s2 = foundMesh->GetShapeToMesh();
+ if ( ! ( isSole = s1->IsSame( s2 )))
+ break;
+ }
+ foundMesh = SMESH::SMESH_Mesh::_narrow( obj );
+ }
+
+ } // loop on meshes
+
+ if ( isSole &&
+ ! foundMesh->_is_nil() &&
+ ! foundShape.IsNull() )
+ {
+ theMesh = foundMesh._retn();
+ theShape = ShapeToGeomObject( foundShape );
+ return ( !theMesh->_is_nil() && !theShape->_is_nil() );
+ }
+ return false;
+}
+
//=============================================================================
/*!
* Sets number of segments per diagonal of boundary box of geometry by which
// if ( sm->GetSubShape().ShapeType() == TopAbs_VERTEX )
// break;
SMESH_ComputeErrorPtr error = sm->GetComputeError();
- if ( error && !error->IsOK() && error->myAlgo )
+ if ( error && !error->IsOK() )
{
+ if ( !( error->myAlgo ) &&
+ !( error->myAlgo = sm->GetAlgo() ))
+ continue;
SMESH::ComputeError & errStruct = error_array[ nbErr++ ];
errStruct.code = -( error->myName < 0 ? error->myName + 1: error->myName ); // -1 -> 0
errStruct.comment = error->myComment.c_str();
myLocMesh.ShapeToMesh( nullShape ); // remove shape referring data
}
- if ( !mySMESHDSMesh->SubMeshes().empty() )
+ SMESHDS_SubMeshIteratorPtr smIt = mySMESHDSMesh->SubMeshes();
+ if ( smIt->more() )
{
// Store submeshes
// ----------------
// each element belongs to one or none submesh,
// so for each node/element, we store a submesh ID
- // Make maps of submesh IDs of elements sorted by element IDs
- // typedef int TElemID;
- // typedef int TSubMID;
- // map< TElemID, TSubMID > eId2smId, nId2smId;
- const map<int,SMESHDS_SubMesh*>& aSubMeshes = mySMESHDSMesh->SubMeshes();
- map<int,SMESHDS_SubMesh*>::const_iterator itSubM ( aSubMeshes.begin() );
- // SMDS_NodeIteratorPtr itNode;
- // SMDS_ElemIteratorPtr itElem;
- // for ( itSubM = aSubMeshes.begin(); itSubM != aSubMeshes.end() ; itSubM++ )
- // {
- // TSubMID aSubMeID = itSubM->first;
- // SMESHDS_SubMesh* aSubMesh = itSubM->second;
- // if ( aSubMesh->IsComplexSubmesh() )
- // continue; // sub-mesh containing other sub-meshes
- // // nodes
- // for ( itNode = aSubMesh->GetNodes(); itNode->more(); ++hint)
- // nId2smId.insert( nId2smId.back(), make_pair( itNode->next()->GetID(), aSubMeID ));
- // // elements
- // for ( itElem = aSubMesh->GetElements(); itElem->more(); ++hint)
- // hint = eId2smId.insert( eId2smId.back(), make_pair( itElem->next()->GetID(), aSubMeID ));
- // }
-
- // // Care of elements that are not on submeshes
- // if ( mySMESHDSMesh->NbNodes() != nId2smId.size() ) {
- // for ( itNode = mySMESHDSMesh->nodesIterator(); itNode->more(); )
- // /* --- stl_map.h says : */
- // /* A %map relies on unique keys and thus a %pair is only inserted if its */
- // /* first element (the key) is not already present in the %map. */
- // nId2smId.insert( make_pair( itNode->next()->GetID(), 0 ));
- // }
- // int nbElems = mySMESHDSMesh->GetMeshInfo().NbElements();
- // if ( nbElems != eId2smId.size() ) {
- // for ( itElem = mySMESHDSMesh->elementsIterator(); itElem->more(); )
- // eId2smId.insert( make_pair( itElem->next()->GetID(), 0 ));
- // }
-
// Store submesh IDs
for ( int isNode = 0; isNode < 2; ++isNode )
{
- // map< TElemID, TSubMID >& id2smId = isNode ? nId2smId : eId2smId;
- // if ( id2smId.empty() ) continue;
- // map< TElemID, TSubMID >::const_iterator id_smId = id2smId.begin();
- // // make and fill array of submesh IDs
- // int* smIDs = new int [ id2smId.size() ];
- // for ( int i = 0; id_smId != id2smId.end(); ++id_smId, ++i )
- // smIDs[ i ] = id_smId->second;
SMDS_ElemIteratorPtr eIt =
mySMESHDSMesh->elementsIterator( isNode ? SMDSAbs_Node : SMDSAbs_All );
int nbElems = isNode ? mySMESHDSMesh->NbNodes() : mySMESHDSMesh->GetMeshInfo().NbElements();
int nbEdgeNodes = 0, nbFaceNodes = 0;
list<SMESHDS_SubMesh*> aEdgeSM, aFaceSM;
// loop on SMESHDS_SubMesh'es
- for ( itSubM = aSubMeshes.begin(); itSubM != aSubMeshes.end() ; itSubM++ )
+ while ( smIt->more() )
{
- SMESHDS_SubMesh* aSubMesh = (*itSubM).second;
+ SMESHDS_SubMesh* aSubMesh = const_cast< SMESHDS_SubMesh* >( smIt->next() );
if ( aSubMesh->IsComplexSubmesh() )
continue; // submesh containing other submeshs
int nbNodes = aSubMesh->NbNodes();
if ( nbNodes == 0 ) continue;
- int aShapeID = (*itSubM).first;
+ int aShapeID = aSubMesh->GetID();
if ( aShapeID < 1 || aShapeID > mySMESHDSMesh->MaxShapeIndex() )
continue;
int aShapeType = mySMESHDSMesh->IndexToShape( aShapeID ).ShapeType();
useCaseBuilder->AppendTo( where, sobj ); // append to the end of list
}
}
-//=================================================================================
-// function : IsApplicable
-// purpose : Return true if algorithm can be applied
-//=================================================================================
+//================================================================================
+/*!
+ * \brief Returns true if algorithm can be used to mesh a given geometry
+ * \param [in] theAlgoType - the algorithm type
+ * \param [in] theLibName - a name of the Plug-in library implementing the algorithm
+ * \param [in] theGeomObject - the geometry to mesh
+ * \param [in] toCheckAll - if \c True, returns \c True if all shapes are meshable,
+ * else, returns \c True if at least one shape is meshable
+ * \return CORBA::Boolean - can or can't
+ */
+//================================================================================
+
CORBA::Boolean SMESH_Gen_i::IsApplicable ( const char* theAlgoType,
const char* theLibName,
GEOM::GEOM_Object_ptr theGeomObject,
std::string aPlatformLibName;
typedef GenericHypothesisCreator_i* (*GetHypothesisCreator)(const char*);
- GenericHypothesisCreator_i* aCreator = getHypothesisCreator(theAlgoType, theLibName, aPlatformLibName);
+ GenericHypothesisCreator_i* aCreator =
+ getHypothesisCreator(theAlgoType, theLibName, aPlatformLibName);
if (aCreator)
{
TopoDS_Shape shape = GeomObjectToShape( theGeomObject );
CORBA::Boolean byMesh)
throw ( SALOME::SALOME_Exception );
+ /*
+ * Returns True if a hypothesis is assigned to a sole sub-mesh in a current Study
+ */
+ CORBA::Boolean GetSoleSubMeshUsingHyp( SMESH::SMESH_Hypothesis_ptr theHyp,
+ SMESH::SMESH_Mesh_out theMesh,
+ GEOM::GEOM_Object_out theShape);
+
// Preferences
// ------------
/*!
void SMESH_GroupOnFilter_i::SetFilter(SMESH::Filter_ptr theFilter)
{
+ if ( myFilter->_is_equivalent( theFilter ))
+ return;
+
if ( myPreMeshInfo )
myPreMeshInfo->FullLoadFromFile();
*/
//================================================================================
+ enum IDSource_Error { IDSource_OK, IDSource_INVALID, IDSource_EMPTY };
+
bool idSourceToSet(SMESH::SMESH_IDSource_ptr theIDSource,
const SMESHDS_Mesh* theMeshDS,
TIDSortedElemSet& theElemSet,
const SMDSAbs_ElementType theType,
- const bool emptyIfIsMesh=false)
+ const bool emptyIfIsMesh = false,
+ IDSource_Error* error = 0)
{
+ if ( error ) *error = IDSource_OK;
+
if ( CORBA::is_nil( theIDSource ) )
+ {
+ if ( error ) *error = IDSource_INVALID;
return false;
+ }
if ( emptyIfIsMesh && SMESH::DownCast<SMESH_Mesh_i*>( theIDSource ))
+ {
+ if ( error && theMeshDS->GetMeshInfo().NbElements( theType ) == 0 )
+ *error = IDSource_EMPTY;
return true;
-
+ }
SMESH::long_array_var anIDs = theIDSource->GetIDs();
if ( anIDs->length() == 0 )
+ {
+ if ( error ) *error = IDSource_EMPTY;
return false;
+ }
SMESH::array_of_ElementType_var types = theIDSource->GetTypes();
if ( types->length() == 1 && types[0] == SMESH::NODE ) // group of nodes
{
if ( theType == SMDSAbs_All || theType == SMDSAbs_Node )
+ {
arrayToSet( anIDs, theMeshDS, theElemSet, SMDSAbs_Node );
+ }
else
+ {
+ if ( error ) *error = IDSource_INVALID;
return false;
+ }
}
else
{
arrayToSet( anIDs, theMeshDS, theElemSet, theType);
- return bool(anIDs->length()) == bool(theElemSet.size());
+ if ( bool(anIDs->length()) != bool(theElemSet.size()))
+ {
+ if ( error ) *error = IDSource_INVALID;
+ return false;
+ }
}
return true;
}
TIDSortedElemSet elements;
prepareIdSource( the2Dgroup );
- if ( !idSourceToSet( the2Dgroup, getMeshDS(), elements, SMDSAbs_Face, /*emptyIfIsMesh=*/1))
+ IDSource_Error error;
+ idSourceToSet( the2Dgroup, getMeshDS(), elements, SMDSAbs_Face, /*emptyIfIsMesh=*/1, &error );
+ if ( error == IDSource_EMPTY )
+ return 0;
+ if ( error == IDSource_INVALID )
THROW_SALOME_CORBA_EXCEPTION("No faces in given group", SALOME::BAD_PARAM);
return 0;
}
+//=======================================================================
+//function : Reorient2DBy3D
+//purpose : Reorient faces basing on orientation of adjacent volumes.
+//=======================================================================
+
+CORBA::Long SMESH_MeshEditor_i::Reorient2DBy3D(const SMESH::ListOfIDSources& faceGroups,
+ SMESH::SMESH_IDSource_ptr volumeGroup,
+ CORBA::Boolean outsideNormal)
+ throw (SALOME::SALOME_Exception)
+{
+ SMESH_TRY;
+ initData();
+
+ TIDSortedElemSet volumes;
+ prepareIdSource( volumeGroup );
+ IDSource_Error volsError;
+ idSourceToSet( volumeGroup, getMeshDS(), volumes, SMDSAbs_Volume, /*emptyIfMesh=*/1, &volsError);
+
+ int nbReori = 0;
+ for ( size_t i = 0; i < faceGroups.length(); ++i )
+ {
+ SMESH::SMESH_IDSource_ptr faceGrp = faceGroups[i].in();
+ prepareIdSource( faceGrp );
+
+ TIDSortedElemSet faces;
+ IDSource_Error error;
+ idSourceToSet( faceGrp, getMeshDS(), faces, SMDSAbs_Face, /*emptyIfIsMesh=*/1, &error );
+ if ( error == IDSource_INVALID && faceGroups.length() == 1 )
+ THROW_SALOME_CORBA_EXCEPTION("No faces in a given object", SALOME::BAD_PARAM);
+ if ( error == IDSource_OK && volsError != IDSource_OK )
+ THROW_SALOME_CORBA_EXCEPTION("No volumes in a given object", SALOME::BAD_PARAM);
+
+ nbReori += getEditor().Reorient2DBy3D( faces, volumes, outsideNormal );
+
+ if ( error != IDSource_EMPTY && faces.empty() ) // all faces in the mesh treated
+ break;
+ }
+
+ if ( nbReori ) {
+ declareMeshModified( /*isReComputeSafe=*/false );
+ }
+ TPythonDump() << this << ".Reorient2DBy3D( "
+ << faceGroups << ", "
+ << volumeGroup << ", "
+ << outsideNormal << " )";
+
+ return nbReori;
+
+ SMESH_CATCH( SMESH::throwCorbaException );
+ return 0;
+}
+
//=============================================================================
/*!
* \brief Fuse neighbour triangles into quadrangles.
const SMESH::DirStruct& theDirection,
CORBA::Long theFace,
const SMESH::PointStruct& thePoint) throw (SALOME::SALOME_Exception);
+ /*!
+ * \brief Reorient faces basing on orientation of adjacent volumes.
+ * \param faces - a list of objects containing face to reorient
+ * \param volumes - an object containing volumes.
+ * \param outsideNormal - to orient faces to have their normal
+ * pointing either \a outside or \a inside the adjacent volumes.
+ * \return number of reoriented faces.
+ */
+ CORBA::Long Reorient2DBy3D(const SMESH::ListOfIDSources & faces,
+ SMESH::SMESH_IDSource_ptr volumes,
+ CORBA::Boolean outsideNormal)
+ throw (SALOME::SALOME_Exception);
// Split/Join faces
CORBA::Boolean TriToQuad (const SMESH::long_array & IDsOfElements,
RETURNCASE( HYP_BAD_SUBSHAPE );
RETURNCASE( HYP_BAD_GEOMETRY );
RETURNCASE( HYP_NEED_SHAPE );
+ RETURNCASE( HYP_INCOMPAT_HYPS );
default:;
}
return SMESH::HYP_UNKNOWN_FATAL;
*/
//=============================================================================
-SMESH::Hypothesis_Status SMESH_Mesh_i::AddHypothesis(GEOM::GEOM_Object_ptr aSubShapeObject,
- SMESH::SMESH_Hypothesis_ptr anHyp)
+SMESH::Hypothesis_Status
+SMESH_Mesh_i::AddHypothesis(GEOM::GEOM_Object_ptr aSubShape,
+ SMESH::SMESH_Hypothesis_ptr anHyp,
+ CORBA::String_out anErrorText)
throw(SALOME::SALOME_Exception)
{
Unexpect aCatch(SALOME_SalomeException);
if ( _preMeshInfo )
_preMeshInfo->ForgetOrLoad();
- SMESH_Hypothesis::Hypothesis_Status status = addHypothesis( aSubShapeObject, anHyp );
+ std::string error;
+ SMESH_Hypothesis::Hypothesis_Status status = addHypothesis( aSubShape, anHyp, &error );
+ anErrorText = error.c_str();
SMESH::SMESH_Mesh_var mesh( _this() );
if ( !SMESH_Hypothesis::IsStatusFatal(status) )
{
SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
- _gen_i->AddHypothesisToShape( study, mesh, aSubShapeObject, anHyp );
+ _gen_i->AddHypothesisToShape( study, mesh, aSubShape, anHyp );
}
if(MYDEBUG) MESSAGE( " AddHypothesis(): status = " << status );
// Update Python script
- //if(_impl->HasShapeToMesh())
- {
- TPythonDump() << "status = " << mesh << ".AddHypothesis( "
- << aSubShapeObject << ", " << anHyp << " )";
- }
- // else {
- // TPythonDump() << "status = " << mesh << ".AddHypothesis( "<< anHyp << " )";
- // }
+ TPythonDump() << "status = " << mesh << ".AddHypothesis( "
+ << aSubShape << ", " << anHyp << " )";
return ConvertHypothesisStatus(status);
}
//=============================================================================
SMESH_Hypothesis::Hypothesis_Status
-SMESH_Mesh_i::addHypothesis(GEOM::GEOM_Object_ptr aSubShapeObject,
- SMESH::SMESH_Hypothesis_ptr anHyp)
+SMESH_Mesh_i::addHypothesis(GEOM::GEOM_Object_ptr aSubShape,
+ SMESH::SMESH_Hypothesis_ptr anHyp,
+ std::string* anErrorText)
{
if(MYDEBUG) MESSAGE("addHypothesis");
- if (CORBA::is_nil( aSubShapeObject ) && HasShapeToMesh())
+ if (CORBA::is_nil( aSubShape ) && HasShapeToMesh())
THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference",SALOME::BAD_PARAM);
if (CORBA::is_nil( anHyp ))
TopoDS_Shape myLocSubShape;
//use PseudoShape in case if mesh has no shape
if(HasShapeToMesh())
- myLocSubShape = _gen_i->GeomObjectToShape( aSubShapeObject);
+ myLocSubShape = _gen_i->GeomObjectToShape( aSubShape);
else
myLocSubShape = _impl->GetShapeToMesh();
const int hypId = anHyp->GetId();
- status = _impl->AddHypothesis(myLocSubShape, hypId);
- if ( !SMESH_Hypothesis::IsStatusFatal(status) ) {
+ std::string error;
+ status = _impl->AddHypothesis( myLocSubShape, hypId, &error );
+ if ( !SMESH_Hypothesis::IsStatusFatal(status) )
+ {
_mapHypo[hypId] = SMESH::SMESH_Hypothesis::_duplicate( anHyp );
anHyp->Register();
// assure there is a corresponding submesh
if ( !_impl->IsMainShape( myLocSubShape )) {
int shapeId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
if ( _mapSubMesh_i.find( shapeId ) == _mapSubMesh_i.end() )
- SMESH::SMESH_subMesh_var( createSubMesh( aSubShapeObject ));
+ SMESH::SMESH_subMesh_var( createSubMesh( aSubShape ));
}
}
+ else if ( anErrorText )
+ {
+ *anErrorText = error;
+ }
}
catch(SALOME_Exception & S_ex)
{
*/
//=============================================================================
-SMESH::Hypothesis_Status SMESH_Mesh_i::RemoveHypothesis(GEOM::GEOM_Object_ptr aSubShapeObject,
+SMESH::Hypothesis_Status SMESH_Mesh_i::RemoveHypothesis(GEOM::GEOM_Object_ptr aSubShape,
SMESH::SMESH_Hypothesis_ptr anHyp)
throw(SALOME::SALOME_Exception)
{
if ( _preMeshInfo )
_preMeshInfo->ForgetOrLoad();
- SMESH_Hypothesis::Hypothesis_Status status = removeHypothesis( aSubShapeObject, anHyp );
+ SMESH_Hypothesis::Hypothesis_Status status = removeHypothesis( aSubShape, anHyp );
SMESH::SMESH_Mesh_var mesh = _this();
if ( !SMESH_Hypothesis::IsStatusFatal(status) )
{
SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
- _gen_i->RemoveHypothesisFromShape( study, mesh, aSubShapeObject, anHyp );
+ _gen_i->RemoveHypothesisFromShape( study, mesh, aSubShape, anHyp );
}
// Update Python script
if(_impl->HasShapeToMesh())
TPythonDump() << "status = " << mesh << ".RemoveHypothesis( "
- << aSubShapeObject << ", " << anHyp << " )";
+ << aSubShape << ", " << anHyp << " )";
else
TPythonDump() << "status = " << mesh << ".RemoveHypothesis( "
<< anHyp << " )";
//=============================================================================
SMESH_Hypothesis::Hypothesis_Status
-SMESH_Mesh_i::removeHypothesis(GEOM::GEOM_Object_ptr aSubShapeObject,
+SMESH_Mesh_i::removeHypothesis(GEOM::GEOM_Object_ptr aSubShape,
SMESH::SMESH_Hypothesis_ptr anHyp)
{
if(MYDEBUG) MESSAGE("removeHypothesis()");
- if (CORBA::is_nil( aSubShapeObject ) && HasShapeToMesh())
+ if (CORBA::is_nil( aSubShape ) && HasShapeToMesh())
THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference", SALOME::BAD_PARAM);
if (CORBA::is_nil( anHyp ))
TopoDS_Shape myLocSubShape;
//use PseudoShape in case if mesh has no shape
if( _impl->HasShapeToMesh() )
- myLocSubShape = _gen_i->GeomObjectToShape( aSubShapeObject );
+ myLocSubShape = _gen_i->GeomObjectToShape( aSubShape );
else
myLocSubShape = _impl->GetShapeToMesh();
//=============================================================================
SMESH::ListOfHypothesis *
-SMESH_Mesh_i::GetHypothesisList(GEOM::GEOM_Object_ptr aSubShapeObject)
+SMESH_Mesh_i::GetHypothesisList(GEOM::GEOM_Object_ptr aSubShape)
throw(SALOME::SALOME_Exception)
{
Unexpect aCatch(SALOME_SalomeException);
if (MYDEBUG) MESSAGE("GetHypothesisList");
- if (_impl->HasShapeToMesh() && CORBA::is_nil(aSubShapeObject))
+ if (_impl->HasShapeToMesh() && CORBA::is_nil(aSubShape))
THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference", SALOME::BAD_PARAM);
SMESH::ListOfHypothesis_var aList = new SMESH::ListOfHypothesis();
try {
- TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(aSubShapeObject);
+ TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(aSubShape);
if ( myLocSubShape.IsNull() && !_impl->HasShapeToMesh() )
myLocSubShape = _impl->GetShapeToMesh();
const list<const SMESHDS_Hypothesis*>& aLocalList = _impl->GetHypothesisList( myLocSubShape );
*/
//=============================================================================
-SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::GetSubMesh(GEOM::GEOM_Object_ptr aSubShapeObject,
+SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::GetSubMesh(GEOM::GEOM_Object_ptr aSubShape,
const char* theName )
throw(SALOME::SALOME_Exception)
{
Unexpect aCatch(SALOME_SalomeException);
- if (CORBA::is_nil(aSubShapeObject))
+ if (CORBA::is_nil(aSubShape))
THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference", SALOME::BAD_PARAM);
SMESH::SMESH_subMesh_var subMesh;
SMESH::SMESH_Mesh_var aMesh = _this();
try {
- TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(aSubShapeObject);
+ TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(aSubShape);
//Get or Create the SMESH_subMesh object implementation
// create a new subMesh object servant if there is none for the shape
if ( subMesh->_is_nil() )
- subMesh = createSubMesh( aSubShapeObject );
+ subMesh = createSubMesh( aSubShape );
if ( _gen_i->CanPublishInStudy( subMesh ))
{
SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
SALOMEDS::SObject_wrap aSO =
- _gen_i->PublishSubMesh( study, aMesh, subMesh, aSubShapeObject, theName );
+ _gen_i->PublishSubMesh( study, aMesh, subMesh, aSubShape, theName );
if ( !aSO->_is_nil()) {
// Update Python script
TPythonDump() << aSO << " = " << aMesh << ".GetSubMesh( "
- << aSubShapeObject << ", '" << theName << "' )";
+ << aSubShape << ", '" << theName << "' )";
}
}
}
if ( theSubMesh->_is_nil() )
return;
- GEOM::GEOM_Object_var aSubShapeObject;
+ GEOM::GEOM_Object_var aSubShape;
SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
if ( !aStudy->_is_nil() ) {
// Remove submesh's SObject
anObj->ReferencedObject( aRef.inout() ))
{
CORBA::Object_var obj = aRef->GetObject();
- aSubShapeObject = GEOM::GEOM_Object::_narrow( obj );
+ aSubShape = GEOM::GEOM_Object::_narrow( obj );
}
- // if ( aSubShapeObject->_is_nil() ) // not published shape (IPAL13617)
- // aSubShapeObject = theSubMesh->GetSubShape();
+ // if ( aSubShape->_is_nil() ) // not published shape (IPAL13617)
+ // aSubShape = theSubMesh->GetSubShape();
SALOMEDS::StudyBuilder_var builder = aStudy->NewBuilder();
builder->RemoveObjectWithChildren( anSO );
}
}
- if ( removeSubMesh( theSubMesh, aSubShapeObject.in() ))
+ if ( removeSubMesh( theSubMesh, aSubShape.in() ))
if ( _preMeshInfo )
_preMeshInfo->ForgetOrLoad();
// Update Python script
pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var( _this() )
- << ".CutListOfGroups( " << theMainGroups
+ << ".CutListOfGroups( " << theMainGroups << ", "
<< theToolGroups << ", '" << theName << "' )";
SMESH_CATCH( SMESH::throwCorbaException );
void ClearSubMesh(CORBA::Long ShapeID)
throw (SALOME::SALOME_Exception);
- SMESH::Hypothesis_Status AddHypothesis(GEOM::GEOM_Object_ptr aSubShapeObject,
- SMESH::SMESH_Hypothesis_ptr anHyp)
+ SMESH::Hypothesis_Status AddHypothesis(GEOM::GEOM_Object_ptr aSubShape,
+ SMESH::SMESH_Hypothesis_ptr anHyp,
+ CORBA::String_out anErrorText)
throw (SALOME::SALOME_Exception);
- SMESH::Hypothesis_Status RemoveHypothesis(GEOM::GEOM_Object_ptr aSubShapeObject,
+ SMESH::Hypothesis_Status RemoveHypothesis(GEOM::GEOM_Object_ptr aSubShape,
SMESH::SMESH_Hypothesis_ptr anHyp)
throw (SALOME::SALOME_Exception);
- SMESH::ListOfHypothesis* GetHypothesisList(GEOM::GEOM_Object_ptr aSubShapeObject)
+ SMESH::ListOfHypothesis* GetHypothesisList(GEOM::GEOM_Object_ptr aSubShape)
throw (SALOME::SALOME_Exception);
SMESH::submesh_array* GetSubMeshes()
throw (SALOME::SALOME_Exception);
- SMESH::SMESH_subMesh_ptr GetSubMesh(GEOM::GEOM_Object_ptr aSubShapeObject, const char* theName)
+ SMESH::SMESH_subMesh_ptr GetSubMesh(GEOM::GEOM_Object_ptr aSubShape, const char* theName)
throw (SALOME::SALOME_Exception);
void RemoveSubMesh( SMESH::SMESH_subMesh_ptr theSubMesh )
// Internal methods not available through CORBA
// They are called by corresponding interface methods
- SMESH_Hypothesis::Hypothesis_Status addHypothesis(GEOM::GEOM_Object_ptr aSubShapeObject,
- SMESH::SMESH_Hypothesis_ptr anHyp);
+ SMESH_Hypothesis::Hypothesis_Status addHypothesis(GEOM::GEOM_Object_ptr aSubShape,
+ SMESH::SMESH_Hypothesis_ptr anHyp,
+ std::string* anErrorText=0);
- SMESH_Hypothesis::Hypothesis_Status removeHypothesis(GEOM::GEOM_Object_ptr aSubShapeObject,
+ SMESH_Hypothesis::Hypothesis_Status removeHypothesis(GEOM::GEOM_Object_ptr aSubShape,
SMESH::SMESH_Hypothesis_ptr anHyp);
static SMESH::Hypothesis_Status
algo = self.mesh.smeshpyD.CreateHypothesis("SegmentAroundVertex_0D", "libStdMeshersEngine.so")
pass
status = self.mesh.mesh.AddHypothesis(self.geom, algo)
- TreatHypoStatus(status, "SegmentAroundVertex_0D", name, True)
+ TreatHypoStatus(status, "SegmentAroundVertex_0D", name, True, self.mesh)
#
from salome.smesh.smeshBuilder import IsEqual
comFun = lambda hyp, args: IsEqual(hyp.GetLength(), args[0])
from salome.smesh.smeshBuilder import AssureGeomPublished
AssureGeomPublished( self.mesh, geom )
hyp = self.Hypothesis("ProjectionSource2D", [face,mesh,srcV1,tgtV1,srcV2,tgtV2],
- UseExisting=0)
+ UseExisting=0, toAdd=False)
# it does not seem to be useful to reuse the existing "SourceFace" hypothesis
#UseExisting=UseExisting, CompareMethod=self.CompareSourceFace)
hyp.SetSourceFace( face )
hyp.SetSourceMesh( mesh )
hyp.SetVertexAssociation( srcV1, srcV2, tgtV1, tgtV2 )
+ self.mesh.AddHypothesis(hyp, self.geom)
return hyp
pass # end of StdMeshersBuilder_Projection2D class
raise RuntimeError, "Null or invalid object"
## Prints error message if a hypothesis was not assigned.
-def TreatHypoStatus(status, hypName, geomName, isAlgo):
+def TreatHypoStatus(status, hypName, geomName, isAlgo, mesh):
if isAlgo:
hypType = "algorithm"
else:
hypType = "hypothesis"
pass
+ reason = ""
+ if hasattr( status, "__getitem__" ):
+ status,reason = status[0],status[1]
if status == HYP_UNKNOWN_FATAL :
reason = "for unknown reason"
elif status == HYP_INCOMPATIBLE :
elif status == HYP_HIDING_ALGO:
reason = "it hides algorithms of lower dimensions by generating elements of all dimensions"
elif status == HYP_NEED_SHAPE:
- reason = "Algorithm can't work without shape"
+ reason = "algorithm can't work without shape"
+ elif status == HYP_INCOMPAT_HYPS:
+ pass
else:
return
- hypName = '"' + hypName + '"'
- geomName= '"' + geomName+ '"'
- if status < HYP_UNKNOWN_FATAL and not geomName =='""':
- print hypName, "was assigned to", geomName,"but", reason
- elif not geomName == '""':
- print hypName, "was not assigned to",geomName,":", reason
+ where = geomName
+ if where:
+ where = '"%s"' % geomName
+ if mesh:
+ meshName = GetName( mesh )
+ if meshName and meshName != NO_NAME:
+ where = '"%s" in "%s"' % ( geomName, meshName )
+ if status < HYP_UNKNOWN_FATAL and where:
+ print '"%s" was assigned to %s but %s' %( hypName, where, reason )
+ elif where:
+ print '"%s" was not assigned to %s : %s' %( hypName, where, reason )
else:
- print hypName, "was not assigned:", reason
+ print '"%s" was not assigned : %s' %( hypName, reason )
pass
## Private method. Add geom (sub-shape of the main shape) into the study if not yet there
# @return SMESH.AxisStruct
# @ingroup l1_auxiliary
def GetAxisStruct(self,theObj):
+ import GEOM
edges = self.geompyD.SubShapeAll( theObj, geomBuilder.geomBuilder.ShapeType["EDGE"] )
+ axis = None
if len(edges) > 1:
vertex1, vertex2 = self.geompyD.SubShapeAll( edges[0], geomBuilder.geomBuilder.ShapeType["VERTEX"] )
vertex3, vertex4 = self.geompyD.SubShapeAll( edges[1], geomBuilder.geomBuilder.ShapeType["VERTEX"] )
v2 = [vertex4[0]-vertex3[0], vertex4[1]-vertex3[1], vertex4[2]-vertex3[2]]
normal = [ v1[1]*v2[2]-v2[1]*v1[2], v1[2]*v2[0]-v2[2]*v1[0], v1[0]*v2[1]-v2[0]*v1[1] ]
axis = AxisStruct(vertex1[0], vertex1[1], vertex1[2], normal[0], normal[1], normal[2])
- return axis
+ axis._mirrorType = SMESH.SMESH_MeshEditor.PLANE
elif len(edges) == 1:
vertex1, vertex2 = self.geompyD.SubShapeAll( edges[0], geomBuilder.geomBuilder.ShapeType["VERTEX"] )
p1 = self.geompyD.PointCoordinates( vertex1 )
p2 = self.geompyD.PointCoordinates( vertex2 )
axis = AxisStruct(p1[0], p1[1], p1[2], p2[0]-p1[0], p2[1]-p1[1], p2[2]-p1[2])
- return axis
- return None
+ axis._mirrorType = SMESH.SMESH_MeshEditor.AXIS
+ elif theObj.GetShapeType() == GEOM.VERTEX:
+ x,y,z = self.geompyD.PointCoordinates( theObj )
+ axis = AxisStruct( x,y,z, 1,0,0,)
+ axis._mirrorType = SMESH.SMESH_MeshEditor.POINT
+ return axis
# From SMESH_Gen interface:
# ------------------------
smeshgui.SetMeshIcon( salome.ObjectToID( self.mesh ), False, True )
salome.sg.updateObjBrowser(1)
- ## Computes a tetrahedral mesh using AutomaticLength + MEFISTO + NETGEN
+ ## Computes a tetrahedral mesh using AutomaticLength + MEFISTO + Tetrahedron
# @param fineness [0.0,1.0] defines mesh fineness
# @return True or False
# @ingroup l3_algos_basic
self.Triangle().LengthFromEdges()
pass
if dim > 2 :
- from salome.NETGENPlugin.NETGENPluginBuilder import NETGEN
- self.Tetrahedron(NETGEN)
+ self.Tetrahedron()
pass
return self.Compute()
AssureGeomPublished( self, geom, "shape for %s" % hyp.GetName())
status = self.mesh.AddHypothesis(geom, hyp)
else:
- status = HYP_BAD_GEOMETRY
+ status = HYP_BAD_GEOMETRY,""
hyp_name = GetName( hyp )
geom_name = ""
if geom:
geom_name = geom.GetName()
isAlgo = hyp._narrow( SMESH_Algo )
- TreatHypoStatus( status, hyp_name, geom_name, isAlgo )
+ TreatHypoStatus( status, hyp_name, geom_name, isAlgo, self )
return status
## Return True if an algorithm of hypothesis is assigned to a given shape
# @ingroup l2_grps_create
def MakeGroupByIds(self, groupName, elementType, elemIDs):
group = self.mesh.CreateGroup(elementType, groupName)
- group.Add(elemIDs)
+ if hasattr( elemIDs, "GetIDs" ):
+ if hasattr( elemIDs, "SetMesh" ):
+ elemIDs.SetMesh( self.GetMesh() )
+ group.AddFrom( elemIDs )
+ else:
+ group.Add(elemIDs)
return group
## Creates a mesh group by the given conditions
# @param UnaryOp FT_LogicalNOT or FT_Undefined
# @param Tolerance the tolerance used by FT_BelongToGeom, FT_BelongToSurface,
# FT_LyingOnGeom, FT_CoplanarFaces criteria
- # @return SMESH_Group
+ # @return SMESH_GroupOnFilter
# @ingroup l2_grps_create
def MakeGroup(self,
groupName,
## Creates a mesh group by the given criterion
# @param groupName the name of the mesh group
# @param Criterion the instance of Criterion class
- # @return SMESH_Group
+ # @return SMESH_GroupOnFilter
# @ingroup l2_grps_create
def MakeGroupByCriterion(self, groupName, Criterion):
- aFilterMgr = self.smeshpyD.CreateFilterManager()
- aFilter = aFilterMgr.CreateFilter()
- aCriteria = []
- aCriteria.append(Criterion)
- aFilter.SetCriteria(aCriteria)
- group = self.MakeGroupByFilter(groupName, aFilter)
- aFilterMgr.UnRegister()
- return group
+ return self.MakeGroupByCriteria( groupName, [Criterion] )
## Creates a mesh group by the given criteria (list of criteria)
# @param groupName the name of the mesh group
# @param theCriteria the list of criteria
- # @return SMESH_Group
+ # @param binOp binary operator used when binary operator of criteria is undefined
+ # @return SMESH_GroupOnFilter
# @ingroup l2_grps_create
- def MakeGroupByCriteria(self, groupName, theCriteria):
- aFilterMgr = self.smeshpyD.CreateFilterManager()
- aFilter = aFilterMgr.CreateFilter()
- aFilter.SetCriteria(theCriteria)
+ def MakeGroupByCriteria(self, groupName, theCriteria, binOp=SMESH.FT_LogicalAND):
+ aFilter = self.smeshpyD.GetFilterFromCriteria( theCriteria, binOp )
group = self.MakeGroupByFilter(groupName, aFilter)
- aFilterMgr.UnRegister()
return group
## Creates a mesh group by the given filter
# @param groupName the name of the mesh group
# @param theFilter the instance of Filter class
- # @return SMESH_Group
+ # @return SMESH_GroupOnFilter
# @ingroup l2_grps_create
def MakeGroupByFilter(self, groupName, theFilter):
- group = self.CreateEmptyGroup(theFilter.GetElementType(), groupName)
- theFilter.SetMesh( self.mesh )
- group.AddFrom( theFilter )
+ #group = self.CreateEmptyGroup(theFilter.GetElementType(), groupName)
+ #theFilter.SetMesh( self.mesh )
+ #group.AddFrom( theFilter )
+ group = self.GroupOnFilter( theFilter.GetElementType(), groupName, theFilter )
return group
## Removes a group
## Get measure structure specifying bounding box data of the specified object(s)
# @param IDs single source object or list of source objects or list of nodes/elements IDs
- # @param isElem if @a objects is a list of IDs, @c True value in this parameters specifies that @a objects are elements,
+ # @param isElem if @a IDs is a list of IDs, @c True value in this parameters specifies that @a objects are elements,
# @c False specifies that @a objects are nodes
# @return Measure structure
# @sa BoundingBox()
theFace = -1
return self.editor.Reorient2D( the2DObject, theDirection, theFace, thePoint )
+ ## Reorient faces according to adjacent volumes.
+ # @param the2DObject is a mesh, sub-mesh, group or list of
+ # either IDs of faces or face groups.
+ # @param the3DObject is a mesh, sub-mesh, group or list of IDs of volumes.
+ # @param theOutsideNormal to orient faces to have their normals
+ # pointing either \a outside or \a inside the adjacent volumes.
+ # @return number of reoriented faces.
+ # @ingroup l2_modif_changori
+ def Reorient2DBy3D(self, the2DObject, the3DObject, theOutsideNormal=True ):
+ unRegister = genObjUnRegister()
+ # check the2DObject
+ if not isinstance( the2DObject, list ):
+ the2DObject = [ the2DObject ]
+ elif the2DObject and isinstance( the2DObject[0], int ):
+ the2DObject = self.GetIDSource( the2DObject, SMESH.FACE )
+ unRegister.set( the2DObject )
+ the2DObject = [ the2DObject ]
+ for i,obj2D in enumerate( the2DObject ):
+ if isinstance( obj2D, Mesh ):
+ the2DObject[i] = obj2D.GetMesh()
+ if isinstance( obj2D, list ):
+ the2DObject[i] = self.GetIDSource( obj2D, SMESH.FACE )
+ unRegister.set( the2DObject[i] )
+ # check the3DObject
+ if isinstance( the3DObject, Mesh ):
+ the3DObject = the3DObject.GetMesh()
+ if isinstance( the3DObject, list ):
+ the3DObject = self.GetIDSource( the3DObject, SMESH.VOLUME )
+ unRegister.set( the3DObject )
+ return self.editor.Reorient2DBy3D( the2DObject, the3DObject, theOutsideNormal )
+
## Fuses the neighbouring triangles into quadrangles.
# @param IDsOfElements The triangles to be fused,
# @param theCriterion is a numerical functor, in terms of enum SMESH.FunctorType, used to
# @param MakeGroups forces the generation of new groups from existing ones (if Copy)
# @return list of created groups (SMESH_GroupBase) if MakeGroups=True, empty list otherwise
# @ingroup l2_modif_trsf
- def Mirror(self, IDsOfElements, Mirror, theMirrorType, Copy=0, MakeGroups=False):
+ def Mirror(self, IDsOfElements, Mirror, theMirrorType=None, Copy=0, MakeGroups=False):
if IDsOfElements == []:
IDsOfElements = self.GetElementsId()
if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
- Mirror = self.smeshpyD.GetAxisStruct(Mirror)
- self.mesh.SetParameters(Mirror.parameters)
+ Mirror = self.smeshpyD.GetAxisStruct(Mirror)
+ theMirrorType = Mirror._mirrorType
+ else:
+ self.mesh.SetParameters(Mirror.parameters)
if Copy and MakeGroups:
return self.editor.MirrorMakeGroups(IDsOfElements, Mirror, theMirrorType)
self.editor.Mirror(IDsOfElements, Mirror, theMirrorType, Copy)
# @param NewMeshName a name of the new mesh to create
# @return instance of Mesh class
# @ingroup l2_modif_trsf
- def MirrorMakeMesh(self, IDsOfElements, Mirror, theMirrorType, MakeGroups=0, NewMeshName=""):
+ def MirrorMakeMesh(self, IDsOfElements, Mirror, theMirrorType=0, MakeGroups=0, NewMeshName=""):
if IDsOfElements == []:
IDsOfElements = self.GetElementsId()
if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
- Mirror = self.smeshpyD.GetAxisStruct(Mirror)
- self.mesh.SetParameters(Mirror.parameters)
+ Mirror = self.smeshpyD.GetAxisStruct(Mirror)
+ theMirrorType = Mirror._mirrorType
+ else:
+ self.mesh.SetParameters(Mirror.parameters)
mesh = self.editor.MirrorMakeMesh(IDsOfElements, Mirror, theMirrorType,
MakeGroups, NewMeshName)
return Mesh(self.smeshpyD,self.geompyD,mesh)
# @param MakeGroups forces the generation of new groups from existing ones (if Copy)
# @return list of created groups (SMESH_GroupBase) if MakeGroups=True, empty list otherwise
# @ingroup l2_modif_trsf
- def MirrorObject (self, theObject, Mirror, theMirrorType, Copy=0, MakeGroups=False):
+ def MirrorObject (self, theObject, Mirror, theMirrorType=None, Copy=0, MakeGroups=False):
if ( isinstance( theObject, Mesh )):
theObject = theObject.GetMesh()
if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
- Mirror = self.smeshpyD.GetAxisStruct(Mirror)
- self.mesh.SetParameters(Mirror.parameters)
+ Mirror = self.smeshpyD.GetAxisStruct(Mirror)
+ theMirrorType = Mirror._mirrorType
+ else:
+ self.mesh.SetParameters(Mirror.parameters)
if Copy and MakeGroups:
return self.editor.MirrorObjectMakeGroups(theObject, Mirror, theMirrorType)
self.editor.MirrorObject(theObject, Mirror, theMirrorType, Copy)
# @param NewMeshName the name of the new mesh to create
# @return instance of Mesh class
# @ingroup l2_modif_trsf
- def MirrorObjectMakeMesh (self, theObject, Mirror, theMirrorType,MakeGroups=0, NewMeshName=""):
+ def MirrorObjectMakeMesh (self, theObject, Mirror, theMirrorType=0,MakeGroups=0,NewMeshName=""):
if ( isinstance( theObject, Mesh )):
theObject = theObject.GetMesh()
- if (isinstance(Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
- Mirror = self.smeshpyD.GetAxisStruct(Mirror)
- self.mesh.SetParameters(Mirror.parameters)
+ if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
+ Mirror = self.smeshpyD.GetAxisStruct(Mirror)
+ theMirrorType = Mirror._mirrorType
+ else:
+ self.mesh.SetParameters(Mirror.parameters)
mesh = self.editor.MirrorObjectMakeMesh(theObject, Mirror, theMirrorType,
MakeGroups, NewMeshName)
return Mesh( self.smeshpyD,self.geompyD,mesh )
## Return minimal and maximal value of a given functor.
# @param funType a functor type, an item of SMESH.FunctorType enum
# (one of SMESH.FunctorType._items)
+ # @param meshPart a part of mesh (group, sub-mesh) to treat
# @return tuple (min,max)
# @ingroup l1_measurements
- def GetMinMax(self, funType):
+ def GetMinMax(self, funType, meshPart=None):
+ unRegister = genObjUnRegister()
+ if isinstance( meshPart, list ):
+ meshPart = self.GetIDSource( meshPart, SMESH.ALL )
+ unRegister.set( meshPart )
+ if isinstance( meshPart, Mesh ):
+ meshPart = meshPart.mesh
fun = self._getFunctor( funType )
if fun:
- hist = fun.GetHistogram( 1, False )
+ if meshPart:
+ hist = fun.GetLocalHistogram( 1, False, meshPart )
+ else:
+ hist = fun.GetHistogram( 1, False )
if hist:
return hist[0].min, hist[0].max
return None
## Private method
def Hypothesis (self, hyp, args=[], so="libStdMeshersEngine.so",
- UseExisting=0, CompareMethod=""):
+ UseExisting=0, CompareMethod="", toAdd=True):
from salome.smesh.smeshBuilder import TreatHypoStatus, GetName
hypo = None
if UseExisting:
geomName=""
if self.geom:
geomName = GetName(self.geom)
- status = self.mesh.mesh.AddHypothesis(self.geom, hypo)
- TreatHypoStatus( status, GetName(hypo), geomName, 0 )
+ if toAdd:
+ status = self.mesh.mesh.AddHypothesis(self.geom, hypo)
+ TreatHypoStatus( status, GetName(hypo), geomName, 0, self.mesh )
return hypo
## Returns entry of the shape to mesh in the study
if faces and isinstance( faces[0], geomBuilder.GEOM._objref_GEOM_Object ):
faces = [ self.mesh.geompyD.GetSubShapeID(self.mesh.geom, f) for f in faces ]
hyp = self.Hypothesis("ViscousLayers",
- [thickness, numberOfLayers, stretchFactor, faces])
+ [thickness, numberOfLayers, stretchFactor, faces, isFacesToIgnore],
+ toAdd=False)
hyp.SetTotalThickness(thickness)
hyp.SetNumberLayers(numberOfLayers)
hyp.SetStretchFactor(stretchFactor)
hyp.SetFaces(faces, isFacesToIgnore)
+ self.mesh.AddHypothesis( hyp, self.geom )
return hyp
## Defines "ViscousLayers2D" hypothesis to give parameters of layers of quadrilateral
if edges and isinstance( edges[0], geomBuilder.GEOM._objref_GEOM_Object ):
edges = [ self.mesh.geompyD.GetSubShapeID(self.mesh.geom, f) for f in edges ]
hyp = self.Hypothesis("ViscousLayers2D",
- [thickness, numberOfLayers, stretchFactor,
- edges, isEdgesToIgnore])
+ [thickness, numberOfLayers, stretchFactor, edges, isEdgesToIgnore],
+ toAdd=False)
hyp.SetTotalThickness(thickness)
hyp.SetNumberLayers(numberOfLayers)
hyp.SetStretchFactor(stretchFactor)
hyp.SetEdges(edges, isEdgesToIgnore)
+ self.mesh.AddHypothesis( hyp, self.geom )
return hyp
## Transform a list of either edges or tuples (edge, 1st_vertex_of_edge)
#include <BRepAdaptor_Curve.hxx>
#include <BRepAdaptor_Surface.hxx>
+#include <BRepBndLib.hxx>
#include <BRepMesh_IncrementalMesh.hxx>
#include <BRep_Tool.hxx>
#include <Bnd_B3d.hxx>
+#include <Bnd_Box.hxx>
#include <GCPnts_AbscissaPoint.hxx>
#include <GeomAdaptor_Curve.hxx>
#include <Geom_Curve.hxx>
vector< int > _elementIDs;
};
//================================================================================
- /*!
- * \brief BRepMesh_IncrementalMesh with access to its protected Bnd_Box
- */
- struct IncrementalMesh : public BRepMesh_IncrementalMesh
- {
- IncrementalMesh(const TopoDS_Shape& shape,
- const Standard_Real deflection,
- const bool relative):
- BRepMesh_IncrementalMesh( shape, deflection, relative )
- {
- }
- Bnd_B3d GetBox() const
- {
- Standard_Real TXmin, TYmin, TZmin, TXmax, TYmax, TZmax;
- myBox.Get(TXmin, TYmin, TZmin, TXmax, TYmax, TZmax);
- Bnd_B3d bb;
- bb.Add( gp_XYZ( TXmin, TYmin, TZmin ));
- bb.Add( gp_XYZ( TXmax, TYmax, TZmax ));
- return bb;
- }
- };
- //================================================================================
/*!
* \brief Link of two nodes
*/
TopExp::MapShapes( theMesh.GetShapeToMesh(), TopAbs_FACE, faceMap );
// Triangulate the shape with the given deflection ?????????
+ {
+ BRepMesh_IncrementalMesh im( theMesh.GetShapeToMesh(), myHyp->GetDeflection(), /*isRelatif=*/0);
+ }
+
+ // get a bnd box
Bnd_B3d box;
{
- IncrementalMesh im( theMesh.GetShapeToMesh(), myHyp->GetDeflection(), /*Relatif=*/false);
- box = im.GetBox();
+ Bnd_Box aBox;
+ BRepBndLib::Add( theMesh.GetShapeToMesh(), aBox);
+ Standard_Real TXmin, TYmin, TZmin, TXmax, TYmax, TZmax;
+ aBox.Get(TXmin, TYmin, TZmin, TXmax, TYmax, TZmax);
+ box.Add( gp_XYZ( TXmin, TYmin, TZmin ));
+ box.Add( gp_XYZ( TXmax, TYmax, TZmax ));
}
// *theProgress = 0.3;
list< int > nbEdges;
int nbW = SMESH_Block::GetOrderedEdges (face, edges, nbEdges);
if ( nbW > 1 ) {
- // select a WIRE
+ // select a WIRE - remove EDGEs of irrelevant WIREs from edges
list< TopoDS_Edge >::iterator e = edges.begin(), eEnd = e;
list< int >::iterator nE = nbEdges.begin();
- for ( ; nbW ; ++nE, --nbW )
+ for ( ; nbW > 0; ++nE, --nbW )
{
std::advance( eEnd, *nE );
for ( ; e != eEnd; ++e )
( std::find( &nShapeIds[0], nShapeIdsEnd, id ) != nShapeIdsEnd ))
{
edges.erase( eEnd, edges.end() ); // remove rest wires
- e = eEnd;
+ e = eEnd = edges.end();
+ --e;
nbW = 0;
break;
}
}
if ( nbW > 0 )
- edges.erase( edges.begin(), eEnd ); // remove a current wire
+ edges.erase( edges.begin(), eEnd ); // remove a current irrelevant wire
}
}
// rotate edges to have the first one at least partially out of the hexa
SMESH_Mesh & theMesh,
const bool theIgnoreMediumNodes,
TError & theError,
- SMESH_ProxyMesh::Ptr theProxyMesh)
+ SMESH_ProxyMesh::Ptr theProxyMesh,
+ const bool theCheckVertexNodes)
{
list< TopoDS_Edge > edges, internalEdges;
list< int > nbEdgesInWires;
// as StdMeshers_FaceSide::GetUVPtStruct() requires
if ( wireEdges.front().Orientation() != TopAbs_INTERNAL ) // Issue 0020676
{
- while ( !SMESH_Algo::VertexNode( TopExp::FirstVertex( wireEdges.front(), true),
- theMesh.GetMeshDS()))
- {
- wireEdges.splice(wireEdges.end(), wireEdges,
- wireEdges.begin(), ++wireEdges.begin());
- if ( from->IsSame( wireEdges.front() )) {
- theError = TError
- ( new SMESH_ComputeError(COMPERR_BAD_INPUT_MESH,"No nodes on vertices"));
- return TSideVector(0);
+ if ( theCheckVertexNodes )
+ while ( !SMESH_Algo::VertexNode( TopExp::FirstVertex( wireEdges.front(), true),
+ theMesh.GetMeshDS()))
+ {
+ wireEdges.splice(wireEdges.end(), wireEdges,
+ wireEdges.begin(), ++wireEdges.begin());
+ if ( from->IsSame( wireEdges.front() )) {
+ theError = TError
+ ( new SMESH_ComputeError(COMPERR_BAD_INPUT_MESH,"No nodes on vertices"));
+ return TSideVector(0);
+ }
}
- }
}
else if ( *nbE > 1 ) // Issue 0020676 (Face_pb_netgen.brep) - several internal edges in a wire
{
SMESH_Mesh & theMesh,
const bool theIgnoreMediumNodes,
TError & theError,
- SMESH_ProxyMesh::Ptr theProxyMesh = SMESH_ProxyMesh::Ptr());
+ SMESH_ProxyMesh::Ptr theProxyMesh = SMESH_ProxyMesh::Ptr(),
+ const bool theCheckVertexNodes=true);
/*!
* \brief Change orientation of side geometry
*/
return true;
}
+ // only StdMeshers_ViscousLayers can be used
aStatus = HYP_OK;
for ( ; h != hyps.end(); ++h )
{
- string hypName = (*h)->GetName();
- if ( find( _compatibleHypothesis.begin(),_compatibleHypothesis.end(),hypName )
- != _compatibleHypothesis.end() )
- {
- _viscousLayersHyp = dynamic_cast< const StdMeshers_ViscousLayers*> ( *h );
- }
- else
- {
- aStatus = HYP_INCOMPATIBLE;
- }
+ if ( !(_viscousLayersHyp = dynamic_cast< const StdMeshers_ViscousLayers*> ( *h )))
+ break;
}
-
if ( !_viscousLayersHyp )
aStatus = HYP_INCOMPATIBLE;
+ else
+ error( _viscousLayersHyp->CheckHypothesis( aMesh, aShape, aStatus ));
return aStatus == HYP_OK;
}
for ( int i = 0; i < 6; ++i )
{
const TopoDS_Face& sideF = aCubeSide[i]._quad->face;
- if ( !SMESH_MesherHelper::IsSameElemGeometry( meshDS->MeshElements( sideF ),
- SMDSGeom_QUADRANGLE,
+ const SMESHDS_SubMesh* smDS =
+ proxymesh ? proxymesh->GetSubMesh( sideF ) : meshDS->MeshElements( sideF );
+ if ( !SMESH_MesherHelper::IsSameElemGeometry( smDS, SMDSGeom_QUADRANGLE,
/*nullSubMeshRes=*/false ))
{
SMESH_ComputeErrorPtr err = ComputePentahedralMesh(aMesh, aShape, proxymesh.get());
_compatibleHypothesis.push_back("ImportSource1D");
}
-//=============================================================================
-/*!
- * Check presence of a hypothesis
- */
-//=============================================================================
-
-bool StdMeshers_Import_1D::CheckHypothesis
- (SMESH_Mesh& aMesh,
- const TopoDS_Shape& aShape,
- SMESH_Hypothesis::Hypothesis_Status& aStatus)
-{
- _sourceHyp = 0;
-
- const list <const SMESHDS_Hypothesis * >&hyps = GetUsedHypothesis(aMesh, aShape);
- if ( hyps.size() == 0 )
- {
- aStatus = SMESH_Hypothesis::HYP_MISSING;
- return false; // can't work with no hypothesis
- }
-
- if ( hyps.size() > 1 )
- {
- aStatus = SMESH_Hypothesis::HYP_ALREADY_EXIST;
- return false;
- }
-
- const SMESHDS_Hypothesis *theHyp = hyps.front();
-
- string hypName = theHyp->GetName();
-
- if (hypName == _compatibleHypothesis.front())
- {
- _sourceHyp = (StdMeshers_ImportSource1D *)theHyp;
- aStatus = SMESH_Hypothesis::HYP_OK;
- return true;
- }
-
- aStatus = SMESH_Hypothesis::HYP_INCOMPATIBLE;
- return true;
-}
-
//================================================================================
namespace // INTERNAL STUFF
//================================================================================
bool rmGroups = (d->_copyGroupSubM.erase( sm ) && d->_copyGroupSubM.empty()) || rmMesh;
if ( rmMesh )
d->removeImportedMesh( sm->GetFather()->GetMeshDS() );
- if ( rmGroups && data )
+ if ( rmGroups && data && data->myType == SRC_HYP )
d->removeGroups( sm, data->_srcHyp );
}
}
// remove imported mesh and groups
d->removeImportedMesh( sm->GetFather()->GetMeshDS() );
- if ( data )
+ if ( data && data->myType == SRC_HYP )
d->removeGroups( sm, data->_srcHyp );
// clear the rest submeshes
{
SMESH_subMesh* subM = *sub;
_ListenerData* hypData = (_ListenerData*) subM->GetEventListenerData( get() );
- if ( hypData )
+ if ( hypData && hypData->myType == SRC_HYP )
d->removeGroups( sm, hypData->_srcHyp );
subM->ComputeStateEngine( SMESH_subMesh::CLEAN );
if ( sm->GetSubShape().ShapeType() == TopAbs_FACE )
sm->ComputeSubMeshStateEngine( SMESH_subMesh::CLEAN );
}
- if ( data )
+ if ( data && data->myType == SRC_HYP )
d->trackHypParams( sm, data->_srcHyp );
d->_n2n.clear();
d->_e2e.clear();
} // namespace
+//=============================================================================
+/*!
+ * Check presence of a hypothesis
+ */
+//=============================================================================
+
+bool StdMeshers_Import_1D::CheckHypothesis
+ (SMESH_Mesh& aMesh,
+ const TopoDS_Shape& aShape,
+ SMESH_Hypothesis::Hypothesis_Status& aStatus)
+{
+ _sourceHyp = 0;
+
+ const list <const SMESHDS_Hypothesis * >&hyps = GetUsedHypothesis(aMesh, aShape);
+ if ( hyps.size() == 0 )
+ {
+ aStatus = SMESH_Hypothesis::HYP_MISSING;
+ return false; // can't work with no hypothesis
+ }
+
+ if ( hyps.size() > 1 )
+ {
+ aStatus = SMESH_Hypothesis::HYP_ALREADY_EXIST;
+ return false;
+ }
+
+ const SMESHDS_Hypothesis *theHyp = hyps.front();
+
+ string hypName = theHyp->GetName();
+
+ if (hypName == _compatibleHypothesis.front())
+ {
+ _sourceHyp = (StdMeshers_ImportSource1D *)theHyp;
+ aStatus = _sourceHyp->GetGroups().empty() ? HYP_BAD_PARAMETER : HYP_OK;
+ if ( aStatus == HYP_BAD_PARAMETER )
+ _Listener::waitHypModification( aMesh.GetSubMesh( aShape ));
+ return aStatus == HYP_OK;
+ }
+
+ aStatus = SMESH_Hypothesis::HYP_INCOMPATIBLE;
+ return false;
+}
//=============================================================================
/*!
_edgeLength = 0;
_maxElementArea = 0;
+ if ( !error( StdMeshers_ViscousLayers2D::CheckHypothesis( aMesh, aShape, aStatus )))
+ return false;
+
list <const SMESHDS_Hypothesis * >::const_iterator itl;
const SMESHDS_Hypothesis *theHyp;
using namespace std;
#define RETURN_BAD_RESULT(msg) { MESSAGE(")-: Error: " << msg); return false; }
-#define gpXYZ(n) gp_XYZ(n->X(),n->Y(),n->Z())
-#define SHOWYXZ(msg, xyz) // {\
-// gp_Pnt p (xyz); \
-// cout << msg << " ("<< p.X() << "; " <<p.Y() << "; " <<p.Z() << ") " <<endl;\
-// }
+#define gpXYZ(n) SMESH_TNodeXYZ(n)
+
#ifdef _DEBUG_
#define DBGOUT(msg) //cout << msg << endl;
+#define SHOWYXZ(msg, xyz) \
+ // { gp_Pnt p (xyz); \
+ // cout << msg << " ("<< p.X() << "; " <<p.Y() << "; " <<p.Z() << ") " <<endl; }
#else
#define DBGOUT(msg)
+#define SHOWYXZ(msg, xyz)
#endif
namespace TAssocTool = StdMeshers_ProjectionUtils;
( sm->NbElements() > 0 ) &&
( !theHelper.IsSameElemGeometry( sm, SMDSGeom_QUADRANGLE ) ))
{
- faceFound;
+ faceFound = true;
break;
}
if ( !faceFound )
*/
//================================================================================
- double normAngle(const TopoDS_Edge & E1, const TopoDS_Edge & E2, const TopoDS_Face & F)
- {
- return SMESH_MesherHelper::GetAngle( E1, E2, F ) / ( 0.5 * M_PI );
- }
+ // double normAngle(const TopoDS_Edge & E1, const TopoDS_Edge & E2, const TopoDS_Face & F)
+ // {
+ // return SMESH_MesherHelper::GetAngle( E1, E2, F ) / ( 0.5 * M_PI );
+ // }
//================================================================================
/*!
// create a node
node = meshDS->AddNode( coords.X(), coords.Y(), coords.Z() );
meshDS->SetNodeInVolume( node, volumeID );
+
+ if ( _computeCanceled )
+ return false;
}
} // loop on bottom nodes
}
TProjction1dAlgo* projector1D = TProjction1dAlgo::instance( this );
StdMeshers_Quadrangle_2D* quadAlgo = TQuadrangleAlgo::instance( this, myHelper );
- SMESH_HypoFilter hyp1dFilter( SMESH_HypoFilter::IsAlgo(),/*not=*/true);
- hyp1dFilter.And( SMESH_HypoFilter::HasDim( 1 ));
- hyp1dFilter.And( SMESH_HypoFilter::IsMoreLocalThan( thePrism.myShape3D, *mesh ));
+ // SMESH_HypoFilter hyp1dFilter( SMESH_HypoFilter::IsAlgo(),/*not=*/true);
+ // hyp1dFilter.And( SMESH_HypoFilter::HasDim( 1 ));
+ // hyp1dFilter.And( SMESH_HypoFilter::IsMoreLocalThan( thePrism.myShape3D, *mesh ));
// Discretize equally 'vertical' EDGEs
// -----------------------------------
// find source FACE sides for projection: either already computed ones or
// the 'most composite' ones
- multimap< int, int > wgt2quad;
- for ( size_t iW = 0; iW != thePrism.myWallQuads.size(); ++iW )
+ const size_t nbWalls = thePrism.myWallQuads.size();
+ vector< int > wgt( nbWalls, 0 ); // "weight" of a wall
+ for ( size_t iW = 0; iW != nbWalls; ++iW )
{
Prism_3D::TQuadList::const_iterator quad = thePrism.myWallQuads[iW].begin();
- int wgt = 0; // "weight"
for ( ; quad != thePrism.myWallQuads[iW].end(); ++quad )
{
StdMeshers_FaceSidePtr lftSide = (*quad)->side[ QUAD_LEFT_SIDE ];
for ( int i = 0; i < lftSide->NbEdges(); ++i )
{
- ++wgt;
+ ++wgt[ iW ];
const TopoDS_Edge& E = lftSide->Edge(i);
if ( mesh->GetSubMesh( E )->IsMeshComputed() )
- wgt += 10;
- else if ( mesh->GetHypothesis( E, hyp1dFilter, true )) // local hypothesis!
- wgt += 100;
+ {
+ wgt[ iW ] += 100;
+ wgt[ myHelper->WrapIndex( iW+1, nbWalls)] += 10;
+ wgt[ myHelper->WrapIndex( iW-1, nbWalls)] += 10;
+ }
+ // else if ( mesh->GetHypothesis( E, hyp1dFilter, true )) // local hypothesis!
+ // wgt += 100;
}
}
- wgt2quad.insert( make_pair( wgt, iW ));
-
// in quadratic mesh, pass ignoreMediumNodes to quad sides
if ( myHelper->GetIsQuadratic() )
{
(*quad)->side[ i ].grid->SetIgnoreMediumNodes( true );
}
}
+ multimap< int, int > wgt2quad;
+ for ( size_t iW = 0; iW != nbWalls; ++iW )
+ wgt2quad.insert( make_pair( wgt[ iW ], iW ));
// Project 'vertical' EDGEs, from left to right
multimap< int, int >::reverse_iterator w2q = wgt2quad.rbegin();
{
const TopoDS_Edge& tgtE = rgtSide->Edge(i);
SMESH_subMesh* tgtSM = mesh->GetSubMesh( tgtE );
- if (( isTgtEdgeComputed[ i ] = tgtSM->IsMeshComputed() )) {
+ if ( !( isTgtEdgeComputed[ i ] = tgtSM->IsMeshComputed() )) {
+ tgtSM->ComputeSubMeshStateEngine( SMESH_subMesh::COMPUTE );
+ tgtSM->ComputeStateEngine ( SMESH_subMesh::COMPUTE );
+ }
+ if ( tgtSM->IsMeshComputed() ) {
++nbTgtMeshed;
nbTgtSegments += tgtSM->GetSubMeshDS()->NbElements();
}
{
if ( nbTgtSegments != nbSrcSegments )
{
- for ( int i = 0; i < lftSide->NbEdges(); ++i )
- addBadInputElements( meshDS->MeshElements( lftSide->Edge( i )));
+ bool badMeshRemoved = false;
+ // remove just computed segments
for ( int i = 0; i < rgtSide->NbEdges(); ++i )
- addBadInputElements( meshDS->MeshElements( rgtSide->Edge( i )));
- return toSM( error( TCom("Different nb of segment on logically vertical edges #")
- << shapeID( lftSide->Edge(0) ) << " and #"
- << shapeID( rgtSide->Edge(0) ) << ": "
- << nbSrcSegments << " != " << nbTgtSegments ));
+ if ( !isTgtEdgeComputed[ i ])
+ {
+ const TopoDS_Edge& tgtE = rgtSide->Edge(i);
+ SMESH_subMesh* tgtSM = mesh->GetSubMesh( tgtE );
+ tgtSM->ComputeStateEngine( SMESH_subMesh::CLEAN );
+ badMeshRemoved = true;
+ nbTgtMeshed--;
+ }
+ if ( !badMeshRemoved )
+ {
+ for ( int i = 0; i < lftSide->NbEdges(); ++i )
+ addBadInputElements( meshDS->MeshElements( lftSide->Edge( i )));
+ for ( int i = 0; i < rgtSide->NbEdges(); ++i )
+ addBadInputElements( meshDS->MeshElements( rgtSide->Edge( i )));
+ return toSM( error( TCom("Different nb of segment on logically vertical edges #")
+ << shapeID( lftSide->Edge(0) ) << " and #"
+ << shapeID( rgtSide->Edge(0) ) << ": "
+ << nbSrcSegments << " != " << nbTgtSegments ));
+ }
+ }
+ else // if ( nbTgtSegments == nbSrcSegments )
+ {
+ continue;
}
- continue;
}
// Compute 'vertical projection'
if ( nbTgtMeshed == 0 )
// new nodes are on different EDGEs; put one of them on VERTEX
const int edgeIndex = rgtSide->EdgeIndex( srcNodeStr[ iN-1 ].normParam );
const double vertexParam = rgtSide->LastParameter( edgeIndex );
- const gp_Pnt p = BRep_Tool::Pnt( rgtSide->LastVertex( edgeIndex ));
+ TopoDS_Vertex vertex = rgtSide->LastVertex( edgeIndex );
+ const SMDS_MeshNode* vn = SMESH_Algo::VertexNode( vertex, meshDS );
+ const gp_Pnt p = BRep_Tool::Pnt( vertex );
const int isPrev = ( Abs( srcNodeStr[ iN-1 ].normParam - vertexParam ) <
Abs( srcNodeStr[ iN ].normParam - vertexParam ));
meshDS->UnSetNodeOnShape( newNodes[ iN-isPrev ] );
- meshDS->SetNodeOnVertex ( newNodes[ iN-isPrev ], rgtSide->LastVertex( edgeIndex ));
+ meshDS->SetNodeOnVertex ( newNodes[ iN-isPrev ], vertex );
meshDS->MoveNode ( newNodes[ iN-isPrev ], p.X(), p.Y(), p.Z() );
id2type.first = newNodes[ iN-(1-isPrev) ]->getshapeId();
+ if ( vn )
+ {
+ SMESH_MeshEditor::TListOfListOfNodes lln( 1, list< const SMDS_MeshNode* >() );
+ lln.back().push_back ( vn );
+ lln.back().push_front( newNodes[ iN-isPrev ] ); // to keep
+ SMESH_MeshEditor( mesh ).MergeNodes( lln );
+ }
}
SMDS_MeshElement* newEdge = myHelper->AddEdge( newNodes[ iN-1 ], newNodes[ iN ] );
meshDS->SetMeshElementOnShape( newEdge, id2type.first );
if ( !botSMDS || botSMDS->NbElements() == 0 )
{
- _gen->Compute( *myHelper->GetMesh(), botSM->GetSubShape() );
+ _gen->Compute( *myHelper->GetMesh(), botSM->GetSubShape(), /*aShapeOnly=*/true );
botSMDS = botSM->GetSubMeshDS();
if ( !botSMDS || botSMDS->NbElements() == 0 )
return toSM( error(TCom("No elements on face #") << botSM->GetId() ));
}
if ( !edge.IsNull() )
{
- double u1 = myHelper.GetNodeU( edge, nn[0] );
- double u3 = myHelper.GetNodeU( edge, nn[2] );
+ double u1 = myHelper.GetNodeU( edge, nn[0], nn[2] );
+ double u3 = myHelper.GetNodeU( edge, nn[2], nn[0] );
double u = u1 * ( 1 - hR ) + u3 * hR;
TopLoc_Location loc; double f,l;
Handle(Geom_Curve) curve = BRep_Tool::Curve( edge,loc,f,l );
TShapePairsList::iterator s1_s2 = shapesQueue.begin();
for ( ; s1_s2 != shapesQueue.end(); ++s1_s2 )
{
+ if ( theMap.IsBound( s1_s2->first )) // avoid re-binding for a seam edge
+ continue; // to avoid this: Forward seam -> Reversed seam
InsertAssociation( s1_s2->first, s1_s2->second, theMap );
TopoDS_Iterator s1It( s1_s2->first), s2It( s1_s2->second );
for ( ; s1It.More(); s1It.Next(), s2It.Next() )
mesh->GetHypotheses( shape, hypoFilter, hyps, true, &assignedTo );
if ( nbAlgos > 1 ) // concurrent algos
{
- list<SMESH_subMesh*> smList; // where an algo is assigned
+ vector<SMESH_subMesh*> smList; // where an algo is assigned
list< TopoDS_Shape >::iterator shapeIt = assignedTo.begin();
for ( ; shapeIt != assignedTo.end(); ++shapeIt )
smList.push_back( mesh->GetSubMesh( *shapeIt ));
}
else
{
- subMesh->SetEventListener( getSrcSubMeshListener(),
- SMESH_subMeshEventListenerData::MakeData( subMesh ),
- srcShapeSM );
+ if ( SMESH_subMeshEventListenerData* data =
+ srcShapeSM->GetEventListenerData( getSrcSubMeshListener() ))
+ {
+ bool alreadyIn =
+ (std::find( data->mySubMeshes.begin(),
+ data->mySubMeshes.end(), subMesh ) != data->mySubMeshes.end() );
+ if ( !alreadyIn )
+ data->mySubMeshes.push_back( subMesh );
+ }
+ else
+ {
+ subMesh->SetEventListener( getSrcSubMeshListener(),
+ SMESH_subMeshEventListenerData::MakeData( subMesh ),
+ srcShapeSM );
+ }
}
}
}
!SMESH_MesherHelper::IsSubShape( edge, _sourceHypo->GetSourceFace() ))
{
theStatus = HYP_BAD_PARAMETER;
+ error("Invalid source vertices");
SCRUTE((edge.IsNull()));
SCRUTE((SMESH_MesherHelper::IsSubShape( edge, srcMesh )));
SCRUTE((SMESH_MesherHelper::IsSubShape( edge, _sourceHypo->GetSourceFace() )));
if ( edge.IsNull() || !SMESH_MesherHelper::IsSubShape( edge, tgtMesh ))
{
theStatus = HYP_BAD_PARAMETER;
+ error("Invalid target vertices");
SCRUTE((edge.IsNull()));
SCRUTE((SMESH_MesherHelper::IsSubShape( edge, tgtMesh )));
}
!SMESH_MesherHelper::IsSubShape( edge, theShape ))
{
theStatus = HYP_BAD_PARAMETER;
+ error("Invalid target vertices");
SCRUTE((SMESH_MesherHelper::IsSubShape( edge, theShape )));
}
}
( srcMesh == tgtMesh && theShape == _sourceHypo->GetSourceFace() ))
{
theStatus = HYP_BAD_PARAMETER;
+ error("Invalid source face");
SCRUTE((SMESH_MesherHelper::IsSubShape( _sourceHypo->GetSourceFace(), srcMesh )));
SCRUTE((srcMesh == tgtMesh));
SCRUTE(( theShape == _sourceHypo->GetSourceFace() ));
SMESH_Mesh * srcMesh,
const TAssocTool::TShapeShapeMap& shape2ShapeMap)
{
- MESSAGE("projectPartner");
- const double tol = 1.e-7*srcMesh->GetMeshDS()->getMaxDim();
+ SMESHDS_Mesh* tgtMeshDS = tgtMesh->GetMeshDS();
+ SMESHDS_Mesh* srcMeshDS = srcMesh->GetMeshDS();
+
+ const double tol = 1.e-7 * srcMeshDS->getMaxDim();
gp_Trsf trsf; // transformation to get location of target nodes from source ones
if ( tgtFace.IsPartner( srcFace ))
else
pOK = (( tgtP.Distance( tgtPP[0] ) > tol*tol ) &&
( tgtPP.size() == 1 || tgtP.Distance( tgtPP[1] ) > tol*tol ));
- //cout << "V - nS " << p._node->GetID() << " - nT " << SMESH_Algo::VertexNode(TopoDS::Vertex( tgtShape),tgtMesh->GetMeshDS())->GetID() << endl;
+ //cout << "V - nS " << p._node->GetID() << " - nT " << SMESH_Algo::VertexNode(TopoDS::Vertex( tgtShape),tgtMeshDS)->GetID() << endl;
}
else if ( tgtPP.size() > 0 )
{
- if ( SMESHDS_SubMesh* tgtSmds = tgtMesh->GetMeshDS()->MeshElements( tgtShape ))
+ if ( SMESHDS_SubMesh* tgtSmds = tgtMeshDS->MeshElements( tgtShape ))
{
double srcDist = srcPP[0].Distance( p );
double eTol = BRep_Tool::Tolerance( TopoDS::Edge( tgtShape ));
map<const SMDS_MeshNode* , const SMDS_MeshNode*> src2tgtNodes;
map<const SMDS_MeshNode* , const SMDS_MeshNode*>::iterator srcN_tgtN;
- for ( TopExp_Explorer srcEdge( srcFace, TopAbs_EDGE); srcEdge.More(); srcEdge.Next() )
+ bool tgtEdgesMeshed = false;
+ for ( TopExp_Explorer srcExp( srcFace, TopAbs_EDGE); srcExp.More(); srcExp.Next() )
{
- const TopoDS_Shape& tgtEdge = shape2ShapeMap( srcEdge.Current(), /*isSrc=*/true );
+ const TopoDS_Shape& srcEdge = srcExp.Current();
+ const TopoDS_Shape& tgtEdge = shape2ShapeMap( srcEdge, /*isSrc=*/true );
+ tgtEdgesMeshed != tgtMesh->GetSubMesh( tgtEdge )->IsEmpty();
+
+ if ( srcMesh->GetSubMesh( srcEdge )->IsEmpty() ||
+ tgtMesh->GetSubMesh( tgtEdge )->IsEmpty() )
+ continue;
map< double, const SMDS_MeshNode* > srcNodes, tgtNodes;
- if ( !SMESH_Algo::GetSortedNodesOnEdge( srcMesh->GetMeshDS(),
- TopoDS::Edge( srcEdge.Current() ),
- /*ignoreMediumNodes = */true,
- srcNodes )
+ if (( ! SMESH_Algo::GetSortedNodesOnEdge( srcMeshDS,
+ TopoDS::Edge( srcEdge ),
+ /*ignoreMediumNodes = */true,
+ srcNodes ))
||
- !SMESH_Algo::GetSortedNodesOnEdge( tgtMesh->GetMeshDS(),
- TopoDS::Edge( tgtEdge ),
- /*ignoreMediumNodes = */true,
- tgtNodes )
+ ( ! SMESH_Algo::GetSortedNodesOnEdge( tgtMeshDS,
+ TopoDS::Edge( tgtEdge ),
+ /*ignoreMediumNodes = */true,
+ tgtNodes ))
||
- srcNodes.size() != tgtNodes.size())
+ (( srcNodes.size() != tgtNodes.size() ) && tgtNodes.size() > 0 )
+ )
return false;
- if ( !tgtEdge.IsPartner( srcEdge.Current() ))
+ if ( !tgtEdge.IsPartner( srcEdge ))
{
+ if ( tgtNodes.empty() )
+ return false;
// check that transformation is OK by three nodes
gp_Pnt p0S = SMESH_TNodeXYZ( (srcNodes.begin()) ->second);
gp_Pnt p1S = SMESH_TNodeXYZ( (srcNodes.rbegin()) ->second);
return false;
}
}
+ if ( !tgtNodes.empty() )
+ {
+ map< double, const SMDS_MeshNode* >::iterator u_tn = tgtNodes.begin();
+ map< double, const SMDS_MeshNode* >::iterator u_sn = srcNodes.begin();
+ for ( ; u_tn != tgtNodes.end(); ++u_tn, ++u_sn)
+ src2tgtNodes.insert( make_pair( u_sn->second, u_tn->second ));
+ }
+ }
+ // check nodes on VERTEXes for a case of not meshes EDGEs
+ for ( TopExp_Explorer srcExp( srcFace, TopAbs_VERTEX); srcExp.More(); srcExp.Next() )
+ {
+ const TopoDS_Shape& srcV = srcExp.Current();
+ const TopoDS_Shape& tgtV = shape2ShapeMap( srcV, /*isSrc=*/true );
+ const SMDS_MeshNode* srcN = SMESH_Algo::VertexNode( TopoDS::Vertex( srcV ), srcMeshDS );
+ const SMDS_MeshNode* tgtN = SMESH_Algo::VertexNode( TopoDS::Vertex( tgtV ), tgtMeshDS );
+ if ( !srcN )
+ continue;
+ if ( !tgtN || tgtV.ShapeType() != TopAbs_VERTEX )
+ return false;
- map< double, const SMDS_MeshNode* >::iterator u_tn = tgtNodes.begin();
- map< double, const SMDS_MeshNode* >::iterator u_sn = srcNodes.begin();
- for ( ; u_tn != tgtNodes.end(); ++u_tn, ++u_sn)
- src2tgtNodes.insert( make_pair( u_sn->second, u_tn->second ));
+ if ( !tgtV.IsPartner( srcV ))
+ {
+ // check that transformation is OK by three nodes
+ gp_Pnt p0S = SMESH_TNodeXYZ( srcN );
+ gp_Pnt p0T = SMESH_TNodeXYZ( tgtN );
+ if ( p0T.SquareDistance( p0S.Transformed( trsf )) > tol )
+ {
+ return false;
+ }
+ }
+ src2tgtNodes.insert( make_pair( srcN, tgtN ));
}
+
// Make new faces
// prepare the helper to adding quadratic elements if necessary
SMESH_MesherHelper helper( *tgtMesh );
helper.SetSubShape( tgtFace );
helper.IsQuadraticSubMesh( tgtFace );
- helper.SetElementsOnShape( true );
+
+ SMESHDS_SubMesh* srcSubDS = srcMeshDS->MeshElements( srcFace );
+ if ( !tgtEdgesMeshed && srcSubDS->NbElements() )
+ helper.SetIsQuadratic( srcSubDS->GetElements()->next()->IsQuadratic() );
SMESH_MesherHelper srcHelper( *srcMesh );
srcHelper.SetSubShape( srcFace );
const SMDS_MeshNode* nullNode = 0;
// indices of nodes to create properly oriented faces
+ bool isReverse = ( trsf.Form() != gp_Identity );
int tri1 = 1, tri2 = 2, quad1 = 1, quad3 = 3;
- if ( trsf.Form() != gp_Identity )
+ if ( isReverse )
std::swap( tri1, tri2 ), std::swap( quad1, quad3 );
- SMESHDS_SubMesh* srcSubDS = srcMesh->GetMeshDS()->MeshElements( srcFace );
SMDS_ElemIteratorPtr elemIt = srcSubDS->GetElements();
vector< const SMDS_MeshNode* > tgtNodes;
while ( elemIt->more() ) // loop on all mesh faces on srcFace
const SMDS_MeshElement* elem = elemIt->next();
const int nbN = elem->NbCornerNodes();
tgtNodes.resize( nbN );
+ helper.SetElementsOnShape( false );
for ( int i = 0; i < nbN; ++i ) // loop on nodes of the source element
{
const SMDS_MeshNode* srcNode = elem->GetNode(i);
if ( srcN_tgtN->second == nullNode )
{
// create a new node
- gp_Pnt tgtP = gp_Pnt(srcNode->X(),srcNode->Y(),srcNode->Z()).Transformed( trsf );
+ gp_Pnt tgtP = gp_Pnt( SMESH_TNodeXYZ( srcNode )).Transformed( trsf );
SMDS_MeshNode* n = helper.AddNode( tgtP.X(), tgtP.Y(), tgtP.Z() );
srcN_tgtN->second = n;
-
- gp_Pnt2d srcUV = srcHelper.GetNodeUV( srcFace, srcNode,
- elem->GetNode( helper.WrapIndex(i+1,nbN)));
- n->SetPosition( new SMDS_FacePosition( srcUV.X(), srcUV.Y() ));
+ switch ( srcNode->GetPosition()->GetTypeOfPosition() )
+ {
+ case SMDS_TOP_FACE:
+ {
+ gp_Pnt2d srcUV = srcHelper.GetNodeUV( srcFace, srcNode );
+ tgtMeshDS->SetNodeOnFace( n, helper.GetSubShapeID(), srcUV.X(), srcUV.Y() );
+ break;
+ }
+ case SMDS_TOP_EDGE:
+ {
+ const TopoDS_Shape & srcE = srcMeshDS->IndexToShape( srcNode->getshapeId() );
+ const TopoDS_Shape & tgtE = shape2ShapeMap( srcE, /*isSrc=*/true );
+ double srcU = srcHelper.GetNodeU( TopoDS::Edge( srcE ), srcNode );
+ tgtMeshDS->SetNodeOnEdge( n, TopoDS::Edge( tgtE ), srcU );
+ break;
+ }
+ case SMDS_TOP_VERTEX:
+ {
+ const TopoDS_Shape & srcV = srcMeshDS->IndexToShape( srcNode->getshapeId() );
+ const TopoDS_Shape & tgtV = shape2ShapeMap( srcV, /*isSrc=*/true );
+ tgtMeshDS->SetNodeOnVertex( n, TopoDS::Vertex( tgtV ));
+ break;
+ }
+ default:;
+ }
}
tgtNodes[i] = srcN_tgtN->second;
}
// create a new face
+ helper.SetElementsOnShape( true );
switch ( nbN )
{
case 3: helper.AddFace(tgtNodes[0], tgtNodes[tri1], tgtNodes[tri2]); break;
case 4: helper.AddFace(tgtNodes[0], tgtNodes[quad1], tgtNodes[2], tgtNodes[quad3]); break;
+ default:
+ if ( isReverse ) std::reverse( tgtNodes.begin(), tgtNodes.end() );
+ helper.AddPolygonalFace( tgtNodes );
+ }
+ }
+
+ // check node positions
+
+ if ( !tgtFace.IsPartner( srcFace ) )
+ {
+ int nbOkPos = 0;
+ const double tol2d = 1e-12;
+ srcN_tgtN = src2tgtNodes.begin();
+ for ( ; srcN_tgtN != src2tgtNodes.end(); ++srcN_tgtN )
+ {
+ const SMDS_MeshNode* n = srcN_tgtN->second;
+ switch ( n->GetPosition()->GetTypeOfPosition() )
+ {
+ case SMDS_TOP_FACE:
+ {
+ gp_XY uv = helper.GetNodeUV( tgtFace, n ), uvBis = uv;
+ if (( helper.CheckNodeUV( tgtFace, n, uv, tol )) &&
+ (( uv - uvBis ).SquareModulus() < tol2d ) &&
+ ( ++nbOkPos > 10 ))
+ return true;
+ else
+ nbOkPos = 0;
+ break;
+ }
+ case SMDS_TOP_EDGE:
+ {
+ const TopoDS_Edge & tgtE = TopoDS::Edge( tgtMeshDS->IndexToShape( n->getshapeId() ));
+ double u = helper.GetNodeU( tgtE, n ), uBis = u;
+ if (( !helper.CheckNodeU( tgtE, n, u, tol )) ||
+ (( u - uBis ) < tol2d ))
+ nbOkPos = 0;
+ break;
+ }
+ default:;
+ }
}
}
+
return true;
} // bool projectPartner()
+ //================================================================================
+ /*!
+ * \brief Check if two consecutive EDGEs are connected in 2D
+ * \param [in] E1 - a well oriented non-seam EDGE
+ * \param [in] E2 - a possibly well oriented seam EDGE
+ * \param [in] F - a FACE
+ * \return bool - result
+ */
+ //================================================================================
+
+ bool are2dConnected( const TopoDS_Edge & E1,
+ const TopoDS_Edge & E2,
+ const TopoDS_Face & F )
+ {
+ double f,l;
+ Handle(Geom2d_Curve) c1 = BRep_Tool::CurveOnSurface( E1, F, f, l );
+ gp_Pnt2d uvLast1 = c1->Value( E1.Orientation() == TopAbs_REVERSED ? f : l );
+
+ Handle(Geom2d_Curve) c2 = BRep_Tool::CurveOnSurface( E2, F, f, l );
+ gp_Pnt2d uvFirst2 = c2->Value( f );
+ gp_Pnt2d uvLast2 = c2->Value( l );
+ double tol2 = 1e-5 * uvLast2.SquareDistance( uvFirst2 );
+
+ return (( uvLast1.SquareDistance( uvFirst2 ) < tol2 ) ||
+ ( uvLast1.SquareDistance( uvLast2 ) < tol2 ));
+ }
+
//================================================================================
/*!
* \brief Preform projection in case if the faces are similar in 2D space
// make corresponding sequence of tgt EDGEs
TSideVector tgtWires( srcWires.size() );
- for ( unsigned iW = 0; iW < srcWires.size(); ++iW )
+ for ( size_t iW = 0; iW < srcWires.size(); ++iW )
{
list< TopoDS_Edge > tgtEdges;
StdMeshers_FaceSidePtr srcWire = srcWires[iW];
TopTools_IndexedMapOfShape edgeMap; // to detect seam edges
for ( int iE = 0; iE < srcWire->NbEdges(); ++iE )
{
- tgtEdges.push_back( TopoDS::Edge( shape2ShapeMap( srcWire->Edge( iE ), /*isSrc=*/true)));
+ TopoDS_Edge E = TopoDS::Edge( shape2ShapeMap( srcWire->Edge( iE ), /*isSrc=*/true));
// reverse a seam edge encountered for the second time
- const int oldExtent = edgeMap.Extent();
- edgeMap.Add( tgtEdges.back() );
- if ( oldExtent == edgeMap.Extent() )
- tgtEdges.back().Reverse();
+ const int index = edgeMap.Add( E );
+ if ( index < edgeMap.Extent() ) // E is a seam
+ {
+ // check which of edges to reverse, E or one already being in tgtEdges
+ if ( are2dConnected( tgtEdges.back(), E, tgtFace ))
+ {
+ list< TopoDS_Edge >::iterator eIt = tgtEdges.begin();
+ std::advance( eIt, index-1 );
+ eIt->Reverse();
+ }
+ else
+ {
+ E.Reverse();
+ }
+ }
+ tgtEdges.push_back( E );
}
tgtWires[ iW ].reset( new StdMeshers_FaceSide( tgtFace, tgtEdges, tgtMesh,
/*theIsForward = */ true,
return PropagationMgr::GetSource( theMesh.GetSubMeshContaining( theEdge ),
isPropagOfDistribution);
}
-
+const SMESH_HypoFilter& StdMeshers_Propagation::GetFilter()
+{
+ static SMESH_HypoFilter propagHypFilter;
+ if ( propagHypFilter.IsEmpty() )
+ {
+ propagHypFilter.
+ Init( SMESH_HypoFilter::HasName( StdMeshers_Propagation::GetName ())).
+ Or ( SMESH_HypoFilter::HasName( StdMeshers_PropagOfDistribution::GetName ()));
+ }
+ return propagHypFilter;
+}
//=============================================================================
//=============================================================================
// PROPAGATION MANAGEMENT
/*!
* \brief Returns a local 1D hypothesis used for theEdge
*/
- const SMESH_Hypothesis* getLocal1DHyp (SMESH_Mesh& theMesh,
- const TopoDS_Shape& theEdge)
+ const SMESH_Hypothesis* getLocal1DHyp (SMESH_subMesh* theSubMesh,
+ //const TopoDS_Shape& theEdge,
+ TopoDS_Shape* theSssignedTo=0)
{
static SMESH_HypoFilter hypo;
hypo.Init( hypo.HasDim( 1 )).
AndNot ( hypo.IsAlgo() ).
- AndNot ( hypo.IsAssignedTo( theMesh.GetMeshDS()->ShapeToMesh() ));
- return theMesh.GetHypothesis( theEdge, hypo, true );
+ AndNot ( hypo.HasName( StdMeshers_Propagation::GetName() )).
+ AndNot ( hypo.HasName( StdMeshers_PropagOfDistribution::GetName() )).
+ AndNot ( hypo.IsAssignedTo( theSubMesh->GetFather()->GetShapeToMesh() ));
+
+ return theSubMesh->GetFather()->GetHypothesis( theSubMesh, hypo, true, theSssignedTo );
}
//=============================================================================
/*!
* \brief Returns a propagation hypothesis assigned to theEdge
*/
- const SMESH_Hypothesis* getProagationHyp (SMESH_Mesh& theMesh,
- const TopoDS_Shape& theEdge)
+ const SMESH_Hypothesis* getProagationHyp (SMESH_subMesh* theSubMesh)
{
- static SMESH_HypoFilter propagHypFilter;
- if ( propagHypFilter.IsEmpty() )
- {
- propagHypFilter.
- Init( SMESH_HypoFilter::HasName( StdMeshers_Propagation::GetName ())).
- Or ( SMESH_HypoFilter::HasName( StdMeshers_PropagOfDistribution::GetName ()));
- }
- return theMesh.GetHypothesis( theEdge, propagHypFilter, true );
+ return theSubMesh->GetFather()->GetHypothesis
+ ( theSubMesh, StdMeshers_Propagation::GetFilter(), true );
}
//================================================================================
/*!
SMESH_Mesh* mesh = theMainSubMesh->GetFather();
+ TopoDS_Shape shapeOfHyp1D; // shape to which an hyp being propagated is assigned
+ const SMESH_Hypothesis* hyp1D = getLocal1DHyp( theMainSubMesh, &shapeOfHyp1D );
+ SMESH_HypoFilter moreLocalCheck( SMESH_HypoFilter::IsMoreLocalThan( shapeOfHyp1D, *mesh ));
+
PropagationMgrData* chainData = getData( theMainSubMesh );
chainData->SetState( HAS_PROPAG_HYP );
- if ( const SMESH_Hypothesis * propagHyp = getProagationHyp( *mesh, theMainEdge ))
+ if ( const SMESH_Hypothesis * propagHyp = getProagationHyp( theMainSubMesh ))
chainData->myIsPropagOfDistribution =
( StdMeshers_PropagOfDistribution::GetName() == propagHyp->GetName() );
TopTools_MapOfShape checkedShapes;
checkedShapes.Add( theMainEdge );
+ vector<TopoDS_Edge> edges;
+
list<SMESH_subMesh*>::iterator smIt = chain.begin();
for ( ; smIt != chain.end(); ++smIt )
{
continue;
// Get ordered edges and find index of anE in a sequence
+ edges.clear();
BRepTools_WireExplorer aWE (TopoDS::Wire(itA.Value()));
- vector<TopoDS_Edge> edges;
- edges.reserve(4);
int edgeIndex = 0;
for (; aWE.More(); aWE.Next()) {
TopoDS_Edge edge = aWE.Current();
if ( oppData->State() == WAIT_PROPAG_HYP ) // ... anOppE is not in any chain
{
oppData->SetSource( theMainSubMesh );
- if ( !getLocal1DHyp( *mesh, anOppE )) // ... no 1d hyp on anOppE
+ if ( ! (hyp1D = getLocal1DHyp( oppSM, &shapeOfHyp1D )) || //...no 1d hyp on anOppE
+ ! (moreLocalCheck.IsOk( hyp1D, shapeOfHyp1D ))) // ... or hyp1D is "more global"
{
oppData->myForward = data->myForward;
if ( edges[ edgeIndex ].Orientation() == anOppE.Orientation() )
DBGMSG( "set IN_CHAIN on " << oppSM->GetId() );
if ( oppSM->GetAlgoState() != SMESH_subMesh::HYP_OK )
// make oppSM check algo state
- if ( SMESH_Algo* algo = mesh->GetGen()->GetAlgo( *mesh, anOppE ))
- oppSM->AlgoStateEngine(SMESH_subMesh::ADD_FATHER_ALGO,algo);
+ if ( SMESH_Algo* algo = oppSM->GetAlgo() )
+ oppSM->AlgoStateEngine(SMESH_subMesh::ADD_FATHER_ALGO, algo);
}
else {
oppData->SetState( LAST_IN_CHAIN );
submesh->SetEventListener( getListener(), data, submesh );
const SMESH_Hypothesis * propagHyp =
- getProagationHyp( *submesh->GetFather(), submesh->GetSubShape() );
+ getProagationHyp( submesh );
if ( propagHyp )
{
data->myIsPropagOfDistribution =
case WAIT_PROPAG_HYP: { // propagation hyp or local 1D hyp is missing
// --------------------------------------------------------
- bool hasPropagHyp = ( isPropagHyp ||
- getProagationHyp( *subMesh->GetFather(), subMesh->GetSubShape()) );
+ bool hasPropagHyp = ( isPropagHyp || getProagationHyp( subMesh ));
if ( !hasPropagHyp )
return;
- bool hasLocal1DHyp = getLocal1DHyp( *subMesh->GetFather(), subMesh->GetSubShape());
+ bool hasLocal1DHyp = getLocal1DHyp( subMesh );
if ( !hasLocal1DHyp )
return;
if ( event == SMESH_subMesh::ADD_HYP ||
switch ( event ) {
case SMESH_subMesh::REMOVE_HYP:
case SMESH_subMesh::REMOVE_FATHER_HYP: // remove propagation hyp
- if ( isPropagHyp && !getProagationHyp( *subMesh->GetFather(), subMesh->GetSubShape()) )
+ if ( isPropagHyp && !getProagationHyp( subMesh ))
{
DBGMSG( "REMOVE_HYP propagation from HAS_PROPAG_HYP " << subMesh->GetId() );
// clear propagation chain
#include <TopoDS_Edge.hxx>
+class SMESH_HypoFilter;
// =======================================================================
/*!
*/
// =======================================================================
-class STDMESHERS_EXPORT StdMeshers_Propagation:public SMESH_Hypothesis
+class STDMESHERS_EXPORT StdMeshers_Propagation : public SMESH_Hypothesis
{
public:
StdMeshers_Propagation(int hypId, int studyId, SMESH_Gen * gen);
virtual std::ostream & SaveTo(std::ostream & save);
virtual std::istream & LoadFrom(std::istream & load);
- static std::string GetName ();
+ static std::string GetName();
+
+ /*!
+ * \brief Returns a filter selecting both StdMeshers_Propagation and
+ * StdMeshers_PropagOfDistribution hypotheses
+ */
+ static const SMESH_HypoFilter& GetFilter();
/*!
* \brief Set EventListener managing propagation of hypotheses
#include "StdMeshers_QuadToTriaAdaptor.hxx"
#include "SMDS_SetIterator.hxx"
-
#include "SMESHDS_GroupBase.hxx"
#include "SMESH_Algo.hxx"
#include "SMESH_Group.hxx"
#include <TopoDS.hxx>
#include <gp_Lin.hxx>
#include <gp_Pln.hxx>
+
#include "utilities.h"
#include <string>
bool tooClose = ( angle < 15. * M_PI / 180. );
// Check if pyramids collide
- if ( !tooClose && baI * baJ > 0 )
+ if ( !tooClose && ( baI * baJ > 0 ) && ( nI * nJ > 0 ))
{
// find out if nI points outside of PrmI or inside
int dInd = baseNodesIndI[1] - baseNodesIndI[0];
nodesToMove.insert( aNode1 );
nodesToMove.insert( aNode2 );
}
- // fix intersections that could appear after apex movement
+ // fix intersections that can appear after apex movement
MergeAdjacent( PrmI, nodesToMove );
MergeAdjacent( PrmJ, nodesToMove );
#ifndef StdMeshers_Array2OfNode_HeaderFile
#define StdMeshers_Array2OfNode_HeaderFile
typedef const SMDS_MeshNode* SMDS_MeshNodePtr;
-DEFINE_BASECOLLECTION (StdMeshers_BaseCollectionNodePtr, SMDS_MeshNodePtr)
-DEFINE_ARRAY2(StdMeshers_Array2OfNode,
- StdMeshers_BaseCollectionNodePtr, SMDS_MeshNodePtr)
+typedef NCollection_Array2<SMDS_MeshNodePtr> StdMeshers_Array2OfNode;
#endif
using namespace std;
}
}
- return isOk;
+ error( StdMeshers_ViscousLayers2D::CheckHypothesis( aMesh, aShape, aStatus ));
+
+ return aStatus == HYP_OK;
}
//=============================================================================
"two opposite sides should have same number of segments, "
"but actual number of segments is different on all sides. "
"'Standard' transion has been used.");
- else
+ else if ( ! ( n1 == n3 && n2 == n4 ))
error( COMPERR_WARNING,
"To use 'Reduced' transition, "
"two opposite sides should have an even difference in number of segments. "
int iPrev = myHelper->WrapIndex( i-1, wire->NbEdges() );
const TopoDS_Edge& e1 = wire->Edge( iPrev );
const TopoDS_Edge& e2 = wire->Edge( i );
- double angle = myHelper->GetAngle( e1, e2, geomFace );
+ double angle = myHelper->GetAngle( e1, e2, geomFace, wire->FirstVertex( i ));
if (( maxAngle < angle ) &&
( 5.* M_PI/180 < angle && angle < 175.* M_PI/180 ))
{
TopoDS_Vertex v = helper.IthVertex( 0, *edge );
if ( !theConsiderMesh || SMESH_Algo::VertexNode( v, helper.GetMeshDS() ))
{
- double angle = SMESH_MesherHelper::GetAngle( prevE, *edge, theFace );
+ double angle = SMESH_MesherHelper::GetAngle( prevE, *edge, theFace, v );
vertexByAngle.insert( make_pair( angle, v ));
angleByVertex.Bind( v, angle );
}
if ( !edge.IsNull() )
{
// find a hyp usable by TNodeDistributor
- SMESH_HypoFilter hypKind;
- TNodeDistributor::GetDistributor(*mesh)->InitCompatibleHypoFilter(hypKind,/*ignoreAux=*/1);
- hyp1D = mesh->GetHypothesis( edge, hypKind, /*fromAncestors=*/true);
+ const SMESH_HypoFilter* hypKind =
+ TNodeDistributor::GetDistributor(*mesh)->GetCompatibleHypoFilter(/*ignoreAux=*/true);
+ hyp1D = mesh->GetHypothesis( edge, *hypKind, /*fromAncestors=*/true);
}
}
if ( hyp1D ) // try to compute with hyp1D
//=============================================================================
/*!
- *
+ *
*/
//=============================================================================
const list <const SMESHDS_Hypothesis * > & hyps =
GetUsedHypothesis(aMesh, aShape, /*ignoreAuxiliaryHyps=*/false);
+ const SMESH_HypoFilter & propagFilter = StdMeshers_Propagation::GetFilter();
+
// find non-auxiliary hypothesis
const SMESHDS_Hypothesis *theHyp = 0;
+ set< string > propagTypes;
list <const SMESHDS_Hypothesis * >::const_iterator h = hyps.begin();
for ( ; h != hyps.end(); ++h ) {
if ( static_cast<const SMESH_Hypothesis*>(*h)->IsAuxiliary() ) {
if ( strcmp( "QuadraticMesh", (*h)->GetName() ) == 0 )
_quadraticMesh = true;
+ if ( propagFilter.IsOk( static_cast< const SMESH_Hypothesis*>( *h ), aShape ))
+ propagTypes.insert( (*h)->GetName() );
}
else {
if ( !theHyp )
ASSERT(_adaptiveHyp);
_hypType = ADAPTIVE;
_onlyUnaryInput = false;
+ aStatus = SMESH_Hypothesis::HYP_OK;
}
else
+ {
aStatus = SMESH_Hypothesis::HYP_INCOMPATIBLE;
+ }
+
+ if ( propagTypes.size() > 1 && aStatus == HYP_OK )
+ {
+ // detect concurrent Propagation hyps
+ _usedHypList.clear();
+ list< TopoDS_Shape > assignedTo;
+ if ( aMesh.GetHypotheses( aShape, propagFilter, _usedHypList, true, &assignedTo ) > 1 )
+ {
+ // find most simple shape and a hyp on it
+ int simpleShape = TopAbs_COMPOUND;
+ const SMESHDS_Hypothesis* localHyp = 0;
+ list< TopoDS_Shape >::iterator shape = assignedTo.begin();
+ list< const SMESHDS_Hypothesis *>::iterator hyp = _usedHypList.begin();
+ for ( ; shape != assignedTo.end(); ++shape )
+ if ( shape->ShapeType() > simpleShape )
+ {
+ simpleShape = shape->ShapeType();
+ localHyp = (*hyp);
+ }
+ // check if there a different hyp on simpleShape
+ shape = assignedTo.begin();
+ hyp = _usedHypList.begin();
+ for ( ; hyp != _usedHypList.end(); ++hyp, ++shape )
+ if ( shape->ShapeType() == simpleShape &&
+ !localHyp->IsSameName( **hyp ))
+ {
+ aStatus = HYP_INCOMPAT_HYPS;
+ return error( SMESH_Comment("Hypotheses of both \"")
+ << StdMeshers_Propagation::GetName() << "\" and \""
+ << StdMeshers_PropagOfDistribution::GetName()
+ << "\" types can't be applied to the same edge");
+ }
+ }
+ }
- return ( _hypType != NONE );
+ return ( aStatus == SMESH_Hypothesis::HYP_OK );
}
static bool computeParamByFunc(Adaptor3d_Curve& C3d, double first, double last,
_usedHypList.clear();
_mainEdge.Nullify();
- SMESH_HypoFilter auxiliaryFilter, compatibleFilter;
- auxiliaryFilter.Init( SMESH_HypoFilter::IsAuxiliary() );
- InitCompatibleHypoFilter( compatibleFilter, /*ignoreAux=*/true );
+ SMESH_HypoFilter auxiliaryFilter( SMESH_HypoFilter::IsAuxiliary() );
+ const SMESH_HypoFilter* compatibleFilter = GetCompatibleHypoFilter(/*ignoreAux=*/true );
// get non-auxiliary assigned directly to aShape
- int nbHyp = aMesh.GetHypotheses( aShape, compatibleFilter, _usedHypList, false );
+ int nbHyp = aMesh.GetHypotheses( aShape, *compatibleFilter, _usedHypList, false );
if (nbHyp == 0 && aShape.ShapeType() == TopAbs_EDGE)
{
{
// Propagation of 1D hypothesis from <aMainEdge> on this edge;
// get non-auxiliary assigned to _mainEdge
- nbHyp = aMesh.GetHypotheses( _mainEdge, compatibleFilter, _usedHypList, true );
+ nbHyp = aMesh.GetHypotheses( _mainEdge, *compatibleFilter, _usedHypList, true );
}
}
enum UIndex { U_TGT = 1, U_SRC, LEN_TGT };
+ const double theMinSmoothCosin = 0.1;
+ const double theSmoothThickToElemSizeRatio = 0.3;
+
+ bool needSmoothing( double cosin, double tgtThick, double elemSize )
+ {
+ return cosin * tgtThick > theSmoothThickToElemSizeRatio * elemSize;
+ }
+
/*!
* \brief SMESH_ProxyMesh computed by _ViscousBuilder for a SOLID.
* It is stored in a SMESH_subMesh of the SOLID as SMESH_subMeshEventListenerData
c = new _Curvature;
c->_r = avgDist * avgDist / avgNormProj;
c->_k = avgDist * avgDist / c->_r / c->_r;
+ //c->_k = avgNormProj / c->_r;
c->_k *= ( c->_r < 0 ? 1/1.1 : 1.1 ); // not to be too restrictive
c->_h2lenRatio = avgNormProj / ( avgDist + avgDist );
}
double lenDelta(double len) const { return _k * ( _r + len ); }
double lenDeltaByDist(double dist) const { return dist * _h2lenRatio; }
};
- struct _LayerEdge;
- //--------------------------------------------------------------------------------
- /*!
- * Structure used to smooth a _LayerEdge (master) based on an EDGE.
- */
- struct _2NearEdges
- {
- // target nodes of 2 neighbour _LayerEdge's based on the same EDGE
- const SMDS_MeshNode* _nodes[2];
- // vectors from source nodes of 2 _LayerEdge's to the source node of master _LayerEdge
- //gp_XYZ _vec[2];
- double _wgt[2]; // weights of _nodes
- _LayerEdge* _edges[2];
-
- // normal to plane passing through _LayerEdge._normal and tangent of EDGE
- gp_XYZ* _plnNorm;
-
- _2NearEdges() { _nodes[0]=_nodes[1]=0; _plnNorm = 0; }
- void reverse() {
- std::swap( _nodes[0], _nodes[1] );
- std::swap( _wgt[0], _wgt[1] );
- }
- };
+ struct _2NearEdges;
//--------------------------------------------------------------------------------
/*!
* \brief Edge normal to surface, connecting a node on solid surface (_nodes[0])
void SetDataByNeighbors( const SMDS_MeshNode* n1,
const SMDS_MeshNode* n2,
SMESH_MesherHelper& helper);
- void InvalidateStep( int curStep );
+ void InvalidateStep( int curStep, bool restoreLength=false );
bool Smooth(int& badNb);
bool SmoothOnEdge(Handle(Geom_Surface)& surface,
const TopoDS_Face& F,
double& dist,
const double& epsilon) const;
gp_Ax1 LastSegment(double& segLen) const;
- bool IsOnEdge() const { return _2neibors; }
+ gp_XY LastUV( const TopoDS_Face& F ) const;
+ bool IsOnEdge() const { return _2neibors; }
gp_XYZ Copy( _LayerEdge& other, SMESH_MesherHelper& helper );
- void SetCosin( double cosin );
+ void SetCosin( double cosin );
+ int NbSteps() const { return _pos.size() - 1; } // nb inlation steps
};
struct _LayerEdgeCmp
{
return cmpNodes ? ( e1->_nodes[0]->GetID() < e2->_nodes[0]->GetID()) : ( e1 < e2 );
}
};
+ struct _LayerEdge;
+ //--------------------------------------------------------------------------------
+ /*!
+ * Structure used to smooth a _LayerEdge based on an EDGE.
+ */
+ struct _2NearEdges
+ {
+ double _wgt [2]; // weights of _nodes
+ _LayerEdge* _edges[2];
+
+ // normal to plane passing through _LayerEdge._normal and tangent of EDGE
+ gp_XYZ* _plnNorm;
+
+ _2NearEdges() { _edges[0]=_edges[1]=0; _plnNorm = 0; }
+ const SMDS_MeshNode* tgtNode(bool is2nd) {
+ return _edges[is2nd] ? _edges[is2nd]->_nodes.back() : 0;
+ }
+ const SMDS_MeshNode* srcNode(bool is2nd) {
+ return _edges[is2nd] ? _edges[is2nd]->_nodes[0] : 0;
+ }
+ void reverse() {
+ std::swap( _wgt [0], _wgt [1] );
+ std::swap( _edges[0], _edges[1] );
+ }
+ };
+ //--------------------------------------------------------------------------------
+ /*!
+ * \brief Convex FACE whose radius of curvature is less than the thickness of
+ * layers. It is used to detect distortion of prisms based on a convex
+ * FACE and to update normals to enable further increasing the thickness
+ */
+ struct _ConvexFace
+ {
+ TopoDS_Face _face;
+
+ // edges whose _simplices are used to detect prism destorsion
+ vector< _LayerEdge* > _simplexTestEdges;
+
+ // map a sub-shape to it's index in _SolidData::_endEdgeOnShape vector
+ map< TGeomID, int > _subIdToEdgeEnd;
+
+ bool _normalsFixed;
+
+ bool GetCenterOfCurvature( _LayerEdge* ledge,
+ BRepLProp_SLProps& surfProp,
+ SMESH_MesherHelper& helper,
+ gp_Pnt & center ) const;
+ bool CheckPrisms() const;
+ };
+
+ //--------------------------------------------------------------------------------
+ /*!
+ * \brief Layers parameters got by averaging several hypotheses
+ */
+ struct AverageHyp
+ {
+ AverageHyp( const StdMeshers_ViscousLayers* hyp = 0 )
+ :_nbLayers(0), _nbHyps(0), _thickness(0), _stretchFactor(0)
+ {
+ Add( hyp );
+ }
+ void Add( const StdMeshers_ViscousLayers* hyp )
+ {
+ if ( hyp )
+ {
+ _nbHyps++;
+ _nbLayers = hyp->GetNumberLayers();
+ //_thickness += hyp->GetTotalThickness();
+ _thickness = Max( _thickness, hyp->GetTotalThickness() );
+ _stretchFactor += hyp->GetStretchFactor();
+ }
+ }
+ double GetTotalThickness() const { return _thickness; /*_nbHyps ? _thickness / _nbHyps : 0;*/ }
+ double GetStretchFactor() const { return _nbHyps ? _stretchFactor / _nbHyps : 0; }
+ int GetNumberLayers() const { return _nbLayers; }
+ private:
+ int _nbLayers, _nbHyps;
+ double _thickness, _stretchFactor;
+ };
+
//--------------------------------------------------------------------------------
typedef map< const SMDS_MeshNode*, _LayerEdge*, TIDCompare > TNode2Edge;
*/
struct _SolidData
{
+ typedef const StdMeshers_ViscousLayers* THyp;
TopoDS_Shape _solid;
- const StdMeshers_ViscousLayers* _hyp;
- TopoDS_Shape _hypShape;
+ TGeomID _index; // SOLID id
_MeshOfSolid* _proxyMesh;
- set<TGeomID> _reversedFaceIds;
- set<TGeomID> _ignoreFaceIds;
+ list< THyp > _hyps;
+ list< TopoDS_Shape > _hypShapes;
+ map< TGeomID, THyp > _face2hyp; // filled if _hyps.size() > 1
+ set< TGeomID > _reversedFaceIds;
+ set< TGeomID > _ignoreFaceIds; // WOL FACEs and FACEs of other SOLIDs
- double _stepSize, _stepSizeCoeff;
+ double _stepSize, _stepSizeCoeff, _geomSize;
const SMDS_MeshNode* _stepSizeNodes[2];
- TNode2Edge _n2eMap;
+ TNode2Edge _n2eMap; // nodes and _LayerEdge's based on them
+
// map to find _n2eMap of another _SolidData by a shrink shape shared by two _SolidData's
map< TGeomID, TNode2Edge* > _s2neMap;
// edges of _n2eMap. We keep same data in two containers because
- // iteration over the map is 5 time longer than over the vector
+ // iteration over the map is 5 times longer than over the vector
vector< _LayerEdge* > _edges;
- // edges on EDGE's with null _sWOL, whose _simplices are used to stop inflation
- vector< _LayerEdge* > _simplexTestEdges;
// key: an id of shape (EDGE or VERTEX) shared by a FACE with
// layers and a FACE w/o layers
// _LayerEdge's basing on nodes on key shape are inflated along the value shape
map< TGeomID, TopoDS_Shape > _shrinkShape2Shape;
- // FACE's WOL, srink on which is forbiden due to algo on the adjacent SOLID
- set< TGeomID > _noShrinkFaces;
+ // Convex FACEs whose radius of curvature is less than the thickness of layers
+ map< TGeomID, _ConvexFace > _convexFaces;
- // <EDGE to smooth on> to <it's curve>
+ // shapes (EDGEs and VERTEXes) srink from which is forbiden due to collisions with
+ // the adjacent SOLID
+ set< TGeomID > _noShrinkShapes;
+
+ // <EDGE to smooth on> to <it's curve> -- for analytic smooth
map< TGeomID,Handle(Geom_Curve)> _edge2curve;
- // end indices in _edges of _LayerEdge on one shape to smooth
- vector< int > _endEdgeToSmooth;
+ // end indices in _edges of _LayerEdge on each shape, first go shapes to smooth
+ vector< int > _endEdgeOnShape;
+ int _nbShapesToSmooth;
- double _epsilon; // precision for SegTriaInter()
+ // data of averaged StdMeshers_ViscousLayers parameters for each shape with _LayerEdge's
+ vector< AverageHyp > _hypOnShape;
+ double _maxThickness; // of all _hyps
+ double _minThickness; // of all _hyps
- int _index; // for debug
+ double _epsilon; // precision for SegTriaInter()
- _SolidData(const TopoDS_Shape& s=TopoDS_Shape(),
- const StdMeshers_ViscousLayers* h=0,
- const TopoDS_Shape& hs=TopoDS_Shape(),
- _MeshOfSolid* m=0)
- :_solid(s), _hyp(h), _hypShape(hs), _proxyMesh(m) {}
+ _SolidData(const TopoDS_Shape& s=TopoDS_Shape(),
+ _MeshOfSolid* m=0)
+ :_solid(s), _proxyMesh(m) {}
~_SolidData();
Handle(Geom_Curve) CurveForSmooth( const TopoDS_Edge& E,
Handle(Geom_Surface)& surface,
const TopoDS_Face& F,
SMESH_MesherHelper& helper);
+
+ void SortOnEdge( const TopoDS_Edge& E,
+ const int iFrom,
+ const int iTo,
+ SMESH_MesherHelper& helper);
+
+ _ConvexFace* GetConvexFace( const TGeomID faceID )
+ {
+ map< TGeomID, _ConvexFace >::iterator id2face = _convexFaces.find( faceID );
+ return id2face == _convexFaces.end() ? 0 : & id2face->second;
+ }
+ void GetEdgesOnShape( size_t end, int & iBeg, int & iEnd )
+ {
+ iBeg = end > 0 ? _endEdgeOnShape[ end-1 ] : 0;
+ iEnd = _endEdgeOnShape[ end ];
+ }
+
+ bool GetShapeEdges(const TGeomID shapeID, size_t& iEdgeEnd, int* iBeg=0, int* iEnd=0 ) const;
+
+ void AddShapesToSmooth( const set< TGeomID >& shapeIDs );
+ };
+ //--------------------------------------------------------------------------------
+ /*!
+ * \brief Container of centers of curvature at nodes on an EDGE bounding _ConvexFace
+ */
+ struct _CentralCurveOnEdge
+ {
+ bool _isDegenerated;
+ vector< gp_Pnt > _curvaCenters;
+ vector< _LayerEdge* > _ledges;
+ vector< gp_XYZ > _normals; // new normal for each of _ledges
+ vector< double > _segLength2;
+
+ TopoDS_Edge _edge;
+ TopoDS_Face _adjFace;
+ bool _adjFaceToSmooth;
+
+ void Append( const gp_Pnt& center, _LayerEdge* ledge )
+ {
+ if ( _curvaCenters.size() > 0 )
+ _segLength2.push_back( center.SquareDistance( _curvaCenters.back() ));
+ _curvaCenters.push_back( center );
+ _ledges.push_back( ledge );
+ _normals.push_back( ledge->_normal );
+ }
+ bool FindNewNormal( const gp_Pnt& center, gp_XYZ& newNormal );
+ void SetShapes( const TopoDS_Edge& edge,
+ const _ConvexFace& convFace,
+ const _SolidData& data,
+ SMESH_MesherHelper& helper);
};
//--------------------------------------------------------------------------------
/*!
struct _SmoothNode
{
const SMDS_MeshNode* _node;
- //vector<const SMDS_MeshNode*> _nodesAround;
vector<_Simplex> _simplices; // for quality check
enum SmoothType { LAPLACIAN, CENTROIDAL, ANGULAR, TFI };
// does it's job
SMESH_ComputeErrorPtr Compute(SMESH_Mesh& mesh,
const TopoDS_Shape& shape);
+ // check validity of hypotheses
+ SMESH_ComputeErrorPtr CheckHypotheses( SMESH_Mesh& mesh,
+ const TopoDS_Shape& shape );
// restore event listeners used to clear an inferior dim sub-mesh modified by viscous layers
void RestoreListeners();
private:
bool findSolidsWithLayers();
- bool findFacesWithLayers();
+ bool findFacesWithLayers(const bool onlyWith=false);
+ void getIgnoreFaces(const TopoDS_Shape& solid,
+ const StdMeshers_ViscousLayers* hyp,
+ const TopoDS_Shape& hypShape,
+ set<TGeomID>& ignoreFaces);
bool makeLayer(_SolidData& data);
bool setEdgeData(_LayerEdge& edge, const set<TGeomID>& subIds,
SMESH_MesherHelper& helper, _SolidData& data);
const bool toSort = false);
void findSimplexTestEdges( _SolidData& data,
vector< vector<_LayerEdge*> >& edgesByGeom);
+ void computeGeomSize( _SolidData& data );
bool sortEdges( _SolidData& data,
vector< vector<_LayerEdge*> >& edgesByGeom);
- void limitStepSizeByCurvature( _SolidData& data,
- vector< vector<_LayerEdge*> >& edgesByGeom);
+ void limitStepSizeByCurvature( _SolidData& data );
void limitStepSize( _SolidData& data,
const SMDS_MeshElement* face,
- const double cosin);
+ const _LayerEdge* maxCosinEdge );
void limitStepSize( _SolidData& data, const double minSize);
bool inflate(_SolidData& data);
bool smoothAndCheck(_SolidData& data, const int nbSteps, double & distToIntersection);
Handle(Geom_Surface)& surface,
const TopoDS_Face& F,
SMESH_MesherHelper& helper);
- bool updateNormals( _SolidData& data, SMESH_MesherHelper& helper );
+ bool updateNormals( _SolidData& data, SMESH_MesherHelper& helper, int stepNb );
+ bool updateNormalsOfConvexFaces( _SolidData& data,
+ SMESH_MesherHelper& helper,
+ int stepNb );
bool refine(_SolidData& data);
bool shrink();
bool prepareEdgeToShrink( _LayerEdge& edge, const TopoDS_Face& F,
SMESH_MesherHelper& helper,
const SMESHDS_SubMesh* faceSubMesh );
+ void restoreNoShrink( _LayerEdge& edge ) const;
void fixBadFaces(const TopoDS_Face& F,
SMESH_MesherHelper& helper,
const bool is2D,
bool addBoundaryElements();
bool error( const string& text, int solidID=-1 );
- SMESHDS_Mesh* getMeshDS() { return _mesh->GetMeshDS(); }
+ SMESHDS_Mesh* getMeshDS() const { return _mesh->GetMeshDS(); }
// debug
void makeGroupOfLE();
* We can't use SMDS_FaceOfNodes since it's impossible to set it's ID which is
* needed because SMESH_ElementSearcher internaly uses set of elements sorted by ID
*/
- struct TmpMeshFace : public SMDS_MeshElement
+ struct _TmpMeshFace : public SMDS_MeshElement
{
vector<const SMDS_MeshNode* > _nn;
- TmpMeshFace( const vector<const SMDS_MeshNode*>& nodes, int id):
- SMDS_MeshElement(id), _nn(nodes) {}
+ _TmpMeshFace( const vector<const SMDS_MeshNode*>& nodes, int id, int faceID=-1):
+ SMDS_MeshElement(id), _nn(nodes) { setShapeId(faceID); }
virtual const SMDS_MeshNode* GetNode(const int ind) const { return _nn[ind]; }
virtual SMDSAbs_ElementType GetType() const { return SMDSAbs_Face; }
virtual vtkIdType GetVtkType() const { return -1; }
virtual SMDSAbs_EntityType GetEntityType() const { return SMDSEntity_Last; }
- virtual SMDSAbs_GeometryType GetGeomType() const { return SMDSGeom_TRIANGLE; }
+ virtual SMDSAbs_GeometryType GetGeomType() const
+ { return _nn.size() == 3 ? SMDSGeom_TRIANGLE : SMDSGeom_QUADRANGLE; }
virtual SMDS_ElemIteratorPtr elementsIterator(SMDSAbs_ElementType) const
{ return SMDS_ElemIteratorPtr( new SMDS_NodeVectorElemIterator( _nn.begin(), _nn.end()));}
};
/*!
* \brief Class of temporary mesh face storing _LayerEdge it's based on
*/
- struct TmpMeshFaceOnEdge : public TmpMeshFace
+ struct _TmpMeshFaceOnEdge : public _TmpMeshFace
{
_LayerEdge *_le1, *_le2;
- TmpMeshFaceOnEdge( _LayerEdge* le1, _LayerEdge* le2, int ID ):
- TmpMeshFace( vector<const SMDS_MeshNode*>(4), ID ), _le1(le1), _le2(le2)
+ _TmpMeshFaceOnEdge( _LayerEdge* le1, _LayerEdge* le2, int ID ):
+ _TmpMeshFace( vector<const SMDS_MeshNode*>(4), ID ), _le1(le1), _le2(le2)
{
_nn[0]=_le1->_nodes[0];
_nn[1]=_le1->_nodes.back();
* \brief Retriever of node coordinates either directly of from a surface by node UV.
* \warning Location of a surface is ignored
*/
- struct NodeCoordHelper
+ struct _NodeCoordHelper
{
SMESH_MesherHelper& _helper;
const TopoDS_Face& _face;
Handle(Geom_Surface) _surface;
- gp_XYZ (NodeCoordHelper::* _fun)(const SMDS_MeshNode* n) const;
+ gp_XYZ (_NodeCoordHelper::* _fun)(const SMDS_MeshNode* n) const;
- NodeCoordHelper(const TopoDS_Face& F, SMESH_MesherHelper& helper, bool is2D)
+ _NodeCoordHelper(const TopoDS_Face& F, SMESH_MesherHelper& helper, bool is2D)
: _helper( helper ), _face( F )
{
if ( is2D )
_surface = BRep_Tool::Surface( _face, loc );
}
if ( _surface.IsNull() )
- _fun = & NodeCoordHelper::direct;
+ _fun = & _NodeCoordHelper::direct;
else
- _fun = & NodeCoordHelper::byUV;
+ _fun = & _NodeCoordHelper::byUV;
}
gp_XYZ operator()(const SMDS_MeshNode* n) const { return (this->*_fun)( n ); }
return _surface->Value( uv.X(), uv.Y() ).XYZ();
}
};
+
} // namespace VISCOUS_3D
+
+
//================================================================================
// StdMeshers_ViscousLayers hypothesis
//
{
// TODO
return false;
+} // --------------------------------------------------------------------------------
+SMESH_ComputeErrorPtr
+StdMeshers_ViscousLayers::CheckHypothesis(SMESH_Mesh& theMesh,
+ const TopoDS_Shape& theShape,
+ SMESH_Hypothesis::Hypothesis_Status& theStatus)
+{
+ VISCOUS_3D::_ViscousBuilder bulder;
+ SMESH_ComputeErrorPtr err = bulder.CheckHypotheses( theMesh, theShape );
+ if ( err && !err->IsOK() )
+ theStatus = SMESH_Hypothesis::HYP_INCOMPAT_HYPS;
+ else
+ theStatus = SMESH_Hypothesis::HYP_OK;
+
+ return err;
+}
+// --------------------------------------------------------------------------------
+bool StdMeshers_ViscousLayers::IsShapeWithLayers(int shapeIndex) const
+{
+ bool isIn =
+ ( std::find( _shapeIds.begin(), _shapeIds.end(), shapeIndex ) != _shapeIds.end() );
+ return IsToIgnoreShapes() ? !isIn : isIn;
}
// END StdMeshers_ViscousLayers hypothesis
//================================================================================
gp_Vec dir;
double f,l; gp_Pnt p;
Handle(Geom_Curve) c = BRep_Tool::Curve( E, f, l );
+ if ( c.IsNull() ) return gp_XYZ( 1e100, 1e100, 1e100 );
double u = helper.GetNodeU( E, atNode );
c->D1( u, p, dir );
return dir.XYZ();
}
//--------------------------------------------------------------------------------
+ gp_XYZ getFaceDir( const TopoDS_Face& F, const TopoDS_Vertex& fromV,
+ const SMDS_MeshNode* node, SMESH_MesherHelper& helper, bool& ok,
+ double* cosin=0);
+ //--------------------------------------------------------------------------------
gp_XYZ getFaceDir( const TopoDS_Face& F, const TopoDS_Edge& fromE,
const SMDS_MeshNode* node, SMESH_MesherHelper& helper, bool& ok)
{
+ double f,l;
+ Handle(Geom_Curve) c = BRep_Tool::Curve( fromE, f, l );
+ if ( c.IsNull() )
+ {
+ TopoDS_Vertex v = helper.IthVertex( 0, fromE );
+ return getFaceDir( F, v, node, helper, ok );
+ }
gp_XY uv = helper.GetNodeUV( F, node, 0, &ok );
Handle(Geom_Surface) surface = BRep_Tool::Surface( F );
gp_Pnt p; gp_Vec du, dv, norm;
surface->D1( uv.X(),uv.Y(), p, du,dv );
norm = du ^ dv;
- double f,l;
- Handle(Geom_Curve) c = BRep_Tool::Curve( fromE, f, l );
double u = helper.GetNodeU( fromE, node, 0, &ok );
c->D1( u, p, du );
TopAbs_Orientation o = helper.GetSubShapeOri( F.Oriented(TopAbs_FORWARD), fromE);
//--------------------------------------------------------------------------------
gp_XYZ getFaceDir( const TopoDS_Face& F, const TopoDS_Vertex& fromV,
const SMDS_MeshNode* node, SMESH_MesherHelper& helper,
- bool& ok, double* cosin=0)
+ bool& ok, double* cosin)
{
TopoDS_Face faceFrw = F;
faceFrw.Orientation( TopAbs_FORWARD );
if ( SMESH_Algo::isDegenerated( e )) continue;
TopExp::Vertices( e, VV[0], VV[1], /*CumOri=*/true );
if ( VV[1].IsSame( fromV )) {
+ nbEdges += edges[ 0 ].IsNull();
edges[ 0 ] = e;
- nbEdges++;
}
else if ( VV[0].IsSame( fromV )) {
+ nbEdges += edges[ 1 ].IsNull();
edges[ 1 ] = e;
- nbEdges++;
}
}
}
// get angle between the 2 edges
gp_Vec faceNormal;
- double angle = helper.GetAngle( edges[0], edges[1], faceFrw, &faceNormal );
+ double angle = helper.GetAngle( edges[0], edges[1], faceFrw, fromV, &faceNormal );
if ( Abs( angle ) < 5 * M_PI/180 )
{
dir = ( faceNormal.XYZ() ^ edgeDir[0].Reversed()) + ( faceNormal.XYZ() ^ edgeDir[1] );
}
else if ( nbEdges == 1 )
{
- dir = getFaceDir( faceFrw, edges[0], node, helper, ok );
+ dir = getFaceDir( faceFrw, edges[ edges[0].IsNull() ], node, helper, ok );
if ( cosin ) *cosin = 1.;
}
else
cross = -cross;
isConvex = ( cross > 0.1 ); //-1e-9 );
}
- // check if concavity is strong enough to care about it
- //const double maxAngle = 5 * Standard_PI180;
if ( !isConvex )
{
//cout << "Concave FACE " << helper.GetMeshDS()->ShapeToIndex( F ) << endl;
return true;
- // map< double, const SMDS_MeshNode* > u2nodes;
- // if ( !SMESH_Algo::GetSortedNodesOnEdge( helper.GetMeshDS(), E,
- // /*ignoreMedium=*/true, u2nodes))
- // continue;
- // map< double, const SMDS_MeshNode* >::iterator u2n = u2nodes.begin();
- // gp_Pnt2d uvPrev = helper.GetNodeUV( F, u2n->second );
- // double uPrev = u2n->first;
- // for ( ++u2n; u2n != u2nodes.end(); ++u2n )
- // {
- // gp_Pnt2d uv = helper.GetNodeUV( F, u2n->second );
- // gp_Vec2d segmentDir( uvPrev, uv );
- // curve.D1( uPrev, p, drv1 );
- // try {
- // if ( fabs( segmentDir.Angle( drv1 )) > maxAngle )
- // return true;
- // }
- // catch ( ... ) {}
- // uvPrev = uv;
- // uPrev = u2n->first;
- // }
}
}
// check angles at VERTEXes
while ( SMESH_Algo::isDegenerated( wires[iW]->Edge( iE2 )))
iE2 = ( iE2 + 1 ) % nbEdges;
double angle = helper.GetAngle( wires[iW]->Edge( iE1 ),
- wires[iW]->Edge( iE2 ), F );
+ wires[iW]->Edge( iE2 ), F,
+ wires[iW]->FirstVertex( iE2 ));
if ( angle < -5. * M_PI / 180. )
return true;
}
}
return false;
}
+ //================================================================================
+ /*!
+ * \brief Computes mimimal distance of face in-FACE nodes from an EDGE
+ * \param [in] face - the mesh face to treat
+ * \param [in] nodeOnEdge - a node on the EDGE
+ * \param [out] faceSize - the computed distance
+ * \return bool - true if faceSize computed
+ */
+ //================================================================================
+
+ bool getDistFromEdge( const SMDS_MeshElement* face,
+ const SMDS_MeshNode* nodeOnEdge,
+ double & faceSize )
+ {
+ faceSize = Precision::Infinite();
+ bool done = false;
+
+ int nbN = face->NbCornerNodes();
+ int iOnE = face->GetNodeIndex( nodeOnEdge );
+ int iNext[2] = { SMESH_MesherHelper::WrapIndex( iOnE+1, nbN ),
+ SMESH_MesherHelper::WrapIndex( iOnE-1, nbN ) };
+ const SMDS_MeshNode* nNext[2] = { face->GetNode( iNext[0] ),
+ face->GetNode( iNext[1] ) };
+ gp_XYZ segVec, segEnd = SMESH_TNodeXYZ( nodeOnEdge ); // segment on EDGE
+ double segLen = -1.;
+ // look for two neighbor not in-FACE nodes of face
+ for ( int i = 0; i < 2; ++i )
+ {
+ if ( nNext[i]->GetPosition()->GetDim() != 2 &&
+ nNext[i]->GetID() < nodeOnEdge->GetID() )
+ {
+ // look for an in-FACE node
+ for ( int iN = 0; iN < nbN; ++iN )
+ {
+ if ( iN == iOnE || iN == iNext[i] )
+ continue;
+ SMESH_TNodeXYZ pInFace = face->GetNode( iN );
+ gp_XYZ v = pInFace - segEnd;
+ if ( segLen < 0 )
+ {
+ segVec = SMESH_TNodeXYZ( nNext[i] ) - segEnd;
+ segLen = segVec.Modulus();
+ }
+ double distToSeg = v.Crossed( segVec ).Modulus() / segLen;
+ faceSize = Min( faceSize, distToSeg );
+ done = true;
+ }
+ segLen = -1;
+ }
+ }
+ return done;
+ }
+
//--------------------------------------------------------------------------------
// DEBUG. Dump intermediate node positions into a python script
+ // HOWTO use: run python commands written in a console to see
+ // construction steps of viscous layers
#ifdef __myDEBUG
ofstream* py;
+ int theNbFunc;
struct PyDump {
PyDump() {
const char* fname = "/tmp/viscous.py";
<< "smesh = smeshBuilder.New(salome.myStudy)" << endl
<< "meshSO = smesh.GetCurrentStudy().FindObjectID('0:1:2:3')" << endl
<< "mesh = smesh.Mesh( meshSO.GetObject() )"<<endl;
+ theNbFunc = 0;
}
void Finish() {
- if (py)
- *py << "mesh.MakeGroup('Viscous Prisms',SMESH.VOLUME,SMESH.FT_ElemGeomType,'=',SMESH.Geom_PENTA)"<<endl;
+ if (py) {
+ *py << "mesh.GroupOnFilter(SMESH.VOLUME,'Viscous Prisms',"
+ "smesh.GetFilter(SMESH.VOLUME,SMESH.FT_ElemGeomType,'=',SMESH.Geom_PENTA))"<<endl;
+ *py << "mesh.GroupOnFilter(SMESH.VOLUME,'Neg Volumes',"
+ "smesh.GetFilter(SMESH.VOLUME,SMESH.FT_Volume3D,'<',0))"<<endl;
+ }
delete py; py=0;
}
- ~PyDump() { Finish(); }
+ ~PyDump() { Finish(); cout << "NB FUNCTIONS: " << theNbFunc << endl; }
};
#define dumpFunction(f) { _dumpFunction(f, __LINE__);}
#define dumpMove(n) { _dumpMove(n, __LINE__);}
#define dumpCmd(txt) { _dumpCmd(txt, __LINE__);}
void _dumpFunction(const string& fun, int ln)
- { if (py) *py<< "def "<<fun<<"(): # "<< ln <<endl; cout<<fun<<"()"<<endl;}
+ { if (py) *py<< "def "<<fun<<"(): # "<< ln <<endl; cout<<fun<<"()"<<endl; ++theNbFunc; }
void _dumpMove(const SMDS_MeshNode* n, int ln)
{ if (py) *py<< " mesh.MoveNode( "<<n->GetID()<< ", "<< n->X()
<< ", "<<n->Y()<<", "<< n->Z()<< ")\t\t # "<< ln <<endl; }
{ if (py) { *py<< " mesh.ChangeElemNodes( " << f->GetID()<<", [";
for ( int i=1; i < f->NbNodes(); ++i ) *py << f->GetNode(i-1)->GetID()<<", ";
*py << f->GetNode( f->NbNodes()-1 )->GetID() << " ])"<< endl; }}
+#define debugMsg( txt ) { cout << txt << " (line: " << __LINE__ << ")" << endl; }
#else
struct PyDump { void Finish() {} };
#define dumpFunction(f) f
#define dumpCmd(txt)
#define dumpFunctionEnd()
#define dumpChangeNodes(f)
+#define debugMsg( txt ) {}
#endif
}
bool _ViscousBuilder::error(const string& text, int solidId )
{
+ const string prefix = string("Viscous layers builder: ");
_error->myName = COMPERR_ALGO_FAILED;
- _error->myComment = string("Viscous layers builder: ") + text;
+ _error->myComment = prefix + text;
if ( _mesh )
{
SMESH_subMesh* sm = _mesh->GetSubMeshContaining( solidId );
if ( !sm && !_sdVec.empty() )
- sm = _mesh->GetSubMeshContaining( _sdVec[0]._index );
+ sm = _mesh->GetSubMeshContaining( solidId = _sdVec[0]._index );
if ( sm && sm->GetSubShape().ShapeType() == TopAbs_SOLID )
{
SMESH_ComputeErrorPtr& smError = sm->GetComputeError();
if ( smError && smError->myAlgo )
_error->myAlgo = smError->myAlgo;
smError = _error;
+ sm->ComputeStateEngine( SMESH_subMesh::CHECK_COMPUTE_STATE );
+ }
+ // set KO to all solids
+ for ( size_t i = 0; i < _sdVec.size(); ++i )
+ {
+ if ( _sdVec[i]._index == solidId )
+ continue;
+ sm = _mesh->GetSubMesh( _sdVec[i]._solid );
+ if ( !sm->IsEmpty() )
+ continue;
+ SMESH_ComputeErrorPtr& smError = sm->GetComputeError();
+ if ( !smError || smError->IsOK() )
+ {
+ smError = SMESH_ComputeError::New( COMPERR_ALGO_FAILED, prefix + "failed");
+ sm->ComputeStateEngine( SMESH_subMesh::CHECK_COMPUTE_STATE );
+ }
}
}
makeGroupOfLE(); // debug
return _error;
}
+//================================================================================
+/*!
+ * \brief Check validity of hypotheses
+ */
+//================================================================================
+
+SMESH_ComputeErrorPtr _ViscousBuilder::CheckHypotheses( SMESH_Mesh& mesh,
+ const TopoDS_Shape& shape )
+{
+ _mesh = & mesh;
+
+ if ( _ViscousListener::GetSolidMesh( _mesh, shape, /*toCreate=*/false))
+ return SMESH_ComputeErrorPtr(); // everything already computed
+
+
+ findSolidsWithLayers();
+ bool ok = findFacesWithLayers();
+
+ // remove _MeshOfSolid's of _SolidData's
+ for ( size_t i = 0; i < _sdVec.size(); ++i )
+ _ViscousListener::RemoveSolidMesh( _mesh, _sdVec[i]._solid );
+
+ if ( !ok )
+ return _error;
+
+ return SMESH_ComputeErrorPtr();
+}
+
//================================================================================
/*!
* \brief Finds SOLIDs to compute using viscous layers. Fills _sdVec
// TODO: check if algo is hidden
const list <const SMESHDS_Hypothesis *> & allHyps =
algo->GetUsedHypothesis(*_mesh, allSolids(i), /*ignoreAuxiliary=*/false);
+ _SolidData* soData = 0;
list< const SMESHDS_Hypothesis *>::const_iterator hyp = allHyps.begin();
const StdMeshers_ViscousLayers* viscHyp = 0;
- for ( ; hyp != allHyps.end() && !viscHyp; ++hyp )
- viscHyp = dynamic_cast<const StdMeshers_ViscousLayers*>( *hyp );
- if ( viscHyp )
- {
- TopoDS_Shape hypShape;
- filter.Init( filter.Is( viscHyp ));
- _mesh->GetHypothesis( allSolids(i), filter, true, &hypShape );
+ for ( ; hyp != allHyps.end(); ++hyp )
+ if ( viscHyp = dynamic_cast<const StdMeshers_ViscousLayers*>( *hyp ))
+ {
+ TopoDS_Shape hypShape;
+ filter.Init( filter.Is( viscHyp ));
+ _mesh->GetHypothesis( allSolids(i), filter, true, &hypShape );
- _MeshOfSolid* proxyMesh = _ViscousListener::GetSolidMesh( _mesh,
- allSolids(i),
- /*toCreate=*/true);
- _sdVec.push_back( _SolidData( allSolids(i), viscHyp, hypShape, proxyMesh ));
- _sdVec.back()._index = getMeshDS()->ShapeToIndex( allSolids(i));
- }
+ if ( !soData )
+ {
+ _MeshOfSolid* proxyMesh = _ViscousListener::GetSolidMesh( _mesh,
+ allSolids(i),
+ /*toCreate=*/true);
+ _sdVec.push_back( _SolidData( allSolids(i), proxyMesh ));
+ soData = & _sdVec.back();
+ soData->_index = getMeshDS()->ShapeToIndex( allSolids(i));
+ }
+ soData->_hyps.push_back( viscHyp );
+ soData->_hypShapes.push_back( hypShape );
+ }
}
if ( _sdVec.empty() )
return error
*/
//================================================================================
-bool _ViscousBuilder::findFacesWithLayers()
+bool _ViscousBuilder::findFacesWithLayers(const bool onlyWith)
{
SMESH_MesherHelper helper( *_mesh );
TopExp_Explorer exp;
{
solids.Add( _sdVec[i]._solid );
- vector<TGeomID> ids = _sdVec[i]._hyp->GetBndShapes();
- if ( _sdVec[i]._hyp->IsToIgnoreShapes() ) // FACEs to ignore are given
+ // get faces to ignore defined by each hyp
+ typedef const StdMeshers_ViscousLayers* THyp;
+ typedef std::pair< set<TGeomID>, THyp > TFacesOfHyp;
+ list< TFacesOfHyp > ignoreFacesOfHyps;
+ list< THyp >::iterator hyp = _sdVec[i]._hyps.begin();
+ list< TopoDS_Shape >::iterator hypShape = _sdVec[i]._hypShapes.begin();
+ for ( ; hyp != _sdVec[i]._hyps.end(); ++hyp, ++hypShape )
{
- for ( size_t ii = 0; ii < ids.size(); ++ii )
- {
- const TopoDS_Shape& s = getMeshDS()->IndexToShape( ids[ii] );
- if ( !s.IsNull() && s.ShapeType() == TopAbs_FACE )
- _sdVec[i]._ignoreFaceIds.insert( ids[ii] );
- }
+ ignoreFacesOfHyps.push_back( TFacesOfHyp( set<TGeomID>(), *hyp ));
+ getIgnoreFaces( _sdVec[i]._solid, *hyp, *hypShape, ignoreFacesOfHyps.back().first );
}
- else // FACEs with layers are given
+
+ // fill _SolidData::_face2hyp and check compatibility of hypotheses
+ const int nbHyps = _sdVec[i]._hyps.size();
+ if ( nbHyps > 1 )
{
- exp.Init( _sdVec[i]._solid, TopAbs_FACE );
- for ( ; exp.More(); exp.Next() )
+ // check if two hypotheses define different parameters for the same FACE
+ list< TFacesOfHyp >::iterator igFacesOfHyp;
+ for ( exp.Init( _sdVec[i]._solid, TopAbs_FACE ); exp.More(); exp.Next() )
{
- TGeomID faceInd = getMeshDS()->ShapeToIndex( exp.Current() );
- if ( find( ids.begin(), ids.end(), faceInd ) == ids.end() )
- _sdVec[i]._ignoreFaceIds.insert( faceInd );
+ const TGeomID faceID = getMeshDS()->ShapeToIndex( exp.Current() );
+ THyp hyp = 0;
+ igFacesOfHyp = ignoreFacesOfHyps.begin();
+ for ( ; igFacesOfHyp != ignoreFacesOfHyps.end(); ++igFacesOfHyp )
+ if ( ! igFacesOfHyp->first.count( faceID ))
+ {
+ if ( hyp )
+ return error(SMESH_Comment("Several hypotheses define "
+ "Viscous Layers on the face #") << faceID );
+ hyp = igFacesOfHyp->second;
+ }
+ if ( hyp )
+ _sdVec[i]._face2hyp.insert( make_pair( faceID, hyp ));
+ else
+ _sdVec[i]._ignoreFaceIds.insert( faceID );
}
- }
- // ignore internal FACEs if inlets and outlets are specified
+ // check if two hypotheses define different number of viscous layers for
+ // adjacent faces of a solid
+ set< int > nbLayersSet;
+ igFacesOfHyp = ignoreFacesOfHyps.begin();
+ for ( ; igFacesOfHyp != ignoreFacesOfHyps.end(); ++igFacesOfHyp )
+ {
+ nbLayersSet.insert( igFacesOfHyp->second->GetNumberLayers() );
+ }
+ if ( nbLayersSet.size() > 1 )
+ {
+ for ( exp.Init( _sdVec[i]._solid, TopAbs_EDGE ); exp.More(); exp.Next() )
+ {
+ PShapeIteratorPtr fIt = helper.GetAncestors( exp.Current(), *_mesh, TopAbs_FACE );
+ THyp hyp1 = 0, hyp2 = 0;
+ while( const TopoDS_Shape* face = fIt->next() )
+ {
+ const TGeomID faceID = getMeshDS()->ShapeToIndex( *face );
+ map< TGeomID, THyp >::iterator f2h = _sdVec[i]._face2hyp.find( faceID );
+ if ( f2h != _sdVec[i]._face2hyp.end() )
+ {
+ ( hyp1 ? hyp2 : hyp1 ) = f2h->second;
+ }
+ }
+ if ( hyp1 && hyp2 &&
+ hyp1->GetNumberLayers() != hyp2->GetNumberLayers() )
+ {
+ return error("Two hypotheses define different number of "
+ "viscous layers on adjacent faces");
+ }
+ }
+ }
+ } // if ( nbHyps > 1 )
+ else
{
- TopTools_IndexedDataMapOfShapeListOfShape solidsOfFace;
- if ( _sdVec[i]._hyp->IsToIgnoreShapes() )
- TopExp::MapShapesAndAncestors( _sdVec[i]._hypShape,
- TopAbs_FACE, TopAbs_SOLID, solidsOfFace);
+ _sdVec[i]._ignoreFaceIds.swap( ignoreFacesOfHyps.back().first );
+ }
+ // fill _SolidData::_reversedFaceIds
+ {
exp.Init( _sdVec[i]._solid.Oriented( TopAbs_FORWARD ), TopAbs_FACE );
for ( ; exp.More(); exp.Next() )
{
const TopoDS_Face& face = TopoDS::Face( exp.Current() );
- if ( helper.NbAncestors( face, *_mesh, TopAbs_SOLID ) < 2 )
- continue;
-
- const TGeomID faceInd = getMeshDS()->ShapeToIndex( face );
- if ( _sdVec[i]._hyp->IsToIgnoreShapes() )
- {
- int nbSolids = solidsOfFace.FindFromKey( face ).Extent();
- if ( nbSolids > 1 )
- _sdVec[i]._ignoreFaceIds.insert( faceInd );
- }
-
- if ( helper.IsReversedSubMesh( face ))
+ const TGeomID faceID = getMeshDS()->ShapeToIndex( face );
+ if ( //!sdVec[i]._ignoreFaceIds.count( faceID ) && ???????
+ helper.NbAncestors( face, *_mesh, TopAbs_SOLID ) > 1 &&
+ helper.IsReversedSubMesh( face ))
{
- _sdVec[i]._reversedFaceIds.insert( faceInd );
+ _sdVec[i]._reversedFaceIds.insert( faceID );
}
}
}
- }
+ } // loop on _sdVec
+
+ if ( onlyWith ) // is called to check hypotheses compatibility only
+ return true;
// Find faces to shrink mesh on (solution 2 in issue 0020832);
TopTools_IndexedMapOfShape shapes;
continue; // nothing interesting
TopoDS_Shape fWOL = FF[ ignore[0] ? 0 : 1 ];
// check presence of layers on fWOL within an adjacent SOLID
+ bool collision = false;
PShapeIteratorPtr sIt = helper.GetAncestors( fWOL, *_mesh, TopAbs_SOLID );
while ( const TopoDS_Shape* solid = sIt->next() )
if ( !solid->IsSame( _sdVec[i]._solid ))
int iFace = getMeshDS()->ShapeToIndex( fWOL );
if ( iSolid > 0 && !_sdVec[ iSolid-1 ]._ignoreFaceIds.count( iFace ))
{
- _sdVec[i]._noShrinkFaces.insert( iFace );
- fWOL.Nullify();
+ //_sdVec[i]._noShrinkShapes.insert( iFace );
+ //fWOL.Nullify();
+ collision = true;
}
}
// add edge to maps
{
TGeomID edgeInd = getMeshDS()->ShapeToIndex( edge );
_sdVec[i]._shrinkShape2Shape.insert( make_pair( edgeInd, fWOL ));
+ if ( collision )
+ {
+ // _shrinkShape2Shape will be used to temporary inflate _LayerEdge's based
+ // on the edge but shrink won't be performed
+ _sdVec[i]._noShrinkShapes.insert( edgeInd );
+ }
}
}
}
set< string > notSupportAlgos; notSupportAlgos.insert("Hexa_3D");
for ( size_t i = 0; i < _sdVec.size(); ++i )
{
- TopTools_MapOfShape noShrinkVertices;
map< TGeomID, TopoDS_Shape >::iterator e2f = _sdVec[i]._shrinkShape2Shape.begin();
for ( ; e2f != _sdVec[i]._shrinkShape2Shape.end(); ++e2f )
{
const TopoDS_Shape& fWOL = e2f->second;
- TGeomID edgeID = e2f->first;
+ const TGeomID edgeID = e2f->first;
bool notShrinkFace = false;
PShapeIteratorPtr soIt = helper.GetAncestors(fWOL, *_mesh, TopAbs_SOLID);
- while ( soIt->more())
+ while ( soIt->more() )
{
const TopoDS_Shape* solid = soIt->next();
if ( _sdVec[i]._solid.IsSame( *solid )) continue;
SMESH_Algo* algo = _mesh->GetGen()->GetAlgo( *_mesh, *solid );
if ( !algo || !notSupportAlgos.count( algo->GetName() )) continue;
notShrinkFace = true;
- for ( size_t j = 0; j < _sdVec.size(); ++j )
+ size_t iSolid = 0;
+ for ( ; iSolid < _sdVec.size(); ++iSolid )
{
- if ( _sdVec[j]._solid.IsSame( *solid ) )
- if ( _sdVec[j]._shrinkShape2Shape.count( edgeID ))
+ if ( _sdVec[iSolid]._solid.IsSame( *solid ) ) {
+ if ( _sdVec[iSolid]._shrinkShape2Shape.count( edgeID ))
notShrinkFace = false;
+ break;
+ }
}
- }
- if ( notShrinkFace )
- {
- _sdVec[i]._noShrinkFaces.insert( getMeshDS()->ShapeToIndex( fWOL ));
- for ( TopExp_Explorer vExp( fWOL, TopAbs_VERTEX ); vExp.More(); vExp.Next() )
- noShrinkVertices.Add( vExp.Current() );
- }
- }
- // erase from _shrinkShape2Shape all srink EDGE's of a SOLID connected
- // to the found not shrinked fWOL's
- e2f = _sdVec[i]._shrinkShape2Shape.begin();
- for ( ; e2f != _sdVec[i]._shrinkShape2Shape.end(); )
- {
- TGeomID edgeID = e2f->first;
- TopoDS_Vertex VV[2];
- TopExp::Vertices( TopoDS::Edge( getMeshDS()->IndexToShape( edgeID )),VV[0],VV[1]);
- if ( noShrinkVertices.Contains( VV[0] ) || noShrinkVertices.Contains( VV[1] ))
- {
- _sdVec[i]._noShrinkFaces.insert( getMeshDS()->ShapeToIndex( e2f->second ));
- _sdVec[i]._shrinkShape2Shape.erase( e2f++ );
- }
- else
- {
- e2f++;
- }
- }
- }
+ if ( notShrinkFace )
+ {
+ _sdVec[i]._noShrinkShapes.insert( edgeID );
+
+ // add VERTEXes of the edge in _noShrinkShapes
+ TopoDS_Shape edge = getMeshDS()->IndexToShape( edgeID );
+ for ( TopoDS_Iterator vIt( edge ); vIt.More(); vIt.Next() )
+ _sdVec[i]._noShrinkShapes.insert( getMeshDS()->ShapeToIndex( vIt.Value() ));
+
+ // check if there is a collision with to-shrink-from EDGEs in iSolid
+ if ( iSolid == _sdVec.size() )
+ continue; // no VL in the solid
+ shapes.Clear();
+ TopExp::MapShapes( fWOL, TopAbs_EDGE, shapes);
+ for ( int iE = 1; iE <= shapes.Extent(); ++iE )
+ {
+ const TopoDS_Edge& E = TopoDS::Edge( shapes( iE ));
+ const TGeomID eID = getMeshDS()->ShapeToIndex( E );
+ if ( eID == edgeID ||
+ !_sdVec[iSolid]._shrinkShape2Shape.count( eID ) ||
+ _sdVec[i]._noShrinkShapes.count( eID ))
+ continue;
+ for ( int is1st = 0; is1st < 2; ++is1st )
+ {
+ TopoDS_Vertex V = helper.IthVertex( is1st, E );
+ if ( _sdVec[i]._noShrinkShapes.count( getMeshDS()->ShapeToIndex( V ) ))
+ {
+ // _sdVec[i]._noShrinkShapes.insert( eID );
+ // V = helper.IthVertex( !is1st, E );
+ // _sdVec[i]._noShrinkShapes.insert( getMeshDS()->ShapeToIndex( V ));
+ //iE = 0; // re-start the loop on EDGEs of fWOL
+ return error("No way to make a conformal mesh with "
+ "the given set of faces with layers", _sdVec[i]._index);
+ }
+ }
+ }
+ }
+
+ } // while ( soIt->more() )
+ } // loop on _sdVec[i]._shrinkShape2Shape
+ } // loop on _sdVec to fill in _SolidData::_noShrinkShapes
// Find the SHAPE along which to inflate _LayerEdge based on VERTEX
{
totalNbFaces++;
const int fID = getMeshDS()->ShapeToIndex( *f );
- if ( _sdVec[i]._ignoreFaceIds.count ( fID ) &&
- !_sdVec[i]._noShrinkFaces.count( fID ))
+ if ( _sdVec[i]._ignoreFaceIds.count ( fID ) /*&&
+ !_sdVec[i]._noShrinkShapes.count( fID )*/)
facesWOL.push_back( *f );
}
}
return true;
}
+//================================================================================
+/*!
+ * \brief Finds FACEs w/o layers for a given SOLID by an hypothesis
+ */
+//================================================================================
+
+void _ViscousBuilder::getIgnoreFaces(const TopoDS_Shape& solid,
+ const StdMeshers_ViscousLayers* hyp,
+ const TopoDS_Shape& hypShape,
+ set<TGeomID>& ignoreFaceIds)
+{
+ TopExp_Explorer exp;
+
+ vector<TGeomID> ids = hyp->GetBndShapes();
+ if ( hyp->IsToIgnoreShapes() ) // FACEs to ignore are given
+ {
+ for ( size_t ii = 0; ii < ids.size(); ++ii )
+ {
+ const TopoDS_Shape& s = getMeshDS()->IndexToShape( ids[ii] );
+ if ( !s.IsNull() && s.ShapeType() == TopAbs_FACE )
+ ignoreFaceIds.insert( ids[ii] );
+ }
+ }
+ else // FACEs with layers are given
+ {
+ exp.Init( solid, TopAbs_FACE );
+ for ( ; exp.More(); exp.Next() )
+ {
+ TGeomID faceInd = getMeshDS()->ShapeToIndex( exp.Current() );
+ if ( find( ids.begin(), ids.end(), faceInd ) == ids.end() )
+ ignoreFaceIds.insert( faceInd );
+ }
+ }
+
+ // ignore internal FACEs if inlets and outlets are specified
+ if ( hyp->IsToIgnoreShapes() )
+ {
+ TopTools_IndexedDataMapOfShapeListOfShape solidsOfFace;
+ TopExp::MapShapesAndAncestors( hypShape,
+ TopAbs_FACE, TopAbs_SOLID, solidsOfFace);
+
+ for ( exp.Init( solid, TopAbs_FACE ); exp.More(); exp.Next() )
+ {
+ const TopoDS_Face& face = TopoDS::Face( exp.Current() );
+ if ( SMESH_MesherHelper::NbAncestors( face, *_mesh, TopAbs_SOLID ) < 2 )
+ continue;
+
+ int nbSolids = solidsOfFace.FindFromKey( face ).Extent();
+ if ( nbSolids > 1 )
+ ignoreFaceIds.insert( getMeshDS()->ShapeToIndex( face ));
+ }
+ }
+}
+
//================================================================================
/*!
* \brief Create the inner surface of the viscous layer and prepare data for infation
{
// get all sub-shapes to make layers on
set<TGeomID> subIds, faceIds;
- subIds = data._noShrinkFaces;
+ subIds = data._noShrinkShapes;
TopExp_Explorer exp( data._solid, TopAbs_FACE );
for ( ; exp.More(); exp.Next() )
{
SMESH_subMesh* fSubM = _mesh->GetSubMesh( exp.Current() );
- if ( ! data._ignoreFaceIds.count( getMeshDS()->ShapeToIndex( exp.Current() )))
+ if ( ! data._ignoreFaceIds.count( fSubM->GetId() ))
faceIds.insert( fSubM->GetId() );
- SMESH_subMeshIteratorPtr subIt =
- fSubM->getDependsOnIterator(/*includeSelf=*/true, /*complexShapeFirst=*/false);
+ SMESH_subMeshIteratorPtr subIt = fSubM->getDependsOnIterator(/*includeSelf=*/true);
while ( subIt->more() )
subIds.insert( subIt->next()->GetId() );
}
SMESH_MesherHelper helper( *_mesh );
helper.SetSubShape( data._solid );
- helper.SetElementsOnShape(true);
+ helper.SetElementsOnShape( true );
vector< const SMDS_MeshNode*> newNodes; // of a mesh face
TNode2Edge::iterator n2e2;
while ( eIt->more() )
{
const SMDS_MeshElement* face = eIt->next();
+ double faceMaxCosin = -1;
+ _LayerEdge* maxCosinEdge = 0;
+ int nbDegenNodes = 0;
+
newNodes.resize( face->NbCornerNodes() );
- double faceMaxCosin = -1;
- for ( int i = 0 ; i < face->NbCornerNodes(); ++i )
+ for ( size_t i = 0 ; i < newNodes.size(); ++i )
{
- const SMDS_MeshNode* n = face->GetNode(i);
+ const SMDS_MeshNode* n = face->GetNode( i );
+ const int shapeID = n->getshapeId();
+ const bool onDegenShap = helper.IsDegenShape( shapeID );
+ const bool onDegenEdge = ( onDegenShap && n->GetPosition()->GetDim() == 1 );
+ if ( onDegenShap )
+ {
+ if ( onDegenEdge )
+ {
+ // substitute n on a degenerated EDGE with a node on a corresponding VERTEX
+ const TopoDS_Shape& E = getMeshDS()->IndexToShape( shapeID );
+ TopoDS_Vertex V = helper.IthVertex( 0, TopoDS::Edge( E ));
+ if ( const SMDS_MeshNode* vN = SMESH_Algo::VertexNode( V, getMeshDS() )) {
+ n = vN;
+ nbDegenNodes++;
+ }
+ }
+ else
+ {
+ nbDegenNodes++;
+ }
+ }
TNode2Edge::iterator n2e = data._n2eMap.insert( make_pair( n, (_LayerEdge*)0 )).first;
if ( !(*n2e).second )
{
// add a _LayerEdge
_LayerEdge* edge = new _LayerEdge();
- n2e->second = edge;
edge->_nodes.push_back( n );
- const int shapeID = n->getshapeId();
+ n2e->second = edge;
edgesByGeom[ shapeID ].push_back( edge );
+ const bool noShrink = data._noShrinkShapes.count( shapeID );
SMESH_TNodeXYZ xyz( n );
// set edge data or find already refined _LayerEdge and get data from it
- if ( n->GetPosition()->GetTypeOfPosition() != SMDS_TOP_FACE &&
- ( s2ne = data._s2neMap.find( shapeID )) != data._s2neMap.end() &&
- ( n2e2 = (*s2ne).second->find( n )) != s2ne->second->end())
+ if (( !noShrink ) &&
+ ( n->GetPosition()->GetTypeOfPosition() != SMDS_TOP_FACE ) &&
+ (( s2ne = data._s2neMap.find( shapeID )) != data._s2neMap.end() ) &&
+ (( n2e2 = (*s2ne).second->find( n )) != s2ne->second->end() ))
{
_LayerEdge* foundEdge = (*n2e2).second;
gp_XYZ lastPos = edge->Copy( *foundEdge, helper );
}
else
{
- edge->_nodes.push_back( helper.AddNode( xyz.X(), xyz.Y(), xyz.Z() ));
+ if ( !noShrink )
+ {
+ edge->_nodes.push_back( helper.AddNode( xyz.X(), xyz.Y(), xyz.Z() ));
+ }
if ( !setEdgeData( *edge, subIds, helper, data ))
return false;
}
dumpMove(edge->_nodes.back());
- if ( edge->_cosin > 0.01 )
+
+ if ( edge->_cosin > faceMaxCosin )
{
- if ( edge->_cosin > faceMaxCosin )
- faceMaxCosin = edge->_cosin;
+ faceMaxCosin = edge->_cosin;
+ maxCosinEdge = edge;
}
}
newNodes[ i ] = n2e->second->_nodes.back();
+
+ if ( onDegenEdge )
+ data._n2eMap.insert( make_pair( face->GetNode( i ), n2e->second ));
}
+ if ( newNodes.size() - nbDegenNodes < 2 )
+ continue;
+
// create a temporary face
- const SMDS_MeshElement* newFace = new TmpMeshFace( newNodes, --_tmpFaceID );
+ const SMDS_MeshElement* newFace =
+ new _TmpMeshFace( newNodes, --_tmpFaceID, face->getshapeId() );
proxySub->AddElement( newFace );
// compute inflation step size by min size of element on a convex surface
- if ( faceMaxCosin > 0.1 )
- limitStepSize( data, face, faceMaxCosin );
+ if ( faceMaxCosin > theMinSmoothCosin )
+ limitStepSize( data, face, maxCosinEdge );
+
} // loop on 2D elements on a FACE
} // loop on FACEs of a SOLID
if ( data._stepSize < 1. )
data._epsilon *= data._stepSize;
- // fill data._simplexTestEdges
- findSimplexTestEdges( data, edgesByGeom );
-
- // limit data._stepSize depending on surface curvature
- limitStepSizeByCurvature( data, edgesByGeom );
-
// Put _LayerEdge's into the vector data._edges
if ( !sortEdges( data, edgesByGeom ))
return false;
- // Set target nodes into _Simplex and _2NearEdges of _LayerEdge's
+ // limit data._stepSize depending on surface curvature and fill data._convexFaces
+ limitStepSizeByCurvature( data ); // !!! it must be before node substitution in _Simplex
+
+ // Set target nodes into _Simplex and _LayerEdge's to _2NearEdges
TNode2Edge::iterator n2e;
+ const SMDS_MeshNode* nn[2];
for ( size_t i = 0; i < data._edges.size(); ++i )
{
- if ( data._edges[i]->IsOnEdge())
+ _LayerEdge* edge = data._edges[i];
+ if ( edge->IsOnEdge() )
+ {
+ // get neighbor nodes
+ bool hasData = ( edge->_2neibors->_edges[0] );
+ if ( hasData ) // _LayerEdge is a copy of another one
+ {
+ nn[0] = edge->_2neibors->srcNode(0);
+ nn[1] = edge->_2neibors->srcNode(1);
+ }
+ else if ( !findNeiborsOnEdge( edge, nn[0],nn[1], data ))
+ {
+ return false;
+ }
+ // set neighbor _LayerEdge's
for ( int j = 0; j < 2; ++j )
{
- if ( data._edges[i]->_nodes.back()->NbInverseElements(SMDSAbs_Volume) > 0 )
- break; // _LayerEdge is shared by two _SolidData's
- const SMDS_MeshNode* & n = data._edges[i]->_2neibors->_nodes[j];
- if (( n2e = data._n2eMap.find( n )) == data._n2eMap.end() )
+ if (( n2e = data._n2eMap.find( nn[j] )) == data._n2eMap.end() )
return error("_LayerEdge not found by src node", data._index);
- n = (*n2e).second->_nodes.back();
- data._edges[i]->_2neibors->_edges[j] = n2e->second;
+ edge->_2neibors->_edges[j] = n2e->second;
}
- //else
- for ( size_t j = 0; j < data._edges[i]->_simplices.size(); ++j )
- {
- _Simplex& s = data._edges[i]->_simplices[j];
+ if ( !hasData )
+ edge->SetDataByNeighbors( nn[0], nn[1], helper);
+ }
+
+ for ( size_t j = 0; j < edge->_simplices.size(); ++j )
+ {
+ _Simplex& s = edge->_simplices[j];
s._nNext = data._n2eMap[ s._nNext ]->_nodes.back();
s._nPrev = data._n2eMap[ s._nPrev ]->_nodes.back();
}
+
+ // For an _LayerEdge on a degenerated EDGE, copy some data from
+ // a corresponding _LayerEdge on a VERTEX
+ // (issue 52453, pb on a downloaded SampleCase2-Tet-netgen-mephisto.hdf)
+ if ( helper.IsDegenShape( edge->_nodes[0]->getshapeId() ))
+ {
+ // Generally we should not get here
+ const TopoDS_Shape& E = getMeshDS()->IndexToShape( edge->_nodes[0]->getshapeId() );
+ if ( E.ShapeType() != TopAbs_EDGE )
+ continue;
+ TopoDS_Vertex V = helper.IthVertex( 0, TopoDS::Edge( E ));
+ const SMDS_MeshNode* vN = SMESH_Algo::VertexNode( V, getMeshDS() );
+ if (( n2e = data._n2eMap.find( vN )) == data._n2eMap.end() )
+ continue;
+ const _LayerEdge* vEdge = n2e->second;
+ edge->_normal = vEdge->_normal;
+ edge->_lenFactor = vEdge->_lenFactor;
+ edge->_cosin = vEdge->_cosin;
+ }
}
dumpFunctionEnd();
void _ViscousBuilder::limitStepSize( _SolidData& data,
const SMDS_MeshElement* face,
- const double cosin)
+ const _LayerEdge* maxCosinEdge )
{
int iN = 0;
double minSize = 10 * data._stepSize;
for ( int i = 0; i < nbNodes; ++i )
{
const SMDS_MeshNode* nextN = face->GetNode( SMESH_MesherHelper::WrapIndex( i+1, nbNodes ));
- const SMDS_MeshNode* curN = face->GetNode( i );
+ const SMDS_MeshNode* curN = face->GetNode( i );
if ( nextN->GetPosition()->GetTypeOfPosition() == SMDS_TOP_FACE ||
- curN->GetPosition()->GetTypeOfPosition() == SMDS_TOP_FACE )
+ curN-> GetPosition()->GetTypeOfPosition() == SMDS_TOP_FACE )
{
- double dist = SMESH_TNodeXYZ( face->GetNode(i)).Distance( nextN );
+ double dist = SMESH_TNodeXYZ( curN ).Distance( nextN );
if ( dist < minSize )
minSize = dist, iN = i;
}
}
- double newStep = 0.8 * minSize / cosin;
+ double newStep = 0.8 * minSize / maxCosinEdge->_lenFactor;
if ( newStep < data._stepSize )
{
data._stepSize = newStep;
- data._stepSizeCoeff = 0.8 / cosin;
+ data._stepSizeCoeff = 0.8 / maxCosinEdge->_lenFactor;
data._stepSizeNodes[0] = face->GetNode( iN );
data._stepSizeNodes[1] = face->GetNode( SMESH_MesherHelper::WrapIndex( iN+1, nbNodes ));
}
//================================================================================
/*!
- * \brief Limit data._stepSize by evaluating curvature of shapes
+ * \brief Limit data._stepSize by evaluating curvature of shapes and fill data._convexFaces
*/
//================================================================================
-void _ViscousBuilder::limitStepSizeByCurvature( _SolidData& data,
- vector< vector<_LayerEdge*> >& edgesByGeom)
+void _ViscousBuilder::limitStepSizeByCurvature( _SolidData& data )
{
- const int nbTestPnt = 5;
- const double minCurvature = 0.9 / data._hyp->GetTotalThickness();
+ const int nbTestPnt = 5; // on a FACE sub-shape
BRepLProp_SLProps surfProp( 2, 1e-6 );
SMESH_MesherHelper helper( *_mesh );
+ data._convexFaces.clear();
+
TopExp_Explorer face( data._solid, TopAbs_FACE );
for ( ; face.More(); face.Next() )
{
const TopoDS_Face& F = TopoDS::Face( face.Current() );
+ SMESH_subMesh * sm = _mesh->GetSubMesh( F );
+ const TGeomID faceID = sm->GetId();
+ if ( data._ignoreFaceIds.count( faceID )) continue;
+
BRepAdaptor_Surface surface( F, false );
surfProp.SetSurface( surface );
- SMESH_subMesh * sm = _mesh->GetSubMesh( F );
+ bool isTooCurved = false;
+ int iBeg, iEnd;
+
+ _ConvexFace cnvFace;
+ const double oriFactor = ( F.Orientation() == TopAbs_REVERSED ? +1. : -1. );
SMESH_subMeshIteratorPtr smIt = sm->getDependsOnIterator(/*includeSelf=*/true);
while ( smIt->more() )
{
sm = smIt->next();
- const vector<_LayerEdge*>& ledges = edgesByGeom[ sm->GetId() ];
- int step = Max( 1, int( ledges.size()) / nbTestPnt );
- for ( size_t i = 0; i < ledges.size(); i += step )
+ const TGeomID subID = sm->GetId();
+ // find _LayerEdge's of a sub-shape
+ size_t edgesEnd;
+ if ( data.GetShapeEdges( subID, edgesEnd, &iBeg, &iEnd ))
+ cnvFace._subIdToEdgeEnd.insert( make_pair( subID, edgesEnd ));
+ else
+ continue;
+ // check concavity and curvature and limit data._stepSize
+ const double minCurvature = 0.9 / data._hypOnShape[ edgesEnd ].GetTotalThickness();
+ int nbLEdges = iEnd - iBeg;
+ int iStep = Max( 1, nbLEdges / nbTestPnt );
+ for ( ; iBeg < iEnd; iBeg += iStep )
{
- gp_XY uv = helper.GetNodeUV( F, ledges[i]->_nodes[0] );
+ gp_XY uv = helper.GetNodeUV( F, data._edges[ iBeg ]->_nodes[0] );
surfProp.SetParameters( uv.X(), uv.Y() );
if ( !surfProp.IsCurvatureDefined() )
continue;
- double surfCurvature = Max( Abs( surfProp.MaxCurvature() ),
- Abs( surfProp.MinCurvature() ));
- if ( surfCurvature < minCurvature )
- continue;
-
- gp_Dir minDir, maxDir;
- surfProp.CurvatureDirections( maxDir, minDir );
- if ( F.Orientation() == TopAbs_REVERSED ) {
- maxDir.Reverse(); minDir.Reverse();
+ if ( surfProp.MaxCurvature() * oriFactor > minCurvature )
+ {
+ limitStepSize( data, 0.9 / surfProp.MaxCurvature() * oriFactor );
+ isTooCurved = true;
+ }
+ if ( surfProp.MinCurvature() * oriFactor > minCurvature )
+ {
+ limitStepSize( data, 0.9 / surfProp.MinCurvature() * oriFactor );
+ isTooCurved = true;
}
- const gp_XYZ& inDir = ledges[i]->_normal;
- if ( inDir * maxDir.XYZ() < 0 &&
- inDir * minDir.XYZ() < 0 )
- continue;
-
- limitStepSize( data, 0.9 / surfCurvature );
}
- }
- }
-}
-
-//================================================================================
-/*!
- * Fill data._simplexTestEdges. These _LayerEdge's are used to stop inflation
- * in the case where there are no _LayerEdge's on a curved convex FACE,
- * as e.g. on a fillet surface with no internal nodes - issue 22580,
- * so that collision of viscous internal faces is not detected by check of
- * intersection of _LayerEdge's with the viscous internal faces.
- */
-//================================================================================
-
-void _ViscousBuilder::findSimplexTestEdges( _SolidData& data,
- vector< vector<_LayerEdge*> >& edgesByGeom)
-{
- data._simplexTestEdges.clear();
+ } // loop on sub-shapes of the FACE
- SMESH_MesherHelper helper( *_mesh );
-
- vector< vector<_LayerEdge*> * > ledgesOnEdges;
- set< const SMDS_MeshNode* > usedNodes;
+ if ( !isTooCurved ) continue;
- const double minCurvature = 1. / data._hyp->GetTotalThickness();
+ _ConvexFace & convFace =
+ data._convexFaces.insert( make_pair( faceID, cnvFace )).first->second;
- for ( size_t iS = 1; iS < edgesByGeom.size(); ++iS )
- {
- // look for a FACE with layers and w/o _LayerEdge's
- const vector<_LayerEdge*>& eS = edgesByGeom[iS];
- if ( !eS.empty() ) continue;
- const TopoDS_Shape& S = getMeshDS()->IndexToShape( iS );
- if ( S.IsNull() || S.ShapeType() != TopAbs_FACE ) continue;
- if ( data._ignoreFaceIds.count( iS )) continue;
+ convFace._face = F;
+ convFace._normalsFixed = false;
- const TopoDS_Face& F = TopoDS::Face( S );
-
- // look for _LayerEdge's on EDGEs with null _sWOL
- ledgesOnEdges.clear();
- TopExp_Explorer eExp( F, TopAbs_EDGE );
- for ( ; eExp.More(); eExp.Next() )
+ // Fill _ConvexFace::_simplexTestEdges. These _LayerEdge's are used to detect
+ // prism distortion.
+ map< TGeomID, int >::iterator id2end = convFace._subIdToEdgeEnd.find( faceID );
+ if ( id2end != convFace._subIdToEdgeEnd.end() )
{
- TGeomID iE = getMeshDS()->ShapeToIndex( eExp.Current() );
- vector<_LayerEdge*>& eE = edgesByGeom[iE];
- if ( !eE.empty() && eE[0]->_sWOL.IsNull() )
- ledgesOnEdges.push_back( & eE );
+ // there are _LayerEdge's on the FACE it-self;
+ // select _LayerEdge's near EDGEs
+ data.GetEdgesOnShape( id2end->second, iBeg, iEnd );
+ for ( ; iBeg < iEnd; ++iBeg )
+ {
+ _LayerEdge* ledge = data._edges[ iBeg ];
+ for ( size_t j = 0; j < ledge->_simplices.size(); ++j )
+ if ( ledge->_simplices[j]._nNext->GetPosition()->GetDim() < 2 )
+ {
+ convFace._simplexTestEdges.push_back( ledge );
+ break;
+ }
+ }
}
- if ( ledgesOnEdges.empty() ) continue;
-
- // check FACE convexity
- const _LayerEdge* le = ledgesOnEdges[0]->back();
- gp_XY uv = helper.GetNodeUV( F, le->_nodes[0] );
- BRepAdaptor_Surface surf( F );
- BRepLProp_SLProps surfProp( surf, uv.X(), uv.Y(), 2, 1e-6 );
- if ( !surfProp.IsCurvatureDefined() )
- continue;
- double surfCurvature = Max( Abs( surfProp.MaxCurvature() ),
- Abs( surfProp.MinCurvature() ));
- if ( surfCurvature < minCurvature )
- continue;
- gp_Dir minDir, maxDir;
- surfProp.CurvatureDirections( maxDir, minDir );
- if ( F.Orientation() == TopAbs_REVERSED ) {
- maxDir.Reverse(); minDir.Reverse();
- }
- const gp_XYZ& inDir = le->_normal;
- if ( inDir * maxDir.XYZ() < 0 &&
- inDir * minDir.XYZ() < 0 )
- continue;
+ else
+ {
+ // where there are no _LayerEdge's on a _ConvexFace,
+ // as e.g. on a fillet surface with no internal nodes - issue 22580,
+ // so that collision of viscous internal faces is not detected by check of
+ // intersection of _LayerEdge's with the viscous internal faces.
- limitStepSize( data, 0.9 / surfCurvature );
+ set< const SMDS_MeshNode* > usedNodes;
- // add _simplices to the _LayerEdge's
- for ( size_t iE = 0; iE < ledgesOnEdges.size(); ++iE )
- {
- const vector<_LayerEdge*>& ledges = *ledgesOnEdges[iE];
- for ( size_t iLE = 0; iLE < ledges.size(); ++iLE )
+ // look for _LayerEdge's with null _sWOL
+ map< TGeomID, int >::iterator id2end = convFace._subIdToEdgeEnd.begin();
+ for ( ; id2end != convFace._subIdToEdgeEnd.end(); ++id2end )
{
- _LayerEdge* ledge = ledges[iLE];
- const SMDS_MeshNode* srcNode = ledge->_nodes[0];
- if ( !usedNodes.insert( srcNode ).second ) continue;
-
- getSimplices( srcNode, ledge->_simplices, data._ignoreFaceIds, &data );
- for ( size_t i = 0; i < ledge->_simplices.size(); ++i )
+ data.GetEdgesOnShape( id2end->second, iBeg, iEnd );
+ if ( iBeg >= iEnd || !data._edges[ iBeg ]->_sWOL.IsNull() )
+ continue;
+ for ( ; iBeg < iEnd; ++iBeg )
{
- usedNodes.insert( ledge->_simplices[i]._nPrev );
- usedNodes.insert( ledge->_simplices[i]._nNext );
+ _LayerEdge* ledge = data._edges[ iBeg ];
+ const SMDS_MeshNode* srcNode = ledge->_nodes[0];
+ if ( !usedNodes.insert( srcNode ).second ) continue;
+
+ getSimplices( srcNode, ledge->_simplices, data._ignoreFaceIds, &data );
+ for ( size_t i = 0; i < ledge->_simplices.size(); ++i )
+ {
+ usedNodes.insert( ledge->_simplices[i]._nPrev );
+ usedNodes.insert( ledge->_simplices[i]._nNext );
+ }
+ convFace._simplexTestEdges.push_back( ledge );
}
- data._simplexTestEdges.push_back( ledge );
}
}
- }
+ } // loop on FACEs of data._solid
}
//================================================================================
bool _ViscousBuilder::sortEdges( _SolidData& data,
vector< vector<_LayerEdge*> >& edgesByGeom)
{
+ // define allowed thickness
+ computeGeomSize( data ); // compute data._geomSize
+
+ data._maxThickness = 0;
+ data._minThickness = 1e100;
+ list< const StdMeshers_ViscousLayers* >::iterator hyp = data._hyps.begin();
+ for ( ; hyp != data._hyps.end(); ++hyp )
+ {
+ data._maxThickness = Max( data._maxThickness, (*hyp)->GetTotalThickness() );
+ data._minThickness = Min( data._minThickness, (*hyp)->GetTotalThickness() );
+ }
+ const double tgtThick = /*Min( 0.5 * data._geomSize, */data._maxThickness;
+
// Find shapes needing smoothing; such a shape has _LayerEdge._normal on it's
- // boundry inclined at a sharp angle to the shape
+ // boundry inclined to the shape at a sharp angle
list< TGeomID > shapesToSmooth;
{
case TopAbs_EDGE: {
- bool isShrinkEdge = !eS[0]->_sWOL.IsNull();
+ if ( SMESH_Algo::isDegenerated( TopoDS::Edge( S )))
+ break;
+ //bool isShrinkEdge = !eS[0]->_sWOL.IsNull();
for ( TopoDS_Iterator vIt( S ); vIt.More() && !needSmooth; vIt.Next() )
{
TGeomID iV = getMeshDS()->ShapeToIndex( vIt.Value() );
vector<_LayerEdge*>& eV = edgesByGeom[ iV ];
if ( eV.empty() ) continue;
- double cosin = eV[0]->_cosin;
- bool badCosin =
- ( !eV[0]->_sWOL.IsNull() && ( eV[0]->_sWOL.ShapeType() == TopAbs_EDGE || !isShrinkEdge));
- if ( badCosin )
+ gp_Vec eDir = getEdgeDir( TopoDS::Edge( S ), TopoDS::Vertex( vIt.Value() ));
+ double angle = eDir.Angle( eV[0]->_normal );
+ double cosin = Cos( angle );
+ if ( cosin > theMinSmoothCosin )
{
- gp_Vec dir1, dir2;
- if ( eV[0]->_sWOL.ShapeType() == TopAbs_EDGE )
- dir1 = getEdgeDir( TopoDS::Edge( eV[0]->_sWOL ), TopoDS::Vertex( vIt.Value() ));
- else
- dir1 = getFaceDir( TopoDS::Face( eV[0]->_sWOL ), TopoDS::Vertex( vIt.Value() ),
- eV[0]->_nodes[0], helper, ok);
- dir2 = getEdgeDir( TopoDS::Edge( S ), TopoDS::Vertex( vIt.Value() ));
- double angle = dir1.Angle( dir2 );
- cosin = cos( angle );
+ // compare tgtThick with the length of an end segment
+ SMDS_ElemIteratorPtr eIt = eV[0]->_nodes[0]->GetInverseElementIterator(SMDSAbs_Edge);
+ while ( eIt->more() )
+ {
+ const SMDS_MeshElement* endSeg = eIt->next();
+ if ( endSeg->getshapeId() == iS )
+ {
+ double segLen =
+ SMESH_TNodeXYZ( endSeg->GetNode(0) ).Distance( endSeg->GetNode(1 ));
+ needSmooth = needSmoothing( cosin, tgtThick, segLen );
+ break;
+ }
+ }
}
- needSmooth = ( cosin > 0.1 );
}
break;
}
TGeomID iE = getMeshDS()->ShapeToIndex( eExp.Current() );
vector<_LayerEdge*>& eE = edgesByGeom[ iE ];
if ( eE.empty() ) continue;
- if ( eE[0]->_sWOL.IsNull() )
+ // TopLoc_Location loc;
+ // Handle(Geom_Surface) surface = BRep_Tool::Surface( TopoDS::Face( S ), loc );
+ // bool isPlane = GeomLib_IsPlanarSurface( surface ).IsPlanar();
+ //if ( eE[0]->_sWOL.IsNull() )
{
+ double faceSize;
for ( size_t i = 0; i < eE.size() && !needSmooth; ++i )
- needSmooth = ( eE[i]->_cosin > 0.1 );
- }
- else
- {
- const TopoDS_Face& F1 = TopoDS::Face( S );
- const TopoDS_Face& F2 = TopoDS::Face( eE[0]->_sWOL );
- const TopoDS_Edge& E = TopoDS::Edge( eExp.Current() );
- for ( size_t i = 0; i < eE.size() && !needSmooth; ++i )
- {
- gp_Vec dir1 = getFaceDir( F1, E, eE[i]->_nodes[0], helper, ok );
- gp_Vec dir2 = getFaceDir( F2, E, eE[i]->_nodes[0], helper, ok );
- double angle = dir1.Angle( dir2 );
- double cosin = cos( angle );
- needSmooth = ( cosin > 0.1 );
- }
+ if ( eE[i]->_cosin > theMinSmoothCosin )
+ {
+ SMDS_ElemIteratorPtr fIt = eE[i]->_nodes[0]->GetInverseElementIterator(SMDSAbs_Face);
+ while ( fIt->more() && !needSmooth )
+ {
+ const SMDS_MeshElement* face = fIt->next();
+ if ( getDistFromEdge( face, eE[i]->_nodes[0], faceSize ))
+ needSmooth = needSmoothing( eE[i]->_cosin, tgtThick, faceSize );
+ }
+ }
}
+ // else
+ // {
+ // const TopoDS_Face& F1 = TopoDS::Face( S );
+ // const TopoDS_Face& F2 = TopoDS::Face( eE[0]->_sWOL );
+ // const TopoDS_Edge& E = TopoDS::Edge( eExp.Current() );
+ // for ( size_t i = 0; i < eE.size() && !needSmooth; ++i )
+ // {
+ // gp_Vec dir1 = getFaceDir( F1, E, eE[i]->_nodes[0], helper, ok );
+ // gp_Vec dir2 = getFaceDir( F2, E, eE[i]->_nodes[0], helper, ok );
+ // double angle = dir1.Angle( );
+ // double cosin = cos( angle );
+ // needSmooth = ( cosin > theMinSmoothCosin );
+ // }
+ // }
}
break;
}
continue;
default:;
}
+
if ( needSmooth )
{
if ( S.ShapeType() == TopAbs_EDGE ) shapesToSmooth.push_front( iS );
} // loop on edgesByGeom
data._edges.reserve( data._n2eMap.size() );
- data._endEdgeToSmooth.clear();
+ data._endEdgeOnShape.clear();
// first we put _LayerEdge's on shapes to smooth
+ data._nbShapesToSmooth = 0;
list< TGeomID >::iterator gIt = shapesToSmooth.begin();
for ( ; gIt != shapesToSmooth.end(); ++gIt )
{
vector<_LayerEdge*>& eVec = edgesByGeom[ *gIt ];
if ( eVec.empty() ) continue;
data._edges.insert( data._edges.end(), eVec.begin(), eVec.end() );
- data._endEdgeToSmooth.push_back( data._edges.size() );
+ data._endEdgeOnShape.push_back( data._edges.size() );
+ data._nbShapesToSmooth++;
eVec.clear();
}
for ( size_t iS = 0; iS < edgesByGeom.size(); ++iS )
{
vector<_LayerEdge*>& eVec = edgesByGeom[iS];
+ if ( eVec.empty() ) continue;
data._edges.insert( data._edges.end(), eVec.begin(), eVec.end() );
- eVec.clear();
+ data._endEdgeOnShape.push_back( data._edges.size() );
+ //eVec.clear();
+ }
+
+ // compute average StdMeshers_ViscousLayers parameters for each shape
+
+ data._hypOnShape.clear();
+ if ( data._hyps.size() == 1 )
+ {
+ data._hypOnShape.resize( data._endEdgeOnShape.size(), AverageHyp( data._hyps.back() ));
+ }
+ else
+ {
+ data._hypOnShape.resize( data._endEdgeOnShape.size() );
+ map< TGeomID, const StdMeshers_ViscousLayers* >::iterator f2hyp;
+ for ( size_t i = 0; i < data._endEdgeOnShape.size(); ++i )
+ {
+ int iEnd = data._endEdgeOnShape[i];
+ _LayerEdge* LE = data._edges[ iEnd-1 ];
+ TGeomID iShape = LE->_nodes[0]->getshapeId();
+ const TopoDS_Shape& S = getMeshDS()->IndexToShape( iShape );
+ if ( S.ShapeType() == TopAbs_FACE )
+ {
+ if (( f2hyp = data._face2hyp.find( iShape )) != data._face2hyp.end() )
+ {
+ data._hypOnShape[ i ].Add( f2hyp->second );
+ }
+ }
+ else
+ {
+ PShapeIteratorPtr fIt = SMESH_MesherHelper::GetAncestors( S, *_mesh, TopAbs_FACE );
+ while ( const TopoDS_Shape* face = fIt->next() )
+ {
+ TGeomID faceID = getMeshDS()->ShapeToIndex( *face );
+ if (( f2hyp = data._face2hyp.find( faceID )) != data._face2hyp.end() )
+ {
+ data._hypOnShape[ i ].Add( f2hyp->second );
+ }
+ }
+ }
+ }
}
return ok;
const SMDS_MeshNode* node = edge._nodes[0]; // source node
SMDS_TypeOfPosition posType = node->GetPosition()->GetTypeOfPosition();
- edge._len = 0;
- edge._2neibors = 0;
+ edge._len = 0;
+ edge._2neibors = 0;
edge._curvature = 0;
// --------------------------
edge._normal.SetCoord(0,0,0);
int totalNbFaces = 0;
- gp_Pnt p;
- gp_Vec du, dv, geomNorm;
+ gp_Vec geomNorm;
bool normOK = true;
- TGeomID shapeInd = node->getshapeId();
+ const TGeomID shapeInd = node->getshapeId();
map< TGeomID, TopoDS_Shape >::const_iterator s2s = data._shrinkShape2Shape.find( shapeInd );
- bool onShrinkShape ( s2s != data._shrinkShape2Shape.end() );
- TopoDS_Shape vertEdge;
+ const bool onShrinkShape ( s2s != data._shrinkShape2Shape.end() );
if ( onShrinkShape ) // one of faces the node is on has no layers
{
- vertEdge = getMeshDS()->IndexToShape( s2s->first ); // vertex or edge
+ TopoDS_Shape vertEdge = getMeshDS()->IndexToShape( s2s->first ); // vertex or edge
if ( s2s->second.ShapeType() == TopAbs_EDGE )
{
// inflate from VERTEX along EDGE
if ( edge._sWOL.ShapeType() == TopAbs_EDGE )
{
double u = helper.GetNodeU( TopoDS::Edge( edge._sWOL ), node, 0, &normOK );
- edge._pos.push_back( gp_XYZ( u, 0, 0));
- getMeshDS()->SetNodeOnEdge( tgtNode, TopoDS::Edge( edge._sWOL ), u );
+ edge._pos.push_back( gp_XYZ( u, 0, 0 ));
+ if ( edge._nodes.size() > 1 )
+ getMeshDS()->SetNodeOnEdge( tgtNode, TopoDS::Edge( edge._sWOL ), u );
}
else // TopAbs_FACE
{
gp_XY uv = helper.GetNodeUV( TopoDS::Face( edge._sWOL ), node, 0, &normOK );
edge._pos.push_back( gp_XYZ( uv.X(), uv.Y(), 0));
- getMeshDS()->SetNodeOnFace( tgtNode, TopoDS::Face( edge._sWOL ), uv.X(), uv.Y() );
+ if ( edge._nodes.size() > 1 )
+ getMeshDS()->SetNodeOnFace( tgtNode, TopoDS::Face( edge._sWOL ), uv.X(), uv.Y() );
}
}
else
{
edge._2neibors = new _2NearEdges;
// target node instead of source ones will be set later
- if ( ! findNeiborsOnEdge( &edge,
- edge._2neibors->_nodes[0],
- edge._2neibors->_nodes[1],
- data))
- return false;
- edge.SetDataByNeighbors( edge._2neibors->_nodes[0],
- edge._2neibors->_nodes[1],
- helper);
+ // if ( ! findNeiborsOnEdge( &edge,
+ // edge._2neibors->_nodes[0],
+ // edge._2neibors->_nodes[1],
+ // data))
+ // return false;
+ // edge.SetDataByNeighbors( edge._2neibors->_nodes[0],
+ // edge._2neibors->_nodes[1],
+ // helper);
}
edge.SetCosin( edge._cosin ); // to update edge._lenFactor
isOK = false;
Handle(Geom_Surface) surface = BRep_Tool::Surface( face );
- if ( GeomLib::NormEstim( surface, uv, 1e-10, normal ) < 3 )
+ int pointKind = GeomLib::NormEstim( surface, uv, 1e-5, normal );
+ enum { REGULAR = 0, QUASYSINGULAR, CONICAL, IMPOSSIBLE };
+
+ if ( pointKind == IMPOSSIBLE &&
+ node->GetPosition()->GetDim() == 2 ) // node inside the FACE
+ {
+ // probably NormEstim() failed due to a too high tolerance
+ pointKind = GeomLib::NormEstim( surface, uv, 1e-20, normal );
+ isOK = ( pointKind < IMPOSSIBLE );
+ }
+ if ( pointKind < IMPOSSIBLE )
{
- normal;
+ if ( pointKind != REGULAR &&
+ !shiftInside &&
+ node->GetPosition()->GetDim() < 2 ) // FACE boundary
+ {
+ gp_XYZ normShift = getFaceNormal( node, face, helper, isOK, /*shiftInside=*/true );
+ if ( normShift * normal.XYZ() < 0. )
+ normal = normShift;
+ }
isOK = true;
}
- else // hard singularity
+
+ if ( !isOK ) // hard singularity, to call with shiftInside=true ?
{
const TGeomID faceID = helper.GetMeshDS()->ShapeToIndex( face );
isOK = SMESH_MeshAlgos::FaceNormal( f, (gp_XYZ&) normal.XYZ(), /*normalized=*/true );
if ( isOK )
{
- if ( helper.IsReversedSubMesh( face ))
+ TopoDS_Face ff = face;
+ ff.Orientation( TopAbs_FORWARD );
+ if ( helper.IsReversedSubMesh( ff ))
normal.Reverse();
break;
}
}
else
{
- TopoDS_Vertex v10 = SMESH_MesherHelper::IthVertex( 1, ee[ 0 ]);
- TopoDS_Vertex v01 = SMESH_MesherHelper::IthVertex( 0, ee[ 1 ]);
- if ( !v10.IsSame( v01 ))
+ if ( !V.IsSame( SMESH_MesherHelper::IthVertex( 0, ee[ 1 ] )))
std::swap( ee[0], ee[1] );
}
- angles[i] = SMESH_MesherHelper::GetAngle( ee[0], ee[1], F );
+ angles[i] = SMESH_MesherHelper::GetAngle( ee[0], ee[1], F, TopoDS::Vertex( V ));
}
// compute a weighted normal
_SolidData& data)
{
const SMDS_MeshNode* node = edge->_nodes[0];
- const int shapeInd = node->getshapeId();
- SMESHDS_SubMesh* edgeSM = 0;
+ const int shapeInd = node->getshapeId();
+ SMESHDS_SubMesh* edgeSM = 0;
if ( node->GetPosition()->GetTypeOfPosition() == SMDS_TOP_EDGE )
{
-
edgeSM = getMeshDS()->MeshElements( shapeInd );
if ( !edgeSM || edgeSM->NbElements() == 0 )
return error(SMESH_Comment("Not meshed EDGE ") << shapeInd, data._index);
// Set _curvature
- double sumLen = vec1.Modulus() + vec2.Modulus();
+ double sumLen = vec1.Modulus() + vec2.Modulus();
_2neibors->_wgt[0] = 1 - vec1.Modulus() / sumLen;
_2neibors->_wgt[1] = 1 - vec2.Modulus() / sumLen;
double avgNormProj = 0.5 * ( _normal * vec1 + _normal * vec2 );
- double avgLen = 0.5 * ( vec1.Modulus() + vec2.Modulus() );
+ double avgLen = 0.5 * ( vec1.Modulus() + vec2.Modulus() );
if ( _curvature ) delete _curvature;
_curvature = _Curvature::New( avgNormProj, avgLen );
-#ifdef __myDEBUG
-// if ( _curvature )
-// cout << _nodes[0]->GetID()
-// << " CURV r,k: " << _curvature->_r<<","<<_curvature->_k
-// << " proj = "<<avgNormProj<< " len = " << avgLen << "| lenDelta(0) = "
-// << _curvature->lenDelta(0) << endl;
-#endif
+ // if ( _curvature )
+ // debugMsg( _nodes[0]->GetID()
+ // << " CURV r,k: " << _curvature->_r<<","<<_curvature->_k
+ // << " proj = "<<avgNormProj<< " len = " << avgLen << "| lenDelta(0) = "
+ // << _curvature->lenDelta(0) );
// Set _plnNorm
if ( _sWOL.IsNull() )
{
TopoDS_Shape S = helper.GetSubShapeByNode( _nodes[0], helper.GetMeshDS() );
- gp_XYZ dirE = getEdgeDir( TopoDS::Edge( S ), _nodes[0], helper );
+ TopoDS_Edge E = TopoDS::Edge( S );
+ // if ( SMESH_Algo::isDegenerated( E ))
+ // return;
+ gp_XYZ dirE = getEdgeDir( E, _nodes[0], helper );
gp_XYZ plnNorm = dirE ^ _normal;
- double proj0 = plnNorm * vec1;
- double proj1 = plnNorm * vec2;
+ double proj0 = plnNorm * vec1;
+ double proj1 = plnNorm * vec2;
if ( fabs( proj0 ) > 1e-10 || fabs( proj1 ) > 1e-10 )
{
if ( _2neibors->_plnNorm ) delete _2neibors->_plnNorm;
for ( size_t i = 0 ; i < _sdVec.size(); ++i )
{
if ( _sdVec[i]._edges.empty() ) continue;
-// string name = SMESH_Comment("_LayerEdge's_") << i;
-// int id;
-// SMESH_Group* g = _mesh->AddGroup(SMDSAbs_Edge, name.c_str(), id );
-// SMESHDS_Group* gDS = (SMESHDS_Group*)g->GetGroupDS();
-// SMESHDS_Mesh* mDS = _mesh->GetMeshDS();
dumpFunction( SMESH_Comment("make_LayerEdge_") << i );
for ( size_t j = 0 ; j < _sdVec[i]._edges.size(); ++j )
for ( size_t iN = 1; iN < le->_nodes.size(); ++iN )
dumpCmd(SMESH_Comment("mesh.AddEdge([ ") <<le->_nodes[iN-1]->GetID()
<< ", " << le->_nodes[iN]->GetID() <<"])");
- //gDS->SMDSGroup().Add( mDS->AddEdge( le->_nodes[iN-1], le->_nodes[iN]));
}
dumpFunctionEnd();
}
dumpFunctionEnd();
-// name = SMESH_Comment("tmp_faces ") << i;
-// g = _mesh->AddGroup(SMDSAbs_Face, name.c_str(), id );
-// gDS = (SMESHDS_Group*)g->GetGroupDS();
-// SMESH_MeshEditor editor( _mesh );
dumpFunction( SMESH_Comment("makeTmpFaces_") << i );
TopExp_Explorer fExp( _sdVec[i]._solid, TopAbs_FACE );
for ( ; fExp.More(); fExp.Next() )
for ( int j=0; j < e->NbCornerNodes(); ++j )
cmd << e->GetNode(j)->GetID() << (j+1<e->NbCornerNodes() ? ",": "])");
dumpCmd( cmd );
- //vector<const SMDS_MeshNode*> nodes( e->begin_nodes(), e->end_nodes() );
- //gDS->SMDSGroup().Add( editor.AddElement( nodes, e->GetType(), e->IsPoly()));
}
}
}
#endif
}
+//================================================================================
+/*!
+ * \brief Find maximal _LayerEdge length (layer thickness) limited by geometry
+ */
+//================================================================================
+
+void _ViscousBuilder::computeGeomSize( _SolidData& data )
+{
+ data._geomSize = Precision::Infinite();
+ double intersecDist;
+ auto_ptr<SMESH_ElementSearcher> searcher
+ ( SMESH_MeshAlgos::GetElementSearcher( *getMeshDS(),
+ data._proxyMesh->GetFaces( data._solid )) );
+
+ TNode2Edge::iterator n2e = data._n2eMap.begin(), n2eEnd = data._n2eMap.end();
+ for ( ; n2e != n2eEnd; ++n2e )
+ {
+ _LayerEdge* edge = n2e->second;
+ if ( edge->IsOnEdge() ) continue;
+ edge->FindIntersection( *searcher, intersecDist, data._epsilon );
+ if ( data._geomSize > intersecDist && intersecDist > 0 )
+ data._geomSize = intersecDist;
+ }
+}
+
//================================================================================
/*!
* \brief Increase length of _LayerEdge's to reach the required thickness of layers
// Limit inflation step size by geometry size found by itersecting
// normals of _LayerEdge's with mesh faces
- double geomSize = Precision::Infinite(), intersecDist;
- auto_ptr<SMESH_ElementSearcher> searcher
- ( SMESH_MeshAlgos::GetElementSearcher( *getMeshDS(),
- data._proxyMesh->GetFaces( data._solid )) );
- for ( size_t i = 0; i < data._edges.size(); ++i )
- {
- if ( data._edges[i]->IsOnEdge() ) continue;
- data._edges[i]->FindIntersection( *searcher, intersecDist, data._epsilon );
- if ( geomSize > intersecDist && intersecDist > 0 )
- geomSize = intersecDist;
- }
- if ( data._stepSize > 0.3 * geomSize )
- limitStepSize( data, 0.3 * geomSize );
+ if ( data._stepSize > 0.3 * data._geomSize )
+ limitStepSize( data, 0.3 * data._geomSize );
- const double tgtThick = data._hyp->GetTotalThickness();
- if ( data._stepSize > tgtThick )
- limitStepSize( data, tgtThick );
+ const double tgtThick = data._maxThickness;
+ if ( data._stepSize > data._minThickness )
+ limitStepSize( data, data._minThickness );
if ( data._stepSize < 1. )
data._epsilon = data._stepSize * 1e-7;
-#ifdef __myDEBUG
- cout << "-- geomSize = " << geomSize << ", stepSize = " << data._stepSize << endl;
-#endif
+ debugMsg( "-- geomSize = " << data._geomSize << ", stepSize = " << data._stepSize );
double avgThick = 0, curThick = 0, distToIntersection = Precision::Infinite();
int nbSteps = 0, nbRepeats = 0;
- while ( 1.01 * avgThick < tgtThick )
+ int iBeg, iEnd, iS;
+ while ( avgThick < 0.99 )
{
// new target length
curThick += data._stepSize;
if ( curThick > tgtThick )
{
- curThick = tgtThick + ( tgtThick-avgThick ) * nbRepeats;
+ curThick = tgtThick + tgtThick*( 1.-avgThick ) * nbRepeats;
nbRepeats++;
}
// Elongate _LayerEdge's
dumpFunction(SMESH_Comment("inflate")<<data._index<<"_step"<<nbSteps); // debug
- for ( size_t i = 0; i < data._edges.size(); ++i )
+ for ( iBeg = 0, iS = 0; iS < data._endEdgeOnShape.size(); ++iS )
{
- data._edges[i]->SetNewLength( curThick, helper );
+ const double shapeCurThick = Min( curThick, data._hypOnShape[ iS ].GetTotalThickness() );
+ for ( iEnd = data._endEdgeOnShape[ iS ]; iBeg < iEnd; ++iBeg )
+ {
+ data._edges[iBeg]->SetNewLength( shapeCurThick, helper );
+ }
}
dumpFunctionEnd();
- if ( !nbSteps )
- if ( !updateNormals( data, helper ) )
- return false;
+ if ( !updateNormals( data, helper, nbSteps ))
+ return false;
// Improve and check quality
if ( !smoothAndCheck( data, nbSteps, distToIntersection ))
// Evaluate achieved thickness
avgThick = 0;
- for ( size_t i = 0; i < data._edges.size(); ++i )
- avgThick += data._edges[i]->_len;
+ for ( iBeg = 0, iS = 0; iS < data._endEdgeOnShape.size(); ++iS )
+ {
+ const double shapeTgtThick = data._hypOnShape[ iS ].GetTotalThickness();
+ for ( iEnd = data._endEdgeOnShape[ iS ]; iBeg < iEnd; ++iBeg )
+ {
+ avgThick += Min( 1., data._edges[iBeg]->_len / shapeTgtThick );
+ }
+ }
avgThick /= data._edges.size();
-#ifdef __myDEBUG
- cout << "-- Thickness " << avgThick << " reached" << endl;
-#endif
+ debugMsg( "-- Thickness " << curThick << " ("<< avgThick*100 << "%) reached" );
- if ( distToIntersection < avgThick*1.5 )
+ if ( distToIntersection < tgtThick*avgThick*1.5 )
{
-#ifdef __myDEBUG
- cout << "-- Stop inflation since distToIntersection( "<<distToIntersection<<" ) < avgThick( "
- << avgThick << " ) * 1.5" << endl;
-#endif
+ debugMsg( "-- Stop inflation since "
+ << " distToIntersection( "<<distToIntersection<<" ) < avgThick( "
+ << tgtThick*avgThick << " ) * 1.5" );
break;
}
// new step size
if ( data._stepSizeNodes[0] )
data._stepSize = data._stepSizeCoeff *
SMESH_TNodeXYZ(data._stepSizeNodes[0]).Distance(data._stepSizeNodes[1]);
- }
+
+ } // while ( avgThick < 0.99 )
if (nbSteps == 0 )
return error("failed at the very first inflation step", data._index);
+ if ( avgThick < 0.99 )
+ if ( SMESH_subMesh* sm = _mesh->GetSubMeshContaining( data._index ))
+ {
+ SMESH_ComputeErrorPtr& smError = sm->GetComputeError();
+ if ( !smError || smError->IsOK() )
+ smError.reset
+ ( new SMESH_ComputeError (COMPERR_WARNING,
+ SMESH_Comment("Thickness ") << tgtThick <<
+ " of viscous layers not reached,"
+ " average reached thickness is " << avgThick*tgtThick));
+ }
+
+
+ // Restore position of src nodes moved by infaltion on _noShrinkShapes
+ dumpFunction(SMESH_Comment("restoNoShrink_So")<<data._index); // debug
+ for ( iEnd = iS = 0; iS < data._endEdgeOnShape.size(); ++iS )
+ {
+ iBeg = iEnd;
+ iEnd = data._endEdgeOnShape[ iS ];
+ if ( data._edges[ iBeg ]->_nodes.size() == 1 )
+ for ( ; iBeg < iEnd; ++iBeg )
+ {
+ restoreNoShrink( *data._edges[ iBeg ] );
+ }
+ }
+ dumpFunctionEnd();
+
return true;
}
const int nbSteps,
double & distToIntersection)
{
- if ( data._endEdgeToSmooth.empty() )
+ if ( data._nbShapesToSmooth == 0 )
return true; // no shapes needing smoothing
bool moved, improved;
TopoDS_Face F;
int iBeg, iEnd = 0;
- for ( size_t iS = 0; iS < data._endEdgeToSmooth.size(); ++iS )
+ for ( int iS = 0; iS < data._nbShapesToSmooth; ++iS )
{
iBeg = iEnd;
- iEnd = data._endEdgeToSmooth[ iS ];
+ iEnd = data._endEdgeOnShape[ iS ];
+
+ // bool toSmooth = false;
+ // for ( int i = iBeg; i < iEnd; ++i )
+ // toSmooth = data._edges[ iBeg ]->NbSteps() >= nbSteps+1;
+ // if ( !toSmooth )
+ // {
+ // if ( iS+1 == data._nbShapesToSmooth )
+ // data._nbShapesToSmooth--;
+ // continue; // target length reached some steps before
+ // }
if ( !data._edges[ iBeg ]->_sWOL.IsNull() &&
data._edges[ iBeg ]->_sWOL.ShapeType() == TopAbs_FACE )
dumpCmd( SMESH_Comment("# end step ")<<step);
}
while ( moved && step++ < 5 );
- //cout << " NB STEPS: " << step << endl;
}
dumpFunctionEnd();
}
int oldBadNb = badNb;
badNb = 0;
moved = false;
- for ( int i = iBeg; i < iEnd; ++i )
- moved |= data._edges[i]->Smooth(badNb);
+ if ( step % 2 )
+ for ( int i = iBeg; i < iEnd; ++i ) // iterate forward
+ moved |= data._edges[i]->Smooth(badNb);
+ else
+ for ( int i = iEnd-1; i >= iBeg; --i ) // iterate backward
+ moved |= data._edges[i]->Smooth(badNb);
improved = ( badNb < oldBadNb );
- // issue 22576. no bad faces but still there are intersections to fix
+ // issue 22576 -- no bad faces but still there are intersections to fix
if ( improved && badNb == 0 )
stepLimit = step + 3;
}
} // loop on shapes to smooth
- // Check orientation of simplices of _simplexTestEdges
- for ( size_t i = 0; i < data._simplexTestEdges.size(); ++i )
+ // Check orientation of simplices of _ConvexFace::_simplexTestEdges
+ map< TGeomID, _ConvexFace >::iterator id2face = data._convexFaces.begin();
+ for ( ; id2face != data._convexFaces.end(); ++id2face )
{
- const _LayerEdge* edge = data._simplexTestEdges[i];
- SMESH_TNodeXYZ tgtXYZ( edge->_nodes.back() );
- for ( size_t j = 0; j < edge->_simplices.size(); ++j )
- if ( !edge->_simplices[j].IsForward( edge->_nodes[0], &tgtXYZ ))
- {
-#ifdef __myDEBUG
- cout << "Bad simplex of _simplexTestEdges ("
- << " "<< edge->_nodes[0]->GetID()<< " "<< tgtXYZ._node->GetID()
- << " "<< edge->_simplices[j]._nPrev->GetID()
- << " "<< edge->_simplices[j]._nNext->GetID() << " )" << endl;
-#endif
- return false;
- }
+ _ConvexFace & convFace = (*id2face).second;
+ if ( !convFace._simplexTestEdges.empty() &&
+ convFace._simplexTestEdges[0]->_nodes[0]->GetPosition()->GetDim() == 2 )
+ continue; // _simplexTestEdges are based on FACE -- already checked while smoothing
+
+ if ( !convFace.CheckPrisms() )
+ return false;
}
// Check if the last segments of _LayerEdge intersects 2D elements;
distToIntersection = Precision::Infinite();
double dist;
const SMDS_MeshElement* intFace = 0;
-#ifdef __myDEBUG
const SMDS_MeshElement* closestFace = 0;
int iLE = 0;
-#endif
for ( size_t i = 0; i < data._edges.size(); ++i )
{
+ if ( !data._edges[i]->_sWOL.IsNull() )
+ continue;
if ( data._edges[i]->FindIntersection( *searcher, dist, data._epsilon, &intFace ))
return false;
if ( distToIntersection > dist )
{
+ // ignore intersection of a _LayerEdge based on a _ConvexFace with a face
+ // lying on this _ConvexFace
+ if ( _ConvexFace* convFace = data.GetConvexFace( intFace->getshapeId() ))
+ if ( convFace->_subIdToEdgeEnd.count ( data._edges[i]->_nodes[0]->getshapeId() ))
+ continue;
+
distToIntersection = dist;
-#ifdef __myDEBUG
iLE = i;
closestFace = intFace;
-#endif
}
}
#ifdef __myDEBUG
if ( i2curve == _edge2curve.end() )
{
// sort _LayerEdge's by position on the EDGE
- {
- map< double, _LayerEdge* > u2edge;
- for ( int i = iFrom; i < iTo; ++i )
- u2edge.insert( make_pair( helper.GetNodeU( E, _edges[i]->_nodes[0] ), _edges[i] ));
-
- ASSERT( u2edge.size() == iTo - iFrom );
- map< double, _LayerEdge* >::iterator u2e = u2edge.begin();
- for ( int i = iFrom; i < iTo; ++i, ++u2e )
- _edges[i] = u2e->second;
-
- // set _2neibors according to the new order
- for ( int i = iFrom; i < iTo-1; ++i )
- if ( _edges[i]->_2neibors->_nodes[1] != _edges[i+1]->_nodes.back() )
- _edges[i]->_2neibors->reverse();
- if ( u2edge.size() > 1 &&
- _edges[iTo-1]->_2neibors->_nodes[0] != _edges[iTo-2]->_nodes.back() )
- _edges[iTo-1]->_2neibors->reverse();
- }
+ SortOnEdge( E, iFrom, iTo, helper );
SMESHDS_SubMesh* smDS = helper.GetMeshDS()->MeshElements( eIndex );
bndBox.Add( SMESH_TNodeXYZ( nIt->next() ));
gp_XYZ size = bndBox.CornerMax() - bndBox.CornerMin();
- SMESH_TNodeXYZ p0( _edges[iFrom]->_2neibors->_nodes[0] );
- SMESH_TNodeXYZ p1( _edges[iFrom]->_2neibors->_nodes[1] );
+ SMESH_TNodeXYZ p0( _edges[iFrom]->_2neibors->tgtNode(0) );
+ SMESH_TNodeXYZ p1( _edges[iFrom]->_2neibors->tgtNode(1) );
const double lineTol = 1e-2 * ( p0 - p1 ).Modulus();
for ( int i = 0; i < 3 && !isLine; ++i )
isLine = ( size.Coord( i+1 ) <= lineTol );
return i2curve->second;
}
+//================================================================================
+/*!
+ * \brief Sort _LayerEdge's by a parameter on a given EDGE
+ */
+//================================================================================
+
+void _SolidData::SortOnEdge( const TopoDS_Edge& E,
+ const int iFrom,
+ const int iTo,
+ SMESH_MesherHelper& helper)
+{
+ map< double, _LayerEdge* > u2edge;
+ for ( int i = iFrom; i < iTo; ++i )
+ u2edge.insert( make_pair( helper.GetNodeU( E, _edges[i]->_nodes[0] ), _edges[i] ));
+
+ ASSERT( u2edge.size() == iTo - iFrom );
+ map< double, _LayerEdge* >::iterator u2e = u2edge.begin();
+ for ( int i = iFrom; i < iTo; ++i, ++u2e )
+ _edges[i] = u2e->second;
+
+ // set _2neibors according to the new order
+ for ( int i = iFrom; i < iTo-1; ++i )
+ if ( _edges[i]->_2neibors->tgtNode(1) != _edges[i+1]->_nodes.back() )
+ _edges[i]->_2neibors->reverse();
+ if ( u2edge.size() > 1 &&
+ _edges[iTo-1]->_2neibors->tgtNode(0) != _edges[iTo-2]->_nodes.back() )
+ _edges[iTo-1]->_2neibors->reverse();
+}
+
+//================================================================================
+/*!
+ * \brief Return index corresponding to the shape in _endEdgeOnShape
+ */
+//================================================================================
+
+bool _SolidData::GetShapeEdges(const TGeomID shapeID,
+ size_t & iEdgesEnd,
+ int* iBeg,
+ int* iEnd ) const
+{
+ int beg = 0, end = 0;
+ for ( iEdgesEnd = 0; iEdgesEnd < _endEdgeOnShape.size(); ++iEdgesEnd )
+ {
+ end = _endEdgeOnShape[ iEdgesEnd ];
+ TGeomID sID = _edges[ beg ]->_nodes[0]->getshapeId();
+ if ( sID == shapeID )
+ {
+ if ( iBeg ) *iBeg = beg;
+ if ( iEnd ) *iEnd = end;
+ return true;
+ }
+ beg = end;
+ }
+ return false;
+}
+
+//================================================================================
+/*!
+ * \brief Add faces for smoothing
+ */
+//================================================================================
+
+void _SolidData::AddShapesToSmooth( const set< TGeomID >& faceIDs )
+{
+ // convert faceIDs to indices in _endEdgeOnShape
+ set< size_t > iEnds;
+ size_t end;
+ set< TGeomID >::const_iterator fId = faceIDs.begin();
+ for ( ; fId != faceIDs.end(); ++fId )
+ if ( GetShapeEdges( *fId, end ) && end >= _nbShapesToSmooth )
+ iEnds.insert( end );
+
+ set< size_t >::iterator endsIt = iEnds.begin();
+
+ // "add" by move of _nbShapesToSmooth
+ int nbFacesToAdd = iEnds.size();
+ while ( endsIt != iEnds.end() && *endsIt == _nbShapesToSmooth )
+ {
+ ++endsIt;
+ ++_nbShapesToSmooth;
+ --nbFacesToAdd;
+ }
+ if ( endsIt == iEnds.end() )
+ return;
+
+ // Move _LayerEdge's on FACEs just after _nbShapesToSmooth
+
+ vector< _LayerEdge* > nonSmoothLE, smoothLE;
+ size_t lastSmooth = *iEnds.rbegin();
+ int iBeg, iEnd;
+ for ( size_t i = _nbShapesToSmooth; i <= lastSmooth; ++i )
+ {
+ vector< _LayerEdge* > & edgesVec = iEnds.count(i) ? smoothLE : nonSmoothLE;
+ iBeg = i ? _endEdgeOnShape[ i-1 ] : 0;
+ iEnd = _endEdgeOnShape[ i ];
+ edgesVec.insert( edgesVec.end(), _edges.begin() + iBeg, _edges.begin() + iEnd );
+ }
+
+ iBeg = _nbShapesToSmooth ? _endEdgeOnShape[ _nbShapesToSmooth-1 ] : 0;
+ std::copy( smoothLE.begin(), smoothLE.end(), &_edges[ iBeg ] );
+ std::copy( nonSmoothLE.begin(), nonSmoothLE.end(), &_edges[ iBeg + smoothLE.size()]);
+
+ // update _endEdgeOnShape
+ for ( size_t i = _nbShapesToSmooth; i < _endEdgeOnShape.size(); ++i )
+ {
+ TGeomID curShape = _edges[ iBeg ]->_nodes[0]->getshapeId();
+ while ( ++iBeg < _edges.size() &&
+ curShape == _edges[ iBeg ]->_nodes[0]->getshapeId() );
+
+ _endEdgeOnShape[ i ] = iBeg;
+ }
+
+ _nbShapesToSmooth += nbFacesToAdd;
+}
+
//================================================================================
/*!
* \brief smooth _LayerEdge's on a staight EDGE or circular EDGE
{
if ( F.IsNull() ) // 3D
{
- SMESH_TNodeXYZ p0( data._edges[iFrom]->_2neibors->_nodes[0]);
- SMESH_TNodeXYZ p1( data._edges[iTo-1]->_2neibors->_nodes[1]);
+ SMESH_TNodeXYZ p0( data._edges[iFrom]->_2neibors->tgtNode(0));
+ SMESH_TNodeXYZ p1( data._edges[iTo-1]->_2neibors->tgtNode(1));
for ( int i = iFrom; i < iTo; ++i )
{
double r = len[i-iFrom] / len.back();
}
else
{
- gp_XY uv0 = helper.GetNodeUV( F, data._edges[iFrom]->_2neibors->_nodes[0]);
- gp_XY uv1 = helper.GetNodeUV( F, data._edges[iTo-1]->_2neibors->_nodes[1]);
- if ( data._edges[iFrom]->_2neibors->_nodes[0] ==
- data._edges[iTo-1]->_2neibors->_nodes[1] ) // closed edge
+ // gp_XY uv0 = helper.GetNodeUV( F, data._edges[iFrom]->_2neibors->tgtNode(0));
+ // gp_XY uv1 = helper.GetNodeUV( F, data._edges[iTo-1]->_2neibors->tgtNode(1));
+ gp_XY uv0 = data._edges[iFrom]->_2neibors->_edges[0]->LastUV( F );
+ gp_XY uv1 = data._edges[iTo-1]->_2neibors->_edges[1]->LastUV( F );
+ if ( data._edges[iFrom]->_2neibors->tgtNode(0) ==
+ data._edges[iTo-1]->_2neibors->tgtNode(1) ) // closed edge
{
int iPeriodic = helper.GetPeriodicIndex();
if ( iPeriodic == 1 || iPeriodic == 2 )
if ( F.IsNull() ) // 3D
{
- if ( data._edges[iFrom]->_2neibors->_nodes[0] ==
- data._edges[iTo-1]->_2neibors->_nodes[1] )
+ if ( data._edges[iFrom]->_2neibors->tgtNode(0) ==
+ data._edges[iTo-1]->_2neibors->tgtNode(1) )
return true; // closed EDGE - nothing to do
return false; // TODO ???
{
const gp_XY center( center3D.X(), center3D.Y() );
- gp_XY uv0 = helper.GetNodeUV( F, data._edges[iFrom]->_2neibors->_nodes[0]);
- gp_XY uvM = helper.GetNodeUV( F, data._edges[iFrom]->_nodes.back());
- gp_XY uv1 = helper.GetNodeUV( F, data._edges[iTo-1]->_2neibors->_nodes[1]);
+ gp_XY uv0 = data._edges[iFrom]->_2neibors->_edges[0]->LastUV( F );
+ gp_XY uvM = data._edges[iFrom]->LastUV( F );
+ gp_XY uv1 = data._edges[iTo-1]->_2neibors->_edges[1]->LastUV( F );
+ // gp_XY uv0 = helper.GetNodeUV( F, data._edges[iFrom]->_2neibors->tgtNode(0));
+ // gp_XY uvM = helper.GetNodeUV( F, data._edges[iFrom]->_nodes.back());
+ // gp_XY uv1 = helper.GetNodeUV( F, data._edges[iTo-1]->_2neibors->tgtNode(1));
gp_Vec2d vec0( center, uv0 );
gp_Vec2d vecM( center, uvM );
gp_Vec2d vec1( center, uv1 );
//================================================================================
bool _ViscousBuilder::updateNormals( _SolidData& data,
- SMESH_MesherHelper& helper )
+ SMESH_MesherHelper& helper,
+ int stepNb )
{
+ if ( stepNb > 0 )
+ return updateNormalsOfConvexFaces( data, helper, stepNb );
+
// make temporary quadrangles got by extrusion of
// mesh edges along _LayerEdge._normal's
const SMDS_MeshNode* tgt1 = edge->_nodes.back();
for ( int j = 0; j < 2; ++j ) // loop on _2NearEdges
{
- const SMDS_MeshNode* tgt2 = edge->_2neibors->_nodes[j];
+ const SMDS_MeshNode* tgt2 = edge->_2neibors->tgtNode(j);
pair< set< SMESH_TLink >::iterator, bool > link_isnew =
extrudedLinks.insert( SMESH_TLink( tgt1, tgt2 ));
if ( !link_isnew.second )
extrudedLinks.erase( link_isnew.first );
continue; // already extruded and will no more encounter
}
- // look for a _LayerEdge containg tgt2
-// _LayerEdge* neiborEdge = 0;
-// size_t di = 0; // check _edges[i+di] and _edges[i-di]
-// while ( !neiborEdge && ++di <= data._edges.size() )
-// {
-// if ( i+di < data._edges.size() && data._edges[i+di]->_nodes.back() == tgt2 )
-// neiborEdge = data._edges[i+di];
-// else if ( di <= i && data._edges[i-di]->_nodes.back() == tgt2 )
-// neiborEdge = data._edges[i-di];
-// }
-// if ( !neiborEdge )
-// return error("updateNormals(): neighbor _LayerEdge not found", data._index);
+ // a _LayerEdge containg tgt2
_LayerEdge* neiborEdge = edge->_2neibors->_edges[j];
- TmpMeshFaceOnEdge* f = new TmpMeshFaceOnEdge( edge, neiborEdge, --_tmpFaceID );
+ _TmpMeshFaceOnEdge* f = new _TmpMeshFaceOnEdge( edge, neiborEdge, --_tmpFaceID );
tmpFaces.push_back( f );
dumpCmd(SMESH_Comment("mesh.AddFace([ ")
for ( size_t i = 0; i < data._edges.size(); ++i )
{
_LayerEdge* edge = data._edges[i];
- if ( !edge->IsOnEdge() || !edge->_sWOL.IsNull() ) continue;
+ if (( !edge->IsOnEdge() ) &&
+ ( edge->_sWOL.IsNull() || edge->_sWOL.ShapeType() != TopAbs_FACE ))
+ continue;
if ( edge->FindIntersection( *searcher, dist, eps, &face ))
{
- const TmpMeshFaceOnEdge* f = (const TmpMeshFaceOnEdge*) face;
+ const _TmpMeshFaceOnEdge* f = (const _TmpMeshFaceOnEdge*) face;
set< _LayerEdge*, _LayerEdgeCmp > & ee = edge2CloseEdge[ edge ];
ee.insert( f->_le1 );
ee.insert( f->_le2 );
{
dumpFunction(SMESH_Comment("updateNormals")<<data._index);
+ set< TGeomID > shapesToSmooth;
+
+ // vector to store new _normal and _cosin for each edge in edge2CloseEdge
+ vector< pair< _LayerEdge*, _LayerEdge > > edge2newEdge( edge2CloseEdge.size() );
+
TLEdge2LEdgeSet::iterator e2ee = edge2CloseEdge.begin();
- for ( ; e2ee != edge2CloseEdge.end(); ++e2ee )
+ for ( size_t iE = 0; e2ee != edge2CloseEdge.end(); ++e2ee, ++iE )
+ {
+ _LayerEdge* edge1 = e2ee->first;
+ _LayerEdge* edge2 = 0;
+ set< _LayerEdge*, _LayerEdgeCmp >& ee = e2ee->second;
+
+ edge2newEdge[ iE ].first = NULL;
+
+ // find EDGEs the edges reside
+ // TopoDS_Edge E1, E2;
+ // TopoDS_Shape S = helper.GetSubShapeByNode( edge1->_nodes[0], getMeshDS() );
+ // if ( S.ShapeType() != TopAbs_EDGE )
+ // continue; // TODO: find EDGE by VERTEX
+ // E1 = TopoDS::Edge( S );
+ set< _LayerEdge*, _LayerEdgeCmp >::iterator eIt = ee.begin();
+ for ( ; !edge2 && eIt != ee.end(); ++eIt )
+ {
+ if ( edge1->_sWOL == (*eIt)->_sWOL )
+ edge2 = *eIt;
+ }
+ if ( !edge2 ) continue;
+
+ edge2newEdge[ iE ].first = edge1;
+ _LayerEdge& newEdge = edge2newEdge[ iE ].second;
+ // while ( E2.IsNull() && eIt != ee.end())
+ // {
+ // _LayerEdge* e2 = *eIt++;
+ // TopoDS_Shape S = helper.GetSubShapeByNode( e2->_nodes[0], getMeshDS() );
+ // if ( S.ShapeType() == TopAbs_EDGE )
+ // E2 = TopoDS::Edge( S ), edge2 = e2;
+ // }
+ // if ( E2.IsNull() ) continue; // TODO: find EDGE by VERTEX
+
+ // find 3 FACEs sharing 2 EDGEs
+
+ // TopoDS_Face FF1[2], FF2[2];
+ // PShapeIteratorPtr fIt = helper.GetAncestors(E1, *_mesh, TopAbs_FACE);
+ // while ( fIt->more() && FF1[1].IsNull() )
+ // {
+ // const TopoDS_Face *F = (const TopoDS_Face*) fIt->next();
+ // if ( helper.IsSubShape( *F, data._solid))
+ // FF1[ FF1[0].IsNull() ? 0 : 1 ] = *F;
+ // }
+ // fIt = helper.GetAncestors(E2, *_mesh, TopAbs_FACE);
+ // while ( fIt->more() && FF2[1].IsNull())
+ // {
+ // const TopoDS_Face *F = (const TopoDS_Face*) fIt->next();
+ // if ( helper.IsSubShape( *F, data._solid))
+ // FF2[ FF2[0].IsNull() ? 0 : 1 ] = *F;
+ // }
+ // // exclude a FACE common to E1 and E2 (put it to FFn[1] )
+ // if ( FF1[0].IsSame( FF2[0]) || FF1[0].IsSame( FF2[1]))
+ // std::swap( FF1[0], FF1[1] );
+ // if ( FF2[0].IsSame( FF1[0]) )
+ // std::swap( FF2[0], FF2[1] );
+ // if ( FF1[0].IsNull() || FF2[0].IsNull() )
+ // continue;
+
+ // get a new normal for edge1
+ //bool ok;
+ gp_Vec dir1 = edge1->_normal, dir2 = edge2->_normal;
+ // if ( edge1->_cosin < 0 )
+ // dir1 = getFaceDir( FF1[0], E1, edge1->_nodes[0], helper, ok ).Normalized();
+ // if ( edge2->_cosin < 0 )
+ // dir2 = getFaceDir( FF2[0], E2, edge2->_nodes[0], helper, ok ).Normalized();
+
+ double cos1 = Abs( edge1->_cosin ), cos2 = Abs( edge2->_cosin );
+ double wgt1 = ( cos1 + 0.001 ) / ( cos1 + cos2 + 0.002 );
+ double wgt2 = ( cos2 + 0.001 ) / ( cos1 + cos2 + 0.002 );
+ newEdge._normal = ( wgt1 * dir1 + wgt2 * dir2 ).XYZ();
+ newEdge._normal.Normalize();
+
+ // cout << edge1->_nodes[0]->GetID() << " "
+ // << edge2->_nodes[0]->GetID() << " NORM: "
+ // << newEdge._normal.X() << ", " << newEdge._normal.Y() << ", " << newEdge._normal.Z() << endl;
+
+ // get new cosin
+ if ( cos1 < theMinSmoothCosin )
+ {
+ newEdge._cosin = edge2->_cosin;
+ }
+ else if ( cos2 > theMinSmoothCosin ) // both cos1 and cos2 > theMinSmoothCosin
+ {
+ // gp_Vec dirInFace;
+ // if ( edge1->_cosin < 0 )
+ // dirInFace = dir1;
+ // else
+ // dirInFace = getFaceDir( FF1[0], E1, edge1->_nodes[0], helper, ok );
+ // double angle = dirInFace.Angle( edge1->_normal ); // [0,PI]
+ // edge1->SetCosin( Cos( angle ));
+ //newEdge._cosin = 0; // ???????????
+ newEdge._cosin = ( wgt1 * cos1 + wgt2 * cos2 ) * edge1->_cosin / cos1;
+ }
+ else
+ {
+ newEdge._cosin = edge1->_cosin;
+ }
+
+ // find shapes that need smoothing due to change of _normal
+ if ( edge1->_cosin < theMinSmoothCosin &&
+ newEdge._cosin > theMinSmoothCosin )
+ {
+ if ( edge1->_sWOL.IsNull() )
+ {
+ SMDS_ElemIteratorPtr fIt = edge1->_nodes[0]->GetInverseElementIterator(SMDSAbs_Face);
+ while ( fIt->more() )
+ shapesToSmooth.insert( fIt->next()->getshapeId() );
+ //limitStepSize( data, fIt->next(), edge1->_cosin ); // too late
+ }
+ else // edge1 inflates along a FACE
+ {
+ TopoDS_Shape V = helper.GetSubShapeByNode( edge1->_nodes[0], getMeshDS() );
+ PShapeIteratorPtr eIt = helper.GetAncestors( V, *_mesh, TopAbs_EDGE );
+ while ( const TopoDS_Shape* E = eIt->next() )
+ {
+ if ( !helper.IsSubShape( *E, /*FACE=*/edge1->_sWOL ))
+ continue;
+ gp_Vec edgeDir = getEdgeDir( TopoDS::Edge( *E ), TopoDS::Vertex( V ));
+ double angle = edgeDir.Angle( newEdge._normal ); // [0,PI]
+ if ( angle < M_PI / 2 )
+ shapesToSmooth.insert( getMeshDS()->ShapeToIndex( *E ));
+ }
+ }
+ }
+ }
+
+ data.AddShapesToSmooth( shapesToSmooth );
+
+ // Update data of edges depending on a new _normal
+
+ for ( size_t iE = 0; iE < edge2newEdge.size(); ++iE )
+ {
+ _LayerEdge* edge1 = edge2newEdge[ iE ].first;
+ _LayerEdge& newEdge = edge2newEdge[ iE ].second;
+ if ( !edge1 ) continue;
+
+ edge1->_normal = newEdge._normal;
+ edge1->SetCosin( newEdge._cosin );
+ edge1->InvalidateStep( 1 );
+ edge1->_len = 0;
+ edge1->SetNewLength( data._stepSize, helper );
+ if ( edge1->IsOnEdge() )
+ {
+ const SMDS_MeshNode * n1 = edge1->_2neibors->srcNode(0);
+ const SMDS_MeshNode * n2 = edge1->_2neibors->srcNode(1);
+ edge1->SetDataByNeighbors( n1, n2, helper );
+ }
+
+ // Update normals and other dependent data of not intersecting _LayerEdge's
+ // neighboring the intersecting ones
+
+ if ( !edge1->_2neibors )
+ continue;
+ for ( int j = 0; j < 2; ++j ) // loop on 2 neighbors
+ {
+ _LayerEdge* neighbor = edge1->_2neibors->_edges[j];
+ if ( edge2CloseEdge.count ( neighbor ))
+ continue; // j-th neighbor is also intersected
+ _LayerEdge* prevEdge = edge1;
+ const int nbSteps = 10;
+ for ( int step = nbSteps; step; --step ) // step from edge1 in j-th direction
+ {
+ if ( !neighbor->_2neibors )
+ break; // neighbor is on VERTEX
+ int iNext = 0;
+ _LayerEdge* nextEdge = neighbor->_2neibors->_edges[iNext];
+ if ( nextEdge == prevEdge )
+ nextEdge = neighbor->_2neibors->_edges[ ++iNext ];
+ double r = double(step-1)/nbSteps;
+ if ( !nextEdge->_2neibors )
+ r = 0.5;
+
+ gp_XYZ newNorm = prevEdge->_normal * r + nextEdge->_normal * (1-r);
+ newNorm.Normalize();
+
+ neighbor->_normal = newNorm;
+ neighbor->SetCosin( prevEdge->_cosin * r + nextEdge->_cosin * (1-r) );
+ neighbor->SetDataByNeighbors( prevEdge->_nodes[0], nextEdge->_nodes[0], helper );
+
+ neighbor->InvalidateStep( 1 );
+ neighbor->_len = 0;
+ neighbor->SetNewLength( data._stepSize, helper );
+
+ // goto the next neighbor
+ prevEdge = neighbor;
+ neighbor = nextEdge;
+ }
+ }
+ }
+ dumpFunctionEnd();
+ }
+ // 2) Check absence of intersections
+ // TODO?
+
+ for ( size_t i = 0 ; i < tmpFaces.size(); ++i )
+ delete tmpFaces[i];
+
+ return true;
+}
+
+//================================================================================
+/*!
+ * \brief Modify normals of _LayerEdge's on _ConvexFace's
+ */
+//================================================================================
+
+bool _ViscousBuilder::updateNormalsOfConvexFaces( _SolidData& data,
+ SMESH_MesherHelper& helper,
+ int stepNb )
+{
+ SMESHDS_Mesh* meshDS = helper.GetMeshDS();
+ bool isOK;
+
+ map< TGeomID, _ConvexFace >::iterator id2face = data._convexFaces.begin();
+ for ( ; id2face != data._convexFaces.end(); ++id2face )
+ {
+ _ConvexFace & convFace = (*id2face).second;
+ if ( convFace._normalsFixed )
+ continue; // already fixed
+ if ( convFace.CheckPrisms() )
+ continue; // nothing to fix
+
+ convFace._normalsFixed = true;
+
+ BRepAdaptor_Surface surface ( convFace._face, false );
+ BRepLProp_SLProps surfProp( surface, 2, 1e-6 );
+
+ // check if the convex FACE is of spherical shape
+
+ Bnd_B3d centersBox; // bbox of centers of curvature of _LayerEdge's on VERTEXes
+ Bnd_B3d nodesBox;
+ gp_Pnt center;
+ int iBeg, iEnd;
+
+ map< TGeomID, int >::iterator id2end = convFace._subIdToEdgeEnd.begin();
+ for ( ; id2end != convFace._subIdToEdgeEnd.end(); ++id2end )
+ {
+ data.GetEdgesOnShape( id2end->second, iBeg, iEnd );
+
+ if ( meshDS->IndexToShape( id2end->first ).ShapeType() == TopAbs_VERTEX )
+ {
+ _LayerEdge* ledge = data._edges[ iBeg ];
+ if ( convFace.GetCenterOfCurvature( ledge, surfProp, helper, center ))
+ centersBox.Add( center );
+ }
+ for ( ; iBeg < iEnd; ++iBeg )
+ nodesBox.Add( SMESH_TNodeXYZ( data._edges[ iBeg ]->_nodes[0] ));
+ }
+ if ( centersBox.IsVoid() )
{
- _LayerEdge* edge1 = e2ee->first;
- _LayerEdge* edge2 = 0;
- set< _LayerEdge*, _LayerEdgeCmp >& ee = e2ee->second;
+ debugMsg( "Error: centersBox.IsVoid()" );
+ return false;
+ }
+ const bool isSpherical =
+ ( centersBox.SquareExtent() < 1e-6 * nodesBox.SquareExtent() );
+
+ int nbEdges = helper.Count( convFace._face, TopAbs_EDGE, /*ignoreSame=*/false );
+ vector < _CentralCurveOnEdge > centerCurves( nbEdges );
+
+ if ( isSpherical )
+ {
+ // set _LayerEdge::_normal as average of all normals
+
+ // WARNING: different density of nodes on EDGEs is not taken into account that
+ // can lead to an improper new normal
+
+ gp_XYZ avgNormal( 0,0,0 );
+ nbEdges = 0;
+ id2end = convFace._subIdToEdgeEnd.begin();
+ for ( ; id2end != convFace._subIdToEdgeEnd.end(); ++id2end )
+ {
+ data.GetEdgesOnShape( id2end->second, iBeg, iEnd );
+ // set data of _CentralCurveOnEdge
+ const TopoDS_Shape& S = meshDS->IndexToShape( id2end->first );
+ if ( S.ShapeType() == TopAbs_EDGE )
+ {
+ _CentralCurveOnEdge& ceCurve = centerCurves[ nbEdges++ ];
+ ceCurve.SetShapes( TopoDS::Edge(S), convFace, data, helper );
+ if ( !data._edges[ iBeg ]->_sWOL.IsNull() )
+ ceCurve._adjFace.Nullify();
+ else
+ ceCurve._ledges.insert( ceCurve._ledges.end(),
+ &data._edges[ iBeg ], &data._edges[ iEnd ]);
+ }
+ // summarize normals
+ for ( ; iBeg < iEnd; ++iBeg )
+ avgNormal += data._edges[ iBeg ]->_normal;
+ }
+ double normSize = avgNormal.SquareModulus();
+ if ( normSize < 1e-200 )
+ {
+ debugMsg( "updateNormalsOfConvexFaces(): zero avgNormal" );
+ return false;
+ }
+ avgNormal /= Sqrt( normSize );
+
+ // compute new _LayerEdge::_cosin on EDGEs
+ double avgCosin = 0;
+ int nbCosin = 0;
+ gp_Vec inFaceDir;
+ for ( size_t iE = 0; iE < centerCurves.size(); ++iE )
+ {
+ _CentralCurveOnEdge& ceCurve = centerCurves[ iE ];
+ if ( ceCurve._adjFace.IsNull() )
+ continue;
+ for ( size_t iLE = 0; iLE < ceCurve._ledges.size(); ++iLE )
+ {
+ const SMDS_MeshNode* node = ceCurve._ledges[ iLE ]->_nodes[0];
+ inFaceDir = getFaceDir( ceCurve._adjFace, ceCurve._edge, node, helper, isOK );
+ if ( isOK )
+ {
+ double angle = inFaceDir.Angle( avgNormal ); // [0,PI]
+ ceCurve._ledges[ iLE ]->_cosin = Cos( angle );
+ avgCosin += ceCurve._ledges[ iLE ]->_cosin;
+ nbCosin++;
+ }
+ }
+ }
+ if ( nbCosin > 0 )
+ avgCosin /= nbCosin;
+
+ // set _LayerEdge::_normal = avgNormal
+ id2end = convFace._subIdToEdgeEnd.begin();
+ for ( ; id2end != convFace._subIdToEdgeEnd.end(); ++id2end )
+ {
+ data.GetEdgesOnShape( id2end->second, iBeg, iEnd );
+ const TopoDS_Shape& S = meshDS->IndexToShape( id2end->first );
+ if ( S.ShapeType() != TopAbs_EDGE )
+ for ( int i = iBeg; i < iEnd; ++i )
+ data._edges[ i ]->_cosin = avgCosin;
+
+ for ( ; iBeg < iEnd; ++iBeg )
+ data._edges[ iBeg ]->_normal = avgNormal;
+ }
+ }
+ else // if ( isSpherical )
+ {
+ // We suppose that centers of curvature at all points of the FACE
+ // lie on some curve, let's call it "central curve". For all _LayerEdge's
+ // having a common center of curvature we define the same new normal
+ // as a sum of normals of _LayerEdge's on EDGEs among them.
+
+ // get all centers of curvature for each EDGE
+
+ helper.SetSubShape( convFace._face );
+ _LayerEdge* vertexLEdges[2], **edgeLEdge, **edgeLEdgeEnd;
+
+ TopExp_Explorer edgeExp( convFace._face, TopAbs_EDGE );
+ for ( int iE = 0; edgeExp.More(); edgeExp.Next(), ++iE )
+ {
+ const TopoDS_Edge& edge = TopoDS::Edge( edgeExp.Current() );
+
+ // set adjacent FACE
+ centerCurves[ iE ].SetShapes( edge, convFace, data, helper );
+
+ // get _LayerEdge's of the EDGE
+ TGeomID edgeID = meshDS->ShapeToIndex( edge );
+ id2end = convFace._subIdToEdgeEnd.find( edgeID );
+ if ( id2end == convFace._subIdToEdgeEnd.end() )
+ {
+ // no _LayerEdge's on EDGE, use _LayerEdge's on VERTEXes
+ for ( int iV = 0; iV < 2; ++iV )
+ {
+ TopoDS_Vertex v = helper.IthVertex( iV, edge );
+ TGeomID vID = meshDS->ShapeToIndex( v );
+ int end = convFace._subIdToEdgeEnd[ vID ];
+ int iBeg = end > 0 ? data._endEdgeOnShape[ end-1 ] : 0;
+ vertexLEdges[ iV ] = data._edges[ iBeg ];
+ }
+ edgeLEdge = &vertexLEdges[0];
+ edgeLEdgeEnd = edgeLEdge + 2;
+
+ centerCurves[ iE ]._adjFace.Nullify();
+ }
+ else
+ {
+ data.GetEdgesOnShape( id2end->second, iBeg, iEnd );
+ if ( id2end->second >= data._nbShapesToSmooth )
+ data.SortOnEdge( edge, iBeg, iEnd, helper );
+ edgeLEdge = &data._edges[ iBeg ];
+ edgeLEdgeEnd = edgeLEdge + iEnd - iBeg;
+ vertexLEdges[0] = data._edges[ iBeg ]->_2neibors->_edges[0];
+ vertexLEdges[1] = data._edges[ iEnd-1 ]->_2neibors->_edges[1];
+
+ if ( ! data._edges[ iBeg ]->_sWOL.IsNull() )
+ centerCurves[ iE ]._adjFace.Nullify();
+ }
+
+ // Get curvature centers
+
+ centersBox.Clear();
+
+ if ( edgeLEdge[0]->IsOnEdge() &&
+ convFace.GetCenterOfCurvature( vertexLEdges[0], surfProp, helper, center ))
+ { // 1st VERTEX
+ centerCurves[ iE ].Append( center, vertexLEdges[0] );
+ centersBox.Add( center );
+ }
+ for ( ; edgeLEdge < edgeLEdgeEnd; ++edgeLEdge )
+ if ( convFace.GetCenterOfCurvature( *edgeLEdge, surfProp, helper, center ))
+ { // EDGE or VERTEXes
+ centerCurves[ iE ].Append( center, *edgeLEdge );
+ centersBox.Add( center );
+ }
+ if ( edgeLEdge[-1]->IsOnEdge() &&
+ convFace.GetCenterOfCurvature( vertexLEdges[1], surfProp, helper, center ))
+ { // 2nd VERTEX
+ centerCurves[ iE ].Append( center, vertexLEdges[1] );
+ centersBox.Add( center );
+ }
+ centerCurves[ iE ]._isDegenerated =
+ ( centersBox.IsVoid() || centersBox.SquareExtent() < 1e-6 * nodesBox.SquareExtent() );
+
+ } // loop on EDGES of convFace._face to set up data of centerCurves
+
+ // Compute new normals for _LayerEdge's on EDGEs
+
+ double avgCosin = 0;
+ int nbCosin = 0;
+ gp_Vec inFaceDir;
+ for ( size_t iE1 = 0; iE1 < centerCurves.size(); ++iE1 )
+ {
+ _CentralCurveOnEdge& ceCurve = centerCurves[ iE1 ];
+ if ( ceCurve._isDegenerated )
+ continue;
+ const vector< gp_Pnt >& centers = ceCurve._curvaCenters;
+ vector< gp_XYZ > & newNormals = ceCurve._normals;
+ for ( size_t iC1 = 0; iC1 < centers.size(); ++iC1 )
+ {
+ isOK = false;
+ for ( size_t iE2 = 0; iE2 < centerCurves.size() && !isOK; ++iE2 )
+ {
+ if ( iE1 != iE2 )
+ isOK = centerCurves[ iE2 ].FindNewNormal( centers[ iC1 ], newNormals[ iC1 ]);
+ }
+ if ( isOK && !ceCurve._adjFace.IsNull() )
+ {
+ // compute new _LayerEdge::_cosin
+ const SMDS_MeshNode* node = ceCurve._ledges[ iC1 ]->_nodes[0];
+ inFaceDir = getFaceDir( ceCurve._adjFace, ceCurve._edge, node, helper, isOK );
+ if ( isOK )
+ {
+ double angle = inFaceDir.Angle( newNormals[ iC1 ] ); // [0,PI]
+ ceCurve._ledges[ iC1 ]->_cosin = Cos( angle );
+ avgCosin += ceCurve._ledges[ iC1 ]->_cosin;
+ nbCosin++;
+ }
+ }
+ }
+ }
+ // set new normals to _LayerEdge's of NOT degenerated central curves
+ for ( size_t iE = 0; iE < centerCurves.size(); ++iE )
+ {
+ if ( centerCurves[ iE ]._isDegenerated )
+ continue;
+ for ( size_t iLE = 0; iLE < centerCurves[ iE ]._ledges.size(); ++iLE )
+ centerCurves[ iE ]._ledges[ iLE ]->_normal = centerCurves[ iE ]._normals[ iLE ];
+ }
+ // set new normals to _LayerEdge's of degenerated central curves
+ for ( size_t iE = 0; iE < centerCurves.size(); ++iE )
+ {
+ if ( !centerCurves[ iE ]._isDegenerated ||
+ centerCurves[ iE ]._ledges.size() < 3 )
+ continue;
+ // new normal is an average of new normals at VERTEXes that
+ // was computed on non-degenerated _CentralCurveOnEdge's
+ gp_XYZ newNorm = ( centerCurves[ iE ]._ledges.front()->_normal +
+ centerCurves[ iE ]._ledges.back ()->_normal );
+ double sz = newNorm.Modulus();
+ if ( sz < 1e-200 )
+ continue;
+ newNorm /= sz;
+ double newCosin = ( 0.5 * centerCurves[ iE ]._ledges.front()->_cosin +
+ 0.5 * centerCurves[ iE ]._ledges.back ()->_cosin );
+ for ( size_t iLE = 1, nb = centerCurves[ iE ]._ledges.size() - 1; iLE < nb; ++iLE )
+ {
+ centerCurves[ iE ]._ledges[ iLE ]->_normal = newNorm;
+ centerCurves[ iE ]._ledges[ iLE ]->_cosin = newCosin;
+ }
+ }
+
+ // Find new normals for _LayerEdge's based on FACE
+
+ if ( nbCosin > 0 )
+ avgCosin /= nbCosin;
+ const TGeomID faceID = meshDS->ShapeToIndex( convFace._face );
+ map< TGeomID, int >::iterator id2end = convFace._subIdToEdgeEnd.find( faceID );
+ if ( id2end != convFace._subIdToEdgeEnd.end() )
+ {
+ int iE = 0;
+ gp_XYZ newNorm;
+ data.GetEdgesOnShape( id2end->second, iBeg, iEnd );
+ for ( ; iBeg < iEnd; ++iBeg )
+ {
+ _LayerEdge* ledge = data._edges[ iBeg ];
+ if ( !convFace.GetCenterOfCurvature( ledge, surfProp, helper, center ))
+ continue;
+ for ( size_t i = 0; i < centerCurves.size(); ++i, ++iE )
+ {
+ iE = iE % centerCurves.size();
+ if ( centerCurves[ iE ]._isDegenerated )
+ continue;
+ newNorm.SetCoord( 0,0,0 );
+ if ( centerCurves[ iE ].FindNewNormal( center, newNorm ))
+ {
+ ledge->_normal = newNorm;
+ ledge->_cosin = avgCosin;
+ break;
+ }
+ }
+ }
+ }
+
+ } // not a quasi-spherical FACE
+
+ // Update _LayerEdge's data according to a new normal
+
+ dumpFunction(SMESH_Comment("updateNormalsOfConvexFaces")<<data._index
+ <<"_F"<<meshDS->ShapeToIndex( convFace._face ));
+
+ id2end = convFace._subIdToEdgeEnd.begin();
+ for ( ; id2end != convFace._subIdToEdgeEnd.end(); ++id2end )
+ {
+ data.GetEdgesOnShape( id2end->second, iBeg, iEnd );
+ for ( ; iBeg < iEnd; ++iBeg )
+ {
+ _LayerEdge* & ledge = data._edges[ iBeg ];
+ double len = ledge->_len;
+ ledge->InvalidateStep( stepNb + 1, /*restoreLength=*/true );
+ ledge->SetCosin( ledge->_cosin );
+ ledge->SetNewLength( len, helper );
+ }
+
+ } // loop on sub-shapes of convFace._face
+
+ // Find FACEs adjacent to convFace._face that got necessity to smooth
+ // as a result of normals modification
+
+ set< TGeomID > adjFacesToSmooth;
+ for ( size_t iE = 0; iE < centerCurves.size(); ++iE )
+ {
+ if ( centerCurves[ iE ]._adjFace.IsNull() ||
+ centerCurves[ iE ]._adjFaceToSmooth )
+ continue;
+ for ( size_t iLE = 0; iLE < centerCurves[ iE ]._ledges.size(); ++iLE )
+ {
+ if ( centerCurves[ iE ]._ledges[ iLE ]->_cosin > theMinSmoothCosin )
+ {
+ adjFacesToSmooth.insert( meshDS->ShapeToIndex( centerCurves[ iE ]._adjFace ));
+ break;
+ }
+ }
+ }
+ data.AddShapesToSmooth( adjFacesToSmooth );
+
+ dumpFunctionEnd();
+
+
+ } // loop on data._convexFaces
+
+ return true;
+}
+
+//================================================================================
+/*!
+ * \brief Finds a center of curvature of a surface at a _LayerEdge
+ */
+//================================================================================
- // find EDGEs the edges reside
- TopoDS_Edge E1, E2;
- TopoDS_Shape S = helper.GetSubShapeByNode( edge1->_nodes[0], getMeshDS() );
- if ( S.ShapeType() != TopAbs_EDGE )
- continue; // TODO: find EDGE by VERTEX
- E1 = TopoDS::Edge( S );
- set< _LayerEdge*, _LayerEdgeCmp >::iterator eIt = ee.begin();
- while ( E2.IsNull() && eIt != ee.end())
- {
- _LayerEdge* e2 = *eIt++;
- TopoDS_Shape S = helper.GetSubShapeByNode( e2->_nodes[0], getMeshDS() );
- if ( S.ShapeType() == TopAbs_EDGE )
- E2 = TopoDS::Edge( S ), edge2 = e2;
- }
- if ( E2.IsNull() ) continue; // TODO: find EDGE by VERTEX
+bool _ConvexFace::GetCenterOfCurvature( _LayerEdge* ledge,
+ BRepLProp_SLProps& surfProp,
+ SMESH_MesherHelper& helper,
+ gp_Pnt & center ) const
+{
+ gp_XY uv = helper.GetNodeUV( _face, ledge->_nodes[0] );
+ surfProp.SetParameters( uv.X(), uv.Y() );
+ if ( !surfProp.IsCurvatureDefined() )
+ return false;
- // find 3 FACEs sharing 2 EDGEs
+ const double oriFactor = ( _face.Orientation() == TopAbs_REVERSED ? +1. : -1. );
+ double surfCurvatureMax = surfProp.MaxCurvature() * oriFactor;
+ double surfCurvatureMin = surfProp.MinCurvature() * oriFactor;
+ if ( surfCurvatureMin > surfCurvatureMax )
+ center = surfProp.Value().Translated( surfProp.Normal().XYZ() / surfCurvatureMin * oriFactor );
+ else
+ center = surfProp.Value().Translated( surfProp.Normal().XYZ() / surfCurvatureMax * oriFactor );
- TopoDS_Face FF1[2], FF2[2];
- PShapeIteratorPtr fIt = helper.GetAncestors(E1, *_mesh, TopAbs_FACE);
- while ( fIt->more() && FF1[1].IsNull())
- {
- const TopoDS_Face *F = (const TopoDS_Face*) fIt->next();
- if ( helper.IsSubShape( *F, data._solid))
- FF1[ FF1[0].IsNull() ? 0 : 1 ] = *F;
- }
- fIt = helper.GetAncestors(E2, *_mesh, TopAbs_FACE);
- while ( fIt->more() && FF2[1].IsNull())
- {
- const TopoDS_Face *F = (const TopoDS_Face*) fIt->next();
- if ( helper.IsSubShape( *F, data._solid))
- FF2[ FF2[0].IsNull() ? 0 : 1 ] = *F;
- }
- // exclude a FACE common to E1 and E2 (put it at [1] in FF* )
- if ( FF1[0].IsSame( FF2[0]) || FF1[0].IsSame( FF2[1]))
- std::swap( FF1[0], FF1[1] );
- if ( FF2[0].IsSame( FF1[0]) )
- std::swap( FF2[0], FF2[1] );
- if ( FF1[0].IsNull() || FF2[0].IsNull() )
- continue;
+ return true;
+}
- // get a new normal for edge1
- bool ok;
- gp_Vec dir1 = edge1->_normal, dir2 = edge2->_normal;
- if ( edge1->_cosin < 0 )
- dir1 = getFaceDir( FF1[0], E1, edge1->_nodes[0], helper, ok ).Normalized();
- if ( edge2->_cosin < 0 )
- dir2 = getFaceDir( FF2[0], E2, edge2->_nodes[0], helper, ok ).Normalized();
- // gp_Vec dir1 = getFaceDir( FF1[0], E1, edge1->_nodes[0], helper, ok );
- // gp_Vec dir2 = getFaceDir( FF2[0], E2, edge2->_nodes[0], helper, ok2 );
- // double wgt1 = ( edge1->_cosin + 1 ) / ( edge1->_cosin + edge2->_cosin + 2 );
- // double wgt2 = ( edge2->_cosin + 1 ) / ( edge1->_cosin + edge2->_cosin + 2 );
- // gp_Vec newNorm = wgt1 * dir1 + wgt2 * dir2;
- // newNorm.Normalize();
-
- double wgt1 = ( edge1->_cosin + 1 ) / ( edge1->_cosin + edge2->_cosin + 2 );
- double wgt2 = ( edge2->_cosin + 1 ) / ( edge1->_cosin + edge2->_cosin + 2 );
- gp_Vec newNorm = wgt1 * dir1 + wgt2 * dir2;
- newNorm.Normalize();
-
- edge1->_normal = newNorm.XYZ();
-
- // update data of edge1 depending on _normal
- const SMDS_MeshNode *n1, *n2;
- n1 = edge1->_2neibors->_edges[0]->_nodes[0];
- n2 = edge1->_2neibors->_edges[1]->_nodes[0];
- //if ( !findNeiborsOnEdge( edge1, n1, n2, data ))
- // continue;
- edge1->SetDataByNeighbors( n1, n2, helper );
- gp_Vec dirInFace;
- if ( edge1->_cosin < 0 )
- dirInFace = dir1;
- else
- dirInFace = getFaceDir( FF1[0], E1, edge1->_nodes[0], helper, ok );
- double angle = dir1.Angle( edge1->_normal ); // [0,PI]
- edge1->SetCosin( cos( angle ));
+//================================================================================
+/*!
+ * \brief Check that prisms are not distorted
+ */
+//================================================================================
- // limit data._stepSize
- if ( edge1->_cosin > 0.1 )
+bool _ConvexFace::CheckPrisms() const
+{
+ for ( size_t i = 0; i < _simplexTestEdges.size(); ++i )
+ {
+ const _LayerEdge* edge = _simplexTestEdges[i];
+ SMESH_TNodeXYZ tgtXYZ( edge->_nodes.back() );
+ for ( size_t j = 0; j < edge->_simplices.size(); ++j )
+ if ( !edge->_simplices[j].IsForward( edge->_nodes[0], &tgtXYZ ))
{
- SMDS_ElemIteratorPtr fIt = edge1->_nodes[0]->GetInverseElementIterator(SMDSAbs_Face);
- while ( fIt->more() )
- limitStepSize( data, fIt->next(), edge1->_cosin );
+ debugMsg( "Bad simplex of _simplexTestEdges ("
+ << " "<< edge->_nodes[0]->GetID()<< " "<< tgtXYZ._node->GetID()
+ << " "<< edge->_simplices[j]._nPrev->GetID()
+ << " "<< edge->_simplices[j]._nNext->GetID() << " )" );
+ return false;
}
- // set new XYZ of target node
- edge1->InvalidateStep( 1 );
- edge1->_len = 0;
- edge1->SetNewLength( data._stepSize, helper );
- }
+ }
+ return true;
+}
- // Update normals and other dependent data of not intersecting _LayerEdge's
- // neighboring the intersecting ones
+//================================================================================
+/*!
+ * \brief Try to compute a new normal by interpolating normals of _LayerEdge's
+ * stored in this _CentralCurveOnEdge.
+ * \param [in] center - curvature center of a point of another _CentralCurveOnEdge.
+ * \param [in,out] newNormal - current normal at this point, to be redefined
+ * \return bool - true if succeeded.
+ */
+//================================================================================
- for ( e2ee = edge2CloseEdge.begin(); e2ee != edge2CloseEdge.end(); ++e2ee )
- {
- _LayerEdge* edge1 = e2ee->first;
- if ( !edge1->_2neibors )
- continue;
- for ( int j = 0; j < 2; ++j ) // loop on 2 neighbors
- {
- _LayerEdge* neighbor = edge1->_2neibors->_edges[j];
- if ( edge2CloseEdge.count ( neighbor ))
- continue; // j-th neighbor is also intersected
- _LayerEdge* prevEdge = edge1;
- const int nbSteps = 6;
- for ( int step = nbSteps; step; --step ) // step from edge1 in j-th direction
- {
- if ( !neighbor->_2neibors )
- break; // neighbor is on VERTEX
- int iNext = 0;
- _LayerEdge* nextEdge = neighbor->_2neibors->_edges[iNext];
- if ( nextEdge == prevEdge )
- nextEdge = neighbor->_2neibors->_edges[ ++iNext ];
-// const double& wgtPrev = neighbor->_2neibors->_wgt[1-iNext];
-// const double& wgtNext = neighbor->_2neibors->_wgt[iNext];
- double r = double(step-1)/nbSteps;
- if ( !nextEdge->_2neibors )
- r = 0.5;
+bool _CentralCurveOnEdge::FindNewNormal( const gp_Pnt& center, gp_XYZ& newNormal )
+{
+ if ( this->_isDegenerated )
+ return false;
- gp_XYZ newNorm = prevEdge->_normal * r + nextEdge->_normal * (1-r);
- newNorm.Normalize();
+ // find two centers the given one lies between
- neighbor->_normal = newNorm;
- neighbor->SetCosin( prevEdge->_cosin * r + nextEdge->_cosin * (1-r) );
- neighbor->SetDataByNeighbors( prevEdge->_nodes[0], nextEdge->_nodes[0], helper );
+ for ( size_t i = 0, nb = _curvaCenters.size()-1; i < nb; ++i )
+ {
+ double sl2 = 1.001 * _segLength2[ i ];
- neighbor->InvalidateStep( 1 );
- neighbor->_len = 0;
- neighbor->SetNewLength( data._stepSize, helper );
+ double d1 = center.SquareDistance( _curvaCenters[ i ]);
+ if ( d1 > sl2 )
+ continue;
+
+ double d2 = center.SquareDistance( _curvaCenters[ i+1 ]);
+ if ( d2 > sl2 || d2 + d1 < 1e-100 )
+ continue;
- // goto the next neighbor
- prevEdge = neighbor;
- neighbor = nextEdge;
- }
- }
- }
- dumpFunctionEnd();
+ d1 = Sqrt( d1 );
+ d2 = Sqrt( d2 );
+ double r = d1 / ( d1 + d2 );
+ gp_XYZ norm = (( 1. - r ) * _ledges[ i ]->_normal +
+ ( r ) * _ledges[ i+1 ]->_normal );
+ norm.Normalize();
+
+ newNormal += norm;
+ double sz = newNormal.Modulus();
+ if ( sz < 1e-200 )
+ break;
+ newNormal /= sz;
+ return true;
}
- // 2) Check absence of intersections
- // TODO?
+ return false;
+}
- for ( size_t i = 0 ; i < tmpFaces.size(); ++i )
- delete tmpFaces[i];
+//================================================================================
+/*!
+ * \brief Set shape members
+ */
+//================================================================================
- return true;
+void _CentralCurveOnEdge::SetShapes( const TopoDS_Edge& edge,
+ const _ConvexFace& convFace,
+ const _SolidData& data,
+ SMESH_MesherHelper& helper)
+{
+ _edge = edge;
+
+ PShapeIteratorPtr fIt = helper.GetAncestors( edge, *helper.GetMesh(), TopAbs_FACE );
+ while ( const TopoDS_Shape* F = fIt->next())
+ if ( !convFace._face.IsSame( *F ))
+ {
+ _adjFace = TopoDS::Face( *F );
+ _adjFaceToSmooth = false;
+ // _adjFace already in a smoothing queue ?
+ size_t end;
+ TGeomID adjFaceID = helper.GetMeshDS()->ShapeToIndex( *F );
+ if ( data.GetShapeEdges( adjFaceID, end ))
+ _adjFaceToSmooth = ( end < data._nbShapesToSmooth );
+ break;
+ }
}
//================================================================================
bool segmentIntersected = false;
distance = Precision::Infinite();
int iFace = -1; // intersected face
- for ( size_t j = 0 ; j < suspectFaces.size() && !segmentIntersected; ++j )
+ for ( size_t j = 0 ; j < suspectFaces.size() /*&& !segmentIntersected*/; ++j )
{
const SMDS_MeshElement* face = suspectFaces[j];
if ( face->GetNodeIndex( _nodes.back() ) >= 0 ||
{
const SMDS_MeshNode* tria[3];
tria[0] = *nIt++;
- tria[1] = *nIt++;;
+ tria[1] = *nIt++;
for ( int n2 = 2; n2 < nbNodes && !intFound; ++n2 )
{
tria[2] = *nIt++;
}
if ( intFound )
{
- if ( dist < segLen*(1.01) && dist > -(_len-segLen) )
+ if ( dist < segLen*(1.01) && dist > -(_len*_lenFactor-segLen) )
segmentIntersected = true;
if ( distance > dist )
distance = dist, iFace = j;
}
}
if ( iFace != -1 && face ) *face = suspectFaces[iFace];
-// if ( distance && iFace > -1 )
-// {
-// // distance is used to limit size of inflation step which depends on
-// // whether the intersected face bears viscous layers or not
-// bool faceHasVL = suspectFaces[iFace]->GetID() < 1;
-// if ( faceHasVL )
-// *distance /= 2;
-// }
+
if ( segmentIntersected )
{
#ifdef __myDEBUG
return segDir;
}
+//================================================================================
+/*!
+ * \brief Return the last position of the target node on a FACE.
+ * \param [in] F - the FACE this _LayerEdge is inflated along
+ * \return gp_XY - result UV
+ */
+//================================================================================
+
+gp_XY _LayerEdge::LastUV( const TopoDS_Face& F ) const
+{
+ if ( F.IsSame( _sWOL )) // F is my FACE
+ return gp_XY( _pos.back().X(), _pos.back().Y() );
+
+ if ( _sWOL.IsNull() || _sWOL.ShapeType() != TopAbs_EDGE ) // wrong call
+ return gp_XY( 1e100, 1e100 );
+
+ // _sWOL is EDGE of F; _pos.back().X() is the last U on the EDGE
+ double f, l, u = _pos.back().X();
+ Handle(Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface( TopoDS::Edge(_sWOL), F, f,l);
+ if ( !C2d.IsNull() && f <= u && u <= l )
+ return C2d->Value( u ).XY();
+
+ return gp_XY( 1e100, 1e100 );
+}
+
//================================================================================
/*!
* \brief Test intersection of the last segment with a given triangle
/* calculate distance from vert0 to ray origin */
gp_XYZ tvec = orig - vert0;
- if ( tvec * dir > EPSILON )
+ //if ( tvec * dir > EPSILON )
// intersected face is at back side of the temporary face this _LayerEdge belongs to
- return false;
+ //return false;
gp_XYZ edge1 = vert1 - vert0;
gp_XYZ edge2 = vert2 - vert0;
double det = edge1 * pvec;
if (det > -EPSILON && det < EPSILON)
- return 0;
+ return false;
double inv_det = 1.0 / det;
/* calculate U parameter and test bounds */
double u = ( tvec * pvec ) * inv_det;
- if (u < 0.0 || u > 1.0)
- return 0;
+ //if (u < 0.0 || u > 1.0)
+ if (u < -EPSILON || u > 1.0 + EPSILON)
+ return false;
/* prepare to test V parameter */
gp_XYZ qvec = tvec ^ edge1;
/* calculate V parameter and test bounds */
double v = (dir * qvec) * inv_det;
- if ( v < 0.0 || u + v > 1.0 )
- return 0;
+ //if ( v < 0.0 || u + v > 1.0 )
+ if ( v < -EPSILON || u + v > 1.0 + EPSILON)
+ return false;
/* calculate t, ray intersects triangle */
t = (edge2 * qvec) * inv_det;
- // if (det < EPSILON)
- // return false;
-
- // /* calculate distance from vert0 to ray origin */
- // gp_XYZ tvec = orig - vert0;
-
- // /* calculate U parameter and test bounds */
- // double u = tvec * pvec;
- // if (u < 0.0 || u > det)
-// return 0;
-
-// /* prepare to test V parameter */
-// gp_XYZ qvec = tvec ^ edge1;
-
-// /* calculate V parameter and test bounds */
-// double v = dir * qvec;
-// if (v < 0.0 || u + v > det)
-// return 0;
-
-// /* calculate t, scale parameters, ray intersects triangle */
-// double t = edge2 * qvec;
-// double inv_det = 1.0 / det;
-// t *= inv_det;
-// //u *= inv_det;
-// //v *= inv_det;
-
- return true;
+ //return true;
+ return t > 0.;
}
//================================================================================
SMESH_TNodeXYZ oldPos( tgtNode );
double dist01, distNewOld;
- SMESH_TNodeXYZ p0( _2neibors->_nodes[0]);
- SMESH_TNodeXYZ p1( _2neibors->_nodes[1]);
- dist01 = p0.Distance( _2neibors->_nodes[1] );
+ SMESH_TNodeXYZ p0( _2neibors->tgtNode(0));
+ SMESH_TNodeXYZ p1( _2neibors->tgtNode(1));
+ dist01 = p0.Distance( _2neibors->tgtNode(1) );
gp_Pnt newPos = p0 * _2neibors->_wgt[0] + p1 * _2neibors->_wgt[1];
double lenDelta = 0;
newPos += SMESH_TNodeXYZ( _simplices[i]._nPrev );
newPos /= _simplices.size();
+ const gp_XYZ& curPos ( _pos.back() );
+ const gp_Pnt prevPos( _pos[ _pos.size()-2 ]);
if ( _curvature )
- newPos += _normal * _curvature->lenDelta( _len );
-
- gp_Pnt prevPos( _pos[ _pos.size()-2 ]);
-// if ( _cosin < -0.1)
-// {
-// // Avoid decreasing length of edge on concave surface
-// //gp_Vec oldMove( _pos[ _pos.size()-2 ], _pos.back() );
-// gp_Vec newMove( prevPos, newPos );
-// newPos = _pos.back() + newMove.XYZ();
-// }
-// else if ( _cosin > 0.3 )
-// {
-// // Avoid increasing length of edge too much
-
-// }
+ {
+ double delta = _curvature->lenDelta( _len );
+ if ( delta > 0 )
+ newPos += _normal * delta;
+ else
+ {
+ double segLen = _normal * ( newPos - prevPos.XYZ() );
+ if ( segLen + delta > 0 )
+ newPos += _normal * delta;
+ }
+ // double segLenChange = _normal * ( curPos - newPos );
+ // newPos += 0.5 * _normal * segLenChange;
+ }
+
// count quality metrics (orientation) of tetras around _tgtNode
int nbOkBefore = 0;
- SMESH_TNodeXYZ tgtXYZ( _nodes.back() );
for ( size_t i = 0; i < _simplices.size(); ++i )
- nbOkBefore += _simplices[i].IsForward( _nodes[0], &tgtXYZ );
+ nbOkBefore += _simplices[i].IsForward( _nodes[0], &curPos );
int nbOkAfter = 0;
for ( size_t i = 0; i < _simplices.size(); ++i )
{
if ( _len - len > -1e-6 )
{
- _pos.push_back( _pos.back() );
+ //_pos.push_back( _pos.back() );
return;
}
double u = Precision::Infinite(); // to force projection w/o distance check
helper.CheckNodeU( TopoDS::Edge( _sWOL ), n, u, 1e-10, /*force=*/true, distXYZ );
_pos.back().SetCoord( u, 0, 0 );
- SMDS_EdgePosition* pos = static_cast<SMDS_EdgePosition*>( n->GetPosition() );
- pos->SetUParameter( u );
+ if ( _nodes.size() > 1 )
+ {
+ SMDS_EdgePosition* pos = static_cast<SMDS_EdgePosition*>( n->GetPosition() );
+ pos->SetUParameter( u );
+ }
}
else // TopAbs_FACE
{
gp_XY uv( Precision::Infinite(), 0 );
helper.CheckNodeUV( TopoDS::Face( _sWOL ), n, uv, 1e-10, /*force=*/true, distXYZ );
_pos.back().SetCoord( uv.X(), uv.Y(), 0 );
- SMDS_FacePosition* pos = static_cast<SMDS_FacePosition*>( n->GetPosition() );
- pos->SetUParameter( uv.X() );
- pos->SetVParameter( uv.Y() );
+ if ( _nodes.size() > 1 )
+ {
+ SMDS_FacePosition* pos = static_cast<SMDS_FacePosition*>( n->GetPosition() );
+ pos->SetUParameter( uv.X() );
+ pos->SetVParameter( uv.Y() );
+ }
}
n->setXYZ( distXYZ[1], distXYZ[2], distXYZ[3]);
}
*/
//================================================================================
-void _LayerEdge::InvalidateStep( int curStep )
+void _LayerEdge::InvalidateStep( int curStep, bool restoreLength )
{
if ( _pos.size() > curStep )
{
+ if ( restoreLength )
+ _len -= ( _pos[ curStep-1 ] - _pos.back() ).Modulus();
+
_pos.resize( curStep );
gp_Pnt nXYZ = _pos.back();
SMDS_MeshNode* n = const_cast< SMDS_MeshNode*>( _nodes.back() );
TNode2Edge* n2eMap = 0;
TNode2Edge::iterator n2e;
+ // Create intermediate nodes on each _LayerEdge
+
+ int iS = 0, iEnd = data._endEdgeOnShape[ iS ];
+
for ( size_t i = 0; i < data._edges.size(); ++i )
{
_LayerEdge& edge = *data._edges[i];
+ if ( edge._nodes.size() < 2 )
+ continue; // on _noShrinkShapes
+
+ // get parameters of layers for the edge
+ if ( i == iEnd )
+ iEnd = data._endEdgeOnShape[ ++iS ];
+ const AverageHyp& hyp = data._hypOnShape[ iS ];
+
// get accumulated length of segments
vector< double > segLen( edge._pos.size() );
segLen[0] = 0.0;
const SMDS_MeshNode* tgtNode = edge._nodes.back();
if ( edge._nodes.size() == 2 )
{
- edge._nodes.resize( data._hyp->GetNumberLayers() + 1, 0 );
+ edge._nodes.resize( hyp.GetNumberLayers() + 1, 0 );
edge._nodes[1] = 0;
edge._nodes.back() = tgtNode;
}
n2eMap = ( s2ne == data._s2neMap.end() ) ? 0 : n2eMap = s2ne->second;
prevBaseId = baseShapeId;
}
+ _LayerEdge* edgeOnSameNode = 0;
if ( n2eMap && (( n2e = n2eMap->find( edge._nodes[0] )) != n2eMap->end() ))
{
- _LayerEdge* foundEdge = n2e->second;
- const gp_XYZ& foundPos = foundEdge->_pos.back();
- SMDS_PositionPtr lastPos = tgtNode->GetPosition();
+ edgeOnSameNode = n2e->second;
+ const gp_XYZ& otherTgtPos = edgeOnSameNode->_pos.back();
+ SMDS_PositionPtr lastPos = tgtNode->GetPosition();
if ( isOnEdge )
{
SMDS_EdgePosition* epos = static_cast<SMDS_EdgePosition*>( lastPos );
- epos->SetUParameter( foundPos.X() );
+ epos->SetUParameter( otherTgtPos.X() );
}
else
{
SMDS_FacePosition* fpos = static_cast<SMDS_FacePosition*>( lastPos );
- fpos->SetUParameter( foundPos.X() );
- fpos->SetVParameter( foundPos.Y() );
+ fpos->SetUParameter( otherTgtPos.X() );
+ fpos->SetVParameter( otherTgtPos.Y() );
}
}
// calculate height of the first layer
double h0;
const double T = segLen.back(); //data._hyp.GetTotalThickness();
- const double f = data._hyp->GetStretchFactor();
- const int N = data._hyp->GetNumberLayers();
+ const double f = hyp.GetStretchFactor();
+ const int N = hyp.GetNumberLayers();
const double fPowN = pow( f, N );
if ( fPowN - 1 <= numeric_limits<double>::min() )
h0 = T / N;
double r = ( segLen[iSeg] - hSum ) / ( segLen[iSeg] - segLen[iPrevSeg] );
gp_Pnt pos = r * edge._pos[iPrevSeg] + (1-r) * edge._pos[iSeg];
- SMDS_MeshNode*& node = const_cast< SMDS_MeshNode*& >(edge._nodes[ iStep ]);
+ SMDS_MeshNode*& node = const_cast< SMDS_MeshNode*& >( edge._nodes[ iStep ]);
if ( !edge._sWOL.IsNull() )
{
// compute XYZ by parameters <pos>
}
node->setXYZ( pos.X(), pos.Y(), pos.Z() );
}
+ } // loop on edge._nodes
+
+ if ( !edge._sWOL.IsNull() ) // prepare for shrink()
+ {
+ if ( isOnEdge )
+ edge._pos.back().SetCoord( u, 0,0);
+ else
+ edge._pos.back().SetCoord( uv.X(), uv.Y() ,0);
+
+ if ( edgeOnSameNode )
+ edgeOnSameNode->_pos.back() = edge._pos.back();
}
- }
+
+ } // loop on data._edges to create nodes
if ( !getMeshDS()->IsEmbeddedMode() )
// Log node movement
getMeshDS()->MoveNode( p._node, p.X(), p.Y(), p.Z() );
}
- // TODO: make quadratic prisms and polyhedrons(?)
+ // Create volumes
helper.SetElementsOnShape(true);
+ vector< vector<const SMDS_MeshNode*>* > nnVec;
+ set< vector<const SMDS_MeshNode*>* > nnSet;
+ set< int > degenEdgeInd;
+ vector<const SMDS_MeshElement*> degenVols;
+
TopExp_Explorer exp( data._solid, TopAbs_FACE );
for ( ; exp.More(); exp.Next() )
{
- if ( data._ignoreFaceIds.count( getMeshDS()->ShapeToIndex( exp.Current() )))
+ const TGeomID faceID = getMeshDS()->ShapeToIndex( exp.Current() );
+ if ( data._ignoreFaceIds.count( faceID ))
continue;
- SMESHDS_SubMesh* fSubM = getMeshDS()->MeshElements( exp.Current() );
- SMDS_ElemIteratorPtr fIt = fSubM->GetElements();
- vector< vector<const SMDS_MeshNode*>* > nnVec;
+ const bool isReversedFace = data._reversedFaceIds.count( faceID );
+ SMESHDS_SubMesh* fSubM = getMeshDS()->MeshElements( exp.Current() );
+ SMDS_ElemIteratorPtr fIt = fSubM->GetElements();
while ( fIt->more() )
{
const SMDS_MeshElement* face = fIt->next();
- int nbNodes = face->NbCornerNodes();
+ const int nbNodes = face->NbCornerNodes();
nnVec.resize( nbNodes );
- SMDS_ElemIteratorPtr nIt = face->nodesIterator();
+ nnSet.clear();
+ degenEdgeInd.clear();
+ int nbZ = 0;
+ SMDS_NodeIteratorPtr nIt = face->nodeIterator();
for ( int iN = 0; iN < nbNodes; ++iN )
{
- const SMDS_MeshNode* n = static_cast<const SMDS_MeshNode*>( nIt->next() );
- nnVec[ iN ] = & data._n2eMap[ n ]->_nodes;
+ const SMDS_MeshNode* n = nIt->next();
+ const int i = isReversedFace ? nbNodes-1-iN : iN;
+ nnVec[ i ] = & data._n2eMap[ n ]->_nodes;
+ if ( nnVec[ i ]->size() < 2 )
+ degenEdgeInd.insert( iN );
+ else
+ nbZ = nnVec[ i ]->size();
+
+ if ( helper.HasDegeneratedEdges() )
+ nnSet.insert( nnVec[ i ]);
}
+ if ( nbZ == 0 )
+ continue;
+ if ( 0 < nnSet.size() && nnSet.size() < 3 )
+ continue;
- int nbZ = nnVec[0]->size();
switch ( nbNodes )
{
case 3:
- for ( int iZ = 1; iZ < nbZ; ++iZ )
- helper.AddVolume( (*nnVec[0])[iZ-1], (*nnVec[1])[iZ-1], (*nnVec[2])[iZ-1],
- (*nnVec[0])[iZ], (*nnVec[1])[iZ], (*nnVec[2])[iZ]);
+ switch ( degenEdgeInd.size() )
+ {
+ case 0: // PENTA
+ {
+ for ( int iZ = 1; iZ < nbZ; ++iZ )
+ helper.AddVolume( (*nnVec[0])[iZ-1], (*nnVec[1])[iZ-1], (*nnVec[2])[iZ-1],
+ (*nnVec[0])[iZ], (*nnVec[1])[iZ], (*nnVec[2])[iZ]);
+ break;
+ }
+ case 1: // PYRAM
+ {
+ int i2 = *degenEdgeInd.begin();
+ int i0 = helper.WrapIndex( i2 - 1, nbNodes );
+ int i1 = helper.WrapIndex( i2 + 1, nbNodes );
+ for ( int iZ = 1; iZ < nbZ; ++iZ )
+ helper.AddVolume( (*nnVec[i0])[iZ-1], (*nnVec[i1])[iZ-1],
+ (*nnVec[i1])[iZ], (*nnVec[i0])[iZ], (*nnVec[i2])[0]);
+ break;
+ }
+ case 2: // TETRA
+ {
+ int i3 = !degenEdgeInd.count(0) ? 0 : !degenEdgeInd.count(1) ? 1 : 2;
+ for ( int iZ = 1; iZ < nbZ; ++iZ )
+ helper.AddVolume( (*nnVec[0])[iZ-1], (*nnVec[1])[iZ-1], (*nnVec[2])[iZ-1],
+ (*nnVec[i3])[iZ]);
+ break;
+ }
+ }
break;
+
case 4:
- for ( int iZ = 1; iZ < nbZ; ++iZ )
- helper.AddVolume( (*nnVec[0])[iZ-1], (*nnVec[1])[iZ-1],
- (*nnVec[2])[iZ-1], (*nnVec[3])[iZ-1],
- (*nnVec[0])[iZ], (*nnVec[1])[iZ],
- (*nnVec[2])[iZ], (*nnVec[3])[iZ]);
+ switch ( degenEdgeInd.size() )
+ {
+ case 0: // HEX
+ {
+ for ( int iZ = 1; iZ < nbZ; ++iZ )
+ helper.AddVolume( (*nnVec[0])[iZ-1], (*nnVec[1])[iZ-1],
+ (*nnVec[2])[iZ-1], (*nnVec[3])[iZ-1],
+ (*nnVec[0])[iZ], (*nnVec[1])[iZ],
+ (*nnVec[2])[iZ], (*nnVec[3])[iZ]);
+ break;
+ }
+ case 2: // PENTA?
+ {
+ int i2 = *degenEdgeInd.begin();
+ int i3 = *degenEdgeInd.rbegin();
+ bool ok = ( i3 - i2 == 1 );
+ if ( i2 == 0 && i3 == 3 ) { i2 = 3; i3 = 0; ok = true; }
+ int i0 = helper.WrapIndex( i3 + 1, nbNodes );
+ int i1 = helper.WrapIndex( i0 + 1, nbNodes );
+ for ( int iZ = 1; iZ < nbZ; ++iZ )
+ {
+ const SMDS_MeshElement* vol =
+ helper.AddVolume( (*nnVec[i3])[0], (*nnVec[i0])[iZ], (*nnVec[i0])[iZ-1],
+ (*nnVec[i2])[0], (*nnVec[i1])[iZ], (*nnVec[i1])[iZ-1]);
+ if ( !ok && vol )
+ degenVols.push_back( vol );
+ }
+ break;
+ }
+ case 3: // degen HEX
+ {
+ const SMDS_MeshNode* nn[8];
+ for ( int iZ = 1; iZ < nbZ; ++iZ )
+ {
+ const SMDS_MeshElement* vol =
+ helper.AddVolume( nnVec[0]->size() > 1 ? (*nnVec[0])[iZ-1] : (*nnVec[0])[0],
+ nnVec[1]->size() > 1 ? (*nnVec[1])[iZ-1] : (*nnVec[1])[0],
+ nnVec[2]->size() > 1 ? (*nnVec[2])[iZ-1] : (*nnVec[2])[0],
+ nnVec[3]->size() > 1 ? (*nnVec[3])[iZ-1] : (*nnVec[3])[0],
+ nnVec[0]->size() > 1 ? (*nnVec[0])[iZ] : (*nnVec[0])[0],
+ nnVec[1]->size() > 1 ? (*nnVec[1])[iZ] : (*nnVec[1])[0],
+ nnVec[2]->size() > 1 ? (*nnVec[2])[iZ] : (*nnVec[2])[0],
+ nnVec[3]->size() > 1 ? (*nnVec[3])[iZ] : (*nnVec[3])[0]);
+ degenVols.push_back( vol );
+ }
+ }
break;
+ }
+ break;
+
default:
return error("Not supported type of element", data._index);
- }
+
+ } // switch ( nbNodes )
+ } // while ( fIt->more() )
+ } // loop on FACEs
+
+ if ( !degenVols.empty() )
+ {
+ SMESH_ComputeErrorPtr& err = _mesh->GetSubMesh( data._solid )->GetComputeError();
+ if ( !err || err->IsOK() )
+ {
+ err.reset( new SMESH_ComputeError( COMPERR_WARNING,
+ "Degenerated volumes created" ));
+ err->myBadElements.insert( err->myBadElements.end(),
+ degenVols.begin(),degenVols.end() );
}
}
+
return true;
}
// EDGE's to shrink
map< TGeomID, _Shrinker1D > e2shrMap;
+ vector< _LayerEdge* > lEdges;
// loop on FACES to srink mesh on
map< TGeomID, _SolidData* >::iterator f2sd = f2sdMap.begin();
for ( ; f2sd != f2sdMap.end(); ++f2sd )
{
- _SolidData& data = *f2sd->second;
- TNode2Edge& n2eMap = data._n2eMap;
- const TopoDS_Face& F = TopoDS::Face( getMeshDS()->IndexToShape( f2sd->first ));
-
- Handle(Geom_Surface) surface = BRep_Tool::Surface(F);
-
+ _SolidData& data = *f2sd->second;
+ const TopoDS_Face& F = TopoDS::Face( getMeshDS()->IndexToShape( f2sd->first ));
SMESH_subMesh* sm = _mesh->GetSubMesh( F );
SMESHDS_SubMesh* smDS = sm->GetSubMeshDS();
+ Handle(Geom_Surface) surface = BRep_Tool::Surface(F);
+
helper.SetSubShape(F);
// ===========================
}
// Find _LayerEdge's inflated along F
- vector< _LayerEdge* > lEdges;
+ lEdges.clear();
{
- SMESH_subMeshIteratorPtr subIt =
- sm->getDependsOnIterator(/*includeSelf=*/false, /*complexShapeFirst=*/false);
+ set< TGeomID > subIDs;
+ SMESH_subMeshIteratorPtr subIt = sm->getDependsOnIterator(/*includeSelf=*/false);
while ( subIt->more() )
+ subIDs.insert( subIt->next()->GetId() );
+
+ int iBeg, iEnd = 0;
+ for ( int iS = 0; iS < data._endEdgeOnShape.size() && !subIDs.empty(); ++iS )
{
- SMESH_subMesh* sub = subIt->next();
- SMESHDS_SubMesh* subDS = sub->GetSubMeshDS();
- if ( subDS->NbNodes() == 0 || !n2eMap.count( subDS->GetNodes()->next() ))
- continue;
- SMDS_NodeIteratorPtr nIt = subDS->GetNodes();
- while ( nIt->more() )
- {
- _LayerEdge* edge = n2eMap[ nIt->next() ];
- lEdges.push_back( edge );
- prepareEdgeToShrink( *edge, F, helper, smDS );
- }
+ iBeg = iEnd;
+ iEnd = data._endEdgeOnShape[ iS ];
+ TGeomID shapeID = data._edges[ iBeg ]->_nodes[0]->getshapeId();
+ set< TGeomID >::iterator idIt = subIDs.find( shapeID );
+ if ( idIt == subIDs.end() ||
+ data._edges[ iBeg ]->_sWOL.IsNull() ) continue;
+ subIDs.erase( idIt );
+
+ if ( !data._noShrinkShapes.count( shapeID ))
+ for ( ; iBeg < iEnd; ++iBeg )
+ {
+ lEdges.push_back( data._edges[ iBeg ] );
+ prepareEdgeToShrink( *data._edges[ iBeg ], F, helper, smDS );
+ }
}
}
dumpChangeNodes( f );
// Replace source nodes by target nodes in mesh faces to shrink
+ dumpFunction(SMESH_Comment("replNodesOnFace")<<f2sd->first); // debug
const SMDS_MeshNode* nodes[20];
for ( size_t i = 0; i < lEdges.size(); ++i )
{
nodes[iN] = ( n == srcNode ? tgtNode : n );
}
helper.GetMeshDS()->ChangeElementNodes( f, nodes, f->NbNodes() );
+ dumpChangeNodes( f );
}
}
// Create _SmoothNode's on face F
vector< _SmoothNode > nodesToSmooth( smoothNodes.size() );
{
+ dumpFunction(SMESH_Comment("fixUVOnFace")<<f2sd->first); // debug
const bool sortSimplices = isConcaveFace;
for ( size_t i = 0; i < smoothNodes.size(); ++i )
{
}
}
}
+ // TODO: check effect of this additional smooth
+ // additional laplacian smooth to increase allowed shrink step
+ // for ( int st = 1; st; --st )
+ // {
+ // dumpFunction(SMESH_Comment("shrinkFace")<<f2sd->first<<"_st"<<++smooStep); // debug
+ // for ( size_t i = 0; i < nodesToSmooth.size(); ++i )
+ // {
+ // nodesToSmooth[i].Smooth( badNb,surface,helper,refSign,
+ // _SmoothNode::LAPLACIAN,/*set3D=*/false);
+ // }
+ // }
} // while ( shrinked )
// No wrongly shaped faces remain; final smooth. Set node XYZ.
const SMDS_MeshNode* srcNode = edge._nodes[0];
const SMDS_MeshNode* tgtNode = edge._nodes.back();
- edge._pos.clear();
-
if ( edge._sWOL.ShapeType() == TopAbs_FACE )
{
- gp_XY srcUV = helper.GetNodeUV( F, srcNode );
- gp_XY tgtUV = helper.GetNodeUV( F, tgtNode );
+ gp_XY srcUV( edge._pos[0].X(), edge._pos[0].Y() );//helper.GetNodeUV( F, srcNode );
+ gp_XY tgtUV = edge.LastUV( F ); //helper.GetNodeUV( F, tgtNode );
gp_Vec2d uvDir( srcUV, tgtUV );
double uvLen = uvDir.Magnitude();
uvDir /= uvLen;
- edge._normal.SetCoord( uvDir.X(),uvDir.Y(), 0);
+ edge._normal.SetCoord( uvDir.X(),uvDir.Y(), 0 );
edge._len = uvLen;
- // // IMPORTANT to have src nodes NOT yet REPLACED by tgt nodes in shrinked faces
- // vector<const SMDS_MeshElement*> faces;
- // multimap< double, const SMDS_MeshNode* > proj2node;
- // SMDS_ElemIteratorPtr fIt = srcNode->GetInverseElementIterator(SMDSAbs_Face);
- // while ( fIt->more() )
- // {
- // const SMDS_MeshElement* f = fIt->next();
- // if ( faceSubMesh->Contains( f ))
- // faces.push_back( f );
- // }
- // for ( size_t i = 0; i < faces.size(); ++i )
- // {
- // const int nbNodes = faces[i]->NbCornerNodes();
- // for ( int j = 0; j < nbNodes; ++j )
- // {
- // const SMDS_MeshNode* n = faces[i]->GetNode(j);
- // if ( n == srcNode ) continue;
- // if ( n->GetPosition()->GetTypeOfPosition() != SMDS_TOP_FACE &&
- // ( faces.size() > 1 || nbNodes > 3 ))
- // continue;
- // gp_Pnt2d uv = helper.GetNodeUV( F, n );
- // gp_Vec2d uvDirN( srcUV, uv );
- // double proj = uvDirN * uvDir;
- // proj2node.insert( make_pair( proj, n ));
- // }
- // }
-
- // multimap< double, const SMDS_MeshNode* >::iterator p2n = proj2node.begin(), p2nEnd;
- // const double minProj = p2n->first;
- // const double projThreshold = 1.1 * uvLen;
- // if ( minProj > projThreshold )
- // {
- // // tgtNode is located so that it does not make faces with wrong orientation
- // return true;
- // }
edge._pos.resize(1);
edge._pos[0].SetCoord( tgtUV.X(), tgtUV.Y(), 0 );
- // store most risky nodes in _simplices
- // p2nEnd = proj2node.lower_bound( projThreshold );
- // int nbSimpl = ( std::distance( p2n, p2nEnd ) + 1) / 2;
- // edge._simplices.resize( nbSimpl );
- // for ( int i = 0; i < nbSimpl; ++i )
- // {
- // edge._simplices[i]._nPrev = p2n->second;
- // if ( ++p2n != p2nEnd )
- // edge._simplices[i]._nNext = p2n->second;
- // }
// set UV of source node to target node
SMDS_FacePosition* pos = static_cast<SMDS_FacePosition*>( tgtNode->GetPosition() );
pos->SetUParameter( srcUV.X() );
}
else // _sWOL is TopAbs_EDGE
{
- TopoDS_Edge E = TopoDS::Edge( edge._sWOL);
+ const TopoDS_Edge& E = TopoDS::Edge( edge._sWOL );
SMESHDS_SubMesh* edgeSM = getMeshDS()->MeshElements( E );
if ( !edgeSM || edgeSM->NbElements() == 0 )
return error(SMESH_Comment("Not meshed EDGE ") << getMeshDS()->ShapeToIndex( E ));
double uSrc = helper.GetNodeU( E, srcNode, n2 );
double uTgt = helper.GetNodeU( E, tgtNode, srcNode );
- double u2 = helper.GetNodeU( E, n2, srcNode );
+ double u2 = helper.GetNodeU( E, n2, srcNode );
+
+ edge._pos.clear();
if ( fabs( uSrc-uTgt ) < 0.99 * fabs( uSrc-u2 ))
{
edge._simplices.resize( 1 );
edge._simplices[0]._nPrev = n2;
- // set UV of source node to target node
+ // set U of source node to the target node
SMDS_EdgePosition* pos = static_cast<SMDS_EdgePosition*>( tgtNode->GetPosition() );
pos->SetUParameter( uSrc );
}
return true;
+}
- //================================================================================
- /*!
- * \brief Compute positions (UV) to set to a node on edge moved during shrinking
- */
- //================================================================================
-
- // Compute UV to follow during shrinking
-
-// const SMDS_MeshNode* srcNode = edge._nodes[0];
-// const SMDS_MeshNode* tgtNode = edge._nodes.back();
-
-// gp_XY srcUV = helper.GetNodeUV( F, srcNode );
-// gp_XY tgtUV = helper.GetNodeUV( F, tgtNode );
-// gp_Vec2d uvDir( srcUV, tgtUV );
-// double uvLen = uvDir.Magnitude();
-// uvDir /= uvLen;
-
-// // Select shrinking step such that not to make faces with wrong orientation.
-// // IMPORTANT to have src nodes NOT yet REPLACED by tgt nodes in shrinked faces
-// const double minStepSize = uvLen / 20;
-// double stepSize = uvLen;
-// SMDS_ElemIteratorPtr fIt = srcNode->GetInverseElementIterator(SMDSAbs_Face);
-// while ( fIt->more() )
-// {
-// const SMDS_MeshElement* f = fIt->next();
-// if ( !faceSubMesh->Contains( f )) continue;
-// const int nbNodes = f->NbCornerNodes();
-// for ( int i = 0; i < nbNodes; ++i )
-// {
-// const SMDS_MeshNode* n = f->GetNode(i);
-// if ( n->GetPosition()->GetTypeOfPosition() != SMDS_TOP_FACE || n == srcNode)
-// continue;
-// gp_XY uv = helper.GetNodeUV( F, n );
-// gp_Vec2d uvDirN( srcUV, uv );
-// double proj = uvDirN * uvDir;
-// if ( proj < stepSize && proj > minStepSize )
-// stepSize = proj;
-// }
-// }
-// stepSize *= 0.8;
-
-// const int nbSteps = ceil( uvLen / stepSize );
-// gp_XYZ srcUV0( srcUV.X(), srcUV.Y(), 0 );
-// gp_XYZ tgtUV0( tgtUV.X(), tgtUV.Y(), 0 );
-// edge._pos.resize( nbSteps );
-// edge._pos[0] = tgtUV0;
-// for ( int i = 1; i < nbSteps; ++i )
-// {
-// double r = i / double( nbSteps );
-// edge._pos[i] = (1-r) * tgtUV0 + r * srcUV0;
-// }
-// return true;
+//================================================================================
+/*!
+ * \brief Restore position of a sole node of a _LayerEdge based on _noShrinkShapes
+ */
+//================================================================================
+
+void _ViscousBuilder::restoreNoShrink( _LayerEdge& edge ) const
+{
+ if ( edge._nodes.size() == 1 )
+ {
+ edge._pos.clear();
+ edge._len = 0;
+
+ const SMDS_MeshNode* srcNode = edge._nodes[0];
+ TopoDS_Shape S = SMESH_MesherHelper::GetSubShapeByNode( srcNode, getMeshDS() );
+ if ( S.IsNull() ) return;
+
+ gp_Pnt p;
+
+ switch ( S.ShapeType() )
+ {
+ case TopAbs_EDGE:
+ {
+ double f,l;
+ TopLoc_Location loc;
+ Handle(Geom_Curve) curve = BRep_Tool::Curve( TopoDS::Edge( S ), loc, f, l );
+ if ( curve.IsNull() ) return;
+ SMDS_EdgePosition* ePos = static_cast<SMDS_EdgePosition*>( srcNode->GetPosition() );
+ p = curve->Value( ePos->GetUParameter() );
+ break;
+ }
+ case TopAbs_VERTEX:
+ {
+ p = BRep_Tool::Pnt( TopoDS::Vertex( S ));
+ break;
+ }
+ default: return;
+ }
+ getMeshDS()->MoveNode( srcNode, p.X(), p.Y(), p.Z() );
+ dumpMove( srcNode );
+ }
}
//================================================================================
SMESH::Controls::AspectRatio qualifier;
SMESH::Controls::TSequenceOfXYZ points(3), points1(3), points2(3);
const double maxAspectRatio = is2D ? 4. : 2;
- NodeCoordHelper xyz( F, helper, is2D );
+ _NodeCoordHelper xyz( F, helper, is2D );
// find bad triangles
const double kSafe = Max( 0.5, 1. - 0.1 * _simplices.size() );
// Select shrinking step such that not to make faces with wrong orientation.
- double stepSize = uvLen;
+ double stepSize = 1e100;
for ( size_t i = 0; i < _simplices.size(); ++i )
{
// find intersection of 2 lines: curUV-tgtUV and that connecting simplex nodes
stepSize = Min( step, stepSize );
}
gp_Pnt2d newUV;
- if ( uvLen - stepSize < _len / 200. )
+ if ( uvLen <= stepSize )
{
newUV = tgtUV;
_pos.clear();
}
else // _sWOL is TopAbs_EDGE
{
- TopoDS_Edge E = TopoDS::Edge( _sWOL );
- const SMDS_MeshNode* n2 = _simplices[0]._nPrev;
+ const TopoDS_Edge& E = TopoDS::Edge( _sWOL );
+ const SMDS_MeshNode* n2 = _simplices[0]._nPrev;
SMDS_EdgePosition* tgtPos = static_cast<SMDS_EdgePosition*>( tgtNode->GetPosition() );
- const double u2 = helper.GetNodeU( E, n2, tgtNode );
+ const double u2 = helper.GetNodeU( E, n2, tgtNode );
const double uSrc = _pos[0].Coord( U_SRC );
const double lenTgt = _pos[0].Coord( LEN_TGT );
{
SMESH_MesherHelper helper( *_mesh );
+ vector< const SMDS_MeshNode* > faceNodes;
+
for ( size_t i = 0; i < _sdVec.size(); ++i )
{
_SolidData& data = _sdVec[i];
for ( int iE = 1; iE <= geomEdges.Extent(); ++iE )
{
const TopoDS_Edge& E = TopoDS::Edge( geomEdges(iE));
+ if ( data._noShrinkShapes.count( getMeshDS()->ShapeToIndex( E )))
+ continue;
// Get _LayerEdge's based on E
if ( nbSharedPyram > 1 )
continue; // not free border of the pyramid
- if ( getMeshDS()->FindFace( ledges[0]->_nodes[0], ledges[0]->_nodes[1],
- ledges[1]->_nodes[0], ledges[1]->_nodes[1]))
+ faceNodes.clear();
+ faceNodes.push_back( ledges[0]->_nodes[0] );
+ faceNodes.push_back( ledges[1]->_nodes[0] );
+ if ( ledges[0]->_nodes.size() > 1 ) faceNodes.push_back( ledges[0]->_nodes[1] );
+ if ( ledges[1]->_nodes.size() > 1 ) faceNodes.push_back( ledges[1]->_nodes[1] );
+
+ if ( getMeshDS()->FindElement( faceNodes, SMDSAbs_Face, /*noMedium=*/true))
continue; // faces already created
}
for ( ++u2n; u2n != u2nodes.end(); ++u2n )
{
vector< const SMDS_MeshNode*>& nn1 = ledges[j-dj1]->_nodes;
vector< const SMDS_MeshNode*>& nn2 = ledges[j-dj2]->_nodes;
- if ( isOnFace )
- for ( size_t z = 1; z < nn1.size(); ++z )
- sm->AddElement( getMeshDS()->AddFace( nn1[z-1], nn2[z-1], nn2[z], nn1[z] ));
+ if ( nn1.size() == nn2.size() )
+ {
+ if ( isOnFace )
+ for ( size_t z = 1; z < nn1.size(); ++z )
+ sm->AddElement( getMeshDS()->AddFace( nn1[z-1], nn2[z-1], nn2[z], nn1[z] ));
+ else
+ for ( size_t z = 1; z < nn1.size(); ++z )
+ sm->AddElement( new SMDS_FaceOfNodes( nn1[z-1], nn2[z-1], nn2[z], nn1[z] ));
+ }
+ else if ( nn1.size() == 1 )
+ {
+ if ( isOnFace )
+ for ( size_t z = 1; z < nn2.size(); ++z )
+ sm->AddElement( getMeshDS()->AddFace( nn1[0], nn2[z-1], nn2[z] ));
+ else
+ for ( size_t z = 1; z < nn2.size(); ++z )
+ sm->AddElement( new SMDS_FaceOfNodes( nn1[0], nn2[z-1], nn2[z] ));
+ }
else
- for ( size_t z = 1; z < nn1.size(); ++z )
- sm->AddElement( new SMDS_FaceOfNodes( nn1[z-1], nn2[z-1], nn2[z], nn1[z]));
+ {
+ if ( isOnFace )
+ for ( size_t z = 1; z < nn1.size(); ++z )
+ sm->AddElement( getMeshDS()->AddFace( nn1[z-1], nn2[0], nn1[z] ));
+ else
+ for ( size_t z = 1; z < nn1.size(); ++z )
+ sm->AddElement( new SMDS_FaceOfNodes( nn1[z-1], nn2[0], nn2[z] ));
+ }
}
// Make edges
if ( !edge->_sWOL.IsNull() && edge->_sWOL.ShapeType() == TopAbs_EDGE )
{
vector< const SMDS_MeshNode*>& nn = edge->_nodes;
- if ( nn[1]->GetInverseElementIterator( SMDSAbs_Edge )->more() )
+ if ( nn.size() < 2 || nn[1]->GetInverseElementIterator( SMDSAbs_Edge )->more() )
continue;
helper.SetSubShape( edge->_sWOL );
helper.SetElementsOnShape( true );
#include "SMESH_Hypothesis.hxx"
#include "SMESH_ProxyMesh.hxx"
+#include "SMESH_ComputeError.hxx"
#include <vector>
public:
StdMeshers_ViscousLayers(int hypId, int studyId, SMESH_Gen* gen);
- // Set boundary shapes, faces in 3D, edges in 2D, either to exclude from
+ // Set boundary shapes (faces in 3D, edges in 2D) either to exclude from
// treatment or to make the Viscous Layers on
void SetBndShapes(const std::vector<int>& shapeIds, bool toIgnore);
std::vector<int> GetBndShapes() const { return _shapeIds; }
const TopoDS_Shape& theShape,
const bool toMakeN2NMap=false) const;
+ // Checks compatibility of assigned StdMeshers_ViscousLayers hypotheses
+ static SMESH_ComputeErrorPtr
+ CheckHypothesis(SMESH_Mesh& aMesh,
+ const TopoDS_Shape& aShape,
+ SMESH_Hypothesis::Hypothesis_Status& aStatus);
+
+ // Checks if viscous layers should be constructed on a shape
+ bool IsShapeWithLayers(int shapeIndex) const;
+
virtual std::ostream & SaveTo(std::ostream & save);
virtual std::istream & LoadFrom(std::istream & load);
_PolyLine* _rightLine;
int _firstPntInd; // index in vector<UVPtStruct> of _wire
int _lastPntInd;
+ int _index; // index in _ViscousBuilder2D::_polyLineVec
vector< _LayerEdge > _lEdges; /* _lEdges[0] is usually is not treated
as it is equal to the last one of the _leftLine */
//--------------------------------------------------------------------------------
typedef map< const SMDS_MeshNode*, _LayerEdge*, TIDCompare > TNode2Edge;
+ typedef StdMeshers_ViscousLayers2D THypVL;
//--------------------------------------------------------------------------------
/*!
public:
_ViscousBuilder2D(SMESH_Mesh& theMesh,
const TopoDS_Face& theFace,
- const StdMeshers_ViscousLayers2D* theHyp);
+ vector< const THypVL* > & theHyp,
+ vector< TopoDS_Shape > & theHypShapes);
SMESH_ComputeErrorPtr GetError() const { return _error; }
// does it's job
- SMESH_ProxyMesh::Ptr Compute(const TopoDS_Shape& theShapeHypAssignedTo);
+ SMESH_ProxyMesh::Ptr Compute();
private:
- bool findEdgesWithLayers(const TopoDS_Shape& theShapeHypAssignedTo);
+ friend class ::StdMeshers_ViscousLayers2D;
+
+ bool findEdgesWithLayers();
bool makePolyLines();
bool inflate();
bool fixCollisions();
GeomAPI_ProjectPointOnSurf* faceProj);
void adjustCommonEdge( _PolyLine& LL, _PolyLine& LR );
void calcLayersHeight(const double totalThick,
- vector<double>& heights);
+ vector<double>& heights,
+ const THypVL* hyp);
bool removeMeshFaces(const TopoDS_Shape& face);
+ const THypVL* getLineHypothesis(int iPL);
+ double getLineThickness (int iPL);
+
bool error( const string& text );
SMESHDS_Mesh* getMeshDS() { return _mesh->GetMeshDS(); }
_ProxyMeshOfFace* getProxyMesh();
// input data
SMESH_Mesh* _mesh;
TopoDS_Face _face;
- const StdMeshers_ViscousLayers2D* _hyp;
+ vector< const THypVL* > _hyps;
+ vector< TopoDS_Shape > _hypShapes;
// result data
SMESH_ProxyMesh::Ptr _proxyMesh;
SMESH_MesherHelper _helper;
TSideVector _faceSideVec; // wires (StdMeshers_FaceSide) of _face
vector<_PolyLine> _polyLineVec; // fronts to advance
+ vector< const THypVL* > _hypOfEdge; // a hyp per an EDGE of _faceSideVec
bool _is2DIsotropic; // is same U and V resoulution of _face
vector<TopoDS_Face> _clearedFaces; // FACEs whose mesh was removed by shrink()
- double _fPowN; // to compute thickness of layers
- double _thickness; // required or possible layers thickness
+ //double _fPowN; // to compute thickness of layers
+ double _maxThickness; // max possible layers thickness
// sub-shapes of _face
set<TGeomID> _ignoreShapeIds; // ids of EDGEs w/o layers
/*!
* \brief Returns StdMeshers_ViscousLayers2D for the FACE
*/
- const StdMeshers_ViscousLayers2D* findHyp(SMESH_Mesh& theMesh,
- const TopoDS_Face& theFace,
- TopoDS_Shape* assignedTo=0)
+ bool findHyps(SMESH_Mesh& theMesh,
+ const TopoDS_Face& theFace,
+ vector< const StdMeshers_ViscousLayers2D* > & theHyps,
+ vector< TopoDS_Shape > & theAssignedTo)
{
+ theHyps.clear();
+ theAssignedTo.clear();
SMESH_HypoFilter hypFilter
( SMESH_HypoFilter::HasName( StdMeshers_ViscousLayers2D::GetHypType() ));
- const SMESH_Hypothesis * hyp =
- theMesh.GetHypothesis( theFace, hypFilter, /*ancestors=*/true, assignedTo );
- return dynamic_cast< const StdMeshers_ViscousLayers2D* > ( hyp );
+ list< const SMESHDS_Hypothesis * > hypList;
+ list< TopoDS_Shape > hypShapes;
+ int nbHyps = theMesh.GetHypotheses
+ ( theFace, hypFilter, hypList, /*ancestors=*/true, &hypShapes );
+ if ( nbHyps )
+ {
+ theHyps.reserve( nbHyps );
+ theAssignedTo.reserve( nbHyps );
+ list< const SMESHDS_Hypothesis * >::iterator hyp = hypList.begin();
+ list< TopoDS_Shape >::iterator shape = hypShapes.begin();
+ for ( ; hyp != hypList.end(); ++hyp, ++shape )
+ {
+ theHyps.push_back( static_cast< const StdMeshers_ViscousLayers2D* > ( *hyp ));
+ theAssignedTo.push_back( *shape );
+ }
+ }
+ return nbHyps;
}
//================================================================================
const SMESHDS_Mesh* theMesh,
set< int > & theEdgeIds)
{
- int nbToEdgesIgnore = 0;
+ int nbEdgesToIgnore = 0;
vector<TGeomID> ids = theHyp->GetBndShapes();
if ( theHyp->IsToIgnoreShapes() ) // EDGEs to ignore are given
{
SMESH_MesherHelper::IsSubShape( E, theFace ))
{
theEdgeIds.insert( ids[i] );
- ++nbToEdgesIgnore;
+ ++nbEdgesToIgnore;
}
}
}
else // EDGEs to make the Viscous Layers on are given
{
TopExp_Explorer E( theFace, TopAbs_EDGE );
- for ( ; E.More(); E.Next(), ++nbToEdgesIgnore )
+ for ( ; E.More(); E.Next(), ++nbEdgesToIgnore )
theEdgeIds.insert( theMesh->ShapeToIndex( E.Current() ));
for ( size_t i = 0; i < ids.size(); ++i )
- nbToEdgesIgnore -= theEdgeIds.erase( ids[i] );
+ nbEdgesToIgnore -= theEdgeIds.erase( ids[i] );
}
- return nbToEdgesIgnore;
+ return nbEdgesToIgnore;
}
} // namespace VISCOUS_2D
{
SMESH_ProxyMesh::Ptr pm;
- TopoDS_Shape hypAssignedTo;
- const StdMeshers_ViscousLayers2D* vlHyp = VISCOUS_2D::findHyp( theMesh, theFace, &hypAssignedTo );
- if ( vlHyp )
+ vector< const StdMeshers_ViscousLayers2D* > hyps;
+ vector< TopoDS_Shape > hypShapes;
+ if ( VISCOUS_2D::findHyps( theMesh, theFace, hyps, hypShapes ))
{
- VISCOUS_2D::_ViscousBuilder2D builder( theMesh, theFace, vlHyp );
- pm = builder.Compute( hypAssignedTo );
+ VISCOUS_2D::_ViscousBuilder2D builder( theMesh, theFace, hyps, hypShapes );
+ pm = builder.Compute();
SMESH_ComputeErrorPtr error = builder.GetError();
if ( error && !error->IsOK() )
theMesh.GetSubMesh( theFace )->GetComputeError() = error;
return pm;
}
// --------------------------------------------------------------------------------
+SMESH_ComputeErrorPtr
+StdMeshers_ViscousLayers2D::CheckHypothesis(SMESH_Mesh& theMesh,
+ const TopoDS_Shape& theShape,
+ SMESH_Hypothesis::Hypothesis_Status& theStatus)
+{
+ SMESH_ComputeErrorPtr error = SMESH_ComputeError::New(COMPERR_OK);
+ theStatus = SMESH_Hypothesis::HYP_OK;
+
+ TopExp_Explorer exp( theShape, TopAbs_FACE );
+ for ( ; exp.More() && theStatus == SMESH_Hypothesis::HYP_OK; exp.Next() )
+ {
+ const TopoDS_Face& face = TopoDS::Face( exp.Current() );
+ vector< const StdMeshers_ViscousLayers2D* > hyps;
+ vector< TopoDS_Shape > hypShapes;
+ if ( VISCOUS_2D::findHyps( theMesh, face, hyps, hypShapes ))
+ {
+ VISCOUS_2D::_ViscousBuilder2D builder( theMesh, face, hyps, hypShapes );
+ builder._faceSideVec =
+ StdMeshers_FaceSide::GetFaceWires( face, theMesh, true, error,
+ SMESH_ProxyMesh::Ptr(),
+ /*theCheckVertexNodes=*/false);
+ if ( error->IsOK() && !builder.findEdgesWithLayers())
+ {
+ error = builder.GetError();
+ if ( error && !error->IsOK() )
+ theStatus = SMESH_Hypothesis::HYP_INCOMPAT_HYPS;
+ }
+ }
+ }
+ return error;
+}
+// --------------------------------------------------------------------------------
void StdMeshers_ViscousLayers2D::RestoreListeners() const
{
StudyContextStruct* sc = _gen->GetStudyContext( _studyId );
*/
//================================================================================
-_ViscousBuilder2D::_ViscousBuilder2D(SMESH_Mesh& theMesh,
- const TopoDS_Face& theFace,
- const StdMeshers_ViscousLayers2D* theHyp):
- _mesh( &theMesh ), _face( theFace ), _hyp( theHyp ), _helper( theMesh )
+_ViscousBuilder2D::_ViscousBuilder2D(SMESH_Mesh& theMesh,
+ const TopoDS_Face& theFace,
+ vector< const THypVL* > & theHyps,
+ vector< TopoDS_Shape > & theAssignedTo):
+ _mesh( &theMesh ), _face( theFace ), _helper( theMesh )
{
+ _hyps.swap( theHyps );
+ _hypShapes.swap( theAssignedTo );
+
_helper.SetSubShape( _face );
_helper.SetElementsOnShape( true );
_face.Orientation( TopAbs_FORWARD ); // 2D logic works only in this case
_surface = BRep_Tool::Surface( _face );
- if ( _hyp )
- _fPowN = pow( _hyp->GetStretchFactor(), _hyp->GetNumberLayers() );
+ _error = SMESH_ComputeError::New(COMPERR_OK);
_nbLE = 0;
}
*/
//================================================================================
-SMESH_ProxyMesh::Ptr _ViscousBuilder2D::Compute(const TopoDS_Shape& theShapeHypAssignedTo)
+SMESH_ProxyMesh::Ptr _ViscousBuilder2D::Compute()
{
- _error = SMESH_ComputeError::New(COMPERR_OK);
- _faceSideVec = StdMeshers_FaceSide::GetFaceWires( _face, *_mesh, true, _error );
+ _faceSideVec = StdMeshers_FaceSide::GetFaceWires( _face, *_mesh, true, _error);
+
if ( !_error->IsOK() )
return _proxyMesh;
- if ( !findEdgesWithLayers(theShapeHypAssignedTo) ) // analysis of a shape
+ if ( !findEdgesWithLayers() ) // analysis of a shape
return _proxyMesh;
if ( ! makePolyLines() ) // creation of fronts
*/
//================================================================================
-bool _ViscousBuilder2D::findEdgesWithLayers(const TopoDS_Shape& theShapeHypAssignedTo)
+bool _ViscousBuilder2D::findEdgesWithLayers()
{
- // collect all EDGEs to ignore defined by hyp
- int nbMyEdgesIgnored = getEdgesToIgnore( _hyp, _face, getMeshDS(), _ignoreShapeIds );
+ // collect all EDGEs to ignore defined by _hyps
+ typedef std::pair< set<TGeomID>, const THypVL* > TEdgesOfHyp;
+ vector< TEdgesOfHyp > ignoreEdgesOfHyp( _hyps.size() );
+ for ( size_t i = 0; i < _hyps.size(); ++i )
+ {
+ ignoreEdgesOfHyp[i].second = _hyps[i];
+ getEdgesToIgnore( _hyps[i], _face, getMeshDS(), ignoreEdgesOfHyp[i].first );
+ }
// get all shared EDGEs
TopTools_MapOfShape sharedEdges;
+ TopTools_IndexedMapOfShape hypFaces; // faces with VL hyps
+ for ( size_t i = 0; i < _hypShapes.size(); ++i )
+ TopExp::MapShapes( _hypShapes[i], TopAbs_FACE, hypFaces );
TopTools_IndexedDataMapOfShapeListOfShape facesOfEdgeMap;
- TopExp::MapShapesAndAncestors( theShapeHypAssignedTo,
- TopAbs_EDGE, TopAbs_FACE, facesOfEdgeMap);
+ for ( int iF = 1; iF <= hypFaces.Extent(); ++iF )
+ TopExp::MapShapesAndAncestors( hypFaces(iF), TopAbs_EDGE, TopAbs_FACE, facesOfEdgeMap);
for ( int iE = 1; iE <= facesOfEdgeMap.Extent(); ++iE )
if ( facesOfEdgeMap( iE ).Extent() > 1 )
sharedEdges.Add( facesOfEdgeMap.FindKey( iE ));
- // check all EDGEs of the _face
+ // fill _hypOfEdge
+ if ( _hyps.size() > 1 )
+ {
+ // check if two hypotheses define different parameters for the same EDGE
+ for ( size_t iWire = 0; iWire < _faceSideVec.size(); ++iWire )
+ {
+ StdMeshers_FaceSidePtr wire = _faceSideVec[ iWire ];
+ for ( int iE = 0; iE < wire->NbEdges(); ++iE )
+ {
+ const THypVL* hyp = 0;
+ const TGeomID edgeID = wire->EdgeID( iE );
+ if ( !sharedEdges.Contains( wire->Edge( iE )))
+ {
+ for ( size_t i = 0; i < ignoreEdgesOfHyp.size(); ++i )
+ if ( ! ignoreEdgesOfHyp[i].first.count( edgeID ))
+ {
+ if ( hyp )
+ return error(SMESH_Comment("Several hypotheses define "
+ "Viscous Layers on the edge #") << edgeID );
+ hyp = ignoreEdgesOfHyp[i].second;
+ }
+ }
+ _hypOfEdge.push_back( hyp );
+ if ( !hyp )
+ _ignoreShapeIds.insert( edgeID );
+ }
+ // check if two hypotheses define different number of viscous layers for
+ // adjacent EDGEs
+ const THypVL *hyp, *prevHyp = _hypOfEdge.back();
+ size_t iH = _hypOfEdge.size() - wire->NbEdges();
+ for ( ; iH < _hypOfEdge.size(); ++iH )
+ {
+ hyp = _hypOfEdge[ iH ];
+ if ( hyp && prevHyp &&
+ hyp->GetNumberLayers() != prevHyp->GetNumberLayers() )
+ {
+ return error("Two hypotheses define different number of "
+ "viscous layers on adjacent edges");
+ }
+ prevHyp = hyp;
+ }
+ }
+ }
+ else if ( _hyps.size() == 1 )
+ {
+ _ignoreShapeIds.swap( ignoreEdgesOfHyp[0].first );
+ }
+
+ // check all EDGEs of the _face to fill _ignoreShapeIds and _noShrinkVert
+
int totalNbEdges = 0;
for ( size_t iWire = 0; iWire < _faceSideVec.size(); ++iWire )
{
for ( ; hyp != allHyps.end() && !viscHyp; ++hyp )
viscHyp = dynamic_cast<const StdMeshers_ViscousLayers2D*>( *hyp );
- set<TGeomID> neighbourIgnoreEdges;
- if (viscHyp)
- getEdgesToIgnore( viscHyp, neighbourFace, getMeshDS(), neighbourIgnoreEdges );
+ // set<TGeomID> neighbourIgnoreEdges;
+ // if (viscHyp)
+ // getEdgesToIgnore( viscHyp, neighbourFace, getMeshDS(), neighbourIgnoreEdges );
for ( int iV = 0; iV < 2; ++iV )
{
PShapeIteratorPtr edgeIt = _helper.GetAncestors( vertex, *_mesh, TopAbs_EDGE );
while ( const TopoDS_Shape* edge = edgeIt->next() )
if ( !edge->IsSame( wire->Edge( iE )) &&
- _helper.IsSubShape( *edge, neighbourFace ) &&
- ( neighbourIgnoreEdges.count( getMeshDS()->ShapeToIndex( *edge )) ||
- sharedEdges.Contains( *edge )))
+ _helper.IsSubShape( *edge, neighbourFace ))
{
- _noShrinkVert.insert( getMeshDS()->ShapeToIndex( vertex ));
- break;
+ const TGeomID neighbourID = getMeshDS()->ShapeToIndex( *edge );
+ bool hasVL = !sharedEdges.Contains( *edge );
+ if ( hasVL )
+ {
+ hasVL = false;
+ for ( hyp = allHyps.begin(); hyp != allHyps.end() && !hasVL; ++hyp )
+ if ( viscHyp = dynamic_cast<const THypVL*>( *hyp ))
+ hasVL = viscHyp->IsShapeWithLayers( neighbourID );
+ }
+ if ( !hasVL )
+ {
+ _noShrinkVert.insert( getMeshDS()->ShapeToIndex( vertex ));
+ break;
+ }
}
}
}
}
}
+ int nbMyEdgesIgnored = _ignoreShapeIds.size();
+
// add VERTEXes w/o layers to _ignoreShapeIds (this is used by toShrinkForAdjacent())
- for ( size_t iWire = 0; iWire < _faceSideVec.size(); ++iWire )
- {
- StdMeshers_FaceSidePtr wire = _faceSideVec[ iWire ];
- for ( int iE = 0; iE < wire->NbEdges(); ++iE )
- {
- TGeomID edge1 = wire->EdgeID( iE );
- TGeomID edge2 = wire->EdgeID( iE+1 );
- if ( _ignoreShapeIds.count( edge1 ) && _ignoreShapeIds.count( edge2 ))
- _ignoreShapeIds.insert( getMeshDS()->ShapeToIndex( wire->LastVertex( iE )));
- }
- }
+ // for ( size_t iWire = 0; iWire < _faceSideVec.size(); ++iWire )
+ // {
+ // StdMeshers_FaceSidePtr wire = _faceSideVec[ iWire ];
+ // for ( int iE = 0; iE < wire->NbEdges(); ++iE )
+ // {
+ // TGeomID edge1 = wire->EdgeID( iE );
+ // TGeomID edge2 = wire->EdgeID( iE+1 );
+ // if ( _ignoreShapeIds.count( edge1 ) && _ignoreShapeIds.count( edge2 ))
+ // _ignoreShapeIds.insert( getMeshDS()->ShapeToIndex( wire->LastVertex( iE )));
+ // }
+ // }
return ( nbMyEdgesIgnored < totalNbEdges );
}
for ( int iE = 0; iE < wire->NbEdges(); ++iE )
{
_PolyLine& L = _polyLineVec[ iPoLine++ ];
+ L._index = iPoLine-1;
L._wire = wire.get();
L._edgeInd = iE;
L._advancable = !_ignoreShapeIds.count( wire->EdgeID( iE ));
// Evaluate max possible _thickness if required layers thickness seems too high
// ----------------------------------------------------------------------------
- _thickness = _hyp->GetTotalThickness();
+ _maxThickness = _hyps[0]->GetTotalThickness();
+ for ( size_t iH = 1; iH < _hyps.size(); ++iH )
+ _maxThickness = Max( _maxThickness, _hyps[iH]->GetTotalThickness() );
+
_SegmentTree::box_type faceBndBox2D;
for ( iPoLine = 0; iPoLine < _polyLineVec.size(); ++iPoLine )
faceBndBox2D.Add( *_polyLineVec[ iPoLine]._segTree->getBox() );
- double boxTol = 1e-3 * sqrt( faceBndBox2D.SquareExtent() );
- //
- if ( _thickness * maxLen2dTo3dRatio > sqrt( faceBndBox2D.SquareExtent() ) / 10 )
+ const double boxTol = 1e-3 * sqrt( faceBndBox2D.SquareExtent() );
+
+ if ( _maxThickness * maxLen2dTo3dRatio > sqrt( faceBndBox2D.SquareExtent() ) / 10 )
{
vector< const _Segment* > foundSegs;
double maxPossibleThick = 0;
}
}
if ( maxPossibleThick > 0. )
- _thickness = Min( _hyp->GetTotalThickness(), maxPossibleThick );
+ _maxThickness = Min( _maxThickness, maxPossibleThick );
}
// Adjust _LayerEdge's at _PolyLine's extremities
for ( iPoLine = 0; iPoLine < _polyLineVec.size(); ++iPoLine )
{
lineBoxes[ iPoLine ] = *_polyLineVec[ iPoLine ]._segTree->getBox();
- lineBoxes[ iPoLine ].Enlarge( maxLen2dTo3dRatio * _thickness *
+ lineBoxes[ iPoLine ].Enlarge( maxLen2dTo3dRatio * getLineThickness( iPoLine ) *
( _polyLineVec[ iPoLine ]._advancable ? 2. : 1.2 ));
}
// _reachableLines
for ( iPoLine = 0; iPoLine < _polyLineVec.size(); ++iPoLine )
{
_PolyLine& L1 = _polyLineVec[ iPoLine ];
+ const double thick1 = getLineThickness( iPoLine );
for ( size_t iL2 = 0; iL2 < _polyLineVec.size(); ++iL2 )
{
_PolyLine& L2 = _polyLineVec[ iL2 ];
{
_LayerEdge& LE = L1._lEdges[iLE];
if ( !lineBoxes[ iL2 ].IsOut ( LE._uvOut,
- LE._uvOut + LE._normal2D *_thickness * LE._len2dTo3dRatio ))
+ LE._uvOut + LE._normal2D * thick1 * LE._len2dTo3dRatio ))
{
L1._reachableLines.push_back( & L2 );
break;
// Remove _LayerEdge's intersecting the normAvg to avoid collisions
// during inflate().
//
- // find max length of the VERTEX based _LayerEdge whose direction is normAvg
- double maxLen2D = _thickness * EL._len2dTo3dRatio;
- const gp_XY& pCommOut = ER._uvOut;
- gp_XY pCommIn = pCommOut + normAvg * maxLen2D;
+ // find max length of the VERTEX-based _LayerEdge whose direction is normAvg
+ double maxLen2D = _maxThickness * EL._len2dTo3dRatio;
+ const gp_XY& pCommOut = ER._uvOut;
+ gp_XY pCommIn = pCommOut + normAvg * maxLen2D;
_Segment segCommon( pCommOut, pCommIn );
_SegmentIntersection intersection;
vector< const _Segment* > foundSegs;
_SegmentIntersection lastIntersection;
for ( ; iLE < L._lEdges.size(); ++iLE, eIt += dIt )
{
- gp_XY uvIn = eIt->_uvOut + eIt->_normal2D * _thickness * eIt->_len2dTo3dRatio;
+ gp_XY uvIn = eIt->_uvOut + eIt->_normal2D * _maxThickness * eIt->_len2dTo3dRatio;
_Segment segOfEdge( eIt->_uvOut, uvIn );
if ( !intersection.Compute( segCommon, segOfEdge ))
break;
gp_Vec faceNorm = du ^ dv;
gp_Vec normal = faceNorm ^ tangent;
normal.Normalize();
- p = pOut.XYZ() + normal.XYZ() * /*1e-2 * */_hyp->GetTotalThickness() / _hyp->GetNumberLayers();
+ p = pOut.XYZ() + normal.XYZ() * /*1e-2 * */_hyps[0]->GetTotalThickness() / _hyps[0]->GetNumberLayers();
faceProj->Perform( p );
if ( !faceProj->IsDone() || faceProj->NbPoints() < 1 )
return setLayerEdgeData( lEdge, u, pcurve, curve, p, reverse, NULL );
{
// Limit size of inflation step by geometry size found by
// itersecting _LayerEdge's with _Segment's
- double minSize = _thickness, maxSize = 0;
+ double minSize = _maxThickness, maxSize = 0;
vector< const _Segment* > foundSegs;
_SegmentIntersection intersection;
for ( size_t iL1 = 0; iL1 < _polyLineVec.size(); ++iL1 )
}
}
if ( minSize > maxSize ) // no collisions possible
- maxSize = _thickness;
+ maxSize = _maxThickness;
#ifdef __myDEBUG
cout << "-- minSize = " << minSize << ", maxSize = " << maxSize << endl;
#endif
double curThick = 0, stepSize = minSize;
int nbSteps = 0;
- if ( maxSize > _thickness )
- maxSize = _thickness;
+ if ( maxSize > _maxThickness )
+ maxSize = _maxThickness;
while ( curThick < maxSize )
{
curThick += stepSize * 1.25;
- if ( curThick > _thickness )
- curThick = _thickness;
+ if ( curThick > _maxThickness )
+ curThick = _maxThickness;
// Elongate _LayerEdge's
for ( size_t iL = 0; iL < _polyLineVec.size(); ++iL )
{
_PolyLine& L = _polyLineVec[ iL ];
if ( !L._advancable ) continue;
+ const double lineThick = Min( curThick, getLineThickness( iL ));
bool lenChange = false;
for ( size_t iLE = L.FirstLEdge(); iLE < L._lEdges.size(); ++iLE )
- lenChange |= L._lEdges[iLE].SetNewLength( curThick );
+ lenChange |= L._lEdges[iLE].SetNewLength( lineThick );
// for ( int k=0; k<L._segments.size(); ++k)
// cout << "( " << L._segments[k].p1().X() << ", " <<L._segments[k].p1().Y() << " ) "
// << "( " << L._segments[k].p2().X() << ", " <<L._segments[k].p2().Y() << " ) "
{
break; // no more inflating possible
}
- stepSize = Max( stepSize , _thickness / 10. );
+ stepSize = Max( stepSize , _maxThickness / 10. );
nbSteps++;
}
int iPFrom = L._firstPntInd, iPTo = L._lastPntInd;
if ( isShrinkableL )
{
+ const THypVL* hyp = getLineHypothesis( L._leftLine->_index );
vector<gp_XY>& uvVec = L._lEdges.front()._uvRefined;
- for ( int i = 0; i < _hyp->GetNumberLayers(); ++i ) {
+ for ( int i = 0; i < hyp->GetNumberLayers(); ++i ) {
const UVPtStruct& uvPt = points[ iPFrom + i + 1 ];
L._leftNodes.push_back( uvPt.node );
uvVec.push_back ( pcurve->Value( uvPt.param ).XY() );
}
+ iPFrom += hyp->GetNumberLayers();
}
if ( isShrinkableR )
{
+ const THypVL* hyp = getLineHypothesis( L._rightLine->_index );
vector<gp_XY>& uvVec = L._lEdges.back()._uvRefined;
- for ( int i = 0; i < _hyp->GetNumberLayers(); ++i ) {
+ for ( int i = 0; i < hyp->GetNumberLayers(); ++i ) {
const UVPtStruct& uvPt = points[ iPTo - i - 1 ];
L._rightNodes.push_back( uvPt.node );
uvVec.push_back ( pcurve->Value( uvPt.param ).XY() );
}
+ iPTo -= hyp->GetNumberLayers();
}
// make proxy sub-mesh data of present nodes
//
- if ( isShrinkableL ) iPFrom += _hyp->GetNumberLayers();
- if ( isShrinkableR ) iPTo -= _hyp->GetNumberLayers();
UVPtStructVec nodeDataVec( & points[ iPFrom ], & points[ iPTo + 1 ]);
double normSize = nodeDataVec.back().normParam - nodeDataVec.front().normParam;
myEdgeSM->SetUVPtStructVec( nodeDataVec );
existingNodesFound = true;
+ break;
}
} // loop on FACEs sharing E
+ // Commented as a case with a seam EDGE (issue 0052461) is hard to support
+ // because SMESH_ProxyMesh can't hold different sub-meshes for two
+ // 2D representations of the seam. But such a case is not a real practice one.
+ // Check if L is an already shrinked seam
+ // if ( adjFace.IsNull() && _helper.IsRealSeam( edgeID ))
+ // {
+ // for ( int iL2 = iL1-1; iL2 > -1; --iL2 )
+ // {
+ // _PolyLine& L2 = _polyLineVec[ iL2 ];
+ // if ( edgeID == L2._wire->EdgeID( L2._edgeInd ))
+ // {
+ // // copy layer nodes
+ // const int seamPar = _helper.GetPeriodicIndex();
+ // vector<gp_XY>& uvVec = L._lEdges.front()._uvRefined;
+ // if ( isShrinkableL )
+ // {
+ // L._leftNodes = L2._rightNodes;
+ // uvVec = L2._lEdges.back()._uvRefined;
+ // }
+ // if ( isShrinkableR )
+ // {
+ // L._rightNodes = L2._leftNodes;
+ // uvVec = L2._lEdges.front()._uvRefined;
+ // }
+ // for ( size_t i = 0; i < uvVec.size(); ++i )
+ // {
+ // gp_XY & uv = uvVec[i];
+ // uv.SetCoord( seamPar, _helper.GetOtherParam( uv.Coord( seamPar )));
+ // }
+
+ // existingNodesFound = true;
+ // break;
+ // }
+ // }
+ // }
+
if ( existingNodesFound )
continue; // nothing more to do in this case
( isR ? L._leftLine->_lEdges.back() : L._rightLine->_lEdges.front() );
length2D = neighborLE._length2D;
if ( length2D == 0 )
- length2D = _thickness * nearLE._len2dTo3dRatio;
+ length2D = _maxThickness * nearLE._len2dTo3dRatio;
}
}
// move u to the internal boundary of layers
// u --> u
// x-x-x-x-----x-----x----
- double maxLen3D = Min( _thickness, edgeLen / ( 1 + nbAdvancable ));
+ double maxLen3D = Min( _maxThickness, edgeLen / ( 1 + nbAdvancable ));
double maxLen2D = maxLen3D * nearLE._len2dTo3dRatio;
if ( !length2D ) length2D = length1D / len1dTo2dRatio;
if ( Abs( length2D ) > maxLen2D )
// compute params of layers on L
vector<double> heights;
- calcLayersHeight( u - u0, heights );
+ const THypVL* hyp = getLineHypothesis( L2->_index );
+ calcLayersHeight( u - u0, heights, hyp );
//
vector< double > params( heights.size() );
for ( size_t i = 0; i < params.size(); ++i )
// x-x-x-x---
vector< const SMDS_MeshNode* >& layersNode = isR ? L._rightNodes : L._leftNodes;
vector<gp_XY>& nodeUV = ( isR ? L._lEdges.back() : L._lEdges[0] )._uvRefined;
- nodeUV.resize ( _hyp->GetNumberLayers() );
- layersNode.resize( _hyp->GetNumberLayers() );
+ nodeUV.resize ( hyp->GetNumberLayers() );
+ layersNode.resize( hyp->GetNumberLayers() );
const SMDS_MeshNode* vertexNode = nodeDataVec[ iPEnd ].node;
const SMDS_MeshNode * prevNode = vertexNode;
for ( size_t i = 0; i < params.size(); ++i )
{
- gp_Pnt p = curve.Value( params[i] );
+ const gp_Pnt p = curve.Value( params[i] );
layersNode[ i ] = helper.AddNode( p.X(), p.Y(), p.Z(), /*id=*/0, params[i] );
nodeUV [ i ] = pcurve->Value( params[i] ).XY();
helper.AddEdge( prevNode, layersNode[ i ] );
if ( !L2->_advancable )
{
isRShrinkedForAdjacent = isR;
- nodeDataForAdjacent.resize( _hyp->GetNumberLayers() );
+ nodeDataForAdjacent.resize( hyp->GetNumberLayers() );
size_t iFrw = 0, iRev = nodeDataForAdjacent.size()-1, *i = isR ? &iRev : &iFrw;
nodeDataForAdjacent[ *i ] = points[ isR ? L._lastPntInd : L._firstPntInd ];
{
// refine the not shared _LayerEdge
vector<double> layersHeight;
- calcLayersHeight( LE2._length2D, layersHeight );
+ calcLayersHeight( LE2._length2D, layersHeight, getLineHypothesis( L2._index ));
vector<gp_XY>& nodeUV2 = LE2._uvRefined;
- nodeUV2.resize ( _hyp->GetNumberLayers() );
- layerNodes2.resize( _hyp->GetNumberLayers() );
+ nodeUV2.resize ( layersHeight.size() );
+ layerNodes2.resize( layersHeight.size() );
for ( size_t i = 0; i < layersHeight.size(); ++i )
{
gp_XY uv = LE2._uvOut + LE2._normal2D * layersHeight[i];
const TopoDS_Edge& E,
const TopoDS_Vertex& V)
{
- if ( _noShrinkVert.count( getMeshDS()->ShapeToIndex( V )))
+ if ( _noShrinkVert.count( getMeshDS()->ShapeToIndex( V )) || adjFace.IsNull() )
return false;
- TopoDS_Shape hypAssignedTo;
- if ( const StdMeshers_ViscousLayers2D* vlHyp = findHyp( *_mesh, adjFace, &hypAssignedTo ))
+ vector< const StdMeshers_ViscousLayers2D* > hyps;
+ vector< TopoDS_Shape > hypShapes;
+ if ( VISCOUS_2D::findHyps( *_mesh, adjFace, hyps, hypShapes ))
{
- VISCOUS_2D::_ViscousBuilder2D builder( *_mesh, adjFace, vlHyp );
+ VISCOUS_2D::_ViscousBuilder2D builder( *_mesh, adjFace, hyps, hypShapes );
builder._faceSideVec = StdMeshers_FaceSide::GetFaceWires( adjFace, *_mesh, true, _error );
- builder.findEdgesWithLayers( hypAssignedTo );
+ builder.findEdgesWithLayers();
PShapeIteratorPtr edgeIt = _helper.GetAncestors( V, *_mesh, TopAbs_EDGE );
while ( const TopoDS_Shape* edgeAtV = edgeIt->next() )
}
// limit length of neighbour _LayerEdge's to avoid sharp change of layers thickness
+
vector< double > segLen( L._lEdges.size() );
segLen[0] = 0.0;
- for ( size_t i = 1; i < segLen.size(); ++i )
- {
- // accumulate length of segments
- double sLen = (L._lEdges[i-1]._uvOut - L._lEdges[i]._uvOut ).Modulus();
- segLen[i] = segLen[i-1] + sLen;
- }
- for ( int isR = 0; isR < 2; ++isR )
+
+ // check if length modification is usefull: look for _LayerEdge's
+ // with length limited due to collisions
+ bool lenLimited = false;
+ for ( size_t iLE = 1; ( iLE < L._lEdges.size()-1 && !lenLimited ); ++iLE )
+ lenLimited = L._lEdges[ iLE ]._isBlocked;
+
+ if ( lenLimited )
{
- size_t iF = 0, iL = L._lEdges.size()-1;
- size_t *i = isR ? &iL : &iF;
- _LayerEdge* prevLE = & L._lEdges[ *i ];
- double weight = 0;
- for ( ++iF, --iL; iF < L._lEdges.size()-1; ++iF, --iL )
+ for ( size_t i = 1; i < segLen.size(); ++i )
+ {
+ // accumulate length of segments
+ double sLen = (L._lEdges[i-1]._uvOut - L._lEdges[i]._uvOut ).Modulus();
+ segLen[i] = segLen[i-1] + sLen;
+ }
+ const double totSegLen = segLen.back();
+ // normalize the accumulated length
+ for ( size_t iS = 1; iS < segLen.size(); ++iS )
+ segLen[iS] /= totSegLen;
+
+ for ( int isR = 0; isR < 2; ++isR )
{
- _LayerEdge& LE = L._lEdges[*i];
- if ( prevLE->_length2D > 0 )
+ size_t iF = 0, iL = L._lEdges.size()-1;
+ size_t *i = isR ? &iL : &iF;
+ _LayerEdge* prevLE = & L._lEdges[ *i ];
+ double weight = 0;
+ for ( ++iF, --iL; iF < L._lEdges.size()-1; ++iF, --iL )
{
- gp_XY tangent ( LE._normal2D.Y(), -LE._normal2D.X() );
- weight += Abs( tangent * ( prevLE->_uvIn - LE._uvIn )) / segLen.back();
- // gp_XY prevTang( LE._uvOut - prevLE->_uvOut );
- // gp_XY prevNorm( -prevTang.Y(), prevTang.X() );
- gp_XY prevNorm = LE._normal2D;
- double prevProj = prevNorm * ( prevLE->_uvIn - prevLE->_uvOut );
- if ( prevProj > 0 ) {
- prevProj /= prevNorm.Modulus();
- if ( LE._length2D < prevProj )
- weight += 0.75 * ( 1 - weight ); // length decrease is more preferable
- LE._length2D = weight * LE._length2D + ( 1 - weight ) * prevProj;
- LE._uvIn = LE._uvOut + LE._normal2D * LE._length2D;
+ _LayerEdge& LE = L._lEdges[*i];
+ if ( prevLE->_length2D > 0 )
+ {
+ gp_XY tangent ( LE._normal2D.Y(), -LE._normal2D.X() );
+ weight += Abs( tangent * ( prevLE->_uvIn - LE._uvIn )) / totSegLen;
+ // gp_XY prevTang( LE._uvOut - prevLE->_uvOut );
+ // gp_XY prevNorm( -prevTang.Y(), prevTang.X() );
+ gp_XY prevNorm = LE._normal2D;
+ double prevProj = prevNorm * ( prevLE->_uvIn - prevLE->_uvOut );
+ if ( prevProj > 0 ) {
+ prevProj /= prevNorm.Modulus();
+ if ( LE._length2D < prevProj )
+ weight += 0.75 * ( 1 - weight ); // length decrease is more preferable
+ LE._length2D = weight * LE._length2D + ( 1 - weight ) * prevProj;
+ LE._uvIn = LE._uvOut + LE._normal2D * LE._length2D;
+ }
}
+ prevLE = & LE;
}
- prevLE = & LE;
}
}
// DEBUG: to see _uvRefined. cout can be redirected to hide NETGEN output
// cerr << "import smesh" << endl << "mesh = smesh.Mesh()"<< endl;
- // calculate intermediate UV on _LayerEdge's ( _LayerEdge::_uvRefined )
- size_t iLE = 0, nbLE = L._lEdges.size();
- if ( ! L._lEdges[0]._uvRefined.empty() ) ++iLE;
- if ( ! L._lEdges.back()._uvRefined.empty() ) --nbLE;
- for ( ; iLE < nbLE; ++iLE )
- {
- _LayerEdge& LE = L._lEdges[iLE];
- if ( fabs( LE._length2D - prevLen2D ) > LE._length2D / 100. )
- {
- calcLayersHeight( LE._length2D, layersHeight );
- prevLen2D = LE._length2D;
- }
- for ( size_t i = 0; i < layersHeight.size(); ++i )
- LE._uvRefined.push_back( LE._uvOut + LE._normal2D * layersHeight[i] );
-
- // DEBUG: to see _uvRefined
- // for ( size_t i = 0; i < LE._uvRefined.size(); ++i )
- // {
- // gp_XY uv = LE._uvRefined[i];
- // gp_Pnt p = _surface->Value( uv.X(), uv.Y() );
- // cerr << "mesh.AddNode( " << p.X() << ", " << p.Y() << ", " << p.Z() << " )" << endl;
- // }
- }
-
- // nodes to create 1 layer of faces
- vector< const SMDS_MeshNode* > outerNodes( L._lastPntInd - L._firstPntInd + 1 );
- vector< const SMDS_MeshNode* > innerNodes( L._lastPntInd - L._firstPntInd + 1 );
-
- // initialize outerNodes by nodes of the L._wire
const vector<UVPtStruct>& points = L._wire->GetUVPtStruct();
- for ( int i = L._firstPntInd; i <= L._lastPntInd; ++i )
- outerNodes[ i-L._firstPntInd ] = points[i].node;
-
- // compute normalized [0;1] node parameters of outerNodes
- vector< double > normPar( L._lastPntInd - L._firstPntInd + 1 );
- const double
- normF = L._wire->FirstParameter( L._edgeInd ),
- normL = L._wire->LastParameter ( L._edgeInd ),
- normDist = normL - normF;
- for ( int i = L._firstPntInd; i <= L._lastPntInd; ++i )
- normPar[ i - L._firstPntInd ] = ( points[i].normParam - normF ) / normDist;
- // Create layers of faces
-
+ // analyse extremities of the _PolyLine to find existing nodes
const TopoDS_Vertex& V1 = L._wire->FirstVertex( L._edgeInd );
const TopoDS_Vertex& V2 = L._wire->LastVertex ( L._edgeInd );
const int v1ID = getMeshDS()->ShapeToIndex( V1 );
bool hasRightNode = ( !L._rightLine->_leftNodes.empty() && rightEdgeShared );
bool hasOwnLeftNode = ( !L._leftNodes.empty() );
bool hasOwnRightNode = ( !L._rightNodes.empty() );
- bool isClosedEdge = ( outerNodes.front() == outerNodes.back() );
- size_t iS,
+ bool isClosedEdge = ( points[ L._firstPntInd ].node == points[ L._lastPntInd ].node );
+ const size_t
+ nbN = L._lastPntInd - L._firstPntInd + 1,
iN0 = ( hasLeftNode || hasOwnLeftNode || isClosedEdge || !isShrinkableL ),
- nbN = innerNodes.size() - ( hasRightNode || hasOwnRightNode || !isShrinkableR);
- L._leftNodes .reserve( _hyp->GetNumberLayers() );
- L._rightNodes.reserve( _hyp->GetNumberLayers() );
- int cur = 0, prev = -1; // to take into account orientation of _face
- if ( isReverse ) std::swap( cur, prev );
- for ( int iF = 0; iF < _hyp->GetNumberLayers(); ++iF ) // loop on layers of faces
+ iNE = nbN - ( hasRightNode || hasOwnRightNode || !isShrinkableR );
+
+ // update _uvIn of end _LayerEdge's by existing nodes
+ const SMDS_MeshNode *nL = 0, *nR = 0;
+ if ( hasOwnLeftNode ) nL = L._leftNodes.back();
+ else if ( hasLeftNode ) nL = L._leftLine->_rightNodes.back();
+ if ( hasOwnRightNode ) nR = L._rightNodes.back();
+ else if ( hasRightNode ) nR = L._rightLine->_leftNodes.back();
+ if ( nL )
+ L._lEdges[0]._uvIn = _helper.GetNodeUV( _face, nL, points[ L._firstPntInd + 1 ].node );
+ if ( nR )
+ L._lEdges.back()._uvIn = _helper.GetNodeUV( _face, nR, points[ L._lastPntInd - 1 ].node );
+
+ // compute normalized [0;1] node parameters of nodes on a _PolyLine
+ vector< double > normPar( nbN );
+ const double
+ normF = L._wire->FirstParameter( L._edgeInd ),
+ normL = L._wire->LastParameter ( L._edgeInd ),
+ normDist = normL - normF;
+ for ( int i = L._firstPntInd; i <= L._lastPntInd; ++i )
+ normPar[ i - L._firstPntInd ] = ( points[i].normParam - normF ) / normDist;
+
+ // Calculate UV of most inner nodes
+
+ vector< gp_XY > innerUV( nbN );
+
+ // check if innerUV should be interpolated between _LayerEdge::_uvIn's
+ const size_t nbLE = L._lEdges.size();
+ bool needInterpol = ( nbN != nbLE );
+ if ( !needInterpol )
+ {
+ // more check: compare length of inner and outer end segments
+ double lenIn, lenOut;
+ for ( int isR = 0; isR < 2 && !needInterpol; ++isR )
+ {
+ const _Segment& segIn = isR ? L._segments.back() : L._segments[0];
+ const gp_XY& uvIn1 = segIn.p1();
+ const gp_XY& uvIn2 = segIn.p2();
+ const gp_XY& uvOut1 = L._lEdges[ isR ? nbLE-1 : 0 ]._uvOut;
+ const gp_XY& uvOut2 = L._lEdges[ isR ? nbLE-2 : 1 ]._uvOut;
+ if ( _is2DIsotropic )
+ {
+ lenIn = ( uvIn1 - uvIn2 ).Modulus();
+ lenOut = ( uvOut1 - uvOut2 ).Modulus();
+ }
+ else
+ {
+ lenIn = _surface->Value( uvIn1.X(), uvIn1.Y() )
+ .Distance( _surface->Value( uvIn2.X(), uvIn2.Y() ));
+ lenOut = _surface->Value( uvOut1.X(), uvOut1.Y() )
+ .Distance( _surface->Value( uvOut2.X(), uvOut2.Y() ));
+ }
+ needInterpol = ( lenIn < 0.66 * lenOut );
+ }
+ }
+
+ if ( needInterpol )
{
- // get accumulated length of intermediate segments
+ // compute normalized accumulated length of inner segments
+ size_t iS;
if ( _is2DIsotropic )
for ( iS = 1; iS < segLen.size(); ++iS )
{
- double sLen = (L._lEdges[iS-1]._uvRefined[iF] - L._lEdges[iS]._uvRefined[iF] ).Modulus();
+ double sLen = ( L._lEdges[iS-1]._uvIn - L._lEdges[iS]._uvIn ).Modulus();
segLen[iS] = segLen[iS-1] + sLen;
}
else
for ( iS = 1; iS < segLen.size(); ++iS )
{
- const gp_XY& uv1 = L._lEdges[iS-1]._uvRefined[iF];
- const gp_XY& uv2 = L._lEdges[iS ]._uvRefined[iF];
+ const gp_XY& uv1 = L._lEdges[iS-1]._uvIn;
+ const gp_XY& uv2 = L._lEdges[iS ]._uvIn;
gp_Pnt p1 = _surface->Value( uv1.X(), uv1.Y() );
gp_Pnt p2 = _surface->Value( uv2.X(), uv2.Y() );
double sLen = p1.Distance( p2 );
for ( iS = 1; iS < segLen.size(); ++iS )
segLen[iS] /= segLen.back();
- // create innerNodes of a current layer
+ // calculate UV of most inner nodes according to the normalized node parameters
iS = 0;
- for ( size_t i = iN0; i < nbN; ++i )
+ for ( size_t i = 0; i < innerUV.size(); ++i )
{
while ( normPar[i] > segLen[iS+1] )
++iS;
double r = ( normPar[i] - segLen[iS] ) / ( segLen[iS+1] - segLen[iS] );
- gp_XY uv = r * L._lEdges[iS+1]._uvRefined[iF] + (1-r) * L._lEdges[iS]._uvRefined[iF];
- gp_Pnt p = _surface->Value( uv.X(), uv.Y() );
+ innerUV[ i ] = r * L._lEdges[iS+1]._uvIn + (1-r) * L._lEdges[iS]._uvIn;
+ }
+ }
+ else // ! needInterpol
+ {
+ for ( size_t i = 0; i < nbLE; ++i )
+ innerUV[ i ] = L._lEdges[i]._uvIn;
+ }
+
+ // normalized height of layers
+ const THypVL* hyp = getLineHypothesis( iL );
+ calcLayersHeight( 1., layersHeight, hyp);
+
+ // Create layers of faces
+
+ // nodes to create 1 layer of faces
+ vector< const SMDS_MeshNode* > outerNodes( nbN );
+ vector< const SMDS_MeshNode* > innerNodes( nbN );
+
+ // initialize outerNodes by nodes of the L._wire
+ for ( int i = L._firstPntInd; i <= L._lastPntInd; ++i )
+ outerNodes[ i-L._firstPntInd ] = points[i].node;
+
+ L._leftNodes .reserve( hyp->GetNumberLayers() );
+ L._rightNodes.reserve( hyp->GetNumberLayers() );
+ int cur = 0, prev = -1; // to take into account orientation of _face
+ if ( isReverse ) std::swap( cur, prev );
+ for ( int iF = 0; iF < hyp->GetNumberLayers(); ++iF ) // loop on layers of faces
+ {
+ // create innerNodes of a current layer
+ for ( size_t i = iN0; i < iNE; ++i )
+ {
+ gp_XY uvOut = points[ L._firstPntInd + i ].UV();
+ gp_XY& uvIn = innerUV[ i ];
+ gp_XY uv = layersHeight[ iF ] * uvIn + ( 1.-layersHeight[ iF ]) * uvOut;
+ gp_Pnt p = _surface->Value( uv.X(), uv.Y() );
innerNodes[i] = _helper.AddNode( p.X(), p.Y(), p.Z(), /*id=*/0, uv.X(), uv.Y() );
}
// use nodes created for adjacent _PolyLine's
outerNodes.swap( innerNodes );
}
+
// faces between not shared _LayerEdge's (at concave VERTEX)
for ( int isR = 0; isR < 2; ++isR )
{
return thereWereElems;
}
+//================================================================================
+/*!
+ * \brief Returns a hypothesis for a _PolyLine
+ */
+//================================================================================
+
+const StdMeshers_ViscousLayers2D* _ViscousBuilder2D::getLineHypothesis(int iPL)
+{
+ return iPL < (int)_hypOfEdge.size() ? _hypOfEdge[ iPL ] : _hyps[0];
+}
+
+//================================================================================
+/*!
+ * \brief Returns a layers thickness for a _PolyLine
+ */
+//================================================================================
+
+double _ViscousBuilder2D::getLineThickness(int iPL)
+{
+ if ( const StdMeshers_ViscousLayers2D* h = getLineHypothesis( iPL ))
+ return Min( _maxThickness, h->GetTotalThickness() );
+ return _maxThickness;
+}
+
//================================================================================
/*!
* \brief Creates a _ProxyMeshOfFace and store it in a sub-mesh of FACE
//================================================================================
void _ViscousBuilder2D::calcLayersHeight(const double totalThick,
- vector<double>& heights)
+ vector<double>& heights,
+ const THypVL* hyp)
{
- heights.resize( _hyp->GetNumberLayers() );
+ const double fPowN = pow( hyp->GetStretchFactor(), hyp->GetNumberLayers() );
+ heights.resize( hyp->GetNumberLayers() );
double h0;
- if ( _fPowN - 1 <= numeric_limits<double>::min() )
- h0 = totalThick / _hyp->GetNumberLayers();
+ if ( fPowN - 1 <= numeric_limits<double>::min() )
+ h0 = totalThick / hyp->GetNumberLayers();
else
- h0 = totalThick * ( _hyp->GetStretchFactor() - 1 )/( _fPowN - 1 );
+ h0 = totalThick * ( hyp->GetStretchFactor() - 1 )/( fPowN - 1 );
double hSum = 0, hi = h0;
- for ( int i = 0; i < _hyp->GetNumberLayers(); ++i )
+ for ( int i = 0; i < hyp->GetNumberLayers(); ++i )
{
hSum += hi;
heights[ i ] = hSum;
- hi *= _hyp->GetStretchFactor();
+ hi *= hyp->GetStretchFactor();
}
}
{
public:
StdMeshers_ViscousLayers2D(int hypId, int studyId, SMESH_Gen* gen);
-
- // Computes temporary 2D mesh to be used by 2D algorithm.
- // Return SMESH_ProxyMesh for the given FACE, or NULL in case of error
+ /*!
+ * \brief Computes temporary 2D mesh to be used by 2D algorithm.
+ * Return SMESH_ProxyMesh for the given FACE, or NULL in case of error
+ */
static SMESH_ProxyMesh::Ptr Compute(SMESH_Mesh& theMesh,
const TopoDS_Face& theShape);
/*!
*/
void RestoreListeners() const;
+ /*!
+ * \brief Checks compatibility of assigned StdMeshers_ViscousLayers2D hypotheses
+ */
+ static SMESH_ComputeErrorPtr CheckHypothesis(SMESH_Mesh& aMesh,
+ const TopoDS_Shape& aShape,
+ Hypothesis_Status& aStatus);
/*!
* \brief Initialize my parameter values by the mesh built on the geometry
- * \param theMesh - the built mesh
- * \param theShape - the geometry of interest
- * \retval bool - true if parameter values have been successfully defined
- *
- * Just return false as this hypothesis does not have parameters values
+ * \param theMesh - the built mesh
+ * \param theShape - the geometry of interest
+ * \retval bool - true if parameter values have been successfully defined
+ *
+ * Just return false as this hypothesis does not have parameters values
*/
virtual bool SetParametersByMesh(const SMESH_Mesh* theMesh, const TopoDS_Shape& theShape);
#include <QApplication>
#include <QButtonGroup>
#include <QCheckBox>
+#include <QFontMetrics>
#include <QGridLayout>
#include <QGroupBox>
#include <QHBoxLayout>
dirs[( iOk+2 ) % 3] = dirs[ iOk ] ^ dirs[ ( iOk+1 ) % 3 ];
dirs[( iOk+1 ) % 3] = dirs[ ( iOk+2 ) % 3 ] ^ dirs[ iOk ];
}
+
+ //================================================================================
+ /*!
+ * \brief Returns a minimal width of a SpinBox depending on a precision type
+ */
+ //================================================================================
+
+ int getMinWidth( const char* precisionType )
+ {
+ int nb = SMESHGUI::resourceMgr()->integerValue( "SMESH", precisionType, -3 );
+ QString s;
+ s.fill('0', qAbs(nb)+7 );
+ QLineEdit le;
+ QFontMetrics metrics( le.font() );
+ return metrics.width( s );
+ }
}
//================================================================================
axisLbl[2] = new QLabel( tr( "AXIS_Z"), axesDirGrp );
QLabel* dLbl[3];
myAxisBtnGrp = new QButtonGroup( axesDirGrp );
- SMESHGUI_SpinBox** spins[3] = { &myXDirSpin[0], &myYDirSpin[0], &myZDirSpin[0] };
+ // get spin width
+ const char * const precisionType = "len_tol_precision";
+ int minWidth = getMinWidth( precisionType );
for ( int i = 0; i < 3; ++i )
{
QPushButton* axisBtn = new QPushButton( QIcon(aPix), "", axesDirGrp );
myXDirSpin[i] = new SMESHGUI_SpinBox( axesDirGrp );
myYDirSpin[i] = new SMESHGUI_SpinBox( axesDirGrp );
myZDirSpin[i] = new SMESHGUI_SpinBox( axesDirGrp );
- myXDirSpin[i]->RangeStepAndValidator( -1, 1, 0.1, "len_tol_precision" );
- myYDirSpin[i]->RangeStepAndValidator( -1, 1, 0.1, "len_tol_precision" );
- myZDirSpin[i]->RangeStepAndValidator( -1, 1, 0.1, "len_tol_precision" );
+ myXDirSpin[i]->RangeStepAndValidator( -1, 1, 0.1, precisionType );
+ myYDirSpin[i]->RangeStepAndValidator( -1, 1, 0.1, precisionType );
+ myZDirSpin[i]->RangeStepAndValidator( -1, 1, 0.1, precisionType );
+ myXDirSpin[i]->setMinimumWidth( minWidth );
+ myYDirSpin[i]->setMinimumWidth( minWidth );
+ myZDirSpin[i]->setMinimumWidth( minWidth );
dLbl[0] = new QLabel( tr("SMESH_DX"), axesDirGrp );
dLbl[1] = new QLabel( tr("SMESH_DY"), axesDirGrp );
dLbl[2] = new QLabel( tr("SMESH_DZ"), axesDirGrp );
myObjNameLineEdit->setStyleSheet("");
myObjects.push_back( CORBA::Object::_duplicate( obj ));
myParamValue = sobj->GetID().c_str();
- emit contentModified();
}
+ emit contentModified();
}
//================================================================================
// SALOME GUI includes
#include <SUIT_ResourceMgr.h>
+#include <SUIT_MessageBox.h>
// IDL includes
#include <SALOMEconfig.h>
idsWg->SetMainShapeEntry( aMainEntry );
idsWg->SetGeomShapeEntry( aSubEntry.isEmpty() ? aMainEntry : aSubEntry );
- idsWg->SetListOfIDs( h->GetFaces() );
- idsWg->showPreview( true );
+ if ( idsWg->SetListOfIDs( h->GetFaces() ))
+ {
+ idsWg->showPreview( true );
+ }
+ else
+ {
+ SUIT_MessageBox::warning( dlg(),tr( "SMESH_WRN_WARNING" ),tr( "BAD_FACES_WARNING" ));
+ idsWg->setEnabled( false );
+ }
customWidgets()->append ( idsWg );
}
}
idsWg->SetMainShapeEntry( aMainEntry );
idsWg->SetGeomShapeEntry( aSubEntry.isEmpty() ? aMainEntry : aSubEntry );
- idsWg->SetListOfIDs( h->GetEdges() );
- idsWg->showPreview( true );
+ if ( idsWg->SetListOfIDs( h->GetEdges() ))
+ {
+ idsWg->showPreview( true );
+ }
+ else
+ {
+ SUIT_MessageBox::warning( dlg(),tr( "SMESH_WRN_WARNING" ),tr( "BAD_EDGES_WARNING" ));
+ idsWg->setEnabled( false );
+ }
customWidgets()->append ( idsWg );
}
}
//=================================================================================
// function : SetListOfIds
-// purpose : Called to set the list of SubShapes IDs
+// purpose : Called to set the list of SubShapes IDs. Returns false if any ID is invalid
//=================================================================================
-void StdMeshersGUI_SubShapeSelectorWdg::SetListOfIDs( SMESH::long_array_var theIds)
+bool StdMeshersGUI_SubShapeSelectorWdg::SetListOfIDs( SMESH::long_array_var theIds)
{
mySelectedIDs.clear();
myListOfIDs.clear();
for ( int i = 0; i < size; i++ )
mySelectedIDs.append( theIds[ i ] );
- mySelectedIDs = GetCorrectedListOfIDs( false );
+ bool isOk;
+ mySelectedIDs = GetCorrectedListOfIDs( false, &isOk );
onAdd();
+ return isOk;
}
//=================================================================================
// function : GetCorrectedListOfIds
// purpose : Called to convert the list of IDs from sub-shape IDs to main shape IDs
//=================================================================================
-QList<int> StdMeshersGUI_SubShapeSelectorWdg::GetCorrectedListOfIDs( bool fromSubshapeToMainshape )
+QList<int>
+StdMeshersGUI_SubShapeSelectorWdg::GetCorrectedListOfIDs( bool fromSubshapeToMainshape,
+ bool* isOK )
{
- if ( ( myMainShape.IsNull() || myGeomShape.IsNull() ) && fromSubshapeToMainshape )
+ if (( myMainShape.IsNull() || myGeomShape.IsNull() ) && fromSubshapeToMainshape )
return myListOfIDs;
- else if ( ( myMainShape.IsNull() || myGeomShape.IsNull() ) && !fromSubshapeToMainshape )
+ else if (( myMainShape.IsNull() /*||*/&& myGeomShape.IsNull() ) && !fromSubshapeToMainshape )
return mySelectedIDs;
+ if ( !fromSubshapeToMainshape ) // called from SetListOfIDs
+ {
+ if ( myMainShape.IsNull() )
+ std::swap( myMainShape, myGeomShape );
+ }
+
QList<int> aList;
- TopTools_IndexedMapOfShape aGeomMap;
- TopTools_IndexedMapOfShape aMainMap;
- TopExp::MapShapes(myGeomShape, aGeomMap);
+ TopTools_IndexedMapOfShape aGeomMap, aMainMap;
TopExp::MapShapes(myMainShape, aMainMap);
+ if ( !myGeomShape.IsNull() )
+ TopExp::MapShapes(myGeomShape, aGeomMap);
- if ( fromSubshapeToMainshape ) { // convert indexes from sub-shape to mainshape
+ bool ok = true;
+ if ( fromSubshapeToMainshape ) // convert indexes from sub-shape to mainshape
+ {
int size = myListOfIDs.size();
for (int i = 0; i < size; i++) {
- TopoDS_Shape aSubShape = aGeomMap.FindKey( myListOfIDs.at(i) );
- int index = aMainMap.FindIndex( aSubShape );
+ int index = myListOfIDs.at(i);
+ if ( aGeomMap.Extent() < index )
+ {
+ ok = false;
+ }
+ else
+ {
+ TopoDS_Shape aSubShape = aGeomMap.FindKey( index );
+ if ( mySubShType != aSubShape.ShapeType() )
+ ok = false;
+ if ( !aMainMap.Contains( aSubShape ))
+ ok = false;
+ else
+ index = aMainMap.FindIndex( aSubShape );
+ }
aList.append( index );
}
myIsNotCorrected = false;
- } else { // convert indexes from main shape to sub-shape
+ }
+ else // convert indexes from main shape to sub-shape, or just check indices
+ {
int size = mySelectedIDs.size();
for (int i = 0; i < size; i++) {
- TopoDS_Shape aSubShape = aMainMap.FindKey( mySelectedIDs.at(i) );
- int index = aGeomMap.FindIndex( aSubShape );
+ int index = mySelectedIDs.at(i);
+ if ( aMainMap.Extent() < index )
+ {
+ ok = false;
+ }
+ else
+ {
+ TopoDS_Shape aSubShape = aMainMap.FindKey( index );
+ if ( mySubShType != aSubShape.ShapeType() )
+ ok = false;
+ if ( !aGeomMap.Contains( aSubShape ) && !aGeomMap.IsEmpty() )
+ ok = false;
+ else
+ index = aGeomMap.FindIndex( aSubShape );
+ }
aList.append( index );
}
}
+ if ( isOK ) *isOK = ok;
return aList;
}
~StdMeshersGUI_SubShapeSelectorWdg();
SMESH::long_array_var GetListOfIDs();
- void SetListOfIDs( SMESH::long_array_var );
+ bool SetListOfIDs( SMESH::long_array_var );
void SetGeomShapeEntry( const QString& theEntry );
const char* GetGeomShapeEntry() { return myEntry.toLatin1().data();}
TopoDS_Shape GetGeomShape() { return myGeomShape; }
TopoDS_Shape GetMainShape() { return myMainShape; }
- QList<int> GetCorrectedListOfIDs( bool fromSubshapeToMainshape = true );
+ QList<int> GetCorrectedListOfIDs( bool fromSubshapeToMainshape,
+ bool* isOK=0);
static GEOM::GEOM_Object_var GetGeomObjectByEntry( const QString& );
static TopoDS_Shape GetTopoDSByEntry( const QString& );
<source>TO_IGNORE_FACES</source>
<translation>Faces without layers (inlets and oulets)</translation>
</message>
+ <message>
+ <source>BAD_FACES_WARNING</source>
+ <translation>
+Specified faces are not sub-shapes of the shape of
+mesh/sub-mesh.
+Consider creating another hypothesis instead of using
+this one for this mesh/sub-mesh.</translation>
+ </message>
+ <message>
+ <source>BAD_EDGES_WARNING</source>
+ <translation>
+Specified edges are not sub-shapes of the shape of
+mesh/sub-mesh.
+Consider creating another hypothesis instead of using
+this one for this mesh/sub-mesh.</translation>
+ </message>
</context>
<context>
<name>@default</name>