diff --git a/doc/salome/gui/SMESH/images/2d_from_3d_menu.png b/doc/salome/gui/SMESH/images/2d_from_3d_menu.png
new file mode 100644
index 000000000..ec5117214
Binary files /dev/null and b/doc/salome/gui/SMESH/images/2d_from_3d_menu.png differ
diff --git a/doc/salome/gui/SMESH/input/make_2dmesh_from_3d.doc b/doc/salome/gui/SMESH/input/make_2dmesh_from_3d.doc
new file mode 100644
index 000000000..23ea94517
--- /dev/null
+++ b/doc/salome/gui/SMESH/input/make_2dmesh_from_3d.doc
@@ -0,0 +1,22 @@
+/*!
+
+\page make_2dmesh_from_3d_page Generate the skin elements (2D) of a mesh having 3D elements
+
+\n This functionality allows you to generate 2D mesh elements as skin
+on existing 3D mesh elements
+
+To generate 2D mesh:
+
+- From the Modification menu choose the "Create 2D mesh from 3D"
+Mesh item, or invoke from popup menu.
+
+\image html 2d_from_3d_menu.png
+
+The algorithm detects boundary volume faces without connections to
+other volumes and create 2D mesh elements on face nodes. If mesh
+already contains 2D elements on detected nodes - no new element
+created. The result dilog shows mesh information statistoc about new
+created 2D mesh elements.
+
+
+*/
diff --git a/doc/salome/gui/SMESH/input/modifying_meshes.doc b/doc/salome/gui/SMESH/input/modifying_meshes.doc
index f7a882524..cf63ff5f4 100644
--- a/doc/salome/gui/SMESH/input/modifying_meshes.doc
+++ b/doc/salome/gui/SMESH/input/modifying_meshes.doc
@@ -45,9 +45,11 @@ of the selected node or edge.
Apply \subpage pattern_mapping_page "pattern mapping".
\subpage convert_to_from_quadratic_mesh_page "Convert regular mesh to quadratic",
or vice versa.
+\subpage make_2dmesh_from_3d_page "Create 2D mesh from 3D".
+
\note It is possible to use the variables defined in the SALOME \b NoteBook
to specify the numerical parameters used for modification of any object.
-*/
\ No newline at end of file
+*/
diff --git a/src/SMESH/SMESH_MeshEditor.cxx b/src/SMESH/SMESH_MeshEditor.cxx
index f2961c5a6..e84487512 100644
--- a/src/SMESH/SMESH_MeshEditor.cxx
+++ b/src/SMESH/SMESH_MeshEditor.cxx
@@ -8830,7 +8830,8 @@ bool SMESH_MeshEditor::Make2DMeshFrom3D()
{
const SMDS_MeshVolume* volume = vIt->next();
SMDS_VolumeTool vTool( volume );
- bool isPoly = volume->IsPoly();
+ const bool isPoly = volume->IsPoly();
+ const bool isQuad = volume->IsQuadratic();
for ( int iface = 0, n = vTool.NbFaces(); iface < n; iface++ )
{
if (!vTool.IsFreeFace(iface))
@@ -8838,12 +8839,24 @@ bool SMESH_MeshEditor::Make2DMeshFrom3D()
vector nodes;
int nbFaceNodes = vTool.NbFaceNodes(iface);
const SMDS_MeshNode** faceNodes = vTool.GetFaceNodes(iface);
- if (vTool.IsFaceExternal(iface))
- for (int inode = 0; inode < nbFaceNodes; inode++)
+ if (vTool.IsFaceExternal(iface))
+ {
+ int inode = 0;
+ for ( ; inode < nbFaceNodes; inode += isQuad ? 2 : 1)
nodes.push_back(faceNodes[inode]);
+ if (isQuad)
+ for ( inode = 1; inode < nbFaceNodes; inode += 2)
+ nodes.push_back(faceNodes[inode]);
+ }
else
- for (int inode = nbFaceNodes - 1; inode >= 0; inode--)
+ {
+ int inode = nbFaceNodes-1;
+ for ( ; inode >=0; inode -= isQuad ? 2 : 1)
nodes.push_back(faceNodes[inode]);
+ if (isQuad)
+ for ( inode = nbFaceNodes-2; inode >=0; inode -= 2)
+ nodes.push_back(faceNodes[inode]);
+ }
// add new face based on volume nodes
if (aMesh->FindFace( nodes ) )
diff --git a/src/SMESHGUI/SMESHGUI.cxx b/src/SMESHGUI/SMESHGUI.cxx
index 2190c6a3c..4b41c1d20 100644
--- a/src/SMESHGUI/SMESHGUI.cxx
+++ b/src/SMESHGUI/SMESHGUI.cxx
@@ -3068,6 +3068,19 @@ void SMESHGUI::initialize( CAM_Application* app )
hyp_alg = hypo + " " + algo;
// popup for object browser
+ QString
+ isInvisible("not( isVisible )"),
+ isEmpty("numberOfNodes = 0"),
+ isNotEmpty("numberOfNodes <> 0"),
+
+ // has nodes, edges, etc in VISIBLE! actor
+ hasNodes("(numberOfNodes > 0 )"),//&& isVisible)"),
+ hasElems("(count( elemTypes ) > 0)"),
+ hasDifferentElems("(count( elemTypes ) > 1)"),
+ hasElems0d("({'Elem0d'} in elemTypes)"),
+ hasEdges("({'Edge'} in elemTypes)"),
+ hasFaces("({'Face'} in elemTypes)"),
+ hasVolumes("({'Volume'} in elemTypes)");
createPopupItem( 150, OB, mesh, "&& selcount=1 && isImported" ); // FILE INFORMATION
createPopupItem( 703, OB, mesh, "&& isComputable"); // CREATE_SUBMESH
@@ -3096,6 +3109,9 @@ void SMESHGUI::initialize( CAM_Application* app )
popupMgr()->insert( separator(), -1, 0 );
createPopupItem( 4043, OB, mesh ); // CLEAR_MESH
popupMgr()->insert( separator(), -1, 0 );
+ createPopupItem( 417, OB, mesh/*, "&& " + hasElems*/); // convert to quadratic
+ createPopupItem( 418, OB, mesh/*, "&& " + hasVolumes*/); // create 2D mesh on 3D
+ popupMgr()->insert( separator(), -1, 0 );
QString only_one_non_empty = QString( " && %1=1 && numberOfNodes>0" ).arg( dc );
@@ -3123,20 +3139,6 @@ void SMESHGUI::initialize( CAM_Application* app )
popupMgr()->insert( separator(), -1, 0 );
int anId;
- QString
- isInvisible("not( isVisible )"),
- isEmpty("numberOfNodes = 0"),
- isNotEmpty("numberOfNodes <> 0"),
-
- // has nodes, edges, etc in VISIBLE! actor
- hasNodes("(numberOfNodes > 0 )"),//&& isVisible)"),
- hasElems("(count( elemTypes ) > 0)"),
- hasDifferentElems("(count( elemTypes ) > 1)"),
- hasElems0d("({'Elem0d'} in elemTypes)"),
- hasEdges("({'Edge'} in elemTypes)"),
- hasFaces("({'Face'} in elemTypes)"),
- hasVolumes("({'Volume'} in elemTypes)");
-
QString aClient = QString( "%1client in {%2}" ).arg( lc ).arg( "'VTKViewer'" );
QString aType = QString( "%1type in {%2}" ).arg( lc );
aType = aType.arg( mesh_group );