diff --git a/Examples/scatter2d/CustomFormFactor.py b/Examples/scatter2d/CustomFormFactor.py
index 23468b7e070144803dc355087828327ed47b32dd..5781665ed2a0a79f9143f0ab99bdb662c180e4d3 100755
--- a/Examples/scatter2d/CustomFormFactor.py
+++ b/Examples/scatter2d/CustomFormFactor.py
@@ -44,7 +44,7 @@ class CustomFormFactor(ba.IFormFactor):
                sinc(qzhH)*(sinc(0.5*qyhL)*(sinc(qxhL)-0.5*sinc(0.5*qxhL))+\
                sinc(0.5*qxhL)*sinc(qyhL))
 
-    def spanZ(self, rotation):
+    def exec_spanZ(self, rotation):
         return ba.Span(0, self.H)
 
 
diff --git a/Sample/HardParticle/IFormFactorPolyhedron.cpp b/Sample/HardParticle/IFormFactorPolyhedron.cpp
index 5c6946ee687e4b071484fdd6ab8261e347700ccd..fa056c952c58310169ee5b38362fe2e7119da2dd 100644
--- a/Sample/HardParticle/IFormFactorPolyhedron.cpp
+++ b/Sample/HardParticle/IFormFactorPolyhedron.cpp
@@ -63,7 +63,7 @@ double IFormFactorPolyhedron::radialExtension() const
     return pimpl->radius();
 }
 
-Span IFormFactorPolyhedron::spanZ(const IRotation* rotation) const
+Span IFormFactorPolyhedron::exec_spanZ(const IRotation* rotation) const
 {
     ASSERT(m_validated);
     return PolyhedralUtil::spanZ(m_vertices, rotation);
diff --git a/Sample/HardParticle/IFormFactorPolyhedron.h b/Sample/HardParticle/IFormFactorPolyhedron.h
index 60a38a129e24eac14af17987eb6a03c24fcfe1b0..bcf76ef6f4d15b85e660a71ddaf0ac53cf8d6d55 100644
--- a/Sample/HardParticle/IFormFactorPolyhedron.h
+++ b/Sample/HardParticle/IFormFactorPolyhedron.h
@@ -35,7 +35,6 @@ public:
 
     double volume() const override;
     double radialExtension() const override;
-    Span spanZ(const IRotation* rotation) const override;
 
     complex_t formfactor_at_bottom(C3 q) const override;
 
@@ -48,6 +47,9 @@ protected:
     mutable std::unique_ptr<ff::Polyhedron> pimpl;
     mutable std::vector<R3> m_vertices; //! for topZ, bottomZ computation only
     mutable double m_z_bottom;
+
+private:
+    Span exec_spanZ(const IRotation* rotation) const override;
 };
 
 #endif // BORNAGAIN_SAMPLE_HARDPARTICLE_IFORMFACTORPOLYHEDRON_H
diff --git a/Sample/HardParticle/IFormFactorPrism.cpp b/Sample/HardParticle/IFormFactorPrism.cpp
index b145739646af8f171490397073777d72398ac680..c5b274d4ca13b12a65851d8fecefcc81bcdbce14 100644
--- a/Sample/HardParticle/IFormFactorPrism.cpp
+++ b/Sample/HardParticle/IFormFactorPrism.cpp
@@ -49,7 +49,7 @@ double IFormFactorPrism::radialExtension() const
     return pimpl->radius();
 }
 
-Span IFormFactorPrism::spanZ(const IRotation* rotation) const
+Span IFormFactorPrism::exec_spanZ(const IRotation* rotation) const
 {
     ASSERT(m_validated);
     return PolyhedralUtil::spanZ(m_vertices, rotation);
diff --git a/Sample/HardParticle/IFormFactorPrism.h b/Sample/HardParticle/IFormFactorPrism.h
index d3a61a636cbdfa5896b115c2ce92525d93f3027e..206c8bfaa5b501dde0dd3e72b4383352dfb73583 100644
--- a/Sample/HardParticle/IFormFactorPrism.h
+++ b/Sample/HardParticle/IFormFactorPrism.h
@@ -36,7 +36,6 @@ public:
     double volume() const override;
     double radialExtension() const override;
     virtual double height() const = 0;
-    Span spanZ(const IRotation* rotation) const override;
 
     complex_t formfactor_at_bottom(C3 q) const override;
 
@@ -50,6 +49,8 @@ protected:
 private:
     mutable std::unique_ptr<ff::Prism> pimpl;
     mutable std::vector<R3> m_vertices; //! for topZ, bottomZ computation only
+
+    Span exec_spanZ(const IRotation* rotation) const override;
 };
 
 #endif // BORNAGAIN_SAMPLE_HARDPARTICLE_IFORMFACTORPRISM_H
