diff --git a/Common/Context.h b/Common/Context.h
index 4e7029135691e9bf5b9787bb6bb374b5b2ac81f8..81a26ba0b78d8211da215f21f936df3772f65e50 100644
--- a/Common/Context.h
+++ b/Common/Context.h
@@ -164,7 +164,7 @@ class Context_T {
     int light, light_two_side, light_lines;
     int format, nb_smoothing, algo2d, algo3d, algo_recombine;
     int order, second_order_linear, second_order_incomplete;
-    int second_order_experimental;
+    int second_order_experimental, mesh_only_visible;
     int smooth_internal_edges, c1_continuity;
     int min_circ_points, min_curv_points;
     double normals, tangents, explode;
diff --git a/Common/DefaultOptions.h b/Common/DefaultOptions.h
index 9338047f6dd5e7fd0807936952596fed73d428c1..9447ca4c76808d0297bf076e1c11cc5c1c7ba70d 100644
--- a/Common/DefaultOptions.h
+++ b/Common/DefaultOptions.h
@@ -982,6 +982,8 @@ StringXNumber MeshOptions_Number[] = {
   { F|O, "LineWidth" , opt_mesh_line_width , 1.0 , 
     "Display width of mesh lines (in pixels)" },
 
+  { F|O, "MeshOnlyVisible" , opt_mesh_mesh_only_visible, 0. ,
+    "Mesh only visible entities" },
   { F|O, "MetisAlgorithm" , opt_mesh_partition_metis_algorithm, 1. ,
     "METIS partitioning algorithm (1=Recursive, 2=K-way)" },
   { F|O, "MetisEdgeMatching" , opt_mesh_partition_metis_edge_matching, 3. ,
diff --git a/Common/Options.cpp b/Common/Options.cpp
index c6a422924928f954cbfc82f11db8b2297d3810d4..bf984c53fcec5675be3a7466e9943b7f89c4a6b2 100644
--- a/Common/Options.cpp
+++ b/Common/Options.cpp
@@ -5104,6 +5104,13 @@ double opt_mesh_algo3d(OPT_ARGS_NUM)
   return CTX.mesh.algo3d;
 }
 
+double opt_mesh_mesh_only_visible(OPT_ARGS_NUM)
+{
+  if(action & GMSH_SET)
+    CTX.mesh.mesh_only_visible = (int)val;
+  return CTX.mesh.mesh_only_visible;
+}
+
 double opt_mesh_min_circ_points(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
diff --git a/Common/Options.h b/Common/Options.h
index 377655857acf5c8b3240b641c7f45c6a503026b2..8116a499641c51d0b56df04cc0a9c53a6f1810c7 100644
--- a/Common/Options.h
+++ b/Common/Options.h
@@ -475,6 +475,7 @@ double opt_mesh_nb_smoothing(OPT_ARGS_NUM);
 double opt_mesh_algo2d(OPT_ARGS_NUM);
 double opt_mesh_algo3d(OPT_ARGS_NUM);
 double opt_mesh_recombine_algo(OPT_ARGS_NUM);
+double opt_mesh_mesh_only_visible(OPT_ARGS_NUM);
 double opt_mesh_min_circ_points(OPT_ARGS_NUM);
 double opt_mesh_allow_swap_edge_angle(OPT_ARGS_NUM);
 double opt_mesh_min_curv_points(OPT_ARGS_NUM);
diff --git a/Mesh/meshGEdge.cpp b/Mesh/meshGEdge.cpp
index d05c5326262d8180161bfa6fa5f68c1bb4b44a0c..74dc00479e483b1e1b3459bad381acfbac2f2f66 100644
--- a/Mesh/meshGEdge.cpp
+++ b/Mesh/meshGEdge.cpp
@@ -271,6 +271,7 @@ void meshGEdge::operator() (GEdge *ge)
   if(ge->geomType() == GEntity::DiscreteCurve) return;
   if(ge->geomType() == GEntity::BoundaryLayerCurve) return;
   if(ge->meshAttributes.Method == MESH_NONE) return;
+  if(CTX.mesh.mesh_only_visible && !ge->getVisibility()) return;
 
   deMeshGEdge dem;
   dem(ge);
diff --git a/Mesh/meshGFace.cpp b/Mesh/meshGFace.cpp
index 68a4fe4253c30b5c94a83d095d9e4a95d20b9e6c..abc6b5b3ea27d36e71a56c6dfabfee0bd78c43f1 100644
--- a/Mesh/meshGFace.cpp
+++ b/Mesh/meshGFace.cpp
@@ -1297,6 +1297,7 @@ void meshGFace::operator() (GFace *gf)
   if(gf->geomType() == GEntity::BoundaryLayerSurface) return;
   if(gf->geomType() == GEntity::ProjectionFace) return;
   if(gf->meshAttributes.Method == MESH_NONE) return;
+  if(CTX.mesh.mesh_only_visible && !gf->getVisibility()) return;
 
   // destroy the mesh if it exists
   deMeshGFace dem;
diff --git a/Mesh/meshGRegion.cpp b/Mesh/meshGRegion.cpp
index c4c2f46f8ee02a3557f7af533d8281dc47c605fd..e88a2140bc17cefffb5d5be8b50ba96772e2f9fc 100644
--- a/Mesh/meshGRegion.cpp
+++ b/Mesh/meshGRegion.cpp
@@ -544,6 +544,7 @@ void meshGRegion::operator() (GRegion *gr)
 
   if(gr->geomType() == GEntity::DiscreteVolume) return;
   if(gr->meshAttributes.Method == MESH_NONE) return;
+  if(CTX.mesh.mesh_only_visible && !gr->getVisibility()) return;
 
   ExtrudeParams *ep = gr->meshAttributes.extrude;