diff --git a/Framework/Algorithms/inc/MantidAlgorithms/SampleCorrections/MCAbsorptionStrategy.h b/Framework/Algorithms/inc/MantidAlgorithms/SampleCorrections/MCAbsorptionStrategy.h
index 5d1bc89e2d9ee5f1fe303eb7856842e56d37252a..fd4d706b57cc20bcdd20ffbba8bd756a28c8b8b0 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/SampleCorrections/MCAbsorptionStrategy.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/SampleCorrections/MCAbsorptionStrategy.h
@@ -38,15 +38,16 @@ public:
                        size_t maxScatterPtAttempts);
   std::tuple<double, double> calculate(Kernel::PseudoRandomNumberGenerator &rng,
                                        const Kernel::V3D &finalPos,
-                                       double lambdaBefore, double lambdaAfter,
-                                       std::string &debugString) const;
+                                       double lambdaBefore, double lambdaAfter);
+  std::string getDebugString() const { return debugString; };
 
 private:
   const IBeamProfile &m_beamProfile;
-  const MCInteractionVolume m_scatterVol;
+  MCInteractionVolume m_scatterVol;
   const size_t m_nevents;
   const size_t m_maxScatterAttempts;
   const double m_error;
+  std::string debugString;
 };
 
 } // namespace Algorithms
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/SampleCorrections/MCInteractionVolume.h b/Framework/Algorithms/inc/MantidAlgorithms/SampleCorrections/MCInteractionVolume.h
index a93d3ad1b61e896328c509f2f572f5b5cdaae3d0..80eac35fec68ae51beccc44ac59c717452e063e7 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/SampleCorrections/MCInteractionVolume.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/SampleCorrections/MCInteractionVolume.h
@@ -9,6 +9,7 @@
 
 #include "MantidAlgorithms/DllConfig.h"
 #include "MantidGeometry/Objects/BoundingBox.h"