diff --git a/Sample/HardParticle/Sphere.cpp b/Sample/HardParticle/Sphere.cpp
index 8d975f7d0a936a2fd8d20c2f2df4da723e5161c8..4fe052104296b17d96c77bad173f4212e6b19d10 100644
--- a/Sample/HardParticle/Sphere.cpp
+++ b/Sample/HardParticle/Sphere.cpp
@@ -33,7 +33,7 @@ Sphere::Sphere(double radius, bool position_at_center)
 {
 }
 
-Span Sphere::spanZ(const IRotation* rotation) const
+Span Sphere::exec_spanZ(const IRotation* rotation) const
 {
     if (m_position_at_center)
         return {-m_radius, +m_radius};
diff --git a/Sample/HardParticle/Sphere.h b/Sample/HardParticle/Sphere.h
index 0b8656ec29938b3e97962acdc5ca532a712f22bb..a628eec115c081485218134fa4829a855770a642 100644
--- a/Sample/HardParticle/Sphere.h
+++ b/Sample/HardParticle/Sphere.h
@@ -49,8 +49,6 @@ public:
         return m_radius;
     }
 
-    Span spanZ(const IRotation* rotation) const override;
-
     complex_t formfactor_at_bottom(C3 q) const override;
 
     std::string validate() const override;
@@ -62,6 +60,8 @@ protected:
     }
 
 private:
+    Span exec_spanZ(const IRotation* rotation) const override;
+
     const double& m_radius;
     bool m_position_at_center;
 #endif // USER_API
diff --git a/Sample/Particle/IFormFactor.cpp b/Sample/Particle/IFormFactor.cpp
index 88d1a739b7a62fd476af4ddb3e2b4c50e3015bc3..68e4ee60adb622e702551acd2b6fbf103c1dabec 100644
--- a/Sample/Particle/IFormFactor.cpp
+++ b/Sample/Particle/IFormFactor.cpp
@@ -37,6 +37,11 @@ double IFormFactor::volume() const
 }
 
 Span IFormFactor::spanZ(const IRotation* rotation) const
