diff --git a/modules/gfx/pymod/CMakeLists.txt b/modules/gfx/pymod/CMakeLists.txt
index 210cce509623565695582e20969f818e8f2e042d..386dba45cfc14e32c41471e35407b62c2999d33a 100644
--- a/modules/gfx/pymod/CMakeLists.txt
+++ b/modules/gfx/pymod/CMakeLists.txt
@@ -14,6 +14,7 @@ set(OST_GFX_PYMOD_SOURCES
   export_gradient.cc
   export_color_ops.cc
   export_glwin_base.cc
+  export_exporter.cc
 )
 
 if (ENABLE_IMG)
diff --git a/modules/gfx/pymod/export_exporter.cc b/modules/gfx/pymod/export_exporter.cc
new file mode 100644
index 0000000000000000000000000000000000000000..655fe54f77282e2d6656142addf51e18006d7f7c
--- /dev/null
+++ b/modules/gfx/pymod/export_exporter.cc
@@ -0,0 +1,38 @@
+//------------------------------------------------------------------------------
+// This file is part of the OpenStructure project <www.openstructure.org>
+//
+// Copyright (C) 2008-2011 by the OpenStructure authors
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License as published by the Free
+// Software Foundation; either version 3.0 of the License, or (at your option)
+// any later version.
+// This library is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+// FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
+// details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with this library; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+//------------------------------------------------------------------------------
+#include <boost/python.hpp>
+using namespace boost::python;
+
+#include <ost/gfx/exporter.hh>
+#include <ost/gfx/gost_exporter.hh>
+#include <ost/gfx/collada_exporter.hh>
+
+using namespace ost;
+using namespace ost::gfx;
+
+void export_Exporter()
+{
+  class_<Exporter, boost::noncopyable>("Exporter", no_init);
+
+  class_<GostExporter, bases<Exporter>, boost::noncopyable>("GostExporter", init<const std::string&>())
+    ;
+
+  class_<ColladaExporter, bases<Exporter>, boost::noncopyable>("ColladaExporter", init<const std::string&, optional<float> >())
+    ;
+}
diff --git a/modules/gfx/pymod/export_primitives.cc b/modules/gfx/pymod/export_primitives.cc
index 91ce753ed91df2006caf3928438d4ed1937032cc..01b328d7288116ab8c6dcd9e7d86c5c3ad97fb07 100644
--- a/modules/gfx/pymod/export_primitives.cc
+++ b/modules/gfx/pymod/export_primitives.cc
@@ -25,8 +25,7 @@ using namespace ost::gfx;
 
 void export_primitives()
 {
-  class_<Primitive, boost::shared_ptr<Primitive>, 
-         bases<GfxNode>, boost::noncopyable>("Primitive", no_init)
+  class_<Primitive, bases<GfxNode>, boost::noncopyable>("Primitive", no_init)
     .def("HasOutline", &Primitive::HasOutline)
     .def("HasFill", &Primitive::HasFill)    
     .def("SetFill", &Primitive::SetFill)
@@ -40,10 +39,10 @@ void export_primitives()
     .def("GetOutlineColor", &Primitive::GetOutlineColor,
          return_value_policy<copy_const_reference>())
   ;
-  class_<Cuboid, boost::shared_ptr<Cuboid>, bases<Primitive>, 
+  class_<Cuboid, bases<Primitive>, 
          boost::noncopyable>("Cuboid", init<const String&, const geom::Cuboid>())
   ; 
-  class_<Quad, boost::shared_ptr<Quad>, bases<Primitive>, 
+  class_<Quad, bases<Primitive>, 
        boost::noncopyable>("Quad", init<const String&, const geom::Vec3&,
                                         const geom::Vec3&, const geom::Vec3&,
                                         const geom::Vec3&>())
diff --git a/modules/gfx/pymod/export_scene.cc b/modules/gfx/pymod/export_scene.cc
index f5692fad5b197d02c94f024add51392e78f72b2b..6e40adce4eb487dd36d48335571948a50b2e47b8 100644
--- a/modules/gfx/pymod/export_scene.cc
+++ b/modules/gfx/pymod/export_scene.cc
@@ -21,6 +21,7 @@ using namespace boost::python;
 
 #include <ost/gfx/gfx_object.hh>
 #include <ost/gfx/scene.hh>
+#include <ost/gfx/exporter.hh>
 using namespace ost;
 using namespace ost::gfx;
 
@@ -63,6 +64,7 @@ void export_Scene()
 
   void (Scene::* export1)(const String&, uint, uint, bool) = &Scene::Export;
   void (Scene::* export2)(const String&, bool) = &Scene::Export;
+  void (Scene::* export3)(Exporter*) const = &Scene::Export;
   void (Scene::*remove1)(const GfxNodeP&) = &Scene::Remove;
   void (Scene::*remove2)(const String&) = &Scene::Remove;
   void (Scene::*center_on1)(const String&) = &Scene::CenterOn;
@@ -161,6 +163,7 @@ void export_Scene()
     .def("Apply", apply)
     .def("Export",export1, arg("transparent")=true)
     .def("Export",export2, arg("transparent")=true)
+    .def("Export",export3)
     .def("ExportPov",&Scene::ExportPov,
          scene_export_pov_overloads())
     .def("PushView",&Scene::PushView)
diff --git a/modules/gfx/pymod/wrap_gfx.cc b/modules/gfx/pymod/wrap_gfx.cc
index 0198d3a0fb27ae5869ff572b9335e6580737b8e9..28229edf12ada259a25443f363d43db51199291d 100644
--- a/modules/gfx/pymod/wrap_gfx.cc
+++ b/modules/gfx/pymod/wrap_gfx.cc
@@ -37,6 +37,8 @@ extern void export_primlist();
 extern void export_primitives();
 extern void export_color();
 extern void export_gradient();
+extern void export_Exporter();
+
 #if OST_IMG_ENABLED
   extern void export_Map();
 #endif
@@ -135,6 +137,8 @@ BOOST_PYTHON_MODULE(_ost_gfx)
     ;
 #endif
 
+  export_primitives();
+  export_Exporter();
 }
 
 
