diff --git a/modules/gfx/pymod/color_by_def.hh b/modules/gfx/pymod/color_by_def.hh
index 1c4643acd6ec55c61df7a483d5c05a13282da574..d45bb327e87db0772e4e09f41b939cc467727ecd 100644
--- a/modules/gfx/pymod/color_by_def.hh
+++ b/modules/gfx/pymod/color_by_def.hh
@@ -22,13 +22,16 @@
 #include <ost/config.hh>
 #include <ost/gfx/gfx_object.hh>
 
+#if OST_IMG_ENABLED
+#include <ost/img/alg/stat.hh>
+#endif
+
 using namespace ost;
 using namespace ost::gfx;
 
 namespace ost_gfx {
 
-#if OST_IMG_ENABLED
-inline void color_by_01(GfxObj* go,
+inline void color_by_e0(GfxObj* go,
                 const mol::EntityView& ev, 
                 const String& prop,
                 const Gradient& g, float minv, float maxv)
@@ -36,117 +39,141 @@ inline void color_by_01(GfxObj* go,
   go->ColorBy(ev,prop,g,minv,maxv);
 }
 
-inline void color_by_02(GfxObj* go,
-                const ::img::MapHandle& mh, 
-                const String& prop,
-                const Gradient& g, float minv, float maxv)
+inline void color_by_e1(GfxObj* go,
+			const mol::EntityView& ev, 
+			const String& prop,
+			const Color& c1, const Color& c2, float minv, float maxv)
 {
-  go->ColorBy(mh,prop,g,minv,maxv);
+  Gradient g;
+  g.SetColorAt(0.0,c1);
+  g.SetColorAt(1.0,c2);
+  go->ColorBy(ev,prop,g,minv,maxv);
 }
 
-
-inline void color_by_11(GfxObj* go,
-                 const ::img::MapHandle& mh, 
-                 const String& prop,
-                 const Gradient& g)
+inline void color_by_e2(GfxObj* go,
+			const mol::EntityHandle& eh, 
+			const String& prop,
+			const Gradient& g, float minv, float maxv)
 {
-  go->ColorBy(mh,prop,g);
+  go->ColorBy(eh.CreateFullView(),prop,g,minv,maxv);
 }
 
-inline void color_by_12(GfxObj* go,
-                 const ::img::MapHandle& mh, 
-                 const String& prop,
-                 const Color& c1, const Color& c2)
+inline void color_by_e3(GfxObj* go,
+			const mol::EntityHandle& eh, 
+			const String& prop,
+			const Color& c1, const Color& c2, float minv, float maxv)
 {
-  go->ColorBy(mh,prop,c1,c2);
+  Gradient g;
+  g.SetColorAt(0.0,c1);
+  g.SetColorAt(1.0,c2);
+  go->ColorBy(eh.CreateFullView(),prop,g,minv,maxv);
 }
 
-
-inline void color_by_04(GfxObj* go,
-                const ::img::MapHandle& mh, 
-                const String& prop,
-                const Color& c1, const Color& c2, float minv, float maxv)
+inline void color_by_e4(GfxObj* go,
+			const mol::EntityView& ev, 
+			const String& prop,
+			const Gradient& g)
 {
-  go->ColorBy(mh,prop,c1,c2,minv,maxv);
+  std::pair<float,float> minmax = ev.GetMinMax(prop);
+  go->ColorBy(ev,prop,g,minmax.first, minmax.second);
 }
 
-#endif
-
-inline void color_by_03(GfxObj* go,
-                const mol::EntityView& ev, 
-                const String& prop,
-                const Color& c1, const Color& c2, float minv, float maxv)
+inline void color_by_e5(GfxObj* go,
+			const mol::EntityView& ev, 
+			const String& prop,
+			const Color& c1, const Color& c2)
 {
-  go->ColorBy(ev,prop,c1,c2,minv,maxv);
+  Gradient g;
+  g.SetColorAt(0.0,c1);
+  g.SetColorAt(1.0,c2);
+  std::pair<float,float> minmax = ev.GetMinMax(prop);
+  go->ColorBy(ev,prop,g,minmax.first, minmax.second);
 }
 
-
-
-inline void color_by_05(GfxObj* go,
-                const mol::EntityHandle& eh, 
-                const String& prop,
-                const Gradient& g, float minv, float maxv)
+inline void color_by_e6(GfxObj* go,
+			const mol::EntityHandle& eh, 
+			const String& prop,
+			const Gradient& g)
 {
-  go->ColorBy(eh,prop,g,minv,maxv);
+  color_by_e4(go,eh.CreateFullView(),prop,g);
 }
 
-inline void color_by_06(GfxObj* go,
-                const mol::EntityHandle& eh, 
-                const String& prop,
-                const Color& c1, const Color& c2, float minv, float maxv)
+inline void color_by_e7(GfxObj* go,
+			const mol::EntityHandle& eh, 
+			const String& prop,
+			const Color& c1, const Color& c2)
 {
-  go->ColorBy(eh,prop,c1,c2,minv,maxv);
+  color_by_e5(go,eh.CreateFullView(),prop,c1,c2);
 }
 
-inline void color_by_07(GfxObj* go,
-                const mol::EntityView& ev, 
-                const String& prop,
-                const Gradient& g){
-  go->ColorBy(ev,prop,g);
+#if OST_IMG_ENABLED
+inline void color_by_m0(GfxObj* go,
+			const ::img::MapHandle& mh, 
+			const String& prop,
+			const Gradient& g, float minv, float maxv)
+{
+  go->ColorBy(mh,prop,g,minv,maxv);
 }
 
-inline void color_by_08(GfxObj* go,
-                const mol::EntityView& ev, 
-                const String& prop,
-                const Color& c1, const Color& c2)
+inline void color_by_m1(GfxObj* go,
+			  const ::img::MapHandle& mh, 
+			  const String& prop,
+			  const Gradient& g)
 {
-  go->ColorBy(ev,prop,c1,c2);
+  ost::img::alg::Stat stat;
+  mh.Apply(stat);
+  float min = static_cast<float>(stat.GetMinimum());
+  float max = static_cast<float>(stat.GetMaximum());
+  std::pair<float,float> minmax = std::make_pair(min,max);
+  go->ColorBy(mh,prop,g,minmax.first, minmax.second);
 }
 
-inline void color_by_09(GfxObj* go,
-                const mol::EntityHandle& ev, 
-                const String& prop,
-                const Gradient& g)
+inline void color_by_m2(GfxObj* go,
+			const ::img::MapHandle& mh, 
+			const String& prop,
+			const Color& c1, const Color& c2)
 {
-  go->ColorBy(ev,prop,g);
+  Gradient g;
+  g.SetColorAt(0.0,c1);
+  g.SetColorAt(1.0,c2);
+  ost::img::alg::Stat stat;
+  mh.Apply(stat);
+  float min = static_cast<float>(stat.GetMinimum());
+  float max = static_cast<float>(stat.GetMaximum());
+  std::pair<float,float> minmax = std::make_pair(min,max);
+  go->ColorBy(mh,prop,g,minmax.first, minmax.second);
 }
 
-inline void color_by_10(GfxObj* go,
-                 const mol::EntityHandle& ev, 
-                 const String& prop,
-                 const Color& c1, const Color& c2)
+inline void color_by_m3(GfxObj* go,
+			const ::img::MapHandle& mh, 
+			const String& prop,
+			const Color& c1, const Color& c2, float minv, float maxv)
 {
-  go->ColorBy(ev,prop,c1,c2);
+  Gradient g;
+  g.SetColorAt(0.0,c1);
+  g.SetColorAt(1.0,c2);
+  go->ColorBy(mh,prop,g,minv, maxv);
 }
+#endif
 
 }
 
 #define COLOR_BY_DEF_STD() \
-    .def("ColorBy",ost_gfx::color_by_03)\
-    .def("ColorBy",ost_gfx::color_by_05)\
-    .def("ColorBy",ost_gfx::color_by_06)\
-    .def("ColorBy",ost_gfx::color_by_07)\
-    .def("ColorBy",ost_gfx::color_by_08)\
-    .def("ColorBy",ost_gfx::color_by_09)\
-    .def("ColorBy",ost_gfx::color_by_10)
+    .def("ColorBy",ost_gfx::color_by_e0)\
+    .def("ColorBy",ost_gfx::color_by_e1)\
+    .def("ColorBy",ost_gfx::color_by_e2)\
+    .def("ColorBy",ost_gfx::color_by_e3)\
+    .def("ColorBy",ost_gfx::color_by_e4)\
+    .def("ColorBy",ost_gfx::color_by_e5)\
+    .def("ColorBy",ost_gfx::color_by_e6)\
+    .def("ColorBy",ost_gfx::color_by_e7)
 
 #if OST_IMG_ENABLED
 #  define COLOR_BY_DEF_MAP() \
-    .def("ColorBy",ost_gfx::color_by_01)\
-    .def("ColorBy",ost_gfx::color_by_02)\
-    .def("ColorBy",ost_gfx::color_by_04)\
-    .def("ColorBy",ost_gfx::color_by_11)\
-    .def("ColorBy",ost_gfx::color_by_12)
+    .def("ColorBy",ost_gfx::color_by_m0)\
+    .def("ColorBy",ost_gfx::color_by_m1)\
+    .def("ColorBy",ost_gfx::color_by_m2)\
+    .def("ColorBy",ost_gfx::color_by_m3)
 #else
 #  define COLOR_BY_DEF_MAP()
 #endif
diff --git a/modules/gfx/pymod/export_gfx_obj.cc b/modules/gfx/pymod/export_gfx_obj.cc
index a285e524d7bcf89ccf776a4bebd20d7ad8f8b464..3a0f4d7be36f3a9f0ca0695627264a878847662d 100644
--- a/modules/gfx/pymod/export_gfx_obj.cc
+++ b/modules/gfx/pymod/export_gfx_obj.cc
@@ -25,62 +25,77 @@ using namespace ost::gfx;
 
 #include "color_by_def.hh"
 
+namespace {
+  // convenience for python
+  void set_mat_amb2(GfxObjBase* b, float c) {b->SetMatAmb(Color(c,c,c,1.0));}
+  void set_mat_diff2(GfxObjBase* b, float c) {b->SetMatDiff(Color(c,c,c,1.0));}
+  void set_mat_spec2(GfxObjBase* b, float c) {b->SetMatSpec(Color(c,c,c,1.0));}
+  void set_mat_emm2(GfxObjBase* b, float c) {b->SetMatEmm(Color(c,c,c,1.0));}
+  void set_mat1(GfxObjBase* b, float a, float d, float s, float p)
+  {
+    set_mat_amb2(b,a);
+    set_mat_diff2(b,d);
+    set_mat_spec2(b,s);
+    b->SetMatShin(p);
+    set_mat_emm2(b,0.0);
+  }
+  void set_mat2(GfxObjBase* b, Color a, Color d, Color s, float p)
+  {
+    b->SetMatAmb(a);
+    b->SetMatDiff(d);
+    b->SetMatSpec(s);
+    b->SetMatShin(p);
+    set_mat_emm2(b,0.0);
+  }
+}
+
 void export_GfxObj()
 {
-  void (GfxObj::* set_mat_amb1)(const Color&) = &GfxObj::SetMatAmb;
-  void (GfxObj::* set_mat_amb2)(float) = &GfxObj::SetMatAmb;
-  void (GfxObj::* set_mat_diff1)(const Color&) = &GfxObj::SetMatDiff;
-  void (GfxObj::* set_mat_diff2)(float) = &GfxObj::SetMatDiff;
-  void (GfxObj::* set_mat_spec1)(const Color&) = &GfxObj::SetMatSpec;
-  void (GfxObj::* set_mat_spec2)(float) = &GfxObj::SetMatSpec;
-  void (GfxObj::* set_mat_emm1)(const Color&) = &GfxObj::SetMatEmm;
-  void (GfxObj::* set_mat_emm2)(float) = &GfxObj::SetMatEmm;
-  void (GfxObj::* set_mat1)(const Color&,const Color&, 
-                            const Color&, float) = &GfxObj::SetMat;
-  void (GfxObj::* set_mat2)(float,float,float,float) = &GfxObj::SetMat;
-
-  class_<GfxObj, bases<GfxNode>, boost::noncopyable>("GfxObj",no_init)
-    .def("GetCenter",&GfxObj::GetCenter)
-    .def("SetRenderMode", &GfxObj::SetRenderMode)
-    .def("GetRenderMode", &GfxObj::GetRenderMode)
-    .def("SetLineWidth", &GfxObj::SetLineWidth)
-    .def("GetLineWidth", &GfxObj::GetLineWidth)
-    .def("SetLineHalo",&GfxObj::SetLineHalo)
-    .def("GetLineHalo",&GfxObj::GetLineHalo)
-    .def("SetSphereDetail",&GfxObj::SetSphereDetail)
-    .def("SetArcDetail",&GfxObj::SetArcDetail)
-    .def("SetSplineDetail",&GfxObj::SetSplineDetail)
-    .def("SetMatAmb",set_mat_amb1)
+  class_<GfxObjBase, bases<GfxNode>, boost::noncopyable>("GfxObjBase",no_init)
+    .def("SetMatAmb",&GfxObjBase::SetMatAmb)
     .def("SetMatAmb",set_mat_amb2)
-    .def("SetMatDiff",set_mat_diff1)
+    .def("SetMatDiff",&GfxObjBase::SetMatDiff)
     .def("SetMatDiff",set_mat_diff2)
-    .def("GetTF", &GfxObj::GetTF, return_value_policy<copy_const_reference>())
-    .def("SetTF", &GfxObj::SetTF)
-    .def("SetMatSpec",set_mat_spec1)
+    .def("SetMatSpec",&GfxObjBase::SetMatSpec)
     .def("SetMatSpec",set_mat_spec2)
-    .def("SetMatEmm",set_mat_emm1)
+    .def("SetMatEmm",&GfxObjBase::SetMatEmm)
     .def("SetMatEmm",set_mat_emm2)
-    .def("SetMatShin",&GfxObj::SetMatShin)
+    .def("SetMatShin",&GfxObjBase::SetMatShin)
     .def("SetMat",set_mat1)
     .def("SetMat",set_mat2)
-    .def("SetPolyMode",&GfxObj::SetPolyMode)
-    .def("SetAALines",&GfxObj::SetAALines)
-    .def("SetOpacity",&GfxObj::SetOpacity)
-    .def("GetOpacity",&GfxObj::GetOpacity)
+    .def("ContextSwitch", &GfxObjBase::ContextSwitch)
+    .def("SetRenderMode", &GfxObjBase::SetRenderMode)
+    .def("GetRenderMode", &GfxObjBase::GetRenderMode)
+    .def("GetCenter",&GfxObjBase::GetCenter)
+    .def("SetLineWidth", &GfxObjBase::SetLineWidth)
+    .def("SetPolyMode",&GfxObjBase::SetPolyMode)
+    .def("AALines",&GfxObjBase::AALines)
+    .def("SetLineHalo",&GfxObjBase::SetLineHalo)
+    .def("Outline",&GfxObjBase::Outline)
+    .def("SetOutlineMode",&GfxObjBase::SetOutlineMode)
+    .def("SetOutlineExpandFactor",&GfxObjBase::SetOutlineExpandFactor)
+    .def("SetOutlineExpandColor",&GfxObjBase::SetOutlineExpandColor)
+    .def("AmbientOcclusion",&GfxObjBase::AmbientOcclusion)
+    .def("SetAmbientLocalWeight",&GfxObjBase::SetAmbientLocalWeight)
+    .def("SetAmbientOcclusionWeight",&GfxObjBase::SetAmbientOcclusionWeight)
+    .def("SetOpacity",&GfxObjBase::SetOpacity)
+    .add_property("center", &GfxObjBase::GetCenter)
+    COLOR_BY_DEF()
+   ;
+
+  class_<GfxObj, bases<GfxObjBase>, boost::noncopyable>("GfxObj",no_init)
+    .def("GetTF", &GfxObj::GetTF, return_value_policy<copy_const_reference>())
+    .def("SetTF", &GfxObj::SetTF)
     .def("FlagRebuild",&GfxObj::FlagRebuild)
     .def("FlagRefresh",&GfxObj::FlagRefresh)
     .def("SetNormalSmoothFactor",&GfxObj::SetNormalSmoothFactor)
     .def("GetNormalSmoothFactor",&GfxObj::GetNormalSmoothFactor)
-    .def("SetOutlineMode",&GfxObj::SetOutlineMode)
-    .def("SetOutlineExpandFactor",&GfxObj::SetOutlineExpandFactor)
-    .def("SetOutlineExpandColor",&GfxObj::SetOutlineExpandColor)
     .def("SmoothVertices",&GfxObj::SmoothVertices)
-    .def("AmbientOcclusion",&GfxObj::AmbientOcclusion)
-    .def("AmbientLocalWeight",&GfxObj::AmbientLocalWeight)
-    .def("AmbientOcclusionWeight",&GfxObj::AmbientOcclusionWeight)
     .def("Debug",&GfxObj::Debug)
-    .add_property("center", &GfxObj::GetCenter)
-    COLOR_BY_DEF()
+    .def("GetAALines",&GfxObj::GetAALines)
+    .def("GetLineWidth",&GfxObj::GetLineWidth)
+    .def("GetLineHalo",&GfxObj::GetLineHalo)
+    .def("GetOpacity",&GfxObj::GetOpacity)
     ;
   register_ptr_to_python<GfxObjP>();
 
diff --git a/modules/gfx/src/CMakeLists.txt b/modules/gfx/src/CMakeLists.txt
index e48ee57101157e4389077e410220a7f9d31e3200..9f3d471ff3381816efa024a3af871f9460da7527 100644
--- a/modules/gfx/src/CMakeLists.txt
+++ b/modules/gfx/src/CMakeLists.txt
@@ -10,6 +10,7 @@ gfx_fw.hh
 gfx_node.hh
 gfx_node_fw.hh
 gfx_node_visitor.hh
+gfx_object_base.hh
 gfx_object.hh
 gfx_object_fw.hh
 gfx_prim.hh
diff --git a/modules/gfx/src/entity.cc b/modules/gfx/src/entity.cc
index dfae13a3707eddb51e9a12dc4516c668d1d70e44..25d63fd4ac1864d893f2cf1ce9521317f95b56d7 100644
--- a/modules/gfx/src/entity.cc
+++ b/modules/gfx/src/entity.cc
@@ -145,7 +145,10 @@ impl::EntityRenderer* Entity::GetOrCreateRenderer(RenderMode::Type rm)
 void Entity::init(RenderMode::Type rm)
 {
   // TODO replace with def mat for this gfx obj type
-  SetMat(0.0,1.0,0.8,96.0);
+  SetMatAmb(Color(0,0,0));
+  SetMatDiff(Color(1,1,1));
+  SetMatSpec(Color(0.7,0.7,0.7));
+  SetMatShin(96);
 
   update_view_=true;
   render_mode_=rm;
@@ -340,8 +343,8 @@ void Entity::CustomRenderGL(RenderPass pass)
     if(r->IsEnabled()){
       if(pass==STANDARD_RENDER_PASS || pass==OPAQUE_RENDER_PASS) {
         r->Render(pass);
-        if(pass==STANDARD_RENDER_PASS && omode_>0) {
-          r->VA().SetOutlineMode(omode_);
+        if(pass==STANDARD_RENDER_PASS && outline_flag_) {
+          r->VA().SetOutlineMode(outline_mode_);
           r->Render(pass);
           r->VA().SetOutlineMode(0);
         }
diff --git a/modules/gfx/src/gfx_object.cc b/modules/gfx/src/gfx_object.cc
index 3959e465325c5987d36b04b064c710e2c364ac5b..4231be8dc6a491c3793c349039246e970ece0c16 100644
--- a/modules/gfx/src/gfx_object.cc
+++ b/modules/gfx/src/gfx_object.cc
@@ -41,7 +41,7 @@
 namespace ost { namespace gfx {
 
 GfxObj::GfxObj(const String& name):
-  GfxNode(name),
+  GfxObjBase(name),
   va_(),
   render_mode_(RenderMode::SIMPLE),
   debug_flags_(0),
@@ -49,9 +49,6 @@ GfxObj::GfxObj(const String& name):
   rebuild_(true),
   refresh_(false),
   line_width_(2.0),
-  sphere_detail_(4),
-  arc_detail_(4),
-  spline_detail_(8),
   poly_mode_(2),
   aalines_flag_(false),
   line_halo_(0.0),
@@ -60,64 +57,22 @@ GfxObj::GfxObj(const String& name):
   mat_update_(true),
   opacity_(1.0),
   smoothf_(0.0),
-  omode_(0),
+  outline_flag_(false),
+  outline_mode_(1),
   c_ops_(),
   labels_(),
   use_occlusion_(false)
 {
 }
 
-GfxObj::~GfxObj()
-{}
-
-GfxObj::GfxObj(const GfxObj& o):
-  GfxNode("") // to make the compiler happy
+GfxObj::GfxObj(const GfxObj&):
+  GfxObjBase("") // to make the compiler happy
 {}
 
 GfxObj& GfxObj::operator=(const GfxObj&) {return *this;}
 
-void GfxObj::Apply(GfxNodeVisitor& v, GfxNodeVisitor::Stack st)
-{
-  v.VisitObject(this,st);
-}
-
-int GfxObj::GetType() const
-{
-  return 1;
-}
-
-geom::AlignedCuboid GfxObj::GetBoundingBox() const
-{
-  return geom::AlignedCuboid(geom::Vec3(),geom::Vec3());
-}
-
-void GfxObj::ProcessLimits(geom::Vec3& minc, geom::Vec3& maxc, 
-                           const mol::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], 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))))))));
-  } catch(Error& e) {
-    // in case the object is empty...
-  }
-}
+////////////////////////////////////////
+// the GfxNode interface
 
 GfxNodeP GfxObj::Copy() const
 {
@@ -130,9 +85,6 @@ void GfxObj::DeepSwap(GfxObj& go)
   std::swap(transform_,go.transform_);
   std::swap(rebuild_,go.rebuild_);
   std::swap(refresh_,go.refresh_);
-  std::swap(sphere_detail_,go.sphere_detail_);
-  std::swap(arc_detail_,go.arc_detail_);
-  std::swap(spline_detail_,go.spline_detail_);
   std::swap(poly_mode_,go.poly_mode_);
   std::swap(aalines_flag_,go.aalines_flag_);
   std::swap(line_halo_,go.line_halo_);
@@ -141,148 +93,150 @@ void GfxObj::DeepSwap(GfxObj& go)
   std::swap(mat_update_,go.mat_update_);
   std::swap(opacity_,go.opacity_);
   std::swap(smoothf_,go.smoothf_);
+  std::swap(outline_flag_,go.outline_flag_);
+  std::swap(outline_mode_,go.outline_mode_);
+  std::swap(c_ops_,go.c_ops_);
+  std::swap(labels_,go.labels_);
+  std::swap(use_occlusion_,go.use_occlusion_);
 }
 
-void GfxObj::CustomRenderGL(RenderPass pass) {}
-void GfxObj::CustomPreRenderGL(bool flag) {}
+void GfxObj::RenderGL(RenderPass pass)
+{
+  LOGN_TRACE("object " << GetName() << ": RenderGL()");
 
-void GfxObj::CustomRenderPov(PovState& pov) {}
+  if(pass==0) {
+    if(mat_update_) {
+      LOGN_TRACE("updating material display list");
+      if(mat_dlist_==0) {
+        mat_dlist_=glGenLists(1);
+      }
+      glNewList(mat_dlist_,GL_COMPILE);
+      mat_.RenderGL();
+      glEndList();
+      mat_update_=false;
+    }
+    
+    if(rebuild_ || refresh_) {
+      PreRenderGL(rebuild_);
+      rebuild_=false;
+      refresh_=false;
+    }
+  }
+  if(IsVisible()) {
+    LOGN_TRACE("applying local transformation");
+    glMatrixMode(GL_MODELVIEW);
+    glPushMatrix();
+    glMultMatrix(transform_.GetTransposedMatrix().Data());
+    if(Scene::Instance().InOffscreenMode()) {
+      LOGN_TRACE("applying material");
+      mat_.RenderGL();
+    } else {
+      LOGN_TRACE("applying material display list");
+      glCallList(mat_dlist_);
+    }
+    LOGN_TRACE("calling custom render gl pass " << pass);
 
-void GfxObj::ContextSwitch()
-{
-  FlagRebuild();
-  GfxNode::ContextSwitch();
-}
+    CustomRenderGL(pass);
 
-/* 
-  this should not be necessary anymore
+    if(pass==0 && outline_flag_>0) {
+      va_.SetOutlineMode(outline_mode_);
+      CustomRenderGL(pass);
+      va_.SetOutlineMode(0);
+    }
 
-void GfxObj::RefreshVA(IndexedVertexArray& va)
-{
+    if(pass==1) {
+      LOGN_TRACE("drawing labels");
+      render_labels();
+    }
 
-  va.SetLineWidth(GetLineWidth());
-  va.SetPolyMode(GetPolyMode());
-  va.SetAALines(GetAALines());
-  va.SetLineHalo(GetLineHalo());
-  va.DrawNormals(debug_flags_&0x1);
-  va.SetPolyMode(debug_flags_&0x2 ? 1 : 2);
-  va.UseAmbient(use_occlusion_);
-  va.FlagRefresh();
+    glPopMatrix();    
+  }
 }
-*/
 
-void GfxObj::OnInput(const InputEvent& e) 
-{
-  geom::Mat3 rot=gfx::Scene::Instance().GetTransform().GetRot();
-  geom::Vec3 cam_trans=gfx::Scene::Instance().GetTransform().GetTrans();  
-  float x=e.GetDelta()*M_PI/180.0;
-  bool transformed=false;
-  if (e.GetCommand()==INPUT_COMMAND_ROTX) {
-    transformed=true;
-    transform_.SetRot(AxisRotation(geom::Vec3(1,0,0)*rot,x)*transform_.GetRot());
-  } else if(e.GetCommand()==INPUT_COMMAND_ROTY) {
-    transformed=true;
-    transform_.SetRot(AxisRotation(geom::Vec3(0,1,0)*rot,x)*transform_.GetRot());
-  } else if(e.GetCommand()==INPUT_COMMAND_ROTZ) {
-    transformed=true;
-    transform_.SetRot(AxisRotation(geom::Vec3(0,0,1)*rot,x)*transform_.GetRot());
-  } else if(e.GetCommand()==INPUT_COMMAND_TRANSX ||
-            e.GetCommand()==INPUT_COMMAND_TRANSY) {
- 
-    double mm[]={1,0,0,0,
-                 0,1,0,0,
-                 0,0,1,0,
-                 transform_.GetTrans()[0]-cam_trans[0],
-                 transform_.GetTrans()[1]-cam_trans[1],
-                 transform_.GetTrans()[2]-cam_trans[2], 1};
-    double pm[16];
-    glGetDoublev(GL_PROJECTION_MATRIX,pm);
-    GLint vp[4];
-    glGetIntegerv(GL_VIEWPORT,vp);
-    double wx,wy,wz;
-    gluProject(0.0,0.0,0.0,mm,pm,vp,&wx,&wy,&wz);
-    double ox,oy,oz;
-    gluUnProject(wx+1.0,wy+1.0,wz,mm,pm,vp,&ox,&oy,&oz);
 
-    float fx=ox;
-    float fy=oy;   
-    geom::Vec3 trans=transform_.GetTrans();
-    transformed=true;    
-    if (e.GetCommand()==INPUT_COMMAND_TRANSX) {
-      trans+=geom::Vec3(-fx*e.GetDelta(), 0.0, 0.0)*rot;
-    } else {
-      trans+=geom::Vec3(0.0, -fy*e.GetDelta(), 0.0)*rot;
+void GfxObj::RenderPov(PovState& pov)
+{
+  if(IsVisible()) {
+    pov.start_obj(GetName(),1.0,1.0,1.0);
+    // apply local transformation
+    // using transform_
+    if(rebuild_ || refresh_) {
+      PreRenderGL(true);
     }
-    transform_.SetTrans(trans);
-  }
-  if (transformed) {
-    GfxObjP obj=dyn_cast<GfxObj>(this->shared_from_this());
-    Scene::Instance().NodeTransformed(obj);
+    CustomRenderPov(pov);
+    pov.end_obj();
   }
 }
 
-const mol::Transform& GfxObj::GetTF() const
+void GfxObj::Apply(GfxNodeVisitor& v, GfxNodeVisitor::Stack st)
 {
-  return transform_;
+  v.VisitObject(this,st);
 }
 
-
-void GfxObj::SetTF(const mol::Transform& tf)
+int GfxObj::GetType() const
 {
-  transform_=tf;
+  return 1;
 }
 
-geom::Vec3 GfxObj::GetCenter() const 
+////////////////////////////////////////
+// now for the GfxObjBase interface
+void GfxObj::SetMatAmb(const Color& c)
 {
-  return this->GetBoundingBox().GetCenter();
+  mat_.SetAmb(c);
+  mat_update_=true;
+  Scene::Instance().RequestRedraw();
 }
 
-bool GfxObj::OnSelect(const geom::Line3& l, geom::Vec3& result, 
-                      float zlim, bool pick_flag)
+void GfxObj::SetMatDiff(const Color& c)
 {
-  return false;
+  mat_.SetDiff(c);
+  mat_update_=true;
+  Scene::Instance().RequestRedraw();
 }
 
-void GfxObj::SetRenderMode(RenderMode::Type m)
+void GfxObj::SetMatSpec(const Color& c)
 {
-  if (render_mode_==m) return;
-  render_mode_=m;
-  OnRenderModeChange();
-  FlagRebuild();
+  mat_.SetSpec(c);
+  mat_update_=true;
+  Scene::Instance().RequestRedraw();
 }
 
-RenderMode::Type GfxObj::GetRenderMode() const
+void GfxObj::SetMatShin(float s)
 {
-  return render_mode_;
+  mat_.SetShin(s);
+  mat_update_=true;
+  Scene::Instance().RequestRedraw();
 }
 
-void GfxObj::FlagRebuild()
+void GfxObj::SetMatEmm(const Color& c)
 {
-  rebuild_=true;
+  mat_.SetEmm(c);
+  mat_update_=true;
   Scene::Instance().RequestRedraw();
 }
 
-void GfxObj::FlagRefresh()
+void GfxObj::ContextSwitch()
 {
-  refresh_=true;
-  Scene::Instance().RequestRedraw();
+  FlagRebuild();
+  GfxNode::ContextSwitch();
 }
 
-void GfxObj::SetNormalSmoothFactor(float smoothf)
+void GfxObj::SetRenderMode(RenderMode::Type m)
 {
-  smoothf_=smoothf;
+  if (render_mode_==m) return;
+  render_mode_=m;
+  OnRenderModeChange();
   FlagRebuild();
 }
 
-float GfxObj::GetNormalSmoothFactor() const
+RenderMode::Type GfxObj::GetRenderMode() const
 {
-  return smoothf_;
+  return render_mode_;
 }
 
-void GfxObj::OnRenderModeChange()
+geom::Vec3 GfxObj::GetCenter() const 
 {
-  Scene::Instance().ObjectChanged(GetName());
-  Scene::Instance().RenderModeChanged(GetName());
+  return this->GetBoundingBox().GetCenter();
 }
 
 void GfxObj::SetLineWidth(float w)
@@ -293,47 +247,6 @@ void GfxObj::SetLineWidth(float w)
   Scene::Instance().RenderModeChanged(GetName());
 }
 
-float GfxObj::GetLineWidth() const
-{
-  return line_width_;
-}
-
-void GfxObj::SetSphereDetail(unsigned int d)
-{
-  if(d==sphere_detail_) return;
-  sphere_detail_=d;
-  FlagRebuild();
-}
-
-unsigned int GfxObj::GetSphereDetail() const
-{
-  return sphere_detail_;
-}
-
-void GfxObj::SetArcDetail(unsigned int d)
-{
-  if(d==arc_detail_) return;
-  arc_detail_=d;
-  FlagRebuild();
-}
-
-unsigned int GfxObj::GetArcDetail() const
-{
-  return arc_detail_;
-}
-
-void GfxObj::SetSplineDetail(unsigned int d)
-{
-  if(d==spline_detail_) return;
-  spline_detail_=d;
-  FlagRebuild();
-}
-
-unsigned int GfxObj::GetSplineDetail() const
-{
-  return spline_detail_;
-}
-
 void GfxObj::SetPolyMode(unsigned int m)
 {
   if(m==poly_mode_) return;
@@ -342,12 +255,7 @@ void GfxObj::SetPolyMode(unsigned int m)
   FlagRefresh();
 }
 
-unsigned int GfxObj::GetPolyMode() const
-{
-  return poly_mode_;
-}
-
-void GfxObj::SetAALines(bool f)
+void GfxObj::AALines(bool f)
 {
   if(f==aalines_flag_) return;
   va_.SetAALines(f);
@@ -355,11 +263,6 @@ void GfxObj::SetAALines(bool f)
   FlagRefresh();
 }
 
-bool GfxObj::GetAALines() const
-{
-  return aalines_flag_;
-}
-
 void GfxObj::SetLineHalo(float f)
 {
   va_.SetLineHalo(f);
@@ -367,15 +270,23 @@ void GfxObj::SetLineHalo(float f)
   FlagRefresh();
 }
 
-float GfxObj::GetLineHalo() const
+void GfxObj::Outline(bool f)
 {
-  return line_halo_;
+  outline_flag_=f;
+  FlagRefresh();
+  if(f) {
+    outline_mode_=std::min(3,std::max(1,outline_mode_));
+  }
+  Scene::Instance().RequestRedraw();
 }
 
 void GfxObj::SetOutlineMode(int m)
 {
-  omode_=m;
-  FlagRefresh();
+  outline_mode_=m;
+  if(outline_flag_) {
+    FlagRefresh();
+    Scene::Instance().RequestRedraw();
+  }
 }
 
 void GfxObj::SetOutlineExpandFactor(float f)
@@ -388,372 +299,262 @@ void GfxObj::SetOutlineExpandColor(const Color& c)
   va_.SetOutlineExpandColor(c);
 }
 
-void GfxObj::RenderGL(RenderPass pass)
+void GfxObj::AmbientOcclusion(bool f)
 {
-  LOGN_TRACE("object " << GetName() << ": RenderGL()");
-
-  if(pass==0) {
-    if(mat_update_) {
-      LOGN_TRACE("updating material display list");
-      if(mat_dlist_==0) {
-        mat_dlist_=glGenLists(1);
-      }
-      glNewList(mat_dlist_,GL_COMPILE);
-      mat_.RenderGL();
-      glEndList();
-      mat_update_=false;
-    }
-    
-    if(rebuild_ || refresh_) {
-      PreRenderGL(rebuild_);
-      rebuild_=false;
-      refresh_=false;
-    }
-  }
-  if(IsVisible()) {
-    LOGN_TRACE("applying local transformation");
-    glMatrixMode(GL_MODELVIEW);
-    glPushMatrix();
-    glMultMatrix(transform_.GetTransposedMatrix().Data());
-    if(Scene::Instance().InOffscreenMode()) {
-      LOGN_TRACE("applying material");
-      mat_.RenderGL();
-    } else {
-      LOGN_TRACE("applying material display list");
-      glCallList(mat_dlist_);
-    }
-    LOGN_TRACE("calling custom render gl pass " << pass);
-
-    CustomRenderGL(pass);
-
-    if(pass==0 && omode_>0) {
-      va_.SetOutlineMode(omode_);
-      CustomRenderGL(pass);
-      va_.SetOutlineMode(0);
-    }
-
-    if(pass==1) {
-      LOGN_TRACE("drawing labels");
-      render_labels();
-    }
-
-    glPopMatrix();    
-  }
+  va_.UseAmbient(f);
+  Scene::Instance().RequestRedraw();
 }
 
-
-void GfxObj::RenderPov(PovState& pov)
+void GfxObj::SetAmbientLocalWeight(float w)
 {
-  if(IsVisible()) {
-    pov.start_obj(GetName(),1.0,1.0,1.0);
-    // apply local transformation
-    // using transform_
-    if(rebuild_ || refresh_) {
-      PreRenderGL(true);
-    }
-    CustomRenderPov(pov);
-    pov.end_obj();
-  }
+  va_.AmbientLocalWeight(w);
+  Scene::Instance().RequestRedraw();
 }
 
-void GfxObj::PreRenderGL(bool f)
+void GfxObj::SetAmbientOcclusionWeight(float w)
 {
-  LOGN_DUMP("object " << GetName() << ": PreRenderGL()");
-  CustomPreRenderGL(f);
+  va_.AmbientOcclusionWeight(w);
+  Scene::Instance().RequestRedraw();
 }
 
-void GfxObj::Clear()
+void GfxObj::SetOpacity(float o)
 {
+  opacity_=o;
+  FlagRebuild();
 }
 
-Color GfxObj::Ele2Color(const String& ele)
+void GfxObj::ColorBy(const mol::EntityView& ev, 
+                      const String& prop,
+                      const Gradient& g, float minv, float maxv)
 {
-  // TODO 1: allow this table to be set by the user
-  // TODO 2: move this table to entity gfx
-  if(ele=="C") {return Color(0.83,0.97,0.97);}
-  else if(ele=="N") {return Color(0.0,0.0,1.0);}
-  else if(ele=="O") {return Color(1.0,0.0,0.0);}
-  else if(ele=="S") {return Color(1.0,1.0,0.0);}
-  else if(ele=="P") {return Color(1.0,0.0,1.0);}
-  else if(ele=="H") {return Color(0.95,0.95,1.0);}
-  
-  return Color(0.8,0.8,0.8);
+  LOGN_VERBOSE("ColorBy not implemented for this gfx object");
 }
 
-void GfxObj::AddLabel(const String& s, const geom::Vec3& pos, const Color& col, float psize)
+#if OST_IMG_ENABLED
+void GfxObj::ColorBy(const img::MapHandle& mh,
+                      const String& prop,
+                      const Gradient& g, float minv, float maxv)
 {
-  labels_.push_back(TextPrim(s,pos,col,psize));
+  LOGN_VERBOSE("ColorBy not implemented for this gfx object");
 }
+#endif
 
-void GfxObj::AddLabel(const String& s, const geom::Vec3& pos, const Color& col)
-{
-  AddLabel(s,pos,col,1.0);
-}
+//////////////////////////////////////////////////
+// and now for the rest of the GfxObj interface
 
-void GfxObj::AddLabel(const String& s, const geom::Vec3& pos, float psize)
+geom::AlignedCuboid GfxObj::GetBoundingBox() const
 {
-  AddLabel(s,pos,Color(1,1,1),psize);
+  return geom::AlignedCuboid(geom::Vec3(),geom::Vec3());
 }
 
-void GfxObj::AddLabel(const String& s, const geom::Vec3& pos)
+void GfxObj::ProcessLimits(geom::Vec3& minc, geom::Vec3& maxc, 
+                           const mol::Transform& tf) const
 {
-  AddLabel(s,pos,Color(1,1,1),1.0);
+  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], 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))))))));
+  } catch(Error& e) {
+    // in case the object is empty...
+  }
 }
 
