diff --git a/modules/gfx/pymod/export_scene.cc b/modules/gfx/pymod/export_scene.cc
index 11d0f49d5d3f418c7f4531a3d4bba3b0b36c8192..b810b91225474ce769daf530ccb4e6af4e71f8a6 100644
--- a/modules/gfx/pymod/export_scene.cc
+++ b/modules/gfx/pymod/export_scene.cc
@@ -87,6 +87,10 @@ void scene_set_hemi_p(Scene* s, tuple p)
 
 } // anon ns
 
+void clear_scene() {
+  Scene::Instance().RemoveAll();
+}
+
 void export_Scene()
 {
   def("Scene",get_scene,return_value_policy<reference_existing_object>());
@@ -264,5 +268,15 @@ void export_Scene()
     .add_property("hemi_params",scene_get_hemi_p,scene_set_hemi_p)
   ;
 
-}
 
+// we need to make sure there are no pending references to Python objects
+// tied to the scene singleton. The destructor of 
+// scene may be called after Python is shutdown which results
+// in a segfault.
+scope().attr("__dict__")["atexit"]=handle<>(PyImport_ImportModule("atexit"));
+
+def("_clear_scene", &clear_scene);
+object r=scope().attr("_clear_scene");
+scope().attr("atexit").attr("register")(r);
+
+}
diff --git a/modules/gfx/src/scene.cc b/modules/gfx/src/scene.cc
index 7631d2123a74ecebd31d9a2c03b475d8adcfca21..9aeb22a01ef170a2bb0937034e1b26a4f0b999e2 100644
--- a/modules/gfx/src/scene.cc
+++ b/modules/gfx/src/scene.cc
@@ -151,6 +151,13 @@ Scene::Scene():
   transform_.SetTrans(Vec3(0,0,-100));
 }
 
+Scene::~Scene()
+{
+  // cleanup all observers / gfx_nodes when scene is destructed
+  observers_.clear();
+  this->RemoveAll();
+}
+
 void Scene::SetFog(bool f)
 {
   fog_flag_=f;
diff --git a/modules/gfx/src/scene.hh b/modules/gfx/src/scene.hh
index 4205263fc2f5a054dc5c0baae3e98bb18231d21e..adacb4ca9e307ca1c96ee664d91da85f5b7e3b1f 100644
--- a/modules/gfx/src/scene.hh
+++ b/modules/gfx/src/scene.hh
@@ -548,6 +548,7 @@ private:
   Scene();
   Scene(const Scene&) {}
   Scene& operator=(const Scene&) {return *this;}
+  ~Scene();
 
   // The GL Context gets typically handled externally, e.g. using QT when
   // calling InitGL(), RenderGL() etc. However, there is no guarantee that the