diff --git a/Makefile.am b/Makefile.am
index aaf432892..b782b886e 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -48,6 +48,8 @@ salomeinclude_DATA = SMESH_version.h
EXTRA_DIST += \
build_configure \
clean_configure \
+ build_cmake \
+ build_cmake.bat \
LICENCE
dist-hook:
diff --git a/adm_local/unix/make_common_starter.am b/adm_local/unix/make_common_starter.am
index 77936ec88..feb12fc58 100644
--- a/adm_local/unix/make_common_starter.am
+++ b/adm_local/unix/make_common_starter.am
@@ -39,6 +39,12 @@ salomescriptdir = $(bindir)
salomepythondir = $(pythondir)/salome
salomepyexecdir = $(pyexecdir)/salome
+# Root directory of the python packages of SMESH
+smeshpypkgdir = $(salomepythondir)/salome/smesh
+
+# Directory for installing SALOME plugins files
+salomepluginsdir = $(prefix)/share/salome/plugins/@MODULE_NAME@
+
# Directory for installing idl files
salomeidldir = $(prefix)/idl/salome
diff --git a/configure.ac b/configure.ac
index b1de4d2f4..f7569d1ce 100644
--- a/configure.ac
+++ b/configure.ac
@@ -24,7 +24,7 @@
# Modified by : Alexander BORODIN (OCN) - autotools usage
# Created from configure.in.base
#
-AC_INIT([Salome2 Project SMESH module], [6.3.1], [webmaster.salome@opencascade.com], [SalomeSMESH])
+AC_INIT([Salome2 Project SMESH module], [6.4.0], [webmaster.salome@opencascade.com], [SalomeSMESH])
AC_CONFIG_AUX_DIR(adm_local/unix/config_files)
AC_CANONICAL_HOST
AC_CANONICAL_TARGET
@@ -302,6 +302,22 @@ if test "${gui_ok}" = "yes"; then
CHECK_QT
+ echo
+ echo ---------------------------------------------
+ echo testing sip
+ echo ---------------------------------------------
+ echo
+
+ CHECK_SIP
+
+ echo
+ echo ---------------------------------------------
+ echo testing pyqt
+ echo ---------------------------------------------
+ echo
+
+ CHECK_PYQT
+
echo
echo ---------------------------------------------
echo Testing qwt
@@ -366,6 +382,14 @@ echo ---------------------------------------------
echo
CHECK_SPHINX
+echo
+echo ---------------------------------------------
+echo testing libxm
+echo ---------------------------------------------
+echo
+dnl Check the libxml that will be required to use the SALOME launcher
+CHECK_LIBXML
+
echo
echo ---------------------------------------------
echo Testing Kernel
@@ -520,6 +544,25 @@ AC_OUTPUT([ \
src/SMESH_PY/Makefile \
src/Tools/Makefile \
src/Tools/MeshCut/Makefile \
+ src/Tools/padder/Makefile \
+ src/Tools/padder/meshjob/Makefile \
+ src/Tools/padder/meshjob/idl/Makefile \
+ src/Tools/padder/meshjob/impl/Makefile \
+ src/Tools/padder/spadderpy/Makefile \
+ src/Tools/padder/spadderpy/padder.cfg \
+ src/Tools/padder/spadderpy/gui/Makefile \
+ src/Tools/padder/spadderpy/plugin/Makefile \
+ src/Tools/padder/spadderpy/plugin/envPlugins.sh \
+ src/Tools/padder/resources/Makefile \
+ src/Tools/padder/resources/appligen/Makefile \
+ src/Tools/padder/resources/appligen/appligen.sh \
+ src/Tools/padder/resources/appligen/config_appli.xml \
+ src/Tools/padder/resources/padderexe/Makefile \
+ src/Tools/padder/resources/padderexe/envPadder.sh \
+ src/Tools/padder/unittests/Makefile \
+ src/Tools/padder/unittests/autotest.sh \
+ src/Tools/padder/doc/Makefile \
+ src/Tools/padder/doc/doxyfile \
resources/Makefile \
resources/SMESHCatalog.xml \
resources/SalomeApp.xml \
diff --git a/doc/Makefile.am b/doc/Makefile.am
index e5c494e51..3edbc8c0a 100644
--- a/doc/Makefile.am
+++ b/doc/Makefile.am
@@ -25,6 +25,7 @@
# source path
#
SUBDIRS = salome docutils
+#SUBDIRS = salome
usr_docs:
(cd salome && $(MAKE) $(AM_MAKEFLAGS) usr_docs)
diff --git a/doc/docutils/conf.py.in b/doc/docutils/conf.py.in
index b2bb21f71..1aea4dc54 100644
--- a/doc/docutils/conf.py.in
+++ b/doc/docutils/conf.py.in
@@ -184,7 +184,7 @@ latex_documents = [
# The name of an image file (relative to this directory) to place at the top of
# the title page.
-latex_logo = '../salome/tui/images/head.png'
+latex_logo = '@srcdir@/../salome/tui/images/head.png'
# For "manual" documents, if this is true, then toplevel headings are parts,
# not chapters.
diff --git a/doc/salome/gui/SMESH/doxyfile.in b/doc/salome/gui/SMESH/doxyfile.in
index aec3397c2..b303e8487 100755
--- a/doc/salome/gui/SMESH/doxyfile.in
+++ b/doc/salome/gui/SMESH/doxyfile.in
@@ -38,10 +38,10 @@ WARNINGS = YES
#---------------------------------------------------------------------------
#Input related options
#---------------------------------------------------------------------------
-INPUT = @srcdir@/input
+INPUT = @srcdir@/input @top_srcdir@/src/Tools/padder/doc/input
FILE_PATTERNS = *.doc
EXCLUDE =
-IMAGE_PATH = @srcdir@/images
+IMAGE_PATH = @srcdir@/images @top_srcdir@/src/Tools/padder/doc/images
EXAMPLE_PATH = @top_srcdir@/src/SMESH_SWIG
#---------------------------------------------------------------------------
diff --git a/doc/salome/gui/SMESH/images/cartesian3D_hyp.png b/doc/salome/gui/SMESH/images/cartesian3D_hyp.png
new file mode 100644
index 000000000..b8373ed6d
Binary files /dev/null and b/doc/salome/gui/SMESH/images/cartesian3D_hyp.png differ
diff --git a/doc/salome/gui/SMESH/images/cartesian3D_sphere.png b/doc/salome/gui/SMESH/images/cartesian3D_sphere.png
new file mode 100644
index 000000000..45bffdabe
Binary files /dev/null and b/doc/salome/gui/SMESH/images/cartesian3D_sphere.png differ
diff --git a/doc/salome/gui/SMESH/input/basic_meshing_algos.doc b/doc/salome/gui/SMESH/input/basic_meshing_algos.doc
index 274ab7438..828561875 100644
--- a/doc/salome/gui/SMESH/input/basic_meshing_algos.doc
+++ b/doc/salome/gui/SMESH/input/basic_meshing_algos.doc
@@ -23,10 +23,8 @@ shape of a mesh.
Triangle meshing algorithms (Mefisto, Netgen 1D-2D and BLSUFR ) - Faces
are split into triangular elements.
-
Quadrangle meshing algorithm (Mapping) - Faces are split into
+
Quadrangle meshing algorithm (Mapping) - quadrilateral Faces are split into
quadrangular elements.
-
Radial quadrangle 1D2D algorithm - Faces (circles or part of circles)
-are split into triangular and quadrangle elements.
\image html image123.gif "Example of a triangular 2D mesh"
@@ -36,10 +34,14 @@ are split into triangular and quadrangle elements.
For meshing of 3D entities (volume objects):
-
Hexahedron meshing algorithm (i,j,k) - Volumes are split into
+
Hexahedron meshing algorithm (i,j,k) - 6-sided Volumes are split into
hexahedral (cubic) elements.
Tetrahedron (Netgen and GHS3D) meshing algorithms - Volumes are split into
tetrahedral (pyramidal) elements.
+
\subpage cartesian_algo_page
+internal parts of Volumes are split into hexahedral elements forming a
+Cartesian grid; polyhedra and other types of elements are generated
+where the geometrical boundary intersects Cartesian cells.
\image html image125.gif "Example of a tetrahedral 3D mesh"
diff --git a/doc/salome/gui/SMESH/input/blsurf_hypo.doc b/doc/salome/gui/SMESH/input/blsurf_hypo.doc
index c5cc5c8e2..2f39999da 100644
--- a/doc/salome/gui/SMESH/input/blsurf_hypo.doc
+++ b/doc/salome/gui/SMESH/input/blsurf_hypo.doc
@@ -96,8 +96,8 @@ not sewed faces.
"PreCAD" is an auxiliary CAD pre-processing module which has
two main goals:
-
Complete missing or inadequate CAD-description.
-
Perform topology reconstruction and specific geometry
+
Complete missing or inadequate CAD descriptions.
+
Perform topology reconstruction and specific geometry
enhancement for mesh generation.
This module requires a specific licence.
@@ -105,15 +105,15 @@ not sewed faces.
The following PreCAD options are the most significant and important ones:
Merge Edges - allows PreCAD to optimize the geometry by merging some
- edges. Default is 0.
+ edges. This option is 0 by default.
Remove nano edges - allows PreCAD to optimize the geometry by removing
- the nano edges whenever possible. Default is 0.
+ the nano edges whenever possible. This option is 0 by default.
Nano edge length - gives the length below which an edge is considered as nano
for the topology processing. See also the \b remove_nano_edges option. If unset, PreCAD
default value is \f$\mathrm{diag} \times 10^{-5}\f$.
Discard input topology - computes the CAD topology from scratch,
without considering the toplogical information contained in the original CAD
- (Useful for iges files). Default is 0.
+ (Useful for iges files). This option is 0 by default.
@@ -208,29 +208,34 @@ files. Default is 1.
The following PreCAD options are commonly usable.
\b closed_geometry (int) - describes whether the working geometry
-should be closed or not. When activated, this option helps PreCAD to treat
-the most dirtiest geometries. Default is 0.
+should be closed or not. When activated, this option helps PreCAD to process
+the dirtiest geometries. By default this option is 0.
\b debug (int) - If debug = 1 PreCAD will be very verbose and will output
-some intermediate files in the working directory. Default is 0.
-
\b eps_nano_relative (real) - Same as \b eps_nano but given in relatively to
-the diagonal of the box bounding the geometry. Default is \f$10^{-5}\f$.
+some intermediate files in the working directory. By default this
+option is 0.
+
\b eps_nano_relative (real) - the same as \b eps_nano, but relatively to
+the diagonal of the box bounding the geometry. By default this option is \f$10^{-5}\f$.
\b eps_sewing (real) - tolerance of the assembly. It rarely requires to be tuned.
-Default is \f$\mathrm{diag} \times 5 \cdot 10^{-4}\f$.
-
\b eps_sewing_relative (real) - Same as \b eps_nano but given in relatively to
-the diagonal of the box bounding the geometry. Default is \f$5 \cdot 10^{-4}\f$.
+By default this option is \f$\mathrm{diag} \times 5 \cdot 10^{-4}\f$.
+
\b eps_sewing_relative (real) - the same as \b eps_nano but relatively to
+the diagonal of the box bounding the geometry. By default this option is \f$5 \cdot 10^{-4}\f$.
\b manifold_geometry (int) - describes whether the working geometry should be manifold or not.
-When activated, this option helps PreCAD to treat the most dirtiest geometries. Default is 0.
-
\b create_tag_collision (int) - creates some new tags from original ones in case
-of collision (entity merge or association for example). Default is 0.
-
\b periodic_tolerance (real) - defines the maximum distance error accepted between
-two sets of periodic entities. Default is \f$\mathrm{diag} \times 10^{-5}\f$.
-
\b periodic_tolerance_relative (real) - Same as \b periodic_tolerance but in relative
-unit. Default is \f$10^{-5}\f$.
-
\b periodic_split_tolerance (real) - This periodicity processing related option defines
+When activated, this option helps PreCAD to process the dirtiest
+geometries. By default this option is 0.
+
\b create_tag_collision (int) - creates new tags from original ones in case
+of collision (entity merge or association for example). By default
+this option is 0.
+
\b periodic_tolerance (real) - defines the maximum distance error accepted between
+two sets of periodic entities. By default this option is \f$\mathrm{diag} \times 10^{-5}\f$.
+
\b periodic_tolerance_relative (real) - the same as \b
+periodic_tolerance but in a relative unit. Bu default this option is \f$10^{-5}\f$.
+
\b periodic_split_tolerance (real) - This periodicity processing related option defines
the minimum distance between a CAD point and an imprinted point. It allows to indirectly
-control the number of points and small edges created. Default is \f$\mathrm{diag} \times 10^{-4}\f$.
-
\b periodic_split_tolerance_relative (real - Same as \b periodic_split_tolerance but in
-relative unit. Default is \f$10^{-4}\f$.
+control the number of created points and small edges. By default this
+option is \f$\mathrm{diag} \times 10^{-4}\f$.
+
\b periodic_split_tolerance_relative (real - the same as \b
+periodic_split_tolerance but in a relative unit. By default this
+option is \f$10^{-4}\f$.
\n
diff --git a/doc/salome/gui/SMESH/input/cartesian_algo.doc b/doc/salome/gui/SMESH/input/cartesian_algo.doc
new file mode 100644
index 000000000..89b11e947
--- /dev/null
+++ b/doc/salome/gui/SMESH/input/cartesian_algo.doc
@@ -0,0 +1,75 @@
+/*!
+
+\page cartesian_algo_page Body Fitting 3D meshing algorithm
+
+Body Fitting algorithm generates hexahedrons of a Cartesian grid in
+the internal part of geometry and polyhedra and other types of
+elements at the intersection of Cartesian cells with the geometrical
+boundary.
+
+\image html cartesian3D_sphere.png "A shpere meshed by Body Fitting algorithm"
+
+The meshing algorithm is as follows.
+
+
Lines of a Cartesian structured grid defined by
+\ref cartesian_hyp_anchor "Body Fitting Parameters" hypothesis are
+intersected with the geometry boundary, thus nodes lying on the
+boundary are found. This step also allows finding out for each node of
+the Cartesian grid if it is inside or outside the geometry.
+
For each cell of the grid, check how many of its nodes are outside
+of the geometry boundary. Depending on a result of this check
+
+
skip a cell, if all its nodes are outside
+
skip a cell, if it is too small according to Size
+ Threshold paremeter
+
add a hexahedron in the mesh, if all nodes are inside
+
add a polyhedron or another cell type in the mesh, if some
+nodes are inside and some outside.
+
+
+
+To apply this algorithm when you define your mesh, select Body
+ Fitting in the list of 3D algorithms and click "Add
+ Hypothesis" button and "Body Fitting Parameters"" menu
+ item. Dialog of Body Fitting Parameters
+ hypothesis will appear.
+
+
+\anchor cartesian_hyp_anchor
+
Body Fitting Parameters hypothesis
+
+\image html cartesian3D_hyp.png "Body Fitting Parameters hypothesis dialog"
+
+This dialog allows to define
+
+
\b Name of the algorithm
+
Minimal size of a cell truncated by the geometry boundary. If the
+ size of a truncated grid cell is \b Threshold times less than a
+ initial cell size, then a mesh element is not created.
+
Cartesian structured grid. Each grid axis is defined
+ individually. Definition mode chooses a way of grid
+ definition:
+
You can specify the \b Coordinates of grid nodes. \b Insert button
+ inserts a node at distance \b Step (negative or positive) from a
+ selected node. \b Delete button removes a selected node. Double
+ click on a coordinate in the list enables its edition. A grid
+ defined by \b Coordinates should enclose the geometry, else the
+ algorithm will fail.
+
You can define the \b Spacing of a grid as an algebraic formular
+ f(t) where \a t is a position along a grid axiz
+ normalized at [0.0,1.0]. The whole range of geometry can be
+ divided into sub-ranges with their own spacing formulars to apply;
+ \a t varies between 0.0 and 1.0 within each sub-range. \b Insert button
+ divides a selected range into two ones. \b Delete button adds the
+ selected sub-range to the previous one. Double click on a range in
+ the list enables edition of its right boundary. Double click on a
+ function in the list enables its edition.
+
+
+
+
+
+See Also a sample TUI Script of a
+\ref tui_cartesian_algo "Usage of Body Fitting algorithm".
+
+*/
diff --git a/doc/salome/gui/SMESH/input/clipping.doc b/doc/salome/gui/SMESH/input/clipping.doc
index df3e39495..2bfa8292b 100644
--- a/doc/salome/gui/SMESH/input/clipping.doc
+++ b/doc/salome/gui/SMESH/input/clipping.doc
@@ -9,15 +9,20 @@ To start, click on the \em New button.
\image html a-clipping2.png
-Now you can define the parameters of your cross-section: list of
-meshes, sub-meshes and groups the cross-section will be applied to
-(Select all button allows to select and deselect all available
-objects at once), \b Orientation (X-Y, X-Z or Y-Z); \b Distance between the
-opposite extremities of the boundary box of selected objects, if it is set
-to 0.5 the boundary box is split in two halves; and \b Rotation (in angle
-degrees) around X (Y to Z) and around Y (X to Z).
-If the Show preview button is on, you can see the clipping plane
-in the 3D Viewer.
+Now you can define the parameters of cross-section:
+
+
List of meshes, sub-meshes and groups to which the cross-section will be applied.
+/n Select all button allows to select and deselect all available
+objects at once).
+
\b Orientation (X-Y, X-Z or Y-Z).
+
\b Distance between the opposite extremities of the boundary box
+of selected objects, if it is set
+to 0.5 the boundary box is split in two halves.
+
\b Rotation (in angle
+degrees) around X (Y to Z) and around Y (X to Z).
+
If the Show preview button is on, you can see the clipping plane
+in the 3D Viewer.
+
\image html image79.jpg "The plane and the cut object"
diff --git a/doc/salome/gui/SMESH/input/colors_size.doc b/doc/salome/gui/SMESH/input/colors_size.doc
index 1eb84f0ca..1ac27a494 100644
--- a/doc/salome/gui/SMESH/input/colors_size.doc
+++ b/doc/salome/gui/SMESH/input/colors_size.doc
@@ -9,11 +9,11 @@ parameters:
Elements
-
Surface color - color of surface of elements (seen in Shading mode).
-
Back surface color - color of interior surface of elements. Use slider to select this color. This color
-generated on base of the Surface color by changing it's brightness and saturation.
-
Outline color - color of borders of elements.
-
Wireframe color - color of borders of elements in wireframe mode.
+
Surface color - surface color of elements (seen in Shading mode).
+
Back surface color - interior surface color of elements. Use slider to select this color
+generated on base of the Surface color by changing its brightness and saturation.
+
Outline color - color of element borders.
+
Wireframe color - color of element borders in wireframe mode.
0D slements - color of 0D elements.
Size of 0D slements - size of 0D elements.
Width - width of lines (edges and borders of elements).
@@ -34,4 +34,4 @@ generated on base of the Surface color by changing it's brightness and sa
-*/
\ No newline at end of file
+*/
diff --git a/doc/salome/gui/SMESH/input/creating_groups.doc b/doc/salome/gui/SMESH/input/creating_groups.doc
index de0953a55..966e091fe 100644
--- a/doc/salome/gui/SMESH/input/creating_groups.doc
+++ b/doc/salome/gui/SMESH/input/creating_groups.doc
@@ -2,10 +2,10 @@
\page creating_groups_page Creating groups
-\n In MESH you can create groups of elements of a certain type whose
-contents is defined in different ways. To create a group, in the \b
+\n In MESH you can create a group of elements of a certain type. The
+contents of the group can be defined in different ways. To create a group, in the \b
Mesh menu select Create Group item (also available in the
-contextual menu of the mesh).
+context menu of the mesh).
To create a group of any type you should define the following:
Mesh - the mesh whose elements will form your
@@ -36,18 +36,18 @@ the following ways:
By adding all entities of the chosen type existing in the
mesh. For this, turn on the Select All check box. In this mode
- all controls, which allow selecting the entities in other ways are
+ all controls, which allow selecting the entities in other ways, are
disabled.
By applying the Filter. The Set filter 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.
- If the Enable manual edition check box is turned off, the defined
- filter defines contents of the group. In this mode, the filter is
- applied to all elements of the mesh. If none entity satisfies the
- filter, the \b Apply button is disabled.
+ If the Enable manual edition 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.
If the Enable manual edition check box is turned on, the defined
- filter can be used to for selection of entities composing the group.
+ filter can be used to for selection of entities for the group.
By choosing entities manually with the mouse in the 3D Viewer. For
this, turn on the Enable manual edition check box. You can
click on an element in the 3D viewer and it will be highlighted. After
@@ -56,11 +56,11 @@ the following ways:
By adding entities from either a submesh or an existing
group. For this, turn on the Enable manual edition check
box. Select from set of fields allows to select a submesh or
- a group of an appropriate type.
+ a group of the appropriate type.
In the manual edition mode you can
-
click the \b Remove button to remove selected elements from the list
+
click the \b Remove button to remove the selected elements from the list
click the Sort List button to sort the list of IDs of
mesh elements.
@@ -104,7 +104,7 @@ operation.
To create a group on geometry check Group on geometry in the \b
Group \b type field. The group on geometry contains the elements
of a certain type generated on the selected geometrical object. Group
-contents is dynamically updated if the mesh is modified.
+contents are dynamically updated if the mesh is modified.
To define a group, select in the Objet Browser or in the 3D viewer a
geometrical object from which the elements will be taken. After
confirmation of the operation a new group of mesh elements will be
@@ -121,12 +121,11 @@ created.
operation.
-
\anchor group_on_filter
"Group on Filter"
To create a group on filter check Group on filter in the
Group type field. The group on filter contains the elements
-of a certain type satisfying the defined filter. Group contents is
+of a certain type satisfying the defined filter. Group contents are
dynamically updated if the mesh is modified. To define a group,
click the Set filter button and define criteria of the
filter in the opened dialog. After confirmation of the operation a
diff --git a/doc/salome/gui/SMESH/input/editing_groups.doc b/doc/salome/gui/SMESH/input/editing_groups.doc
index d59bdcb10..ca9b7a222 100644
--- a/doc/salome/gui/SMESH/input/editing_groups.doc
+++ b/doc/salome/gui/SMESH/input/editing_groups.doc
@@ -15,7 +15,7 @@ The following dialog box will appear:
\image html editgroup.png
In this dialog box you can modify the name and the color of your group
-despite of it's type. You can add or remove the elements forming the
+despite of its type. You can add or remove the elements forming a
standalone group. You can change criteria of the filter of
the group on filter. For more information see
\ref creating_groups_page "Creating Groups" page.
@@ -35,8 +35,8 @@ Standalone item.
\image html image74.gif
"Edit Group as Standalone" button
-The selected group will be converted into a standalone group and can
-it's contents can be modified.
+The selected group will be converted into a standalone group and
+its contents can be modified.
Click the \b Apply or Apply and Close button to confirm modification of the
group.
diff --git a/doc/salome/gui/SMESH/input/ghs3d_hypo.doc b/doc/salome/gui/SMESH/input/ghs3d_hypo.doc
index c2216427b..dfd0041f5 100644
--- a/doc/salome/gui/SMESH/input/ghs3d_hypo.doc
+++ b/doc/salome/gui/SMESH/input/ghs3d_hypo.doc
@@ -122,7 +122,8 @@ for ghs3d, for example, advanced options.
\anchor ghs3d_enforced_vertices
Enforced vertices
-\note This feature is currently only available on meshes with no geometry attached. Such meshes can be obtained by
+\note This feature is currently available only on meshes with no
+geometry attached. Such meshes can be obtained by
Copying an existing mesh
Importing a mesh from file
@@ -131,7 +132,8 @@ for ghs3d, for example, advanced options.
\image html ghs3d_enforced_vertices.png
-GHS3D algorithm can locally make the mesh finer. It is possible to define enforced vertices in the volume where the mesh will be detailed.
+GHS3D algorithm can locally make the mesh finer. It is possible to
+define enforced vertices in the volume where the mesh will be detailed.
A node will be created at the enforced vertex coordinates.
An enforced vertex is defined by:
@@ -142,14 +144,16 @@ An enforced vertex is defined by:
or from (x,y,z) cartesian coordinates
A constant physical size
-
If a group name is given, the created node will be added to the group. If the group does not exist, it is created.
+
If a group name is given, the created node will be added to the
+group. If the group does not exist, it is created.
\ref ghs3d_top "Back to top"
\anchor ghs3d_enforced_meshes
Enforced Meshes
-\note This feature is currently only available on meshes with no geometry attached. Such meshes can be obtained by
+\note This feature is currently only available on meshes with no
+geometry attached. Such meshes can be obtained by
Copying an existing mesh
Importing a mesh from file
@@ -158,8 +162,9 @@ An enforced vertex is defined by:
\image html ghs3d_enforced_meshes.png
-GHS3D algorithm can be forced by other meshes, sub-meshes or groups. The constraint elements should be contained
-entirely into the solid meshed.
+GHS3D algorithm can be forced by other meshes, sub-meshes or
+groups. The constraint elements should be contained
+entirely into the solid mesh.
The constraint element types are:
@@ -167,8 +172,10 @@ entirely into the solid meshed.
EDGE
FACE
-
If a size is given, the meshe will be refined around the enforced elements given the size
-
If a group name is given, the enforced elements will be added to the group. If the group does not exist, it is created.
+
If a size is given, the mesh will be refined around the enforced
+elements given the size
+
If a group name is given, the enforced elements will be added to
+the group. If the group does not exist, it is created.
See Also a sample TUI Script of the \ref tui_ghs3d "creation of a Ghs3D hypothesis", including enforced vertices.
diff --git a/doc/salome/gui/SMESH/input/grouping_elements.doc b/doc/salome/gui/SMESH/input/grouping_elements.doc
index 8d0754630..9615ad4c3 100644
--- a/doc/salome/gui/SMESH/input/grouping_elements.doc
+++ b/doc/salome/gui/SMESH/input/grouping_elements.doc
@@ -6,39 +6,33 @@ In Mesh module it is possible to create groups of mesh elements:
nodes, edges, faces or volumes. One group contains elements of only
one type. The following ways of creation are possible:
-
-
by selecting the elements using filters and/or
- directly on the presentation in the VTK viewer, and/or by using
- elements of other mesh objects - Standalone group tab of
- \ref standalone_group "Create group" dialog.
-
by creating a group of elements generated on the chosen
- geometrical object - Group on geometry tab of \ref
- creating_groups_page "Create group" dialog and \ref
- create_groups_from_geometry_page "Create Groups from Geometry"
- dialog.
-
by creating a group of elements satisfying to certain critaria -
- Group on filter tab of \ref creating_groups_page
- "Create group" dialog.
-
by creating groups of nodes and elements from the chosen submesh
+- by selecting the elements using filters and/or directly on the
+ presentation in the VTK viewer, and/or by using elements of other
+ mesh objects - \ref standalone_group "Standalone group"
+ tab of \ref creating_groups_page "Create group" dialog.
+- by creating a group of elements generated on the chosen geometrical
+ object - \ref group_on_geom "Group on geometry" tab of
+ \subpage creating_groups_page "Create group" dialog and
+ \subpage create_groups_from_geometry_page "Create Groups from Geometry"
+ dialog.
+- by creating a group of elements satisfying to certain criteria -
+ \ref group_on_filter "Group on filter" tab of
+ \subpage creating_groups_page "Create group" dialog.
+- by creating groups of nodes and elements from the chosen submesh
(type of elements depends on dimension of submesh geometry) -
- using Mesh -> Construct Group menu item (available in contextual
- menu as well).
-
by creating groups of entities from existing groups of superior
+ using Mesh -> Construct Group menu item (available in context
+ menu as well).
+- by creating groups of entities from existing groups of superior
dimensions - using \subpage group_of_underlying_elements_page
- "Create Group of Underlying Elements" dialog.
-
-
+ "Create Group of Underlying Elements" dialog.
The created groups can be later:
-
-
\subpage editing_groups_page "Edited"
-
\subpage using_operations_on_groups_page "Subjected to Boolean operations"
-
\subpage deleting_groups_page "Deleted"
-
+- \subpage editing_groups_page "Edited"
+- \subpage using_operations_on_groups_page "Subjected to Boolean operations"
+- \subpage deleting_groups_page "Deleted"
An important tool, providing filters for creation of \b Standalone
groups is \ref selection_filter_library_page.
-
*/
diff --git a/doc/salome/gui/SMESH/input/make_2dmesh_from_3d.doc b/doc/salome/gui/SMESH/input/make_2dmesh_from_3d.doc
index 0ab41a24d..a53257eef 100644
--- a/doc/salome/gui/SMESH/input/make_2dmesh_from_3d.doc
+++ b/doc/salome/gui/SMESH/input/make_2dmesh_from_3d.doc
@@ -7,7 +7,7 @@ elements of a higher dimension.
To generate border elements:
-
Select a mesh or groups in the Object Browser or in the 3D Viewer
+
Select a mesh or group in the Object Browser or in the 3D Viewer
From the Modification menu choose "Create boundary elements"
item, or click "Create boundary elements" button in the toolbar
diff --git a/doc/salome/gui/SMESH/input/max_element_length_2d.doc b/doc/salome/gui/SMESH/input/max_element_length_2d.doc
index 933ac55ee..6ec4f7116 100644
--- a/doc/salome/gui/SMESH/input/max_element_length_2d.doc
+++ b/doc/salome/gui/SMESH/input/max_element_length_2d.doc
@@ -2,9 +2,8 @@
\page max_element_length_2d_page Element Diameter 2D
-\n This quality control criterion consists of calculation of length of
-the edges and diagonals combining the meshing elements (triangles and quadrangles)
-of your mesh.
+\n This quality control criterion consists in calculation of the length of
+edges and diagonals combining 2D mesh elements (triangles and quadrangles).
To apply the Element Diameter 2D quality criterion to your mesh:
@@ -26,4 +25,4 @@ applied mesh quality control criterion:
See Also a sample TUI Script of a
\ref tui_max_element_length_2d "Element Diameter 2D quality control" operation.
-*/
\ No newline at end of file
+*/
diff --git a/doc/salome/gui/SMESH/input/max_element_length_3d.doc b/doc/salome/gui/SMESH/input/max_element_length_3d.doc
index 9326ad837..7aa70ad7b 100644
--- a/doc/salome/gui/SMESH/input/max_element_length_3d.doc
+++ b/doc/salome/gui/SMESH/input/max_element_length_3d.doc
@@ -2,10 +2,9 @@
\page max_element_length_3d_page Element Diameter 3D
-\n This quality control criterion consists of calculation of length of
-the edges and diagonals combining the 3D meshing elements
-(tetrahedrons, pyramids, pentahendrons, hexahedrons and polyhedrons)
-of your mesh.
+\n This quality control criterion consists in calculation of the length of
+edges and diagonals combining 3D mesh elements
+(tetrahedrons, pyramids, pentahendrons, hexahedrons and polyhedrons).
To apply the Element Diameter 3D quality criterion to your mesh:
@@ -27,4 +26,4 @@ applied mesh quality control criterion:
See Also a sample TUI Script of a
\ref tui_max_element_length_3d "Element Diameter 3D quality control" operation.
-*/
\ No newline at end of file
+*/
diff --git a/doc/salome/gui/SMESH/input/measurements.doc b/doc/salome/gui/SMESH/input/measurements.doc
index 27894a49a..6514cf287 100644
--- a/doc/salome/gui/SMESH/input/measurements.doc
+++ b/doc/salome/gui/SMESH/input/measurements.doc
@@ -2,19 +2,19 @@
\page measurements_page Measurements
-Mesh module provides possibility to perform different measurements
+Mesh module provides the possibility to perform different measurements
of the selected mesh data.
-All the measurement operations are available via \b Measurements
-top-level menu. An access to the measurements operations is
-implemented via single dialog box, where each operation is represented
+All measurement operations are available via \b Measurements
+top-level menu. Access to the measurements operations is
+implemented via a single dialog box, where each operation is represented
as a separate tab page.
\section min_distance_anchor Minimum Distance
-This operation allows measuring a distance between two objects.
+This operation allows measuring the distance between two objects.
Currently only node-to-node and node-to-origin operations are
-available, but this operation will be extended in future to support
+available, but this operation will be extended in the future to support
other mesh objects - elements, meshes, sub-meshes and groups.
To start Minimum Distance operation, select Minimum Distance
@@ -22,9 +22,9 @@ item from \b Measurements menu.
\image html min_distance.png
-In the dialog box choose the first target and second target mode by
-switching the corresponding radio buttons, then select the objects
-between which the distance is to be calculated (or enter directly IDs
+In the dialog box choose the first target and the second target mode by
+switching the corresponding radio buttons, then select the objects the distance
+between which is to be calculated (or input their IDs directly
in case of nodes/elements) and press \em Compute button.
The following types of targets are supported:
@@ -35,7 +35,7 @@ version);
- \em Origin: origin of the global co-ordinate system.
The result will
-be shown in the bottom area of the dialog box. In addition, the simple
+be shown in the bottom area of the dialog box. In addition, a simple
preview will be shown in the 3D viewer.
\image html min_distance_preview.png
@@ -50,17 +50,16 @@ item from \b Measurements menu.
\image html bnd_box.png
-In the dialog box choose desired type of the object by switching the
-corresponding radio button, select the desired object(s) and press
-\em Compute button.
+In the dialog box choose the required type of the object by switching the
+corresponding radio button, select the object(s) and press \em Compute button.
The following types of input are available:
-- \em Objects: select one or more mesh, sub-mesh, group objects;
-- \em Nodes: select set of mesh nodes;
-- \em Elements: select set of mesh elements.
+- \em Objects: select one or several mesh, sub-mesh or group objects;
+- \em Nodes: select a set of mesh nodes;
+- \em Elements: select a set of mesh elements.
The result of calculation will be shown in the bottom area of the
-dialog box. In addition, the simple preview will be shown in the 3D
+dialog box. In addition, a simple preview will be shown in the 3D
viewer.
\image html bnd_box_preview.png
diff --git a/doc/salome/gui/SMESH/input/mesh_infos.doc b/doc/salome/gui/SMESH/input/mesh_infos.doc
index 1a34bc48b..06a02d2cc 100644
--- a/doc/salome/gui/SMESH/input/mesh_infos.doc
+++ b/doc/salome/gui/SMESH/input/mesh_infos.doc
@@ -2,7 +2,7 @@
\page mesh_infos_page Mesh Information
-The user can obtain an information about the selected mesh object
+The user can obtain information about the selected mesh object
(mesh, sub-mesh or group) using Mesh Information dialog box.
To view the Mesh Information, select your mesh, sub-mesh or
@@ -14,12 +14,12 @@ in the toolbar.
"Mesh Information" button
The Mesh Information dialog box provides three tab pages:
-- \ref advanced_mesh_infos_anchor "Base Info" - to show base information about selected mesh
-object
-- \ref mesh_element_info_anchor "Element Info" - to show detail information about selected mesh
-node or element.
+- \ref advanced_mesh_infos_anchor "Base Info" - to show base
+information about the selected mesh object
+- \ref mesh_element_info_anchor "Element Info" - to show
+detailed information about the selected mesh node or element.
- \ref mesh_addition_info_anchor "Additional Info" - to show additional information available
-for selected mesh, sub-mesh or group object.
+for the selected mesh, sub-mesh or group object.
\anchor advanced_mesh_infos_anchor
Base Information
@@ -56,7 +56,7 @@ The Additional Info tab page of the dialog box provides an
additional information on the selected object: mesh, sub-mesh or
group.
-For mesh object, the following information is shown:
+For a mesh object, the following information is shown:
- Name
- Type: based on geomerty, imported, standalone
- Shape (if mesh is based on geometry)
@@ -68,7 +68,7 @@ For mesh object, the following information is shown:
"Additional Info" page, mesh information
-For sub-mesh object, the following information is shown:
+For a sub-mesh object, the following information is shown:
- Name
- Parent mesh
- Shape
@@ -77,7 +77,7 @@ For sub-mesh object, the following information is shown:
"Additional Info" page, sub-mesh information
-For group object, the following information is shown:
+For a group object, the following information is shown:
- Name
- Parent mesh
- Type: standalone, group on geometry, group on filter
@@ -90,12 +90,12 @@ For group object, the following information is shown:
"Additional Info" page, group information
-\note For the performance reasons, number of underlying nodes is
+\note For the performance reasons, the number of underlying nodes is
computed only by demand. For this, the user should press the "Compute"
-button (see picture). Also, number of underlying nodes is
+button (see picture). Also, the number of underlying nodes is
automatically calculated if the size of the group does not exceed
-limit set via the preferences - "Mesh information" group,
-"Automatic nodes compute limit" item (zero value means no limit).
+the "Automatic nodes compute limit" set via the "Mesh information"
+preferences (zero value means no limit).
In case you get Mesh Information via a TUI script, the information is
displayed in the Python Console.
diff --git a/doc/salome/gui/SMESH/input/over_constrained_faces.doc b/doc/salome/gui/SMESH/input/over_constrained_faces.doc
index ca00dbd1a..6c026f84a 100644
--- a/doc/salome/gui/SMESH/input/over_constrained_faces.doc
+++ b/doc/salome/gui/SMESH/input/over_constrained_faces.doc
@@ -2,9 +2,11 @@
\page over_constrained_faces_page Over-constrained faces
-\n This mesh quality control highlights faces sharing only one of its borders with other faces. In other words the faces having all there nodes on the external border of the mesh are highlighted.
+\n This mesh quality control highlights faces sharing only one border
+with other faces. In other words, the faces having all thier nodes on
+the external border of the mesh are highlighted.
-\note The highlighted faces are actually over constrained only if, at the computation time,
+\note The highlighted faces are actually over-constrained only if, at the computation time,
the boundary conditions on the borders where the nodes are located are all Dirichlet boundary conditions.
\image html over_constrained_faces.png
diff --git a/doc/salome/gui/SMESH/input/over_constrained_volumes.doc b/doc/salome/gui/SMESH/input/over_constrained_volumes.doc
index 9c11ebb0c..7f1ba280d 100644
--- a/doc/salome/gui/SMESH/input/over_constrained_volumes.doc
+++ b/doc/salome/gui/SMESH/input/over_constrained_volumes.doc
@@ -2,10 +2,10 @@
\page over_constrained_volumes_page Over-constrained volumes
-\n This mesh quality control highlights volumes sharing only one of its borders with other volumes.
-In other words the volumes having all there nodes on the external border of the mesh are highlighted.
+\n This mesh quality control highlights volumes sharing only one border with other volumes.
+In other words, the volumes having all their nodes on the external border of the mesh are highlighted.
-\note The highlighted volumes are actually over constrained only if, at the computation time,
+\note The highlighted volumes are actually over-constrained only if, at the computation time,
the boundary conditions on the borders where the nodes are located are all Dirichlet boundary conditions.
\image html over_constrained_volumes.png
@@ -15,4 +15,4 @@ In this picture the over-constrained volume is displayed in red.
See Also a sample TUI Script of a
\ref tui_over_constrained_volumes "Over-constrained volumes" filter.
-*/
\ No newline at end of file
+*/
diff --git a/doc/salome/gui/SMESH/input/projection_algos.doc b/doc/salome/gui/SMESH/input/projection_algos.doc
index 69ea855d6..dcbae8db4 100644
--- a/doc/salome/gui/SMESH/input/projection_algos.doc
+++ b/doc/salome/gui/SMESH/input/projection_algos.doc
@@ -26,7 +26,7 @@ the created \b Edge.
For a group of edges, Source and Target vertices should be
shared by one edge of the group. If Source and Target
-vertices are specified, the elements of the group must be ajacent.
+vertices are specified, the elements of the group must be adjacent.
The source and target groups must contain equal number of edges
and they must form topologically equal structures.
@@ -56,13 +56,12 @@ For groups of face, they must contain equal number of faces
and they must form topologically equal structures.
\n Projection 1D-2D algorithm differs from Projection 2D
-algorithm in one point, namely it generates mesh segments on edges of
+algorithm in one aspect: it generates mesh segments on edges of
the face according to the projected 2D elements; thus it does not
-require that edges to be meshed by any other 1D algorithm; moreover it
+require the edges to be meshed by any other 1D algorithm; moreover it
does not allow to mesh edges of the face using another algorithm via
definition of sub-meshes.
-
\n Projection 3D algorithm allows to define the mesh of a shape by
the projection of another already meshed shape. This algorithm works
only if all faces and edges of the target shape have been meshed as 1D-2D
diff --git a/doc/salome/gui/SMESH/input/selection_filter_library.doc b/doc/salome/gui/SMESH/input/selection_filter_library.doc
index 823643d80..0e83703c4 100644
--- a/doc/salome/gui/SMESH/input/selection_filter_library.doc
+++ b/doc/salome/gui/SMESH/input/selection_filter_library.doc
@@ -180,7 +180,7 @@ normal to the neighboring face and the normal to the selected face is less then
angular tolerance (defined in degrees). Selection continues among all neighbor faces of already
selected ones.
-Element Diameter 2D selects triangles and quadrangles combining of the edges and
+Element Diameter 2D selects triangles and quadrangles composed of the edges and
diagonals with a value of length, which is more, less or equal
(within a given Tolerance) to the predefined Threshold Value. See also a
\ref max_element_length_2d_page "Element Diameter 2D quality control".
@@ -197,7 +197,7 @@ Additional criteria to select mesh Volumes are the following:
\ref volume_page "Volume quality control"), which is more, less or equal (within a given
Tolerance) to the predefined Threshold Value.
-Element Diameter 3D selects 3D mesh elements combining of the edges and
+Element Diameter 3D selects 3D mesh elements composed of the edges and
diagonals with a value of length, which is more, less or equal
(within a given Tolerance) to the predefined Threshold Value. See also a
\ref max_element_length_3d_page "Element Diameter 3D quality control".
diff --git a/doc/salome/gui/SMESH/input/smeshpy_interface.doc b/doc/salome/gui/SMESH/input/smeshpy_interface.doc
index a677107cf..84663c93d 100644
--- a/doc/salome/gui/SMESH/input/smeshpy_interface.doc
+++ b/doc/salome/gui/SMESH/input/smeshpy_interface.doc
@@ -130,6 +130,7 @@ Examples of Python scripts for all Mesh operations are available by
the following links:
- \subpage tui_creating_meshes_page
+- \subpage tui_cartesian_algo
- \subpage tui_viewing_meshes_page
- \subpage tui_defining_hypotheses_page
- \subpage tui_quality_controls_page
diff --git a/doc/salome/gui/SMESH/input/tui_cartesian_algo.doc b/doc/salome/gui/SMESH/input/tui_cartesian_algo.doc
new file mode 100644
index 000000000..f1218439b
--- /dev/null
+++ b/doc/salome/gui/SMESH/input/tui_cartesian_algo.doc
@@ -0,0 +1,49 @@
+/*!
+
+\page tui_cartesian_algo Usage of Body Fitting algorithm
+
+\code
+from smesh import *
+SetCurrentStudy(salome.myStudy)
+
+# create a sphere
+sphere = geompy.MakeSphereR( 50 )
+geompy.addToStudy( sphere, "sphere" )
+
+# create a mesh and assign a "Body Fitting" algo
+mesh = Mesh( sphere )
+cartAlgo = mesh.BodyFitted()
+
+# define a cartesian grid using Coordinates
+coords = range(-100,100,10)
+cartHyp = cartAlgo.SetGrid( coords,coords,coords, 1000000)
+
+# compute the mesh
+mesh.Compute()
+print "nb hexahedra",mesh.NbHexas()
+print "nb tetrahedra",mesh.NbTetras()
+print "nb polyhedra",mesh.NbPolyhedrons()
+print
+
+# define the grid by sitting constant spacing
+cartHyp = cartAlgo.SetGrid( "10","10","10", 1000000)
+
+mesh.Compute()
+print "nb hexahedra",mesh.NbHexas()
+print "nb tetrahedra",mesh.NbTetras()
+print "nb polyhedra",mesh.NbPolyhedrons()
+
+
+# define the grid by sitting different spacing in 2 sub-ranges of geometry
+spaceFuns = ["5","10+10*t"]
+cartAlgo.SetGrid( [spaceFuns, [0.5]], [spaceFuns, [0.5]], [spaceFuns, [0.25]], 2 )
+
+mesh.Compute()
+print "nb hexahedra",mesh.NbHexas()
+print "nb tetrahedra",mesh.NbTetras()
+print "nb polyhedra",mesh.NbPolyhedrons()
+print
+
+\endcode
+
+*/
diff --git a/doc/salome/gui/SMESH/input/use_existing_algos.doc b/doc/salome/gui/SMESH/input/use_existing_algos.doc
index 9f77b3b62..3634ccf60 100644
--- a/doc/salome/gui/SMESH/input/use_existing_algos.doc
+++ b/doc/salome/gui/SMESH/input/use_existing_algos.doc
@@ -3,9 +3,9 @@
\page import_algos_page Use Existing Elements Algorithms
\n Use Existing Elements algorithms allow to define the mesh of a geometrical
-object by the importing suitably located mesh elements from another
-mesh. The mesh elements to import from the other mesh are to be contained in
-groups. If several groups are used to mesh one geometry, validity of
+object by importing suitably located mesh elements from another
+mesh. The mesh elements to import from the other mesh should be contained in
+groups. If several groups are used to mesh the same geometry, validity of
nodal connectivity of result mesh must be assured by connectivity of
the source mesh; no geometrical checks are performed to merge
different nodes at same locations.
@@ -32,9 +32,9 @@ In this dialog box you can define
The \b Name of the algorithm.
The Groups of Edges to import 1D elements from.
-
The To copy mesh checkbox is to import not only the edges of
-the selected Groups of Edges but to copy the whole source
-mesh. In this case To copy groups, if checked, forces creating
+
To copy mesh checkbox allows to import not only the edges of
+the selected Groups of Edges, but the whole source
+mesh. In this case To copy groups checkbox allows to create
the same groups as in the imported source mesh.
@@ -52,10 +52,10 @@ The following dialog box will appear:
In this dialog box you can define
The \b Name of the algorithm.
-
The Groups of Faces to import 2D elements from.
-
The To copy mesh checkbox is to import not only the faces of
-the selected Groups of Faces but to copy the whole source
-mesh. In this case To copy groups, if checked, forces creating
+
The Groups of Edges to import 1D elements from.
+
To copy mesh checkbox allows to import not only the edges of
+the selected Groups of Edges, but the whole source
+mesh. In this case To copy groups checkbox allows to create
the same groups as in the imported source mesh.
diff --git a/doc/salome/tui/Makefile.am b/doc/salome/tui/Makefile.am
index d5e3e13ee..e35ac049b 100644
--- a/doc/salome/tui/Makefile.am
+++ b/doc/salome/tui/Makefile.am
@@ -23,7 +23,7 @@
#
include $(top_srcdir)/adm_local/unix/make_common_starter.am
-EXTRA_DIST += images static/doxygen.css static/footer.html
+EXTRA_DIST += input images static/doxygen.css static/footer.html
tuidocdir = $(docdir)/tui/SMESH
tuidoc_DATA = images/head.png images/smeshscreen.png
diff --git a/doc/salome/tui/static/myheader.html b/doc/salome/tui/static/myheader.html
deleted file mode 100755
index d2efb75fa..000000000
--- a/doc/salome/tui/static/myheader.html
+++ /dev/null
@@ -1,13 +0,0 @@
-
-
-
-
-
- Main Page
-
-
-
-
-
-
-
diff --git a/idl/SMESH_MeshEditor.idl b/idl/SMESH_MeshEditor.idl
index 8ee52b341..e461074de 100644
--- a/idl/SMESH_MeshEditor.idl
+++ b/idl/SMESH_MeshEditor.idl
@@ -1031,7 +1031,8 @@ module SMESH
* \return TRUE if operation has been completed successfully, FALSE otherwise
*/
boolean DoubleNodesOnGroupBoundaries( in ListOfGroups theDomains,
- in boolean createJointElems );
+ in boolean createJointElems )
+ raises (SALOME::SALOME_Exception);
/*!
* \brief Double nodes on some external faces and create flat elements.
diff --git a/src/MEFISTO2/Makefile.am b/src/MEFISTO2/Makefile.am
index 846e441c9..1e02043bf 100644
--- a/src/MEFISTO2/Makefile.am
+++ b/src/MEFISTO2/Makefile.am
@@ -51,3 +51,6 @@ libMEFISTO2D_la_LDFLAGS = \
#libMEFISTO2D_la_LDFLAGS += -lg2c
#endif
+OBSOLETE_FILES = areteideale.f
+
+EXTRA_DIST += $(OBSOLETE_FILES)
diff --git a/src/OBJECT/Makefile.am b/src/OBJECT/Makefile.am
index 0264d62eb..6b38c0ca4 100644
--- a/src/OBJECT/Makefile.am
+++ b/src/OBJECT/Makefile.am
@@ -35,7 +35,9 @@ salomeinclude_HEADERS = \
SMESH_PreviewActorsCollection.h \
SMESH_ExtractGeometry.h \
SMESH_FaceOrientationFilter.h \
- SMESH_ScalarBarActor.h
+ SMESH_ScalarBarActor.h \
+ SMESH_NodeLabelActor.h \
+ SMESH_CellLabelActor.h
# Libraries targets
@@ -48,7 +50,9 @@ dist_libSMESHObject_la_SOURCES = \
SMESH_ExtractGeometry.cxx \
SMESH_ActorUtils.cxx \
SMESH_FaceOrientationFilter.cxx \
- SMESH_ScalarBarActor.cxx
+ SMESH_ScalarBarActor.cxx \
+ SMESH_NodeLabelActor.cxx \
+ SMESH_CellLabelActor.cxx
libSMESHObject_la_CPPFLAGS = \
$(QT_INCLUDES) \
diff --git a/src/OBJECT/SMESH_Actor.cxx b/src/OBJECT/SMESH_Actor.cxx
index 8a4df7dbb..4d5dcfd11 100644
--- a/src/OBJECT/SMESH_Actor.cxx
+++ b/src/OBJECT/SMESH_Actor.cxx
@@ -28,11 +28,12 @@
#include "SMESH_ActorDef.h"
#include "SMESH_ActorUtils.h"
#include "SMESH_DeviceActor.h"
+#include "SMESH_NodeLabelActor.h"
+#include "SMESH_CellLabelActor.h"
#include "SMESH_ObjectDef.h"
#include "SMESH_ControlsDef.hxx"
#include "SMDS_UnstructuredGrid.hxx"
#include "SMESH_ScalarBarActor.h"
-#include "VTKViewer_CellCenters.h"
#include "VTKViewer_ExtractUnstructuredGrid.h"
#include "VTKViewer_FramedTextActor.h"
#include "SALOME_InteractiveObject.hxx"
@@ -67,10 +68,7 @@
#include
#include
#include
-#include
#include
-#include
-#include
#include
@@ -121,7 +119,8 @@ SMESH_Actor* SMESH_Actor::New(TVisualObjPtr theVisualObj,
SMESH_ActorDef::SMESH_ActorDef()
{
- if(MYDEBUG) MESSAGE("SMESH_ActorDef - "<SetColor( bfc.red() / 255. , bfc.green() / 255. , bfc.blue() / 255. );
- my2DActor = SMESH_DeviceActor::New();
+ my2DActor = SMESH_CellLabelActor::New();
+ my2DActor->SetStoreGemetryMapping(true);
my2DActor->SetUserMatrix(aMatrix);
my2DActor->PickableOff();
my2DActor->SetProperty(mySurfaceProp);
@@ -193,7 +193,8 @@ SMESH_ActorDef::SMESH_ActorDef()
aFilter->RegisterCellsWithType(VTK_QUADRATIC_TRIANGLE);
aFilter->RegisterCellsWithType(VTK_QUADRATIC_QUAD);
- my3DActor = SMESH_DeviceActor::New();
+ my3DActor = SMESH_CellLabelActor::New();
+ my3DActor->SetStoreGemetryMapping(true);
my3DActor->SetUserMatrix(aMatrix);
my3DActor->PickableOff();
my3DActor->SetProperty(mySurfaceProp);
@@ -246,7 +247,8 @@ SMESH_ActorDef::SMESH_ActorDef()
myEdgeProp->SetColor(anRGB[0],anRGB[1],anRGB[2]);
myEdgeProp->SetLineWidth(aLineWidth);
- my1DActor = SMESH_DeviceActor::New();
+ my1DActor = SMESH_CellLabelActor::New();
+ my1DActor->SetStoreGemetryMapping(true);
my1DActor->SetUserMatrix(aMatrix);
my1DActor->PickableOff();
my1DActor->SetHighlited(true);
@@ -291,9 +293,9 @@ SMESH_ActorDef::SMESH_ActorDef()
my0DProp->SetColor(anRGB[0],anRGB[1],anRGB[2]);
my0DProp->SetPointSize(aElem0DSize);
- my0DActor = SMESH_DeviceActor::New();
+ my0DActor = SMESH_CellLabelActor::New();
my0DActor->SetUserMatrix(aMatrix);
- my0DActor->SetStoreClippingMapping(true);
+ my0DActor->SetStoreGemetryMapping(true);
my0DActor->PickableOff();
my0DActor->SetVisibility(false);
my0DActor->SetProperty(my0DProp);
@@ -331,7 +333,7 @@ SMESH_ActorDef::SMESH_ActorDef()
SMESH::GetColor( "SMESH", "node_color", anRGB[0], anRGB[1], anRGB[2], QColor( 255, 0, 0 ) );
myNodeProp->SetColor(anRGB[0],anRGB[1],anRGB[2]);
- myNodeActor = SMESH_DeviceActor::New();
+ myNodeActor = SMESH_NodeLabelActor::New();
myNodeActor->SetUserMatrix(aMatrix);
myNodeActor->SetStoreClippingMapping(true);
myNodeActor->PickableOff();
@@ -363,11 +365,9 @@ SMESH_ActorDef::SMESH_ActorDef()
//Definition of Pickable and Highlitable engines
//----------------------------------------------
- myBaseActor = SMESH_DeviceActor::New();
myBaseActor->SetUserMatrix(aMatrix);
myBaseActor->SetStoreGemetryMapping(true);
myBaseActor->GetProperty()->SetOpacity(0.0);
-
myPickableActor = myBaseActor;
myHighlightProp = vtkProperty::New();
@@ -430,92 +430,12 @@ SMESH_ActorDef::SMESH_ActorDef()
if( !mgr )
return;
- //Definition of points numbering pipeline
- //---------------------------------------
- myPointsNumDataSet = vtkUnstructuredGrid::New();
-
- myPtsMaskPoints = vtkMaskPoints::New();
- myPtsMaskPoints->SetInput(myPointsNumDataSet);
- myPtsMaskPoints->SetOnRatio(1);
-
- myPtsSelectVisiblePoints = vtkSelectVisiblePoints::New();
- myPtsSelectVisiblePoints->SetInput(myPtsMaskPoints->GetOutput());
- myPtsSelectVisiblePoints->SelectInvisibleOff();
- myPtsSelectVisiblePoints->SetTolerance(0.1);
-
- myPtsLabeledDataMapper = vtkLabeledDataMapper::New();
- myPtsLabeledDataMapper->SetInput(myPtsSelectVisiblePoints->GetOutput());
-#if (VTK_XVERSION < 0x050200)
- myPtsLabeledDataMapper->SetLabelFormat("%g");
-#endif
- myPtsLabeledDataMapper->SetLabelModeToLabelScalars();
-
- vtkTextProperty* aPtsTextProp = vtkTextProperty::New();
- aPtsTextProp->SetFontFamilyToTimes();
- static int aPointsFontSize = 10;
- aPtsTextProp->SetFontSize(aPointsFontSize);
- aPtsTextProp->SetBold(1);
- aPtsTextProp->SetItalic(0);
- aPtsTextProp->SetShadow(0);
- myPtsLabeledDataMapper->SetLabelTextProperty(aPtsTextProp);
- aPtsTextProp->Delete();
-
myEntityMode = eAllEntity;
-
- myIsPointsLabeled = false;
-
- myPointLabels = vtkActor2D::New();
- myPointLabels->SetMapper(myPtsLabeledDataMapper);
- myPointLabels->GetProperty()->SetColor(1,1,1);
- myPointLabels->SetVisibility(myIsPointsLabeled);
-
-
- //Definition of cells numbering pipeline
- //---------------------------------------
- myCellsNumDataSet = vtkUnstructuredGrid::New();
-
- myCellCenters = VTKViewer_CellCenters::New();
- myCellCenters->SetInput(myCellsNumDataSet);
-
- myClsMaskPoints = vtkMaskPoints::New();
- myClsMaskPoints->SetInput(myCellCenters->GetOutput());
- myClsMaskPoints->SetOnRatio(1);
-
- myClsSelectVisiblePoints = vtkSelectVisiblePoints::New();
- myClsSelectVisiblePoints->SetInput(myClsMaskPoints->GetOutput());
- myClsSelectVisiblePoints->SelectInvisibleOff();
- myClsSelectVisiblePoints->SetTolerance(0.1);
-
- myClsLabeledDataMapper = vtkLabeledDataMapper::New();
- myClsLabeledDataMapper->SetInput(myClsSelectVisiblePoints->GetOutput());
-#if (VTK_XVERSION < 0x050200)
- myClsLabeledDataMapper->SetLabelFormat("%g");
-#endif
- myClsLabeledDataMapper->SetLabelModeToLabelScalars();
-
- vtkTextProperty* aClsTextProp = vtkTextProperty::New();
- aClsTextProp->SetFontFamilyToTimes();
- static int aCellsFontSize = 12;
- aClsTextProp->SetFontSize(aCellsFontSize);
- aClsTextProp->SetBold(1);
- aClsTextProp->SetItalic(0);
- aClsTextProp->SetShadow(0);
- myClsLabeledDataMapper->SetLabelTextProperty(aClsTextProp);
- aClsTextProp->Delete();
-
- myIsCellsLabeled = false;
-
- myCellsLabels = vtkActor2D::New();
- myCellsLabels->SetMapper(myClsLabeledDataMapper);
- myCellsLabels->GetProperty()->SetColor(0,1,0);
- myCellsLabels->SetVisibility(myIsCellsLabeled);
-
+
// Clipping planes
myImplicitBoolean = vtkImplicitBoolean::New();
myImplicitBoolean->SetOperationTypeToIntersection();
-
-
//Quadratic 2D elements representation
//-----------------------------------------------------------------------------
int aQuadratic2DMode = mgr->integerValue( "SMESH", "quadratic_mode", 0);
@@ -596,50 +516,9 @@ SMESH_ActorDef::~SMESH_ActorDef()
myNodeActor->Delete();
myBaseActor->Delete();
- myNodeExtActor->Delete();
-
+ myNodeExtActor->Delete();
myHighlitableActor->Delete();
- //Deleting of points numbering pipeline
- //---------------------------------------
- myPointsNumDataSet->Delete();
-
- // commented: porting to vtk 5.0
- // myPtsLabeledDataMapper->RemoveAllInputs();
- myPtsLabeledDataMapper->Delete();
-
- // commented: porting to vtk 5.0
- // myPtsSelectVisiblePoints->UnRegisterAllOutputs();
- myPtsSelectVisiblePoints->Delete();
-
- // commented: porting to vtk 5.0
- // myPtsMaskPoints->UnRegisterAllOutputs();
- myPtsMaskPoints->Delete();
-
- myPointLabels->Delete();
-
-
- //Deleting of cells numbering pipeline
- //---------------------------------------
- myCellsNumDataSet->Delete();
-
- myClsLabeledDataMapper->RemoveAllInputs();
- myClsLabeledDataMapper->Delete();
-
- // commented: porting to vtk 5.0
- // myClsSelectVisiblePoints->UnRegisterAllOutputs();
- myClsSelectVisiblePoints->Delete();
-
- // commented: porting to vtk 5.0
- // myClsMaskPoints->UnRegisterAllOutputs();
- myClsMaskPoints->Delete();
-
- // commented: porting to vtk 5.0
- // myCellCenters->UnRegisterAllOutputs();
- myCellCenters->Delete();
-
- myCellsLabels->Delete();
-
myImplicitBoolean->Delete();
myTimeStamp->Delete();
@@ -648,61 +527,50 @@ SMESH_ActorDef::~SMESH_ActorDef()
void SMESH_ActorDef::SetPointsLabeled( bool theIsPointsLabeled )
{
- vtkUnstructuredGrid* aGrid = GetUnstructuredGrid();
-
- myIsPointsLabeled = theIsPointsLabeled && aGrid->GetNumberOfPoints();
+ if(myNodeActor) {
+ myNodeActor->SetPointsLabeled(theIsPointsLabeled);
+ SetRepresentation(GetRepresentation());
+ myTimeStamp->Modified();
+ }
+}
- if ( myIsPointsLabeled )
- {
- myPointsNumDataSet->ShallowCopy(aGrid);
- vtkDataSet *aDataSet = myPointsNumDataSet;
-
- int aNbElem = aDataSet->GetNumberOfPoints();
-
- vtkIntArray *anArray = vtkIntArray::New();
- anArray->SetNumberOfValues( aNbElem );
-
- for ( vtkIdType anId = 0; anId < aNbElem; anId++ )
- {
- int aSMDSId = myVisualObj->GetNodeObjId( anId );
- anArray->SetValue( anId, aSMDSId );
- }
-
- aDataSet->GetPointData()->SetScalars( anArray );
- anArray->Delete();
- myPtsMaskPoints->SetInput( aDataSet );
- myPointLabels->SetVisibility( GetVisibility() );
- }
- else
- {
- myPointLabels->SetVisibility( false );
- }
- SetRepresentation(GetRepresentation());
+bool SMESH_ActorDef::GetPointsLabeled() {
+ return myNodeActor && myNodeActor->GetPointsLabeled();
+}
+
+void SMESH_ActorDef::SetCellsLabeled(bool theIsCellsLabeled)
+{
+ if(my3DActor)
+ my3DActor->SetCellsLabeled(theIsCellsLabeled);
+
+ if(my2DActor)
+ my2DActor->SetCellsLabeled(theIsCellsLabeled);
+
+ if(my1DActor)
+ my1DActor->SetCellsLabeled(theIsCellsLabeled);
+
+ if(my0DActor)
+ my0DActor->SetCellsLabeled(theIsCellsLabeled);
+
myTimeStamp->Modified();
}
-void SMESH_ActorDef::SetCellsLabeled(bool theIsCellsLabeled)
-{
- vtkUnstructuredGrid* aGrid = GetUnstructuredGrid();
- myIsCellsLabeled = theIsCellsLabeled && aGrid->GetNumberOfPoints();
- if(myIsCellsLabeled){
- myCellsNumDataSet->ShallowCopy(aGrid);
- vtkDataSet *aDataSet = myCellsNumDataSet;
- int aNbElem = aDataSet->GetNumberOfCells();
- vtkIntArray *anArray = vtkIntArray::New();
- anArray->SetNumberOfValues(aNbElem);
- for(int anId = 0; anId < aNbElem; anId++){
- int aSMDSId = myVisualObj->GetElemObjId(anId);
- anArray->SetValue(anId,aSMDSId);
- }
- aDataSet->GetCellData()->SetScalars(anArray);
- myCellCenters->SetInput(aDataSet);
- myCellsLabels->SetVisibility(GetVisibility());
- }else{
- myCellsLabels->SetVisibility(false);
- }
- myTimeStamp->Modified();
+bool SMESH_ActorDef::GetCellsLabeled() {
+ bool result = false;
+ if(my3DActor)
+ result = result || my3DActor->GetCellsLabeled();
+
+ if(my2DActor)
+ result = result || my2DActor->GetCellsLabeled();
+
+ if(my1DActor)
+ result = result || my1DActor->GetCellsLabeled();
+
+ if(my0DActor)
+ result = result || my0DActor->GetCellsLabeled();
+
+ return result;
}
@@ -993,32 +861,23 @@ SetControlMode(eControl theMode,
void SMESH_ActorDef::AddToRender(vtkRenderer* theRenderer){
- theRenderer->AddActor(myNodeActor);
- theRenderer->AddActor(myBaseActor);
-
+ theRenderer->AddActor(myBaseActor);
theRenderer->AddActor(myNodeExtActor);
+ theRenderer->AddActor(my1DExtActor);
my3DActor->AddToRender(theRenderer);
my3DExtActor->AddToRender(theRenderer);
my2DActor->AddToRender(theRenderer);
my2DExtActor->AddToRender(theRenderer);
-
- theRenderer->AddActor(my1DActor);
- theRenderer->AddActor(my1DExtActor);
-
- theRenderer->AddActor(my0DActor);
+ myNodeActor->AddToRender(theRenderer);
+ my1DActor->AddToRender(theRenderer);
+ my0DActor->AddToRender(theRenderer);
//theRenderer->AddActor(my0DExtActor);
theRenderer->AddActor(myHighlitableActor);
theRenderer->AddActor2D(myScalarBarActor);
- myPtsSelectVisiblePoints->SetRenderer(theRenderer);
- myClsSelectVisiblePoints->SetRenderer(theRenderer);
-
- theRenderer->AddActor2D(myPointLabels);
- theRenderer->AddActor2D(myCellsLabels);
-
// the superclass' method should be called at the end
// (in particular, for correct work of selection)
SALOME_Actor::AddToRender(theRenderer);
@@ -1027,27 +886,25 @@ void SMESH_ActorDef::AddToRender(vtkRenderer* theRenderer){
void SMESH_ActorDef::RemoveFromRender(vtkRenderer* theRenderer){
SALOME_Actor::RemoveFromRender(theRenderer);
- theRenderer->RemoveActor(myNodeActor);
theRenderer->RemoveActor(myBaseActor);
theRenderer->RemoveActor(myNodeExtActor);
theRenderer->RemoveActor(myHighlitableActor);
- theRenderer->RemoveActor(my0DActor);
//theRenderer->RemoveActor(my0DExtActor);
- theRenderer->RemoveActor(my1DActor);
theRenderer->RemoveActor(my1DExtActor);
my2DActor->RemoveFromRender(theRenderer);
my2DExtActor->RemoveFromRender(theRenderer);
my3DActor->RemoveFromRender(theRenderer);
my3DExtActor->RemoveFromRender(theRenderer);
+ myNodeActor->RemoveFromRender(theRenderer);
+ my0DActor->RemoveFromRender(theRenderer);
+ my1DActor->RemoveFromRender(theRenderer);
theRenderer->RemoveActor(myScalarBarActor);
- theRenderer->RemoveActor(myPointLabels);
- theRenderer->RemoveActor(myCellsLabels);
}
@@ -1306,8 +1163,6 @@ void SMESH_ActorDef::SetVisibility(int theMode, bool theIsUpdateRepersentation){
my3DExtActor->VisibilityOff();
myScalarBarActor->VisibilityOff();
- myPointLabels->VisibilityOff();
- myCellsLabels->VisibilityOff();
if(GetVisibility()){
if(theIsUpdateRepersentation)
@@ -1362,13 +1217,21 @@ void SMESH_ActorDef::SetVisibility(int theMode, bool theIsUpdateRepersentation){
my3DActor->VisibilityOn();
}
- if(myIsPointsLabeled){
- myPointLabels->VisibilityOn();
+ if(myNodeActor->GetPointsLabeled()){
myNodeActor->VisibilityOn();
}
- if(myIsCellsLabeled)
- myCellsLabels->VisibilityOn();
+ if(my0DActor)
+ my0DActor->UpdateLabels();
+
+ if(my1DActor)
+ my1DActor->UpdateLabels();
+
+ if(my2DActor)
+ my2DActor->UpdateLabels();
+
+ if(my3DActor)
+ my3DActor->UpdateLabels();
}
#ifndef DISABLE_PLOT2DVIEWER
else
@@ -1622,7 +1485,7 @@ void SMESH_ActorDef::SetPointRepresentation(bool theIsPointsVisible){
}
bool SMESH_ActorDef::GetPointRepresentation(){
- return myIsPointsVisible || myIsPointsLabeled;
+ return myIsPointsVisible || myNodeActor->GetPointsLabeled();
}
@@ -1637,18 +1500,18 @@ void SMESH_ActorDef::UpdateHighlight(){
case SMESH_DeviceActor::eWireframe:
{
if(myIsHighlighted) {
- myHighlitableActor->SetProperty(myHighlightProp);
+ myHighlitableActor->SetProperty(myHighlightProp);
}else if(myIsPreselected){
- myHighlitableActor->SetProperty(myPreselectProp);
+ myHighlitableActor->SetProperty(myPreselectProp);
} else if(anIsVisible){
- (myRepresentation == eSurface) ?
- myHighlitableActor->SetProperty(myOutLineProp) : myHighlitableActor->SetProperty(myEdgeProp);
+ (myRepresentation == eSurface) ?
+ myHighlitableActor->SetProperty(myOutLineProp) : myHighlitableActor->SetProperty(myEdgeProp);
}
if(GetUnstructuredGrid()->GetNumberOfCells()) {
- myHighlitableActor->SetHighlited(anIsVisible);
- myHighlitableActor->GetExtractUnstructuredGrid()->
- SetModeOfExtraction(VTKViewer_ExtractUnstructuredGrid::eCells);
- myHighlitableActor->SetRepresentation(SMESH_DeviceActor::eWireframe);
+ myHighlitableActor->SetHighlited(anIsVisible);
+ myHighlitableActor->GetExtractUnstructuredGrid()->
+ SetModeOfExtraction(VTKViewer_ExtractUnstructuredGrid::eCells);
+ myHighlitableActor->SetRepresentation(SMESH_DeviceActor::eWireframe);
}
myHighlitableActor->SetVisibility(anIsVisible);
break;
@@ -1656,11 +1519,11 @@ void SMESH_ActorDef::UpdateHighlight(){
case SMESH_DeviceActor::ePoint:
{
if(myIsHighlighted) {
- myNodeActor->SetProperty(myHighlightProp);
+ myNodeActor->SetProperty(myHighlightProp);
}else if(myIsPreselected) {
- myNodeActor->SetProperty(myPreselectProp);
+ myNodeActor->SetProperty(myPreselectProp);
} else if(anIsVisible) {
- myNodeActor->SetProperty(myNodeProp);
+ myNodeActor->SetProperty(myNodeProp);
}
myNodeActor->SetRepresentation(SMESH_DeviceActor::ePoint);
myNodeActor->GetExtractUnstructuredGrid()->SetModeOfExtraction(VTKViewer_ExtractUnstructuredGrid::ePoints);
@@ -1729,12 +1592,22 @@ void SMESH_ActorDef::Update(){
if (anObjTime > aTime)
SetControlMode(GetControlMode(),false);
}
- if(myIsPointsLabeled){
- SetPointsLabeled(myIsPointsLabeled);
- }
- if(myIsCellsLabeled){
- SetCellsLabeled(myIsCellsLabeled);
- }
+
+ if(myNodeActor)
+ myNodeActor->UpdateLabels();
+
+ if(my0DActor)
+ my0DActor->UpdateLabels();
+
+ if(my1DActor)
+ my1DActor->UpdateLabels();
+
+ if(my2DActor)
+ my2DActor->UpdateLabels();
+
+ if(my3DActor)
+ my3DActor->UpdateLabels();
+
if(myIsFacesOriented){
SetFacesOriented(myIsFacesOriented);
}
@@ -1929,6 +1802,7 @@ SMESH_ActorDef::AddClippingPlane(vtkPlane* thePlane)
myCippingPlaneCont.push_back(thePlane);
if(!IsImplicitFunctionUsed())
SetImplicitFunctionUsed(true);
+ myNodeActor->UpdateLabels();
}
return myCippingPlaneCont.size();
}
@@ -1941,6 +1815,7 @@ RemoveAllClippingPlanes()
myImplicitBoolean->GetFunction()->Modified(); // VTK bug
myCippingPlaneCont.clear();
SetImplicitFunctionUsed(false);
+ myNodeActor->UpdateLabels();
}
vtkIdType
diff --git a/src/OBJECT/SMESH_ActorDef.h b/src/OBJECT/SMESH_ActorDef.h
index 5961cbd06..6eec6aa2a 100644
--- a/src/OBJECT/SMESH_ActorDef.h
+++ b/src/OBJECT/SMESH_ActorDef.h
@@ -61,17 +61,14 @@ class vtkMergeFilter;
class vtkPolyData;
class vtkMapper;
class vtkActor2D;
-class vtkMaskPoints;
-class vtkLabeledDataMapper;
-class vtkSelectVisiblePoints;
class vtkLookupTable;
class vtkPlane;
class vtkImplicitBoolean;
class vtkTimeStamp;
-class VTKViewer_CellCenters;
-
class SMESH_DeviceActor;
+class SMESH_NodeLabelActor;
+class SMESH_CellLabelActor;
class SMESH_ScalarBarActor;
#ifndef DISABLE_PLOT2DVIEWER
@@ -167,10 +164,10 @@ class SMESH_ActorDef : public SMESH_Actor
virtual void UnShrink();
virtual void SetPointsLabeled(bool theIsPointsLabeled);
- virtual bool GetPointsLabeled(){ return myIsPointsLabeled;}
+ virtual bool GetPointsLabeled();
virtual void SetCellsLabeled(bool theIsCellsLabeled);
- virtual bool GetCellsLabeled(){ return myIsCellsLabeled;}
+ virtual bool GetCellsLabeled();
virtual void SetFacesOriented(bool theIsFacesOriented);
virtual bool GetFacesOriented();
@@ -232,7 +229,7 @@ class SMESH_ActorDef : public SMESH_Actor
vtkProperty* myNodeProp;
SMESH_DeviceActor* myBaseActor;
- SMESH_DeviceActor* myNodeActor;
+ SMESH_NodeLabelActor* myNodeActor;
SMESH_DeviceActor* myPickableActor;
vtkProperty* myHighlightProp;
@@ -244,9 +241,9 @@ class SMESH_ActorDef : public SMESH_Actor
eControl myControlMode;
SMESH::Controls::FunctorPtr myFunctor;
vtkProperty* my2DExtProp;
- SMESH_DeviceActor* my2DActor;
+ SMESH_CellLabelActor* my2DActor;
SMESH_DeviceActor* my2DExtActor;
- SMESH_DeviceActor* my3DActor;
+ SMESH_CellLabelActor* my3DActor;
SMESH_DeviceActor* my3DExtActor;
SMESH_DeviceActor* myControlActor;
@@ -254,12 +251,12 @@ class SMESH_ActorDef : public SMESH_Actor
SMESH_DeviceActor* myNodeExtActor;
vtkProperty* my1DProp;
- SMESH_DeviceActor* my1DActor;
+ SMESH_CellLabelActor* my1DActor;
vtkProperty* my1DExtProp;
SMESH_DeviceActor* my1DExtActor;
vtkProperty* my0DProp;
- SMESH_DeviceActor* my0DActor;
+ SMESH_CellLabelActor* my0DActor;
vtkProperty* my0DExtProp;
SMESH_DeviceActor* my0DExtActor;
@@ -270,21 +267,6 @@ class SMESH_ActorDef : public SMESH_Actor
bool myIsShrinkable;
bool myIsShrunk;
- bool myIsPointsLabeled;
- vtkUnstructuredGrid* myPointsNumDataSet;
- vtkActor2D *myPointLabels;
- vtkMaskPoints* myPtsMaskPoints;
- vtkLabeledDataMapper* myPtsLabeledDataMapper;
- vtkSelectVisiblePoints* myPtsSelectVisiblePoints;
-
- bool myIsCellsLabeled;
- vtkUnstructuredGrid* myCellsNumDataSet;
- vtkActor2D *myCellsLabels;
- vtkMaskPoints* myClsMaskPoints;
- VTKViewer_CellCenters* myCellCenters;
- vtkLabeledDataMapper* myClsLabeledDataMapper;
- vtkSelectVisiblePoints* myClsSelectVisiblePoints;
-
vtkImplicitBoolean* myImplicitBoolean;
typedef TVTKSmartPtr TPlanePtr;
typedef std::vector TCippingPlaneCont;
diff --git a/src/OBJECT/SMESH_CellLabelActor.cxx b/src/OBJECT/SMESH_CellLabelActor.cxx
new file mode 100644
index 000000000..399bc869f
--- /dev/null
+++ b/src/OBJECT/SMESH_CellLabelActor.cxx
@@ -0,0 +1,185 @@
+// Copyright (C) 2007-2011 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.
+//
+// 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 : SMESH_CellLabelActor.cxx
+// Author : Roman NIKOLAEV
+// Module : SMESH
+//
+#include "SMESH_CellLabelActor.h"
+
+#include
+#include
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+vtkStandardNewMacro(SMESH_CellLabelActor);
+
+/*!
+ Constructor.
+*/
+SMESH_CellLabelActor::SMESH_CellLabelActor() {
+ //Definition of cells numbering pipeline
+ //---------------------------------------
+ myCellsNumDataSet = vtkPolyData::New();
+
+ myCellCenters = VTKViewer_CellCenters::New();
+ myCellCenters->SetInput(myCellsNumDataSet);
+
+ myClsMaskPoints = vtkMaskPoints::New();
+ myClsMaskPoints->SetInput(myCellCenters->GetOutput());
+ myClsMaskPoints->SetOnRatio(1);
+
+ myClsSelectVisiblePoints = vtkSelectVisiblePoints::New();
+ myClsSelectVisiblePoints->SetInput(myClsMaskPoints->GetOutput());
+ myClsSelectVisiblePoints->SelectInvisibleOff();
+ myClsSelectVisiblePoints->SetTolerance(0.1);
+
+ myClsLabeledDataMapper = vtkLabeledDataMapper::New();
+ myClsLabeledDataMapper->SetInput(myClsSelectVisiblePoints->GetOutput());
+
+ myClsLabeledDataMapper->SetLabelFormat("%d");
+ myClsLabeledDataMapper->SetLabelModeToLabelScalars();
+
+ vtkTextProperty* aClsTextProp = vtkTextProperty::New();
+ aClsTextProp->SetFontFamilyToTimes();
+ static int aCellsFontSize = 12;
+ aClsTextProp->SetFontSize(aCellsFontSize);
+ aClsTextProp->SetBold(1);
+ aClsTextProp->SetItalic(0);
+ aClsTextProp->SetShadow(0);
+ myClsLabeledDataMapper->SetLabelTextProperty(aClsTextProp);
+ aClsTextProp->Delete();
+
+ myIsCellsLabeled = false;
+
+ myCellsLabels = vtkActor2D::New();
+ myCellsLabels->SetMapper(myClsLabeledDataMapper);
+ myCellsLabels->GetProperty()->SetColor(0,1,0);
+ myCellsLabels->SetVisibility(myIsCellsLabeled);
+
+ vtkCallbackCommand* callBackCommand = vtkCallbackCommand::New();
+ callBackCommand->SetClientData(this);
+ callBackCommand->SetCallback(SMESH_CellLabelActor::ProcessEvents);
+
+ myTransformFilter->AddObserver("VTKViewer_TransformFilter::TransformationFinished",
+ callBackCommand);
+ callBackCommand->Delete();
+}
+
+
+/*!
+ Destructor.
+*/
+SMESH_CellLabelActor::~SMESH_CellLabelActor() {
+ //Deleting of cells numbering pipeline
+ //---------------------------------------
+ myCellsNumDataSet->Delete();
+
+ myClsLabeledDataMapper->RemoveAllInputs();
+ myClsLabeledDataMapper->Delete();
+
+ // commented: porting to vtk 5.0
+ // myClsSelectVisiblePoints->UnRegisterAllOutputs();
+ myClsSelectVisiblePoints->Delete();
+
+ // commented: porting to vtk 5.0
+ // myClsMaskPoints->UnRegisterAllOutputs();
+ myClsMaskPoints->Delete();
+
+ // commented: porting to vtk 5.0
+ // myCellCenters->UnRegisterAllOutputs();
+ myCellCenters->Delete();
+
+ myCellsLabels->Delete();
+}
+
+
+void SMESH_CellLabelActor::SetCellsLabeled(bool theIsCellsLabeled) {
+ myTransformFilter->Update();
+ vtkPolyData* aGrid = vtkPolyData::SafeDownCast(myTransformFilter->GetOutput());
+ if(!aGrid)
+ return;
+
+ myIsCellsLabeled = theIsCellsLabeled && aGrid->GetNumberOfPoints();
+ if(myIsCellsLabeled){
+ myCellsNumDataSet->ShallowCopy(aGrid);
+ vtkDataSet *aDataSet = myCellsNumDataSet;
+ int aNbElem = aDataSet->GetNumberOfCells();
+ vtkIntArray *anArray = vtkIntArray::New();
+ anArray->SetNumberOfValues(aNbElem);
+ for(int anId = 0; anId < aNbElem; anId++){
+ int aSMDSId = GetElemObjId(anId);
+ anArray->SetValue(anId,aSMDSId);
+ }
+ aDataSet->GetCellData()->SetScalars(anArray);
+ myCellCenters->SetInput(aDataSet);
+ myCellsLabels->SetVisibility(GetVisibility());
+ }else{
+ myCellsLabels->SetVisibility(false);
+ }
+}
+
+void SMESH_CellLabelActor::SetVisibility(int theMode)
+{
+ SMESH_DeviceActor::SetVisibility(theMode);
+ myCellsLabels->VisibilityOff();
+ if(myIsCellsLabeled && theMode)
+ myCellsLabels->VisibilityOn();
+}
+
+void SMESH_CellLabelActor::AddToRender(vtkRenderer* theRenderer)
+{
+ SMESH_DeviceActor::AddToRender(theRenderer);
+ myClsSelectVisiblePoints->SetRenderer(theRenderer);
+ theRenderer->AddActor2D(myCellsLabels);
+}
+
+void SMESH_CellLabelActor::RemoveFromRender(vtkRenderer* theRenderer)
+{
+ theRenderer->RemoveActor(myCellsLabels);
+ SMESH_DeviceActor::RemoveFromRender(theRenderer);
+}
+
+void SMESH_CellLabelActor::UpdateLabels() {
+ if(myIsCellsLabeled)
+ SetCellsLabeled(myIsCellsLabeled);
+}
+
+
+void SMESH_CellLabelActor::ProcessEvents(vtkObject* vtkNotUsed(theObject),
+ unsigned long theEvent,
+ void* theClientData,
+ void* vtkNotUsed(theCallData)) {
+ SMESH_CellLabelActor* self = reinterpret_cast(theClientData);
+ if(self)
+ self->UpdateLabels();
+}
diff --git a/src/OBJECT/SMESH_CellLabelActor.h b/src/OBJECT/SMESH_CellLabelActor.h
new file mode 100644
index 000000000..dda47fea5
--- /dev/null
+++ b/src/OBJECT/SMESH_CellLabelActor.h
@@ -0,0 +1,82 @@
+// Copyright (C) 2007-2011 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.
+//
+// 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 : SMESH_CellLabelActor.h
+// Author : Roman NIKOLAEV
+// Module : SMESH
+//
+#ifndef SMESH_CELL_LABEL_ACTOR_H
+#define SMESH_CELL_LABEL_ACTOR_H
+
+#include "SMESH_DeviceActor.h"
+
+class vtkSelectVisiblePoints;
+class vtkLabeledDataMapper;
+class vtkActor2D;
+class vtkMaskPoints;
+class vtkPolyData;
+
+class VTKViewer_CellCenters;
+
+
+class SMESHOBJECT_EXPORT SMESH_CellLabelActor : public SMESH_DeviceActor {
+public:
+ static SMESH_CellLabelActor* New();
+
+ static void ProcessEvents(vtkObject* theObject,
+ unsigned long theEvent,
+ void* theClientData,
+ void* theCallData);
+
+
+ vtkTypeMacro(SMESH_CellLabelActor, SMESH_DeviceActor);
+
+
+ virtual void SetCellsLabeled(bool theIsCellsLabeled);
+ virtual bool GetCellsLabeled(){ return myIsCellsLabeled;}
+
+ virtual void SetVisibility(int theMode);
+
+ virtual void AddToRender(vtkRenderer* theRenderer);
+ virtual void RemoveFromRender(vtkRenderer* theRenderer);
+
+ void UpdateLabels();
+
+protected:
+ SMESH_CellLabelActor();
+ ~SMESH_CellLabelActor();
+
+ bool myIsCellsLabeled;
+ vtkPolyData* myCellsNumDataSet;
+ vtkActor2D *myCellsLabels;
+ vtkMaskPoints* myClsMaskPoints;
+ VTKViewer_CellCenters* myCellCenters;
+ vtkLabeledDataMapper* myClsLabeledDataMapper;
+ vtkSelectVisiblePoints* myClsSelectVisiblePoints;
+ SMESH_DeviceActor* myBaseActor; //Pointer to the base actor
+
+protected:
+ // Not implemented.
+ SMESH_CellLabelActor(const SMESH_CellLabelActor&);
+ void operator=(const SMESH_CellLabelActor&);
+};
+
+#endif //SMESH_NODE_LABEL_ACTOR_H
diff --git a/src/OBJECT/SMESH_DeviceActor.cxx b/src/OBJECT/SMESH_DeviceActor.cxx
index fe08178a9..6032c5734 100644
--- a/src/OBJECT/SMESH_DeviceActor.cxx
+++ b/src/OBJECT/SMESH_DeviceActor.cxx
@@ -626,7 +626,7 @@ void
SMESH_DeviceActor
::SetFacesOriented(bool theIsFacesOriented)
{
- if ( vtkDataSet* aDataSet = myPassFilter[ 1 ]->GetOutput() )
+ if ( vtkDataSet* aDataSet = myTransformFilter->GetOutput() )
{
myIsFacesOriented = theIsFacesOriented;
if( theIsFacesOriented )
diff --git a/src/OBJECT/SMESH_ExtractGeometry.cxx b/src/OBJECT/SMESH_ExtractGeometry.cxx
index 26c281382..db42da397 100644
--- a/src/OBJECT/SMESH_ExtractGeometry.cxx
+++ b/src/OBJECT/SMESH_ExtractGeometry.cxx
@@ -239,9 +239,14 @@ int SMESH_ExtractGeometry::RequestData(
if ( npts >= numCellPts || (this->ExtractBoundaryCells && npts > 0) )
{
- newCellId = output->InsertNextCell(cell->GetCellType(),newCellPts);
- myElemVTK2ObjIds.push_back(cellId);
- outputCD->CopyData(cd,cellId,newCellId);
+ if(cell->GetCellType() == VTK_POLYHEDRON) {
+ newCellPts->Reset();
+ vtkUnstructuredGrid::SafeDownCast(input)->GetFaceStream( cellId ,newCellPts );
+ vtkUnstructuredGrid::ConvertFaceStreamPointIds(newCellPts, pointMap);
+ }
+ newCellId = output->InsertNextCell(cell->GetCellType(),newCellPts);
+ myElemVTK2ObjIds.push_back(cellId);
+ outputCD->CopyData(cd,cellId,newCellId);
}
}//for all cells
diff --git a/src/OBJECT/SMESH_NodeLabelActor.cxx b/src/OBJECT/SMESH_NodeLabelActor.cxx
new file mode 100644
index 000000000..51c913585
--- /dev/null
+++ b/src/OBJECT/SMESH_NodeLabelActor.cxx
@@ -0,0 +1,187 @@
+// Copyright (C) 2007-2011 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.
+//
+// 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 : SMESH_NodeLabelActor.cxx
+// Author : Roman NIKOLAEV
+// Module : SMESH
+//
+#include "SMESH_NodeLabelActor.h"
+
+#include
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+vtkStandardNewMacro(SMESH_NodeLabelActor);
+
+/*!
+ Constructor.
+*/
+SMESH_NodeLabelActor::SMESH_NodeLabelActor() {
+ //Definition of points numbering pipeline
+ //---------------------------------------
+ myPointsNumDataSet = vtkPolyData::New();
+
+ myPtsMaskPoints = vtkMaskPoints::New();
+ myPtsMaskPoints->SetInput(myPointsNumDataSet);
+ myPtsMaskPoints->SetOnRatio(1);
+
+ myPtsSelectVisiblePoints = vtkSelectVisiblePoints::New();
+ myPtsSelectVisiblePoints->SetInput(myPtsMaskPoints->GetOutput());
+ myPtsSelectVisiblePoints->SelectInvisibleOff();
+ myPtsSelectVisiblePoints->SetTolerance(0.1);
+
+ myPtsLabeledDataMapper = vtkLabeledDataMapper::New();
+ myPtsLabeledDataMapper->SetInput(myPtsSelectVisiblePoints->GetOutput());
+ myPtsLabeledDataMapper->SetLabelFormat("%d");
+ myPtsLabeledDataMapper->SetLabelModeToLabelScalars();
+
+ vtkTextProperty* aPtsTextProp = vtkTextProperty::New();
+ aPtsTextProp->SetFontFamilyToTimes();
+ static int aPointsFontSize = 10;
+ aPtsTextProp->SetFontSize(aPointsFontSize);
+ aPtsTextProp->SetBold(1);
+ aPtsTextProp->SetItalic(0);
+ aPtsTextProp->SetShadow(0);
+ myPtsLabeledDataMapper->SetLabelTextProperty(aPtsTextProp);
+ aPtsTextProp->Delete();
+
+ myIsPointsLabeled = false;
+
+ myPointLabels = vtkActor2D::New();
+ myPointLabels->SetMapper(myPtsLabeledDataMapper);
+ myPointLabels->GetProperty()->SetColor(1,1,1);
+ myPointLabels->SetVisibility(myIsPointsLabeled);
+
+ vtkCallbackCommand* callBackCommand = vtkCallbackCommand::New();
+ callBackCommand->SetClientData(this);
+ callBackCommand->SetCallback(SMESH_NodeLabelActor::ProcessEvents);
+
+ myTransformFilter->AddObserver("VTKViewer_TransformFilter::TransformationFinished",
+ callBackCommand);
+ callBackCommand->Delete();
+}
+
+/*!
+ Destructor
+*/
+SMESH_NodeLabelActor::~SMESH_NodeLabelActor() {
+ //Deleting of points numbering pipeline
+ //---------------------------------------
+ myPointsNumDataSet->Delete();
+
+ // commented: porting to vtk 5.0
+ // myPtsLabeledDataMapper->RemoveAllInputs();
+ myPtsLabeledDataMapper->Delete();
+
+ // commented: porting to vtk 5.0
+ // myPtsSelectVisiblePoints->UnRegisterAllOutputs();
+ myPtsSelectVisiblePoints->Delete();
+
+ // commented: porting to vtk 5.0
+ // myPtsMaskPoints->UnRegisterAllOutputs();
+ myPtsMaskPoints->Delete();
+ myPointLabels->Delete();
+
+}
+
+void SMESH_NodeLabelActor::SetPointsLabeled(bool theIsPointsLabeled) {
+ myTransformFilter->Update();
+ vtkDataSet* aGrid = vtkPolyData::SafeDownCast(myTransformFilter->GetOutput());
+
+ if(!aGrid)
+ return;
+
+ myIsPointsLabeled = theIsPointsLabeled && aGrid->GetNumberOfPoints();
+
+ if ( myIsPointsLabeled )
+ {
+ myPointsNumDataSet->ShallowCopy(aGrid);
+ vtkDataSet *aDataSet = myPointsNumDataSet;
+
+ int aNbElem = aDataSet->GetNumberOfPoints();
+
+ vtkIntArray *anArray = vtkIntArray::New();
+ anArray->SetNumberOfValues( aNbElem );
+
+ for ( vtkIdType anId = 0; anId < aNbElem; anId++ )
+ {
+ int aSMDSId = GetNodeObjId( anId );
+ anArray->SetValue( anId, aSMDSId );
+ }
+
+ aDataSet->GetPointData()->SetScalars( anArray );
+ myPtsMaskPoints->SetInput( aDataSet );
+ myPointLabels->SetVisibility( GetVisibility() );
+ anArray->Delete();
+ }
+ else
+ {
+ myPointLabels->SetVisibility( false );
+ }
+}
+
+
+void SMESH_NodeLabelActor::SetVisibility(int theMode)
+{
+ SMESH_DeviceActor::SetVisibility(theMode);
+ myPointLabels->VisibilityOff();
+ if(myIsPointsLabeled && theMode)
+ myPointLabels->VisibilityOn();
+}
+
+
+void SMESH_NodeLabelActor::AddToRender(vtkRenderer* theRenderer)
+{
+ SMESH_DeviceActor::AddToRender(theRenderer);
+ myPtsSelectVisiblePoints->SetRenderer(theRenderer);
+ theRenderer->AddActor2D(myPointLabels);
+}
+
+void SMESH_NodeLabelActor::RemoveFromRender(vtkRenderer* theRenderer)
+{
+ theRenderer->RemoveActor(myPointLabels);
+ SMESH_DeviceActor::RemoveFromRender(theRenderer);
+}
+
+void SMESH_NodeLabelActor::UpdateLabels() {
+ if(myIsPointsLabeled)
+ SetPointsLabeled(myIsPointsLabeled);
+}
+
+
+void SMESH_NodeLabelActor::ProcessEvents(vtkObject* vtkNotUsed(theObject),
+ unsigned long theEvent,
+ void* theClientData,
+ void* vtkNotUsed(theCallData)) {
+ SMESH_NodeLabelActor* self = reinterpret_cast(theClientData);
+ if(self)
+ self->UpdateLabels();
+}
diff --git a/src/OBJECT/SMESH_NodeLabelActor.h b/src/OBJECT/SMESH_NodeLabelActor.h
new file mode 100644
index 000000000..0a9ffaa70
--- /dev/null
+++ b/src/OBJECT/SMESH_NodeLabelActor.h
@@ -0,0 +1,78 @@
+// Copyright (C) 2007-2011 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.
+//
+// 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 : SMESH_NodeLabelActor.h
+// Author : Roman NIKOLAEV
+// Module : SMESH
+//
+#ifndef SMESH_NODE_LABEL_ACTOR_H
+#define SMESH_NODE_LABEL_ACTOR_H
+
+#include "SMESH_DeviceActor.h"
+
+class vtkSelectVisiblePoints;
+class vtkLabeledDataMapper;
+class vtkActor2D;
+class vtkMaskPoints;
+class vtkPolyData;
+
+
+class SMESHOBJECT_EXPORT SMESH_NodeLabelActor : public SMESH_DeviceActor {
+public:
+ static SMESH_NodeLabelActor* New();
+
+ static void ProcessEvents(vtkObject* theObject,
+ unsigned long theEvent,
+ void* theClientData,
+ void* theCallData);
+
+
+ vtkTypeMacro(SMESH_NodeLabelActor, SMESH_DeviceActor);
+
+
+ virtual void SetPointsLabeled(bool theIsPointsLabeled);
+ virtual bool GetPointsLabeled(){ return myIsPointsLabeled;}
+
+ virtual void SetVisibility(int theMode);
+
+ virtual void AddToRender(vtkRenderer* theRenderer);
+ virtual void RemoveFromRender(vtkRenderer* theRenderer);
+
+ void UpdateLabels();
+
+protected:
+ SMESH_NodeLabelActor();
+ ~SMESH_NodeLabelActor();
+
+ bool myIsPointsLabeled;
+ vtkPolyData* myPointsNumDataSet;
+ vtkActor2D *myPointLabels;
+ vtkMaskPoints* myPtsMaskPoints;
+ vtkLabeledDataMapper* myPtsLabeledDataMapper;
+ vtkSelectVisiblePoints* myPtsSelectVisiblePoints;
+
+protected:
+ // Not implemented.
+ SMESH_NodeLabelActor(const SMESH_NodeLabelActor&);
+ void operator=(const SMESH_NodeLabelActor&);
+};
+
+#endif //SMESH_NODE_LABEL_ACTOR_H
diff --git a/src/OBJECT/SMESH_Object.cxx b/src/OBJECT/SMESH_Object.cxx
index 5e35f14f2..cfaa700cb 100644
--- a/src/OBJECT/SMESH_Object.cxx
+++ b/src/OBJECT/SMESH_Object.cxx
@@ -368,11 +368,27 @@ void SMESH_VisualObjDef::buildElemPrs()
{
const TEntityList& aList = anEnts[ aTypes[ i ] ];
TEntityList::const_iterator anIter;
- for ( anIter = aList.begin(); anIter != aList.end(); ++anIter )
- aCellsSize += (*anIter)->NbNodes() + 1;
+ for ( anIter = aList.begin(); anIter != aList.end(); ++anIter ) {
+ if((*anIter)->GetEntityType() != SMDSEntity_Polyhedra &&
+ (*anIter)->GetEntityType() != SMDSEntity_Quad_Polyhedra) {
+ aCellsSize += (*anIter)->NbNodes() + 1;
+ }
+ // Special case for the VTK_POLYHEDRON:
+ // itsinput cellArray is of special format.
+ // [nCellFaces, nFace0Pts, i, j, k, nFace1Pts, i, j, k, ...]
+ else {
+ if( const SMDS_VtkVolume* ph = dynamic_cast(*anIter) ) {
+ int nbFaces = ph->NbFaces();
+ aCellsSize += (1 + ph->NbFaces());
+ for( int i = 1; i <= nbFaces; i++ ) {
+ aCellsSize += ph->NbFaceNodes(i);
+ }
+ }
+ }
+ }
}
}
-
+
vtkIdType aNbCells = nbEnts[ SMDSAbs_0DElement ] + nbEnts[ SMDSAbs_Edge ] +
nbEnts[ SMDSAbs_Face ] + nbEnts[ SMDSAbs_Volume ];
@@ -402,44 +418,50 @@ void SMESH_VisualObjDef::buildElemPrs()
for ( int i = 0; i <= 3; i++ ) // iterate through 0d elements, edges, faces and volumes
{
- if ( nbEnts[ aTypes[ i ] ] > 0 )
- {
+ if ( nbEnts[ aTypes[ i ] ] > 0 ) {
+
const SMDSAbs_ElementType& aType = aTypes[ i ];
const TEntityList& aList = anEnts[ aType ];
TEntityList::const_iterator anIter;
for ( anIter = aList.begin(); anIter != aList.end(); ++anIter )
{
const SMDS_MeshElement* anElem = *anIter;
-
+
vtkIdType aNbNodes = anElem->NbNodes();
anIdList->SetNumberOfIds( aNbNodes );
-
+
int anId = anElem->GetID();
-
+
mySMDS2VTKElems.insert( TMapOfIds::value_type( anId, iElem ) );
myVTK2SMDSElems.insert( TMapOfIds::value_type( iElem, anId ) );
-
+
SMDS_ElemIteratorPtr aNodesIter = anElem->nodesIterator();
switch (aType) {
- case SMDSAbs_Volume:{
+ case SMDSAbs_Volume: {
aConnect.clear();
std::vector aConnectivities;
// Convertions connectivities from SMDS to VTK
+
if (anElem->IsPoly() && aNbNodes > 3) { // POLYEDRE
-
- if ( const SMDS_VtkVolume* ph =
- dynamic_cast (anElem))
- {
- aNbNodes = GetConnect(ph->uniqueNodesIterator(),aConnect);
- anIdList->SetNumberOfIds( aNbNodes );
+ anIdList->Reset();
+ if ( const SMDS_VtkVolume* ph = dynamic_cast(anElem) ) {
+ int nbFaces = ph->NbFaces();
+ anIdList->InsertNextId(nbFaces);
+ for( int i = 1; i <= nbFaces; i++ ) {
+ anIdList->InsertNextId(ph->NbFaceNodes(i));
+ for(int j = 1; j <= ph->NbFaceNodes(i); j++) {
+ const SMDS_MeshNode* n = ph->GetFaceNode(i,j);
+ if(n) {
+ anIdList->InsertNextId(mySMDS2VTKNodes[n->GetID()]);
+ }
+ }
+ }
}
- for (int k = 0; k < aNbNodes; k++)
- aConnectivities.push_back(k);
-
+
} else if (aNbNodes == 4) {
static int anIds[] = {0,2,1,3};
for (int k = 0; k < aNbNodes; k++) aConnectivities.push_back(anIds[k]);
-
+
} else if (aNbNodes == 5) {
static int anIds[] = {0,3,2,1,4};
for (int k = 0; k < aNbNodes; k++) aConnectivities.push_back(anIds[k]);
@@ -479,14 +501,16 @@ void SMESH_VisualObjDef::buildElemPrs()
else {
}
- if ( aConnect.empty() )
- GetConnect(aNodesIter,aConnect);
+ if (!(anElem->IsPoly() && aNbNodes > 3)) {
+ if ( aConnect.empty() )
+ GetConnect(aNodesIter,aConnect);
- if (aConnectivities.size() > 0) {
- for (vtkIdType aNodeId = 0; aNodeId < aNbNodes; aNodeId++)
- SetId(anIdList,mySMDS2VTKNodes,aConnect,aNodeId,aConnectivities[aNodeId]);
- }
- break;
+ if (aConnectivities.size() > 0) {
+ for (vtkIdType aNodeId = 0; aNodeId < aNbNodes; aNodeId++)
+ SetId(anIdList,mySMDS2VTKNodes,aConnect,aNodeId,aConnectivities[aNodeId]);
+ }
+ }
+ break;
}
default:
for( vtkIdType aNodeId = 0; aNodesIter->more(); aNodeId++ ){
@@ -495,6 +519,7 @@ void SMESH_VisualObjDef::buildElemPrs()
}
}
+
aConnectivity->InsertNextCell( anIdList );
aCellTypesArray->InsertNextValue( getCellType( aType, anElem->IsPoly(), aNbNodes ) );
@@ -570,8 +595,13 @@ bool SMESH_VisualObjDef::GetEdgeNodes( const int theElemId,
vtkUnstructuredGrid* SMESH_VisualObjDef::GetUnstructuredGrid()
{
- //MESSAGE("SMESH_VisualObjDef::GetUnstructuredGrid " << myGrid);
- return myGrid;
+ if ( !myLocalGrid && !GetMesh()->isCompacted() )
+ {
+ GetMesh()->compactMesh();
+ vtkUnstructuredGrid *theGrid = GetMesh()->getGrid();
+ myGrid->ShallowCopy(theGrid);
+ }
+ return myGrid;
}
diff --git a/src/OBJECT/SMESH_vtkPVUpdateSuppressor.cxx b/src/OBJECT/SMESH_vtkPVUpdateSuppressor.cxx
deleted file mode 100644
index bbab763f9..000000000
--- a/src/OBJECT/SMESH_vtkPVUpdateSuppressor.cxx
+++ /dev/null
@@ -1,230 +0,0 @@
-/*=========================================================================
-
- Program: ParaView
- Module: $RCSfile$
-
- Copyright (c) Kitware, Inc.
- All rights reserved.
- See Copyright.txt or http://www.paraview.org/HTML/Copyright.html for details.
-
- This software is distributed WITHOUT ANY WARRANTY; without even
- the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- PURPOSE. See the above copyright notice for more information.
-
- =========================================================================*/
-#include "SMESH_vtkPVUpdateSuppressor.h"
-
-#include "vtkAlgorithmOutput.h"
-#include "vtkCollection.h"
-#include "vtkCommand.h"
-#include "vtkCompositeDataPipeline.h"
-#include "vtkDataObject.h"
-#include "vtkDemandDrivenPipeline.h"
-#include "vtkInformation.h"
-#include "vtkInformationDoubleVectorKey.h"
-#include "vtkInformationExecutivePortKey.h"
-#include "vtkInformationVector.h"
-#include "vtkObjectFactory.h"
-#include "vtkPolyData.h"
-//#include "vtkProcessModule.h"
-#include "vtkSmartPointer.h"
-#include "vtkUnstructuredGrid.h"
-//#include "vtkUpdateSuppressorPipeline.h"
-
-#include
-
-#ifdef MYDEBUG
-# define vtkMyDebug(x)\
- cout << x;
-#else
-# define vtkMyDebug(x)
-#endif
-
-vtkCxxRevisionMacro(vtkPVUpdateSuppressor, "$Revision$")
-;
-vtkStandardNewMacro(vtkPVUpdateSuppressor)
-;
-//----------------------------------------------------------------------------
-vtkPVUpdateSuppressor::vtkPVUpdateSuppressor()
-{
- this->UpdatePiece = 0;
- this->UpdateNumberOfPieces = 1;
-
- this->UpdateTime = 0.0;
- this->UpdateTimeInitialized = false;
-
- this->Enabled = 1;
-
- // vtkProcessModule* pm = vtkProcessModule::GetProcessModule();
- //
- // if (pm)
- // {
- // this->UpdateNumberOfPieces = pm->GetNumberOfLocalPartitions();
- // this->UpdatePiece = pm->GetPartitionId();
- // }
-}
-
-//----------------------------------------------------------------------------
-vtkPVUpdateSuppressor::~vtkPVUpdateSuppressor()
-{
-}
-
-//----------------------------------------------------------------------------
-void vtkPVUpdateSuppressor::SetUpdateTime(double utime)
-{
- this->UpdateTimeInitialized = true;
- if (this->UpdateTime != utime)
- {
- this->Modified();
- this->UpdateTime = utime;
- }
-}
-
-//----------------------------------------------------------------------------
-void vtkPVUpdateSuppressor::SetEnabled(int enable)
-{
- if (this->Enabled == enable)
- {
- return;
- }
- this->Enabled = enable;
- this->Modified();
- // vtkUpdateSuppressorPipeline* executive =
- // vtkUpdateSuppressorPipeline::SafeDownCast(this->GetExecutive());
- // if (executive)
- // {
- // executive->SetEnabled(enable);
- // }
-}
-
-//----------------------------------------------------------------------------
-void vtkPVUpdateSuppressor::ForceUpdate()
-{
- // Make sure that output type matches input type
- this->UpdateInformation();
-
- vtkDataObject *input = this->GetInput();
- if (input == 0)
- {
- vtkErrorMacro("No valid input.");
- return;
- }
- vtkDataObject *output = this->GetOutput();
-
- // int fixme; // I do not like this hack. How can we get rid of it?
- // Assume the input is the collection filter.
- // Client needs to modify the collection filter because it is not
- // connected to a pipeline.
- vtkAlgorithm *source = input->GetProducerPort()->GetProducer();
- if (source && (source->IsA("vtkMPIMoveData")
- || source->IsA("vtkCollectPolyData") || source->IsA("vtkM2NDuplicate")
- || source->IsA("vtkM2NCollect")
- || source->IsA("vtkOrderedCompositeDistributor")
- || source->IsA("vtkClientServerMoveData")))
- {
- source->Modified();
- }
-
- vtkInformation* info = input->GetPipelineInformation();
- vtkStreamingDemandDrivenPipeline
- * sddp =
- vtkStreamingDemandDrivenPipeline::SafeDownCast(
- vtkExecutive::PRODUCER()->GetExecutive(
- info));
- if (sddp)
- {
- sddp->SetUpdateExtent(info, this->UpdatePiece,
- this->UpdateNumberOfPieces, 0);
- }
- else
- {
- input->SetUpdatePiece(this->UpdatePiece);
- input->SetUpdateNumberOfPieces(this->UpdateNumberOfPieces);
- input->SetUpdateGhostLevel(0);
- } vtkMyDebug("ForceUpdate ");
- if (this->UpdateTimeInitialized)
- {
- info->Set(vtkCompositeDataPipeline::UPDATE_TIME_STEPS(),
- &this->UpdateTime, 1);
- vtkMyDebug(this->UpdateTime);
- } vtkMyDebug(endl);
-
- input->Update();
- // Input may have changed, we obtain the pointer again.
- input = this->GetInput();
-
- output->ShallowCopy(input);
- this->PipelineUpdateTime.Modified();
-}
-
-//----------------------------------------------------------------------------
-vtkExecutive* vtkPVUpdateSuppressor::CreateDefaultExecutive()
-{
- vtkUpdateSuppressorPipeline* executive = vtkUpdateSuppressorPipeline::New();
- executive->SetEnabled(this->Enabled);
- return executive;
-}
-
-//----------------------------------------------------------------------------
-int vtkPVUpdateSuppressor::RequestDataObject(
- vtkInformation* vtkNotUsed(reqInfo),
- vtkInformationVector** inputVector,
- vtkInformationVector* outputVector)
-{
- vtkInformation* inInfo = inputVector[0]->GetInformationObject(0);
- if (!inInfo)
- {
- return 0;
- }
-
- vtkDataObject *input = inInfo->Get(vtkDataObject::DATA_OBJECT());
- if (input)
- {
- // for each output
- for (int i = 0; i < this->GetNumberOfOutputPorts(); ++i)
- {
- vtkInformation* outInfo = outputVector->GetInformationObject(i);
- vtkDataObject *output = outInfo->Get(vtkDataObject::DATA_OBJECT());
-
- if (!output || !output->IsA(input->GetClassName()))
- {
- vtkDataObject* newOutput = input->NewInstance();
- newOutput->SetPipelineInformation(outInfo);
- newOutput->Delete();
- this->GetOutputPortInformation(i)->Set(
- vtkDataObject::DATA_EXTENT_TYPE(),
- newOutput->GetExtentType());
- }
- }
- return 1;
- }
- return 0;
-
-}
-
-//----------------------------------------------------------------------------
-int vtkPVUpdateSuppressor::RequestData(vtkInformation* vtkNotUsed(reqInfo),
- vtkInformationVector** inputVector,
- vtkInformationVector* outputVector)
-{
- // RequestData is only called by its executive when
- // (Enabled==off) and thus acting as a passthrough filter
- vtkInformation *outInfo = outputVector->GetInformationObject(0);
- vtkInformation *inInfo = inputVector[0]->GetInformationObject(0);
- vtkDataObject *input = inInfo->Get(vtkDataObject::DATA_OBJECT());
- vtkDataObject *output = outInfo->Get(vtkDataObject::DATA_OBJECT());
-
- output->ShallowCopy(input);
- return 1;
-}
-
-//----------------------------------------------------------------------------
-void vtkPVUpdateSuppressor::PrintSelf(ostream& os, vtkIndent indent)
-{
- this->Superclass::PrintSelf(os, indent);
- os << indent << "UpdatePiece: " << this->UpdatePiece << endl;
- os << indent << "UpdateNumberOfPieces: " << this->UpdateNumberOfPieces
- << endl;
- os << indent << "Enabled: " << this->Enabled << endl;
- os << indent << "UpdateTime: " << this->UpdateTime << endl;
-}
diff --git a/src/OBJECT/SMESH_vtkPVUpdateSuppressor.h b/src/OBJECT/SMESH_vtkPVUpdateSuppressor.h
deleted file mode 100644
index 4cd0624e7..000000000
--- a/src/OBJECT/SMESH_vtkPVUpdateSuppressor.h
+++ /dev/null
@@ -1,98 +0,0 @@
-/*=========================================================================
-
- Program: ParaView
- Module: $RCSfile$
-
- Copyright (c) Kitware, Inc.
- All rights reserved.
- See Copyright.txt or http://www.paraview.org/HTML/Copyright.html for details.
-
- This software is distributed WITHOUT ANY WARRANTY; without even
- the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- PURPOSE. See the above copyright notice for more information.
-
- =========================================================================*/
-// .NAME vtkPVUpdateSuppressor - prevents propagation of update
-// .SECTION Description
-// vtkPVUpdateSuppressor now uses the vtkProcessModule singleton to set up the
-// default values for UpdateNumberOfPieces and UpdatePiece, so we no longer have
-// to set the default values (in most cases).
-// .SECTION See Also
-// vtkPVCacheKeeper vtkUpdateSuppressorPipeline
-
-#ifndef __vtkPVUpdateSuppressor_h
-#define __vtkPVUpdateSuppressor_h
-
-#include "vtkDataObjectAlgorithm.h"
-
-class VTK_EXPORT vtkPVUpdateSuppressor: public vtkDataObjectAlgorithm
-{
-public:
-vtkTypeRevisionMacro(vtkPVUpdateSuppressor,vtkDataObjectAlgorithm)
- ;
- void PrintSelf(ostream& os, vtkIndent indent);
-
- // Description:
- // Construct with user-specified implicit function.
- static vtkPVUpdateSuppressor *New();
-
- // Description:
- // Force update on the input.
- virtual void ForceUpdate();
-
- // Description:
- // Set number of pieces and piece on the data.
- // This causes the filter to ingore the request from the output.
- // It is here because the user may not have celled update on the output
- // before calling force update (it is an easy fix).
- vtkSetMacro(UpdatePiece, int)
- ;
- vtkGetMacro(UpdatePiece, int)
- ;
- vtkSetMacro(UpdateNumberOfPieces, int)
- ;
- vtkGetMacro(UpdateNumberOfPieces, int)
- ;
-
- // Description:
- // Get/Set if the update suppressor is enabled. If the update suppressor
- // is not enabled, it won't supress any updates. Enabled by default.
- void SetEnabled(int);
- vtkGetMacro(Enabled, int)
- ;
-
- // Description:
- // Get/Set the update time that is sent up the pipeline.
- void SetUpdateTime(double utime);
- vtkGetMacro(UpdateTime, double)
- ;
-
-protected:
- vtkPVUpdateSuppressor();
- ~vtkPVUpdateSuppressor();
-
- int RequestDataObject(vtkInformation* request,
- vtkInformationVector **inputVector,
- vtkInformationVector *outputVector);
- int RequestData(vtkInformation* request, vtkInformationVector **inputVector,
- vtkInformationVector *outputVector);
-
- int UpdatePiece;
- int UpdateNumberOfPieces;
- double UpdateTime;
-
- bool UpdateTimeInitialized;
-
- int Enabled;
-
- vtkTimeStamp PipelineUpdateTime;
-
- // Create a default executive.
- virtual vtkExecutive* CreateDefaultExecutive();
-
-private:
- vtkPVUpdateSuppressor(const vtkPVUpdateSuppressor&); // Not implemented.
- void operator=(const vtkPVUpdateSuppressor&); // Not implemented.
-};
-
-#endif
diff --git a/src/SMDS/SMDS_VtkVolume.cxx b/src/SMDS/SMDS_VtkVolume.cxx
index bc561a20b..d4f4a9abc 100644
--- a/src/SMDS/SMDS_VtkVolume.cxx
+++ b/src/SMDS/SMDS_VtkVolume.cxx
@@ -95,21 +95,27 @@ void SMDS_VtkVolume::initPoly(std::vector nodeIds, std::vector n
{
int nf = nbNodesPerFace[i];
ptIds.push_back(nf);
- double a[3];
- double b[3];
- double c[3];
- grid->GetPoints()->GetPoint(nodeIds[k], a);
- grid->GetPoints()->GetPoint(nodeIds[k + 1], b);
- grid->GetPoints()->GetPoint(nodeIds[k + 2], c);
- bool isFaceForward = this->isForward(a, b, c, center);
+ // EAP: a right approach is:
+ // - either the user should care of order of nodes or
+ // - the user should use a service method arranging nodes if he
+ // don't want or can't to do it by him-self
+ // The method below works OK only with planar faces
+ //
+ // double a[3];
+ // double b[3];
+ // double c[3];
+ // grid->GetPoints()->GetPoint(nodeIds[k], a);
+ // grid->GetPoints()->GetPoint(nodeIds[k + 1], b);
+ // grid->GetPoints()->GetPoint(nodeIds[k + 2], c);
+ // bool isFaceForward = this->isForward(a, b, c, center);
//MESSAGE("isFaceForward " << i << " " << isFaceForward);
vtkIdType *facePts = &nodeIds[k];
- if (isFaceForward)
+ //if (isFaceForward)
for (int n = 0; n < nf; n++)
ptIds.push_back(facePts[n]);
- else
- for (int n = nf - 1; n >= 0; n--)
- ptIds.push_back(facePts[n]);
+ // else
+ // for (int n = nf - 1; n >= 0; n--)
+ // ptIds.push_back(facePts[n]);
k += nf;
}
myVtkID = grid->InsertNextLinkedCell(VTK_POLYHEDRON, nbFaces, &ptIds[0]);
diff --git a/src/SMESH/SMESH_Algo.cxx b/src/SMESH/SMESH_Algo.cxx
index e561cff93..f1d3fad65 100644
--- a/src/SMESH/SMESH_Algo.cxx
+++ b/src/SMESH/SMESH_Algo.cxx
@@ -438,7 +438,7 @@ bool SMESH_Algo::GetSortedNodesOnEdge(const SMESHDS_Mesh* theM
return false;
const SMDS_EdgePosition* epos =
static_cast(node->GetPosition());
- theNodes.insert( make_pair( epos->GetUParameter(), node ));
+ theNodes.insert( theNodes.end(), make_pair( epos->GetUParameter(), node ));
//MESSAGE("U " << epos->GetUParameter() << " ID " << node->GetID());
++nbNodes;
}
diff --git a/src/SMESH/SMESH_Gen.cxx b/src/SMESH/SMESH_Gen.cxx
index e76cc8997..fbcfc3d1a 100644
--- a/src/SMESH/SMESH_Gen.cxx
+++ b/src/SMESH/SMESH_Gen.cxx
@@ -128,6 +128,7 @@ bool SMESH_Gen::Compute(SMESH_Mesh & aMesh,
const bool includeSelf = true;
const bool complexShapeFirst = true;
+ const int globalAlgoDim = 100;
SMESH_subMeshIteratorPtr smIt;
@@ -214,19 +215,30 @@ bool SMESH_Gen::Compute(SMESH_Mesh & aMesh,
if ( algo->SupportSubmeshes() )
{
// reload sub-meshes from shDim2sm into smWithAlgoSupportingSubmeshes
+ // so that more local algos to go first
if ( prevShapeDim != aShapeDim )
{
prevShapeDim = aShapeDim;
for ( shDim2smIt = shDim2sm.rbegin(); shDim2smIt != shDim2sm.rend(); ++shDim2smIt )
- smWithAlgoSupportingSubmeshes.push_front( shDim2smIt->second );
+ if ( shDim2smIt->first == globalAlgoDim )
+ smWithAlgoSupportingSubmeshes.push_back( shDim2smIt->second );
+ else
+ smWithAlgoSupportingSubmeshes.push_front( shDim2smIt->second );
shDim2sm.clear();
}
// add smToCompute to shDim2sm map
- aShapeDim = GetShapeDim( algoShape );
- if ( algoShape.ShapeType() == TopAbs_COMPOUND )
+ if ( algoShape.IsSame( aMesh.GetShapeToMesh() ))
{
- TopoDS_Iterator it( algoShape );
- aShapeDim += GetShapeDim( it.Value() );
+ aShapeDim = globalAlgoDim; // to compute last
+ }
+ else
+ {
+ aShapeDim = GetShapeDim( algoShape );
+ if ( algoShape.ShapeType() == TopAbs_COMPOUND )
+ {
+ TopoDS_Iterator it( algoShape );
+ aShapeDim += GetShapeDim( it.Value() );
+ }
}
shDim2sm.insert( make_pair( aShapeDim, smToCompute ));
}
@@ -248,7 +260,10 @@ bool SMESH_Gen::Compute(SMESH_Mesh & aMesh,
}
// reload sub-meshes from shDim2sm into smWithAlgoSupportingSubmeshes
for ( shDim2smIt = shDim2sm.rbegin(); shDim2smIt != shDim2sm.rend(); ++shDim2smIt )
- smWithAlgoSupportingSubmeshes.push_front( shDim2smIt->second );
+ if ( shDim2smIt->first == globalAlgoDim )
+ smWithAlgoSupportingSubmeshes.push_back( shDim2smIt->second );
+ else
+ smWithAlgoSupportingSubmeshes.push_front( shDim2smIt->second );
// ------------------------------------------------------------
// sort list of submeshes according to mesh order
@@ -289,7 +304,7 @@ bool SMESH_Gen::Compute(SMESH_Mesh & aMesh,
SMESH_HypoFilter filter( SMESH_HypoFilter::IsAlgo() );
filter
.And( SMESH_HypoFilter::IsApplicableTo( aSubShape ))
- .And( SMESH_HypoFilter::IsMoreLocalThan( algoShape ));
+ .And( SMESH_HypoFilter::IsMoreLocalThan( algoShape, aMesh.GetShapeToMesh() ));
if ( SMESH_Algo* subAlgo = (SMESH_Algo*) aMesh.GetHypothesis( aSubShape, filter, true )) {
SMESH_Hypothesis::Hypothesis_Status status;
@@ -501,7 +516,7 @@ bool SMESH_Gen::Evaluate(SMESH_Mesh & aMesh,
SMESH_HypoFilter filter( SMESH_HypoFilter::IsAlgo() );
filter
.And( SMESH_HypoFilter::IsApplicableTo( aSubShape ))
- .And( SMESH_HypoFilter::IsMoreLocalThan( algoShape ));
+ .And( SMESH_HypoFilter::IsMoreLocalThan( algoShape, aMesh.GetShapeToMesh() ));
if ( SMESH_Algo* subAlgo = (SMESH_Algo*) aMesh.GetHypothesis( aSubShape, filter, true )) {
SMESH_Hypothesis::Hypothesis_Status status;
diff --git a/src/SMESH/SMESH_HypoFilter.cxx b/src/SMESH/SMESH_HypoFilter.cxx
index 1bfef1249..ce3093379 100644
--- a/src/SMESH/SMESH_HypoFilter.cxx
+++ b/src/SMESH/SMESH_HypoFilter.cxx
@@ -129,6 +129,9 @@ bool SMESH_HypoFilter::IsAssignedToPredicate::IsOk(const SMESH_Hypothesis* aHyp,
bool SMESH_HypoFilter::IsMoreLocalThanPredicate::IsOk(const SMESH_Hypothesis* aHyp,
const TopoDS_Shape& aShape) const
{
+ if ( aShape.IsSame( _shapeToMesh ))
+ return false; // aHyp is global
+
if ( SMESH_MesherHelper::IsSubShape( aShape, /*mainShape=*/_shape ))
return true;
@@ -293,9 +296,10 @@ SMESH_HypoPredicate* SMESH_HypoFilter::IsApplicableTo(const TopoDS_Shape& theSha
//purpose :
//=======================================================================
-SMESH_HypoPredicate* SMESH_HypoFilter::IsMoreLocalThan(const TopoDS_Shape& theShape)
+SMESH_HypoPredicate* SMESH_HypoFilter::IsMoreLocalThan(const TopoDS_Shape& theShape,
+ const TopoDS_Shape& theShapeToMesh)
{
- return new IsMoreLocalThanPredicate( theShape );
+ return new IsMoreLocalThanPredicate( theShape, theShapeToMesh);
}
//=======================================================================
diff --git a/src/SMESH/SMESH_HypoFilter.hxx b/src/SMESH/SMESH_HypoFilter.hxx
index 31327f1ec..79825295b 100644
--- a/src/SMESH/SMESH_HypoFilter.hxx
+++ b/src/SMESH/SMESH_HypoFilter.hxx
@@ -72,7 +72,8 @@ class SMESH_EXPORT SMESH_HypoFilter: public SMESH_HypoPredicate
static SMESH_HypoPredicate* IsAssignedTo(const TopoDS_Shape& theShape);
static SMESH_HypoPredicate* Is(const SMESH_Hypothesis* theHypo);
static SMESH_HypoPredicate* IsGlobal(const TopoDS_Shape& theMainShape);
- static SMESH_HypoPredicate* IsMoreLocalThan(const TopoDS_Shape& theShape);
+ static SMESH_HypoPredicate* IsMoreLocalThan(const TopoDS_Shape& theShape,
+ const TopoDS_Shape& theShapeToMesh);
static SMESH_HypoPredicate* HasName(const std::string & theName);
static SMESH_HypoPredicate* HasDim(const int theDim);
static SMESH_HypoPredicate* HasType(const int theHypType);
@@ -169,8 +170,10 @@ class SMESH_EXPORT SMESH_HypoFilter: public SMESH_HypoPredicate
};
struct IsMoreLocalThanPredicate : public SMESH_HypoPredicate {
- TopoDS_Shape _shape;
- IsMoreLocalThanPredicate( const TopoDS_Shape& shape ):_shape(shape){}
+ TopoDS_Shape _shape, _shapeToMesh;
+ IsMoreLocalThanPredicate( const TopoDS_Shape& shape,
+ const TopoDS_Shape& shapeToMesh )
+ :_shape(shape),_shapeToMesh(shapeToMesh){}
bool IsOk(const SMESH_Hypothesis* aHyp,
const TopoDS_Shape& aShape) const;
};
diff --git a/src/SMESH/SMESH_Mesh.cxx b/src/SMESH/SMESH_Mesh.cxx
index 09064df27..c750600c4 100644
--- a/src/SMESH/SMESH_Mesh.cxx
+++ b/src/SMESH/SMESH_Mesh.cxx
@@ -1754,6 +1754,9 @@ SMESH_Group* SMESH_Mesh::ConvertToStandalone ( int theGroupID )
while ( anItr->more() )
aNewGrpDS->Add( (anItr->next())->GetID() );
+ // set color
+ aNewGrpDS->SetColor( anOldGrpDS->GetColor() );
+
// remove old group
delete anOldGrp;
diff --git a/src/SMESH/SMESH_MeshEditor.cxx b/src/SMESH/SMESH_MeshEditor.cxx
index 55bd1be81..42f16ded3 100644
--- a/src/SMESH/SMESH_MeshEditor.cxx
+++ b/src/SMESH/SMESH_MeshEditor.cxx
@@ -90,7 +90,7 @@
#include
#include
-#include
+#include
#include
# @ingroup l3_hypos_blsurf
def SetTopology(self, way):
@@ -6524,52 +6546,48 @@ class Mesh_Cartesian_3D(Mesh_Algorithm):
def __init__(self, mesh, geom=0):
self.Create(mesh, geom, "Cartesian_3D")
+ self.hyp = None
return
## Defines "Body Fitting parameters" hypothesis
- # @param xCoords coordinates of grid nodes along the X asix
- # @param yCoords coordinates of grid nodes along the Y asix
- # @param zCoords coordinates of grid nodes along the Z asix
- # @param sizeThreshold size (> 1.0) defines a minimal size of a polyhedron so that
+ # @param xGridDef is definition of the grid along the X asix.
+ # It can be in either of two following forms:
+ # - Explicit coordinates of nodes, e.g. [-1.5, 0.0, 3.1] or range( -100,200,10)
+ # - Functions f(t) defining grid spacing at each point on grid axis. If there are
+ # several functions, they must be accompanied by relative coordinates of
+ # points dividing the whole shape into ranges where the functions apply; points
+ # coodrinates should vary within (0.0, 1.0) range. Parameter \a t of the spacing
+ # function f(t) varies from 0.0 to 1.0 witin a shape range.
+ # Examples:
+ # - "10.5" - defines a grid with a constant spacing
+ # - [["1", "1+10*t", "11"] [0.1, 0.6]] - defines different spacing in 3 ranges.
+ # @param yGridDef defines the grid along the Y asix the same way as \a xGridDef does
+ # @param zGridDef defines the grid along the Z asix the same way as \a xGridDef does
+ # @param sizeThreshold (> 1.0) defines a minimal size of a polyhedron so that
# a polyhedron of size less than hexSize/sizeThreshold is not created
# @param UseExisting if ==true - searches for the existing hypothesis created with
# the same parameters, else (default) - creates a new one
- def SetGrid(self, xCoords, yCoords, zCoords, sizeThreshold, UseExisting=False):
- hyp = self.Hypothesis("CartesianParameters3D", [xCoords, yCoords, zCoords, sizeThreshold],
- UseExisting=UseExisting, CompareMethod=self._compareHyp)
- hyp.SetGrid(xCoords, 0 )
- hyp.SetGrid(yCoords, 1 )
- hyp.SetGrid(zCoords, 2 )
- hyp.SetSizeThreshold( sizeThreshold )
- return hyp
+ def SetGrid(self, xGridDef, yGridDef, zGridDef, sizeThreshold=4.0, UseExisting=False):
+ if not self.hyp:
+ self.hyp = self.Hypothesis("CartesianParameters3D",
+ [xGridDef, yGridDef, zGridDef, sizeThreshold],
+ UseExisting=UseExisting, CompareMethod=self._compareHyp)
+ if not self.mesh.IsUsedHypothesis( self.hyp, self.geom ):
+ self.mesh.AddHypothesis( self.hyp, self.geom )
- ## Defines "Body Fitting parameters" hypothesis
- # @param xSpaceFuns functions f(t) defining spacing value at given point on X axis.
- # Parameter t of \axSpaceFuns is a position [0.,1.] withing bounding box of
- # the shape to mesh or withing an interval defined by internal points
- # @param ySpaceFuns functions f(t) defining spacing value at given point on Y axis.
- # @param zSpaceFuns functions f(t) defining spacing value at given point on Z axis.
- # @param xInternalPoints points (0.,1.) dividing a grid into parts along X direction.
- # Number of \axInternalPoints must be one less than number of \axSpaceFuns
- # @param yInternalPoints points (0.,1.) dividing a grid into parts along Y direction.
- # @param zInternalPoints points (0.,1.) dividing a grid into parts along Z direction.
- # @param sizeThreshold size (> 1.0) defines a minimal size of a polyhedron so that
- # a polyhedron of size less than hexSize/sizeThreshold is not created
- # @param UseExisting if ==true - searches for the existing hypothesis created with
- # the same parameters, else (default) - creates a new one
- def SetSpacing(self,
- xSpaceFuns, ySpaceFuns, zSpaceFuns,
- xInternalPoints, yInternalPoints, zInternalPoints,
- sizeThreshold, UseExisting=False):
- hyp = self.Hypothesis("CartesianParameters3D",
- [xSpaceFuns, ySpaceFuns, zSpaceFuns, \
- xInternalPoints, yInternalPoints, zInternalPoints],
- UseExisting=UseExisting, CompareMethod=self._compareHyp)
- hyp.SetGridSpacing(xSpaceFuns, xInternalPoints, 0)
- hyp.SetGridSpacing(ySpaceFuns, yInternalPoints, 1)
- hyp.SetGridSpacing(zSpaceFuns, zInternalPoints, 2)
- hyp.SetSizeThreshold( sizeThreshold )
- return hyp
+ for axis, gridDef in enumerate( [xGridDef, yGridDef, zGridDef]):
+ if not gridDef: raise ValueError, "Empty grid definition"
+ if isinstance( gridDef, str ):
+ self.hyp.SetGridSpacing( [gridDef], [], axis )
+ elif isinstance( gridDef[0], str ):
+ self.hyp.SetGridSpacing( gridDef, [], axis )
+ elif isinstance( gridDef[0], int ) or \
+ isinstance( gridDef[0], float ):
+ self.hyp.SetGrid(gridDef, axis )
+ else:
+ self.hyp.SetGridSpacing( gridDef[0], gridDef[1], axis )
+ self.hyp.SetSizeThreshold( sizeThreshold )
+ return self.hyp
def _compareHyp(self,hyp,args):
# not implemented yet
diff --git a/src/StdMeshers/StdMeshers_Cartesian_3D.cxx b/src/StdMeshers/StdMeshers_Cartesian_3D.cxx
index b685243a6..9fb64deb3 100644
--- a/src/StdMeshers/StdMeshers_Cartesian_3D.cxx
+++ b/src/StdMeshers/StdMeshers_Cartesian_3D.cxx
@@ -315,7 +315,7 @@ namespace
bool IsCorner() const { return _node; }
};
// --------------------------------------------------------------------------------
- struct _Link // link connection two _Node's
+ struct _Link // link connecting two _Node's
{
_Node* _nodes[2];
vector< _Node> _intNodes; // _Node's at GridLine intersections
diff --git a/src/StdMeshers/StdMeshers_Hexa_3D.cxx b/src/StdMeshers/StdMeshers_Hexa_3D.cxx
index ceb29fa71..5cd250767 100644
--- a/src/StdMeshers/StdMeshers_Hexa_3D.cxx
+++ b/src/StdMeshers/StdMeshers_Hexa_3D.cxx
@@ -261,13 +261,26 @@ namespace
*/
//================================================================================
- bool beginsAtSide( const _FaceGrid& sideGrid1, const _FaceGrid& sideGrid2 )
+ bool beginsAtSide( const _FaceGrid& sideGrid1,
+ const _FaceGrid& sideGrid2,
+ SMESH_ProxyMesh::Ptr proxymesh )
{
- const SMDS_MeshNode* n00 = (sideGrid1._u2nodesMap.begin()->second)[0];
const TNodeColumn& col0 = sideGrid2._u2nodesMap.begin()->second;
const TNodeColumn& col1 = sideGrid2._u2nodesMap.rbegin()->second;
- return ( n00 == col0.front() || n00 == col0.back() ||
- n00 == col1.front() || n00 == col1.back() );
+ const SMDS_MeshNode* n00 = col0.front();
+ const SMDS_MeshNode* n01 = col0.back();
+ const SMDS_MeshNode* n10 = col1.front();
+ const SMDS_MeshNode* n11 = col1.back();
+ const SMDS_MeshNode* n = (sideGrid1._u2nodesMap.begin()->second)[0];
+ if ( proxymesh )
+ {
+ n00 = proxymesh->GetProxyNode( n00 );
+ n10 = proxymesh->GetProxyNode( n10 );
+ n01 = proxymesh->GetProxyNode( n01 );
+ n11 = proxymesh->GetProxyNode( n11 );
+ n = proxymesh->GetProxyNode( n );
+ }
+ return ( n == n00 || n == n01 || n == n10 || n == n11 );
}
}
@@ -433,12 +446,12 @@ bool StdMeshers_Hexa_3D::Compute(SMESH_Mesh & aMesh,
// Orient loaded grids of cube sides along axis of the unitary cube coord system
bool isReverse[6];
- isReverse[B_BOTTOM] = beginsAtSide( aCubeSide[B_BOTTOM], aCubeSide[B_RIGHT ] );
- isReverse[B_TOP ] = beginsAtSide( aCubeSide[B_TOP ], aCubeSide[B_RIGHT ] );
- isReverse[B_FRONT ] = beginsAtSide( aCubeSide[B_FRONT ], aCubeSide[B_RIGHT ] );
- isReverse[B_BACK ] = beginsAtSide( aCubeSide[B_BACK ], aCubeSide[B_RIGHT ] );
- isReverse[B_LEFT ] = beginsAtSide( aCubeSide[B_LEFT ], aCubeSide[B_BACK ] );
- isReverse[B_RIGHT ] = beginsAtSide( aCubeSide[B_RIGHT ], aCubeSide[B_BACK ] );
+ isReverse[B_BOTTOM] = beginsAtSide( aCubeSide[B_BOTTOM], aCubeSide[B_RIGHT ], proxymesh );
+ isReverse[B_TOP ] = beginsAtSide( aCubeSide[B_TOP ], aCubeSide[B_RIGHT ], proxymesh );
+ isReverse[B_FRONT ] = beginsAtSide( aCubeSide[B_FRONT ], aCubeSide[B_RIGHT ], proxymesh );
+ isReverse[B_BACK ] = beginsAtSide( aCubeSide[B_BACK ], aCubeSide[B_RIGHT ], proxymesh );
+ isReverse[B_LEFT ] = beginsAtSide( aCubeSide[B_LEFT ], aCubeSide[B_BACK ], proxymesh );
+ isReverse[B_RIGHT ] = beginsAtSide( aCubeSide[B_RIGHT ], aCubeSide[B_BACK ], proxymesh );
for ( int i = 0; i < 6; ++i )
{
aCubeSide[i]._columns.resize( aCubeSide[i]._u2nodesMap.size() );
diff --git a/src/StdMeshers/StdMeshers_ImportSource.cxx b/src/StdMeshers/StdMeshers_ImportSource.cxx
index 4af40d8d5..5e963a02d 100644
--- a/src/StdMeshers/StdMeshers_ImportSource.cxx
+++ b/src/StdMeshers/StdMeshers_ImportSource.cxx
@@ -26,7 +26,7 @@
//
#include "StdMeshers_ImportSource.hxx"
-#include "SMESHDS_GroupBase.hxx"
+#include "SMESHDS_GroupOnGeom.hxx"
#include "SMESHDS_Mesh.hxx"
#include "SMESH_Algo.hxx"
#include "SMESH_Gen.hxx"
@@ -258,6 +258,51 @@ std::vector StdMeshers_ImportSource1D::GetSourceMeshes() const
return meshes;
}
+//================================================================================
+/*!
+ * \brief Return submeshes whose events affect the target mesh
+ */
+//================================================================================
+
+std::vector
+StdMeshers_ImportSource1D::GetSourceSubMeshes(const SMESH_Mesh* srcMesh) const
+{
+ if ( !srcMesh->HasShapeToMesh() )
+ return vector(1, srcMesh->GetSubMeshContaining(1));
+
+ set shapeIDs;
+ const vector& groups = GetGroups();
+ const SMESHDS_Mesh * srcMeshDS = srcMesh->GetMeshDS();
+ for ( size_t i = 0; i < groups.size(); ++i )
+ {
+ SMESHDS_GroupBase * grDS = groups[i]->GetGroupDS();
+ if ( grDS->GetMesh() != srcMeshDS )
+ continue;
+ if ( SMESHDS_GroupOnGeom* gog = dynamic_cast( grDS ))
+ {
+ shapeIDs.insert( srcMeshDS->ShapeToIndex( gog->GetShape() ));
+ }
+ else
+ {
+ SMDS_ElemIteratorPtr elIt = grDS->GetElements();
+ while ( elIt->more() )
+ shapeIDs.insert( elIt->next()->getshapeId() );
+ }
+ }
+ if ( !shapeIDs.empty() && *shapeIDs.begin() < 1 )
+ {
+ shapeIDs.erase( shapeIDs.begin() );
+ shapeIDs.insert( 1 );
+ }
+
+ vector smVec( shapeIDs.size());
+ set::iterator sID = shapeIDs.begin();
+ for ( int i = 0; sID != shapeIDs.end(); ++sID, ++i )
+ smVec[i] = srcMesh->GetSubMeshContaining( *sID );
+
+ return smVec;
+}
+
//=============================================================================
/*!
* Save _toCopyMesh and _toCopyGroups to a stream
diff --git a/src/StdMeshers/StdMeshers_ImportSource.hxx b/src/StdMeshers/StdMeshers_ImportSource.hxx
index 61b3b1ed5..1f87da44c 100644
--- a/src/StdMeshers/StdMeshers_ImportSource.hxx
+++ b/src/StdMeshers/StdMeshers_ImportSource.hxx
@@ -37,6 +37,7 @@
class SMESH_Group;
class SMESHDS_Mesh;
+class SMESH_subMesh;
//==============================================================================
/*!
@@ -69,6 +70,7 @@ class STDMESHERS_EXPORT StdMeshers_ImportSource1D : public SMESH_Hypothesis
const SMESHDS_Mesh& tgtMesh);
std::vector GetSourceMeshes() const;
+ std::vector GetSourceSubMeshes(const SMESH_Mesh* srcMesh) const;
private:
diff --git a/src/StdMeshers/StdMeshers_Import_1D.cxx b/src/StdMeshers/StdMeshers_Import_1D.cxx
index 1fcd7d560..9fc541c60 100644
--- a/src/StdMeshers/StdMeshers_Import_1D.cxx
+++ b/src/StdMeshers/StdMeshers_Import_1D.cxx
@@ -303,14 +303,16 @@ namespace // INTERNAL STUFF
// set listener to hear events of the submesh computed by "Import" algo
importSub->SetEventListener( get(), new _ListenerData(srcHyp), importSub );
- // set a listener to hear events of the source mesh
+ // set listeners to hear events of the source mesh
SMESH_subMesh* smToNotify = importSub;
- SMESH_subMesh* smToListen = srcMesh->GetSubMeshContaining(1);
- SMESH_subMeshEventListenerData* data = new _ListenerData(srcHyp, LISTEN_SRC_MESH);
- data->mySubMeshes.push_back( smToNotify );
- importSub->SetEventListener( get(), data, smToListen );
-
- // remeber the submesh importSub and its sub-submeshes
+ vector smToListen = srcHyp->GetSourceSubMeshes( srcMesh );
+ for ( size_t i = 0; i < smToListen.size(); ++i )
+ {
+ SMESH_subMeshEventListenerData* data = new _ListenerData(srcHyp, LISTEN_SRC_MESH);
+ data->mySubMeshes.push_back( smToNotify );
+ importSub->SetEventListener( get(), data, smToListen[i] );
+ }
+ // remember the submesh importSub and its sub-submeshes
_ImportData* iData = _Listener::getImportData( srcMesh, importSub->GetFather());
iData->trackHypParams( importSub, srcHyp );
iData->addComputed( importSub );
@@ -370,11 +372,11 @@ namespace // INTERNAL STUFF
// clear the rest submeshes
if ( !d->_computedSubM.empty() )
{
- set< SMESH_subMesh*, _SubLess> subs;
- subs.swap( d->_computedSubM ); // avoid recursion via events
- while ( !subs.empty() )
+ d->_computedSubM.clear();
+ set< SMESH_subMesh*, _SubLess>::iterator sub = d->_subM.begin();
+ for ( ; sub != d->_subM.end(); ++sub )
{
- SMESH_subMesh* subM = *subs.begin(); subs.erase( subs.begin() );
+ SMESH_subMesh* subM = *sub;
_ListenerData* hypData = (_ListenerData*) subM->GetEventListenerData( get() );
if ( hypData )
d->removeGroups( sm, hypData->_srcHyp );
diff --git a/src/StdMeshers/StdMeshers_Prism_3D.cxx b/src/StdMeshers/StdMeshers_Prism_3D.cxx
index 0d70042c8..151926415 100644
--- a/src/StdMeshers/StdMeshers_Prism_3D.cxx
+++ b/src/StdMeshers/StdMeshers_Prism_3D.cxx
@@ -1689,16 +1689,17 @@ bool StdMeshers_PrismAsBlock::GetLayersTransformation(vector & trsf) co
for ( int iE = 0; iE < nbEdgesInWires.front(); ++iE, ++edgeIt )
{
if ( BRep_Tool::Degenerated( *edgeIt )) continue;
- const TParam2ColumnMap& u2colMap =
+ const TParam2ColumnMap* u2colMap =
GetParam2ColumnMap( myHelper->GetMeshDS()->ShapeToIndex( *edgeIt ), isReverse );
+ if ( !u2colMap ) return false;
isReverse = ( edgeIt->Orientation() == TopAbs_REVERSED );
- double f = u2colMap.begin()->first, l = u2colMap.rbegin()->first;
+ double f = u2colMap->begin()->first, l = u2colMap->rbegin()->first;
if ( isReverse ) swap ( f, l );
const int nbCol = 5;
for ( int i = 0; i < nbCol; ++i )
{
double u = f + i/double(nbCol) * ( l - f );
- const TNodeColumn* col = & getColumn( & u2colMap, u )->second;
+ const TNodeColumn* col = & getColumn( u2colMap, u )->second;
if ( columns.empty() || col != columns.back() )
columns.push_back( col );
}
diff --git a/src/StdMeshers/StdMeshers_Prism_3D.hxx b/src/StdMeshers/StdMeshers_Prism_3D.hxx
index 953bb9aef..608cfba70 100644
--- a/src/StdMeshers/StdMeshers_Prism_3D.hxx
+++ b/src/StdMeshers/StdMeshers_Prism_3D.hxx
@@ -148,15 +148,18 @@ public:
* \brief Return TParam2ColumnMap for a base edge
* \param baseEdgeID - base edge SMESHDS Index
* \param isReverse - columns in-block orientation
- * \retval const TParam2ColumnMap& - map
+ * \retval const TParam2ColumnMap* - map
*/
- const TParam2ColumnMap& GetParam2ColumnMap(const int baseEdgeID,
+ const TParam2ColumnMap* GetParam2ColumnMap(const int baseEdgeID,
bool & isReverse) const
{
- std::pair< TParam2ColumnMap*, bool > col_frw =
- myShapeIndex2ColumnMap.find( baseEdgeID )->second;
+ std::map< int, std::pair< TParam2ColumnMap*, bool > >::const_iterator i_mo =
+ myShapeIndex2ColumnMap.find( baseEdgeID );
+ if ( i_mo == myShapeIndex2ColumnMap.end() ) return 0;
+
+ const std::pair< TParam2ColumnMap*, bool >& col_frw = i_mo->second;
isReverse = !col_frw.second;
- return * col_frw.first;
+ return col_frw.first;
}
/*!
diff --git a/src/StdMeshers/StdMeshers_Regular_1D.cxx b/src/StdMeshers/StdMeshers_Regular_1D.cxx
index bedf3692c..f075e0f03 100644
--- a/src/StdMeshers/StdMeshers_Regular_1D.cxx
+++ b/src/StdMeshers/StdMeshers_Regular_1D.cxx
@@ -691,7 +691,7 @@ bool StdMeshers_Regular_1D::computeInternalParameters(SMESH_Mesh & theMesh,
list::iterator u = theParams.begin(), uEnd = theParams.end();
for ( ; u != uEnd; ++u )
{
- GCPnts_AbscissaPoint Discret( theC3d, (*u) * lenFactor, f );
+ GCPnts_AbscissaPoint Discret( theC3d, ((*u)-f) * lenFactor, f );
if ( Discret.IsDone() )
*u = Discret.Parameter();
}
diff --git a/src/StdMeshers/StdMeshers_ViscousLayers.cxx b/src/StdMeshers/StdMeshers_ViscousLayers.cxx
index 912815839..4952afab6 100644
--- a/src/StdMeshers/StdMeshers_ViscousLayers.cxx
+++ b/src/StdMeshers/StdMeshers_ViscousLayers.cxx
@@ -32,16 +32,18 @@
#include "SMESHDS_Hypothesis.hxx"
#include "SMESH_Algo.hxx"
#include "SMESH_ComputeError.hxx"
+#include "SMESH_ControlsDef.hxx"
#include "SMESH_Gen.hxx"
#include "SMESH_Group.hxx"
#include "SMESH_Mesh.hxx"
#include "SMESH_MesherHelper.hxx"
+#include "SMESH_ProxyMesh.hxx"
#include "SMESH_subMesh.hxx"
#include "SMESH_subMeshEventListener.hxx"
-#include "SMESH_ProxyMesh.hxx"
#include "utilities.h"
+#include
#include
#include
#include
@@ -56,6 +58,8 @@
#include
#include
#include
+#include
+#include
#include
#include
#include
@@ -67,7 +71,6 @@
#include
#include
#include
-#include
#include
#include
@@ -224,17 +227,22 @@ namespace VISCOUS
- M[0][2]*M[1][1]*M[2][0]);
return determinant > 1e-100;
}
- bool IsForward(const gp_XY& tgtUV,
- const TopoDS_Face& face,
- SMESH_MesherHelper& helper,
- const double refSign) const
+ bool IsForward(const gp_XY& tgtUV,
+ const SMDS_MeshNode* smoothedNode,
+ const TopoDS_Face& face,
+ SMESH_MesherHelper& helper,
+ const double refSign) const
{
- gp_XY prevUV = helper.GetNodeUV( face, _nPrev );
- gp_XY nextUV = helper.GetNodeUV( face, _nNext );
+ gp_XY prevUV = helper.GetNodeUV( face, _nPrev, smoothedNode );
+ gp_XY nextUV = helper.GetNodeUV( face, _nNext, smoothedNode );
gp_Vec2d v1( tgtUV, prevUV ), v2( tgtUV, nextUV );
double d = v1 ^ v2;
return d*refSign > 1e-100;
}
+ bool IsNeighbour(const _Simplex& other) const
+ {
+ return _nPrev == other._nNext || _nNext == other._nPrev;
+ }
};
//--------------------------------------------------------------------------------
/*!
@@ -411,6 +419,7 @@ namespace VISCOUS
Handle(Geom_Surface)& surface,
SMESH_MesherHelper& helper,
const double refSign,
+ bool isCentroidal,
bool set3D);
};
//--------------------------------------------------------------------------------
@@ -444,7 +453,8 @@ namespace VISCOUS
_SolidData& data);
void getSimplices( const SMDS_MeshNode* node, vector<_Simplex>& simplices,
const set& ingnoreShapes,
- const _SolidData* dataToCheckOri = 0);
+ const _SolidData* dataToCheckOri = 0,
+ const bool toSort = false);
bool sortEdges( _SolidData& data,
vector< vector<_LayerEdge*> >& edgesByGeom);
void limitStepSize( _SolidData& data,
@@ -465,6 +475,7 @@ namespace VISCOUS
bool prepareEdgeToShrink( _LayerEdge& edge, const TopoDS_Face& F,
SMESH_MesherHelper& helper,
const SMESHDS_SubMesh* faceSubMesh );
+ void fixBadFaces(const TopoDS_Face& F, SMESH_MesherHelper& helper);
bool addBoundaryElements();
bool error( const string& text, int solidID=-1 );
@@ -726,6 +737,67 @@ namespace
}
return dir;
}
+ //================================================================================
+ /*!
+ * \brief Returns true if a FACE is bound by a concave EDGE
+ */
+ //================================================================================
+
+ bool isConcave( const TopoDS_Face& F, SMESH_MesherHelper& helper )
+ {
+ gp_Vec2d drv1, drv2;
+ gp_Pnt2d p;
+ TopExp_Explorer eExp( F.Oriented( TopAbs_FORWARD ), TopAbs_EDGE );
+ for ( ; eExp.More(); eExp.Next() )
+ {
+ const TopoDS_Edge& E = TopoDS::Edge( eExp.Current() );
+ if ( BRep_Tool::Degenerated( E )) continue;
+ // check if 2D curve is concave
+ BRepAdaptor_Curve2d curve( E, F );
+ const int nbIntervals = curve.NbIntervals( GeomAbs_C2 );
+ TColStd_Array1OfReal intervals(1, nbIntervals + 1 );
+ curve.Intervals( intervals, GeomAbs_C2 );
+ bool isConvex = true;
+ for ( int i = 1; i <= nbIntervals && isConvex; ++i )
+ {
+ double u1 = intervals( i );
+ double u2 = intervals( i+1 );
+ curve.D2( 0.5*( u1+u2 ), p, drv1, drv2 );
+ double cross = drv2 ^ drv1;
+ if ( E.Orientation() == TopAbs_REVERSED )
+ cross = -cross;
+ isConvex = ( cross < 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;
+ // }
+ }
+ }
+ return false;
+ }
//--------------------------------------------------------------------------------
// DEBUG. Dump intermediate node positions into a python script
#ifdef __myDEBUG
@@ -737,31 +809,38 @@ namespace
py = new ofstream(fname);
*py << "from smesh import *" << endl
<< "meshSO = GetCurrentStudy().FindObjectID('0:1:2:3')" << endl
- << "mesh = Mesh( meshSO.GetObject()._narrow( SMESH.SMESH_Mesh ))"<GetID()<< ", "<< n->X()
- << ", "<Y()<<", "<< n->Z()<< ")\t\t # "<< ln <GetID()<< ", "<< n->X()
+ << ", "<Y()<<", "<< n->Z()<< ")\t\t # "<< ln <GetID()<<", [";
+ for ( int i=1; i < f->NbNodes(); ++i ) *py << f->GetNode(i-1)->GetID()<<", ";
+ *py << f->GetNode( f->NbNodes()-1 )->GetID() << " ])"<< endl; }}
#else
- struct PyDump { PyDump() {} };
- void dumpFunction(const string& fun ){}
- void dumpFunctionEnd() {}
- void dumpMove(const SMDS_MeshNode* n ){}
- void dumpCmd(const string& txt){}
+ struct PyDump { void Finish() {} };
+#define dumpFunction(f) f
+#define dumpMove(n)
+#define dumpCmd(txt)
+#define dumpFunctionEnd()
+#define dumpChangeNodes(f)
#endif
}
@@ -905,6 +984,7 @@ SMESH_ComputeErrorPtr _ViscousBuilder::Compute(SMESH_Mesh& theMesh,
addBoundaryElements();
makeGroupOfLE(); // debug
+ debugDump.Finish();
return _error;
}
@@ -1067,9 +1147,14 @@ bool _ViscousBuilder::findFacesWithLayers()
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++;
+ }
}
}
@@ -1104,7 +1189,25 @@ bool _ViscousBuilder::findFacesWithLayers()
{
case 1:
{
- _sdVec[i]._shrinkShape2Shape.insert( make_pair( vInd, facesWOL[0] )); break;
+ helper.SetSubShape( facesWOL[0] );
+ if ( helper.IsRealSeam( vInd )) // inflate along a seam edge?
+ {
+ TopoDS_Shape seamEdge;
+ PShapeIteratorPtr eIt = helper.GetAncestors(vertex, *_mesh, TopAbs_EDGE);
+ while ( eIt->more() && seamEdge.IsNull() )
+ {
+ const TopoDS_Shape* e = eIt->next();
+ if ( helper.IsRealSeam( *e ) )
+ seamEdge = *e;
+ }
+ if ( !seamEdge.IsNull() )
+ {
+ _sdVec[i]._shrinkShape2Shape.insert( make_pair( vInd, seamEdge ));
+ break;
+ }
+ }
+ _sdVec[i]._shrinkShape2Shape.insert( make_pair( vInd, facesWOL[0] ));
+ break;
}
case 2:
{
@@ -1817,14 +1920,14 @@ void _LayerEdge::SetCosin( double cosin )
void _ViscousBuilder::getSimplices( const SMDS_MeshNode* node,
vector<_Simplex>& simplices,
const set& ingnoreShapes,
- const _SolidData* dataToCheckOri)
+ const _SolidData* dataToCheckOri,
+ const bool toSort)
{
- SMESH_MeshEditor editor( _mesh );
SMDS_ElemIteratorPtr fIt = node->GetInverseElementIterator(SMDSAbs_Face);
while ( fIt->more() )
{
const SMDS_MeshElement* f = fIt->next();
- const TGeomID shapeInd = editor.FindShape( f );
+ const TGeomID shapeInd = f->getshapeId();
if ( ingnoreShapes.count( shapeInd )) continue;
const int nbNodes = f->NbCornerNodes();
int srcInd = f->GetNodeIndex( node );
@@ -1834,7 +1937,25 @@ void _ViscousBuilder::getSimplices( const SMDS_MeshNode* node,
std::swap( nPrev, nNext );
simplices.push_back( _Simplex( nPrev, nNext ));
}
- simplices.resize( simplices.size() );
+
+ if ( toSort )
+ {
+ vector<_Simplex> sortedSimplices( simplices.size() );
+ sortedSimplices[0] = simplices[0];
+ int nbFound = 0;
+ for ( size_t i = 1; i < simplices.size(); ++i )
+ {
+ for ( size_t j = 1; j < simplices.size(); ++j )
+ if ( sortedSimplices[i-1]._nNext == simplices[j]._nPrev )
+ {
+ sortedSimplices[i] = simplices[j];
+ nbFound++;
+ break;
+ }
+ }
+ if ( nbFound == simplices.size() - 1 )
+ simplices.swap( sortedSimplices );
+ }
}
//================================================================================
@@ -2053,10 +2174,12 @@ bool _ViscousBuilder::smoothAndCheck(_SolidData& data,
TGeomID sInd = data._edges[ iBeg ]->_nodes[0]->getshapeId();
if ( data._edges[ iBeg ]->IsOnEdge() )
- { // try a simple solution on an analytic EDGE
+ {
+ dumpFunction(SMESH_Comment("smooth")<_pos.back() = newPos;
SMDS_MeshNode* tgtNode = const_cast( data._edges[i]->_nodes.back() );
tgtNode->setXYZ( newPos.X(), newPos.Y(), newPos.Z() );
+ dumpMove( tgtNode );
}
}
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
+ {
+ int iPeriodic = helper.GetPeriodicIndex();
+ if ( iPeriodic == 1 || iPeriodic == 2 )
+ {
+ uv1.SetCoord( iPeriodic, helper.GetOtherParam( uv1.Coord( iPeriodic )));
+ if ( uv0.Coord( iPeriodic ) > uv1.Coord( iPeriodic ))
+ std::swap( uv0, uv1 );
+ }
+ }
+ const gp_XY rangeUV = uv1 - uv0;
for ( int i = iFrom; i < iTo; ++i )
{
double r = len[i-iFrom] / len.back();
- gp_XY newUV = uv0 * ( 1. - r ) + uv1 * r;
+ gp_XY newUV = uv0 + r * rangeUV;
data._edges[i]->_pos.back().SetCoord( newUV.X(), newUV.Y(), 0 );
gp_Pnt newPos = surface->Value( newUV.X(), newUV.Y() );
SMDS_MeshNode* tgtNode = const_cast( data._edges[i]->_nodes.back() );
tgtNode->setXYZ( newPos.X(), newPos.Y(), newPos.Z() );
+ dumpMove( tgtNode );
SMDS_FacePosition* pos = static_cast( tgtNode->GetPosition() );
pos->SetUParameter( newUV.X() );
@@ -2388,6 +2524,7 @@ bool _ViscousBuilder::smoothAnalyticEdge( _SolidData& data,
gp_Pnt newPos = surface->Value( newUV.X(), newUV.Y() );
SMDS_MeshNode* tgtNode = const_cast( data._edges[i]->_nodes.back() );
tgtNode->setXYZ( newPos.X(), newPos.Y(), newPos.Z() );
+ dumpMove( tgtNode );
SMDS_FacePosition* pos = static_cast( tgtNode->GetPosition() );
pos->SetUParameter( newUV.X() );
@@ -3329,7 +3466,6 @@ bool _ViscousBuilder::shrink()
_SolidData& data = *f2sd->second;
TNode2Edge& n2eMap = data._n2eMap;
const TopoDS_Face& F = TopoDS::Face( getMeshDS()->IndexToShape( f2sd->first ));
- const bool reverse = ( data._reversedFaceIds.count( f2sd->first ));
Handle(Geom_Surface) surface = BRep_Tool::Surface(F);
@@ -3357,12 +3493,15 @@ bool _ViscousBuilder::shrink()
// Find out face orientation
double refSign = 1;
const set ignoreShapes;
+ bool isOkUV;
if ( !smoothNodes.empty() )
{
- gp_XY uv = helper.GetNodeUV( F, smoothNodes[0] );
vector<_Simplex> simplices;
getSimplices( smoothNodes[0], simplices, ignoreShapes );
- if ( simplices[0].IsForward(uv, F, helper,refSign) != (!reverse))
+ helper.GetNodeUV( F, simplices[0]._nPrev, 0, &isOkUV ); // fix UV of silpmex nodes
+ helper.GetNodeUV( F, simplices[0]._nNext, 0, &isOkUV );
+ gp_XY uv = helper.GetNodeUV( F, smoothNodes[0], 0, &isOkUV );
+ if ( !simplices[0].IsForward(uv, smoothNodes[0], F, helper,refSign) )
refSign = -1;
}
@@ -3410,8 +3549,10 @@ bool _ViscousBuilder::shrink()
}
}
+ // find out if a FACE is concave
+ const bool isConcaveFace = isConcave( F, helper );
+
// Create _SmoothNode's on face F
- bool isOkUV;
vector< _SmoothNode > nodesToSmooth( smoothNodes.size() );
{
dumpFunction(SMESH_Comment("beforeShrinkFace")<first); // debug
@@ -3420,7 +3561,7 @@ bool _ViscousBuilder::shrink()
const SMDS_MeshNode* n = smoothNodes[i];
nodesToSmooth[ i ]._node = n;
// src nodes must be replaced by tgt nodes to have tgt nodes in _simplices
- getSimplices( n, nodesToSmooth[ i ]._simplices, ignoreShapes );
+ getSimplices( n, nodesToSmooth[ i ]._simplices, ignoreShapes, NULL, isConcaveFace );
// fix up incorrect uv of nodes on the FACE
helper.GetNodeUV( F, n, 0, &isOkUV);
dumpMove( n );
@@ -3465,8 +3606,6 @@ bool _ViscousBuilder::shrink()
shrinked |= lEdges[i]->SetNewLength2d( surface,F,helper );
}
dumpFunctionEnd();
- if ( !shrinked )
- break;
// Move nodes on EDGE's
set< _Shrinker1D* >::iterator shr = eShri1D.begin();
@@ -3487,7 +3626,8 @@ bool _ViscousBuilder::shrink()
moved = false;
for ( unsigned i = 0; i < nodesToSmooth.size(); ++i )
{
- moved |= nodesToSmooth[i].Smooth( badNb,surface,helper,refSign,/*set3D=*/false );
+ moved |= nodesToSmooth[i].Smooth( badNb,surface,helper,refSign,
+ /*isCentroidal=*/isConcaveFace,/*set3D=*/false );
}
if ( badNb < oldBadNb )
nbNoImpSteps = 0;
@@ -3517,17 +3657,20 @@ bool _ViscousBuilder::shrink()
highQuality = ( *nbNodesSet.begin() == 4 );
}
}
- for ( int st = highQuality ? 8 : 3; st; --st )
+ if ( !highQuality && isConcaveFace )
+ fixBadFaces( F, helper ); // fix narrow faces by swaping diagonals
+ for ( int st = highQuality ? 10 : 3; st; --st )
{
dumpFunction(SMESH_Comment("shrinkFace")<first<<"_st"<<++smooStep); // debug
for ( unsigned i = 0; i < nodesToSmooth.size(); ++i )
- nodesToSmooth[i].Smooth( badNb,surface,helper,refSign,/*set3D=*/st==1 );
+ nodesToSmooth[i].Smooth( badNb,surface,helper,refSign,
+ /*isCentroidal=*/isConcaveFace,/*set3D=*/st==1 );
dumpFunctionEnd();
}
// Set an event listener to clear FACE sub-mesh together with SOLID sub-mesh
_SrinkShapeListener::ToClearSubMeshWithSolid( sm, data._solid );
- }// loop on FACES to srink mesh on
+ } // loop on FACES to srink mesh on
// Replace source nodes by target nodes in shrinked mesh edges
@@ -3713,6 +3856,124 @@ bool _ViscousBuilder::prepareEdgeToShrink( _LayerEdge& edge,
// return true;
}
+//================================================================================
+/*!
+ * \brief Try to fix triangles with high aspect ratio by swaping diagonals
+ */
+//================================================================================
+
+void _ViscousBuilder::fixBadFaces(const TopoDS_Face& F, SMESH_MesherHelper& helper)
+{
+ SMESH::Controls::AspectRatio qualifier;
+ SMESH::Controls::TSequenceOfXYZ points(3), points1(3), points2(3);
+ const double maxAspectRatio = 4.;
+
+ // find bad triangles
+
+ vector< const SMDS_MeshElement* > badTrias;
+ vector< double > badAspects;
+ SMESHDS_SubMesh* sm = helper.GetMeshDS()->MeshElements( F );
+ SMDS_ElemIteratorPtr fIt = sm->GetElements();
+ while ( fIt->more() )
+ {
+ const SMDS_MeshElement * f = fIt->next();
+ if ( f->NbCornerNodes() != 3 ) continue;
+ for ( int iP = 0; iP < 3; ++iP ) points(iP+1) = SMESH_TNodeXYZ( f->GetNode(iP));
+ double aspect = qualifier.GetValue( points );
+ if ( aspect > maxAspectRatio )
+ {
+ badTrias.push_back( f );
+ badAspects.push_back( aspect );
+ }
+ }
+ if ( badTrias.empty() )
+ return;
+
+ // find couples of faces to swap diagonal
+
+ typedef pair < const SMDS_MeshElement* , const SMDS_MeshElement* > T2Trias;
+ vector< T2Trias > triaCouples;
+
+ TIDSortedElemSet involvedFaces, emptySet;
+ for ( size_t iTia = 0; iTia < badTrias.size(); ++iTia )
+ {
+ T2Trias trias [3];
+ double aspRatio [3];
+ int i1, i2, i3;
+
+ involvedFaces.insert( badTrias[iTia] );
+ for ( int iP = 0; iP < 3; ++iP )
+ points(iP+1) = SMESH_TNodeXYZ( badTrias[iTia]->GetNode(iP));
+
+ // find triangles adjacent to badTrias[iTia] with better aspect ratio after diag-swaping
+ int bestCouple = -1;
+ for ( int iSide = 0; iSide < 3; ++iSide )
+ {
+ const SMDS_MeshNode* n1 = badTrias[iTia]->GetNode( iSide );
+ const SMDS_MeshNode* n2 = badTrias[iTia]->GetNode(( iSide+1 ) % 3 );
+ trias [iSide].first = badTrias[iTia];
+ trias [iSide].second = SMESH_MeshEditor::FindFaceInSet( n1, n2, emptySet, involvedFaces,
+ & i1, & i2 );
+ if ( ! trias[iSide].second || trias[iSide].second->NbCornerNodes() != 3 )
+ continue;
+
+ // aspect ratio of an adjacent tria
+ for ( int iP = 0; iP < 3; ++iP )
+ points2(iP+1) = SMESH_TNodeXYZ( trias[iSide].second->GetNode(iP));
+ double aspectInit = qualifier.GetValue( points2 );
+
+ // arrange nodes as after diag-swaping
+ if ( helper.WrapIndex( i1+1, 3 ) == i2 )
+ i3 = helper.WrapIndex( i1-1, 3 );
+ else
+ i3 = helper.WrapIndex( i1+1, 3 );
+ points1 = points;
+ points1( 1+ iSide ) = points2( 1+ i3 );
+ points2( 1+ i2 ) = points1( 1+ ( iSide+2 ) % 3 );
+
+ // aspect ratio after diag-swaping
+ aspRatio[ iSide ] = qualifier.GetValue( points1 ) + qualifier.GetValue( points2 );
+ if ( aspRatio[ iSide ] > aspectInit + badAspects[ iTia ] )
+ continue;
+
+ if ( bestCouple < 0 || aspRatio[ bestCouple ] > aspRatio[ iSide ] )
+ bestCouple = iSide;
+ }
+
+ if ( bestCouple >= 0 )
+ {
+ triaCouples.push_back( trias[bestCouple] );
+ involvedFaces.insert ( trias[bestCouple].second );
+ }
+ else
+ {
+ involvedFaces.erase( badTrias[iTia] );
+ }
+ }
+ if ( triaCouples.empty() )
+ return;
+
+ // swap diagonals
+
+ SMESH_MeshEditor editor( helper.GetMesh() );
+ dumpFunction(SMESH_Comment("beforeSwapDiagonals_F")< uv( _simplices.size() );
+ for ( size_t i = 0; i < _simplices.size(); ++i )
+ uv[i] = helper.GetNodeUV( face, _simplices[i]._nPrev, _node );
+
// compute new UV for the node
gp_XY newPos (0,0);
- for ( unsigned i = 0; i < _simplices.size(); ++i )
- newPos += helper.GetNodeUV( face, _simplices[i]._nPrev );
- newPos /= _simplices.size();
+ if ( isCentroidal && _simplices.size() > 3 )
+ {
+ // average centers of diagonals wieghted with their reciprocal lengths
+ if ( _simplices.size() == 4 )
+ {
+ double w1 = 1. / ( uv[2]-uv[0] ).SquareModulus();
+ double w2 = 1. / ( uv[3]-uv[1] ).SquareModulus();
+ newPos = ( w1 * ( uv[2]+uv[0] ) + w2 * ( uv[3]+uv[1] )) / ( w1+w2 ) / 2;
+ }
+ else
+ {
+ double sumWeight = 0;
+ int nb = _simplices.size() == 4 ? 2 : _simplices.size();
+ for ( int i = 0; i < nb; ++i )
+ {
+ int iFrom = i + 2;
+ int iTo = i + _simplices.size() - 1;
+ for ( int j = iFrom; j < iTo; ++j )
+ {
+ int i2 = SMESH_MesherHelper::WrapIndex( j, _simplices.size() );
+ double w = 1. / ( uv[i]-uv[i2] ).SquareModulus();
+ sumWeight += w;
+ newPos += w * ( uv[i]+uv[i2] );
+ }
+ }
+ newPos /= 2 * sumWeight;
+ }
+ }
+ else
+ {
+ // Laplacian smooth
+ isCentroidal = false;
+ for ( size_t i = 0; i < _simplices.size(); ++i )
+ newPos += uv[i];
+ newPos /= _simplices.size();
+ }
// count quality metrics (orientation) of triangles around the node
int nbOkBefore = 0;
gp_XY tgtUV = helper.GetNodeUV( face, _node );
for ( unsigned i = 0; i < _simplices.size(); ++i )
- nbOkBefore += _simplices[i].IsForward( tgtUV, face, helper, refSign );
+ nbOkBefore += _simplices[i].IsForward( tgtUV, _node, face, helper, refSign );
int nbOkAfter = 0;
for ( unsigned i = 0; i < _simplices.size(); ++i )
- nbOkAfter += _simplices[i].IsForward( newPos, face, helper, refSign );
+ nbOkAfter += _simplices[i].IsForward( newPos, _node, face, helper, refSign );
if ( nbOkAfter < nbOkBefore )
+ {
+ // if ( isCentroidal )
+ // return Smooth( badNb, surface, helper, refSign, !isCentroidal, set3D );
+ badNb += _simplices.size() - nbOkBefore;
return false;
+ }
SMDS_FacePosition* pos = static_cast( _node->GetPosition() );
pos->SetUParameter( newPos.X() );
diff --git a/src/StdMeshersGUI/StdMeshersGUI_CartesianParamCreator.cxx b/src/StdMeshersGUI/StdMeshersGUI_CartesianParamCreator.cxx
index 1a54a4502..e161c9ae2 100644
--- a/src/StdMeshersGUI/StdMeshersGUI_CartesianParamCreator.cxx
+++ b/src/StdMeshersGUI/StdMeshersGUI_CartesianParamCreator.cxx
@@ -688,3 +688,7 @@ QString StdMeshersGUI_CartesianParamCreator::storeParams() const
return "";
}
+QString StdMeshersGUI_CartesianParamCreator::helpPage() const
+{
+ return "cartesian_algo_page.html#cartesian_hyp_anchor";
+}
diff --git a/src/StdMeshersGUI/StdMeshersGUI_CartesianParamCreator.h b/src/StdMeshersGUI/StdMeshersGUI_CartesianParamCreator.h
index a35608f88..7654f26ac 100644
--- a/src/StdMeshersGUI/StdMeshersGUI_CartesianParamCreator.h
+++ b/src/StdMeshersGUI/StdMeshersGUI_CartesianParamCreator.h
@@ -125,7 +125,8 @@ public:
StdMeshersGUI_CartesianParamCreator( const QString& aHypType );
virtual ~StdMeshersGUI_CartesianParamCreator();
- virtual bool checkParams( QString& ) const;
+ virtual bool checkParams( QString& ) const;
+ virtual QString helpPage() const;
protected:
virtual QFrame* buildFrame();
diff --git a/src/StdMeshersGUI/StdMeshers_msg_en.ts b/src/StdMeshersGUI/StdMeshers_msg_en.ts
index 8a5d055b5..8564f2323 100644
--- a/src/StdMeshersGUI/StdMeshers_msg_en.ts
+++ b/src/StdMeshersGUI/StdMeshers_msg_en.ts
@@ -165,7 +165,8 @@
- Faces without layers
+ Faces without layers
+(inlets and oulets)
diff --git a/src/StdMeshersGUI/StdMeshers_msg_fr.ts b/src/StdMeshersGUI/StdMeshers_msg_fr.ts
index 1f2374414..9c9352a4e 100755
--- a/src/StdMeshersGUI/StdMeshers_msg_fr.ts
+++ b/src/StdMeshersGUI/StdMeshers_msg_fr.ts
@@ -139,6 +139,10 @@
Longueur maximale
+
+
+ Paramètres de Body Fitting
+ Utiliser la longueur pré-estimée
@@ -157,16 +161,21 @@
- Facteur d'échelle
+ Facteur d'échelle
- Faces sans couche limite
+ Faces sans couche limite
+(entrées et sorties)Construction de l'hypothèse
+
+
+ Construction de l'hypothèse
+ Aire maximale d'une maille
@@ -434,4 +443,42 @@
Editer
+
+ StdMeshersGUI_CartesianParamCreator
+
+
+ Seuil
+
+
+
+ Axe X
+
+
+
+ Axe Y
+
+
+
+ Axe Z
+
+
+
+ StdMeshersGUI::GridAxisTab
+
+
+ Mode de définition
+
+
+
+ Espacement
+
+
+
+ Insérer
+
+
+
+ Pas
+
+
diff --git a/src/Tools/Makefile.am b/src/Tools/Makefile.am
index 92083da94..96b92e3cf 100644
--- a/src/Tools/Makefile.am
+++ b/src/Tools/Makefile.am
@@ -25,6 +25,4 @@
#
include $(top_srcdir)/adm_local/unix/make_common_starter.am
-SUBDIRS = MeshCut
-
-DIST_SUBDIRS = MeshCut
+SUBDIRS = MeshCut padder
diff --git a/src/Tools/MeshCut/Makefile.am b/src/Tools/MeshCut/Makefile.am
index 62a1d8a4e..c1cecffd9 100644
--- a/src/Tools/MeshCut/Makefile.am
+++ b/src/Tools/MeshCut/Makefile.am
@@ -45,11 +45,15 @@ MeshCut_LDFLAGS = $(MED2_LIBS) $(HDF5_LIBS)
UIPY_FILES = MeshCutDialog.py
-BUILT_SOURCES = $(UIPY_FILES)
-bin_SCRIPTS = $(UIPY_FILES) meshcut_plugin.py
-clean-local:
- rm -f $(UIPY_FILES)
-EXTRA_DIST += MeshCutDialog.ui meshcut_plugin.py
+
+if SMESH_ENABLE_GUI
+ dist_salomescript_SCRIPTS = meshcut_plugin.py
+ nodist_salomescript_SCRIPTS = $(UIPY_FILES)
+endif
+
+CLEANFILES = $(UIPY_FILES)
+
+EXTRA_DIST += $(UIPY_FILES:%.py=%.ui)
%.py : %.ui
- pyuic4 $< -o $@
+ $(PYUIC) $< -o $@
diff --git a/src/Tools/padder/Makefile.am b/src/Tools/padder/Makefile.am
new file mode 100644
index 000000000..6f1623464
--- /dev/null
+++ b/src/Tools/padder/Makefile.am
@@ -0,0 +1,3 @@
+SUBDIRS = meshjob spadderpy unittests resources doc
+
+EXTRA_DIST = README.txt
diff --git a/src/Tools/padder/README.txt b/src/Tools/padder/README.txt
new file mode 100644
index 000000000..2ecebb32c
--- /dev/null
+++ b/src/Tools/padder/README.txt
@@ -0,0 +1,38 @@
+
+
+PADDER overview
+---------------
+
+PADDER is an algorithm that creates a set of particules called a "discrete mesh".
+The particules are characterized by a location in space and a weight that can be considered
+as the radius of a sphere whose center is the location of the particule.
+
+Discrete meshes are typically used to modelize civil components in rapid dynamic
+computation problems (seisms, chocs). These components consists in concrete parts
+embedding steal bares for reinforcement. These parts are input to the algorithm
+as standard finite elements meshes. The cells of theses meshes drive the location
+and sizing of particules.
+
+In the med representation, a discrete mesh is described as MED_BALL elements.
+A MED_BALL element is defined by a location and a radius.
+
+PADDER plugin
+-------------
+
+This directory provides SMESH with a SALOME plugin that can be used to define
+and then run a PADDER execution. The inputs are the FE meshes that describe
+the concrete parts and steal bares parts. The output is a discrete mesh
+containing MED_BALL elements.
+
+A graphical interface is used to drive the user for data input and computation
+supervision (the algorithm may last more than an hour long), and finally the publication
+of the resulting mesh (when succeed) in the SALOME study.
+
+Technically speaking, the PADDER plugin consists in:
+
+* a SALOME component MESHJOB that do the computation job (wrapper to the padder executable program)
+* a graphical interface composed of two dialog windows
+* a configuration mechanism (data file and read function), to define
+ the computation resource (a SALOME resource + the software configuration of the padder executable
+ program on this resource)
+* an integration file (salomeplugin.py)
diff --git a/src/Tools/padder/doc/Makefile.am b/src/Tools/padder/doc/Makefile.am
new file mode 100755
index 000000000..fa2d6f82e
--- /dev/null
+++ b/src/Tools/padder/doc/Makefile.am
@@ -0,0 +1,39 @@
+# Copyright (C) 2007-2011 CEA/DEN, EDF R&D, OPEN CASCADE
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+# Author : Guillaume Boulant (EDF/R&D)
+
+include $(top_srcdir)/adm_local/unix/make_common_starter.am
+
+EXTRA_DIST += images input
+
+#
+# The simplest way to extend the documentation of SMESH with the
+# documentation for PADDER is to add path to the padder documentation
+# in the SMESH gui documentation (see the doxyfile).
+#
+
+# For test purpose, we let the user generate a local dosygen
+# documentation including only the local pages
+#
+test_docs: doxyfile
+ echo "===========================================" ; \
+ echo "Generating PADDER documentation" ; \
+ echo "===========================================" ; \
+ $(DOXYGEN) doxyfile ;
diff --git a/src/Tools/padder/doc/doxyfile.in b/src/Tools/padder/doc/doxyfile.in
new file mode 100755
index 000000000..8f2aa2ac2
--- /dev/null
+++ b/src/Tools/padder/doc/doxyfile.in
@@ -0,0 +1,77 @@
+# Copyright (C) 2007-2011 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.
+#
+# 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
+#
+
+#---------------------------------------------------------------------------
+# Project related configuration options
+#---------------------------------------------------------------------------
+PROJECT_NAME = "SALOME Mesh User's Guide"
+OUTPUT_DIRECTORY = .
+CREATE_SUBDIRS = NO
+OUTPUT_LANGUAGE = English
+TAB_SIZE = 5
+
+#---------------------------------------------------------------------------
+# configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+QUIET = NO
+WARNINGS = YES
+
+#---------------------------------------------------------------------------
+#Input related options
+#---------------------------------------------------------------------------
+INPUT = @srcdir@/input
+FILE_PATTERNS = *.doc
+EXCLUDE =
+IMAGE_PATH = @srcdir@/images
+EXAMPLE_PATH = @top_srcdir@/src/SMESH_SWIG
+
+#---------------------------------------------------------------------------
+#HTML related options
+#---------------------------------------------------------------------------
+GENERATE_HTML = YES
+HTML_OUTPUT = .
+HTML_HEADER = @top_builddir@/doc/salome/gui/SMESH/static/header.html
+HTML_FOOTER = @top_srcdir@/doc/salome/gui/SMESH/static/footer.html
+HTML_STYLESHEET = @top_srcdir@/doc/salome/gui/SMESH/static/doxygen.css
+TOC_EXPAND = YES
+DISABLE_INDEX = NO
+GENERATE_TREEVIEW = YES
+TREEVIEW_WIDTH = 300
+
+#---------------------------------------------------------------------------
+#SORT related options
+#---------------------------------------------------------------------------
+SORT_GROUP_NAMES = NO
+
+
+#---------------------------------------------------------------------------
+#LaTeX related option
+#---------------------------------------------------------------------------
+GENERATE_LATEX = NO
+EXTRA_PACKAGES = amsmath
+
+#---------------------------------------------------------------------------
+#RTF related options
+#---------------------------------------------------------------------------
+GENERATE_RTF = NO
+
+SEARCHENGINE = YES
diff --git a/src/Tools/padder/doc/images/SMESH_spadder_end.png b/src/Tools/padder/doc/images/SMESH_spadder_end.png
new file mode 100644
index 000000000..12e2b7cf2
Binary files /dev/null and b/src/Tools/padder/doc/images/SMESH_spadder_end.png differ
diff --git a/src/Tools/padder/doc/images/SMESH_spadder_inputdialog_concrete.png b/src/Tools/padder/doc/images/SMESH_spadder_inputdialog_concrete.png
new file mode 100644
index 000000000..ed0a8a72c
Binary files /dev/null and b/src/Tools/padder/doc/images/SMESH_spadder_inputdialog_concrete.png differ
diff --git a/src/Tools/padder/doc/images/SMESH_spadder_inputdialog_start.png b/src/Tools/padder/doc/images/SMESH_spadder_inputdialog_start.png
new file mode 100644
index 000000000..8725d7165
Binary files /dev/null and b/src/Tools/padder/doc/images/SMESH_spadder_inputdialog_start.png differ
diff --git a/src/Tools/padder/doc/images/SMESH_spadder_inputdialog_steelbar.png b/src/Tools/padder/doc/images/SMESH_spadder_inputdialog_steelbar.png
new file mode 100644
index 000000000..8e692dcff
Binary files /dev/null and b/src/Tools/padder/doc/images/SMESH_spadder_inputdialog_steelbar.png differ
diff --git a/src/Tools/padder/doc/images/SMESH_spadder_menu.png b/src/Tools/padder/doc/images/SMESH_spadder_menu.png
new file mode 100644
index 000000000..e89140690
Binary files /dev/null and b/src/Tools/padder/doc/images/SMESH_spadder_menu.png differ
diff --git a/src/Tools/padder/doc/images/SMESH_spadder_plugindialog_compute_finished.png b/src/Tools/padder/doc/images/SMESH_spadder_plugindialog_compute_finished.png
new file mode 100644
index 000000000..e29cf5634
Binary files /dev/null and b/src/Tools/padder/doc/images/SMESH_spadder_plugindialog_compute_finished.png differ
diff --git a/src/Tools/padder/doc/images/SMESH_spadder_plugindialog_compute_ready.png b/src/Tools/padder/doc/images/SMESH_spadder_plugindialog_compute_ready.png
new file mode 100644
index 000000000..f86790b0c
Binary files /dev/null and b/src/Tools/padder/doc/images/SMESH_spadder_plugindialog_compute_ready.png differ
diff --git a/src/Tools/padder/doc/images/SMESH_spadder_plugindialog_compute_running.png b/src/Tools/padder/doc/images/SMESH_spadder_plugindialog_compute_running.png
new file mode 100644
index 000000000..b3c9ef169
Binary files /dev/null and b/src/Tools/padder/doc/images/SMESH_spadder_plugindialog_compute_running.png differ
diff --git a/src/Tools/padder/doc/images/SMESH_spadder_plugindialog_published.png b/src/Tools/padder/doc/images/SMESH_spadder_plugindialog_published.png
new file mode 100644
index 000000000..19e1ae71f
Binary files /dev/null and b/src/Tools/padder/doc/images/SMESH_spadder_plugindialog_published.png differ
diff --git a/src/Tools/padder/doc/images/SMESH_spadder_plugindialog_start.png b/src/Tools/padder/doc/images/SMESH_spadder_plugindialog_start.png
new file mode 100644
index 000000000..45ba1a097
Binary files /dev/null and b/src/Tools/padder/doc/images/SMESH_spadder_plugindialog_start.png differ
diff --git a/src/Tools/padder/doc/images/SMESH_spadder_start.png b/src/Tools/padder/doc/images/SMESH_spadder_start.png
new file mode 100644
index 000000000..160da9d26
Binary files /dev/null and b/src/Tools/padder/doc/images/SMESH_spadder_start.png differ
diff --git a/src/Tools/padder/doc/input/padder_userguide.doc b/src/Tools/padder/doc/input/padder_userguide.doc
new file mode 100644
index 000000000..d92f85ef6
--- /dev/null
+++ b/src/Tools/padder/doc/input/padder_userguide.doc
@@ -0,0 +1,139 @@
+/*!
+
+\page padder_userguide_page Use the padder SMESH Plugin
+
+-# \ref S1_PADDER
+-# \ref S2_PADDER
+-# \ref S3_PADDER
+
+\section S1_PADDER The PADDER Algorithm
+
+PADDER is an algorithm that creates a set of particules called a "discrete mesh".
+The particules are characterized by a location in space and a weight that can be considered
+as the radius of a sphere whose center is the location of the particule.
+
+Discrete meshes are typically used to modelize civil components in rapid dynamic
+computation problems (seisms, chocs). These components consists in concrete parts
+embedding steal bares for reinforcement. These parts are input to the algorithm
+as standard finite elements meshes. The cells of theses meshes drive the location
+and sizing of particules.
+
+In the med representation, a discrete mesh is described as MED_BALL elements.
+A MED_BALL element is defined by a location and a radius.
+
+\section S2_PADDER The PADDER SALOME plugin
+
+The PADDER algoritm is integrated in the module SMESH as a SALOME
+plugin. This section illustrates how to use this plugin to create a
+discrete mesh.
+
+In this example, we suppose that two standard meshes (Finite Elements
+Meshes) have been created and publish in the study to modelize the
+concrete part (here with the name "concrete") and the steal bars part
+(here with the name "ferrail"):
+
+\image html SMESH_spadder_start.png
+
+The PADDER plugin can be invoked from the SMESH plugins menu, as
+illustrated on the figure below:
+
+\image html SMESH_spadder_menu.png
+
+When you clic on the "PADDER mesher" item, the graphical interface of
+the PADDER plugin appears:
+
+\image html SMESH_spadder_plugindialog_start.png
+
+This interface invites you to specify input data by pressing the button
+"Input". This command opens the Input dialog box to specify the list
+of meshes and the type of the selected meshes (to be choosen between
+"concrete" or "steelbar" using the combobox on the right side of the
+input line):
+
+\image html SMESH_spadder_inputdialog_start.png
+
+In the figure below, the mesh with name "concrete" has been selected
+in the study and added in the list of input file as a "concrete
+mesh". You have to input the mesh in the dialog using the rounded
+arrow icon, then specify a group name (the name of the group of
+MED_BALL created for this mesh in the resulting mesh), and finnaly
+clic on the "Add" icon:
+
+\image html SMESH_spadder_inputdialog_concrete.png
+
+Then, the mesh with name "ferrail" is selected and added to the list
+as a "steelbar mesh":
+
+\image html SMESH_spadder_inputdialog_steelbar.png
+
+The input dialog box can be validated toreturn to the main plugin
+interface. The "Compute" button is now enable, indicating that the
+problem is ready to be computed:
+
+\image html SMESH_spadder_plugindialog_compute_ready.png
+
+The command "Compute" start the job. The progression can be requested
+using the command "Refresh". In the figure below, the job is still
+running:
+
+\image html SMESH_spadder_plugindialog_compute_running.png
+
+Finally, the job is finished and the result is ready to be published
+in the SALOME study:
+
+\image html SMESH_spadder_plugindialog_compute_finished.png
+
+Clic on the command "Publish" to explicitly import the resulting med
+file in SMESH and published the resulting mesh in the SALOME study:
+
+\image html SMESH_spadder_plugindialog_published.png
+
+Note that this mesh contains one group for each of the input mesh. A
+group with the name specified in the input dialog has been defined for
+the set of MED_BALL created from the corresponding input mesh:
+
+\image html SMESH_spadder_end.png
+
+\section S3_PADDER Configuring the plugin
+
+The configuration of the plugin consists in specifying the location of
+the padder executable program for each of the SALOME resource (at
+least for the localhost resource). This specification is done in the
+file padder.cfg, located in the plugin installation folder
+(i.e. /plugins):
+
+\code
+# This section specify the configurations to be used respectively for
+# the local execution and the remote execution. The value for 'local'
+# and 'remote' keys must be the name of a configuration section in
+# this file. The default key must specify a value between "local" or
+# "remote" to indicate the user preference.
+[resources]
+local = localhost
+remote = nepal
+
+[preferences]
+defaultres = local
+
+# The following sections defines the available configurations.
+# The name of the section can be choosen arbitrary. But the value of
+# the resname key MUST be the name of a SALOME resource defined in the
+# catalog of resources (CatalogResources.xml).
+
+# For each section:
+# - resname : the name of the SALOME resource to be used in this configuration
+# - binpath : the path to the padder executable program on this resource
+# - envpath : the path to the environment file on this resource
+[localhost]
+resname = localhost
+binpath = /home/.programs/salome/workspace/V6_4_BR/SMESH/install/share/salome/resources/smesh/padderexe/padder.exe
+envpath = /home/.programs/salome/workspace/V6_4_BR/SMESH/install/share/salome/resources/smesh/padderexe/envPadder.sh
+
+[nepal]
+resname = nepal@nepal
+binpath = /usr/local/bin/padder.exe
+envpath = /usr/local/share/envPadder.sh
+\endcode
+
+*/
+
diff --git a/src/Tools/padder/meshjob/Makefile.am b/src/Tools/padder/meshjob/Makefile.am
new file mode 100644
index 000000000..26bf6ee9b
--- /dev/null
+++ b/src/Tools/padder/meshjob/Makefile.am
@@ -0,0 +1 @@
+SUBDIRS = idl impl
diff --git a/src/Tools/padder/meshjob/idl/MESHJOB.idl b/src/Tools/padder/meshjob/idl/MESHJOB.idl
new file mode 100644
index 000000000..dc423189b
--- /dev/null
+++ b/src/Tools/padder/meshjob/idl/MESHJOB.idl
@@ -0,0 +1,126 @@
+// Copyright (C) 2011 CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+// Authors : Guillaume Boulant (EDF) - 31/01/2011
+
+#ifndef _MESHJOB_IDL_
+#define _MESHJOB_IDL_
+
+#include "SALOME_Exception.idl"
+#include "SALOME_Component.idl"
+
+//
+// This interface is used for mesh job submission from within the
+// SALOME plugin for PADDER.
+//
+module MESHJOB
+{
+
+ //
+ // Structure to transmit the parameters requiered for the job to run
+ // the executable program on the target resource. See configure
+ // service.
+ //
+ struct ConfigParameter {
+ string resname; // The name of the SALOME resource to be used
+ string binpath; // The path of the executable program on this resource
+ string envpath; // The path of the environment file on this resource
+ };
+
+ //
+ // This set of specification defines the data structure used to
+ // initialize a job on a specific resource, then supervise the job
+ // and finally retrieve the result data.
+ //
+
+ // This defines the set of temporary folders used by the jobmanager
+ // when executing a job (may depends on the job).
+ struct MeshJobPaths
+ {
+ string local_inputdir;
+ string local_resultdir;
+ string remote_workdir;
+ };
+
+ // This defines the possible types for a job parameter
+ enum FileType {MED_CONCRETE, MED_STEELBAR};
+
+ // This defines a single parameter for the job initialization (a med file)
+ struct MeshJobParameter
+ {
+ string file_name;
+ FileType file_type;
+ string group_name;
+ };
+
+ // This defines a set of parameters for the job initialization
+ typedef sequence MeshJobParameterList;
+
+ // This defines the result data of a job
+ struct MeshJobResults
+ {
+ string results_dirname;
+ string outputmesh_filename;
+ string status;
+ };
+
+ // This defines the possible states of a job
+ enum MeshJobState {CREATED, IN_PROCESS, QUEUED, RUNNING, PAUSED, FINISHED, ERROR};
+
+ //
+ // This interface defines the computation services of the component
+ //
+
+ interface MeshJobManager: Engines::EngineComponent
+ {
+
+ /*! Add a resource configuration, identified by the string
+ configId and characterized by the parameters in
+ configParameter */
+ boolean configure(in string configId, in MESHJOB::ConfigParameter configParameter)
+ raises (SALOME::SALOME_Exception);
+
+ /*! Initialize a smesh computation job and return the job identifier */
+ long initialize(in MESHJOB::MeshJobParameterList meshJobParameterList, in string configId)
+ raises (SALOME::SALOME_Exception);
+
+ /*! Submit the job execution and return true if submission is OK */
+ boolean start(in long jobId)
+ raises (SALOME::SALOME_Exception);
+
+ /*! Request the launch manager for the state of the specified job */
+ string getState(in long jobId)
+ raises (SALOME::SALOME_Exception);
+
+ /*! Request the launch manager for downloading the results */
+ MeshJobResults finalize(in long jobid)
+ raises (SALOME::SALOME_Exception);
+
+ /*! Clean all data associated to this job and remove the job from the launch manager */
+ boolean clean(in long jobId)
+ raises (SALOME::SALOME_Exception);
+
+ /*! Returns the set of temporary folders used by the job instance */
+ MeshJobPaths getPaths(in long jobId)
+ raises (SALOME::SALOME_Exception);
+
+ };
+
+};
+
+#endif // _MESHJOB_IDL_
diff --git a/src/Tools/padder/meshjob/idl/Makefile.am b/src/Tools/padder/meshjob/idl/Makefile.am
new file mode 100644
index 000000000..1f6ae9af2
--- /dev/null
+++ b/src/Tools/padder/meshjob/idl/Makefile.am
@@ -0,0 +1,86 @@
+# Copyright (C) 2007-2011 CEA/DEN, EDF R&D, OPEN CASCADE
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+# This Makefile is responsible of generating the client and server
+# implementation of IDL interfaces for both C++ and python usage.
+# The building process of the C++ files is in charge of each source
+# package and then is not manage here.
+#
+include $(top_srcdir)/adm_local/unix/make_common_starter.am
+
+BUILT_SOURCES = MESHJOBSK.cc
+IDL_FILES = MESHJOB.idl
+
+# For test purpose, we add a little component:
+BUILT_SOURCES += SPADDERPluginTestSK.cc
+IDL_FILES += SPADDERPluginTest.idl
+
+salomeidl_DATA = $(IDL_FILES)
+
+lib_LTLIBRARIES = libSalomeIDLSPADDER.la
+libSalomeIDLSPADDER_la_SOURCES =
+nodist_libSalomeIDLSPADDER_la_SOURCES = $(BUILT_SOURCES)
+nodist_salomeinclude_HEADERS= $(IDL_FILES:%idl=%hh)
+
+OMNIORB_CXXFLAGS=@OMNIORB_CXXFLAGS@ @OMNIORB_INCLUDES@
+OMNIORB_LIBS=@OMNIORB_LIBS@
+
+libSalomeIDLSPADDER_la_CXXFLAGS = \
+ $(KERNEL_CXXFLAGS) \
+ $(OMNIORB_CXXFLAGS) \
+ -I.
+
+libSalomeIDLSPADDER_la_LIBADD = \
+ $(KERNEL_LDFLAGS) -lSalomeIDLKernel \
+ $(OMNIORB_LIBS)
+
+
+# These variables defines the building process of CORBA files
+IDLCXXFLAGS = \
+ -bcxx -I. \
+ @OMNIORB_IDLCXXFLAGS@ \
+ -I$(KERNEL_ROOT_DIR)/idl/salome
+
+IDLPYFLAGS = \
+ -I. \
+ @OMNIORB_IDLPYFLAGS@ \
+ -I$(KERNEL_ROOT_DIR)/idl/salome
+
+##########################################################
+SUFFIXES = .idl .hh SK.cc
+
+%SK.cc %.hh : %.idl
+ $(OMNIORB_IDL) $(IDLCXXFLAGS) $<
+
+%_idl.py : %.idl
+ $(OMNIORB_IDL) $(IDLPYFLAGS) $<
+
+CLEANFILES = *.hh *SK.cc *.py *.hxx *.cxx
+
+EXTRA_DIST += $(IDL_FILES)
+
+install-data-local: $(IDL_FILES)
+ $(INSTALL) -d $(DESTDIR)$(salomepythondir)
+ ls $^ | while read file; do \
+ $(OMNIORB_IDL) $(IDLPYFLAGS) -C$(DESTDIR)$(salomepythondir) $$file ; \
+ done
+
+uninstall-local:
+ rm -rf $(DESTDIR)$(salomepythondir)/*
+
diff --git a/src/Tools/padder/meshjob/idl/SPADDERPluginTest.idl b/src/Tools/padder/meshjob/idl/SPADDERPluginTest.idl
new file mode 100644
index 000000000..6f04f0104
--- /dev/null
+++ b/src/Tools/padder/meshjob/idl/SPADDERPluginTest.idl
@@ -0,0 +1,46 @@
+// Copyright (C) 2011 CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+// Authors : Guillaume Boulant (EDF) - 31/01/2011
+
+#ifndef _SPADDERPLUGINTEST_IDL_
+#define _SPADDERPLUGINTEST_IDL_
+
+#include "SALOME_Exception.idl"
+#include "SALOME_Component.idl"
+
+module SPADDERPluginTest {
+
+ //
+ // ========================================================================
+ // Thi module defines an interface provided for testing the usage
+ // of SPADDERPlugin components and underlying classes from within a
+ // C++ unit test running in a SALOME container (easy to run from a
+ // python client)..
+ // ========================================================================
+ //
+
+ interface SPADDERPluginTester: Engines::EngineComponent
+ {
+ void demo(in double a,in double b,out double c) raises (SALOME::SALOME_Exception);
+ boolean testkernel() raises (SALOME::SALOME_Exception);
+ boolean testsmesh(in long studyId) raises (SALOME::SALOME_Exception);
+ };
+};
+
+#endif // _SPADDERPLUGINTEST_IDL_
diff --git a/src/Tools/padder/meshjob/impl/Makefile.am b/src/Tools/padder/meshjob/impl/Makefile.am
new file mode 100644
index 000000000..a1cc70129
--- /dev/null
+++ b/src/Tools/padder/meshjob/impl/Makefile.am
@@ -0,0 +1,71 @@
+
+include $(top_srcdir)/adm_local/unix/make_common_starter.am
+
+AM_CFLAGS=$(SALOME_INCLUDES) -fexceptions
+
+lib_LTLIBRARIES= libMeshJobManagerEngine.la
+
+salomeinclude_HEADERS= \
+ MeshJobManager_i.hxx
+
+
+# =============================================================
+# Definition of MeshJobManagerEngine construction
+# =============================================================
+libMeshJobManagerEngine_la_SOURCES = \
+ MeshJobManager_i.cxx
+
+LIBXML_LIBS=@LIBXML_LIBS@
+KERNEL_CXXFLAGS=@KERNEL_CXXFLAGS@
+
+libMeshJobManagerEngine_la_CXXFLAGS = \
+ -I$(top_builddir)/src/Tools/padder/meshjob/idl $(KERNEL_CXXFLAGS) \
+ @CORBA_CXXFLAGS@ @CORBA_INCLUDES@ @LIBXML_INCLUDES@
+
+libMeshJobManagerEngine_la_FFLAGS = -fexceptions
+libMeshJobManagerEngine_la_LDFLAGS = \
+ $(top_builddir)/src/Tools/padder/meshjob/idl/libSalomeIDLSPADDER.la \
+ @KERNEL_LDFLAGS@ -lSalomeContainer -lSalomeKernelHelpers -lSalomeLifeCycleCORBA \
+ @LIBXML_LIBS@
+
+# =============================================================
+# Definition of the SPADDERPluginTester engine construction
+# =============================================================
+lib_LTLIBRARIES += libSPADDERPluginTesterEngine.la
+
+libSPADDERPluginTesterEngine_la_SOURCES = \
+ SPADDERPluginTester_i.hxx \
+ SPADDERPluginTester_i.cxx
+
+nodist_libSPADDERPluginTesterEngine_la_SOURCES =
+
+libSPADDERPluginTesterEngine_la_CXXFLAGS = \
+ -I$(top_builddir)/src/Tools/padder/meshjob/idl $(KERNEL_CXXFLAGS) \
+ @CORBA_CXXFLAGS@ @CORBA_INCLUDES@ @LIBXML_INCLUDES@
+
+libSPADDERPluginTesterEngine_la_FFLAGS = -fexceptions
+libSPADDERPluginTesterEngine_la_LIBADD = \
+ $(top_builddir)/src/Tools/padder/meshjob/idl/libSalomeIDLSPADDER.la \
+ @KERNEL_LDFLAGS@ -lSalomeContainer -lSalomeKernelHelpers \
+ @LIBXML_LIBS@
+
+
+# For testing SMESH
+#
+libSPADDERPluginTesterEngine_la_CXXFLAGS += \
+ @GEOM_CXXFLAGS@ @MED_CXXFLAGS@ \
+ -I$(top_builddir)/idl \
+ -I$(top_srcdir)/src/SMESH \
+ -I$(top_srcdir)/src/SMESH_I \
+ -I$(top_srcdir)/src/SMESHDS \
+ -I$(top_srcdir)/src/SMDS \
+ -I$(top_srcdir)/src/SMESHUtils \
+ $(VTK_INCLUDES) $(CAS_CPPFLAGS) $(BOOST_CPPFLAGS)
+
+libSPADDERPluginTesterEngine_la_LIBADD += \
+ $(top_builddir)/src/SMESH/libSMESHimpl.la \
+ $(top_builddir)/src/SMESH_I/libSMESHEngine.la \
+ $(top_builddir)/src/SMESHDS/libSMESHDS.la \
+ $(top_builddir)/src/SMDS/libSMDS.la \
+ $(top_builddir)/src/SMESHUtils/libSMESHUtils.la
+
diff --git a/src/Tools/padder/meshjob/impl/MeshJobManager_i.cxx b/src/Tools/padder/meshjob/impl/MeshJobManager_i.cxx
new file mode 100644
index 000000000..beb25fdec
--- /dev/null
+++ b/src/Tools/padder/meshjob/impl/MeshJobManager_i.cxx
@@ -0,0 +1,621 @@
+// Copyright (C) 2011 EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+// Authors : Guillaume Boulant (EDF) - 01/03/2011
+#ifdef WIN32
+#include
+#include
+#else
+#include
+#endif
+
+#include "MeshJobManager_i.hxx"
+
+#include
+#include CORBA_SERVER_HEADER(SALOME_Exception)
+
+
+#include "Basics_Utils.hxx" // For standard logging
+#undef LOG
+#include "SALOME_KernelServices.hxx" // For CORBA logging
+#undef LOG
+
+#define LOG STDLOG
+
+//
+// ====================================================================
+// General purpose helper functions (to put elsewhere at least)
+// ====================================================================
+//
+
+/*!
+ * This function must be used to associate a datetime tag to a job
+ */
+
+#ifndef WIN32
+static long timetag() {
+ timeval tv;
+ gettimeofday(&tv,0);
+ long tag = tv.tv_usec + tv.tv_sec*1000000;
+ return tag;
+}
+#endif
+
+/*!
+ * This function returns true if the string text starts with the string
+ * token.
+ */
+static bool myStartsWith(const std::string& text,const std::string& token){
+ if(text.length() < token.length())
+ return false;
+ return (text.compare(0, token.length(), token) == 0);
+}
+
+//
+// ====================================================================
+// Constructor/Destructor
+// ====================================================================
+//
+MeshJobManager_i::MeshJobManager_i(CORBA::ORB_ptr orb,
+ PortableServer::POA_ptr poa,
+ PortableServer::ObjectId * contId,
+ const char *instanceName,
+ const char *interfaceName)
+ : Engines_Component_i(orb, poa, contId, instanceName, interfaceName)
+{
+ LOG("Activating MESHJOB::MeshJobManager object");
+ _thisObj = this ;
+ _id = _poa->activate_object(_thisObj);
+
+ _salomeLauncher = KERNEL::getSalomeLauncher();
+ if(CORBA::is_nil(_salomeLauncher)){
+ LOG("The SALOME launcher can't be reached ==> STOP");
+ throw KERNEL::createSalomeException("SALOME launcher can't be reached");
+ }
+
+ _resourcesManager = KERNEL::getResourcesManager();
+ if(CORBA::is_nil(_resourcesManager)){
+ LOG("The SALOME resource manager can't be reached ==> STOP");
+ throw KERNEL::createSalomeException("The SALOME resource manager can't be reached");
+ }
+}
+
+MeshJobManager_i::~MeshJobManager_i() {
+ LOG("MeshJobManager_i::~MeshJobManager_i()");
+}
+
+//
+// ====================================================================
+// Helper functions to deals with the local and remote file systems
+// ====================================================================
+//
+#include // to get the file streams
+#ifdef WNT
+#include // to get _splitpath
+#include // to get _mkdir
+#else
+#include // to get basename
+#include // to get mkdir
+#include // to get mkdir options
+#endif
+
+#include // to get system and getenv
+
+static std::string OUTPUTFILE("output.med");
+static std::string DATAFILE("data.txt");
+static std::string SCRIPTFILE("padder.sh");
+static std::string SEPARATOR(" ");
+
+static std::string USER(getenv("USER"));
+static std::string LOCAL_INPUTDIR("/tmp/spadder.local.inputdir."+USER);
+static std::string LOCAL_RESULTDIR("/tmp/spadder.local.resultdir."+USER);
+static std::string REMOTE_WORKDIR("/tmp/spadder.remote.workdir."+USER);
+
+/*!
+ * This function creates the padder text input file containing the
+ * input data (list of filenames and groupnames) and returns the path
+ * of the created file. This function is the one that knows the format
+ * of the padder input file. If the input file format changes, then
+ * this function (and only this one) should be updated.
+ */
+const char * MeshJobManager_i::_writeDataFile(std::vector listConcreteMesh,
+ std::vector listSteelBarMesh) {
+#ifdef WIN32
+ _mkdir(LOCAL_INPUTDIR.c_str());
+#else
+ mkdir(LOCAL_INPUTDIR.c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
+#endif
+
+ // Make it static so that it's allocated once (constant name)
+ static std::string * dataFilename = new std::string(LOCAL_INPUTDIR+"/"+DATAFILE);
+ std::ofstream dataFile(dataFilename->c_str());
+
+ // We first specify the concrete mesh data (filename and groupname)
+ std::string line;
+#ifdef WIN32
+ char fname[ _MAX_FNAME ];
+ _splitpath( listConcreteMesh[0].file_name, NULL, NULL, fname, NULL );
+ char* bname = &fname[0];
+#else
+ char* bname = basename(listConcreteMesh[0].file_name);
+#endif
+ line = std::string(bname) + " " + std::string(listConcreteMesh[0].group_name);
+ dataFile << line.c_str() << std::endl;
+ // Note that we use here the basename because the files are supposed
+ // to be copied in the REMOTE_WORKDIR for execution.
+
+ // The, we can specify the steelbar mesh data, starting by the
+ // number of meshes
+ int nbSteelBarMesh=listSteelBarMesh.size();
+ line = std::string("nbSteelbarMesh") + SEPARATOR + ToString(nbSteelBarMesh);
+ dataFile << line.c_str() << std::endl;
+ for (int i=0; ic_str();
+}
+
+/*!
+ * This function creates a shell script that runs padder whith the
+ * specified data file, and returns the path of the created script
+ * file. The config id is used to retrieve the path to the binary file
+ * and other required files.
+ */
+const char* MeshJobManager_i::_writeScriptFile(const char * dataFileName, const char * configId) {
+#ifdef WIN32
+ _mkdir(LOCAL_INPUTDIR.c_str());
+#else
+ mkdir(LOCAL_INPUTDIR.c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
+#endif
+
+ // Make it static so that it's allocated once (constant name)
+ static std::string * scriptFilename = new std::string(LOCAL_INPUTDIR+"/"+SCRIPTFILE);
+
+ char * binpath = _configMap[configId].binpath;
+ char * envpath = _configMap[configId].envpath;
+
+#ifdef WIN32
+ char fname[ _MAX_FNAME ];
+ _splitpath( dataFileName, NULL, NULL, fname, NULL );
+ const char* bname = &fname[0];
+#else
+ const char* bname = basename(dataFileName);
+#endif
+
+
+ std::ofstream script(scriptFilename->c_str());
+ script << "#!/bin/sh" << std::endl;
+ script << "here=$(dirname $0)" << std::endl;
+ script << ". " << envpath << std::endl;
+ script << binpath << " $here/" << bname << std::endl;
+ // Note that we use the basename of the datafile because all data
+ // files are supposed to have been copied in the REMOTE_WORKDIR.
+ script.close();
+ return scriptFilename->c_str();
+}
+
+//
+// ====================================================================
+// Functions to initialize and supervise the mesh computation job
+// ====================================================================
+//
+bool MeshJobManager_i::configure(const char *configId,
+ const MESHJOB::ConfigParameter & configParameter)
+{
+ beginService("MeshJobManager_i::configure");
+
+ _configMap[configId] = configParameter;
+
+ LOG("Adding configuration for " << configId);
+ LOG("- binpath = " << _configMap[configId].binpath);
+ LOG("- envpath = " << _configMap[configId].envpath);
+
+ endService("MeshJobManager_i::configure");
+ return true;
+}
+
+long MeshJobManager_i::JOBID_UNDEFINED = -1;
+
+/*! Initialize a smesh computation job and return the job identifier */
+CORBA::Long MeshJobManager_i::initialize(const MESHJOB::MeshJobParameterList & meshJobParameterList,
+ const char * configId)
+{
+ beginService("MeshJobManager_i::initialize");
+
+ //
+ // We first analyse the CORBA sequence to store data in C++ vectors
+ //
+ std::vector listConcreteMesh;
+ std::vector listSteelBarMesh;
+ for(CORBA::ULong i=0; iremote_workdir = (REMOTE_WORKDIR + "." + ToString(jobDatetimeTag)).c_str();
+
+ //
+ // Then, we have to create the padder input data file. This input
+ // data is a text file containing the list of file names and group
+ // names.
+ //
+ const char * dataFilename = this->_writeDataFile(listConcreteMesh, listSteelBarMesh);
+ LOG("dataFilename = " << dataFilename);
+ const char * scriptFilename = this->_writeScriptFile(dataFilename, configId);
+ LOG("scriptFilename = " << scriptFilename);
+
+ //
+ // Then, the following instructions consists in preparing the job
+ // parameters to request the SALOME launcher for creating a new
+ // job.
+ //
+ Engines::JobParameters_var jobParameters = new Engines::JobParameters;
+ jobParameters->job_type = CORBA::string_dup("command");
+ // CAUTION: the job_file must be a single filename specifying a
+ // self-consistent script to be executed without any argument on the
+ // remote host.
+ jobParameters->job_file = CORBA::string_dup(scriptFilename);
+
+ //
+ // Specification of the working spaces:
+ //
+ // - local_directory: can be used to specify where to find the input
+ // files on the local resource. It's optionnal if you specify the
+ // absolute path name of input files.
+ //
+ // - result_directory: must be used to specify where to download the
+ // output files on the local resources
+ //
+ // - work_directory: must be used to specify the remote directory
+ // where to put all the stuff to run the job. Note that the job
+ // will be executed from within this directory, i.e. a change
+ // directory toward this working directory is done by the batch
+ // system before running the specified job script.
+ //
+ jobParameters->local_directory = CORBA::string_dup("");
+ jobParameters->result_directory = CORBA::string_dup(jobPaths->local_resultdir);
+ jobParameters->work_directory = CORBA::string_dup(jobPaths->remote_workdir);
+
+ // We specify the input files that are required to execute the
+ // job_file. If basenames are specified, then the files are supposed
+ // to be located in local_directory.
+ int nbFiles = listSteelBarMesh.size()+2;
+ // The number of input file is:
+ // (nb. of steelbar meshfile)
+ // + (1 concrete meshfile)
+ // + (1 padder input file)
+ // = nb steelbar meshfile + 2
+ jobParameters->in_files.length(nbFiles);
+ jobParameters->in_files[0] = CORBA::string_dup(listConcreteMesh[0].file_name);
+ for (int i=0; iin_files[1+i] = CORBA::string_dup(listSteelBarMesh[i].file_name);
+ }
+ jobParameters->in_files[1+listSteelBarMesh.size()] = CORBA::string_dup(dataFilename);
+ // Note that all these input files will be copied in the
+ // REMOTE_WORKDIR on the remote host
+
+ // Then, we have to specify the existance of an output
+ // filenames. The path is supposed to be a path on the remote
+ // resource, i.e. where the job is executed.
+ jobParameters->out_files.length(1);
+ std::string outputfile_name = std::string(jobPaths->remote_workdir)+"/"+OUTPUTFILE;
+ jobParameters->out_files[0] = CORBA::string_dup(outputfile_name.c_str());
+
+ // CAUTION: the maximum duration has to be set with a format like "hh:mm"
+ jobParameters->maximum_duration = CORBA::string_dup("01:00");
+ jobParameters->queue = CORBA::string_dup("");
+
+ // Setting resource and additionnal properties (if needed)
+ // The resource parameters can be initiated from scratch, for
+ // example by specifying the values in hard coding:
+ // >>>
+ //jobParameters->resource_required.name = CORBA::string_dup("localhost");
+ //jobParameters->resource_required.hostname = CORBA::string_dup("localhost");
+ //jobParameters->resource_required.mem_mb = 1024 * 10;
+ //jobParameters->resource_required.nb_proc = 1;
+ // <<<
+ // But it's better to initiate these parameters from a resource
+ // definition known by the resource manager. This ensures that the
+ // resource will be available:
+ //const char * resourceName = "localhost";
+ //const char * resourceName = "boulant@claui2p1";
+ //const char * resourceName = "nepal@nepal";
+ const char * resourceName = _configMap[configId].resname;
+ Engines::ResourceDefinition * resourceDefinition = _resourcesManager->GetResourceDefinition(resourceName);
+ // CAUTION: This resource should have been defined in the
+ // CatalogResource.xml associated to the SALOME application.
+ //
+ // Then, the values can be used to initiate the resource parameters
+ // of the job:
+ jobParameters->resource_required.name = CORBA::string_dup(resourceDefinition->name.in());
+ // CAUTION: the additionnal two following parameters MUST be
+ // specified explicitly, because they are not provided by the
+ // resource definition:
+ jobParameters->resource_required.mem_mb = resourceDefinition->mem_mb;
+ jobParameters->resource_required.nb_proc = resourceDefinition->nb_proc_per_node;
+ // CAUTION: the parameter mem_mb specifies the maximum memory value
+ // that could be allocated for executing the job. This takes into
+ // account not only the data that could be loaded by the batch
+ // process but also the linked dynamic library.
+ //
+ // A possible problem, for exemple in the case where you use the ssh
+ // emulation of a batch system, is to get an error message as below
+ // when libBatch try to run the ssh command:
+ //
+ // ## /usr/bin/ssh: error while loading shared libraries: libcrypto.so.0.9.8: failed
+ // ## to map segment from shared object: Cannot allocate memory
+ //
+ // In this exemple, the mem_mb was set to 1MB, value that is not
+ // sufficient to load the dynamic libraries linked to the ssh
+ // executable (libcrypto.so in the error message).
+ //
+ // So, even in the case of a simple test shell script, you should
+ // set this value at least to a standard threshold as 500MB
+
+ int jobId = JOBID_UNDEFINED;
+ try {
+ jobId = _salomeLauncher->createJob(jobParameters);
+ // We register the datetime tag of this job
+ _jobDateTimeMap[jobId]=jobDatetimeTag;
+ _jobPathsMap[jobId] = jobPaths;
+ }
+ catch (const SALOME::SALOME_Exception & ex) {
+ LOG("SALOME Exception in createJob !" <launchJob(jobId);
+ }
+ catch (const SALOME::SALOME_Exception & ex) {
+ LOG("SALOME Exception in createJob !" <getJobState(jobId);
+ }
+ catch (const SALOME::SALOME_Exception & ex)
+ {
+ LOG("SALOME Exception in getJobState !");
+ state = ex.details.text;
+ }
+ catch (const CORBA::SystemException& ex)
+ {
+ LOG("Receive SALOME System Exception: " << ex);
+ state="SALOME System Exception - see logs";
+ }
+ LOG("jobId="<getPaths(jobId);
+ std::string local_resultdir(jobPaths->local_resultdir);
+ result->results_dirname = local_resultdir.c_str();
+ try
+ {
+ _salomeLauncher->getJobResults(jobId, local_resultdir.c_str());
+
+ // __BUG__: to prevent from a bug of the MED driver (SALOME
+ // 5.1.5), we change the basename of the output file to force the
+ // complete reloading of data by the med driver.
+ long jobDatetimeTag = _jobDateTimeMap[jobId];
+ std::string outputFileName = "output"+ToString(jobDatetimeTag)+".med";
+ rename((local_resultdir+"/"+OUTPUTFILE).c_str(), (local_resultdir+"/"+outputFileName).c_str());
+
+ result->outputmesh_filename = outputFileName.c_str();
+ result->status = "OK";
+ }
+ catch (const SALOME::SALOME_Exception & ex)
+ {
+ LOG("SALOME Exception in getResults !");
+ result->status = "SALOME Exception in getResults !";
+ }
+ catch (const CORBA::SystemException& ex)
+ {
+ LOG("Receive CORBA System Exception: " << ex);
+ result->status = "Receive CORBA System Exception: see log";
+ }
+ endService("MeshJobManager_i::getResults");
+ return result;
+}
+
+
+/*! Clean all data associated to this job and remove the job from the launch manager */
+bool MeshJobManager_i::clean(CORBA::Long jobId) {
+ beginService("MeshJobManager_i::clean");
+
+ // __GBO__ WORK IN PROGRESS: we just clean the temporary local
+ // directories. The remote working directories are tag with the
+ // execution datetime and the we prevent the task from conflict
+ // with files of another task.
+ MESHJOB::MeshJobPaths * jobPaths = this->getPaths(jobId);
+ if ( jobPaths == NULL ) return false;
+
+ // WARN: !!!!!
+ // For safety reason (and prevent from bug that could erase the
+ // filesystem), we cancel the operation in the case where the
+ // directories to delete are not in the /tmp folder.
+ std::string shell_command("rm -rf ");
+ std::string inputdir(jobPaths->local_inputdir);
+ std::string resultdir(jobPaths->local_resultdir);
+ if ( !myStartsWith(inputdir,"/tmp/") ) {
+ LOG("WRN: The directory "< * MeshJobManager_i::_getResourceNames() {
+
+ //
+ // These part is just to control the available resources
+ //
+ Engines::ResourceParameters params;
+ KERNEL::getLifeCycleCORBA()->preSet(params);
+
+ Engines::ResourceList * resourceList = _resourcesManager->GetFittingResources(params);
+ Engines::ResourceDefinition * resourceDefinition = NULL;
+ LOG("### resource list:");
+ std::vector* resourceNames = new std::vector();
+ if (resourceList) {
+ for (int i = 0; i < resourceList->length(); i++) {
+ const char* aResourceName = (*resourceList)[i];
+ resourceNames->push_back(std::string(aResourceName));
+ LOG("resource["<GetResourceDefinition(aResourceName);
+ LOG("protocol["<protocol);
+ }
+ }
+
+ // Note: a ResourceDefinition is used to create a batch configuration
+ // in the Launcher. This operation is done at Launcher startup from
+ // the configuration file CatalogResources.xml provided by the
+ // SALOME application.
+ // In the code instructions, you just have to choose a resource
+ // configuration by its name and then define the ResourceParameters
+ // that specify additionnal properties for a specific job submission
+ // (use the attribute resource_required of the JobParameters).
+
+ return resourceNames;
+}
+
+
+//
+// ==========================================================================
+// Factory services
+// ==========================================================================
+//
+extern "C"
+{
+ PortableServer::ObjectId * MeshJobManagerEngine_factory( CORBA::ORB_ptr orb,
+ PortableServer::POA_ptr poa,
+ PortableServer::ObjectId * contId,
+ const char *instanceName,
+ const char *interfaceName)
+ {
+ LOG("PortableServer::ObjectId * MeshJobManagerEngine_factory()");
+ MeshJobManager_i * myEngine = new MeshJobManager_i(orb, poa, contId, instanceName, interfaceName);
+ return myEngine->getId() ;
+ }
+}
diff --git a/src/Tools/padder/meshjob/impl/MeshJobManager_i.hxx b/src/Tools/padder/meshjob/impl/MeshJobManager_i.hxx
new file mode 100644
index 000000000..a45206639
--- /dev/null
+++ b/src/Tools/padder/meshjob/impl/MeshJobManager_i.hxx
@@ -0,0 +1,81 @@
+// Copyright (C) 2011 EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+// Authors : Guillaume Boulant (EDF) - 01/03/2011
+
+#ifndef _MESHJOBMANAGER_HXX_
+#define _MESHJOBMANAGER_HXX_
+
+// include the stubs generating from MESHJOB.idl
+#include
+#include CORBA_SERVER_HEADER(MESHJOB)
+#include CORBA_SERVER_HEADER(SALOME_Component)
+#include "SALOME_Component_i.hxx"
+
+#include "SALOME_Launcher.hxx"
+#include
+#include
+#include