-void GfxObj::ClearLabels()
-{
-  labels_.clear();
-}
 
-void GfxObj::SetMatAmb(const Color& c)
-{
-  mat_.SetAmb(c);
-  mat_update_=true;
-  Scene::Instance().RequestRedraw();
-}
+void GfxObj::CustomRenderGL(RenderPass pass) {}
 
-void GfxObj::SetMatAmb(float c)
-{
-  mat_.SetAmb(c);
-  mat_update_=true;
-  Scene::Instance().RequestRedraw();
-}
+void GfxObj::CustomPreRenderGL(bool flag) {}
 
-void GfxObj::SetMatDiff(const Color& c)
-{
-  mat_.SetDiff(c);
-  mat_update_=true;
-  Scene::Instance().RequestRedraw();
-}
+void GfxObj::CustomRenderPov(PovState& pov) {}
 
-void GfxObj::SetMatDiff(float c)
+bool GfxObj::OnSelect(const geom::Line3& l, geom::Vec3& result, 
+                      float zlim, bool pick_flag)
 {
-  mat_.SetDiff(c);
-  mat_update_=true;
-  Scene::Instance().RequestRedraw();
+  return false;
 }
 
-void GfxObj::SetMatSpec(const Color& c)
+void GfxObj::OnInput(const InputEvent& e) 
 {
-  mat_.SetSpec(c);
-  mat_update_=true;
-  Scene::Instance().RequestRedraw();
-}
+  geom::Mat3 rot=gfx::Scene::Instance().GetTransform().GetRot();
+  geom::Vec3 cam_trans=gfx::Scene::Instance().GetTransform().GetTrans();  
+  float x=e.GetDelta()*M_PI/180.0;
+  bool transformed=false;
+  if (e.GetCommand()==INPUT_COMMAND_ROTX) {
+    transformed=true;
+    transform_.SetRot(AxisRotation(geom::Vec3(1,0,0)*rot,x)*transform_.GetRot());
+  } else if(e.GetCommand()==INPUT_COMMAND_ROTY) {
+    transformed=true;
+    transform_.SetRot(AxisRotation(geom::Vec3(0,1,0)*rot,x)*transform_.GetRot());
+  } else if(e.GetCommand()==INPUT_COMMAND_ROTZ) {
+    transformed=true;
+    transform_.SetRot(AxisRotation(geom::Vec3(0,0,1)*rot,x)*transform_.GetRot());
+  } else if(e.GetCommand()==INPUT_COMMAND_TRANSX ||
+            e.GetCommand()==INPUT_COMMAND_TRANSY) {
+ 
+    double mm[]={1,0,0,0,
+                 0,1,0,0,
+                 0,0,1,0,
+                 transform_.GetTrans()[0]-cam_trans[0],
+                 transform_.GetTrans()[1]-cam_trans[1],
+                 transform_.GetTrans()[2]-cam_trans[2], 1};
+    double pm[16];
+    glGetDoublev(GL_PROJECTION_MATRIX,pm);
+    GLint vp[4];
+    glGetIntegerv(GL_VIEWPORT,vp);
+    double wx,wy,wz;
+    gluProject(0.0,0.0,0.0,mm,pm,vp,&wx,&wy,&wz);
+    double ox,oy,oz;
+    gluUnProject(wx+1.0,wy+1.0,wz,mm,pm,vp,&ox,&oy,&oz);
 
-void GfxObj::SetMatSpec(float c)
-{
-  mat_.SetSpec(c);
-  mat_update_=true;
-  Scene::Instance().RequestRedraw();
+    float fx=ox;
+    float fy=oy;   
+    geom::Vec3 trans=transform_.GetTrans();
+    transformed=true;    
+    if (e.GetCommand()==INPUT_COMMAND_TRANSX) {
+      trans+=geom::Vec3(-fx*e.GetDelta(), 0.0, 0.0)*rot;
+    } else {
+      trans+=geom::Vec3(0.0, -fy*e.GetDelta(), 0.0)*rot;
+    }
+    transform_.SetTrans(trans);
+  }
+  if (transformed) {
+    GfxObjP obj=dyn_cast<GfxObj>(this->shared_from_this());
+    Scene::Instance().NodeTransformed(obj);
+  }
 }
 