+{
+    return exec_spanZ(rotation);
+}
+
+Span IFormFactor::exec_spanZ(const IRotation* rotation) const
 {
     if (!m_shape3D)
         throw std::runtime_error("Bug: Form factor has no m_shape3D, cannot compute top z");
diff --git a/Sample/Particle/IFormFactor.h b/Sample/Particle/IFormFactor.h
index 58087ed4897aca1eb05e2439c4a27390f65f82de..16c71a8897018dcc1589d3bcc799a4c8e6c1a212 100644
--- a/Sample/Particle/IFormFactor.h
+++ b/Sample/Particle/IFormFactor.h
@@ -48,7 +48,7 @@ public:
     //! form factor's shape. This is used for SSCA calculations
     virtual double radialExtension() const = 0;
 
-    virtual Span spanZ(const IRotation* rotation) const;
+    Span spanZ(const IRotation* rotation) const;
 
     //! Creates the Python constructor of this class (or derived classes)
     std::string pythonConstructor() const;
@@ -67,6 +67,8 @@ public:
     virtual complex_t formfactor_at_bottom(C3 q) const = 0;
 
 protected:
+    virtual Span exec_spanZ(const IRotation* rotation) const;
+
     //! IShape3D object, used to retrieve vertices (which may be approximate in the case
     //! of round shapes). For soft particles, this will be a hard mean shape.
     mutable std::unique_ptr<IShape3D> m_shape3D;
diff --git a/auto/Wrap/libBornAgainSample.py b/auto/Wrap/libBornAgainSample.py
index 3bacadf9b305b57c649608762ad2b25b8df5fa9f..29ebc0fd499f8a0d8e1eb5ba6b5908a7e2d88530 100644
--- a/auto/Wrap/libBornAgainSample.py
+++ b/auto/Wrap/libBornAgainSample.py
@@ -2690,6 +2690,10 @@ class IFormFactor(ISampleNode):
     def formfactor_at_bottom(self, q):
         r"""formfactor_at_bottom(IFormFactor self, C3 q) -> complex_t"""
         return _libBornAgainSample.IFormFactor_formfactor_at_bottom(self, q)
+
+    def exec_spanZ(self, rotation):
+        r"""exec_spanZ(IFormFactor self, IRotation rotation) -> Span"""
+        return _libBornAgainSample.IFormFactor_exec_spanZ(self, rotation)
     def __disown__(self):
         self.this.disown()
         _libBornAgainSample.disown_IFormFactor(self)
@@ -4708,10 +4712,6 @@ class IFormFactorPolyhedron(IFormFactor):
         r"""radialExtension(IFormFactorPolyhedron self) -> double"""
         return _libBornAgainSample.IFormFactorPolyhedron_radialExtension(self)
 
-    def spanZ(self, rotation):
-        r"""spanZ(IFormFactorPolyhedron self, IRotation rotation) -> Span"""
-        return _libBornAgainSample.IFormFactorPolyhedron_spanZ(self, rotation)
-
     def formfactor_at_bottom(self, q):
         r"""formfactor_at_bottom(IFormFactorPolyhedron self, C3 q) -> complex_t"""
         return _libBornAgainSample.IFormFactorPolyhedron_formfactor_at_bottom(self, q)
@@ -4740,10 +4740,6 @@ class IFormFactorPrism(IFormFactor):
         r"""height(IFormFactorPrism self) -> double"""
         return _libBornAgainSample.IFormFactorPrism_height(self)
 
-    def spanZ(self, rotation):
-        r"""spanZ(IFormFactorPrism self, IRotation rotation) -> Span"""
-        return _libBornAgainSample.IFormFactorPrism_spanZ(self, rotation)
-
     def formfactor_at_bottom(self, q):
         r"""formfactor_at_bottom(IFormFactorPrism self, C3 q) -> complex_t"""
         return _libBornAgainSample.IFormFactorPrism_formfactor_at_bottom(self, q)
@@ -5331,10 +5327,6 @@ class Sphere(IFormFactor):
         r"""radialExtension(Sphere self) -> double"""
         return _libBornAgainSample.Sphere_radialExtension(self)
 
-    def spanZ(self, rotation):
-        r"""spanZ(Sphere self, IRotation rotation) -> Span"""
-        return _libBornAgainSample.Sphere_spanZ(self, rotation)
-
     def formfactor_at_bottom(self, q):
         r"""formfactor_at_bottom(Sphere self, C3 q) -> complex_t"""
         return _libBornAgainSample.Sphere_formfactor_at_bottom(self, q)
diff --git a/auto/Wrap/libBornAgainSample_wrap.cpp b/auto/Wrap/libBornAgainSample_wrap.cpp
index cd1405ca702805e98e2ffd535dd83c91da547d06..bde7a89dd8c82599092864b731a4ccb9608d08d5 100644
--- a/auto/Wrap/libBornAgainSample_wrap.cpp
+++ b/auto/Wrap/libBornAgainSample_wrap.cpp
@@ -8027,103 +8027,105 @@ double SwigDirector_IFormFactor::radialExtension() const {
 }
 
 
-Span SwigDirector_IFormFactor::spanZ(IRotation const *rotation) const {
-  void *swig_argp ;
-  int swig_res = 0 ;
+bool SwigDirector_IFormFactor::canSliceAnalytically(IRotation const *rot) const {
+  bool c_result = SwigValueInit< bool >() ;
   
-  Span c_result;
   swig::SwigVar_PyObject obj0;
-  obj0 = SWIG_NewPointerObj(SWIG_as_voidptr(rotation), SWIGTYPE_p_IRotation,  0 );
+  obj0 = SWIG_NewPointerObj(SWIG_as_voidptr(rot), SWIGTYPE_p_IRotation,  0 );
   if (!swig_get_self()) {
     Swig::DirectorException::raise("'self' uninitialized, maybe you forgot to call IFormFactor.__init__.");
   }
 #if defined(SWIG_PYTHON_DIRECTOR_VTABLE)
   const size_t swig_method_index = 9;
-  const char *const swig_method_name = "spanZ";
+  const char *const swig_method_name = "canSliceAnalytically";
   PyObject *method = swig_get_method(swig_method_index, swig_method_name);
   swig::SwigVar_PyObject result = PyObject_CallFunctionObjArgs(method ,(PyObject *)obj0, NULL);
 #else
-  swig::SwigVar_PyObject swig_method_name = SWIG_Python_str_FromChar("spanZ");
+  swig::SwigVar_PyObject swig_method_name = SWIG_Python_str_FromChar("canSliceAnalytically");
   swig::SwigVar_PyObject result = PyObject_CallMethodObjArgs(swig_get_self(), (PyObject *) swig_method_name ,(PyObject *)obj0, NULL);
 #endif
   if (!result) {
     PyObject *error = PyErr_Occurred();
     if (error) {
-      Swig::DirectorMethodException::raise("Error detected when calling 'IFormFactor.spanZ'");
+      Swig::DirectorMethodException::raise("Error detected when calling 'IFormFactor.canSliceAnalytically'");
     }
   }
-  swig_res = SWIG_ConvertPtr(result,&swig_argp,SWIGTYPE_p_Span,  0  | 0);
+  bool swig_val;
+  int swig_res = SWIG_AsVal_bool(result, &swig_val);
   if (!SWIG_IsOK(swig_res)) {
-    Swig::DirectorTypeMismatchException::raise(SWIG_ErrorType(SWIG_ArgError(swig_res)), "in output value of type '""Span""'");
+    Swig::DirectorTypeMismatchException::raise(SWIG_ErrorType(SWIG_ArgError(swig_res)), "in output value of type '""bool""'");
   }
-  c_result = *(reinterpret_cast< Span * >(swig_argp));
-  if (SWIG_IsNewObj(swig_res)) delete reinterpret_cast< Span * >(swig_argp);
-  return (Span) c_result;
+  c_result = static_cast< bool >(swig_val);
+  return (bool) c_result;
 }
 
 
-bool SwigDirector_IFormFactor::canSliceAnalytically(IRotation const *rot) const {
-  bool c_result = SwigValueInit< bool >() ;
-  
+complex_t SwigDirector_IFormFactor::formfactor_at_bottom(C3 q) const {
+  complex_t c_result;
   swig::SwigVar_PyObject obj0;
-  obj0 = SWIG_NewPointerObj(SWIG_as_voidptr(rot), SWIGTYPE_p_IRotation,  0 );
+  obj0 = SWIG_NewPointerObj((new C3(SWIG_STD_MOVE(q))), SWIGTYPE_p_Vec3T_std__complexT_double_t_t, SWIG_POINTER_OWN |  0 );
   if (!swig_get_self()) {
     Swig::DirectorException::raise("'self' uninitialized, maybe you forgot to call IFormFactor.__init__.");
   }
 #if defined(SWIG_PYTHON_DIRECTOR_VTABLE)
   const size_t swig_method_index = 10;
-  const char *const swig_method_name = "canSliceAnalytically";
+  const char *const swig_method_name = "formfactor_at_bottom";
   PyObject *method = swig_get_method(swig_method_index, swig_method_name);
   swig::SwigVar_PyObject result = PyObject_CallFunctionObjArgs(method ,(PyObject *)obj0, NULL);
 #else
-  swig::SwigVar_PyObject swig_method_name = SWIG_Python_str_FromChar("canSliceAnalytically");
+  swig::SwigVar_PyObject swig_method_name = SWIG_Python_str_FromChar("formfactor_at_bottom");
   swig::SwigVar_PyObject result = PyObject_CallMethodObjArgs(swig_get_self(), (PyObject *) swig_method_name ,(PyObject *)obj0, NULL);
 #endif
   if (!result) {
     PyObject *error = PyErr_Occurred();
     if (error) {
-      Swig::DirectorMethodException::raise("Error detected when calling 'IFormFactor.canSliceAnalytically'");
+      Swig::DirectorMethodException::raise("Error detected when calling 'IFormFactor.formfactor_at_bottom'");
     }
   }
-  bool swig_val;
-  int swig_res = SWIG_AsVal_bool(result, &swig_val);
+  std::complex<double> swig_val;
+  int swig_res = SWIG_AsVal_std_complex_Sl_double_Sg_(result, &swig_val);
   if (!SWIG_IsOK(swig_res)) {
-    Swig::DirectorTypeMismatchException::raise(SWIG_ErrorType(SWIG_ArgError(swig_res)), "in output value of type '""bool""'");
+    Swig::DirectorTypeMismatchException::raise(SWIG_ErrorType(SWIG_ArgError(swig_res)), "in output value of type '""complex_t""'");
   }
-  c_result = static_cast< bool >(swig_val);
-  return (bool) c_result;
+  c_result = static_cast< complex_t >(swig_val);
+  return (complex_t) c_result;
 }
 
 
-complex_t SwigDirector_IFormFactor::formfactor_at_bottom(C3 q) const {
-  complex_t c_result;
+Span SwigDirector_IFormFactor::exec_spanZ(IRotation const *rotation) const {
+  void *swig_argp ;
+  int swig_res = 0 ;
+  
+  Span c_result;
   swig::SwigVar_PyObject obj0;
-  obj0 = SWIG_NewPointerObj((new C3(SWIG_STD_MOVE(q))), SWIGTYPE_p_Vec3T_std__complexT_double_t_t, SWIG_POINTER_OWN |  0 );
+  obj0 = SWIG_NewPointerObj(SWIG_as_voidptr(rotation), SWIGTYPE_p_IRotation,  0 );
+  swig_set_inner("exec_spanZ", true);
   if (!swig_get_self()) {
     Swig::DirectorException::raise("'self' uninitialized, maybe you forgot to call IFormFactor.__init__.");
   }
 #if defined(SWIG_PYTHON_DIRECTOR_VTABLE)
   const size_t swig_method_index = 11;
-  const char *const swig_method_name = "formfactor_at_bottom";
+  const char *const swig_method_name = "exec_spanZ";
   PyObject *method = swig_get_method(swig_method_index, swig_method_name);
   swig::SwigVar_PyObject result = PyObject_CallFunctionObjArgs(method ,(PyObject *)obj0, NULL);
 #else
-  swig::SwigVar_PyObject swig_method_name = SWIG_Python_str_FromChar("formfactor_at_bottom");
+  swig::SwigVar_PyObject swig_method_name = SWIG_Python_str_FromChar("exec_spanZ");
   swig::SwigVar_PyObject result = PyObject_CallMethodObjArgs(swig_get_self(), (PyObject *) swig_method_name ,(PyObject *)obj0, NULL);
 #endif
+  swig_set_inner("exec_spanZ", false);
   if (!result) {
     PyObject *error = PyErr_Occurred();
     if (error) {
-      Swig::DirectorMethodException::raise("Error detected when calling 'IFormFactor.formfactor_at_bottom'");
+      Swig::DirectorMethodException::raise("Error detected when calling 'IFormFactor.exec_spanZ'");
     }
   }
-  std::complex<double> swig_val;
-  int swig_res = SWIG_AsVal_std_complex_Sl_double_Sg_(result, &swig_val);
+  swig_res = SWIG_ConvertPtr(result,&swig_argp,SWIGTYPE_p_Span,  0  | 0);
   if (!SWIG_IsOK(swig_res)) {
-    Swig::DirectorTypeMismatchException::raise(SWIG_ErrorType(SWIG_ArgError(swig_res)), "in output value of type '""complex_t""'");
+    Swig::DirectorTypeMismatchException::raise(SWIG_ErrorType(SWIG_ArgError(swig_res)), "in output value of type '""Span""'");
   }
-  c_result = static_cast< complex_t >(swig_val);
-  return (complex_t) c_result;
+  c_result = *(reinterpret_cast< Span * >(swig_argp));
+  if (SWIG_IsNewObj(swig_res)) delete reinterpret_cast< Span * >(swig_argp);
+  return (Span) c_result;
 }
 
 
@@ -34090,8 +34092,6 @@ SWIGINTERN PyObject *_wrap_IFormFactor_spanZ(PyObject *self, PyObject *args) {
   void *argp2 = 0 ;
   int res2 = 0 ;
   PyObject *swig_obj[2] ;
-  Swig::Director *director = 0;
-  bool upcall = false;
   Span result;
   
   if (!SWIG_Python_UnpackTuple(args, "IFormFactor_spanZ", 2, 2, swig_obj)) SWIG_fail;
@@ -34105,17 +34105,7 @@ SWIGINTERN PyObject *_wrap_IFormFactor_spanZ(PyObject *self, PyObject *args) {
     SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "IFormFactor_spanZ" "', argument " "2"" of type '" "IRotation const *""'"); 
   }
   arg2 = reinterpret_cast< IRotation * >(argp2);
-  director = SWIG_DIRECTOR_CAST(arg1);
-  upcall = (director && (director->swig_get_self()==swig_obj[0]));
-  try {
-    if (upcall) {
-      result = ((IFormFactor const *)arg1)->IFormFactor::spanZ((IRotation const *)arg2);
-    } else {
-      result = ((IFormFactor const *)arg1)->spanZ((IRotation const *)arg2);
-    }
-  } catch (Swig::DirectorException&) {
-    SWIG_fail;
-  }
+  result = ((IFormFactor const *)arg1)->spanZ((IRotation const *)arg2);
   resultobj = SWIG_NewPointerObj((new Span(result)), SWIGTYPE_p_Span, SWIG_POINTER_OWN |  0 );
   return resultobj;
 fail:
@@ -34342,6 +34332,54 @@ fail:
 }
 
 
+SWIGINTERN PyObject *_wrap_IFormFactor_exec_spanZ(PyObject *self, PyObject *args) {
+  PyObject *resultobj = 0;
+  IFormFactor *arg1 = (IFormFactor *) 0 ;
+  IRotation *arg2 = (IRotation *) 0 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+  void *argp2 = 0 ;
+  int res2 = 0 ;
+  PyObject *swig_obj[2] ;
+  Swig::Director *director = 0;
+  bool upcall = false;
+  SwigDirector_IFormFactor *darg = 0;
+  Span result;
+  
+  if (!SWIG_Python_UnpackTuple(args, "IFormFactor_exec_spanZ", 2, 2, swig_obj)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_IFormFactor, 0 |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IFormFactor_exec_spanZ" "', argument " "1"" of type '" "IFormFactor const *""'"); 
+  }
+  arg1 = reinterpret_cast< IFormFactor * >(argp1);
+  res2 = SWIG_ConvertPtr(swig_obj[1], &argp2,SWIGTYPE_p_IRotation, 0 |  0 );
+  if (!SWIG_IsOK(res2)) {
+    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "IFormFactor_exec_spanZ" "', argument " "2"" of type '" "IRotation const *""'"); 
+  }
+  arg2 = reinterpret_cast< IRotation * >(argp2);
+  director = SWIG_DIRECTOR_CAST(arg1);
+  if (!director || !(director->swig_get_inner("exec_spanZ"))) {
+    SWIG_SetErrorMsg(PyExc_RuntimeError,"accessing protected member exec_spanZ");
+    SWIG_fail;
+  }
+  upcall = (director && (director->swig_get_self()==swig_obj[0]));
+  try {
+    darg = dynamic_cast<SwigDirector_IFormFactor *>(arg1);
+    if (upcall) {
+      result = ((SwigDirector_IFormFactor const *)darg)->exec_spanZSwigPublic((IRotation const *)arg2);
+    } else {
+      result = ((SwigDirector_IFormFactor const *)darg)->exec_spanZ((IRotation const *)arg2);
+    }
+  } catch (Swig::DirectorException&) {
+    SWIG_fail;
+  }
+  resultobj = SWIG_NewPointerObj((new Span(result)), SWIGTYPE_p_Span, SWIG_POINTER_OWN |  0 );
+  return resultobj;
+fail:
+  return NULL;
+}
+
+
 SWIGINTERN PyObject *_wrap_disown_IFormFactor(PyObject *self, PyObject *args) {
   PyObject *resultobj = 0;
   IFormFactor *arg1 = (IFormFactor *) 0 ;
@@ -48105,36 +48143,6 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_IFormFactorPolyhedron_spanZ(PyObject *self, PyObject *args) {
-  PyObject *resultobj = 0;
-  IFormFactorPolyhedron *arg1 = (IFormFactorPolyhedron *) 0 ;
-  IRotation *arg2 = (IRotation *) 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  void *argp2 = 0 ;
-  int res2 = 0 ;
-  PyObject *swig_obj[2] ;
-  Span result;
-  
-  if (!SWIG_Python_UnpackTuple(args, "IFormFactorPolyhedron_spanZ", 2, 2, swig_obj)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_IFormFactorPolyhedron, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IFormFactorPolyhedron_spanZ" "', argument " "1"" of type '" "IFormFactorPolyhedron const *""'"); 
-  }
-  arg1 = reinterpret_cast< IFormFactorPolyhedron * >(argp1);
-  res2 = SWIG_ConvertPtr(swig_obj[1], &argp2,SWIGTYPE_p_IRotation, 0 |  0 );
-  if (!SWIG_IsOK(res2)) {
-    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "IFormFactorPolyhedron_spanZ" "', argument " "2"" of type '" "IRotation const *""'"); 
-  }
-  arg2 = reinterpret_cast< IRotation * >(argp2);
-  result = ((IFormFactorPolyhedron const *)arg1)->spanZ((IRotation const *)arg2);
-  resultobj = SWIG_NewPointerObj((new Span(result)), SWIGTYPE_p_Span, SWIG_POINTER_OWN |  0 );
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
 SWIGINTERN PyObject *_wrap_IFormFactorPolyhedron_formfactor_at_bottom(PyObject *self, PyObject *args) {
   PyObject *resultobj = 0;
   IFormFactorPolyhedron *arg1 = (IFormFactorPolyhedron *) 0 ;
@@ -48271,36 +48279,6 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_IFormFactorPrism_spanZ(PyObject *self, PyObject *args) {
-  PyObject *resultobj = 0;
-  IFormFactorPrism *arg1 = (IFormFactorPrism *) 0 ;
-  IRotation *arg2 = (IRotation *) 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  void *argp2 = 0 ;
-  int res2 = 0 ;
-  PyObject *swig_obj[2] ;
-  Span result;
-  
-  if (!SWIG_Python_UnpackTuple(args, "IFormFactorPrism_spanZ", 2, 2, swig_obj)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_IFormFactorPrism, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IFormFactorPrism_spanZ" "', argument " "1"" of type '" "IFormFactorPrism const *""'"); 
-  }
-  arg1 = reinterpret_cast< IFormFactorPrism * >(argp1);
-  res2 = SWIG_ConvertPtr(swig_obj[1], &argp2,SWIGTYPE_p_IRotation, 0 |  0 );
-  if (!SWIG_IsOK(res2)) {
-    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "IFormFactorPrism_spanZ" "', argument " "2"" of type '" "IRotation const *""'"); 
-  }
-  arg2 = reinterpret_cast< IRotation * >(argp2);
-  result = ((IFormFactorPrism const *)arg1)->spanZ((IRotation const *)arg2);
-  resultobj = SWIG_NewPointerObj((new Span(result)), SWIGTYPE_p_Span, SWIG_POINTER_OWN |  0 );
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
 SWIGINTERN PyObject *_wrap_IFormFactorPrism_formfactor_at_bottom(PyObject *self, PyObject *args) {
   PyObject *resultobj = 0;
   IFormFactorPrism *arg1 = (IFormFactorPrism *) 0 ;
@@ -52245,36 +52223,6 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_Sphere_spanZ(PyObject *self, PyObject *args) {
-  PyObject *resultobj = 0;
-  Sphere *arg1 = (Sphere *) 0 ;
-  IRotation *arg2 = (IRotation *) 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  void *argp2 = 0 ;
-  int res2 = 0 ;
-  PyObject *swig_obj[2] ;
-  Span result;
-  
-  if (!SWIG_Python_UnpackTuple(args, "Sphere_spanZ", 2, 2, swig_obj)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_Sphere, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Sphere_spanZ" "', argument " "1"" of type '" "Sphere const *""'"); 
-  }
-  arg1 = reinterpret_cast< Sphere * >(argp1);
-  res2 = SWIG_ConvertPtr(swig_obj[1], &argp2,SWIGTYPE_p_IRotation, 0 |  0 );
-  if (!SWIG_IsOK(res2)) {
-    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "Sphere_spanZ" "', argument " "2"" of type '" "IRotation const *""'"); 
-  }
-  arg2 = reinterpret_cast< IRotation * >(argp2);
-  result = ((Sphere const *)arg1)->spanZ((IRotation const *)arg2);
-  resultobj = SWIG_NewPointerObj((new Span(result)), SWIGTYPE_p_Span, SWIG_POINTER_OWN |  0 );
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
 SWIGINTERN PyObject *_wrap_Sphere_formfactor_at_bottom(PyObject *self, PyObject *args) {
   PyObject *resultobj = 0;
   Sphere *arg1 = (Sphere *) 0 ;
@@ -61855,6 +61803,7 @@ static PyMethodDef SwigMethods[] = {
 	 { "IFormFactor_thePolFF", _wrap_IFormFactor_thePolFF, METH_VARARGS, "IFormFactor_thePolFF(IFormFactor self, WavevectorInfo const & wavevectors) -> SpinMatrix"},
 	 { "IFormFactor_formfactor_pol", _wrap_IFormFactor_formfactor_pol, METH_VARARGS, "IFormFactor_formfactor_pol(IFormFactor self, C3 q) -> SpinMatrix"},
 	 { "IFormFactor_formfactor_at_bottom", _wrap_IFormFactor_formfactor_at_bottom, METH_VARARGS, "IFormFactor_formfactor_at_bottom(IFormFactor self, C3 q) -> complex_t"},
+	 { "IFormFactor_exec_spanZ", _wrap_IFormFactor_exec_spanZ, METH_VARARGS, "IFormFactor_exec_spanZ(IFormFactor self, IRotation rotation) -> Span"},
 	 { "disown_IFormFactor", _wrap_disown_IFormFactor, METH_O, NULL},
 	 { "IFormFactor_swigregister", IFormFactor_swigregister, METH_O, NULL},
 	 { "IFormFactor_swiginit", IFormFactor_swiginit, METH_VARARGS, NULL},
@@ -62427,14 +62376,12 @@ static PyMethodDef SwigMethods[] = {
 	 { "delete_IFormFactorPolyhedron", _wrap_delete_IFormFactorPolyhedron, METH_O, "delete_IFormFactorPolyhedron(IFormFactorPolyhedron self)"},
 	 { "IFormFactorPolyhedron_volume", _wrap_IFormFactorPolyhedron_volume, METH_O, "IFormFactorPolyhedron_volume(IFormFactorPolyhedron self) -> double"},
 	 { "IFormFactorPolyhedron_radialExtension", _wrap_IFormFactorPolyhedron_radialExtension, METH_O, "IFormFactorPolyhedron_radialExtension(IFormFactorPolyhedron self) -> double"},
-	 { "IFormFactorPolyhedron_spanZ", _wrap_IFormFactorPolyhedron_spanZ, METH_VARARGS, "IFormFactorPolyhedron_spanZ(IFormFactorPolyhedron self, IRotation rotation) -> Span"},
 	 { "IFormFactorPolyhedron_formfactor_at_bottom", _wrap_IFormFactorPolyhedron_formfactor_at_bottom, METH_VARARGS, "IFormFactorPolyhedron_formfactor_at_bottom(IFormFactorPolyhedron self, C3 q) -> complex_t"},
 	 { "IFormFactorPolyhedron_swigregister", IFormFactorPolyhedron_swigregister, METH_O, NULL},
 	 { "delete_IFormFactorPrism", _wrap_delete_IFormFactorPrism, METH_O, "delete_IFormFactorPrism(IFormFactorPrism self)"},
 	 { "IFormFactorPrism_volume", _wrap_IFormFactorPrism_volume, METH_O, "IFormFactorPrism_volume(IFormFactorPrism self) -> double"},
 	 { "IFormFactorPrism_radialExtension", _wrap_IFormFactorPrism_radialExtension, METH_O, "IFormFactorPrism_radialExtension(IFormFactorPrism self) -> double"},
 	 { "IFormFactorPrism_height", _wrap_IFormFactorPrism_height, METH_O, "IFormFactorPrism_height(IFormFactorPrism self) -> double"},
-	 { "IFormFactorPrism_spanZ", _wrap_IFormFactorPrism_spanZ, METH_VARARGS, "IFormFactorPrism_spanZ(IFormFactorPrism self, IRotation rotation) -> Span"},
 	 { "IFormFactorPrism_formfactor_at_bottom", _wrap_IFormFactorPrism_formfactor_at_bottom, METH_VARARGS, "IFormFactorPrism_formfactor_at_bottom(IFormFactorPrism self, C3 q) -> complex_t"},
 	 { "IFormFactorPrism_swigregister", IFormFactorPrism_swigregister, METH_O, NULL},
 	 { "IProfileRipple_length", _wrap_IProfileRipple_length, METH_O, "IProfileRipple_length(IProfileRipple self) -> double"},
@@ -62615,7 +62562,6 @@ static PyMethodDef SwigMethods[] = {
 	 { "Sphere_parDefs", _wrap_Sphere_parDefs, METH_O, "Sphere_parDefs(Sphere self) -> std::vector< ParaMeta,std::allocator< ParaMeta > >"},
 	 { "Sphere_radius", _wrap_Sphere_radius, METH_O, "Sphere_radius(Sphere self) -> double"},
 	 { "Sphere_radialExtension", _wrap_Sphere_radialExtension, METH_O, "Sphere_radialExtension(Sphere self) -> double"},
-	 { "Sphere_spanZ", _wrap_Sphere_spanZ, METH_VARARGS, "Sphere_spanZ(Sphere self, IRotation rotation) -> Span"},
 	 { "Sphere_formfactor_at_bottom", _wrap_Sphere_formfactor_at_bottom, METH_VARARGS, "Sphere_formfactor_at_bottom(Sphere self, C3 q) -> complex_t"},
 	 { "Sphere_validate", _wrap_Sphere_validate, METH_O, "Sphere_validate(Sphere self) -> std::string"},
 	 { "delete_Sphere", _wrap_delete_Sphere, METH_O, "delete_Sphere(Sphere self)"},
diff --git a/auto/Wrap/libBornAgainSample_wrap.h b/auto/Wrap/libBornAgainSample_wrap.h
index fd3118b95011063248fcf4f21b4912ff604c0553..a9876ffc2cc64f02b47aed23522b475ee06a0107 100644
--- a/auto/Wrap/libBornAgainSample_wrap.h
+++ b/auto/Wrap/libBornAgainSample_wrap.h
@@ -77,9 +77,12 @@ public:
     virtual Material const *material() const;
     virtual double volume() const;
     virtual double radialExtension() const;
-    virtual Span spanZ(IRotation const *rotation) const;
     virtual bool canSliceAnalytically(IRotation const *rot) const;
     virtual complex_t formfactor_at_bottom(C3 q) const;
+    virtual Span exec_spanZ(IRotation const *rotation) const;
+    virtual Span exec_spanZSwigPublic(IRotation const *rotation) const {
+      return IFormFactor::exec_spanZ(rotation);
+    }
 
 /* Internal director utilities */
 public: