diff --git a/modules/geom/pymod/export_composite3.cc b/modules/geom/pymod/export_composite3.cc
index 47988768cc7baf28cb4560895ad43cbdddb8e544..4a37c79f70939446f4a131a1e219ce7e6dc73a21 100644
--- a/modules/geom/pymod/export_composite3.cc
+++ b/modules/geom/pymod/export_composite3.cc
@@ -33,6 +33,7 @@ void export_Composite3()
     .def("GetDirection",&Line3::GetDirection)
     .add_property("origin", &Line3::GetOrigin)
     .add_property("direction", &Line3::GetDirection)
+    .def(self_ns::str(self))
   ;
 
 { // scope
@@ -169,6 +170,7 @@ scope PlaneScope =
          return_value_policy<copy_const_reference>()))
     .add_property("center", &AlignedCuboid::GetCenter)
     .add_property("size", &AlignedCuboid::GetSize)
+    .def(self_ns::str(self))
   ;
 }
 
diff --git a/modules/gfx/pymod/export_gfx_obj.cc b/modules/gfx/pymod/export_gfx_obj.cc
index 45093dd9bb8927e213c5af627babd19fe9d8f9ce..5f9ad7d1a4ecfc29a4b1aadf18b42c4d4f81e6e0 100644
--- a/modules/gfx/pymod/export_gfx_obj.cc
+++ b/modules/gfx/pymod/export_gfx_obj.cc
@@ -65,17 +65,17 @@ using namespace ost::gfx;
       GfxObj(name)
     {}
 
-    virtual geom::AlignedCuboid GetBoundingBox() const
+    virtual geom::AlignedCuboid GetBoundingBox(bool return_global=true) const
     {
       if(override f = this->get_override("GetBoundingBox")) {
-        return f();
+        return f(return_global);
       } else {
-        return GfxObj::GetBoundingBox();
+        return GfxObj::GetBoundingBox(return_global);
       }
     }
 