-void GfxObj::SetMatShin(float s)
+const mol::Transform& GfxObj::GetTF() const
 {
-  mat_.SetShin(s);
-  mat_update_=true;
-  Scene::Instance().RequestRedraw();
+  return transform_;
 }
 
-void GfxObj::SetMatEmm(const Color& c)
-{
-  mat_.SetEmm(c);
-  mat_update_=true;
-  Scene::Instance().RequestRedraw();
-}
 
-void GfxObj::SetMatEmm(float c)
+void GfxObj::SetTF(const mol::Transform& tf)
 {
-  mat_.SetEmm(c);
-  mat_update_=true;
-  Scene::Instance().RequestRedraw();
+  transform_=tf;
 }
 
-void GfxObj::SetMat(const Color& amb, const Color& diff, const Color& spec, float shin)
+void GfxObj::FlagRebuild()
 {
-  SetMatAmb(amb);
-  SetMatDiff(diff);
-  SetMatSpec(spec);
-  SetMatShin(shin);
-  SetMatEmm(0.0);
-  mat_update_=true;
+  rebuild_=true;
   Scene::Instance().RequestRedraw();
 }
 
-void GfxObj::SetMat(float amb, float diff, float spec, float shin)
+void GfxObj::FlagRefresh()
 {
-  SetMatAmb(amb);
-  SetMatDiff(diff);
-  SetMatSpec(spec);
-  SetMatShin(shin);
-  SetMatEmm(0.0);
-  mat_update_=true;
+  refresh_=true;
   Scene::Instance().RequestRedraw();
 }
 