+#include <boost/optional.hpp>
 
 namespace Mantid {
 namespace API {
@@ -45,13 +46,18 @@ public:
   double calculateAbsorption(Kernel::PseudoRandomNumberGenerator &rng,
                              const Kernel::V3D &startPos,
                              const Kernel::V3D &endPos, double lambdaBefore,
-                             double lambdaAfter) const;
+                             double lambdaAfter);
   std::string generateScatterPointStats() const;
-  Kernel::V3D generatePoint(Kernel::PseudoRandomNumberGenerator &rng) const;
+  Kernel::V3D generatePoint(Kernel::PseudoRandomNumberGenerator &rng);
 
 private:
-  mutable int m_sampleScatterPoints = 0;
-  mutable std::vector<int> m_envScatterPoints;
+  int getComponentIndex(Kernel::PseudoRandomNumberGenerator &rng);
+  boost::optional<Kernel::V3D>
+  generatePointInObjectByIndex(int componentIndex,
+                               Kernel::PseudoRandomNumberGenerator &rng);
+  void UpdateScatterPointCounts(int componentIndex);
+  int m_sampleScatterPoints = 0;
+  std::vector<int> m_envScatterPoints;
   const boost::shared_ptr<Geometry::IObject> m_sample;
   const Geometry::SampleEnvironment *m_env;
   const Geometry::BoundingBox m_activeRegion;
diff --git a/Framework/Algorithms/src/MonteCarloAbsorption.cpp b/Framework/Algorithms/src/MonteCarloAbsorption.cpp
index ea990c3c901d05507d30311f9dd08d143fbc98a3..83d75020a49f8faa55b558ac45e8976d9329ab50 100644
--- a/Framework/Algorithms/src/MonteCarloAbsorption.cpp
+++ b/Framework/Algorithms/src/MonteCarloAbsorption.cpp
@@ -276,10 +276,10 @@ MatrixWorkspace_uptr MonteCarloAbsorption::doSimulation(
       } else {
         // elastic case already initialized
       }
-      std::string debugString;
+
       std::tie(outY[j], std::ignore) =
-          strategy.calculate(rng, detPos, lambdaIn, lambdaOut, debugString);
-      g_log.debug(debugString);
+          strategy.calculate(rng, detPos, lambdaIn, lambdaOut);
+      g_log.debug(strategy.getDebugString());
 
       // Ensure we have the last point for the interpolation
       if (lambdaStepSize > 1 && j + lambdaStepSize >= nbins && j + 1 != nbins) {
diff --git a/Framework/Algorithms/src/SampleCorrections/MCAbsorptionStrategy.cpp b/Framework/Algorithms/src/SampleCorrections/MCAbsorptionStrategy.cpp
index 8858f1e9b69138eed602faca4fb61c5c5ca50ad0..40f44015131013c079580976a61e7890a63ff8a4 100644
--- a/Framework/Algorithms/src/SampleCorrections/MCAbsorptionStrategy.cpp
+++ b/Framework/Algorithms/src/SampleCorrections/MCAbsorptionStrategy.cpp
@@ -43,12 +43,12 @@ MCAbsorptionStrategy::MCAbsorptionStrategy(const IBeamProfile &beamProfile,
  * where it is detected
  * @param lambdaBefore Wavelength, in \f$\\A^-1\f$, before scattering
  * @param lambdaAfter Wavelength, in \f$\\A^-1\f$, after scattering
- * @param debugString string to return any debug messages
  * @return A tuple of the <correction factor, associated error>.
  */
-std::tuple<double, double> MCAbsorptionStrategy::calculate(
-    Kernel::PseudoRandomNumberGenerator &rng, const Kernel::V3D &finalPos,
-    double lambdaBefore, double lambdaAfter, std::string &debugString) const {
+std::tuple<double, double>
+MCAbsorptionStrategy::calculate(Kernel::PseudoRandomNumberGenerator &rng,
+                                const Kernel::V3D &finalPos,
+                                double lambdaBefore, double lambdaAfter) {
   const auto scatterBounds = m_scatterVol.getBoundingBox();
   double factor(0.0);
   for (size_t i = 0; i < m_nevents; ++i) {
diff --git a/Framework/Algorithms/src/SampleCorrections/MCInteractionVolume.cpp b/Framework/Algorithms/src/SampleCorrections/MCInteractionVolume.cpp
index 62d8c874eb0a34540b95291935d4aae62eaa9dda..cc85412265e28cfcfe7b25a650c241f2c0f9a4e5 100644
--- a/Framework/Algorithms/src/SampleCorrections/MCInteractionVolume.cpp
+++ b/Framework/Algorithms/src/SampleCorrections/MCInteractionVolume.cpp
@@ -40,6 +40,7 @@ MCInteractionVolume::MCInteractionVolume(
   }
   try {
     m_env = &sample.getEnvironment();
+    assert(m_env);
     if (m_env->nelements() == 0) {
       throw std::invalid_argument(
           "MCInteractionVolume() - Sample enviroment has zero components.");
@@ -61,6 +62,58 @@ const Geometry::BoundingBox &MCInteractionVolume::getBoundingBox() const {
   return m_sample->getBoundingBox();
 }
 
+/**
+ * Randomly select a component across the sample/environment
+ * @param rng A reference to a PseudoRandomNumberGenerator where
+ * nextValue should return a flat random number between 0.0 & 1.0
+ * @return The randomly selected component index
+ */
+int MCInteractionVolume::getComponentIndex(
+    Kernel::PseudoRandomNumberGenerator &rng) {
+  int componentIndex;
+  // the sample has componentIndex -1, env components are number 0 upwards
+  if (m_env) {
+    componentIndex = rng.nextInt(0, static_cast<int>(m_env->nelements())) - 1;
+  } else {
+    componentIndex = -1;
+  }
+  return componentIndex;
+}
+
+/**
+ * Generate a point in an object identified by an index
+ * @param componentIndex Index of the sample/environment component where
+ * the sample is -1
+ * @param rng A reference to a PseudoRandomNumberGenerator where
+ * nextValue should return a flat random number between 0.0 & 1.0
+ * @return The generated point
+ */
+
+boost::optional<Kernel::V3D> MCInteractionVolume::generatePointInObjectByIndex(
+    int componentIndex, Kernel::PseudoRandomNumberGenerator &rng) {
+  boost::optional<Kernel::V3D> pointGenerated;
+  if (componentIndex == -1) {
+    pointGenerated = m_sample->generatePointInObject(rng, m_activeRegion, 1);
+  } else {
+    pointGenerated = m_env->getComponent(componentIndex)
+                         .generatePointInObject(rng, m_activeRegion, 1);
+  }
+  return pointGenerated;
+}
+
+/**
+ * Update the scatter point counts
+ * @param componentIndex Index of the sample/environment component where
+ * the sample is -1
+ */
+void MCInteractionVolume::UpdateScatterPointCounts(int componentIndex) {
+  if (componentIndex == -1) {
+    m_sampleScatterPoints++;
+  } else {
+    m_envScatterPoints[componentIndex]++;
+  }
+}
+
 /**
  * Generate point randomly across one of the components of the environment
  * including the sample itself in the selection. The method first selects
@@ -70,33 +123,15 @@ const Geometry::BoundingBox &MCInteractionVolume::getBoundingBox() const {
  * nextValue should return a flat random number between 0.0 & 1.0
  * @return The generated point
  */
-Kernel::V3D MCInteractionVolume::generatePoint(
-    Kernel::PseudoRandomNumberGenerator &rng) const {
+Kernel::V3D
+MCInteractionVolume::generatePoint(Kernel::PseudoRandomNumberGenerator &rng) {
   for (size_t i = 0; i < m_maxScatterAttempts; i++) {
-    Kernel::V3D point;
-    int componentIndex;
-    if (m_env) {
-      componentIndex = rng.nextInt(0, static_cast<int>(m_env->nelements())) - 1;
-    } else {
-      componentIndex = -1;
-    }
-
-    bool pointGenerated;
-    if (componentIndex == -1) {
-      pointGenerated =
-          m_sample->generatePointInObject(rng, m_activeRegion, 1, point);
-    } else {
-      pointGenerated =
-          m_env->getComponent(componentIndex)
-              .generatePointInObject(rng, m_activeRegion, 1, point);
-    }
+    int componentIndex = getComponentIndex(rng);
+    boost::optional<Kernel::V3D> pointGenerated =
+        generatePointInObjectByIndex(componentIndex, rng);
     if (pointGenerated) {
-      if (componentIndex == -1) {
-        m_sampleScatterPoints++;
-      } else {
-        m_envScatterPoints[componentIndex]++;
-      }
-      return point;
+      UpdateScatterPointCounts(componentIndex);
+      return *pointGenerated;
     }
   }
   throw std::runtime_error("MCInteractionVolume::generatePoint() - Unable to "
@@ -119,7 +154,7 @@ Kernel::V3D MCInteractionVolume::generatePoint(
  */
 double MCInteractionVolume::calculateAbsorption(
     Kernel::PseudoRandomNumberGenerator &rng, const Kernel::V3D &startPos,
-    const Kernel::V3D &endPos, double lambdaBefore, double lambdaAfter) const {
+    const Kernel::V3D &endPos, double lambdaBefore, double lambdaAfter) {
   // Generate scatter point. If there is an environment present then
   // first select whether the scattering occurs on the sample or the
   // environment. The attenuation for the path leading to the scatter point
@@ -174,10 +209,10 @@ std::string MCInteractionVolume::generateScatterPointStats() const {
 
   scatterPointSummary << "Scatter point counts:" << std::endl;
 
-  int totalScatterPoints = m_sampleScatterPoints;
-  for (std::vector<int>::size_type i = 0; i < m_envScatterPoints.size(); i++) {
-    totalScatterPoints += m_envScatterPoints[i];
-  }
+  int totalScatterPoints =
+      std::accumulate(m_envScatterPoints.begin(), m_envScatterPoints.end(),
+                      m_sampleScatterPoints);
+
   scatterPointSummary << "Total scatter points: " << totalScatterPoints
                       << std::endl;
 
diff --git a/Framework/Algorithms/test/MCAbsorptionStrategyTest.h b/Framework/Algorithms/test/MCAbsorptionStrategyTest.h
index 31fcefa7323a45d1e1976f097f7598fd353fe191..c23ed83a607d67cf16349cc07d36b3dacb84db96 100644
--- a/Framework/Algorithms/test/MCAbsorptionStrategyTest.h
+++ b/Framework/Algorithms/test/MCAbsorptionStrategyTest.h
@@ -57,9 +57,8 @@ public:
     const double lambdaBefore(2.5), lambdaAfter(3.5);
 
     double factor(0.0), error(0.0);
-    std::string debugString;
     std::tie(factor, error) =
-        mcabsorb.calculate(rng, endPos, lambdaBefore, lambdaAfter, debugString);
+        mcabsorb.calculate(rng, endPos, lambdaBefore, lambdaAfter);
     TS_ASSERT_DELTA(0.0043828472, factor, 1e-08);
     TS_ASSERT_DELTA(1.0 / std::sqrt(nevents), error, 1e-08);
   }
@@ -86,10 +85,8 @@ public:
     EXPECT_CALL(rng, nextValue()).WillRepeatedly(Return(0.5));
     const double lambdaBefore(2.5), lambdaAfter(3.5);
     const V3D endPos(0.7, 0.7, 1.4);
-    std::string debugString;
-    TS_ASSERT_THROWS(
-        mcabs.calculate(rng, endPos, lambdaBefore, lambdaAfter, debugString),
-        const std::runtime_error &)
+    TS_ASSERT_THROWS(mcabs.calculate(rng, endPos, lambdaBefore, lambdaAfter),
+                     const std::runtime_error &)
   }
 
 private:
diff --git a/Framework/Algorithms/test/MCInteractionVolumeTest.h b/Framework/Algorithms/test/MCInteractionVolumeTest.h
index ccf4ce62e9de9d9208ec41be0aa77020b33fa613..5e0c057231c563841b26b27431dfd5b4e17e2a79 100644
--- a/Framework/Algorithms/test/MCInteractionVolumeTest.h
+++ b/Framework/Algorithms/test/MCInteractionVolumeTest.h
@@ -16,6 +16,9 @@
 #include <gmock/gmock.h>
 
 using Mantid::Algorithms::MCInteractionVolume;
+using namespace ::testing;
+using namespace Mantid::Kernel;
+using namespace MonteCarloTesting;
 
 class MCInteractionVolumeTest : public CxxTest::TestSuite {
 public:
@@ -30,7 +33,6 @@ public:
   // Success cases
   //----------------------------------------------------------------------------
   void test_Bounding_Volume_Matches_Sample() {
-    using namespace MonteCarloTesting;
     auto sample = createTestSample(TestSampleType::SolidSphere);
     const auto sampleBox = sample.getShape().getBoundingBox();
     MCInteractionVolume interactor(sample, sampleBox);
@@ -42,8 +44,6 @@ public:
 
   void test_Absorption_In_Solid_Sample_Gives_Expected_Answer() {
     using Mantid::Kernel::V3D;
-    using namespace MonteCarloTesting;
-    using namespace ::testing;
 
     // Testing inputs
     const V3D startPos(-2.0, 0.0, 0.0), endPos(0.7, 0.7, 1.4);
@@ -62,8 +62,6 @@ public:
 
   void test_Absorption_In_Sample_With_Hole_Container_Scatter_In_All_Segments() {
     using Mantid::Kernel::V3D;
-    using namespace MonteCarloTesting;
-    using namespace ::testing;
 
     // Testing inputs
     const V3D startPos(-2.0, 0.0, 0.0), endPos(2.0, 0.0, 0.0);
@@ -95,8 +93,6 @@ public:
   void
   test_Absorption_In_Sample_And_Environment_Container_Scatter_In_All_Segments() {
     using Mantid::Kernel::V3D;
-    using namespace MonteCarloTesting;
-    using namespace ::testing;
 
     // Testing inputs
     const V3D startPos(-2.0, 0.0, 0.0), endPos(2.0, 0.0, 0.0);
@@ -138,9 +134,7 @@ public:
   // Failure cases
   //----------------------------------------------------------------------------
   void test_Construction_With_Invalid_Sample_Shape_Throws_Error() {
-    using Mantid::API::Sample;
-
-    Sample sample;
+    Mantid::API::Sample sample;
     // nothing
     TS_ASSERT_THROWS(
         MCInteractionVolume mcv(sample, sample.getShape().getBoundingBox()),
@@ -152,9 +146,6 @@ public:
   }
 
   void test_Throws_If_Point_Cannot_Be_Generated() {
-    using namespace Mantid::Kernel;
-    using namespace MonteCarloTesting;
-    using namespace ::testing;
 
     // Testing inputs
     const V3D startPos(-2.0, 0.0, 0.0), endPos(2.0, 0.0, 0.0);
@@ -172,15 +163,11 @@ public:
   }
 
   void testGeneratePointConsidersAllComponents() {
-    using namespace ::testing;
-    using namespace Mantid::Kernel;
-    using namespace MonteCarloTesting;
 
     auto kit = createTestKit();
     size_t maxAttempts(1);
 
-    using Mantid::API::Sample;
-    Sample sample;
+    Mantid::API::Sample sample;
     sample.setShape(ComponentCreationHelper::createSphere(1));
     sample.setEnvironment(
         std::make_unique<Mantid::Geometry::SampleEnvironment>(*kit));
@@ -236,9 +223,6 @@ public:
   }
 
   void testGeneratePointRespectsActiveRegion() {
-    using namespace MonteCarloTesting;
-    using namespace ::testing;
-    using namespace Mantid::Kernel;
 
     auto kit = createTestKit();
     size_t maxAttempts(1);
diff --git a/Framework/Geometry/inc/MantidGeometry/Instrument/Container.h b/Framework/Geometry/inc/MantidGeometry/Instrument/Container.h
index a18ef6de79a2968c954791d1aa2bb831268f3354..3698add9d3146f98bd55af45868d1cc3631b35e4 100644
--- a/Framework/Geometry/inc/MantidGeometry/Instrument/Container.h
+++ b/Framework/Geometry/inc/MantidGeometry/Instrument/Container.h
@@ -79,15 +79,16 @@ public:
   int getPointInObject(Kernel::V3D &point) const override {
     return m_shape->getPointInObject(point);
   }
-  bool generatePointInObject(Kernel::PseudoRandomNumberGenerator &rng,
-                             const size_t i,
-                             Kernel::V3D &point) const override {
-    return m_shape->generatePointInObject(rng, i, point);
-  }
-  bool generatePointInObject(Kernel::PseudoRandomNumberGenerator &rng,
-                             const BoundingBox &activeRegion, const size_t i,
-                             Kernel::V3D &point) const override {
-    return m_shape->generatePointInObject(rng, activeRegion, i, point);
+  boost::optional<Kernel::V3D>
+  generatePointInObject(Kernel::PseudoRandomNumberGenerator &rng,
+                        const size_t i) const override {
+    return m_shape->generatePointInObject(rng, i);
+  }
+  boost::optional<Kernel::V3D>
+  generatePointInObject(Kernel::PseudoRandomNumberGenerator &rng,
+                        const BoundingBox &activeRegion,
+                        const size_t i) const override {
+    return m_shape->generatePointInObject(rng, activeRegion, i);
   }
 
   detail::ShapeInfo::GeometryShape shape() const override {
diff --git a/Framework/Geometry/inc/MantidGeometry/Objects/CSGObject.h b/Framework/Geometry/inc/MantidGeometry/Objects/CSGObject.h
index 4eadddaf38b5ba6bb08438fce5457d8585b7bfd0..bc92e93c1e53947ede4ccb41c88d04b42eb145ec 100644
--- a/Framework/Geometry/inc/MantidGeometry/Objects/CSGObject.h
+++ b/Framework/Geometry/inc/MantidGeometry/Objects/CSGObject.h
@@ -165,11 +165,13 @@ public:
   int getPointInObject(Kernel::V3D &point) const override;
 
   /// Select a random point within the object
-  bool generatePointInObject(Kernel::PseudoRandomNumberGenerator &rng,
-                             const size_t, Kernel::V3D &point) const override;
-  bool generatePointInObject(Kernel::PseudoRandomNumberGenerator &rng,
-                             const BoundingBox &activeRegion, const size_t,
-                             Kernel::V3D &point) const override;
+  boost::optional<Kernel::V3D>
+  generatePointInObject(Kernel::PseudoRandomNumberGenerator &rng,
+                        const size_t) const override;
+  boost::optional<Kernel::V3D>
+  generatePointInObject(Kernel::PseudoRandomNumberGenerator &rng,
+                        const BoundingBox &activeRegion,
+                        const size_t) const override;
 
   // Rendering member functions
   void draw() const override;
diff --git a/Framework/Geometry/inc/MantidGeometry/Objects/IObject.h b/Framework/Geometry/inc/MantidGeometry/Objects/IObject.h
index c53e199de145f3bede302e622cf614934a4dd2a6..13586ebc709e2e54e02bf8dad154631af9c51798 100644
--- a/Framework/Geometry/inc/MantidGeometry/Objects/IObject.h
+++ b/Framework/Geometry/inc/MantidGeometry/Objects/IObject.h
@@ -9,6 +9,7 @@
 
 #include "MantidGeometry/DllConfig.h"
 #include "MantidGeometry/Rendering/ShapeInfo.h"
+#include <boost/optional.hpp>
 #include <boost/shared_ptr.hpp>
 #include <map>
 #include <vector>
@@ -70,13 +71,13 @@ public:
 
   virtual int getPointInObject(Kernel::V3D &point) const = 0;
 
-  virtual bool generatePointInObject(Kernel::PseudoRandomNumberGenerator &rng,
-                                     const size_t,
-                                     Kernel::V3D &point) const = 0;
-  virtual bool generatePointInObject(Kernel::PseudoRandomNumberGenerator &rng,
-                                     const BoundingBox &activeRegion,
-                                     const size_t,
-                                     Kernel::V3D &point) const = 0;
+  virtual boost::optional<Kernel::V3D>
+  generatePointInObject(Kernel::PseudoRandomNumberGenerator &rng,
+                        const size_t) const = 0;
+  virtual boost::optional<Kernel::V3D>
+  generatePointInObject(Kernel::PseudoRandomNumberGenerator &rng,
+                        const BoundingBox &activeRegion,
+                        const size_t) const = 0;
 
   virtual detail::ShapeInfo::GeometryShape shape() const = 0;
   virtual const detail::ShapeInfo &shapeInfo() const = 0;
diff --git a/Framework/Geometry/inc/MantidGeometry/Objects/MeshObject.h b/Framework/Geometry/inc/MantidGeometry/Objects/MeshObject.h
index 55b2c489b47ed1a0f553eb9ce9da820828d540e6..c9cf8bea6b6c265329a29031ead321e6f98194eb 100644
--- a/Framework/Geometry/inc/MantidGeometry/Objects/MeshObject.h
+++ b/Framework/Geometry/inc/MantidGeometry/Objects/MeshObject.h
@@ -110,11 +110,13 @@ public:
   int getPointInObject(Kernel::V3D &point) const override;
 
   /// Select a random point within the object
-  bool generatePointInObject(Kernel::PseudoRandomNumberGenerator &rng,
-                             const size_t, Kernel::V3D &point) const override;
-  bool generatePointInObject(Kernel::PseudoRandomNumberGenerator &rng,
-                             const BoundingBox &activeRegion, const size_t,
-                             Kernel::V3D &point) const override;
+  boost::optional<Kernel::V3D>
+  generatePointInObject(Kernel::PseudoRandomNumberGenerator &rng,
+                        const size_t) const override;
+  boost::optional<Kernel::V3D>
+  generatePointInObject(Kernel::PseudoRandomNumberGenerator &rng,
+                        const BoundingBox &activeRegion,
+                        const size_t) const override;
 
   // Rendering member functions
   void draw() const override;
diff --git a/Framework/Geometry/inc/MantidGeometry/Objects/MeshObject2D.h b/Framework/Geometry/inc/MantidGeometry/Objects/MeshObject2D.h
index 229f591d1594be9a364073062279dac850ea63c6..1b4f83809f7ab5f4d332a789384e30fad2a3b6f4 100644
--- a/Framework/Geometry/inc/MantidGeometry/Objects/MeshObject2D.h
+++ b/Framework/Geometry/inc/MantidGeometry/Objects/MeshObject2D.h
@@ -65,11 +65,13 @@ public:
                       double &ymin, double &zmin) const override;
   int getPointInObject(Kernel::V3D &point) const override;
 
-  bool generatePointInObject(Kernel::PseudoRandomNumberGenerator &rng,
-                             const size_t, Kernel::V3D &point) const override;
-  bool generatePointInObject(Kernel::PseudoRandomNumberGenerator &rng,
-                             const BoundingBox &activeRegion, const size_t,
-                             Kernel::V3D &point) const override;
+  boost::optional<Kernel::V3D>
+  generatePointInObject(Kernel::PseudoRandomNumberGenerator &rng,
+                        const size_t) const override;
+  boost::optional<Kernel::V3D>
+  generatePointInObject(Kernel::PseudoRandomNumberGenerator &rng,
+                        const BoundingBox &activeRegion,
+                        const size_t) const override;
   detail::ShapeInfo::GeometryShape shape() const override;
   const detail::ShapeInfo &shapeInfo() const override;
   void GetObjectGeom(detail::ShapeInfo::GeometryShape &type,
diff --git a/Framework/Geometry/src/Objects/CSGObject.cpp b/Framework/Geometry/src/Objects/CSGObject.cpp
index d6ec6752900cb8577f73212797757e1e1f926dc7..4afe79d3c8f990fa7d808d62e8121f2cfebc33f9 100644
--- a/Framework/Geometry/src/Objects/CSGObject.cpp
+++ b/Framework/Geometry/src/Objects/CSGObject.cpp
@@ -1982,12 +1982,12 @@ int CSGObject::getPointInObject(Kernel::V3D &point) const {
  * @param rng  A reference to a PseudoRandomNumberGenerator where
  * nextValue should return a flat random number between 0.0 & 1.0
  * @param maxAttempts The maximum number of attempts at generating a point
- * @param point The generated point
  * @return whether a point was generated in the object or not
  */
-bool CSGObject::generatePointInObject(PseudoRandomNumberGenerator &rng,
-                                      const size_t maxAttempts,
-                                      V3D &point) const {
+boost::optional<Kernel::V3D>
+CSGObject::generatePointInObject(PseudoRandomNumberGenerator &rng,
+                                 const size_t maxAttempts) const {
+  boost::optional<V3D> point{boost::none};
   // If the shape fills its bounding box well enough then the most efficient
   // way to get the point is just brute force. We'll try that first with
   // just a few attempts.
@@ -2000,7 +2000,7 @@ bool CSGObject::generatePointInObject(PseudoRandomNumberGenerator &rng,
   boost::optional<V3D> maybePoint{
       RandomPoint::inGenericShape(*this, rng, bruteForceAttempts)};
   if (maybePoint) {
-    point = *maybePoint;
+    point = maybePoint;
   } else {
     switch (shape()) {
     case detail::ShapeInfo::GeometryShape::CUBOID:
@@ -2018,15 +2018,10 @@ bool CSGObject::generatePointInObject(PseudoRandomNumberGenerator &rng,
     default:
       maybePoint = RandomPoint::inGenericShape(
           *this, rng, maxAttempts - bruteForceAttempts);
-      if (!maybePoint) {
-        return false;
-      } else {
-        point = *maybePoint;
-        break;
-      }
+      point = maybePoint;
     }
   }
-  return true;
+  return point;
 }
 
 /**
@@ -2037,14 +2032,13 @@ bool CSGObject::generatePointInObject(PseudoRandomNumberGenerator &rng,
  * @param activeRegion Restrict point generation to this sub-region of the
  * object
  * @param maxAttempts The maximum number of attempts at generating a point
- * @param point The generated point
  * @return whether a point was generated in the object or not
  */
-bool CSGObject::generatePointInObject(Kernel::PseudoRandomNumberGenerator &rng,
-                                      const BoundingBox &activeRegion,
-                                      const size_t maxAttempts,
-                                      V3D &point) const {
-  boost::optional<V3D> pointGenerated{boost::none};
+boost::optional<Kernel::V3D>
+CSGObject::generatePointInObject(Kernel::PseudoRandomNumberGenerator &rng,
+                                 const BoundingBox &activeRegion,
+                                 const size_t maxAttempts) const {
+  boost::optional<V3D> point{boost::none};
   // We'll first try brute force. If the shape fills its bounding box
   // well enough, this should be the fastest method.
   // Increasing the brute force attemps speeds up the shapes that fill
@@ -2053,9 +2047,8 @@ bool CSGObject::generatePointInObject(Kernel::PseudoRandomNumberGenerator &rng,
   // shape, its dimension and orientation.
   const size_t bruteForceAttempts{
       std::min(static_cast<size_t>(5), maxAttempts)};
-  pointGenerated =
-      RandomPoint::bounded(*this, rng, activeRegion, bruteForceAttempts);
-  if (!pointGenerated) {
+  point = RandomPoint::bounded(*this, rng, activeRegion, bruteForceAttempts);
+  if (!point) {
     detail::ShapeInfo::GeometryShape shape;
     std::vector<Kernel::V3D> shapeVectors;
     double radius;
@@ -2064,37 +2057,32 @@ bool CSGObject::generatePointInObject(Kernel::PseudoRandomNumberGenerator &rng,
     GetObjectGeom(shape, shapeVectors, innerRadius, radius, height);
     switch (shape) {
     case detail::ShapeInfo::GeometryShape::CUBOID:
-      pointGenerated = RandomPoint::bounded<RandomPoint::inCuboid>(
+      point = RandomPoint::bounded<RandomPoint::inCuboid>(
           m_handler->shapeInfo(), rng, activeRegion,
           maxAttempts - bruteForceAttempts);
       break;
     case detail::ShapeInfo::GeometryShape::CYLINDER:
-      pointGenerated = RandomPoint::bounded<RandomPoint::inCylinder>(
+      point = RandomPoint::bounded<RandomPoint::inCylinder>(
           m_handler->shapeInfo(), rng, activeRegion,
           maxAttempts - bruteForceAttempts);
       break;
     case detail::ShapeInfo::GeometryShape::HOLLOWCYLINDER:
-      pointGenerated = RandomPoint::bounded<RandomPoint::inHollowCylinder>(
+      point = RandomPoint::bounded<RandomPoint::inHollowCylinder>(
           m_handler->shapeInfo(), rng, activeRegion,
           maxAttempts - bruteForceAttempts);
       break;
     case detail::ShapeInfo::GeometryShape::SPHERE:
-      pointGenerated = RandomPoint::bounded<RandomPoint::inSphere>(
+      point = RandomPoint::bounded<RandomPoint::inSphere>(
           m_handler->shapeInfo(), rng, activeRegion,
           maxAttempts - bruteForceAttempts);
       break;
     default:
-      pointGenerated = RandomPoint::bounded(*this, rng, activeRegion,
-                                            maxAttempts - bruteForceAttempts);
+      point = RandomPoint::bounded(*this, rng, activeRegion,
+                                   maxAttempts - bruteForceAttempts);
       break;
     }
   }
-  if (!pointGenerated) {
-    return false;
-  } else {
-    point = *pointGenerated;
-    return true;
-  }
+  return point;
 }
 
 /**
diff --git a/Framework/Geometry/src/Objects/MeshObject.cpp b/Framework/Geometry/src/Objects/MeshObject.cpp
index 150cefb38ca71cbb7a7aafd0109e661b8f4178ef..ae3e6252a8fa9a551a03096e3a17d980da98780f 100644
--- a/Framework/Geometry/src/Objects/MeshObject.cpp
+++ b/Framework/Geometry/src/Objects/MeshObject.cpp
@@ -383,18 +383,17 @@ int MeshObject::getPointInObject(Kernel::V3D &point) const {
  * @param rng  A reference to a PseudoRandomNumberGenerator where
  * nextValue should return a flat random number between 0.0 & 1.0
  * @param maxAttempts The maximum number of attempts at generating a point
- * @param point The newly generated point
- * @return Whether a point was generated or not
+ * @return The generated point
  */
-bool MeshObject::generatePointInObject(Kernel::PseudoRandomNumberGenerator &rng,
-                                       const size_t maxAttempts,
-                                       Kernel::V3D &point) const {
+boost::optional<Kernel::V3D>
+MeshObject::generatePointInObject(Kernel::PseudoRandomNumberGenerator &rng,
+                                  const size_t maxAttempts) const {
   const auto &bbox = getBoundingBox();
   if (bbox.isNull()) {
     throw std::runtime_error("Object::generatePointInObject() - Invalid "
                              "bounding box. Cannot generate new point.");
   }
-  return generatePointInObject(rng, bbox, maxAttempts, point);
+  return generatePointInObject(rng, bbox, maxAttempts);
 }
 
 /**
@@ -405,23 +404,17 @@ bool MeshObject::generatePointInObject(Kernel::PseudoRandomNumberGenerator &rng,
  * @param activeRegion Restrict point generation to this sub-region of the
  * object
  * @param maxAttempts The maximum number of attempts at generating a point
- * @param point The newly generated point
- * @return Whether a point was generated or not
+ * @return The generated point
  */
-bool MeshObject::generatePointInObject(Kernel::PseudoRandomNumberGenerator &rng,
-                                       const BoundingBox &activeRegion,
-                                       const size_t maxAttempts,
-                                       Kernel::V3D &point) const {
+boost::optional<Kernel::V3D>
+MeshObject::generatePointInObject(Kernel::PseudoRandomNumberGenerator &rng,
+                                  const BoundingBox &activeRegion,
+                                  const size_t maxAttempts) const {
 
-  const auto pointGenerated =
+  const auto point =
       RandomPoint::bounded(*this, rng, activeRegion, maxAttempts);
 
-  if (!pointGenerated) {
-    return false;
-  } else {
-    point = *pointGenerated;
-    return true;
-  }
+  return point;
 }
 
 /**
diff --git a/Framework/Geometry/src/Objects/MeshObject2D.cpp b/Framework/Geometry/src/Objects/MeshObject2D.cpp
index f7ef600ba62fc5fd1357bbc77e77cd597c58c6dd..19fc9455fada0d9e4cdbc92ddeb78597f5c0251f 100644
--- a/Framework/Geometry/src/Objects/MeshObject2D.cpp
+++ b/Framework/Geometry/src/Objects/MeshObject2D.cpp
@@ -388,19 +388,18 @@ int MeshObject2D::getPointInObject(Kernel::V3D &point) const {
   return this->isValid(point) ? 1 : 0;
 }
 
-bool MeshObject2D::generatePointInObject(
-    Kernel::PseudoRandomNumberGenerator & /*rng*/, const size_t /*unused*/,
-    Kernel::V3D & /*unused*/) const {
+boost::optional<Kernel::V3D> MeshObject2D::generatePointInObject(
+    Kernel::PseudoRandomNumberGenerator & /*rng*/,
+    const size_t /*unused*/) const {
   // How this would work for a finite plane is not clear. Points within the
   // plane can of course be generated, but most implementations of this method
   // use the bounding box
   throw std::runtime_error("Not implemented.");
 }
 
-bool MeshObject2D::generatePointInObject(
+boost::optional<Kernel::V3D> MeshObject2D::generatePointInObject(
     Kernel::PseudoRandomNumberGenerator & /*rng*/,
-    const BoundingBox & /*activeRegion*/, const size_t /*unused*/,
-    Kernel::V3D & /*unused*/) const {
+    const BoundingBox & /*activeRegion*/, const size_t /*unused*/) const {
 
   // How this would work for a finite plane is not clear. Points within the
   // plane can of course be generated, but most implementations of this method
diff --git a/Framework/Geometry/test/CSGObjectTest.h b/Framework/Geometry/test/CSGObjectTest.h
index 0ffe03d5a58e6b6244e0934266c0dad13d6de397..c91431701249d966b35acffdb65aff1d75aeb371 100644
--- a/Framework/Geometry/test/CSGObjectTest.h
+++ b/Framework/Geometry/test/CSGObjectTest.h
@@ -730,14 +730,13 @@ public:
     // inside hole
     auto shell = ComponentCreationHelper::createHollowShell(0.5, 1.0);
     constexpr size_t maxAttempts{1};
-    V3D point;
-    TS_ASSERT_EQUALS(shell->generatePointInObject(rng, maxAttempts, point),
-                     true);
+    boost::optional<V3D> point = shell->generatePointInObject(rng, maxAttempts);
+    TS_ASSERT_EQUALS(!point, false);
 
     constexpr double tolerance{1e-10};
-    TS_ASSERT_DELTA(-1. + 2. * 0.55, point.X(), tolerance);
-    TS_ASSERT_DELTA(-1. + 2. * 0.65, point.Y(), tolerance);
-    TS_ASSERT_DELTA(-1. + 2. * 0.70, point.Z(), tolerance);
+    TS_ASSERT_DELTA(-1. + 2. * 0.55, point->X(), tolerance);
+    TS_ASSERT_DELTA(-1. + 2. * 0.65, point->Y(), tolerance);
+    TS_ASSERT_DELTA(-1. + 2. * 0.70, point->Z(), tolerance);
   }
 
   void testGeneratePointInsideCuboid() {
@@ -759,14 +758,14 @@ public:
     auto cuboid =
         ComponentCreationHelper::createCuboid(xLength, yLength, zLength);
     constexpr size_t maxAttempts{0};
-    V3D point;
-    TS_ASSERT_EQUALS(cuboid->generatePointInObject(rng, maxAttempts, point),
-                     true);
+    boost::optional<V3D> point =
+        cuboid->generatePointInObject(rng, maxAttempts);
+    TS_ASSERT_EQUALS(!point, false);
 
     constexpr double tolerance{1e-10};
-    TS_ASSERT_DELTA(xLength - randX * 2. * xLength, point.X(), tolerance);
-    TS_ASSERT_DELTA(-yLength + randY * 2. * yLength, point.Y(), tolerance);
-    TS_ASSERT_DELTA(-zLength + randZ * 2. * zLength, point.Z(), tolerance);
+    TS_ASSERT_DELTA(xLength - randX * 2. * xLength, point->X(), tolerance);
+    TS_ASSERT_DELTA(-yLength + randY * 2. * yLength, point->Y(), tolerance);
+    TS_ASSERT_DELTA(-zLength + randZ * 2. * zLength, point->Z(), tolerance);
   }
 
   void testGeneratePointInsideCylinder() {
@@ -793,18 +792,18 @@ public:
     auto cylinder = ComponentCreationHelper::createCappedCylinder(
         radius, height, bottomCentre, axis, "cyl");
     constexpr size_t maxAttempts{0};
-    V3D point;
-    TS_ASSERT_EQUALS(cylinder->generatePointInObject(rng, maxAttempts, point),
-                     true);
+    boost::optional<V3D> point =
+        cylinder->generatePointInObject(rng, maxAttempts);
+    TS_ASSERT_EQUALS(!point, false);
     // Global->cylinder local coordinates
-    point -= bottomCentre;
+    *point -= bottomCentre;
     constexpr double tolerance{1e-10};
     const double polarAngle{2. * M_PI * randT};
     const double radialLength{radius * std::sqrt(randR)};
     const double axisLength{height * randZ};
-    TS_ASSERT_DELTA(radialLength * std::cos(polarAngle), point.X(), tolerance);
-    TS_ASSERT_DELTA(radialLength * std::sin(polarAngle), point.Y(), tolerance);
-    TS_ASSERT_DELTA(axisLength, point.Z(), tolerance);
+    TS_ASSERT_DELTA(radialLength * std::cos(polarAngle), point->X(), tolerance);
+    TS_ASSERT_DELTA(radialLength * std::sin(polarAngle), point->Y(), tolerance);
+    TS_ASSERT_DELTA(axisLength, point->Z(), tolerance);
   }
 
   void testGeneratePointInsideHollowCylinder() {
@@ -832,20 +831,20 @@ public:
     auto hollowCylinder = ComponentCreationHelper::createHollowCylinder(
         innerRadius, radius, height, bottomCentre, axis, "hol-cyl");
     constexpr size_t maxAttempts{0};
-    V3D point;
-    TS_ASSERT_EQUALS(
-        hollowCylinder->generatePointInObject(rng, maxAttempts, point), true);
+    boost::optional<V3D> point;
+    point = hollowCylinder->generatePointInObject(rng, maxAttempts);
+    TS_ASSERT_EQUALS(!point, false);
     // Global->cylinder local coordinates
-    point -= bottomCentre;
+    *point -= bottomCentre;
     constexpr double tolerance{1e-10};
     const double polarAngle{2. * M_PI * randT};
     const double c1 = std::pow(innerRadius, 2);
     const double c2 = std::pow(radius, 2);
     const double radialLength{std::sqrt(c1 + (c2 - c1) * randR)};
     const double axisLength{height * randZ};
-    TS_ASSERT_DELTA(radialLength * std::cos(polarAngle), point.X(), tolerance);
-    TS_ASSERT_DELTA(radialLength * std::sin(polarAngle), point.Y(), tolerance);
-    TS_ASSERT_DELTA(axisLength, point.Z(), tolerance);
+    TS_ASSERT_DELTA(radialLength * std::cos(polarAngle), point->X(), tolerance);
+    TS_ASSERT_DELTA(radialLength * std::sin(polarAngle), point->Y(), tolerance);
+    TS_ASSERT_DELTA(axisLength, point->Z(), tolerance);
   }
 
   void testGeneratePointInsideSphere() {
@@ -864,19 +863,19 @@ public:
     constexpr double radius{0.23};
     auto sphere = ComponentCreationHelper::createSphere(radius);
     constexpr size_t maxAttempts{0};
-    V3D point;
-    TS_ASSERT_EQUALS(sphere->generatePointInObject(rng, maxAttempts, point),
-                     true);
+    boost::optional<V3D> point;
+    point = sphere->generatePointInObject(rng, maxAttempts);
+    TS_ASSERT_EQUALS(!point, false);
     // Global->cylinder local coordinates
     constexpr double tolerance{1e-10};
     const double azimuthalAngle{2. * M_PI * randT};
     const double polarAngle{std::acos(2. * randF - 1.)};
     const double r{radius * randR};
     TS_ASSERT_DELTA(r * std::cos(azimuthalAngle) * std::sin(polarAngle),
-                    point.X(), tolerance);
+                    point->X(), tolerance);
     TS_ASSERT_DELTA(r * std::sin(azimuthalAngle) * std::sin(polarAngle),
-                    point.Y(), tolerance);
-    TS_ASSERT_DELTA(r * std::cos(polarAngle), point.Z(), tolerance);
+                    point->Y(), tolerance);
+    TS_ASSERT_DELTA(r * std::cos(polarAngle), point->Z(), tolerance);
   }
 
   void testGeneratePointInsideRespectsMaxAttempts() {
@@ -893,9 +892,8 @@ public:
     // inside hole
     auto shell = ComponentCreationHelper::createHollowShell(0.5, 1.0);
     constexpr size_t maxAttempts{1};
-    V3D point;
-    TS_ASSERT_EQUALS(shell->generatePointInObject(rng, maxAttempts, point),
-                     false);
+    boost::optional<V3D> point = shell->generatePointInObject(rng, maxAttempts);
+    TS_ASSERT_EQUALS(!point, true);
   }
 
   void testGeneratePointInsideRespectsActiveRegion() {
@@ -916,15 +914,14 @@ public:
     // Create a thin infinite rectangular region to restrict point generation
     BoundingBox activeRegion(0.1, 0.1, 0.1, -0.1, -0.1, -0.1);
     constexpr size_t maxAttempts{1};
-    V3D point;
-    TS_ASSERT_EQUALS(
-        ball->generatePointInObject(rng, activeRegion, maxAttempts, point),
-        true);
+    boost::optional<V3D> point =
+        ball->generatePointInObject(rng, activeRegion, maxAttempts);
+    TS_ASSERT_EQUALS(!point, false);
     // We should get the point generated from the second 'random' triplet.
     constexpr double tolerance{1e-10};
-    TS_ASSERT_DELTA(-0.1 + randX * 0.2, point.X(), tolerance)
-    TS_ASSERT_DELTA(-0.1 + randY * 0.2, point.Y(), tolerance)
-    TS_ASSERT_DELTA(-0.1 + randZ * 0.2, point.Z(), tolerance)
+    TS_ASSERT_DELTA(-0.1 + randX * 0.2, point->X(), tolerance)
+    TS_ASSERT_DELTA(-0.1 + randY * 0.2, point->Y(), tolerance)
+    TS_ASSERT_DELTA(-0.1 + randZ * 0.2, point->Z(), tolerance)
   }
 
   void testSolidAngleSphere()
@@ -1747,52 +1744,44 @@ public:
 
   void test_generatePointInside_Cuboid_With_ActiveRegion() {
     constexpr size_t maxAttempts{500};
-    V3D point;
     for (size_t i{0}; i < m_npoints; ++i) {
-      m_cuboid->generatePointInObject(m_rng, m_activeRegion, maxAttempts,
-                                      point);
+      m_cuboid->generatePointInObject(m_rng, m_activeRegion, maxAttempts);
     }
   }
 
   void test_generatePointInside_Cylinder_With_ActiveRegion() {
     constexpr size_t maxAttempts{500};
-    V3D point;
     for (size_t i{0}; i < m_npoints; ++i) {
-      m_cylinder->generatePointInObject(m_rng, m_activeRegion, maxAttempts,
-                                        point);
+      m_cylinder->generatePointInObject(m_rng, m_activeRegion, maxAttempts);
     }
   }
 
   void test_generatePointInside_Rotated_Cuboid() {
     constexpr size_t maxAttempts{500};
-    V3D point;
     for (size_t i = 0; i < m_npoints; ++i) {
-      m_rotatedCuboid->generatePointInObject(m_rng, maxAttempts, point);
+      m_rotatedCuboid->generatePointInObject(m_rng, maxAttempts);
     }
   }
 
   void test_generatePointInside_Rotated_Cuboid_With_ActiveRegion() {
     constexpr size_t maxAttempts{500};
-    V3D point;
     for (size_t i = 0; i < m_npoints; ++i) {
-      m_rotatedCuboid->generatePointInObject(m_rng, m_activeRegion, maxAttempts,
-                                             point);
+      m_rotatedCuboid->generatePointInObject(m_rng, m_activeRegion,
+                                             maxAttempts);
     }
   }
 
   void test_generatePointInside_Sphere() {
     constexpr size_t maxAttempts{500};
-    V3D point;
     for (size_t i = 0; i < m_npoints; ++i) {
-      m_sphere->generatePointInObject(m_rng, maxAttempts, point);
+      m_sphere->generatePointInObject(m_rng, maxAttempts);
     }
   }
 
   void test_generatePointInside_sphericalShell() {
     constexpr size_t maxAttempts{500};
-    V3D point;
     for (size_t i = 0; i < m_npoints; ++i) {
-      m_sphericalShell->generatePointInObject(m_rng, maxAttempts, point);
+      m_sphericalShell->generatePointInObject(m_rng, maxAttempts);
     }
   }
 
diff --git a/Framework/Geometry/test/MeshObject2DTest.h b/Framework/Geometry/test/MeshObject2DTest.h
index 9eabaf8328e70d9ffb3558966e9663847d0e758a..1aa472f160d7a3fad4c38eaf8f4420f42efd1855 100644
--- a/Framework/Geometry/test/MeshObject2DTest.h
+++ b/Framework/Geometry/test/MeshObject2DTest.h
@@ -332,8 +332,8 @@ public:
     // plane
     auto mesh = makeSimpleTriangleMesh();
     testing::NiceMock<MockRNG> generator;
-    V3D point;
-    TS_ASSERT_THROWS(mesh.generatePointInObject(generator, 10, point),
+    boost::optional<V3D> point;
+    TS_ASSERT_THROWS(point = mesh.generatePointInObject(generator, 10),
                      std::runtime_error &);
   }
   // Characterisation test.
@@ -344,10 +344,10 @@ public:
     auto mesh = makeSimpleTriangleMesh();
     testing::NiceMock<MockRNG> generator;
     Mantid::Geometry::BoundingBox boundingBox;
-    V3D point;
-    TS_ASSERT_THROWS(
-        mesh.generatePointInObject(generator, boundingBox, 10, point),
-        std::runtime_error &);
+    boost::optional<V3D> point;
+    TS_ASSERT_THROWS(point =
+                         mesh.generatePointInObject(generator, boundingBox, 10),
+                     std::runtime_error &);
   }
 
   // Characterisation test.
diff --git a/Framework/Geometry/test/MeshObjectTest.h b/Framework/Geometry/test/MeshObjectTest.h
index b18e51afc8199926e5ebad936dd72696ce84f2f6..ebd57726629da80bcce34a5b6bc575cd17abfa46 100644
--- a/Framework/Geometry/test/MeshObjectTest.h
+++ b/Framework/Geometry/test/MeshObjectTest.h
@@ -18,6 +18,8 @@
 #include "MantidTestHelpers/ComponentCreationHelper.h"
 #include "MockRNG.h"
 
+#include <boost/optional.hpp>
+
 #include <cxxtest/TestSuite.h>
 
 #include <Poco/DOM/AutoPtr.h>
@@ -846,14 +848,14 @@ public:
     //  Random sequence set up so as to give point (0.90, 1.10, 0.65)
     auto geom_obj = createLShape();
     size_t maxAttempts(1);
-    V3D point;
+    boost::optional<Kernel::V3D> point;
     TS_ASSERT_THROWS_NOTHING(
-        geom_obj->generatePointInObject(rng, maxAttempts, point));
+        point = geom_obj->generatePointInObject(rng, maxAttempts));
 
     const double tolerance(1e-10);
-    TS_ASSERT_DELTA(0.90, point.X(), tolerance);
-    TS_ASSERT_DELTA(1.10, point.Y(), tolerance);
-    TS_ASSERT_DELTA(0.65, point.Z(), tolerance);
+    TS_ASSERT_DELTA(0.90, point->X(), tolerance);
+    TS_ASSERT_DELTA(1.10, point->Y(), tolerance);
+    TS_ASSERT_DELTA(0.65, point->Z(), tolerance);
   }
 
   void testGeneratePointInsideRespectsMaxAttempts() {
@@ -870,9 +872,9 @@ public:
     //  which is outside the octahedron
     auto geom_obj = createOctahedron();
     size_t maxAttempts(1);
-    V3D point;
-    TS_ASSERT_EQUALS(geom_obj->generatePointInObject(rng, maxAttempts, point),
-                     false);
+    boost::optional<V3D> point;
+    point = geom_obj->generatePointInObject(rng, maxAttempts);
+    TS_ASSERT_EQUALS(!point, true);
   }
 
   void testVolumeOfCube() {
@@ -1087,18 +1089,18 @@ public:
   void test_generatePointInside_Convex_Solid() {
     const size_t npoints(6000);
     const size_t maxAttempts(500);
-    V3D point;
+    boost::optional<V3D> point;
     for (size_t i = 0; i < npoints; ++i) {
-      octahedron->generatePointInObject(rng, maxAttempts, point);
+      point = octahedron->generatePointInObject(rng, maxAttempts);
     }
   }
 
   void test_generatePointInside_NonConvex_Solid() {
     const size_t npoints(6000);
     const size_t maxAttempts(500);
-    V3D point;
+    boost::optional<V3D> point;
     for (size_t i = 0; i < npoints; ++i) {
-      lShape->generatePointInObject(rng, maxAttempts, point);
+      point = lShape->generatePointInObject(rng, maxAttempts);
     }
   }