diff --git a/api/gmsh.h b/api/gmsh.h
index b345d206295b035d54217aa741112f9571eb38cc..9898fea0ba1ee5356261b0a0050739e6c86083e1 100644
--- a/api/gmsh.h
+++ b/api/gmsh.h
@@ -206,10 +206,12 @@ namespace gmsh { // Top-level functions
     // gmsh::model::getEntities
     //
     // Get all the entities in the current model. If `dim' is >= 0, return only the
-    // entities of the specified dimension (e.g. points if `dim' == 0). The
-    // entities are returned as a vector of (dim, tag) pairs.
+    // entities of the specified dimension (e.g. points if `dim' == 0) if `upto'
+    // is false, otherwise return only entities whose dimension is
+    // <= `dim'. The entities are returned as a vector of (dim, tag) pairs.
     GMSH_API void getEntities(gmsh::vectorpair & dimTags,
-                              const int dim = -1);
+                              const int dim = -1,
+                              const bool upto = false);
 
     // gmsh::model::setEntityName
     //
@@ -228,10 +230,12 @@ namespace gmsh { // Top-level functions
     // gmsh::model::getPhysicalGroups
     //
     // Get all the physical groups in the current model. If `dim' is >= 0, return
-    // only the entities of the specified dimension (e.g. physical points if `dim'
-    // == 0). The entities are returned as a vector of (dim, tag) pairs.
+    // only the physical groups of the specified dimension (e.g. physical points if `dim'
+    // == 0) if `upto' is false, otherwise return only physical groups whose dimension is
+    // <= `dim'. The physical groups are returned as a vector of (dim, tag) pairs.
     GMSH_API void getPhysicalGroups(gmsh::vectorpair & dimTags,
-                                    const int dim = -1);
+                                    const int dim = -1,
+                                    const bool upto = false);
 
     // gmsh::model::getEntitiesForPhysicalGroup
     //
diff --git a/src/common/gmsh.cpp b/src/common/gmsh.cpp
index 70eebd23a81ea2186ce451700786db3d2233fb7d..b70f47b2eebd55e879eb8c98e0071813cff5ce07 100644
--- a/src/common/gmsh.cpp
+++ b/src/common/gmsh.cpp
@@ -356,15 +356,22 @@ GMSH_API void gmsh::model::setFileName(const std::string &fileName)
   GModel::current()->setFileName(fileName);
 }
 
-GMSH_API void gmsh::model::getEntities(vectorpair &dimTags, const int dim)
+GMSH_API void gmsh::model::getEntities(vectorpair &dimTags, const int dim, const bool upto)
 {
   if(!_checkInit()) return;
   dimTags.clear();
-  std::vector<GEntity *> entities;
-  GModel::current()->getEntities(entities, dim);
-  for(std::size_t i = 0; i < entities.size(); i++)
-    dimTags.push_back(
-      std::make_pair(entities[i]->dim(), entities[i]->tag()));
+  for(int idim = 0; idim < 4; ++idim) {
+    if(dim < 0 || idim == dim || (upto && idim <= dim)) {
+      std::vector<GEntity *> entities;
+      GModel::current()->getEntities(entities, idim);
+      dimTags.reserve(dimTags.size() + entities.size());
+      std::transform(
+        entities.cbegin(), entities.cend(),
+        std::back_inserter(dimTags),
+        [&](const GEntity* enty){ return std::make_pair(enty->dim(), enty->tag()); }
+      );
+    }
+  }
 }
 
 GMSH_API void gmsh::model::setEntityName(const int dim, const int tag,
@@ -381,14 +388,14 @@ GMSH_API void gmsh::model::getEntityName(const int dim, const int tag,
   name = GModel::current()->getElementaryName(dim, tag);
 }
 
-GMSH_API void gmsh::model::getPhysicalGroups(vectorpair &dimTags, const int dim)
+GMSH_API void gmsh::model::getPhysicalGroups(vectorpair &dimTags, const int dim, const bool upto)
 {
   if(!_checkInit()) return;
   dimTags.clear();
   std::map<int, std::vector<GEntity *> > groups[4];
   GModel::current()->getPhysicalGroups(groups);
   for(int d = 0; d < 4; d++) {
-    if(dim < 0 || d == dim) {
+    if(dim < 0 || d == dim || (upto && d <= dim)) {
       for(auto it = groups[d].begin(); it != groups[d].end(); it++)
         dimTags.push_back(std::make_pair(d, it->first));
     }