diff --git a/modules/gfx/src/CMakeLists.txt b/modules/gfx/src/CMakeLists.txt
index 4f23812fd1120c170b45ff54ace477657314d9f2..9309a6af7ebec7fed643e303a732bf1b0c53b4ab 100644
--- a/modules/gfx/src/CMakeLists.txt
+++ b/modules/gfx/src/CMakeLists.txt
@@ -1,6 +1,7 @@
 set(OST_GFX_HEADERS
 render_pass.hh
 bitmap_io.hh
+collada_exporter.hh
 color.hh
 entity.hh
 entity_fw.hh
@@ -37,6 +38,9 @@ module_config.hh
 primitives.hh
 povray_fw.hh
 povray.hh
+exporter.hh
+exporter_fw.hh
+gost_exporter.hh
 )
 
 set(OST_GFX_COLOR_OPS_HEADERS
@@ -89,6 +93,7 @@ endif()
 
 set(OST_GFX_SOURCES
 bitmap_io.cc
+collada_exporter.cc
 color.cc
 primitives.cc
 entity.cc
@@ -108,6 +113,7 @@ vertex_array.cc
 vertex_array_helper.cc
 material.cc
 povray.cc
+gost_exporter.cc
 texture.cc
 color_ops/color_op.cc
 color_ops/by_element_color_op.cc
diff --git a/modules/gfx/src/collada_exporter.cc b/modules/gfx/src/collada_exporter.cc
new file mode 100644
index 0000000000000000000000000000000000000000..902334f851fc0df651f58f380e3c3771e8ae1e96
--- /dev/null
+++ b/modules/gfx/src/collada_exporter.cc
@@ -0,0 +1,279 @@
+//------------------------------------------------------------------------------
+// This file is part of the OpenStructure project <www.openstructure.org>
+//
+// Copyright (C) 2008-2011 by the OpenStructure authors
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License as published by the Free
+// Software Foundation; either version 3.0 of the License, or (at your option)
+// any later version.
+// This library is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+// FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
+// details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with this library; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+//------------------------------------------------------------------------------
+
+/*
+  Author: Ansgar Philippsen
+*/
+
+#include <sstream>
+#include <boost/format.hpp>
+
+#include "collada_exporter.hh"
+#include "scene.hh"
+
+namespace ost { namespace gfx {
+
+ColladaExporter::ColladaExporter(const std::string& file, float scale):
+  file_(file),
+  out_(file_.c_str()),
+  scale_(scale),
+  obj_()
+{
+  out_ << "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n";
+  out_ << "<COLLADA version=\"1.4.0\" xmlns=\"http://www.collada.org/2005/11/COLLADASchema\">\n";
+}
+
+ColladaExporter::~ColladaExporter()
+{
+  out_ << "</COLLADA>\n";
+}
+
+void ColladaExporter::SceneStart(const Scene* scene)
+{
+  out_ << " <library_cameras>\n";
+	out_ << "  <camera id=\"Camera-Camera\" name=\"Camera-Camera\">\n";
+  out_ << "   <optics>\n";
+  out_ << "    <technique_common>\n";
+  out_ << "      <perspective>\n";
+  out_ << "       <yfov>" << scene->GetFOV() << "</yfov>\n";
+  out_ << "       <znear>" << scene->GetNear() << "</znear>\n";
+  out_ << "       <zfar>" << scene->GetFar() << "</zfar>\n";
+  out_ << "      </perspective>\n";
+  out_ << "    </technique_common>\n";
+  out_ << "   </optics>\n";
+	out_ << "  </camera>\n";
+  out_ << " </library_cameras>\n";
+
+  out_ << " <library_geometries>\n" << std::endl;
+}
+
+void ColladaExporter::SceneEnd(const Scene* scene)
+{
+  out_ << " </library_geometries>\n" << std::endl;
+
+  out_ << " <library_visual_scenes>\n";
+  out_ << "  <visual_scene id=\"Scene\" name=\"Scene\">\n";
+
+  out_ << "   <node id=\"Camera\" name=\"Camera\">\n";
+  out_ << "    <instance_camera url=\"#Camera-Camera\"/>\n";
+  out_ << "   </node>\n";
+
+  out_ << "   <node id=\"Root\" name=\"Root\">\n";
+  out_ << "    <matrix>\n";
+  geom::Mat4 tm=scene->GetTransform().GetMatrix();
+  out_ << "    " << tm(0,0) << " " << tm(0,1) << " " << tm(0,2) << " " << tm(0,3) << "\n";
+  out_ << "    " << tm(1,0) << " " << tm(1,1) << " " << tm(1,2) << " " << tm(1,3) << "\n";
+  out_ << "    " << tm(2,0) << " " << tm(2,1) << " " << tm(2,2) << " " << tm(2,3) << "\n";
+  out_ << "    " << tm(3,0) << " " << tm(3,1) << " " << tm(3,2) << " " << tm(3,3) << "\n";
+  out_ << "    </matrix>\n";
+  for(std::vector<std::string>::const_iterator oit=obj_.begin();oit!=obj_.end();++oit) {
+    out_ << "    <node id=\"" << *oit << "\" name=\"" << *oit <<"\">\n";
+    out_ << "     <instance_geometry url=\"#" << *oit << "\"/>\n";
+    out_ << "    </node>\n";
+  }
+  out_ << "   </node>\n";
+  out_ << "  </visual_scene>\n";
+	out_ << " </library_visual_scenes>\n";
+
+	out_ << " <scene>\n";
+  out_ << "  <instance_visual_scene url=\"#Scene\"/>\n";
+	out_ << " </scene>\n";
+}
+
+void ColladaExporter::NodeStart(const std::string& name, NodeType t)
+{
+  if(name!="Scene") {
+    obj_.push_back(name);
+    out_ << "<geometry id=\"" << name << "\" name=\"" << name << "\">\n";
+    out_ << " <mesh>\n";
+  }
+}
+
+void ColladaExporter::NodeEnd(const std::string& name)
+{
+  if(name!="Scene") {
+    out_ << " </mesh>\n";
+    out_ << "</geometry>\n";
+  }
+}
+
+void ColladaExporter::WriteVertexData(const float* vdata,
+                                      const float* ndata, 
+                                      const float* cdata,
+                                      const float* tdata,
+                                      size_t stride2, size_t count)
+{
+  std::string name=obj_.back();
+  size_t stride=stride2/sizeof(float);
+
+  out_ << "  <source id=\"" << name+"-Positions" << "\">\n";
+  out_ << "   <float_array count=\"" << count*3 << "\" id=\"" << name+"-Positions-array" << "\">\n";
+  if(vdata) {
+    const float* src=vdata;
+    for(unsigned int i=0;i<count;++i) {
+      out_ << scale_*src[0] << " ";
+      out_ << scale_*src[1] << " ";
+      out_ << scale_*src[2] << " ";
+      src+=stride;
+    }
+  } else {
+    for(unsigned int i=0;i<count;++i) {
+      out_ << "0.0 0.0 0.0 ";
+    }
+  }
+  out_ << "   </float_array>\n";
+  out_ << "   <technique_common>\n";
+  out_ << "    <accessor count=\"" << count << "\" source=\"#" << name + "-Positions-array" << "\" stride=\"3\">\n";
+  out_ << "     <param name=\"X\" type=\"float\"/>\n";
+  out_ << "     <param name=\"Y\" type=\"float\"/>\n";
+  out_ << "     <param name=\"Z\" type=\"float\"/>\n";
+  out_ << "    </accessor>\n";
+  out_ << "   </technique_common>\n";
+  out_ << "  </source>\n";
+
+  // normals, lots of code duplication for now
+  out_ << "  <source id=\"" << name+"-Normals" << "\">\n";
+  out_ << "   <float_array count=\"" << count*3 << "\" id=\"" << name+"-Normals-array" << "\">\n";
+  if(ndata) {
+    const float* src=ndata;
+    for(unsigned int i=0;i<count;++i) {
+      out_ << src[0] << " ";
+      out_ << src[1] << " ";
+      out_ << src[2] << " ";
+      src+=stride;
+    }
+  } else {
+    for(unsigned int i=0;i<count;++i) {
+      out_ << "0.0 0.0 0.0 ";
+    }
+  }
+  out_ << "   </float_array>\n";
+  out_ << "   <technique_common>\n";
+  out_ << "    <accessor count=\"" << count << "\" source=\"#" << name + "-Normals-array" << "\" stride=\"3\">\n";
+  out_ << "     <param name=\"X\" type=\"float\"/>\n";
+  out_ << "     <param name=\"Y\" type=\"float\"/>\n";
+  out_ << "     <param name=\"Z\" type=\"float\"/>\n";
+  out_ << "    </accessor>\n";
+  out_ << "   </technique_common>\n";
+  out_ << "  </source>\n";
+
+  // colors, again lots of code duplication
+  out_ << "  <source id=\"" << name+"-Colors" << "\">\n";
+  //out_ << "   <float_array count=\"" << count*4 << "\" id=\"" << name+"-Colors-array" << "\">\n";
+  out_ << "   <float_array count=\"" << count*3 << "\" id=\"" << name+"-Colors-array" << "\">\n";
+  if(cdata) {
+    const float* src=cdata;
+    for(unsigned int i=0;i<count;++i) {
+      out_ << src[0] << " ";
+      out_ << src[1] << " ";
+      out_ << src[2] << " ";
+      //out_ << src[3] << " ";
+      src+=stride;
+    }
+  } else {
+    for(unsigned int i=0;i<count;++i) {
+      out_ << "0.0 0.0 0.0 ";
+    }
+  }
+  out_ << "   </float_array>\n";
+  out_ << "   <technique_common>\n";
+  //out_ << "    <accessor count=\"" << count << "\" source=\"#" << name + "-Colors-array" << "\" stride=\"4\">\n";
+  out_ << "    <accessor count=\"" << count << "\" source=\"#" << name + "-Colors-array" << "\" stride=\"3\">\n";
+  out_ << "     <param name=\"R\" type=\"float\"/>\n";
+  out_ << "     <param name=\"G\" type=\"float\"/>\n";
+  out_ << "     <param name=\"B\" type=\"float\"/>\n";
+  //out_ << "     <param name=\"A\" type=\"float\"/>\n";
+  out_ << "    </accessor>\n";
+  out_ << "   </technique_common>\n";
+  out_ << "  </source>\n";
+
+  out_ << "  <vertices id=\"" << name+"-Vertex" << "\">\n";
+  out_ << "   <input semantic=\"POSITION\" source =\"#" << name+"-Positions" << "\"/>\n";
+  //out_ << "   <input semantic=\"NORMAL\" source =\"#" << name+"-Normals" << "\"/>\n";
+  //out_ << "   <input semantic=\"COLOR\" source =\"#" << name+"-Colors" << "\"/>\n";
+  out_ << "  </vertices>\n";
+}
+
+void ColladaExporter::WritePointData(const unsigned int* i, size_t count)
+{
+}
+
+void ColladaExporter::WriteLineData(const unsigned int* ij, size_t count)
+{
+}
+
+void ColladaExporter::WriteTriData(const unsigned int* ijk, size_t count)
+{
+  std::string name=obj_.back();
+
+  out_ << "  <triangles count=\"" << count << "\">\n";
+  out_ << "   <input offset=\"0\" semantic=\"VERTEX\" source =\"#" << name+"-Vertex" << "\"/>\n";
+  out_ << "   <input offset=\"1\" semantic=\"NORMAL\" source =\"#" << name+"-Normals" << "\"/>\n";
+  out_ << "   <input offset=\"2\" semantic=\"COLOR\" source =\"#" << name+"-Colors" << "\"/>\n";
+  out_ << "   <p>\n";
+  for(unsigned int c=0;c<count*3;c+=3) {
+    out_ << ijk[c+0] << " ";
+    out_ << ijk[c+0] << " ";
+    out_ << ijk[c+0] << " ";
+    out_ << ijk[c+1] << " ";
+    out_ << ijk[c+1] << " ";
+    out_ << ijk[c+1] << " ";
+    out_ << ijk[c+2] << " ";
+    out_ << ijk[c+2] << " ";
+    out_ << ijk[c+2] << " ";
+  }
+  out_ << "   </p>\n";
+  out_ << "  </triangles>\n";
+}
+
+void ColladaExporter::WriteQuadData(const unsigned int* ijkl, size_t count)
+{
+  std::string name=obj_.back();
+
+  out_ << "  <triangles count=\"" << count << "\">\n";
+  out_ << "   <input offset=\"0\" semantic=\"VERTEX\" source =\"#" << name+"-Vertex" << "\"/>\n";
+  out_ << "   <input offset=\"1\" semantic=\"NORMAL\" source =\"#" << name+"-Normals" << "\"/>\n";
+  out_ << "   <input offset=\"2\" semantic=\"COLOR\" source =\"#" << name+"-Colors" << "\"/>\n";
+  out_ << "   <p>\n";
+  for(unsigned int c=0;c<count*4;c+=4) {
+    out_ << ijkl[c+0] << " ";
+    out_ << ijkl[c+0] << " ";
+    out_ << ijkl[c+0] << " ";
+    out_ << ijkl[c+1] << " ";
+    out_ << ijkl[c+1] << " ";
+    out_ << ijkl[c+1] << " ";
+    out_ << ijkl[c+2] << " ";
+    out_ << ijkl[c+2] << " ";
+    out_ << ijkl[c+2] << " ";
+    //
+    out_ << ijkl[c+0] << " ";
+    out_ << ijkl[c+0] << " ";
+    out_ << ijkl[c+0] << " ";
+    out_ << ijkl[c+2] << " ";
+    out_ << ijkl[c+2] << " ";
+    out_ << ijkl[c+2] << " ";
+    out_ << ijkl[c+3] << " ";
+    out_ << ijkl[c+3] << " ";
+    out_ << ijkl[c+3] << " ";
+  }
+  out_ << "   </p>\n";
+  out_ << "  </triangles>\n";
+}
+
+}} // ns
diff --git a/modules/gfx/src/collada_exporter.hh b/modules/gfx/src/collada_exporter.hh
new file mode 100644
index 0000000000000000000000000000000000000000..c0192a10097e6cb0d2b48801431a3be2437509d5
--- /dev/null
+++ b/modules/gfx/src/collada_exporter.hh
@@ -0,0 +1,62 @@
+//------------------------------------------------------------------------------
+// This file is part of the OpenStructure project <www.openstructure.org>
+//
+// Copyright (C) 2008-2011 by the OpenStructure authors
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License as published by the Free
+// Software Foundation; either version 3.0 of the License, or (at your option)
+// any later version.
+// This library is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+// FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
+// details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with this library; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+//------------------------------------------------------------------------------
+#ifndef OST_GFX_COLLADA_EXPORTER_HH
+#define OST_GFX_COLLADA_EXPORTER_HH
+
+/*
+  Author: Ansgar Philippsen
+*/
+
+#include <string>
+#include <fstream>
+#include <vector>
+
+#include "module_config.hh"
+#include "exporter.hh"
+
+namespace ost { namespace gfx {
+
+class DLLEXPORT_OST_GFX ColladaExporter: public Exporter
+{
+public:
+  ColladaExporter(const std::string& collada_file, float scale=1.0);
+  virtual ~ColladaExporter();
+
+  // exporter interface
+  virtual void SceneStart(const Scene* scene);
+  virtual void SceneEnd(const Scene* scene);
+  virtual void NodeStart(const std::string& name, NodeType t);
+  virtual void NodeEnd(const std::string& name);
+  virtual void WriteVertexData(const float* v, const float* n, const float* c, const float* t, 
+                               size_t stride, size_t count);
+  virtual void WritePointData(const unsigned int* i, size_t count);
+  virtual void WriteLineData(const unsigned int* ij, size_t count);
+  virtual void WriteTriData(const unsigned int* ijk, size_t count);
+  virtual void WriteQuadData(const unsigned int* ijkl, size_t count);
+
+private:
+  std::string file_;
+  std::ofstream out_;
+  float scale_;
+  std::vector<std::string> obj_;
+};
+
+}} // ns
+
+#endif
diff --git a/modules/gfx/src/entity.cc b/modules/gfx/src/entity.cc
index b5f0f6b75c4e6d516caa1bcffa28c26fbbe45ac8..dff4bfa1fb8465036438a59ebdf8f72dc2a3277b 100644
--- a/modules/gfx/src/entity.cc
+++ b/modules/gfx/src/entity.cc
@@ -54,6 +54,7 @@
 #if OST_SHADER_SUPPORT_ENABLED
 #include "shader.hh"
 #endif
+#include "exporter.hh"
 
 namespace ost {
 
@@ -401,6 +402,23 @@ void Entity::CustomRenderPov(PovState& pov)
   }
 }
 
+void Entity::Export(Exporter* ex)
+{
+  ex->NodeStart(GetName(),Exporter::OBJ);
+  // in the simplest case, just export va
+  if(rebuild_ || refresh_) {
+    PreRenderGL(true);
+  }
+
+  for (RendererMap::iterator it=renderer_.begin(); it!=renderer_.end(); ++it) {
+    if(it->second->IsEnabled() && it->second->HasDataToRender()){
+      it->second->Export(ex);
+    }
+  }
+  
+  ex->NodeEnd(GetName());
+}
+
 mol::AtomHandle Entity::PickAtom(const geom::Line3& line, Real line_width)
 {
   mol::AtomHandle picked_atom;
diff --git a/modules/gfx/src/entity.hh b/modules/gfx/src/entity.hh
index 7e6d595fa27f0e34c7d4e7eff73732f28dbca6a6..7663fe3782fe053df4eb7f0428d6401da26905c9 100644
--- a/modules/gfx/src/entity.hh
+++ b/modules/gfx/src/entity.hh
@@ -324,6 +324,8 @@ public:
   void SetSeqHack(bool b);
   bool GetSeqHack() const;
   
+  virtual void Export(Exporter* ex);
+
 protected:
 
   virtual void CustomPreRenderGL(bool flag);
diff --git a/modules/gfx/src/exporter.hh b/modules/gfx/src/exporter.hh
new file mode 100644
index 0000000000000000000000000000000000000000..20b0601aee6a110a4c713a687db50d4834c5978c
--- /dev/null
+++ b/modules/gfx/src/exporter.hh
@@ -0,0 +1,56 @@
+//------------------------------------------------------------------------------
+// This file is part of the OpenStructure project <www.openstructure.org>
+//
+// Copyright (C) 2008-2011 by the OpenStructure authors
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License as published by the Free
+// Software Foundation; either version 3.0 of the License, or (at your option)
+// any later version.
+// This library is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+// FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
+// details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with this library; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+//------------------------------------------------------------------------------
+#ifndef OST_GFX_EXPORTER_HH
+#define OST_GFX_EXPORTER_HH
+
+#include <ost/gfx/module_config.hh>
+
+namespace ost { namespace gfx {
+
+class Scene;
+
+class DLLEXPORT_OST_GFX Exporter
+{
+public:
+  enum NodeType {
+    ROOT=1,
+    GROUP=2,
+    OBJ=3
+  };
+
+  virtual ~Exporter() {}
+  virtual void SceneStart(const Scene* scene) {}
+  virtual void SceneEnd(const Scene* scene) {}
+
+  virtual void NodeStart(const std::string& name, NodeType t) {}
+  virtual void NodeEnd(const std::string& name) {}
+  
+  // this indicates beginning of new data, including a reset of the indices
+  // may occur more than once for a given node
+  virtual void WriteVertexData(const float* v, const float* n, const float* c, const float* t,
+                               size_t stride, size_t count) {}
+  virtual void WritePointData(const unsigned int* i, size_t count) {}
+  virtual void WriteLineData(const unsigned int* ij, size_t count) {}
+  virtual void WriteTriData(const unsigned int* ijk, size_t count) {}
+  virtual void WriteQuadData(const unsigned int* ijkl, size_t count) {}
+};
+
+}} // ns
+
+#endif
diff --git a/modules/gfx/src/exporter_fw.hh b/modules/gfx/src/exporter_fw.hh
new file mode 100644
index 0000000000000000000000000000000000000000..499248014e24d9df5374569c7a66d5227a4c8443
--- /dev/null
+++ b/modules/gfx/src/exporter_fw.hh
@@ -0,0 +1,28 @@
+//------------------------------------------------------------------------------
+// This file is part of the OpenStructure project <www.openstructure.org>
+//
+// Copyright (C) 2008-2011 by the OpenStructure authors
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License as published by the Free
+// Software Foundation; either version 3.0 of the License, or (at your option)
+// any later version.
+// This library is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+// FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
+// details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with this library; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+//------------------------------------------------------------------------------
+#ifndef OST_GFX_EXPORTER_FW_HH
+#define OST_GFX_EXPORTER_FW_HH
+
+namespace ost { namespace gfx {
+
+  class Exporter;
+
+}} // ns
+
+#endif
diff --git a/modules/gfx/src/gfx_node.cc b/modules/gfx/src/gfx_node.cc
index e7f038a2668e2d4fdd162e00f29e4acd37592881..8d417aeec6660d3ecf3aa689cf68d3e90c781fa7 100644
--- a/modules/gfx/src/gfx_node.cc
+++ b/modules/gfx/src/gfx_node.cc
@@ -18,9 +18,11 @@
 //------------------------------------------------------------------------------
 #include <boost/bind.hpp>
 #include <ost/dyn_cast.hh>
+
 #include "gfx_node.hh"
 #include "gfx_object.hh"
 #include "scene.hh"
+#include "exporter.hh"
 
 namespace ost { namespace gfx {
 
@@ -101,6 +103,16 @@ void GfxNode::RenderPov(PovState& pov)
   }
 }
 
+void GfxNode::Export(Exporter* ex)
+{
+  if(!IsVisible()) return;
+  ex->NodeStart(GetName(),Exporter::GROUP);
+  for(GfxNodeVector::iterator it=node_vector_.begin();it!=node_vector_.end();++it) {
+    (*it)->Export(ex);
+  }
+  ex->NodeEnd(GetName());
+}
+
 String GfxNode::GetName() const
 {
   return name_;
diff --git a/modules/gfx/src/gfx_node.hh b/modules/gfx/src/gfx_node.hh
index b211ca8a9ccb7cda837e109a338ac79d33201301..6cff8388518b96924eec6802dad40e5631cf8c4c 100644
--- a/modules/gfx/src/gfx_node.hh
+++ b/modules/gfx/src/gfx_node.hh
@@ -34,6 +34,7 @@
 #include "gfx_object_fw.hh"
 #include "gfx_node_visitor.hh"
 #include "povray_fw.hh"
+#include "exporter_fw.hh"
 
 namespace ost { namespace gfx {
 
@@ -56,10 +57,11 @@ class DLLEXPORT_OST_GFX GfxNode: public boost::enable_shared_from_this<GfxNode>
   // render all child leaves and nodes
   virtual void RenderGL(RenderPass pass);
 
-
   // render all child leaves and nodes into POVray state
   virtual void RenderPov(PovState& pov);
 
+  virtual void Export(Exporter* ex);
+
   // visitor interface
   virtual void Apply(GfxNodeVisitor& v, GfxNodeVisitor::Stack st);
 
diff --git a/modules/gfx/src/gfx_object.cc b/modules/gfx/src/gfx_object.cc
index a7f061e402af59d1a442648a6d238bb4cfc31283..10f6f53c2c648e171416fc98925a84cafab02f53 100644
--- a/modules/gfx/src/gfx_object.cc
+++ b/modules/gfx/src/gfx_object.cc
@@ -33,6 +33,7 @@
 
 #include "povray.hh"
 #include "impl/mapped_property.hh"
+#include "exporter.hh"
 
 #if OST_IMG_ENABLED
 #  include <ost/img/alg/stat.hh>
@@ -195,6 +196,20 @@ void GfxObj::RenderPov(PovState& pov)
   }
 }
 
+
+void GfxObj::Export(Exporter* ex)
+{
+  if(IsVisible()) {
+    ex->NodeStart(GetName(),Exporter::OBJ);
+    // in the simplest case, just export va
+    if(rebuild_ || refresh_) {
+      PreRenderGL(true);
+    }
+    va_.Export(ex);
+    ex->NodeEnd(GetName());
+  }
+}
+
 void GfxObj::Apply(GfxNodeVisitor& v, GfxNodeVisitor::Stack st)
 {
   v.VisitObject(this,st);
diff --git a/modules/gfx/src/gfx_object.hh b/modules/gfx/src/gfx_object.hh
index 1865e7662607ae51624f2c0ec1e5898b41ecb21e..e4b800f3253877d3ae389be666de9c947b25b443 100644
--- a/modules/gfx/src/gfx_object.hh
+++ b/modules/gfx/src/gfx_object.hh
@@ -40,6 +40,7 @@
 #include "gfx_prim.hh"
 #include "vertex_array.hh"
 #include "input.hh"
+#include "exporter_fw.hh"
 
 namespace ost { namespace gfx {
 
@@ -56,7 +57,8 @@ public:
   virtual void DeepSwap(GfxObj& go);
   virtual void RenderGL(RenderPass pass);
   virtual void RenderPov(PovState& pov);
-  virtual void Apply(GfxNodeVisitor& v,GfxNodeVisitor::Stack st);
+  virtual void Export(Exporter* ex);
+  virtual void Apply(GfxNodeVisitor& v, GfxNodeVisitor::Stack st);
   virtual int GetType() const;
   //
 
diff --git a/modules/gfx/src/gost_exporter.cc b/modules/gfx/src/gost_exporter.cc
new file mode 100644
index 0000000000000000000000000000000000000000..79a6e9b28390f1ce2d1890e88d824de48856e358
--- /dev/null
+++ b/modules/gfx/src/gost_exporter.cc
@@ -0,0 +1,277 @@
+//------------------------------------------------------------------------------
+// This file is part of the OpenStructure project <www.openstructure.org>
+//
+// Copyright (C) 2008-2011 by the OpenStructure authors
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License as published by the Free
+// Software Foundation; either version 3.0 of the License, or (at your option)
+// any later version.
+// This library is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+// FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
+// details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with this library; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+//------------------------------------------------------------------------------
+
+/*
+  Author: Ansgar Philippsen
+*/
+
+#include <sstream>
+
+#include "gost_exporter.hh"
+#include "scene.hh"
+
+namespace ost { namespace gfx {
+
+  namespace {
+    enum TYPE {
+      GOST_UNKNOWN=0,
+      GOST_SCENE=1,
+      GOST_START_NODE=2,
+      GOST_END_NODE=3,
+      GOST_DATA=4,
+      GOST_FRAME=5
+    };
+
+    enum NODE_TYPE {
+      GOST_ROOT=1,
+      GOST_GROUP=2,
+      GOST_OBJ=3
+    };
+
+    enum DATA_TYPE {
+      GOST_VDATA=1,
+      GOST_NDATA=2,
+      GOST_CDATA=3,
+      GOST_TDATA=4,
+      GOST_PINDEX=5,
+      GOST_LINDEX=6,
+      GOST_TINDEX=7,
+      GOST_QINDEX=8
+    };
+  }
+
+GostExporter::GostExporter(const std::string& fname):
+  file_(0)
+{
+  file_=fopen(fname.c_str(),"w");
+  if(!file_) {
+    std::ostringstream m;
+    m << "Could not open '" << fname << "' for writing";
+    throw Error(m.str());
+  }
+  char headr[]={'G','O','S','T','1','0'};
+  fwrite(headr,sizeof(char),6,file_);
+}
+
+GostExporter::~GostExporter()
+{
+  fclose(file_);
+  file_=0;
+}
+
+void GostExporter::SceneStart(const Scene* scene)
+{
+  int type=GOST_SCENE;
+  int subtype=0;
+  size_t size=0;
+
+  fwrite(&type,sizeof(int),1,file_);
+  fwrite(&subtype,sizeof(int),1,file_);
+  fwrite(&size,sizeof(size_t),1,file_);
+}
+
+void GostExporter::SceneEnd(const Scene* scene)
+{}
+
+void GostExporter::NodeStart(const std::string& name, NodeType t)
+{
+  int type=GOST_START_NODE;
+  int subtype=0;
+  if(t==Exporter::ROOT) subtype=GOST_ROOT;
+  else if(t==Exporter::GROUP) subtype=GOST_GROUP;
+  else if(t==Exporter::OBJ) subtype=GOST_OBJ;
+  size_t size=name.size();
+
+  fwrite(&type,sizeof(int),1,file_);
+  fwrite(&subtype,sizeof(int),1,file_);
+  fwrite(&size,sizeof(size_t),1,file_);
+  fwrite(name.c_str(),sizeof(char), size,file_);
+}
+
+void GostExporter::NodeEnd(const std::string& name)
+{
+  int type=GOST_END_NODE;
+  int subtype=0;
+  size_t size=0;
+
+  fwrite(&type,sizeof(int),1,file_);
+  fwrite(&subtype,sizeof(int),1,file_);
+  fwrite(&size,sizeof(size_t),1,file_);
+}
+
+void GostExporter::WriteVertexData(const float* vdata, const float* ndata, 
+                                   const float* cdata, const float* tdata,
+                                   size_t stride2, size_t count)
+{
+  std::vector<float> buffer(count*4);
+  int type=GOST_DATA;
+  int subtype=0;
+  size_t size=0;
+  size_t stride=stride2/sizeof(float);
+
+  if(vdata) {
+    // positions
+    subtype=GOST_VDATA;
+    size=sizeof(float)*3*count+sizeof(size_t);
+    float* dest=&buffer[0];
+    const float* src=vdata;
+    for(size_t i=0;i<count;++i) {
+      dest[0]=src[0];
+      dest[1]=src[1];
+      dest[2]=src[2];
+      src+=stride;
+      dest+=3;
+    }
+    fwrite(&type,sizeof(int),1,file_);
+    fwrite(&subtype,sizeof(int),1,file_);
+    fwrite(&size,sizeof(size_t),1,file_);
+    //
+    fwrite(&count,sizeof(size_t),1,file_);
+    fwrite(&buffer[0],sizeof(float),3*count,file_);
+  }
+
+  if(ndata) {
+    // normals
+    subtype=GOST_NDATA;
+    size=sizeof(float)*count*3+sizeof(size_t);
+    float* dest=&buffer[0];
+    const float* src=ndata;
+    for(size_t i=0;i<count;++i) {
+      dest[0]=src[0];
+      dest[1]=src[1];
+      dest[2]=src[2];
+      src+=stride;
+      dest+=3;
+    }
+    fwrite(&type,sizeof(int),1,file_);
+    fwrite(&subtype,sizeof(int),1,file_);
+    fwrite(&size,sizeof(size_t),1,file_);
+    //
+    fwrite(&count,sizeof(size_t),1,file_);
+    fwrite(&buffer[0],sizeof(float),3*count,file_);
+  }
+  
+  if(cdata) {
+    // colors
+    subtype=GOST_CDATA;
+    size=sizeof(float)*count*4+sizeof(size_t);
+    float* dest=&buffer[0];
+    const float* src=cdata;
+    for(size_t i=0;i<count;++i) {
+      dest[0]=src[0];
+      dest[1]=src[1];
+      dest[2]=src[2];
+      dest[3]=src[3];
+      src+=stride;
+      dest+=4;
+    }
+    fwrite(&type,sizeof(int),1,file_);
+    fwrite(&subtype,sizeof(int),1,file_);
+    fwrite(&size,sizeof(size_t),1,file_);
+    //
+    fwrite(&count,sizeof(size_t),1,file_);
+    fwrite(&buffer[0],sizeof(float),4*count,file_);
+  }
+
+  if(tdata) {
+    // texture coordinates
+    subtype=GOST_TDATA;
+    size=sizeof(float)*count*2+sizeof(size_t);
+    float* dest=&buffer[0];
+    const float* src=tdata;
+    for(size_t i=0;i<count;++i) {
+      dest[0]=src[0];
+      dest[1]=src[1];
+      src+=stride;
+      dest+=2;
+    }
+    fwrite(&type,sizeof(int),1,file_);
+    fwrite(&subtype,sizeof(int),1,file_);
+    fwrite(&size,sizeof(size_t),1,file_);
+    //
+    fwrite(&count,sizeof(size_t),1,file_);
+    fwrite(&buffer[0],sizeof(float),2*count,file_);
+  }
+}
+
+void GostExporter::WritePointData(const unsigned int* i, size_t count)
+{
+  int type=GOST_DATA;
+  int subtype=GOST_PINDEX;
+  size_t size=sizeof(unsigned int)*count+sizeof(size_t);
+  fwrite(&type,sizeof(int),1,file_);
+  fwrite(&subtype,sizeof(int),1,file_);
+  fwrite(&size,sizeof(size_t),1,file_);
+  //
+  fwrite(&count,sizeof(size_t),1,file_);
+  fwrite(i,sizeof(unsigned int),count,file_);
+}
+
+void GostExporter::WriteLineData(const unsigned int* ij, size_t count)
+{
+  int type=GOST_DATA;
+  int subtype=GOST_LINDEX;
+  size_t size=sizeof(unsigned int)*2*count+sizeof(size_t);
+  fwrite(&type,sizeof(int),1,file_);
+  fwrite(&subtype,sizeof(int),1,file_);
+  fwrite(&size,sizeof(size_t),1,file_);
+  //
+  fwrite(&count,sizeof(size_t),1,file_);
+  fwrite(ij,sizeof(unsigned int),2*count,file_);
+}
+
+void GostExporter::WriteTriData(const unsigned int* ijk, size_t count)
+{
+  int type=GOST_DATA;
+  int subtype=GOST_TINDEX;
+  size_t size=sizeof(unsigned int)*3*count+sizeof(size_t);
+  fwrite(&type,sizeof(int),1,file_);
+  fwrite(&subtype,sizeof(int),1,file_);
+  fwrite(&size,sizeof(size_t),1,file_);
+  //
+  fwrite(&count,sizeof(size_t),1,file_);
+  fwrite(ijk,sizeof(unsigned int),3*count,file_);
+}
+
+void GostExporter::WriteQuadData(const unsigned int* ijkl, size_t count)
+{
+  int type=GOST_DATA;
+  int subtype=GOST_QINDEX;
+  size_t size=sizeof(unsigned int)*4*count+sizeof(size_t);
+  fwrite(&type,sizeof(int),1,file_);
+  fwrite(&subtype,sizeof(int),1,file_);
+  fwrite(&size,sizeof(size_t),1,file_);
+  //
+  fwrite(&count,sizeof(size_t),1,file_);
+  fwrite(ijkl,sizeof(unsigned int),4*count,file_);
+}
+
+void GostExporter::SetFrame(size_t frame)
+{
+  int type=GOST_FRAME;
+  int subtype=0;
+  size_t size=sizeof(size_t);
+  fwrite(&type,sizeof(int),1,file_);
+  fwrite(&subtype,sizeof(int),1,file_);
+  fwrite(&size,sizeof(size_t),1,file_);
+  //
+  fwrite(&frame,sizeof(size_t),1,file_);
+}
+
+}} // ns
diff --git a/modules/gfx/src/gost_exporter.hh b/modules/gfx/src/gost_exporter.hh
new file mode 100644
index 0000000000000000000000000000000000000000..03f47680eeabba9fe36236ff057b5e13f4385c9c
--- /dev/null
+++ b/modules/gfx/src/gost_exporter.hh
@@ -0,0 +1,54 @@
+//------------------------------------------------------------------------------
+// This file is part of the OpenStructure project <www.openstructure.org>
+//
+// Copyright (C) 2008-2011 by the OpenStructure authors
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License as published by the Free
+// Software Foundation; either version 3.0 of the License, or (at your option)
+// any later version.
+// This library is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+// FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
+// details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with this library; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+//------------------------------------------------------------------------------
+#ifndef OST_GFX_GOST_EXPORTER_HH
+#define OST_GFX_GOST_EXPORTER_HH
+
+#include <cstdio>
+
+#include "exporter.hh"
+
+namespace ost { namespace gfx {
+
+class DLLEXPORT_OST_GFX GostExporter: public Exporter
+{
+public:
+  GostExporter(const std::string& fname);
+  virtual ~GostExporter();
+
+  // exporter interface
+  virtual void SceneStart(const Scene* scene);
+  virtual void SceneEnd(const Scene* scene);
+  virtual void NodeStart(const std::string& name, NodeType t);
+  virtual void NodeEnd(const std::string& name);
+  virtual void WriteVertexData(const float* v, const float* n, const float* c, const float* t, 
+                               size_t stride, size_t count);
+  virtual void WritePointData(const unsigned int* i, size_t count);
+  virtual void WriteLineData(const unsigned int* ij, size_t count);
+  virtual void WriteTriData(const unsigned int* ijk, size_t count);
+  virtual void WriteQuadData(const unsigned int* ijkl, size_t count);
+
+  // gost interface
+  void SetFrame(size_t f);
+private:
+  FILE* file_;
+};
+
+}} // ns
+
+#endif
diff --git a/modules/gfx/src/impl/entity_renderer.cc b/modules/gfx/src/impl/entity_renderer.cc
index 3464d1292297e3161e3aaed4a1130974b7763fb1..fb22e24a375988bdcb36bf8b9b1b9b0e34695fef 100644
--- a/modules/gfx/src/impl/entity_renderer.cc
+++ b/modules/gfx/src/impl/entity_renderer.cc
@@ -156,6 +156,11 @@ void EntityRenderer::RenderPov(PovState& pov, const std::string& name)
   va_.RenderPov(pov,name);
 }
 
+void EntityRenderer::Export(Exporter* ex)
+{
+  va_.Export(ex);
+}
+
 bool EntityRenderer::HasSelection() const
 {
   return (sel_.IsValid() && sel_.GetAtomCount()>0);
diff --git a/modules/gfx/src/impl/entity_renderer.hh b/modules/gfx/src/impl/entity_renderer.hh
index ceed73fa4d8d2f41a739c949a6e978ae29b18fbc..14c0332c3b5a15d0d0f101b19aad3e9363d03047 100644
--- a/modules/gfx/src/impl/entity_renderer.hh
+++ b/modules/gfx/src/impl/entity_renderer.hh
@@ -39,8 +39,9 @@
 #include <ost/gfx/module_config.hh>
 #include <ost/gfx/render_pass.hh>
 #include <ost/gfx/vertex_array.hh>
+#include <ost/gfx/exporter_fw.hh>
+
 #include <ost/gfx/render_options/render_options.hh>
-#include <ost/gfx/impl/mapped_property.hh>
 
 #include <ost/gfx/color_ops/color_op.hh>
 #include <ost/gfx/color_ops/by_element_color_op.hh>
@@ -51,7 +52,9 @@
 #if OST_IMG_ENABLED
 #include <ost/gfx/color_ops/map_handle_color_op.hh>
 #endif //OST_IMG_ENABLED
-#include <ost/gfx/impl/entity_renderer_fw.hh>
+
+#include "mapped_property.hh"
+#include "entity_renderer_fw.hh"
 
 namespace ost { namespace gfx { namespace impl {
 
@@ -123,6 +126,9 @@ public:
   ///\brief povray rendering call
   virtual void RenderPov(PovState& pov, const std::string& name);
 
+  ///\brief scene exporter interface
+  virtual void Export(Exporter* ex);
+
   virtual bool CanSetOptions(RenderOptionsPtr& render_options)=0;
   virtual void SetOptions(RenderOptionsPtr& render_options)=0;
   
diff --git a/modules/gfx/src/scene.cc b/modules/gfx/src/scene.cc
index 7b7ddce245d1d46502519157a1c65608e1fd4c35..bbc615ee5d0ae3a66861509bc6fc7e12a3a74b1c 100644
--- a/modules/gfx/src/scene.cc
+++ b/modules/gfx/src/scene.cc
@@ -42,6 +42,7 @@
 #include "gl_helper.hh"
 
 #include <ost/config.hh>
+
 #include "scene.hh"
 #include "input.hh"
 #include "gfx_node.hh"
@@ -49,6 +50,7 @@
 #include "gfx_test_object.hh"
 #include "bitmap_io.hh"
 #include "entity.hh"
+#include "exporter.hh"
 #include "povray.hh"
 #include "offscreen_buffer.hh"
 
@@ -1576,6 +1578,13 @@ void Scene::ExportPov(const std::string& fname, const std::string& wdir)
   pov.write_postamble();
 }
 
+void Scene::Export(Exporter* ex) const
+{
+  ex->SceneStart(this);
+  root_node_->Export(ex);
+  ex->SceneEnd(this);
+}
+
 void Scene::ResetProjection()
 {
   LOG_TRACE("Scene: projection matrix " << fov_ << " " << znear_ << " " << zfar_);
diff --git a/modules/gfx/src/scene.hh b/modules/gfx/src/scene.hh
index 932f7e5a7a0cf8f11a14b2c60f41f759184d8149..63d9909bcb7e44e490010e500d3e791031b7eb75 100644
--- a/modules/gfx/src/scene.hh
+++ b/modules/gfx/src/scene.hh
@@ -42,6 +42,7 @@
 #include "scene_observer.hh"
 #include "gfx_prim.hh"
 #include "povray_fw.hh"
+#include "exporter_fw.hh"
 
 namespace ost { namespace gfx {
 
@@ -256,6 +257,10 @@ class DLLEXPORT_OST_GFX Scene {
 
   /// \brief export scene into povray files named fname.pov and fname.inc
   void ExportPov(const std::string& fname, const std::string& wdir=".");
+
+  /// \rbrief export scene via exporter
+  void Export(Exporter* ex) const;
+
   //@}
   /// \brief entry point for gui events (internal use)
   void OnInput(const InputEvent& e);
diff --git a/modules/gfx/src/vertex_array.cc b/modules/gfx/src/vertex_array.cc
index c1c53d57fa29110368a7b1a5a2da28fb2c7c5612..be735a3e85db09613302313c3c3f7612bba2f455 100644
--- a/modules/gfx/src/vertex_array.cc
+++ b/modules/gfx/src/vertex_array.cc
@@ -30,6 +30,7 @@
 #include "scene.hh"
 #include "vertex_array_helper.hh"
 #include "povray.hh"
+#include "exporter.hh"
 
 #if OST_SHADER_SUPPORT_ENABLED
 #include "shader.hh"
@@ -654,6 +655,14 @@ void IndexedVertexArray::RenderPov(PovState& pov, const std::string& name)
   pov.inc() << "}\n";
 }
 
+void IndexedVertexArray::Export(Exporter* ex) const
+{
+  ex->WriteVertexData(entry_list_[0].v,entry_list_[0].n, entry_list_[0].c, entry_list_[0].t, sizeof(Entry), entry_list_.size());
+  ex->WriteLineData(&line_index_list_[0],line_index_list_.size()/2);
+  ex->WriteTriData(&tri_index_list_[0],tri_index_list_.size()/3);
+  ex->WriteQuadData(&quad_index_list_[0],quad_index_list_.size()/4);
+}
+
 void IndexedVertexArray::Clear()
 {
   dirty_=true;
diff --git a/modules/gfx/src/vertex_array.hh b/modules/gfx/src/vertex_array.hh
index 3d24320e7900985df54c352135b35e173e488d5c..ee63c939aae475959cfa12963b730f7326392df6 100644
--- a/modules/gfx/src/vertex_array.hh
+++ b/modules/gfx/src/vertex_array.hh
@@ -39,6 +39,7 @@
 #include "material.hh"
 #include "gfx_prim.hh"
 #include "povray_fw.hh"
+#include "exporter_fw.hh"
 
 namespace ost { namespace gfx {
 
@@ -162,6 +163,8 @@ class DLLEXPORT_OST_GFX IndexedVertexArray {
   // POVray export
   void RenderPov(PovState& pov, const std::string& name);
 
+  void Export(Exporter* ex) const;
+
   // only removes the drawing elements
   void Clear();
   // removes all elements and resets internal state to default
diff --git a/modules/gfx/tests/test_gost_export.py b/modules/gfx/tests/test_gost_export.py
new file mode 100644
index 0000000000000000000000000000000000000000..efb56861b18f52fae0b92d25e62477b06901fdfe
--- /dev/null
+++ b/modules/gfx/tests/test_gost_export.py
@@ -0,0 +1,22 @@
+import desost_util as util
+
+e=io.LoadPDB("../../../examples/demos/data/sdh.pdb")
+
+s=util.CreateSurf(e.Select("chain=A"),density=4)
+
+scene.Add(gfx.Entity("trace",gfx.TUBE,e.Select("chain=A")))
+scene["trace"].tube_options.arc_detail=8
+scene["trace"].tube_options.spline_detail=8
+scene["trace"].tube_options.tube_radius=1.0
+grad=gfx.Gradient()
+grad.SetColorAt(0.0,gfx.RED)
+grad.SetColorAt(0.5,gfx.GREEN)
+grad.SetColorAt(1.0,gfx.BLUE)
+scene["trace"].ColorBy("rnum",grad)
+
+scene.Add(gfx.Surface("surf",s))
+scene["surf"].ColorBy("rnum",grad)
+
+if not gui_mode:
+  ge = gfx.GostExporter("test.gost")
+  scene.Export(ge)
diff --git a/modules/gfx/tests/test_gost_import.py b/modules/gfx/tests/test_gost_import.py
new file mode 100644
index 0000000000000000000000000000000000000000..deebd2d31d805c7c0cc190d5ad273262dc7728bf
--- /dev/null
+++ b/modules/gfx/tests/test_gost_import.py
@@ -0,0 +1,15 @@
+import struct
+
+with open("test.gost","rb") as gf:
+
+  header = gf.read(6)
+  if str(header[0:4]) != "GOST":
+    raise RuntimeError("file format mismatch")
+  raw = gf.read(16)
+
+  while raw:
+    (type, subtype,size) = struct.unpack("iiL",raw)
+    print "found type=%d, subtype=%d and blocksize=%u"%(type,subtype,size)
+    if size>0:
+      data = gf.read(size)
+    raw = gf.read(16)