-    geom::AlignedCuboid default_GetBoundingBox() const {
-      return GfxObj::GetBoundingBox();
+    geom::AlignedCuboid default_GetBoundingBox(bool return_global) const {
+      return GfxObj::GetBoundingBox(return_global);
     }
 
     virtual void CustomRenderGL(RenderPass pass) {
@@ -175,7 +175,7 @@ void export_GfxObj()
     .def("GetAALines",&GfxObj::GetAALines)
     .def("GetLineWidth",&GfxObj::GetLineWidth)
     .def("GetLineHalo",&GfxObj::GetLineHalo)
-    .def("GetBoundingBox",&GfxObj::GetBoundingBox, &GfxObjWrap::default_GetBoundingBox)
+    .def("GetBoundingBox",&GfxObj::GetBoundingBox,&GfxObjWrap::default_GetBoundingBox)
     .def("_CustomRenderGL",&GfxObj::CustomRenderGL, &GfxObjWrap::default_CustomRenderGL)
     .def("_CustomPreRenderGL",&GfxObj::CustomPreRenderGL, &GfxObjWrap::default_CustomPreRenderGL)
     .def("_InitGL",&GfxObj::InitGL, &GfxObjWrap::default_InitGL)
diff --git a/modules/gfx/pymod/export_scene.cc b/modules/gfx/pymod/export_scene.cc
index 8b73a3391ec8a0a8ac5f4e41357b17738320d1d2..adaa52e479b97355f5d4adb0c2a6aa269302ff54 100644
--- a/modules/gfx/pymod/export_scene.cc
+++ b/modules/gfx/pymod/export_scene.cc
@@ -29,11 +29,12 @@ namespace {
 
 BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(scene_add_overloads, 
                                        Scene::Add, 1, 2)
-BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(scene_autoslab_overloads, 
-                                       Scene::Autoslab, 0, 2)
 BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(scene_export_pov_overloads,
                                        Scene::ExportPov, 1,2)
 void (Scene::*apply)(const InputEvent&, bool)=&Scene::Apply;
+void (Scene::*autoslab1)()=&Scene::Autoslab;
+void (Scene::*autoslab2)(bool)=&Scene::Autoslab;
+void (Scene::*autoslab3)(bool,bool)=&Scene::Autoslab;
 
 Scene* get_scene()
 {
@@ -49,6 +50,21 @@ GfxObjP scene_getitem(Scene* scene, const String& item)
   return scene->operator[](item);
 }
 
+geom::AlignedCuboid scene_get_bb1(Scene* scene)
+{
+  return scene->GetBoundingBox();
+}
+
+geom::AlignedCuboid scene_get_bb2(Scene* scene, bool use_tf)
+{
+  return scene->GetBoundingBox(use_tf);
+}
+
+geom::AlignedCuboid scene_get_bb3(Scene* scene, const mol::Transform& tf)
+{
+  return scene->GetBoundingBox(tf);
+}
+
 } // anon ns
 
 
@@ -80,11 +96,16 @@ void export_Scene()
   class_<Scene, boost::noncopyable>("SceneSingleton",no_init)
     .def("Add", &Scene::Add, 
          scene_add_overloads())
-    .def("Autoslab", &Scene::Autoslab, 
-         scene_autoslab_overloads())
+    .def("Autoslab", autoslab1)
     .def("AutoAutoslab",&Scene::AutoAutoslab)
     .def("GetAutoAutoslab",&Scene::GetAutoAutoslab)
-    .def("AutoslabMax",&Scene::AutoslabMax)
+    .add_property("auto_autoslab",&Scene::GetAutoAutoslab,&Scene::AutoAutoslab)
+    .def("SetAutoslabMode",&Scene::SetAutoslabMode)
+    .def("GetAutoslabMode",&Scene::GetAutoslabMode)
+    .add_property("autoslab_mode",&Scene::GetAutoslabMode,&Scene::SetAutoslabMode)
+    .def("Autoslab", autoslab2) // DEPRECATED
+    .def("Autoslab", autoslab3) // DEPRECATED
+    .def("AutoslabMax",&Scene::AutoslabMax) // DEPRECATED
     .def("Remove", remove1)
     .def("Remove", remove2)
     .add_property("viewport", &Scene::GetViewport)
@@ -202,5 +223,9 @@ void export_Scene()
     .def("__getitem__",scene_getitem)
     .add_property("show_center",&Scene::GetShowCenter, &Scene::SetShowCenter)
     .add_property("fix_center",&Scene::GetFixCenter, &Scene::SetFixCenter)
+    .def("GetBoundingBox",scene_get_bb1)
+    .def("GetBoundingBox",scene_get_bb2)
+    .def("GetBoundingBox",scene_get_bb3)
+    .add_property("bounding_box",scene_get_bb1)
   ;
 }
diff --git a/modules/gfx/src/entity.cc b/modules/gfx/src/entity.cc
index dff4bfa1fb8465036438a59ebdf8f72dc2a3277b..0154907216fc4940b726707307db806981cb7a2f 100644
--- a/modules/gfx/src/entity.cc
+++ b/modules/gfx/src/entity.cc
@@ -252,39 +252,11 @@ void Entity::UpdatePositions()
 
 
 
-geom::AlignedCuboid Entity::GetBoundingBox() const
+geom::AlignedCuboid Entity::GetBoundingBox(bool use_tf) const
 {
   this->UpdateIfNeeded();
-  return bbox_;
-}
-
-void Entity::ProcessLimits(geom::Vec3& minc, geom::Vec3& maxc, 
-                           const Transform& tf) const
-{
-  try {
-    geom::AlignedCuboid coord_limits=this->GetBoundingBox();
-    // update min/max by transforming all 8 corners of the bounding box and 
-    // comparing it against the current min/max
-    geom::Vec3 mmin=coord_limits.GetMin();
-    geom::Vec3 mmax=coord_limits.GetMax();
-    geom::Vec3 t1=tf.Apply(geom::Vec3(mmin[0], mmin[1], mmin[2]));
-    geom::Vec3 t2=tf.Apply(geom::Vec3(mmin[0], mmax[1], mmin[2]));
-    geom::Vec3 t3=tf.Apply(geom::Vec3(mmax[0], mmin[1], mmin[2]));
-    geom::Vec3 t4=tf.Apply(geom::Vec3(mmax[0], mmax[1], mmin[2]));
-    geom::Vec3 t5=tf.Apply(geom::Vec3(mmin[0], mmin[1], mmax[2]));
-    geom::Vec3 t6=tf.Apply(geom::Vec3(mmin[0], mmax[1], mmax[2]));
-    geom::Vec3 t7=tf.Apply(geom::Vec3(mmax[0], mmin[1], mmax[2]));
-    geom::Vec3 t8=tf.Apply(geom::Vec3(mmax[0], mmax[1], mmax[2]));
-    minc = geom::Min(minc, geom::Min(t1, geom::Min(t2, geom::Min(t3, 
-                     geom::Min(t4, geom::Min(t5, geom::Min(t6, 
-                     geom::Min(t7, t8))))))));
-    maxc = geom::Max(maxc, geom::Max(t1, geom::Max(t2, geom::Max(t3, 
-                     geom::Max(t4, geom::Max(t5, geom::Max(t6,
-                     geom::Max(t7, t8))))))));
-  } catch(Error& e) {
-    // in case the object is empty...
-  }
-} 
+  return use_tf ? transform_.Apply(bbox_) : bbox_;
+}
 
 void Entity::SetColorForAtom(const Color& col,
                              const AtomHandle& atom) 