-Material GfxObj::GetMaterial() const
-{
-  return mat_;
-}
-
-void GfxObj::SetMaterial(const Material& m)
-{
-  mat_=m;
-}
-
-void GfxObj::GLCleanup()
-{
-  if(mat_dlist_!=0) {
-    glDeleteLists(mat_dlist_,1);
-    mat_dlist_=0;
-  }
-  OnGLCleanup();
-}
-
-void GfxObj::OnGLCleanup()
-{}
-
-void GfxObj::SetOpacity(float o)
+void GfxObj::SetNormalSmoothFactor(float smoothf)
 {
-  opacity_=o;
+  smoothf_=smoothf;
   FlagRebuild();
 }
 
-float GfxObj::GetOpacity() const
-{
-  return opacity_;
-}
-
-void GfxObj::SmoothVertices(float smoothf)
+float GfxObj::GetNormalSmoothFactor() const
 {
-  va_.SmoothVertices(smoothf);
-  FlagRefresh();
+  return smoothf_;
 }
 
-void GfxObj::AmbientOcclusion(bool f)
+void GfxObj::OnRenderModeChange()
 {
-  va_.UseAmbient(f);
-  Scene::Instance().RequestRedraw();
+  Scene::Instance().ObjectChanged(GetName());
+  Scene::Instance().RenderModeChanged(GetName());
 }
 
