diff --git a/CHANGELOG.txt b/CHANGELOG.txt
index bc965d74c91f46268aface68d889c048d131c769..ff0a84bfd37daca4a39f53c7884d4463e11be6db 100644
--- a/CHANGELOG.txt
+++ b/CHANGELOG.txt
@@ -1,5 +1,6 @@
 4.10.2 (Work-in-progress): fixed regression introduced in 4.9 for recombined
-meshes with boundary layers; small bug fixes.
+meshes with boundary layers; new HealShapes command in .geo files; simplified
+calculation of OCC STL bounding boxes; small bug fixes.
 
 4.10.1 (May 1, 2022): small bug fixes.
 
diff --git a/src/geo/GModelIO_OCC.cpp b/src/geo/GModelIO_OCC.cpp
index 7fc3bb06974063d89dfd271ec523475c6c5fe2b7..d99b082d20086a7b29491703e587959da4718ffb 100644
--- a/src/geo/GModelIO_OCC.cpp
+++ b/src/geo/GModelIO_OCC.cpp
@@ -4489,6 +4489,26 @@ bool OCC_Internals::_getBoundingBox(const TopoDS_Shape &shape, double &xmin,
     std::vector<SVector3> normals;
     std::vector<int> triangles;
     _makeSTL(shape, vertices, normals, triangles);
+    // BRepBndLib can use the STL mesh if available, but unfortunately it
+    // enlarges the box with the mesh deflection tolerance and the shape
+    // tolerance, which makes it hard to get the expected minimal box in simple
+    // cases (e.g. for plane surfaces), and always leads to boxes that are too
+    // large; so we simply compute the box from the STL vertices. The downside
+    // of this approach is that the bbox might be *smaller* than the actual box
+    // for curved shapes, but this is preferable for us as boxes are mostly used
+    // to find/identify entities
+    if(vertices.size()) {
+      SBoundingBox3d bbox;
+      for(std::size_t i = 0; i < vertices.size(); i++)
+        bbox += vertices[i];
+      xmin = bbox.min().x();
+      ymin = bbox.min().y();
+      zmin = bbox.min().z();
+      xmax = bbox.max().x();
+      ymax = bbox.max().y();
+      zmax = bbox.max().z();
+      return true;
+    }
   }
   Bnd_Box b;
   try {
@@ -4498,8 +4518,6 @@ bool OCC_Internals::_getBoundingBox(const TopoDS_Shape &shape, double &xmin,
     return false;
   }
   b.Get(xmin, ymin, zmin, xmax, ymax, zmax);
-  if(CTX::instance()->geom.occBoundsUseSTL)
-    fixSTLBounds(xmin, ymin, zmin, xmax, ymax, zmax);
   return true;
 }
 
@@ -5745,28 +5763,6 @@ bool OCC_Internals::makeTorusSTL(double x, double y, double z, double r1,
   return true;
 }
 
-void OCC_Internals::fixSTLBounds(double &xmin, double &ymin, double &zmin,
-                                 double &xmax, double &ymax, double &zmax)
-{
-  // When an STL exists, OCC enlarges the bounding box by the allowed linear
-  // deflection given to BRepMesh_IncrementalMesh. This is "safe", but on simple
-  // polyhedral geometries (a cube!) it will consistently lead to enlarging the
-  // bounding box by twice this value in all directions. Since we use bounds()
-  // mostly for locating entities, it's better to remove the tolerance (with the
-  // risk that the bbox is a bit too small for curved boundaries - but that's
-  // fine)
-  double eps = CTX::instance()->mesh.stlLinearDeflection;
-  // OCC also enlarges the bounding box by Precision::Confusion(): remove it as
-  // well
-  eps += Precision::Confusion();
-  xmin += eps;
-  xmax -= eps;
-  ymin += eps;
-  ymax -= eps;
-  zmin += eps;
-  zmax -= eps;
-}
-
 #endif
 
 void GModel::createOCCInternals()
diff --git a/src/geo/GModelIO_OCC.h b/src/geo/GModelIO_OCC.h
index 71c388ece98fdbe1acf84f9ef927b62f1dc051f5..6e7b9764096845bc4cf47662461124bd7244e972 100644
--- a/src/geo/GModelIO_OCC.h
+++ b/src/geo/GModelIO_OCC.h
@@ -460,8 +460,6 @@ public:
                     double angle, std::vector<SPoint3> &vertices,
                     std::vector<SVector3> &normals,
                     std::vector<int> &triangles);
-  void fixSTLBounds(double &xmin, double &ymin, double &zmin, double &xmax,
-                    double &ymax, double &zmax);
 };
 
 #else