diff --git a/modules/gfx/src/entity.hh b/modules/gfx/src/entity.hh
index 7663fe3782fe053df4eb7f0428d6401da26905c9..112a7ac4d8f5b5dbdd6db517a673b9ded7180a34 100644
--- a/modules/gfx/src/entity.hh
+++ b/modules/gfx/src/entity.hh
@@ -90,11 +90,10 @@ public:
          RenderMode::Type m,
          const mol::EntityView& ev);
 
-  virtual geom::AlignedCuboid GetBoundingBox() const;
-  
-  virtual void ProcessLimits(geom::Vec3& minc, geom::Vec3& maxc, 
-                             const mol::Transform& tf) const;
+  virtual geom::AlignedCuboid GetBoundingBox(bool use_global=false) const;
 
+  // ProcessLimits uses the default implementation of bounding box
+  
   /// internal routine
   virtual void CustomRenderGL(RenderPass pass);
 
diff --git a/modules/gfx/src/gfx_object.cc b/modules/gfx/src/gfx_object.cc
index 1f0486017c6139adc74134f712d72409486744cd..d527ceffabf5b805535a0dc1c796cd74b82ab19b 100644
--- a/modules/gfx/src/gfx_object.cc
+++ b/modules/gfx/src/gfx_object.cc
@@ -394,7 +394,7 @@ void GfxObj::ColorBy(const img::MapHandle& mh,
 //////////////////////////////////////////////////
 // and now for the rest of the GfxObj interface
 
-geom::AlignedCuboid GfxObj::GetBoundingBox() const
+geom::AlignedCuboid GfxObj::GetBoundingBox(bool use_tf) const
 {
   return geom::AlignedCuboid(geom::Vec3(),geom::Vec3());
 }
@@ -403,25 +403,11 @@ void GfxObj::ProcessLimits(geom::Vec3& minc, geom::Vec3& maxc,
                            const mol::Transform& tf) const
 {
   try {
-    geom::AlignedCuboid coord_limits=this->GetBoundingBox();
+    geom::AlignedCuboid coord_limits=tf.Apply(this->GetBoundingBox(true));
     // update min/max by transforming all 8 corners of the bounding box and 
     // comparing it against the current min/max
-    geom::Vec3 mmin=coord_limits.GetMin();
-    geom::Vec3 mmax=coord_limits.GetMax();
-    geom::Vec3 t1=tf.Apply(geom::Vec3(mmin[0], mmin[1], mmin[2]));
-    geom::Vec3 t2=tf.Apply(geom::Vec3(mmin[0], mmax[1], mmin[2]));
-    geom::Vec3 t3=tf.Apply(geom::Vec3(mmax[0], mmax[1], mmin[2]));
-    geom::Vec3 t4=tf.Apply(geom::Vec3(mmax[0], mmin[1], mmin[2]));
-    geom::Vec3 t5=tf.Apply(geom::Vec3(mmin[0], mmin[1], mmax[2]));
-    geom::Vec3 t6=tf.Apply(geom::Vec3(mmin[0], mmax[1], mmax[2]));
-    geom::Vec3 t7=tf.Apply(geom::Vec3(mmax[0], mmax[1], mmax[2]));
-    geom::Vec3 t8=tf.Apply(geom::Vec3(mmax[0], mmin[1], mmax[2]));
-    minc = geom::Min(minc, geom::Min(t1, geom::Min(t2, geom::Min(t3, 
-                     geom::Min(t4, geom::Min(t5, geom::Min(t6, 
-                     geom::Min(t7, t8))))))));
-    maxc = geom::Max(maxc, geom::Max(t1, geom::Max(t2, geom::Max(t3, 
-                     geom::Max(t4, geom::Max(t5, geom::Max(t6,
-                     geom::Max(t7, t8))))))));
+    minc=geom::Min(minc,coord_limits.GetMin());
+    maxc=geom::Min(maxc,coord_limits.GetMax());
   } catch(Error& e) {
     // in case the object is empty...
   }
diff --git a/modules/gfx/src/gfx_object.hh b/modules/gfx/src/gfx_object.hh
index d241be75e19f15158d173554f01384b26cdab15f..8809e1046fe10d15c410bc51f86545cc1bc32cf1 100644
--- a/modules/gfx/src/gfx_object.hh
+++ b/modules/gfx/src/gfx_object.hh
@@ -101,15 +101,27 @@ public:
 
   // new gfx obj virtual interface starts here
 
-  /// \brief returns the left-bottom-front and the right-top-back corner
-  /// that encompasses all graphical elements in this object
-  /// 
-  /// the bounding box is in local coordinates. to obtain the coordinates in
-  /// the scene, multiply the bounding box by the object's transformation
-  ///  matrix.
-  virtual geom::AlignedCuboid GetBoundingBox() const;
-
-  /// \brief adjust the given limits according to the represented data
+  /*!
+    \brief returns the bounding box of this object
+
+    The bounding box, i.e. the left-bottom-front and the right-top-back corner
+    of the object, is obtained with this method. The single boolean parameter
+    denotes whether to return local coordinates or global scene coordinates; 
+    global scene coordinates are local coordinates with the object's transformation
+    (if present) applied. The default is false, i.e. return local coordinates.
+  */
+  virtual geom::AlignedCuboid GetBoundingBox(bool use_tf=false) const;
+
+  /*!
+    \brief adjust minimum and maximum extent based on graphical object
+
+    this routine will adjust the provided minimum and maximum points
+    based on the vertices of the underlying graphical representation,
+    combining the given Transform with the object transform.
+
+    If derived classes do not implement this method then the limits
+    will be adjusted based on the Cuboid returned by GetBoundingBox(true)
+  */
   virtual void ProcessLimits(geom::Vec3& minc, geom::Vec3& maxc, 
                              const mol::Transform& tf) const;
 
diff --git a/modules/gfx/src/map_iso.cc b/modules/gfx/src/map_iso.cc
index 8e685e524215dabd1ff12b2abe28965829c2d7b8..5dbd4d3907c57964a3b21c0d9183e3e1917ccf2e 100644
--- a/modules/gfx/src/map_iso.cc
+++ b/modules/gfx/src/map_iso.cc
@@ -93,13 +93,13 @@ MapIso::MapIso(const String& name, const img::MapHandle& mh,
   Rebuild();
 }
 
-geom::AlignedCuboid MapIso::GetBoundingBox() const
+geom::AlignedCuboid MapIso::GetBoundingBox(bool use_tf) const
 {
   if(recalc_bb_) {
     bb_=va_.GetBoundingBox();
     recalc_bb_=false;
   }
-  return bb_;
+  return use_tf ? transform_.Apply(bb_) : bb_;
 }
 
 geom::Vec3 MapIso::GetCenter() const
diff --git a/modules/gfx/src/map_iso.hh b/modules/gfx/src/map_iso.hh
index 814dfa756399c592ddf3df72d3173e5c958a73c6..bb47a129c1d0b04d223387dba693fc89031b12a0 100644
--- a/modules/gfx/src/map_iso.hh
+++ b/modules/gfx/src/map_iso.hh
@@ -54,7 +54,7 @@ public:
   MapIso(const String& name, const img::MapHandle& mh,float level, uint a=0);
 
   /// returns bounding box of iso-contour object, not overall map
-  virtual geom::AlignedCuboid GetBoundingBox() const;
+  virtual geom::AlignedCuboid GetBoundingBox(bool use_global=false) const;
 
   /// returns center of iso-contour object, not overall map
   virtual geom::Vec3 GetCenter() const;
diff --git a/modules/gfx/src/scene.cc b/modules/gfx/src/scene.cc
index 1bd5e460742f0a774bd7e7d46eba5974b4804dd7..a123d3a2dd8f3aba0169763fb723a27e721f7d2c 100644
--- a/modules/gfx/src/scene.cc
+++ b/modules/gfx/src/scene.cc
@@ -115,7 +115,7 @@ Scene::Scene():
   fog_color_(0.0,0.0,0.0,0.0),
   auto_autoslab_(true),
   do_autoslab_(true),
-  do_autoslab_fast_(true),
+  autoslab_mode_(0),
   offscreen_flag_(false),
   main_offscreen_buffer_(0),
   old_vp_(),
@@ -843,7 +843,9 @@ void Scene::Add(const GfxNodeP& n, bool redraw)
     if(root_node_->GetChildCount()==0) {
       SetCenter(go->GetCenter());
     }
-    do_autoslab_=true;
+    if(auto_autoslab_) {
+      do_autoslab_=true;
+    }
   }
 
   root_node_->Add(n);
@@ -1201,18 +1203,11 @@ public:
   }
   void VisitObject(GfxObj* obj, const Stack& st) {
     if(obj->IsVisible()) {
-      geom::AlignedCuboid bb=obj->GetBoundingBox();
+      // use obj transform for BB calculation as well as provided global transform
+      geom::AlignedCuboid bb=tf.Apply(obj->GetBoundingBox(True));
       if(bb.GetVolume()>0.0) {
-        Vec3 t1 = tf.Apply(Vec3(bb.GetMin()[0],bb.GetMin()[1],bb.GetMin()[2]));
-        Vec3 t2 = tf.Apply(Vec3(bb.GetMin()[0],bb.GetMax()[1],bb.GetMin()[2]));
-        Vec3 t3 = tf.Apply(Vec3(bb.GetMax()[0],bb.GetMax()[1],bb.GetMin()[2]));
-        Vec3 t4 = tf.Apply(Vec3(bb.GetMax()[0],bb.GetMin()[1],bb.GetMin()[2]));
-        Vec3 t5 = tf.Apply(Vec3(bb.GetMin()[0],bb.GetMin()[1],bb.GetMax()[2]));
-        Vec3 t6 = tf.Apply(Vec3(bb.GetMin()[0],bb.GetMax()[1],bb.GetMax()[2]));
-        Vec3 t7 = tf.Apply(Vec3(bb.GetMax()[0],bb.GetMax()[1],bb.GetMax()[2]));
-        Vec3 t8 = tf.Apply(Vec3(bb.GetMax()[0],bb.GetMin()[1],bb.GetMax()[2]));
-        minc = Min(minc,Min(t1,Min(t2,Min(t3,Min(t4,Min(t5,Min(t6,Min(t7,t8))))))));
-        maxc = Max(maxc,Max(t1,Max(t2,Max(t3,Max(t4,Max(t5,Max(t6,Max(t7,t8))))))));
+        minc = Min(minc,bb.GetMin());
+        maxc = Max(maxc,bb.GetMax());
         valid=true;
       }
     }
@@ -1225,6 +1220,11 @@ public:
 
 }
 