-void GfxObj::AmbientLocalWeight(float w)
+void GfxObj::PreRenderGL(bool f)
 {
-  va_.AmbientLocalWeight(w);
-  Scene::Instance().RequestRedraw();
+  LOGN_DUMP("object " << GetName() << ": PreRenderGL()");
+  CustomPreRenderGL(f);
 }
 
-void GfxObj::AmbientOcclusionWeight(float w)
+void GfxObj::Clear()
 {
-  va_.AmbientOcclusionWeight(w);
-  Scene::Instance().RequestRedraw();
+  va_.Clear();
 }
 
-void GfxObj::ColorBy(const mol::EntityView& ev, 
-                      const String& prop,
-                      const Gradient& g, float minv, float maxv)
+Color GfxObj::Ele2Color(const String& ele)
 {
-  LOGN_VERBOSE("ColorBy not implemented for this gfx object");
+  // TODO 1: allow this table to be set by the user
+  // TODO 2: move this table to entity gfx
+  if(ele=="C") {return Color(0.83,0.97,0.97);}
+  else if(ele=="N") {return Color(0.0,0.0,1.0);}
+  else if(ele=="O") {return Color(1.0,0.0,0.0);}
+  else if(ele=="S") {return Color(1.0,1.0,0.0);}
+  else if(ele=="P") {return Color(1.0,0.0,1.0);}
+  else if(ele=="H") {return Color(0.95,0.95,1.0);}
+  
+  return Color(0.8,0.8,0.8);
 }
 
-
-void GfxObj::ColorBy(const mol::EntityView& ev, 
-                      const String& prop,
-                      const Color& c1, const Color& c2, float minv, float maxv)
+void GfxObj::AddLabel(const String& s, const geom::Vec3& pos, const Color& col, float psize)
 {
-  Gradient g;
-  g.SetColorAt(0.0,c1);
-  g.SetColorAt(1.0,c2);
-  this->ColorBy(ev,prop,g,minv,maxv);
+  labels_.push_back(TextPrim(s,pos,col,psize));
 }
 
-#if OST_IMG_ENABLED
-void GfxObj::ColorBy(const img::MapHandle& mh,
-                      const String& prop,
-                      const Gradient& g, float minv, float maxv)
+void GfxObj::AddLabel(const String& s, const geom::Vec3& pos, const Color& col)
 {
-  LOGN_VERBOSE("ColorBy not implemented for this gfx object");
+  AddLabel(s,pos,col,1.0);
 }
 
-void GfxObj::ColorBy(const img::MapHandle& mh,
-                      const String& prop,
-                      const Color& c1, const Color& c2, float minv, float maxv)
+void GfxObj::AddLabel(const String& s, const geom::Vec3& pos, float psize)
 {
-  Gradient g;
-  g.SetColorAt(0.0,c1);
-  g.SetColorAt(1.0,c2);
-  this->ColorBy(mh,prop,g,minv,maxv);
+  AddLabel(s,pos,Color(1,1,1),psize);
 }
 
-void GfxObj::ColorBy(const img::MapHandle& mh,
-                      const String& prop,
-                      const Gradient& g)
+void GfxObj::AddLabel(const String& s, const geom::Vec3& pos)
 {
-  ost::img::alg::Stat stat;
-  mh.Apply(stat);
-  float min = static_cast<float>(stat.GetMinimum());
-  float max = static_cast<float>(stat.GetMaximum());
-  std::pair<float,float> minmax = std::make_pair(min,max);
-  this->ColorBy(mh,prop,g,minmax.first, minmax.second);
+  AddLabel(s,pos,Color(1,1,1),1.0);
 }
 
-void GfxObj::ColorBy(const img::MapHandle& mh,
-                      const String& prop,
-                      const Color& c1, const Color& c2)
+void GfxObj::ClearLabels()
 {
-  ost::img::alg::Stat stat;
-  mh.Apply(stat);
-  float min = static_cast<float>(stat.GetMinimum());
-  float max = static_cast<float>(stat.GetMaximum());
-  std::pair<float,float> minmax = std::make_pair(min,max);
-  this->ColorBy(mh,prop,c1,c2,minmax.first, minmax.second);
+  labels_.clear();
 }
 
-#endif //OST_IMG_ENABLED
 
-void GfxObj::ColorBy(const mol::EntityHandle& eh, 
-                      const String& prop,
-                      const Gradient& g, float minv, float maxv)
-{
-  this->ColorBy(eh.CreateFullView(),prop,g,minv,maxv);
-}
-    
-void GfxObj::ColorBy(const mol::EntityHandle& eh, 
-                      const String& prop,
-                      const Color& c1, const Color& c2, float minv, float maxv)
+Material GfxObj::GetMaterial() const
 {
-  Gradient g;
-  g.SetColorAt(0.0,c1);
-  g.SetColorAt(1.0,c2);
-  this->ColorBy(eh,prop,g,minv,maxv);
+  return mat_;
 }
 
-void GfxObj::ColorBy(const mol::EntityView& ev, 
-                      const String& prop,
-                      const Gradient& g)
-{
-  std::pair<float,float> minmax = ev.GetMinMax(prop);
-  this->ColorBy(ev,prop,g,minmax.first, minmax.second);
-}
-    
-void GfxObj::ColorBy(const mol::EntityView& ev, 
-                      const String& prop,
-                      const Color& c1, const Color& c2)
+void GfxObj::SetMaterial(const Material& m)
 {
-  std::pair<float,float> minmax = ev.GetMinMax(prop);
-  this->ColorBy(ev,prop,c1,c2,minmax.first, minmax.second);
+  mat_=m;
 }
 
-void GfxObj::ColorBy(const mol::EntityHandle& eh, 
-                      const String& prop,
-                      const Gradient& g)
+void GfxObj::GLCleanup()
 {
-  this->ColorBy(eh.CreateFullView(),prop,g);
+  if(mat_dlist_!=0) {
+    glDeleteLists(mat_dlist_,1);
+    mat_dlist_=0;
+  }
+  OnGLCleanup();
 }
 