diff --git a/src/geo/OCCEdge.cpp b/src/geo/OCCEdge.cpp
index b62ca7a8523d93d9e81e6b8375c9f06700e86d33..b08cff67d2266ab7c031fc8e57e662de14468aed 100644
--- a/src/geo/OCCEdge.cpp
+++ b/src/geo/OCCEdge.cpp
@@ -72,6 +72,21 @@ void OCCEdge::delFace(GFace *f)
 
 SBoundingBox3d OCCEdge::bounds(bool fast)
 {
+  if(CTX::instance()->geom.occBoundsUseSTL && stl_vertices_xyz.size()) {
+    // BRepBndLib can use the STL mesh if available, but unfortunately it
+    // enlarges the box with the mesh deflection tolerance and the shape
+    // tolerance, which makes it hard to get the expected minimal box in simple
+    // cases (e.g. for straight lines), and always leads to boxes that are too
+    // large; so we simply compute the box from the STL vertices. The downside
+    // of this approach is that the bbox might be *smaller* than the actual box
+    // for curved shapes, but this is preferable for us as boxes are mostly used
+    // to find/identify entities
+    SBoundingBox3d bbox;
+    for(std::size_t i = 0; i < stl_vertices_xyz.size(); i++)
+      bbox += stl_vertices_xyz[i];
+    return bbox;
+  }
+
   Bnd_Box b;
   try {
     BRepBndLib::Add(_c, b);
@@ -81,11 +96,6 @@ SBoundingBox3d OCCEdge::bounds(bool fast)
   }
   double xmin, ymin, zmin, xmax, ymax, zmax;
   b.Get(xmin, ymin, zmin, xmax, ymax, zmax);
-
-  if(CTX::instance()->geom.occBoundsUseSTL)
-    model()->getOCCInternals()->fixSTLBounds(xmin, ymin, zmin, xmax, ymax,
-                                             zmax);
-
   SBoundingBox3d bbox(xmin, ymin, zmin, xmax, ymax, zmax);
   return bbox;
 }
diff --git a/src/geo/OCCFace.cpp b/src/geo/OCCFace.cpp
index 538d8672308b389a18091d9a783c6fc0dc1a2059..ff5654b2d83f5d15fbdb75bd0c7bca18ec531905 100644
--- a/src/geo/OCCFace.cpp
+++ b/src/geo/OCCFace.cpp
@@ -193,7 +193,23 @@ void OCCFace::_setup()
 
 SBoundingBox3d OCCFace::bounds(bool fast)
 {
-  if(CTX::instance()->geom.occBoundsUseSTL) buildSTLTriangulation();
+  if(CTX::instance()->geom.occBoundsUseSTL) {
+    buildSTLTriangulation();
+    // BRepBndLib can use the STL mesh if available, but unfortunately it
+    // enlarges the box with the mesh deflection tolerance and the shape
+    // tolerance, which makes it hard to get the expected minimal box in simple
+    // cases (e.g. for plane surfaces), and always leads to boxes that are too
+    // large; so we simply compute the box from the STL vertices. The downside
+    // of this approach is that the bbox might be *smaller* than the actual box
+    // for curved shapes, but this is preferable for us as boxes are mostly used
+    // to find/identify entities
+    if(stl_vertices_xyz.size()) {
+      SBoundingBox3d bbox;
+      for(std::size_t i = 0; i < stl_vertices_xyz.size(); i++)
+        bbox += stl_vertices_xyz[i];
+      return bbox;
+    }
+  }
 
   Bnd_Box b;
   try {
@@ -204,11 +220,6 @@ SBoundingBox3d OCCFace::bounds(bool fast)
   }
   double xmin, ymin, zmin, xmax, ymax, zmax;
   b.Get(xmin, ymin, zmin, xmax, ymax, zmax);
-
-  if(CTX::instance()->geom.occBoundsUseSTL)
-    model()->getOCCInternals()->fixSTLBounds(xmin, ymin, zmin, xmax, ymax,
-                                             zmax);
-
   SBoundingBox3d bbox(xmin, ymin, zmin, xmax, ymax, zmax);
   return bbox;
 }
diff --git a/src/geo/OCCRegion.cpp b/src/geo/OCCRegion.cpp
index b979d877686ab81d53a5953cc47e0f614733f6c7..3a1b39d37b73905c5459069077f0ad602c7b1278 100644
--- a/src/geo/OCCRegion.cpp
+++ b/src/geo/OCCRegion.cpp
@@ -97,10 +97,13 @@ void OCCRegion::_setup()
 SBoundingBox3d OCCRegion::bounds(bool fast)
 {
   if(CTX::instance()->geom.occBoundsUseSTL) {
-    // if a triangulation exist on a shape, OCC will use it to compute more
-    // accurate bounds
     std::vector<GFace *> f = faces();
-    for(std::size_t i = 0; i < f.size(); i++) f[i]->buildSTLTriangulation();
+    SBoundingBox3d bbox;
+    for(std::size_t i = 0; i < f.size(); i++) {
+      f[i]->buildSTLTriangulation();
+      bbox += f[i]->bounds();
+    }
+    return bbox;
   }
 
   Bnd_Box b;
@@ -112,11 +115,6 @@ SBoundingBox3d OCCRegion::bounds(bool fast)
   }
   double xmin, ymin, zmin, xmax, ymax, zmax;
   b.Get(xmin, ymin, zmin, xmax, ymax, zmax);
-
-  if(CTX::instance()->geom.occBoundsUseSTL)
-    model()->getOCCInternals()->fixSTLBounds(xmin, ymin, zmin, xmax, ymax,
-                                             zmax);
-
   SBoundingBox3d bbox(xmin, ymin, zmin, xmax, ymax, zmax);
   return bbox;
 }