+geom::AlignedCuboid Scene::GetBoundingBox(bool use_tf) const
+{
+  return GetBoundingBox(use_tf ? transform_ : mol::Transform());
+}
+
 geom::AlignedCuboid Scene::GetBoundingBox(const mol::Transform& tf) const
 {
   BBCalc bbcalc(Vec3(std::numeric_limits<float>::max(),
@@ -1706,16 +1706,30 @@ public:
 
 } // anon ns
 
+void Scene::Autoslab(bool fast)
+{
+  LOG_INFO("Autoslab(bool) is deprecated, use Autoslab() and SetAutoslabMode() instead");
+  do_autoslab_=true;
+  autoslab_mode_= fast ? 0 : 1;
+  RequestRedraw();
+}
+
 void Scene::Autoslab(bool fast, bool)
+{
+  LOG_INFO("Autoslab(bool,bool) is deprecated, use Autoslab() and SetAutoslabMode() instead");
+  Autoslab(fast);
+}
+
+void Scene::Autoslab()
 {
   do_autoslab_=true;
-  do_autoslab_fast_=fast;
   RequestRedraw();
 }
 
 void Scene::AutoslabMax()
 {
-  geom::AlignedCuboid bb =this->GetBoundingBox(transform_);
+  LOG_INFO("AutoslabMax() is deprecated, use Autoslab() and SetAutoslabMode() instead");
+  geom::AlignedCuboid bb =this->GetBoundingBox();
 
   if(bb.GetVolume()==0.0) {
     znear_=1;
@@ -2146,21 +2160,17 @@ void Scene::do_autoslab()
 {
   // skip autoslab if nothing to show yet
   if(root_node_->GetChildCount()==0) return;
-  if(do_autoslab_fast_) {
-    geom::AlignedCuboid bb =this->GetBoundingBox(transform_);
-    // necessary code duplication due to awkward slab limit impl
-    if(bb.GetVolume()==0.0) {
-      // skip if empty BB
-      return;
-    } else {
-      float mynear=-(bb.GetMax()[2])-1.0;
-      float myfar=-(bb.GetMin()[2])+1.0;
-      znear_=mynear;
-      zfar_=myfar;
-      set_near(mynear);
-      set_far(myfar);
+  float nnear=znear_;
+  float nfar=zfar_;
+  if(autoslab_mode_==0) {
+    // fast
+    geom::AlignedCuboid bb =this->GetBoundingBox();
+    if(bb.GetVolume()>0.0) {
+      nnear=-(bb.GetMax()[2])-1.0;
+      nfar=-(bb.GetMin()[2])+1.0;
     }
-  } else {
+  } else if (autoslab_mode_==1) {
+    // precise
     LimCalc limcalc;
     limcalc.transform=transform_;
     limcalc.minc = Vec3(std::numeric_limits<float>::max(),
@@ -2170,16 +2180,34 @@ void Scene::do_autoslab()
                               -std::numeric_limits<float>::max(),
                               -std::numeric_limits<float>::max());
     this->Apply(limcalc);
-    if(!limcalc.valid) {
-      return;
+    if(limcalc.valid) {
+      nnear=std::max(float(0.0), std::min(float(-limcalc.minc[2]),float(-limcalc.maxc[2])))-float(1.0);
+      nfar=std::max(float(-limcalc.minc[2]),float(-limcalc.maxc[2]))+float(1.0);
+    }
+  } else if(autoslab_mode_==2) {
+    // max
+    geom::AlignedCuboid bb =this->GetBoundingBox();
+
+    if(bb.GetVolume()>0.0) {
+      Vec3 cen = transform_.Apply(transform_.GetCenter());
+    
+      float bmax = std::max(std::abs(cen[0]-bb.GetMin()[0]),
+                            std::abs(cen[0]-bb.GetMax()[0]));
+      bmax = std::max(bmax,float(std::abs(cen[1]-bb.GetMin()[1])));
+      bmax = std::max(bmax,float(std::abs(cen[1]-bb.GetMax()[1])));
+      bmax = std::max(bmax,float(std::abs(cen[2]-bb.GetMin()[2])));
+      bmax = std::max(bmax,float(std::abs(cen[2]-bb.GetMax()[2])));
+      
+      nnear = -(cen[2]+bmax*1.5);
+      nfar = -(cen[2]-bmax*1.5);
     }
-    float mynear=std::max(float(0.0), std::min(float(-limcalc.minc[2]),float(-limcalc.maxc[2])))-float(1.0);
-    float myfar=std::max(float(-limcalc.minc[2]),float(-limcalc.maxc[2]))+float(1.0);
-    znear_=mynear;
-    zfar_=myfar;
-    set_near(mynear);
-    set_far(myfar);
   }
+
+  // necessary code duplication due to awkward slab limit impl
+  znear_=nnear;
+  zfar_=nfar;
+  set_near(nnear);
+  set_far(nfar);
   ResetProjection();
   RequestRedraw();
 }
diff --git a/modules/gfx/src/scene.hh b/modules/gfx/src/scene.hh
index a5868d0606581bff66c84b32b5d53f071bc44751..6912bfbfffb4d26ac9c8974ddee8a63b8756a6d8 100644
--- a/modules/gfx/src/scene.hh
+++ b/modules/gfx/src/scene.hh
@@ -180,20 +180,48 @@ class DLLEXPORT_OST_GFX Scene {
   /// \brief convenciene function to set fog near and far offset
   void SetFogOffsets(float no, float fo);
   
-  /// \brief adjust near and far clipping plane to fit visible objects
-  // TODO: use mode aka fast, precise, max
-  void Autoslab(bool fast=false, bool redraw=true);
+  /// DEPRECATED, use Autoslab() and SetAutoslabMode(int)
+  void Autoslab(bool fast);
 
-  /// \brief adjust clipping planes to fix maximal extent of all objects
-  ///        even under rotation
-  // TODO: merge with Autoslab
+  /// DEPRECATED, use Autoslab() and SetAutoslabMode(int)
+  void Autoslab(bool fast, bool);
+
+  /// DEPRECATED, use SetAutoslabMode(2)
   void AutoslabMax();
 
-  /// \brief turn on automatic auto-slabbing (using the fast bounding box alg)
-  // TODO: more sophisticated mode, aka fast, precise, max
+  /*!
+    \brief adjust near and far clipping plane to fit visible objects
+
+    Use autoslab mode to calculate near and far clipping places; this
+    does not need to be called explicitely if AutoAutoslab is active.
+    Uses the mode set by \ref SetAutoslabMode
+  */
+  void Autoslab();
+
+  /*!
+    \brief set autoslab mode
+
+    0: fast (default), using only the bounding box
+    1: precise, using each graphical element (not implemented)
+    2: max, using maximal extent upon rotation
+  */
+  void SetAutoslabMode(int mode) {
+    autoslab_mode_=std::min(2,std::max(0,mode));
+  }
+
+  /// \brief return current autoslab mode
+  int GetAutoslabMode() const {
+    return autoslab_mode_;
+  }
+
+  /*!
+    \brief turn automatic autoslab'bing on or off for each scene update
+
+    the current autoslab mode is honored \ref SetAutoslabMode(int)
+  */
   void AutoAutoslab(bool f);
   
-  /// \brief get current state of automatic auto-slabbing
+  /// \brief get current state of automatic autoslab'bing
   bool GetAutoAutoslab() const { return auto_autoslab_; }
 
   //@}
@@ -319,7 +347,15 @@ class DLLEXPORT_OST_GFX Scene {
   /// \brief calculate unprojected point out of the scene
   geom::Vec3 UnProject(const geom::Vec3& v, bool ignore_vp=false) const;
 
-  /// \brief return bounding box of scene under given transform
+  /// \brief return bounding box of scene
+  /*!
+    the sole boolean parameter determines whether or not the scene 
+    transformation is applied to calculate the bounding box. Since in
+    most cases it should be used, the default value is true.
+  */
+  geom::AlignedCuboid GetBoundingBox(bool use_tf=true) const;
+
+  /// \brief return bounding box of with a given transform
   geom::AlignedCuboid GetBoundingBox(const mol::Transform& tf) const;
 
   /// \brief get full underlying transformation
@@ -496,8 +532,9 @@ private:
   bool fix_cor_flag_;
   bool fog_flag_;
   Color fog_color_;
-  bool auto_autoslab_;
-  bool do_autoslab_,do_autoslab_fast_;
+  bool auto_autoslab_; // run autoslab on each scene update
+  bool do_autoslab_;   // run autoslab on next scene update
+  int autoslab_mode_;  // 0: fast, 1:precise, 2: max
 
   bool offscreen_flag_; // a simple indicator whether in offscreen mode or not
   OffscreenBuffer* main_offscreen_buffer_; // not null if a main offscreen buffer is present
diff --git a/modules/gfx/src/surface.cc b/modules/gfx/src/surface.cc
index 488375cf5b46ba29ee9e37c4c28f5368d750ad2c..0500e72b1482ae2ea32b7cd80fd3ee794a96e5bd 100644
--- a/modules/gfx/src/surface.cc
+++ b/modules/gfx/src/surface.cc
@@ -140,29 +140,32 @@ void Surface::Rebuild()
   recalc_bb_=true;
 }
 
-geom::AlignedCuboid Surface::GetBoundingBox() const
+geom::AlignedCuboid Surface::GetBoundingBox(bool use_tf) const
 {
-  static Vec3 minc,maxc;
+  static geom::AlignedCuboid bb;
   if(recalc_bb_) {
-    minc=Vec3(std::numeric_limits<float>::max(),
+    geom::Vec3 minc(std::numeric_limits<float>::max(),
                     std::numeric_limits<float>::max(),
                     std::numeric_limits<float>::max());
-    maxc=Vec3(-std::numeric_limits<float>::max(),
+    geom::Vec3 maxc(-std::numeric_limits<float>::max(),
                     -std::numeric_limits<float>::max(),
                     -std::numeric_limits<float>::max());
     
     std::vector<mol::SurfaceVertexID> svid_list = sh_.GetVertexIDList();
-    for(std::vector<mol::SurfaceVertexID>::const_iterator it=svid_list.begin();
-        it!=svid_list.end();++it) {
-      Vec3 pos = sh_.GetVertex(*it).position;
-      minc=Min(minc,pos);
-      maxc=Max(maxc,pos);
+    if(svid_list.size()>0) {
+      for(std::vector<mol::SurfaceVertexID>::const_iterator it=svid_list.begin();
+          it!=svid_list.end();++it) {
+        geom::Vec3 pos = sh_.GetVertex(*it).position;
+        minc=geom::Min(minc,pos);
+        maxc=geom::Max(maxc,pos);
+      }
+      minc-=geom::Vec3(1.0,1.0,1.0);
+      maxc+=geom::Vec3(1.0,1.0,1.0);
+      recalc_bb_=false;
+      bb=geom::AlignedCuboid(minc,maxc);
     }
-    minc-=Vec3(1.0,1.0,1.0);
-    maxc+=Vec3(1.0,1.0,1.0);
-    recalc_bb_=false;
   }
-  return geom::AlignedCuboid(minc,maxc);
+  return use_tf ? transform_.Apply(bb) : bb;
 }
 
 void Surface::CustomPreRenderGL(bool flag)
diff --git a/modules/gfx/src/surface.hh b/modules/gfx/src/surface.hh
index 740ae787fcb4c5f0550201ae36856c9d2ee07f4e..ff3ea292c6940cce040d5600aa370250f2868105 100644
--- a/modules/gfx/src/surface.hh
+++ b/modules/gfx/src/surface.hh
@@ -56,7 +56,7 @@ public:
 
   virtual void CustomRenderGL(RenderPass pass);
   virtual void CustomRenderPov(PovState& pov);
-  virtual geom::AlignedCuboid GetBoundingBox() const;
+  virtual geom::AlignedCuboid GetBoundingBox(bool use_global=false) const;
 
   mol::SurfaceHandle GetHandle() const;
 
diff --git a/modules/mol/base/src/transform.cc b/modules/mol/base/src/transform.cc
index c1ffbff6b8a34bf6016d01fba72deeba8a2f4fdb..d035bf2b9a0b9887f172f492fe7ed185ead7ac1f 100644
--- a/modules/mol/base/src/transform.cc
+++ b/modules/mol/base/src/transform.cc
@@ -164,6 +164,23 @@ Vec4 Transform::Apply(const Vec4& v) const
   return nrvo;
 }
 
+geom::AlignedCuboid Transform::Apply(const geom::AlignedCuboid& c) const
+{
+  geom::Vec3 cmin=c.GetMin();
+  geom::Vec3 cmax=c.GetMax();
+  Vec3 t1 = Apply(Vec3(cmin[0],cmin[1],cmin[2]));
+  Vec3 t2 = Apply(Vec3(cmin[0],cmax[1],cmin[2]));
+  Vec3 t3 = Apply(Vec3(cmax[0],cmax[1],cmin[2]));
+  Vec3 t4 = Apply(Vec3(cmax[0],cmin[1],cmin[2]));
+  Vec3 t5 = Apply(Vec3(cmin[0],cmin[1],cmax[2]));
+  Vec3 t6 = Apply(Vec3(cmin[0],cmax[1],cmax[2]));
+  Vec3 t7 = Apply(Vec3(cmax[0],cmax[1],cmax[2]));
+  Vec3 t8 = Apply(Vec3(cmax[0],cmin[1],cmax[2]));
+  geom::Vec3 minc = Min(t1,Min(t2,Min(t3,Min(t4,Min(t5,Min(t6,Min(t7,t8)))))));
+  geom::Vec3 maxc = Max(t1,Max(t2,Max(t3,Max(t4,Max(t5,Max(t6,Max(t7,t8)))))));
+  return geom::AlignedCuboid(minc,maxc);
+}
+
 /*
   The order of the transformations given herein is conceptually
   "backward" as they are applied to a vertex, because the left-right
diff --git a/modules/mol/base/src/transform.hh b/modules/mol/base/src/transform.hh
index 1ed33135e1ca1287f0e2c9debc151aeacca069cc..726b578a73f82ee27ab77c0303df8e31a41cc39d 100644
--- a/modules/mol/base/src/transform.hh
+++ b/modules/mol/base/src/transform.hh
@@ -73,6 +73,7 @@ public:
   
   geom::Vec3 Apply(const geom::Vec3& v) const;
   geom::Vec4 Apply(const geom::Vec4& v) const;
+  geom::AlignedCuboid Apply(const geom::AlignedCuboid& c) const;
 
 private:
   geom::Mat3 rot_;
@@ -84,6 +85,8 @@ private:
   void update_tm();
 };
 
+
+
 #if(OST_INFO_ENABLED)
 /// \brief read transformation from info group
 /// \relates Transform