diff --git a/doc/salome/gui/SMESH/images/2d_from_3d_menu.png b/doc/salome/gui/SMESH/images/2d_from_3d_menu.png
index ec5117214..acb7b349e 100644
Binary files a/doc/salome/gui/SMESH/images/2d_from_3d_menu.png 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
index ada914ec1..9d334340f 100644
--- a/doc/salome/gui/SMESH/input/make_2dmesh_from_3d.doc
+++ b/doc/salome/gui/SMESH/input/make_2dmesh_from_3d.doc
@@ -1,22 +1,60 @@
/*!
-\page make_2dmesh_from_3d_page Create 2D mesh from 3D
+\page make_2dmesh_from_3d_page Generate boundary elements
-\n This functionality allows to generate 2D mesh elements as a skin
-on the existing 3D mesh elements.
+\n This functionality allows to generate mesh elements on borders of
+elements of higher dimension.
-To generate 2D mesh:
+
+To generate border elements:
-- From the Modification menu choose "Create 2D mesh from 3D"
+
- From the Modification menu choose "Create boundary elements"
item, or choose from the popup menu.
\image html 2d_from_3d_menu.png
-
-The algorithm detects boundary volume faces without connections to
-other volumes and creates 2D mesh elements on face nodes. If the mesh
-already contains 2D elements on the detected nodes, new elements are not
-created. The the resulting dialog shows mesh information statistics
-about the newly created 2D mesh elements.
+The following dialog box will appear:
+\image html 2d_from_3d_dlg.png
+
+- Check in the dialog box one of three radio buttons corresponding to
+the type of operation you would like to perform.
+- Fill the other fields available in the dialog box.
+- Click the \b Apply or Apply and Close button to perform the operation.
+\n "Create boundary elements" dialog allows creation of boundary elements
+of three types.
+
+- 2D from 3D creates mesh faces on free facets of volume elements
+- 1D from 2D creates mesh edges on free edges of mesh faces
+- 1D from 3D creates mesh edges on all borders of free facets of volume elements
+
+Here free facet means a facet shared by only one volume, free edge
+means an edge shared by only one mesh face.
+
+In this dialog:
+
+- specify Mesh, submesh or group to analyze the boundary.
+- specify Target mesh where boundary elements will
+ be created.
+
+ - This mesh adds elements in the selected mesh or the mesh
+ the selected submesh or group belongs to.
+ - New mesh add elements to a new mesh. The new mesh appears
+ in the Object Browser with the name specified in the adjacent box
+ that you can change.
+
+- activate Copy source mesh checkbox to copy 2D or 3D
+ elements (depending on operation type) belonging to the object
+ specified in Mesh, submesh or group field to the new
+ mesh.
+- deactivate Copy missing elements only checkbox to copy
+ boundary elements already present in the mesh being checked to the
+ new mesh.
+- activate Create group checkbox to create a group where
+ missing boundary elements are added to. The new group appears
+ in the Object Browser with the name specified in the adjacent box
+ that you can change.
+
+
See Also a sample TUI Script of a \ref tui_make_2dmesh_from_3d "Create boundary elements" operation.
+
*/
diff --git a/doc/salome/gui/SMESH/input/modifying_meshes.doc b/doc/salome/gui/SMESH/input/modifying_meshes.doc
index 0eb82ceb6..45e746da4 100644
--- a/doc/salome/gui/SMESH/input/modifying_meshes.doc
+++ b/doc/salome/gui/SMESH/input/modifying_meshes.doc
@@ -47,7 +47,7 @@ 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".
+\subpage make_2dmesh_from_3d_page "Generate boundary elements".
diff --git a/doc/salome/gui/SMESH/input/tui_transforming_meshes.doc b/doc/salome/gui/SMESH/input/tui_transforming_meshes.doc
index e50fcda36..87d75b672 100644
--- a/doc/salome/gui/SMESH/input/tui_transforming_meshes.doc
+++ b/doc/salome/gui/SMESH/input/tui_transforming_meshes.doc
@@ -421,4 +421,167 @@ if salome.sg.hasDesktop():
salome.sg.updateObjBrowser(0)
\endcode
+
+\anchor tui_make_2dmesh_from_3d
+Create boundary elements
+
+\code
+# The goal of this feature is to enable the following use cases:
+# 1) The mesh MESH1 with 3D cells does not have or have only a part of its skin (2D cells):
+# 1.1) Add the 2D skin (missing 2D cells) to MESH1 (what it's done now by the algorithm).
+# 1.2) Create new 3D Mesh MESH2 that consists of MESH1 and added 2D skin cells.
+# 1.3) Create new 2D Mesh MESH3 that consists of only the 2D skin cells.
+# 2) The mesh MESH1 with 3D cells has all its skin (2D cells):
+# Create new 2D Mesh MESH3 that consists of only the 2D skin cells.
+#
+# In all cases an option to create a group containing these 2D skin cells should be available.
+
+from smesh import *
+
+box = geompy.MakeBoxDXDYDZ(1,1,1)
+geompy.addToStudy(box,"box")
+boxFace = geompy.SubShapeAll(box, geompy.ShapeType["FACE"])[0]
+geompy.addToStudyInFather(box,boxFace,"boxFace")
+
+MESH1 = Mesh(box,"MESH1")
+MESH1.AutomaticHexahedralization()
+
+init_nb_edges = MESH1.NbEdges()
+init_nb_faces = MESH1.NbFaces()
+init_nb_volumes = MESH1.NbVolumes()
+
+# =========================================================================================
+# 1) The mesh MESH1 with 3D cells does not have or have only a part of its skin (2D cells)
+# =========================================================================================
+# remove some faces
+all_faces = MESH1.GetElementsByType(SMESH.FACE)
+rm_faces = all_faces[:init_nb_faces/5] + all_faces[4*init_nb_faces/5:]
+MESH1.RemoveElements(rm_faces)
+assert(MESH1.NbFaces() == init_nb_faces-len(rm_faces))
+
+# 1.1) Add the 2D skin (missing 2D cells) to MESH1
+# -------------------------------------------------
+# add missing faces
+# 1.1.1) to the whole mesh
+m,g = MESH1.MakeBoundaryMesh(MESH1)
+assert(init_nb_faces == MESH1.NbFaces())
+assert(init_nb_edges == MESH1.NbEdges())
+assert(m)
+assert(not g)
+
+# 1.1.2) to some elements
+MESH1.RemoveElements(rm_faces)
+MESH1.MakeBoundaryMesh([])
+assert(init_nb_faces != MESH1.NbFaces())
+volumes = MESH1.GetElementsByType(SMESH.VOLUME)
+for v in volumes:
+ MESH1.MakeBoundaryMesh([v])
+assert(init_nb_faces == MESH1.NbFaces())
+assert(init_nb_edges == MESH1.NbEdges())
+
+# 1.1.3) to group of elements
+volGroup1 = MESH1.CreateEmptyGroup(SMESH.VOLUME, "volGroup1")
+volGroup1.Add( volumes[: init_nb_volumes/2])
+volGroup2 = MESH1.CreateEmptyGroup(SMESH.VOLUME, "volGroup2")
+volGroup1.Add( volumes[init_nb_volumes/2:])
+MESH1.RemoveElements(rm_faces)
+MESH1.MakeBoundaryMesh(volGroup1)
+MESH1.MakeBoundaryMesh(volGroup2)
+assert(init_nb_faces == MESH1.NbFaces())
+assert(init_nb_edges == MESH1.NbEdges())
+
+# 1.1.4) to submesh.
+# The submesh has no volumes, so check if it pass w/o a crash and does not create
+# missing faces
+faceSubmesh = MESH1.GetSubMesh( boxFace, "boxFace" )
+MESH1.RemoveElements(rm_faces)
+MESH1.MakeBoundaryMesh(faceSubmesh)
+assert(init_nb_faces != MESH1.NbFaces())
+
+# check group creation
+MESH1.RemoveElements(rm_faces)
+groupName = "added to mesh"
+m,group = MESH1.MakeBoundaryMesh(MESH1,groupName=groupName)
+assert(group)
+assert(group.GetName() == groupName)
+assert(group.Size() == len(rm_faces))
+
+
+# 1.2) Create new 3D Mesh MESH2 that consists of MESH1 and added 2D skin cells.
+# ------------------------------------------------------------------------------
+MESH1.RemoveElements(rm_faces)
+meshName = "MESH2"
+MESH2,group = MESH1.MakeBoundaryMesh(MESH1,meshName=meshName,toCopyElements=True)
+assert(MESH2)
+assert(MESH2.GetName() == meshName)
+assert(MESH2.NbVolumes() == MESH1.NbVolumes())
+assert(MESH2.NbFaces() == len(rm_faces))
+
+# check group creation
+MESH1.RemoveElements(rm_faces)
+MESH2,group = MESH1.MakeBoundaryMesh(MESH1,meshName="MESH2_0",
+ groupName=groupName,toCopyElements=True)
+assert(group)
+assert(group.GetName() == groupName)
+assert(group.Size() == len(rm_faces))
+assert(group.GetMesh()._is_equivalent(MESH2.GetMesh()))
+
+# 1.3) Create new 2D Mesh MESH3 that consists of only the 2D skin cells.
+# -----------------------------------------------------------------------
+MESH1.RemoveElements(rm_faces)
+meshName = "MESH3"
+MESH3,group = MESH1.MakeBoundaryMesh(MESH1,meshName=meshName,toCopyExistingBondary=True)
+assert(MESH3)
+assert(not group)
+assert(MESH3.GetName() == meshName)
+assert(MESH3.NbVolumes() == 0)
+assert(MESH3.NbFaces() == init_nb_faces)
+
+# check group creation
+MESH1.RemoveElements(rm_faces)
+MESH3,group = MESH1.MakeBoundaryMesh(MESH1,meshName=meshName,
+ groupName=groupName, toCopyExistingBondary=True)
+assert(group)
+assert(group.GetName() == groupName)
+assert(group.Size() == len(rm_faces))
+assert(group.GetMesh()._is_equivalent(MESH3.GetMesh()))
+assert(MESH3.NbFaces() == init_nb_faces)
+
+# ==================================================================
+# 2) The mesh MESH1 with 3D cells has all its skin (2D cells)
+# Create new 2D Mesh MESH3 that consists of only the 2D skin cells.
+# ==================================================================
+MESH1.MakeBoundaryMesh(MESH1)
+MESH3,group = MESH1.MakeBoundaryMesh(MESH1,meshName=meshName,toCopyExistingBondary=True)
+assert(MESH3)
+assert(not group)
+assert(MESH3.NbVolumes() == 0)
+assert(MESH3.NbFaces() == init_nb_faces)
+
+# check group creation
+MESH3,group = MESH1.MakeBoundaryMesh(MESH1,meshName=meshName,
+ groupName=groupName, toCopyExistingBondary=True)
+assert(group)
+assert(group.GetName() == groupName)
+assert(group.Size() == 0)
+assert(group.GetMesh()._is_equivalent(MESH3.GetMesh()))
+assert(MESH3.NbFaces() == init_nb_faces)
+
+# ================
+# Make 1D from 2D
+# ================
+
+MESH1.Clear()
+MESH1.Compute()
+MESH1.RemoveElements( MESH1.GetElementsByType(SMESH.EDGE))
+
+rm_faces = faceSubmesh.GetIDs()[:2] # to remove few adjacent faces
+nb_missing_edges = 2 + 2*len(rm_faces)
+
+MESH1.RemoveElements(rm_faces)
+mesh,group = MESH1.MakeBoundaryMesh(MESH1, BND_1DFROM2D)
+assert( MESH1.NbEdges() == nb_missing_edges )
+
+
+\endcode
*/