-void GfxObj::ColorBy(const mol::EntityHandle& eh, 
-                      const String& prop,
-                      const Color& c1, const Color& c2)
+void GfxObj::OnGLCleanup()
+{}
+
+void GfxObj::SmoothVertices(float smoothf)
 {
-  this->ColorBy(eh.CreateFullView(),prop,c1,c2);
+  va_.SmoothVertices(smoothf);
+  FlagRefresh();
 }
 
 namespace {
diff --git a/modules/gfx/src/gfx_object.hh b/modules/gfx/src/gfx_object.hh
index 7f4ac97c20983a423f5f2ab27625632849f60110..0b9322542f19f4aebf671f58c68d5fe63af0e1ce 100644
--- a/modules/gfx/src/gfx_object.hh
+++ b/modules/gfx/src/gfx_object.hh
@@ -33,58 +33,67 @@
 #include <ost/config.hh>
 #include <ost/gfx/module_config.hh>
 
-#include <ost/gfx/color_ops/color_op.hh>
-
-#include <ost/geom/geom.hh>
-#include <ost/mol/entity_handle.hh>
-#include <ost/mol/entity_view.hh>
 #include <ost/mol/transform.hh>
 
-
-#if OST_IMG_ENABLED
-#  include <ost/img/map.hh>
-#endif
-
 #include "gfx_object_fw.hh"
-#include "gfx_node.hh"
+#include "gfx_object_base.hh"
 #include "gfx_prim.hh"
 #include "vertex_array.hh"
 #include "input.hh"
-#include "render_mode.hh"
-#include "material.hh"
-#include "gradient.hh"
-
 
 namespace ost { namespace gfx {
 
 class Scene; // fw decl
 
-/// \brief Base class for all graphical rendering objects
-class DLLEXPORT_OST_GFX GfxObj: public GfxNode
+/// \brief main class for all graphic objects
+class DLLEXPORT_OST_GFX GfxObj: public GfxObjBase
 {
-
 public:
   GfxObj(const String& name);
-  virtual ~GfxObj();
 
+  // gfx node interface
   virtual GfxNodeP Copy() const;
-
+  virtual void DeepSwap(GfxObj& go);
+  virtual void RenderGL(RenderPass pass);
+  virtual void RenderPov(PovState& pov);
   virtual void Apply(GfxNodeVisitor& v,GfxNodeVisitor::Stack st);
-
   virtual int GetType() const;
+  //
+
+  // gfx obj base interface
+  virtual void SetMatAmb(const Color& c);
+  virtual void SetMatDiff(const Color& c);
+  virtual void SetMatSpec(const Color& c);
+  virtual void SetMatShin(float s);
+  virtual void SetMatEmm(const Color& c);
+  virtual void ContextSwitch();
+  virtual void SetRenderMode(RenderMode::Type m);
+  virtual RenderMode::Type GetRenderMode() const;
+  virtual geom::Vec3 GetCenter() const;
+  virtual void SetLineWidth(float w);
+  virtual void SetPolyMode(unsigned int m);
+  virtual void AALines(bool f);
+  virtual void SetLineHalo(float f);
+  virtual void Outline(bool f);
+  virtual void SetOutlineMode(int m);
+  virtual void SetOutlineExpandFactor(float f);
+  virtual void SetOutlineExpandColor(const Color& c);
+  virtual void AmbientOcclusion(bool f);
+  virtual void SetAmbientLocalWeight(float w);
+  virtual void SetAmbientOcclusionWeight(float w);
+  virtual void SetOpacity(float f);
+  virtual void ColorBy(const mol::EntityView& ev, 
+                       const String& prop,
+                       const Gradient& g, float minv, float maxv);
+#if OST_IMG_ENABLED
+  virtual void ColorBy(const img::MapHandle& mh,
+                       const String& prop,
+                       const Gradient& g,float minv, float maxv);
+#endif
 
-  virtual void RenderGL(RenderPass pass);
-
-  virtual void RenderPov(PovState& pov);
+  // end of gfx obj base interface
 
-  void Clear();
-  
-  /// \brief get transform
-  const mol::Transform& GetTF() const;
-  /// \brief set transform
-  void SetTF(const mol::Transform& tf);
-  
-  virtual geom::Vec3 GetCenter() const;
+  // 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
@@ -98,8 +107,10 @@ public:
   virtual void ProcessLimits(geom::Vec3& minc, geom::Vec3& maxc, 
                              const mol::Transform& tf) const;
 
+  // implemented in derived classes for the actual GL rendering
   virtual void CustomRenderGL(RenderPass pass);
 
+  // implemented in derived classes for the actual POVray export
   virtual void CustomRenderPov(PovState& pov);
 
   // handle pick (select) event
@@ -116,47 +127,20 @@ public:
 
   // input event entry point
   virtual void OnInput(const InputEvent& e);
-  
-  virtual void DeepSwap(GfxObj& go);
-  
+
+  // informs derived class that render mode has changes
   virtual void OnRenderModeChange();
   virtual void OnGLCleanup();
+  //
 
-  virtual void ContextSwitch();
-
-  /// \brief change render mode
-  virtual void SetRenderMode(RenderMode::Type m);
-  /// \brief current render mode
-  RenderMode::Type GetRenderMode() const;
-
-  /// \brief set line width
-  void SetLineWidth(float w);
+  /// \brief removes all graphical elements
+  void Clear();
+  
+  /// \brief get transform
+  const mol::Transform& GetTF() const;
+  /// \brief set transform
+  void SetTF(const mol::Transform& tf);
   
-  /// \brief get line width 
-  float GetLineWidth() const;
-
-  void SetSphereDetail(unsigned int d);
-  unsigned int GetSphereDetail() const;
-
-  // subdivions per 90deg
-  void SetArcDetail(unsigned int d);
-  unsigned int GetArcDetail() const;
-
-  void SetSplineDetail(unsigned int d);
-  unsigned int GetSplineDetail() const;
-
-  void SetPolyMode(unsigned int m);
-  unsigned int GetPolyMode() const;
-
-  // sophisticated line anti-aliasing, requires shader
-  void SetAALines(bool f);
-  bool GetAALines() const;
-
-  void SetLineHalo(float f);
-  float GetLineHalo() const;
-
-  void SetOutline(unsigned int m);
-
   // add a label at the given position
   void AddLabel(const String& s, const geom::Vec3& pos, const Color& col, float psize);
   // convenience method
@@ -165,108 +149,30 @@ public:
   void AddLabel(const String& s, const geom::Vec3& pos, float psize);
   // convenience method
   void AddLabel(const String& s, const geom::Vec3& pos);
-
   // remove all labels
   void ClearLabels();
 
-  void SetMatAmb(const Color& c);
-  void SetMatAmb(float c);
-  void SetMatDiff(const Color& c);
-  void SetMatDiff(float c);
-  void SetMatSpec(const Color& c);
-  void SetMatSpec(float c);
-  void SetMatShin(float s);
-  void SetMatEmm(const Color& c);
-  void SetMatEmm(float c);
-  void SetMat(const Color& amb, const Color& diff, const Color& spec, float shin);
-  void SetMat(float amb, float diff, float spec, float shin);
-
-  void SetOpacity(float o);
-  float GetOpacity() const;
-
-  static Color Ele2Color(const String& ele);
-
   void FlagRebuild();
   void FlagRefresh();
 
+  bool GetAALines() const {return aalines_flag_;}
+  float GetLineWidth() const {return line_width_;}
+  float GetLineHalo() const {return line_halo_;}
+  float GetOpacity() const {return opacity_;}
+
   void SetNormalSmoothFactor(float smoothf);
   float GetNormalSmoothFactor() const;
 
   Material GetMaterial() const;
   void SetMaterial(const Material& m);
 
-  void SetOutlineMode(int m);
-  void SetOutlineExpandFactor(float f);
-  void SetOutlineExpandColor(const Color& c);
-
-  /// \brief ambient occlusion rendering
-  /// results are cached, but may be very slow on first call 
-  void AmbientOcclusion(bool f);
-  
-  /// \brief blending weight of local color to fragment color
-  void AmbientLocalWeight(float w);
-
-  /// \brief blending weight of occlusion factor
-  void AmbientOcclusionWeight(float w);
-
   // experimental, don't use
   void SmoothVertices(float smoothf);
  
   void GLCleanup();
 
-  /// \brief color each component based on the gradient-mapped property of 
-  ///    the given entity
-  virtual void ColorBy(const mol::EntityView& ev, 
-                       const String& prop,
-                       const Gradient& g, float minv, float maxv);
-    
-  /// \brief convenience method
-  void ColorBy(const mol::EntityView& ev, 
-               const String& prop,
-               const Color& c1, const Color& c2, float minv, float maxv);
-
-  /// \brief convenience method
-  void ColorBy(const mol::EntityHandle& eh, 
-               const String& prop,
-               const Gradient& g, float minv, float maxv);
-  /// \brief convenience method
-  void ColorBy(const mol::EntityHandle& eh, 
-               const String& prop,
-               const Color& c1, const Color& c2, float minv, float maxv);
-  // convenience method
-  void ColorBy(const mol::EntityView& ev, 
-               const String& prop,
-               const Gradient& g);
-  // convenience method
-  void ColorBy(const mol::EntityView& ev, 
-               const String& prop,
-               const Color& c1, const Color& c2);
-  // convenience method
-  void ColorBy(const mol::EntityHandle& ev, 
-               const String& prop,
-               const Gradient& g);
-  // convenience method
-  void ColorBy(const mol::EntityHandle& ev, 
-               const String& prop,
-               const Color& c1, const Color& c2);
-#if OST_IMG_ENABLED
-  // convenience method
-  void ColorBy(const img::MapHandle& mh,
-               const String& prop,
-               const Gradient& g);
-  // convenience method
-  void ColorBy(const img::MapHandle& mh,
-               const String& prop,
-               const Color& c1, const Color& c2);
-  // dito for maps
-  virtual void ColorBy(const img::MapHandle& mh,
-                       const String& prop,
-                       const Gradient& g,float minv, float maxv);
-  // convenience method
-  void ColorBy(const img::MapHandle& mh,
-               const String& prop,
-               const Color& c1, const Color& c2, float minv, float maxv);  
-#endif
+  // this really should not be here
+  static Color Ele2Color(const String& ele);
 
   void Debug(unsigned int flags);
 
@@ -275,9 +181,6 @@ public:
   void PreRenderGL(bool flag);
   virtual void CustomPreRenderGL(bool flag);
 
-  //void RefreshVA(IndexedVertexArray& va);
-  //virtual void RefreshVA() {RefreshVA(va_);}
-  
  private:
   GfxObj(const GfxObj& o);
   GfxObj& operator=(const GfxObj&);
@@ -286,6 +189,7 @@ public:
   void AppendColorOp(gfx::ColorOp* op);
   void CleanColorOps();
   void ReapplyColorOps();
+  void render_labels() const;
 
   IndexedVertexArray va_;
   RenderMode::Type render_mode_;
@@ -295,9 +199,6 @@ public:
   bool rebuild_;
   bool refresh_;
   float line_width_;
-  unsigned int sphere_detail_;
-  unsigned int arc_detail_;
-  unsigned int spline_detail_;
   unsigned int poly_mode_;
   bool aalines_flag_;
   float line_halo_;
@@ -308,12 +209,12 @@ public:
 
   float opacity_;
   float smoothf_;
-  int omode_;
+  bool outline_flag_;
+  int outline_mode_;
 
   boost::ptr_vector<gfx::ColorOp> c_ops_;
 
   TextPrimList labels_;
-  void render_labels() const;
 
   bool use_occlusion_;
 };
diff --git a/modules/gfx/src/gfx_object_base.hh b/modules/gfx/src/gfx_object_base.hh
new file mode 100644
index 0000000000000000000000000000000000000000..bcbf4613f8e1c7216988845e1f93ccf72e229685
--- /dev/null
+++ b/modules/gfx/src/gfx_object_base.hh
@@ -0,0 +1,134 @@
+//------------------------------------------------------------------------------
+// This file is part of the OpenStructure project <www.openstructure.org>
+//
+// Copyright (C) 2008-2010 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_OBJ_BASE_HH
+#define OST_GFX_OBJ_BASE_HH
+
+/*
+  Author: Ansgar Philippsen
+*/
+
+#include <ost/geom/geom.hh>
+#include <ost/mol/entity_handle.hh>
+#include <ost/mol/entity_view.hh>
+#if OST_IMG_ENABLED
+#  include <ost/img/map.hh>
+#endif
+
+#include <ost/config.hh>
+#include "module_config.hh"
+
+#include "gfx_node.hh"
+#include "color.hh"
+#include "render_mode.hh"
+#include "gradient.hh"
+#include "material.hh"
+#include "color_ops/color_op.hh"
+
+namespace ost { namespace gfx {
+
+class Scene; // fw decl
+
+/// \brief main interface for all graphic objects, both in C++ and Python
+/*
+  this abstract base class is for both the actual GfxObj as well as a 
+  shortly implemented re-design of the GfxNode, and hence temporary in
+  its current form
+*/
+class DLLEXPORT_OST_GFX GfxObjBase: public GfxNode
+{
+ public:
+  GfxObjBase(const String& name): GfxNode(name) {}
+  
+  /// \brief material ambient color
+  virtual void SetMatAmb(const Color& c) = 0;
+  /// \brief material diffuse color
+  virtual void SetMatDiff(const Color& c) = 0;
+  /// \brief material specular color
+  virtual void SetMatSpec(const Color& c) = 0;
+  /// \brief material shininess
+  virtual void SetMatShin(float s) = 0;
+  /// \brief material emmissive color
+  virtual void SetMatEmm(const Color& c) = 0;
+
+  /// \brief rendering context switch, some things need to be regenerated
+  virtual void ContextSwitch() = 0;
+
+  /// \brief change render mode
+  virtual void SetRenderMode(RenderMode::Type m) = 0;
+  /// \brief current render mode
+  virtual RenderMode::Type GetRenderMode() const = 0;
+  
+  /// \brief get geometric center
+  virtual geom::Vec3 GetCenter() const = 0;
+
+  /// \brief set line width
+  virtual void SetLineWidth(float w) = 0;
+  
+  /// \brief set polygon mode
+  virtual void SetPolyMode(unsigned int m) = 0;
+
+  /// \brief turn on sophisticated line anti-aliasing, requires shader
+  virtual void AALines(bool f) = 0;
+
+  /// \brief turn on line halo of given strength
+  virtual void SetLineHalo(float f) = 0;
+
+  /// \brief turn outline rendering on or off
+  virtual void Outline(bool f) = 0;
+
+  /// \brief set outline mode
+  virtual void SetOutlineMode(int m) = 0;
+  /// \brief set outline tweak factor
+  virtual void SetOutlineExpandFactor(float f) = 0;
+  /// \brief set outline color
+  virtual void SetOutlineExpandColor(const Color& c) = 0;
+
+  /// \brief ambient occlusion rendering
+  /// results are cached, but may be very slow on first call 
+  virtual void AmbientOcclusion(bool f) = 0;
+  
+  /// \brief blending weight of local color to fragment color
+  virtual void SetAmbientLocalWeight(float w) = 0;
+  
+  /// \brief blending weight of occlusion factor
+  virtual void SetAmbientOcclusionWeight(float w) = 0;
+
+  /// \brief set opacity (1 = no transparency)
+  virtual void SetOpacity(float f) = 0;
+
+  /// \brief color each component based on the gradient-mapped property of 
+  ///    the given entity
+  virtual void ColorBy(const mol::EntityView& ev, 
+                       const String& prop,
+                       const Gradient& g, float minv, float maxv) = 0;
+
+#if OST_IMG_ENABLED
+  /// \brief color based on image
+  virtual void ColorBy(const img::MapHandle& mh,
+                       const String& prop,
+                       const Gradient& g,float minv, float maxv) = 0;
+#endif
+    
+
+
+};
+
+}} // ns
+
+#endif
diff --git a/modules/gfx/src/map_iso.cc b/modules/gfx/src/map_iso.cc
index 5e340622b227f995609ed60622784fec9efc2efe..20736f6c981ebafc4426a17ff2253355259e3275 100644
--- a/modules/gfx/src/map_iso.cc
+++ b/modules/gfx/src/map_iso.cc
@@ -72,7 +72,10 @@ MapIso::MapIso(const String& name, const img::MapHandle& mh, float level):
   debug_octree_(false),
   color_(Color::GREY)
 {
-  SetMat(0.0,1.0,0.1,32.0);
+  SetMatAmb(Color(0,0,0));
+  SetMatDiff(Color(1,1,1));
+  SetMatSpec(Color(0.1,0.1,0.1));
+  SetMatShin(32);
   mol::Transform tf=this->GetTF();
   tf.SetCenter(this->GetCenter());
   tf.SetTrans(this->GetCenter());
@@ -94,7 +97,10 @@ MapIso::MapIso(const String& name, const img::MapHandle& mh,
   color_(Color::GREY)
 {
   // TODO replace with def mat for this gfx obj type
-  SetMat(0.0,1.0,0.1,32.0);
+  SetMatAmb(Color(0,0,0));
+  SetMatDiff(Color(1,1,1));
+  SetMatSpec(Color(0.1,0.1,0.1));
+  SetMatShin(32);
   mol::Transform tf=this->GetTF();
   tf.SetCenter(this->GetCenter());
   tf.SetTrans(this->GetCenter());  
diff --git a/modules/gfx/src/prim_list.cc b/modules/gfx/src/prim_list.cc
index c2b4641bc66e53cd4f2403c6ff8b1a28444ab199..4c2395c1400088038a6cf5e4aeb48fab152a6383 100644
--- a/modules/gfx/src/prim_list.cc
+++ b/modules/gfx/src/prim_list.cc
@@ -31,7 +31,9 @@ PrimList::PrimList(const String& name):
   points_(),
   lines_(),
   radius_(0.5),
-  diameter_(0.5)
+  diameter_(0.5),
+  sphere_detail_(4),
+  arc_detail_(4)
 {}
 
 void PrimList::Clear()
@@ -153,12 +155,28 @@ void PrimList::SetDiameter(float d)
 {
   diameter_=d;
   Scene::Instance().RequestRedraw();
+  FlagRebuild();
 }
 
 void PrimList::SetRadius(float r)
 {
   radius_=r;
   Scene::Instance().RequestRedraw();
+  FlagRebuild();
+}
+
+void PrimList::SetSphereDetail(unsigned int d)
+{
+  sphere_detail_=d;
+  Scene::Instance().RequestRedraw();
+  FlagRebuild();
+}
+
+void PrimList::SetArcDetail(unsigned int d)
+{
+  arc_detail_=d;
+  Scene::Instance().RequestRedraw();
+  FlagRebuild();
 }
 
 void PrimList::SetColor(const Color& c)
@@ -167,6 +185,7 @@ void PrimList::SetColor(const Color& c)
     it->color=c;
   }
   Scene::Instance().RequestRedraw();
+  FlagRebuild();
 }
 
 
diff --git a/modules/gfx/src/prim_list.hh b/modules/gfx/src/prim_list.hh
index 1de40d7f9c862cc71fd995b7fd8d5c300c081304..fbac2cffc2f633bdf5bfe4ef8fc20ce6658c72d4 100644
--- a/modules/gfx/src/prim_list.hh
+++ b/modules/gfx/src/prim_list.hh
@@ -98,6 +98,12 @@ class DLLEXPORT_OST_GFX PrimList: public GfxObj
   /// \brief set global prims color, overriding individual ones
   void SetColor(const Color& c);
 
+  void SetSphereDetail(unsigned int d);
+  unsigned int GetSphereDetail() const {return sphere_detail_;}
+
+  void SetArcDetail(unsigned int d);
+  unsigned int GetArcDetail() const {return arc_detail_;}
+
  protected:
   virtual void CustomPreRenderGL(bool flag);
 
@@ -106,6 +112,8 @@ class DLLEXPORT_OST_GFX PrimList: public GfxObj
   LineEntryList lines_;
   float radius_;
   float diameter_;
+  unsigned int sphere_detail_;
+  unsigned int arc_detail_;
   
   void render_simple();
   void render_custom();
diff --git a/modules/gfx/src/surface.cc b/modules/gfx/src/surface.cc
index a3ec9db3940758706dfac4c3729040c67a04bb84..40db431fe9aa9cf3954e2d831d07f45ecc5796ed 100644
--- a/modules/gfx/src/surface.cc
+++ b/modules/gfx/src/surface.cc
@@ -43,7 +43,10 @@ Surface::Surface(const String& name, const mol::SurfaceHandle& sh):
   recalc_bb_(true)
 {
   // TODO replace with def mat for this gfx obj type
-  SetMat(0.0,1.0,0.2,48.0);
+  SetMatAmb(Color(0,0,0));
+  SetMatDiff(Color(1,1,1));
+  SetMatSpec(Color(0.2,0.2,0.2));
+  SetMatShin(48);
   Rebuild();
 }