diff --git a/modules/gfx/pymod/export_entity.cc b/modules/gfx/pymod/export_entity.cc
index 23e341b04754d0d960e78747277459dba023d54c..8d80170fb5ad45da30da851cc7a816a292b00c77 100644
--- a/modules/gfx/pymod/export_entity.cc
+++ b/modules/gfx/pymod/export_entity.cc
@@ -92,6 +92,16 @@ void color_by_08(Entity* e,
   e->ColorBy(prop,c1,c2);
 }
 
+// temporary, see comment in gfx/entity.hh
+void detail_color_by_02(Entity* e,
+                        const String& prop, 
+                        const Gradient& gradient,
+                        float minv,float maxv)
+{
+  e->DetailColorBy(prop,gradient,minv,maxv);
+}
+
+
 void radius_by_01(Entity* e,
                   const String& prop, 
                   float rmin,float rmax,
@@ -245,6 +255,7 @@ void export_Entity()
     .add_property("selection", &Entity::GetSelection, 
                   &Entity::SetSelection)
     .def("GetView", &Entity::GetView)
+    .def("UpdateView", &Entity::UpdateView)
     .def("GetRenderModeName", &Entity::GetRenderModeName)
     .def("GetNotEmptyRenderModes", &Entity::GetNotEmptyRenderModes)
     .def("SetRenderMode", set_rm1, arg("keep")=false)
@@ -261,6 +272,7 @@ void export_Entity()
     .def("ColorBy", color_by_06)
     .def("ColorBy", color_by_07)
     .def("ColorBy", color_by_08)
+    .def("DetailColorBy", detail_color_by_02)
     COLOR_BY_DEF()
     .def("RadiusBy", radius_by_01)
     .def("RadiusBy", radius_by_02)
diff --git a/modules/gfx/src/entity.cc b/modules/gfx/src/entity.cc
index d6dad69872bb450e5dd41ca4cb448eb162265a58..dfae13a3707eddb51e9a12dc4516c668d1d70e44 100644
--- a/modules/gfx/src/entity.cc
+++ b/modules/gfx/src/entity.cc
@@ -105,8 +105,9 @@ Entity::Entity(const String& name,
 
 impl::EntityRenderer* Entity::GetOrCreateRenderer(RenderMode::Type rm)
 {
-  if (renderer_.find(rm)!=renderer_.end()) {
-    return renderer_.find(rm)->second;
+  RendererMap::iterator rit = renderer_.find(rm);
+  if(rit!=renderer_.end()) {
+    return rit->second;
   }
   impl::EntityRenderer* r=NULL;
   switch (rm) {
@@ -117,22 +118,22 @@ impl::EntityRenderer* Entity::GetOrCreateRenderer(RenderMode::Type rm)
       r=new impl::CustomRenderer();
       break;
     case RenderMode::SLINE:
-      r=new impl::SlineRenderer(trace_);
+      r=new impl::SlineRenderer(&trace_);
       break;
     case RenderMode::LINE_TRACE:
-      r=new impl::LineTraceRenderer(trace_);
+      r=new impl::LineTraceRenderer(&trace_);
       break;
     case RenderMode::TRACE:
-      r=new impl::TraceRenderer(trace_);
+      r=new impl::TraceRenderer(&trace_);
       break;
     case RenderMode::HSC:
-      r=new impl::CartoonRenderer(trace_);
+      r=new impl::CartoonRenderer(&trace_,false);
       break;
     case RenderMode::CPK:
       r=new impl::CPKRenderer();
       break;
     case RenderMode::TUBE:
-      r=new impl::CartoonRenderer(trace_, true);
+      r=new impl::CartoonRenderer(&trace_, true);
       break;
     default:
       return 0;
@@ -148,7 +149,7 @@ void Entity::init(RenderMode::Type rm)
 
   update_view_=true;
   render_mode_=rm;
-  trace_.SetView(this->GetView());
+  trace_.ResetView(this->GetView());
   sel_=this->GetView().CreateEmptyView();  
   impl::EntityRenderer* r=this->GetOrCreateRenderer(rm);
   if(!r) return;
@@ -197,6 +198,18 @@ void Entity::SetBlurFactors(float bf1,float bf2)
 void Entity::Rebuild()
 {
   geom::Vec3 delta=GetTF().GetTrans()-GetTF().GetCenter();
+
+  if(update_view_) {
+    EntityView nv=this->GetView();
+    for (RendererMap::iterator i=renderer_.begin(), 
+           e=renderer_.end(); i!=e; ++i) {
+      i->second->ClearViews();
+      i->second->AddView(nv);
+      i->second->UpdateViews();
+      i->second->PrepareRendering();
+    }
+  }
+
   this->ReapplyColorOps();
   FlagRebuild();
   geom::Vec3 center=this->GetCenter();
@@ -764,6 +777,16 @@ void Entity::ColorBy(const String& prop,
   this->Apply(glop);
 }
 
+void Entity::DetailColorBy(const String& prop,
+                           const Gradient& gradient,
+                           float minv,float maxv,
+                           mol::Prop::Level level)
+{
+  GradientLevelColorOp glop = GradientLevelColorOp("",prop, gradient,minv,maxv,level);
+  glop.SetMask(DETAIL_COLOR);
+  this->Apply(glop);
+}
+
 void Entity::ColorBy(const String& prop,
                      const Color& c1, const Color& c2,
                      float minv, float maxv,
@@ -947,4 +970,11 @@ void Entity::ReapplyColorOps()
   GfxObj::ReapplyColorOps();
 }
 
+void Entity::UpdateView() 
+{
+  update_view_=true; 
+  Rebuild();
+  UpdatePositions();
+}
+
 }} // ns
diff --git a/modules/gfx/src/entity.hh b/modules/gfx/src/entity.hh
index 368445df056732e6ad47777a1a36fea0b72deea8..c0b3c3a9fd48f94bfbfe67e76530f5f5c36f4c06 100644
--- a/modules/gfx/src/entity.hh
+++ b/modules/gfx/src/entity.hh
@@ -199,6 +199,12 @@ public:
                float minv,float maxv,
                mol::Prop::Level hint=mol::Prop::UNSPECIFIED);
 
+  // temporary, should be incorporated with ColorBy
+  void DetailColorBy(const String& prop, 
+                     const Gradient& gradient,
+                     float minv,float maxv,
+                     mol::Prop::Level hint=mol::Prop::UNSPECIFIED);
+
   // convenience
   void ColorBy(const String& prop, 
                const Gradient& gradient,
@@ -257,6 +263,9 @@ public:
   void ApplyOptions(RenderMode::Type render_mode,
                           RenderOptionsPtr& render_options);
   bool HasSelection() const;
+
+  void UpdateView();
+  
 protected:
 
   virtual void CustomPreRenderGL(bool flag);
diff --git a/modules/gfx/src/gfx_object.cc b/modules/gfx/src/gfx_object.cc
index 319692f50080fcac899901ef7ef4b8d554b1ef7f..3959e465325c5987d36b04b064c710e2c364ac5b 100644
--- a/modules/gfx/src/gfx_object.cc
+++ b/modules/gfx/src/gfx_object.cc
@@ -448,6 +448,9 @@ void GfxObj::RenderPov(PovState& pov)
     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();
   }
diff --git a/modules/gfx/src/impl/backbone_trace.cc b/modules/gfx/src/impl/backbone_trace.cc
index d4314bea8901f49678e55af9fa2cff6f791bfe1d..fb4b714cc363bc243f8a77d096d10765e18fcd93 100644
--- a/modules/gfx/src/impl/backbone_trace.cc
+++ b/modules/gfx/src/impl/backbone_trace.cc
@@ -39,7 +39,7 @@ public:
   {
     if(last_chain_ && chain!=last_chain_) {
       if(!list_.empty()) {
-        backbone_trace_->AddNodeList(list_);
+        backbone_trace_->AddNodeEntryList(list_);
         list_.clear();
       }
       last_chain_=chain;
@@ -51,7 +51,7 @@ public:
   {
     if(!mol::InSequence(last_residue_,res)) {
       if(!list_.empty()) {
-        backbone_trace_->AddNodeList(list_);
+        backbone_trace_->AddNodeEntryList(list_);
         list_.clear();
       }
     }
@@ -76,7 +76,7 @@ public:
   virtual void OnExit()
   {
     if (!list_.empty()) {
-      backbone_trace_->AddNodeList(list_);
+      backbone_trace_->AddNodeEntryList(list_);
       list_.clear();
     }
   }
@@ -87,23 +87,38 @@ private:
   NodeEntryList      list_;
 };
 
+BackboneTrace::BackboneTrace()
+{}
+
 BackboneTrace::BackboneTrace(const mol::EntityView& ent)
 {
   view_=ent;
-  TraceBuilder trace(this);
-  if (view_) {
-    view_.Apply(trace);
-  }
+  Rebuild();
 }
 
-BackboneTrace::BackboneTrace()
+void BackboneTrace::ResetView(const mol::EntityView& ent)
 {
-  
+  view_=ent;
+  Rebuild();
 }
 
-void BackboneTrace::SetView(const mol::EntityView& ent)
+int BackboneTrace::GetListCount() const
+{
+  return node_list_list_.size();
+}
+
+const NodeEntryList& BackboneTrace::GetList(int index) const
+{
+  return node_list_list_[index];
+}
+
+NodeEntryList& BackboneTrace::GetList(int index)
+{
+  return node_list_list_[index];
+}
+
+void BackboneTrace::Rebuild()
 {
-  view_=ent;
   if (view_) {
     node_list_list_.clear();
     TraceBuilder trace(this);    
@@ -111,7 +126,7 @@ void BackboneTrace::SetView(const mol::EntityView& ent)
   }
 }
 
-void BackboneTrace::AddNodeList(const NodeEntryList& l)
+void BackboneTrace::AddNodeEntryList(const NodeEntryList& l)
 {
   if(l.size()>=3) {
     node_list_list_.push_back(l);
@@ -183,114 +198,25 @@ void BackboneTrace::PrepList(NodeEntryList& nelist)
   nelist[i+1].normal=nelist[i].normal;
 }
 
-int BackboneTrace::GetListCount() const
+BackboneTrace BackboneTrace::CreateSubset(const mol::EntityView& subview)
 {
-  return node_list_list_.size();
-}
-
-const NodeEntryList& BackboneTrace::GetList(int index) const
-{
-  return node_list_list_[index];
-}
-
-NodeEntryList& BackboneTrace::GetList(int index)
-{
-  return node_list_list_[index];
-}
-
-void BackboneTrace::Rebuild()
-{
-  TraceBuilder trace(this);
-  view_.Apply(trace);  
-}
-
-NodeListSubset::NodeListSubset(BackboneTrace& trace, int index):
-  trace_(trace), list_index_(index), at_start_(0), at_end_(0)
-{
-}
-
-TraceSubset::TraceSubset(BackboneTrace& trace, 
-                         const mol::EntityView& view, int n):
-  trace_(trace), overshoot_(n)
-{
-  this->Update(view);
-}
-
-TraceSubset::TraceSubset(BackboneTrace& trace, int n):
-  trace_(trace), overshoot_(n)
-{
-  
-}
-
-
-void TraceSubset::NodeListEnd(NodeListSubset& nl, int c, int s)
-{
-  if (nl.GetSize()>0) {
-    int n=std::min(s-(nl.indices_.back()+1), overshoot_);
-    nl.at_end_=n;    
-    while (n>0) {
-      nl.indices_.push_back(nl.indices_.back()+1);
-      --n;
-    }
-  }
-}
-
-void TraceSubset::NodeListStart(NodeListSubset& nl, int c)
-{
-  if (nl.GetSize()==0 && c>0) {
-    for (int i=std::max(0,c-overshoot_); i<c; ++i) {
-      nl.indices_.push_back(i);
-    }
-    nl.at_start_=nl.indices_.size();
-  }
-}
-
-
-void TraceSubset::Update(const mol::EntityView& view)
-{
-
-  lists_.clear();
-  if (!view.IsValid()) {
-    return;
-  }
-  for (int i=0; i<trace_.GetListCount(); ++i) {
-    const NodeEntryList& l=trace_.GetList(i); 
-    int c=0;
-    NodeEntryList::const_iterator j=l.begin(),e=l.end();  
-    NodeListSubset curr(trace_, i);
-    while (j!=e) {  
-      while (j!=e && view.FindAtom(j->atom)) {
-        if (curr.indices_.empty()) {
-          this->NodeListStart(curr, c);
-        }
-        curr.indices_.push_back(c);
-        ++j; ++c;
-      }
-      if (curr.GetSize()) {
-        this->NodeListEnd(curr, curr.indices_.back(), l.size());
-        lists_.push_back(curr);
-        curr=NodeListSubset(trace_, i);
-      } else {
-        ++c; ++j;        
+  BackboneTrace nrvo;
+  nrvo.view_=subview;
+  nrvo.node_list_list_.clear();
+  for(NodeEntryListList::const_iterator nitnit=node_list_list_.begin();nitnit!=node_list_list_.end();++nitnit) {
+    NodeEntryList new_nlist;
+    const NodeEntryList& nlist=*nitnit;
+    for(NodeEntryList::const_iterator nit=nlist.begin();nit!=nlist.end();++nit) {
+      if(subview.FindAtom(nit->atom).IsValid()) {
+	new_nlist.push_back(*nit);
       }
     }
+    if(!new_nlist.empty()) {
+      nrvo.node_list_list_.push_back(new_nlist);
+    }
   }
+  return nrvo;
 }
 
-NodeListSubset& NodeListSubset::operator=(const NodeListSubset& rhs)
-{
-  trace_=rhs.trace_;
-  list_index_=rhs.list_index_;
-  indices_=rhs.indices_;
-  return *this;
-}
-
-TraceSubset& TraceSubset::operator=(const TraceSubset& rhs)
-{
-  trace_=rhs.trace_;
-  lists_=rhs.lists_;
-  overshoot_=rhs.overshoot_;
-  return *this;
-}
+}}} // ns
 
-}}}
diff --git a/modules/gfx/src/impl/backbone_trace.hh b/modules/gfx/src/impl/backbone_trace.hh
index 25ebdce1fe5cf3b764c0aac06e64b546121f4434..debcc54b59b653e5370f3dbe581d46fd3fac87b6 100644
--- a/modules/gfx/src/impl/backbone_trace.hh
+++ b/modules/gfx/src/impl/backbone_trace.hh
@@ -40,100 +40,41 @@ class BackboneTraceBuilder;
 class DLLEXPORT_OST_GFX BackboneTrace {
 public:
 
-  BackboneTrace(const mol::EntityView& ent);
+  // empty trace
   BackboneTrace();
-  
+
+  // initialize with a view, and build
+  BackboneTrace(const mol::EntityView& ent);
+
+  // number of node-lists
   int GetListCount() const;
-  
+
+  // grab a list
   const NodeEntryList& GetList(int index) const;
+  // grab a list
   NodeEntryList& GetList(int index);
-  
-  void SetView(const mol::EntityView& ent);
-  
-  void AddNodeList(const NodeEntryList& entries);  
 
-  static void PrepList(NodeEntryList& nelist);
+  // reset the view and rebuild
+  void ResetView(const mol::EntityView& ent);
+
+  // used internally - adds a finished nodelist
+  void AddNodeEntryList(const NodeEntryList& entries);  
   
+  // used internally - calculates some derived values for a nodelist
+  static void PrepList(NodeEntryList& nelist);
+
+  // re-creates internal nodelist-list based on view
   void Rebuild();
   
+  // extract portions of this backbone trace for a subview
+  // this is faster then re-generating a trace
+  BackboneTrace CreateSubset(const mol::EntityView& subview);
+  
 private:  
   mol::EntityView      view_;
   NodeEntryListList    node_list_list_;
 };
 
-/// \internal
-/// \brief a subset of a node list
-class DLLEXPORT_OST_GFX NodeListSubset {
-public:
-  friend class TraceSubset;
-  
-  NodeListSubset(BackboneTrace& trace, int index);
-  
-  int GetSize() const 
-  {
-     return indices_.size();
-  }
-  int AtStart() const 
-  { 
-    return at_start_;
-  }
-  
-  int AtEnd() const 
-  { 
-    return at_end_;
-  }  
-  const NodeEntry& operator [](int index) const 
-  {
-    assert(index>=0 && index<static_cast<int>(indices_.size()));    
-    return trace_.GetList(list_index_)[indices_[index]];
-  }
-  NodeEntry& operator [](int index)
-  {
-    assert(index>=0 && index<static_cast<int>(indices_.size()));    
-    return trace_.GetList(list_index_)[indices_[index]];
-  }  
-  NodeListSubset& operator=(const NodeListSubset& rhs);    
-private:
-  BackboneTrace&    trace_;
-  int               list_index_;
-protected:
-  std::vector<int>  indices_;
-  int               at_start_;
-  int               at_end_;
-};
-
-/// \brief a subset of the trace
-class DLLEXPORT_OST_GFX TraceSubset {
-public:
-  TraceSubset(BackboneTrace& trace, const mol::EntityView& view, int n);
-  TraceSubset(BackboneTrace& trace, int n);
-  
-  const NodeListSubset& operator[](int index) const
-  {
-    return lists_[index];
-  }
-  
-  NodeListSubset& operator[](int index)
-  {
-    return lists_[index];
-  }
-  
-  int GetSize() const
-  {
-    return lists_.size();
-  }
-  void SetOvershoot(int n) { overshoot_=n; }
-  int GetOvershoot() const { return overshoot_; }
-  TraceSubset& operator=(const TraceSubset& rhs);  
-  void Update(const mol::EntityView& view);
-private:
-  void NodeListStart(NodeListSubset& nl, int c);
-  void NodeListEnd(NodeListSubset& nl, int c, int s);
-  BackboneTrace& trace_;
-  std::vector<NodeListSubset> lists_;
-  int overshoot_;
-};
-
 }}}
 
 #endif
diff --git a/modules/gfx/src/impl/cartoon_renderer.cc b/modules/gfx/src/impl/cartoon_renderer.cc
index c17c1efd861af4db7f0816f933d0177b4a03c191..f4a52b7ee9672ebdf289b8adfc533e15e4edffdf 100644
--- a/modules/gfx/src/impl/cartoon_renderer.cc
+++ b/modules/gfx/src/impl/cartoon_renderer.cc
@@ -16,6 +16,11 @@
 // 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 "cartoon_renderer.hh"
 
 #include <Eigen/Core>
@@ -34,7 +39,7 @@ static const unsigned int MAX_ARC_DETAIL=12;
 
 using namespace impl;
 
-CartoonRenderer::CartoonRenderer(BackboneTrace& trace, bool force_tube): 
+CartoonRenderer::CartoonRenderer(BackboneTrace* trace, bool force_tube): 
   TraceRendererBase(trace, 3),   force_tube_(force_tube),
   options_(new CartoonRenderOptions(force_tube))
 {
@@ -46,7 +51,7 @@ void CartoonRenderer::SetForceTube(bool force_tube)
   force_tube_ = force_tube;
 }
 
-void CartoonRenderer::PrepareRendering(const TraceSubset& subset, 
+void CartoonRenderer::PrepareRendering(const BackboneTrace& subset, 
                                        IndexedVertexArray& va,
                                        SplineEntryListList& spline_list_list,
                                        bool is_sel)
@@ -61,11 +66,11 @@ void CartoonRenderer::PrepareRendering(const TraceSubset& subset,
     va.SetColorMaterial(true);
     va.SetMode(0x4);
     va.SetPolyMode(options_->GetPolyMode());
-    for (int node_list=0; node_list<subset.GetSize(); ++node_list) {
+    for (int node_list=0; node_list<subset.GetListCount(); ++node_list) {
       // first build the spline
       SplineEntryList spl;
-      const NodeListSubset& nl=subset[node_list];
-      for (int i=0; i<nl.GetSize();++i) {      
+      const NodeEntryList& nl=subset.GetList(node_list);
+      for (unsigned int i=0; i<nl.size();++i) {
         int type=0;
         const NodeEntry& entry=nl[i];
         if(!force_tube_) {
@@ -112,8 +117,6 @@ void CartoonRenderer::PrepareRendering()
   state_=0;
 }
 
-void CartoonRenderer::Render(){}
-
 bool CartoonRenderer::CanSetOptions(RenderOptionsPtr& render_options)
 {
  return render_options.get()->GetRenderMode()==RenderMode::HSC;
@@ -302,7 +305,6 @@ void CartoonRenderer::RebuildSplineObj(IndexedVertexArray& va,
   unsigned int detail = std::min(MAX_ARC_DETAIL,
                                  std::max(options_->GetArcDetail(),
                                  (unsigned int)1));
-  int spline_detail=std::max((unsigned int) 1, options_->GetSplineDetail());
   std::vector<TraceProfile> profiles;
   float factor=is_sel ? 0.2 : 0.0;
   profiles.push_back(GetCircProfile(detail,
@@ -346,15 +348,13 @@ void CartoonRenderer::RebuildSplineObj(IndexedVertexArray& va,
     */
     SplineEntryList slist=*it;
     if(slist.empty()) continue;
-    int sit=0, send=slist.size()-spline_detail+1;
-    //int sit=0,send=slist.size();
-    TraceProfile tprof1=TransformAndAddProfile(profiles,slist[sit],va);
-    CapProfile(tprof1,slist[sit],true,va);
+    TraceProfile tprof1=TransformAndAddProfile(profiles,slist[0],va);
+    CapProfile(tprof1,slist[0],true,va);
     TraceProfile tprof2;
-    SplineEntry last_se=slist[std::max(0,send-1)];
-    for (int sc=sit+1; sc<send; ++sc) {
-      if(slist[sc].type==3) {
-        if(slist[sc-1].type==2) {
+    unsigned int sc=1;
+    for (; sc<slist.size(); ++sc) {
+      if(slist.at(sc).type==3) {
+        if(slist.at(sc-1).type==2) {
           // boundary to arrow
           SplineEntry se(slist[sc]);
           tprof2=TransformAndAddProfile(profiles,se, va);
@@ -365,7 +365,7 @@ void CartoonRenderer::RebuildSplineObj(IndexedVertexArray& va,
           se.type2=4;
           tprof2=TransformAndAddProfile(profiles,se, va);
         } else {
-          SplineEntry se(slist[sc]);
+          SplineEntry se(slist.at(sc));
           se.type1=4;
           if(options_->GetStrandMode()==1) se.type2=5;
           tprof2=TransformAndAddProfile(profiles,se, va);
@@ -375,14 +375,11 @@ void CartoonRenderer::RebuildSplineObj(IndexedVertexArray& va,
       }
       AssembleProfile(tprof1,tprof2,va);
       tprof1=tprof2;
-      last_se=slist[sc];
     }
-    CapProfile(tprof1,slist.at(send-1),false,va);
+    CapProfile(tprof1,slist.at(sc-1),false,va);
   }
 }
 
-
-
 TraceProfile CartoonRenderer::TransformAndAddProfile(const std::vector<TraceProfile>& profiles, const SplineEntry& se, IndexedVertexArray& va)
 {
   assert(se.type1>=0 && se.type1<=5);
diff --git a/modules/gfx/src/impl/cartoon_renderer.hh b/modules/gfx/src/impl/cartoon_renderer.hh
index 6b2b703f23b9fc34a590d7151df5da7dcba77f5c..d8a98f761a800deb13c8f36f893f9b8029e65deb 100644
--- a/modules/gfx/src/impl/cartoon_renderer.hh
+++ b/modules/gfx/src/impl/cartoon_renderer.hh
@@ -16,6 +16,11 @@
 // 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
+*/
+
 #ifndef OST_GFX_CARTOON_RENDERER_HH
 #define OST_GFX_CARTOON_RENDERER_HH
 
@@ -34,23 +39,19 @@ namespace ost { namespace gfx { namespace impl {
 /// \internal
 class DLLEXPORT_OST_GFX CartoonRenderer: public TraceRendererBase {
 public:
-  CartoonRenderer(BackboneTrace& trace, bool force_tube=false);
+  CartoonRenderer(BackboneTrace* trace, bool force_tube=false);
+  virtual ~CartoonRenderer();
 
   virtual void PrepareRendering();
-  virtual void Render();
 
   virtual bool CanSetOptions(RenderOptionsPtr& render_options);
   virtual void SetOptions(RenderOptionsPtr& render_options);
   virtual RenderOptionsPtr GetOptions();
 
-
   virtual void SetForceTube(bool force_tube);
-
-
-  virtual ~CartoonRenderer();
   
 private:
-  void PrepareRendering(const TraceSubset& subset, IndexedVertexArray& va, 
+  void PrepareRendering(const BackboneTrace& subset, IndexedVertexArray& va, 
                         SplineEntryListList& spline_list_list, bool is_sel);
 
   void FudgeSplineObj(IndexedVertexArray&, SplineEntryListList&);
diff --git a/modules/gfx/src/impl/cpk_renderer.cc b/modules/gfx/src/impl/cpk_renderer.cc
index 981ff47f38f1fe93db65a8bc64b04b7f5bc1b3cb..fc3b2b916170cc0e5dc16e2ea9f3a0b425fb6cdb 100644
--- a/modules/gfx/src/impl/cpk_renderer.cc
+++ b/modules/gfx/src/impl/cpk_renderer.cc
@@ -70,21 +70,18 @@ void CPKRenderer::PrepareRendering(GfxView& view, IndexedVertexArray& va, bool i
   state_=0;
 }
 
-void CPKRenderer::Render()
+void CPKRenderer::Render(RenderPass pass)
 {
   if(options_!=NULL){
 #if OST_SHADER_SUPPORT_ENABLED
     if(options_->GetCPKMode()==1 || options_->GetCPKMode()==2) {
       this->RenderCPK2();
       return;
-    } else {
-      this->RenderCPK3();
-      return;
     }
-#else
-    this->RenderCPK3();;
 #endif
   }
+  // fall back to parent if above did not fire
+  EntityRenderer::Render(pass);
 }
 
 void CPKRenderer::RenderPov(PovState& pov, const std::string& name)
diff --git a/modules/gfx/src/impl/cpk_renderer.hh b/modules/gfx/src/impl/cpk_renderer.hh
index b44a82e41dfaa5992727c348145c9ff50b8e8cb3..81372f2d022127c94df0dfff1cd189cc5ae4a3c4 100644
--- a/modules/gfx/src/impl/cpk_renderer.hh
+++ b/modules/gfx/src/impl/cpk_renderer.hh
@@ -37,7 +37,7 @@ public:
   
   virtual void RenderPov(PovState& pov, const std::string& name);
 
-  virtual void Render();
+  virtual void Render(RenderPass pass=STANDARD_RENDER_PASS);
 
   virtual bool CanSetOptions(RenderOptionsPtr& render_options);
   virtual void SetOptions(RenderOptionsPtr& render_options);
diff --git a/modules/gfx/src/impl/debug_renderer.cc b/modules/gfx/src/impl/debug_renderer.cc
index 27138b32ef6b4f1d88271b447168f0de58dc1896..c77dca5687203f39c4969ceb5625d641ec1fbef9 100644
--- a/modules/gfx/src/impl/debug_renderer.cc
+++ b/modules/gfx/src/impl/debug_renderer.cc
@@ -33,7 +33,7 @@ namespace gfx {
 using namespace impl;
 using namespace mol;
 
-DebugRenderer::DebugRenderer(BackboneTrace& trace): 
+DebugRenderer::DebugRenderer(BackboneTrace* trace): 
   TraceRendererBase(trace, 2), options_(new SlineRenderOptions()) {
   this->SetName("Debug");
 }
diff --git a/modules/gfx/src/impl/debug_renderer.hh b/modules/gfx/src/impl/debug_renderer.hh
index 206f592ddb3b7bcc4006d2a620f0a41488525e26..3a2b6e79a464b780fbb13ef40a794743564f40a4 100644
--- a/modules/gfx/src/impl/debug_renderer.hh
+++ b/modules/gfx/src/impl/debug_renderer.hh
@@ -30,7 +30,7 @@ namespace ost { namespace gfx { namespace impl {
 
 class DLLEXPORT_OST_GFX DebugRenderer: public TraceRendererBase {
 public:
-  DebugRenderer(BackboneTrace& trace);
+  DebugRenderer(BackboneTrace* trace);
 
   virtual void PrepareRendering();
   virtual void Render();
diff --git a/modules/gfx/src/impl/entity_detail.cc b/modules/gfx/src/impl/entity_detail.cc
index 1d5a3c226c70b674bf9076388272bea46de76fd1..4d2857b4b746ab50d4f61c8cbe22c5fc11102ccb 100644
--- a/modules/gfx/src/impl/entity_detail.cc
+++ b/modules/gfx/src/impl/entity_detail.cc
@@ -95,16 +95,20 @@ static int bsplineGet(float *xa, float *ya, float *y2a, int n, float x, float *y
 
 #define SPLINE_ENTRY_INTERPOLATE(COMPONENT)             \
     for(int c=0;c<size;++c) {                           \
-      yc[c]=entry_list[c]. COMPONENT ;                 \
+      yc[c]=entry_list.at(c). COMPONENT ;		\
     }                                                   \
     bsplineGen(xp,yp,size,1.0e30,1.0e30,y2p);           \
-    for(int c=0;c<size;++c) {                           \
+    for(int c=0;c<size-1;++c) {                         \
       for(int d=0;d<nsub;++d) {                         \
         float u=static_cast<float>(c*nsub+d)*i_nsub;    \
         float v=0.0;                                    \
         bsplineGet(xp,yp,y2p,size,u,&v);                \
-        sublist[c*nsub+d]. COMPONENT = v;               \
+        sublist.at(c*nsub+d). COMPONENT = v;		\
       }                                                 \
+      float u=static_cast<float>((size-1)*nsub)*i_nsub;	\
+      float v=0.0;                                      \
+      bsplineGet(xp,yp,y2p,size,u,&v);                  \
+      sublist.at((size-1)*nsub). COMPONENT = v;		\
     }                                                   
 
 SplineEntryList Spline::Generate(const SplineEntryList& entry_list, int nsub)
@@ -113,10 +117,11 @@ SplineEntryList Spline::Generate(const SplineEntryList& entry_list, int nsub)
     return entry_list;
   }
   int size=entry_list.size();
-  if (size==0) {
+  if (size<2) {
     return entry_list;
   }
-  int ipsize=(size)*nsub;
+  // we want to go to the last point, but not beyond
+  int ipsize=(size-1)*nsub+1;
   float i_nsub=1.0/static_cast<float>(nsub);
   std::vector<float> xc(size);
   std::vector<float> yc(size);
@@ -153,14 +158,14 @@ SplineEntryList Spline::Generate(const SplineEntryList& entry_list, int nsub)
   // assign direction and normal
   // entity trace has the same algorithm
 
-  geom::Vec3 p0 = sublist[0].position;
-  geom::Vec3 p1 = sublist[1].position;
-  geom::Vec3 p2 = sublist[2].position;
+  geom::Vec3 p0 = sublist.at(0).position;
+  geom::Vec3 p1 = sublist.at(1).position;
+  geom::Vec3 p2 = ipsize>2 ? sublist.at(2).position : p1+(p1-p0);
   // normal of 0 is set at the end
-  sublist[0].direction=geom::Normalize(p1-p0);
-  sublist[0].v1=geom::Normalize(sublist[0].v1);
-  geom::Vec3 orth = geom::Cross(sublist[0].direction,sublist[0].v1);
-  sublist[0].v0 = geom::Normalize(geom::Cross(orth,sublist[0].direction));
+  sublist.at(0).direction=geom::Normalize(p1-p0);
+  sublist.at(0).v1=geom::Normalize(sublist.at(0).v1);
+  geom::Vec3 orth = geom::Cross(sublist.at(0).direction,sublist.at(0).v1);
+  sublist.at(0).v0 = geom::Normalize(geom::Cross(orth,sublist.at(0).direction));
 
   // reference normal to avoid twisting
   //geom::Vec3 nref=geom::Normalize(geom::Cross(p0-p1,p2-p1));
@@ -170,90 +175,83 @@ SplineEntryList Spline::Generate(const SplineEntryList& entry_list, int nsub)
     geom::Vec3 p12 = p2-p1;
     // correction for perfectly aligned consecutive directions
     if(p10==-p12 || p10==p12) p12+=geom::Vec3(0.001,0.001,0.001);
-    sublist[i].normal=geom::Normalize(geom::Cross(p10,p12));
+    sublist.at(i).normal=geom::Normalize(geom::Cross(p10,p12));
     // paranoid error checking due to occasional roundoff troubles
     float cosw = geom::Dot(geom::Normalize(p10),geom::Normalize(p12));
     cosw = std::min(float(1.0),std::max(float(-1.0),cosw));
     float omega=0.5*acos(cosw);
-    orth=geom::AxisRotation(sublist[i].normal, -omega)*p12;
-    sublist[i].direction=geom::Normalize(geom::Cross(sublist[i].normal,orth));
+    orth=geom::AxisRotation(sublist.at(i).normal, -omega)*p12;
+    sublist.at(i).direction=geom::Normalize(geom::Cross(sublist.at(i).normal,orth));
     // twist avoidance
-    sublist[i].v1=geom::Normalize(sublist[i].v1);
-    orth = geom::Cross(sublist[i].direction,sublist[i].v1);
-    sublist[i].v0 = geom::Normalize(geom::Cross(orth,sublist[i].direction));
-    if(geom::Dot(sublist[i-1].v0,sublist[i].v0)<0.0) {
-      sublist[i].v0=-sublist[i].v0;
-      //sublist[i].nflip = !sublist[i].nflip;
+    sublist.at(i).v1=geom::Normalize(sublist.at(i).v1);
+    orth = geom::Cross(sublist.at(i).direction,sublist.at(i).v1);
+    sublist.at(i).v0 = geom::Normalize(geom::Cross(orth,sublist.at(i).direction));
+    if(geom::Dot(sublist.at(i-1).v0,sublist.at(i).v0)<0.0) {
+      sublist.at(i).v0=-sublist.at(i).v0;
+      //sublist.at(i).nflip = !sublist.at(i).nflip;
     }
 
     // avoid twisting
-    //if(geom::Dot(sublist[i].normal,nref)<0.0) sublist[i].normal=-sublist[i].normal;
-    //nref=sublist[i].normal;
+    //if(geom::Dot(sublist.at(i).normal,nref)<0.0) sublist.at(i).normal=-sublist.at(i).normal;
+    //nref=sublist.at(i).normal;
     // skip over shift for the last iteration
     if(i==sublist.size()-2) break;
     // shift to i+1 for next iteration
-    p0 = sublist[i].position;
-    p1 = sublist[i+1].position;
-    p2 = sublist[i+2].position;
+    p0 = sublist.at(i).position;
+    p1 = sublist.at(i+1).position;
+    p2 = sublist.at(i+2).position;
   }
   // assign remaining ones
-  sublist[0].normal=sublist[1].normal;
-  sublist[i+1].direction=geom::Normalize(p2-p1);
-  sublist[i+1].normal=sublist[i].normal;
-  sublist[i+1].v1=geom::Normalize(sublist[i+1].v1);
-  orth = geom::Cross(sublist[i+1].direction,sublist[i+1].v1);
-  sublist[i+1].v0 = geom::Normalize(geom::Cross(orth,sublist[i+1].direction));
+  sublist.at(0).normal=sublist.at(1).normal;
+  sublist.at(i+1).direction=geom::Normalize(p2-p1);
+  sublist.at(i+1).normal=sublist.at(i).normal;
+  sublist.at(i+1).v1=geom::Normalize(sublist.at(i+1).v1);
+  orth = geom::Cross(sublist.at(i+1).direction,sublist.at(i+1).v1);
+  sublist.at(i+1).v0 = geom::Normalize(geom::Cross(orth,sublist.at(i+1).direction));
 
   // hack
   // TODO: merge this with above routine
   for(unsigned int i=0;i<sublist.size()-1;++i) {
-    sublist[i].normal = sublist[i].v0;
+    sublist.at(i).normal = sublist.at(i).v0;
   }
 
   // finally the non-interpolated type
   // with some tweaks for proper strand rendering
-  for(int c=0;c<size;++c) {
+  for(int c=0;c<size-1;++c) {
     int type1=entry_list[c].type;
     int type2=entry_list[std::min(c+1,size-1)].type;
-# if 0
-    //int type0=entry_list[std::max(0,c-1)].type;
-    if(type1==2 && type2==3) {
-      type1=2;
-      type2=2;
-    } else if(type1==3) {
-      type1=4;
-      // uncommenting this causes the strand arrows
-      // to blend into a tip instead of the n+1
-      // profile - gives visual artefacts
-      //type2=3;
-    }
-#endif
     for(int d=0;d<nsub;++d) {
-      sublist[c*nsub+d].type=entry_list[c].type;
-      sublist[c*nsub+d].type1=type1;
-      sublist[c*nsub+d].type2=type2;
-      sublist[c*nsub+d].frac=float(d)/float(nsub);
+      sublist.at(c*nsub+d).type=entry_list[c].type;
+      sublist.at(c*nsub+d).type1=type1;
+      sublist.at(c*nsub+d).type2=type2;
+      sublist.at(c*nsub+d).frac=float(d)/float(nsub);
     }
   }                                                   
+  int type1=entry_list.back().type;
+  int type2=type1;
+  sublist.back().type=entry_list.back().type;
+  sublist.back().type1=type1;
+  sublist.back().type2=type2;
+  sublist.back().frac=0.0;
 
   // the nflip flags for helices for correct inside/outside assignment
   int c=0;
   bool nflip=false;
-  while(c<nsub*size-1) {
+  while(c<nsub*(size-1)) {
     int cstart=c;
-    if(sublist[c].type==1 && sublist[c+1].type==1) {
-      geom::Vec3 n = geom::Normalize(geom::Cross(sublist[c].normal,
-                                                 sublist[c].direction));
-      geom::Vec3 p0 = sublist[c].position+n;
-      geom::Vec3 q0 = sublist[c].position-n;
+    if(sublist.at(c).type==1 && sublist.at(c+1).type==1) {
+      geom::Vec3 n = geom::Normalize(geom::Cross(sublist.at(c).normal,
+                                                 sublist.at(c).direction));
+      geom::Vec3 p0 = sublist.at(c).position+n;
+      geom::Vec3 q0 = sublist.at(c).position-n;
       float psum=0.0;
       float qsum=0.0;
       ++c;
-      while(sublist[c].type==1 && c<nsub*size) {
-        n = geom::Normalize(geom::Cross(sublist[c].normal,
-                                        sublist[c].direction));
-        geom::Vec3 p1 = sublist[c].position+n;
-        geom::Vec3 q1 = sublist[c].position-n;
+      while(sublist.at(c).type==1 && c<nsub*size) {
+        n = geom::Normalize(geom::Cross(sublist.at(c).normal,
+                                        sublist.at(c).direction));
+        geom::Vec3 p1 = sublist.at(c).position+n;
+        geom::Vec3 q1 = sublist.at(c).position-n;
         psum+=Length(p1-p0);
         qsum+=Length(q1-q0);
         p0=p1;
@@ -263,7 +261,7 @@ SplineEntryList Spline::Generate(const SplineEntryList& entry_list, int nsub)
       
       nflip = qsum>psum;
       for(int cc=cstart;cc<c;++cc) {
-        sublist[cc].nflip=nflip;
+        sublist.at(c).nflip=nflip;
       }
     } else {
       ++c;
diff --git a/modules/gfx/src/impl/entity_renderer.hh b/modules/gfx/src/impl/entity_renderer.hh
index 2fa91e110442b022a0c64d3ad0cc2963d10f1641..4d90f97e0a3542b50473956b378a923268af3121 100644
--- a/modules/gfx/src/impl/entity_renderer.hh
+++ b/modules/gfx/src/impl/entity_renderer.hh
@@ -180,6 +180,7 @@ protected:
   DirtyFlags            sel_state_;
   DirtyFlags            state_;
   unsigned int          debug_flags_;
+  float                 opacity_;
 };
 
 //Simplify color ops
diff --git a/modules/gfx/src/impl/line_trace_renderer.cc b/modules/gfx/src/impl/line_trace_renderer.cc
index b0279b71f0f274f101757c0e2c321fc102e4c3e2..45e2b63fa7e013df3c2e78653764c83312be4693 100644
--- a/modules/gfx/src/impl/line_trace_renderer.cc
+++ b/modules/gfx/src/impl/line_trace_renderer.cc
@@ -17,12 +17,16 @@
 // 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 //------------------------------------------------------------------------------
 
+/*
+  Authors: Marco Biasini, Ansgar Philippsen
+*/
+
 #include "line_trace_renderer.hh"
 #include <ost/gfx/entity.hh>
 
 namespace ost { namespace gfx { namespace impl {
 
-LineTraceRenderer::LineTraceRenderer(BackboneTrace& trace): 
+LineTraceRenderer::LineTraceRenderer(BackboneTrace* trace): 
   TraceRendererBase(trace, 1), options_(new LineTraceRenderOptions())
 {
   this->SetName("Fast Trace");
@@ -41,10 +45,9 @@ void LineTraceRenderer::PrepareRendering()
   }
 }
 
-void LineTraceRenderer::PrepareRendering(TraceSubset& trace_subset,
+void LineTraceRenderer::PrepareRendering(const BackboneTrace& trace_subset,
                                          IndexedVertexArray& va, bool is_sel)
 {
-
   const Color& sel_clr=this->GetSelectionColor();
   if(options_!=NULL){
     va.Clear();
@@ -56,54 +59,27 @@ void LineTraceRenderer::PrepareRendering(TraceSubset& trace_subset,
     va.SetLineWidth(options_->GetLineWidth());
     va.SetPointSize(options_->GetLineWidth());
     va.SetAALines(options_->GetAALines());
-    for (int node_list=0; node_list<trace_subset.GetSize(); ++node_list) {
-      const NodeListSubset& nl=trace_subset[node_list];
-
-      if (nl.GetSize()==2) {
-        VertexID p0, p1;
-        if (nl.AtStart()==0) {
-          p0=va.Add(nl[0].atom.GetPos(), geom::Vec3(),
-                    is_sel ? sel_clr : nl[0].color1);
-          p1=va.Add((nl[0].atom.GetPos()+nl[1].atom.GetPos())/2, 
-                    geom::Vec3(), is_sel ? sel_clr : nl[1].color1);
-        } else {
-          p0=va.Add((nl[0].atom.GetPos()+nl[1].atom.GetPos())/2, 
-                    geom::Vec3(), is_sel ? sel_clr : nl[0].color1);
-          p1=va.Add(nl[1].atom.GetPos(), 
-                    geom::Vec3(), is_sel ? sel_clr : nl[1].color1);
-        }
-        va.AddLine(p0, p1);        
-        continue;
-      }
-      if (nl.GetSize()<3) {
-        continue;
-      }
-      VertexID p0;      
-      if (nl.AtStart()==0) {
-        p0=va.Add(nl[0].atom.GetPos(), geom::Vec3(),
-                  is_sel ? sel_clr : nl[0].color1);
-      } else {
-        p0=va.Add((nl[0].atom.GetPos()+nl[1].atom.GetPos())/2, 
-                  geom::Vec3(), is_sel ? sel_clr : nl[0].color1);
+    for (int node_list=0; node_list<trace_subset.GetListCount(); ++node_list) {
+      const NodeEntryList& nl=trace_subset.GetList(node_list);
+
+      if (nl.size()<2) {
+	continue;
       }
-      for (int i=1; i<nl.GetSize()-1;++i) {
+
+      VertexID p0=va.Add(nl[0].atom.GetPos(), geom::Vec3(),
+			 is_sel ? sel_clr : nl[0].color1);
+
+      for (unsigned int i=1; i<nl.size()-1;++i) {
         const NodeEntry& entry=nl[i];
         VertexID p1 =va.Add(entry.atom.GetPos(), geom::Vec3(), 
                             is_sel ? sel_clr : entry.color1);
         va.AddLine(p0, p1);
         p0=p1;
       }
-      const NodeEntry& entry=nl[nl.GetSize()-1];      
-      if (nl.AtEnd()==0) {
-        VertexID p1 =va.Add(entry.atom.GetPos(), geom::Vec3(), 
-                            is_sel ? sel_clr : entry.color1);
-        va.AddLine(p0, p1);                            
-      } else {
-        geom::Vec3 p=(entry.atom.GetPos()+nl[nl.GetSize()-2].atom.GetPos())*0.5;
-        VertexID p1 =va.Add(p, geom::Vec3(), 
-                            is_sel ? sel_clr : entry.color1);
-        va.AddLine(p0, p1);
-      }
+      const NodeEntry& entry=nl.back();      
+      VertexID p1 =va.Add(entry.atom.GetPos(), geom::Vec3(), 
+			  is_sel ? sel_clr : entry.color1);
+      va.AddLine(p0, p1);
     }
   }
   sel_state_=0;
@@ -112,7 +88,6 @@ void LineTraceRenderer::PrepareRendering(TraceSubset& trace_subset,
 
 void LineTraceRenderer::Render()
 {
-
 }
 
 bool LineTraceRenderer::CanSetOptions(RenderOptionsPtr& render_options)
diff --git a/modules/gfx/src/impl/line_trace_renderer.hh b/modules/gfx/src/impl/line_trace_renderer.hh
index d4b904e0fa478286e1bcb7f47e677f6772051344..fc2a2ad87b951e4f7e9788f1fb8aa66ff38f28dc 100644
--- a/modules/gfx/src/impl/line_trace_renderer.hh
+++ b/modules/gfx/src/impl/line_trace_renderer.hh
@@ -16,6 +16,11 @@
 // along with this library; if not, write to the Free Software Foundation, Inc.,
 // 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 //------------------------------------------------------------------------------
+
+/*
+  Authors: Marco Biasini, Ansgar Philippsen
+*/
+
 #ifndef OST_GFX_IMPL_LINE_TRACE_RENDERER_HH
 #define OST_GFX_IMPL_LINE_TRACE_RENDERER_HH
 
@@ -36,10 +41,10 @@ using namespace impl;
 /// \internal
 class DLLEXPORT_OST_GFX LineTraceRenderer: public TraceRendererBase {
 public:
-  LineTraceRenderer(BackboneTrace& trace);
+  LineTraceRenderer(BackboneTrace* trace);
 
   virtual void PrepareRendering();
-  virtual void PrepareRendering(TraceSubset& trace_subset, 
+  virtual void PrepareRendering(const BackboneTrace& trace_subset, 
                                 IndexedVertexArray& va, bool is_sel);
   virtual void Render();
 
diff --git a/modules/gfx/src/impl/map_octree.cc b/modules/gfx/src/impl/map_octree.cc
index be5f7a8db5c6f8b27a9454bf7c21fb1b7cfb52d6..33bd93d71ae00f0601015b6ba0571b96621e7a62 100644
--- a/modules/gfx/src/impl/map_octree.cc
+++ b/modules/gfx/src/impl/map_octree.cc
@@ -94,7 +94,7 @@ std::pair<float,float> MapOctree::BuildOctreeRec(const OcRangeVector& range_vec,
   }
   assert(parent.IsLeaf()==false);
   if (levels_.size()<=level) {
-    levels_.push_back(OcNodeList());
+    levels_.push_back(OcNodeEntryList());
     levels_.back().reserve(this->GetNumNodesForLevel(level));
     assert(level<9 && "MAP TOO BIG for Octree");
   }  
diff --git a/modules/gfx/src/impl/map_octree.hh b/modules/gfx/src/impl/map_octree.hh
index 08a2c57c210f41524b2faa7e5ee24a81c3fd9412..999219e83880049f6df6e0f4c0cde3d9558fd778 100644
--- a/modules/gfx/src/impl/map_octree.hh
+++ b/modules/gfx/src/impl/map_octree.hh
@@ -97,7 +97,7 @@ private:
   float    max_;              // < maximum value of voxels inside OctreeNode
 };
 
-typedef std::vector<OctreeNode> OcNodeList;
+typedef std::vector<OctreeNode> OcNodeEntryList;
 
 
 /// \brief Octree datastructure for 3D images
@@ -215,7 +215,7 @@ private:
                                          OctreeNode& parent);
 
   img::ImageHandle            map_;
-  std::vector<OcNodeList>      levels_;
+  std::vector<OcNodeEntryList>      levels_;
 };
 
 }}}
diff --git a/modules/gfx/src/impl/sline_renderer.cc b/modules/gfx/src/impl/sline_renderer.cc
index a558bc6732f27c4a283beab4dfbeaa34763d9fe4..7ae7f937a99eaf5dd374486f9976ccf41b0938e6 100644
--- a/modules/gfx/src/impl/sline_renderer.cc
+++ b/modules/gfx/src/impl/sline_renderer.cc
@@ -16,13 +16,18 @@
 // along with this library; if not, write to the Free Software Foundation, Inc.,
 // 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 //------------------------------------------------------------------------------
+
+/*
+  Authors: Marco Biasini, Ansgar Philippsen
+*/
+
 #include "sline_renderer.hh"
 
 #include <ost/gfx/entity.hh>
 
 namespace ost { namespace gfx { namespace impl {
 
-SlineRenderer::SlineRenderer(BackboneTrace& trace): 
+SlineRenderer::SlineRenderer(BackboneTrace* trace): 
   TraceRendererBase(trace, 3), options_(new SlineRenderOptions()) 
 {
   this->SetName("Fast Spline");
@@ -40,7 +45,7 @@ void SlineRenderer::PrepareRendering()
   }
 }
 
-void SlineRenderer::PrepareRendering(TraceSubset& trace_subset, 
+void SlineRenderer::PrepareRendering(const BackboneTrace& trace_subset, 
                                      IndexedVertexArray& va, bool is_sel)
 {
   const Color& sel_clr=this->GetSelectionColor();
@@ -56,12 +61,12 @@ void SlineRenderer::PrepareRendering(TraceSubset& trace_subset,
     va.SetLineWidth(options_->GetLineWidth());
     va.SetPointSize(options_->GetLineWidth());
     va.SetAALines(options_->GetAALines());
-    for (int node_list=0; node_list<trace_subset.GetSize(); ++node_list) {
+    for (int node_list=0; node_list<trace_subset.GetListCount(); ++node_list) {
       // first build the spline
       SplineEntryList spl;
-      const NodeListSubset& nl=trace_subset[node_list];
-      assert(nl.GetSize() && "node list subset with zero eles encountered!");
-      for (int i=0; i<nl.GetSize();++i) {
+      const NodeEntryList& nl=trace_subset.GetList(node_list);
+      if(nl.empty()) continue;
+      for (unsigned int i=0; i<nl.size();++i) {
         const NodeEntry& entry=nl[i];
         SplineEntry ee(entry.atom.GetPos(), entry.direction,
                        entry.normal, entry.rad, 
@@ -71,16 +76,9 @@ void SlineRenderer::PrepareRendering(TraceSubset& trace_subset,
         spl.push_back(ee);
       }
       SplineEntryList sel = Spline::Generate(spl,spline_detail);      
-      SplineEntryList::const_iterator sit=sel.begin(), 
-                                     send=sel.end()-spline_detail+1;
-      if (nl.AtStart()>0) {
-        sit+=nl.AtStart()*spline_detail-spline_detail/2;
-      }
-      if (nl.AtEnd()>0) {
-        send-=nl.AtEnd()*spline_detail-spline_detail/2;
-      }
+      SplineEntryList::const_iterator sit=sel.begin();
       VertexID p0=va.Add(sit->position, geom::Vec3(),sit->color1);
-      for (++sit; sit<send; ++sit) {
+      for (++sit; sit!=sel.end(); ++sit) {
         VertexID p1 = va.Add(sit->position, geom::Vec3(),sit->color1);
         va.AddLine(p0,p1);
         p0=p1;
diff --git a/modules/gfx/src/impl/sline_renderer.hh b/modules/gfx/src/impl/sline_renderer.hh
index b264fc4b61f99088f595c4e5df6bb42977b19a31..4c08ba3b0fe587960af2b0a48fe808c84e8ed629 100644
--- a/modules/gfx/src/impl/sline_renderer.hh
+++ b/modules/gfx/src/impl/sline_renderer.hh
@@ -16,6 +16,11 @@
 // along with this library; if not, write to the Free Software Foundation, Inc.,
 // 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 //------------------------------------------------------------------------------
+
+/*
+  Authors: Marco Biasini, Ansgar Philippsen
+*/
+
 #ifndef OST_GFX_SLINE_RENDERER_HH
 #define OST_GFX_SLINE_RENDERER_HH
 
@@ -32,7 +37,7 @@ namespace ost { namespace gfx { namespace impl {
 /// \internal
 class DLLEXPORT_OST_GFX SlineRenderer: public TraceRendererBase {
 public:
-  SlineRenderer(BackboneTrace& trace);
+  SlineRenderer(BackboneTrace* trace);
 
   virtual void PrepareRendering();
 
@@ -43,7 +48,7 @@ public:
   virtual ~SlineRenderer();
 
 private:
-  void PrepareRendering(TraceSubset& subset, IndexedVertexArray& va, 
+  void PrepareRendering(const BackboneTrace& subset, IndexedVertexArray& va, 
                         bool is_sel);
   SlineRenderOptionsPtr options_;
 };
diff --git a/modules/gfx/src/impl/trace_renderer.cc b/modules/gfx/src/impl/trace_renderer.cc
index 29691cc1d39bc669628ab6bf7e211d22f8d52fee..eacf3f0a99a6fb38e6e87326c5630ee1fefd17e5 100644
--- a/modules/gfx/src/impl/trace_renderer.cc
+++ b/modules/gfx/src/impl/trace_renderer.cc
@@ -17,6 +17,10 @@
 // 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 //------------------------------------------------------------------------------
 
+/*
+   Authors: Marco Biasini, Ansgar Philippsen
+*/
+
 #include <ost/gfx/entity.hh>
 #include <ost/gfx/povray.hh>
 
@@ -25,7 +29,7 @@
 
 namespace ost { namespace gfx { namespace impl {
 
-TraceRenderer::TraceRenderer(BackboneTrace& trace): 
+TraceRenderer::TraceRenderer(BackboneTrace* trace): 
   TraceRendererBase(trace, 1), options_(new TraceRenderOptions())
 {
   this->SetName("Trace");
@@ -43,8 +47,7 @@ void TraceRenderer::PrepareRendering()
   }
 }
 
-#if 1
-void TraceRenderer::PrepareRendering(TraceSubset& trace_subset,
+void TraceRenderer::PrepareRendering(BackboneTrace& trace_subset,
                                      IndexedVertexArray& va, bool is_sel)
 {
   float plus=is_sel ? 0.05: 0.0;
@@ -55,14 +58,14 @@ void TraceRenderer::PrepareRendering(TraceSubset& trace_subset,
     va.SetCullFace(true);
     va.SetColorMaterial(true);
     va.SetTwoSided(false);
-    for (int node_list=0; node_list<trace_subset.GetSize(); ++node_list) {
-      const NodeListSubset& nl=trace_subset[node_list];
+    for (int node_list=0; node_list<trace_subset.GetListCount(); ++node_list) {
+      const NodeEntryList& nl=trace_subset.GetList(node_list);
       mol::AtomHandle a1=nl[0].atom;
       va.AddSphere(SpherePrim(a1.GetPos(),
                               options_->GetTubeRadius()+plus,
                               is_sel ? sel_clr : nl[0].color1),
                    options_->GetArcDetail());
-      for(int i=1;i<nl.GetSize();++i) {
+      for(unsigned int i=1;i<nl.size();++i) {
         mol::AtomHandle a2=nl[i].atom;
         va.AddSphere(SpherePrim(a2.GetPos(),
                                 options_->GetTubeRadius()+plus,
@@ -83,169 +86,18 @@ void TraceRenderer::PrepareRendering(TraceSubset& trace_subset,
   state_=0;
 }
 
-#else
-
-void TraceRenderer::PrepareRendering(TraceSubset& trace_subset,
-                                     IndexedVertexArray& va, bool is_sel)
-{
-  const Color& sel_clr=this->GetSelectionColor();
-  float radius=options_->GetTubeRadius();
-  if (is_sel) {
-    radius+=0.1;
-  }
-  int n=8*options_->GetArcDetail();
-  if(options_!=NULL) {
-    va.SetLighting(true);
-    va.SetCullFace(false);
-    for (int node_list=0; node_list<trace_subset.GetSize(); ++node_list) {
-      const NodeListSubset& nl=trace_subset[node_list];
-      geom::Vec3 cursor_pos;
-      geom::Mat3 cursor_ori;
-      if (nl.GetSize()==2) {
-        VertexID p0, p1;
-        if (nl.AtStart()==0) {
-          p0=va.Add(nl[0].atom.GetPos(), geom::Vec3(),
-                    is_sel ? sel_clr : nl[0].color1);
-          p1=va.Add((nl[0].atom.GetPos()+nl[1].atom.GetPos())/2, 
-                    geom::Vec3(), is_sel ? sel_clr : nl[1].color1);
-        } else {
-          p0=va.Add((nl[0].atom.GetPos()+nl[1].atom.GetPos())/2, 
-                    geom::Vec3(), is_sel ? sel_clr : nl[0].color1);
-          p1=va.Add(nl[1].atom.GetPos(), 
-                    geom::Vec3(), is_sel ? sel_clr : nl[1].color1);
-        }
-        va.AddLine(p0, p1);        
-        continue;
-      }
-      if (nl.GetSize()<3) {
-        continue;
-      }
-      VertexID p0;
-      geom::Vec3 z=geom::Normalize(nl[1].atom.GetPos()-nl[0].atom.GetPos());
-      geom::Vec3 y=geom::OrthogonalVector(z);
-      geom::Vec3 x=geom::Cross(y, z);
-      cursor_ori=geom::Mat3(x[0], y[0], z[0], x[1], y[1], z[1], 
-                            x[2], y[2], z[2]);    
-      if (nl.AtStart()==0) {
-        cursor_pos=nl[0].atom.GetPos();
-      } else {
-        cursor_pos=(nl[0].atom.GetPos()+nl[1].atom.GetPos())/2;
-      }
-      p0=this->AddCappedProfile(va, is_sel? sel_clr : nl[0].color1, 
-                                cursor_pos, cursor_ori, radius, true, n);
-      for (int i=1; i<nl.GetSize()-1;++i) {
-        const NodeEntry& entry=nl[i];
-        geom::Vec3 old_dir=geom::Normalize(entry.atom.GetPos()-cursor_pos);
-        cursor_pos=entry.atom.GetPos();
-
-        geom::Vec3 z=geom::Normalize(nl[i+1].atom.GetPos()-cursor_pos);
-        geom::Vec3 y=geom::Normalize(geom::Cross(z, cursor_ori.GetCol(0)));
-        geom::Vec3 x=geom::Normalize(geom::Cross(y, z));
-        geom::Vec3 iz=geom::Normalize(cursor_ori.GetCol(2)+z);
-
-        geom::Vec3 iy=geom::Normalize(geom::Cross(cursor_ori.GetCol(2), z));
-        geom::Vec3 ix=geom::Normalize(geom::Cross(iy, iz));
-
-        geom::Mat3 i_ori=geom::Mat3(ix[0], iy[0], iz[0], ix[1], iy[1], iz[1], 
-                                    ix[2], iy[2], iz[2]);                           
-        cursor_ori=geom::Mat3(x[0], y[0], z[0], x[1], y[1], z[1], 
-                              x[2], y[2], z[2]);
-        // TODO. The intersection of two cylinders is an ellipse. Use an 
-        //        elliptic profile instead of a circular profile.
-        VertexID p1=this->AddCircularProfile(va, is_sel ? sel_clr : entry.color1,
-                                             cursor_pos, i_ori, radius, n);
-        this->ConnectProfiles(p0, p1, n, old_dir, va);
-        p0=p1;
-      }
-      const NodeEntry& entry=nl[nl.GetSize()-1];      
-      if (nl.AtEnd()==0) {
-        cursor_pos=entry.atom.GetPos();
-      } else {
-        cursor_pos=(entry.atom.GetPos()+nl[nl.GetSize()-2].atom.GetPos())*0.5;
-      }
-      VertexID p1 =this->AddCappedProfile(va, is_sel ? sel_clr : entry.color1, 
-                                          cursor_pos, cursor_ori, 
-                                          radius, false, n);
-      this->ConnectProfiles(p0, p1, n, cursor_ori.GetCol(2), va);      
-    }
-  }
-  sel_state_=0;
-  state_=0;
-}
-#endif
-
-VertexID TraceRenderer::AddCappedProfile(IndexedVertexArray& va, 
-                                         const Color& color,
-                                         const geom::Vec3& center, 
-                                         const geom::Mat3& ori, float radius, 
-                                         bool flip_normal,
-                                         int n)
-{
-   VertexID center_id=va.Add(center, geom::Vec3(), color);
-   VertexID first=this->AddCircularProfile(va, color, center, ori, radius, n);
-   for (int i=0; i<n; ++i) {
-     va.AddTriN(center_id, first+i, first+((i+1) % n));
-   }
-   return first;
-}
-
-VertexID TraceRenderer::AddCircularProfile(IndexedVertexArray& va, 
-                                           const Color& color,
-                                           const geom::Vec3& center, 
-                                           const geom::Mat3& ori, 
-                                           float radius, 
-                                           int n)
-{
-  float delta_angle=2*M_PI/n;
-  VertexID f=0;
-  geom::Vec3 normal=ori.GetRow(2);
-  for (int i=0; i<n; ++i) {
-    geom::Vec3 normal=ori*geom::Vec3(cos(i*delta_angle), 
-                                     sin(i*delta_angle), 0.0);
-    VertexID x=va.Add(center+normal*radius, normal, color);
-    if (i==0) {
-      f=x;
-    }
-  }
-  return f;
-}
-
-void TraceRenderer::ConnectProfiles(VertexID prof0, VertexID prof1, int n, 
-                                    const geom::Vec3& dir, 
-                                    IndexedVertexArray& va)
-{
-  // avoid twisting
-  int off=0;
-  float best=0.0;
-  geom::Vec3 pp=va.GetVert(prof0);
-  for (int i=0; i<n; ++i) {
-    geom::Vec3 dir2=geom::Normalize(va.GetVert(prof1+i)-pp);
-    float dot=fabs(geom::Dot(dir, dir2));
-    if (best<dot) {
-      best=dot;
-      off=i;
-    }
-  }
-  for (int i=0; i<n; ++i) {
-    VertexID i1=prof1+((i+off) % n), i2=prof1+((i+off+1) % n);
-    VertexID  i3=prof0+i, i4=prof0+((i+1)%n);
-    va.AddTriN(i1, i2, i3);
-    va.AddTriN(i2, i3, i4);
-  }
-}
-
 void TraceRenderer::RenderPov(PovState& pov, const std::string& name)
 {
   pov.write_merge_or_union(name);
 
-  for (int node_list=0; node_list<trace_subset_.GetSize(); ++node_list) {
-    const NodeListSubset& nl=trace_subset_[node_list];
+  for (int node_list=0; node_list<trace_subset_.GetListCount(); ++node_list) {
+    const NodeEntryList& nl=trace_subset_.GetList(node_list);
 
     geom::Vec3 p0=nl[0].atom.GetPos();
     float rad0=0.2;
     Color col0=nl[0].color1;
     pov.write_sphere(p0,rad0,col0,name);
-    for (int i=1; i<nl.GetSize();++i) {
+    for (unsigned int i=1; i<nl.size();++i) {
       geom::Vec3 p1=nl[i].atom.GetPos();
       float rad1=0.2;
       Color col1=nl[i].color1;
@@ -262,11 +114,6 @@ void TraceRenderer::RenderPov(PovState& pov, const std::string& name)
   pov.inc() << " }\n";
 }
 
-void TraceRenderer::Render()
-{
-
-}
-
 bool TraceRenderer::CanSetOptions(RenderOptionsPtr& render_options)
 {
   return render_options.get()->GetRenderMode()==RenderMode::TRACE;
diff --git a/modules/gfx/src/impl/trace_renderer.hh b/modules/gfx/src/impl/trace_renderer.hh
index 77cb8d3daa3d1584b45d38ea125bc03f6181a470..e8f9cff3bd1f66650f797f7c29888553dd31371a 100644
--- a/modules/gfx/src/impl/trace_renderer.hh
+++ b/modules/gfx/src/impl/trace_renderer.hh
@@ -20,8 +20,9 @@
 #define OST_GFX_IMPL_TRACE_RENDERER_HH
 
 /*
-   Author: Marco Biasini
- */
+   Authors: Marco Biasini, Ansgar Philippsen
+*/
+
 #include <ost/gfx/impl/backbone_trace.hh>
 #include <ost/gfx/impl/entity_detail.hh>
 #include <ost/gfx/impl/trace_renderer_base.hh>
@@ -37,12 +38,12 @@ using namespace impl;
 /// \internal
 class DLLEXPORT_OST_GFX TraceRenderer: public TraceRendererBase {
 public:
-  TraceRenderer(BackboneTrace& trace);
+  TraceRenderer(BackboneTrace* trace);
 
   virtual void PrepareRendering();
-  virtual void PrepareRendering(TraceSubset& trace_subset, 
+  virtual void PrepareRendering(BackboneTrace& trace_subset, 
                                 IndexedVertexArray& va, bool is_sel);
-  virtual void Render();
+
   virtual void RenderPov(PovState& pov, const std::string& name);
 
   virtual bool CanSetOptions(RenderOptionsPtr& render_options);
@@ -51,14 +52,6 @@ public:
 
   virtual ~TraceRenderer();
 private:
-  VertexID AddCappedProfile(IndexedVertexArray& va, const Color& color,
-                            const geom::Vec3& center, const geom::Mat3& ori, 
-                            float radius, bool flip_normal, int n);
-  VertexID AddCircularProfile(IndexedVertexArray& va, const Color& color,
-                              const geom::Vec3& center, const geom::Mat3& ori,
-                              float radius, int n);
-  void ConnectProfiles(VertexID prof1, VertexID prof2, int n, 
-                       const geom::Vec3& dir, IndexedVertexArray& va);
   TraceRenderOptionsPtr  options_;
 };
 
diff --git a/modules/gfx/src/impl/trace_renderer_base.cc b/modules/gfx/src/impl/trace_renderer_base.cc
index 7fa679e88e98393087a4f79d3b02df46a60effaf..9231e929c5c791fc823bfbb8afc108b14d32319d 100644
--- a/modules/gfx/src/impl/trace_renderer_base.cc
+++ b/modules/gfx/src/impl/trace_renderer_base.cc
@@ -17,6 +17,10 @@
 // 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 //------------------------------------------------------------------------------
 
+/*
+  Authors: Marco Biasini, Ansgar Philippsen
+*/
+
 #include <ost/gfx/scene.hh>
 
 #include "trace_renderer_base.hh"
@@ -34,15 +38,15 @@ void set_node_entry_color(NodeEntry& e, ColorMask mask,
 }
 
 template <typename T1>
-inline void apply_color_op(TraceRendererBase* rend, TraceSubset& trace_subset, T1 get_col, const ColorOp& op)
+inline void apply_color_op(TraceRendererBase* rend, BackboneTrace& trace_subset, T1 get_col, const ColorOp& op)
 {
   rend->UpdateViews();
   ColorMask mask = op.GetMask();
   if(op.IsSelectionOnly()){
     mol::Query q(op.GetSelection());
-    for (int node_list=0; node_list<trace_subset.GetSize(); ++node_list) {
-      NodeListSubset& nl=trace_subset[node_list];
-      for (int i=0; i<nl.GetSize();++i) {
+    for (int node_list=0; node_list<trace_subset.GetListCount(); ++node_list) {
+      NodeEntryList& nl=trace_subset.GetList(node_list);
+      for (unsigned int i=0; i<nl.size();++i) {
         if (q.IsAtomSelected(nl[i].atom)) {
           Color clr =get_col.ColorOfAtom(nl[i].atom);
           set_node_entry_color(nl[i],mask,clr);
@@ -52,9 +56,9 @@ inline void apply_color_op(TraceRendererBase* rend, TraceSubset& trace_subset, T
   }
   else{
     mol::EntityView view = op.GetView();
-    for (int node_list=0; node_list<trace_subset.GetSize(); ++node_list) {
-      NodeListSubset& nl=trace_subset[node_list];
-      for (int i=0; i<nl.GetSize();++i) {
+    for (int node_list=0; node_list<trace_subset.GetListCount(); ++node_list) {
+      NodeEntryList& nl=trace_subset.GetList(node_list);
+      for (unsigned int i=0; i<nl.size();++i) {
         if(view.FindAtom(nl[i].atom)){
           Color clr =get_col.ColorOfAtom(nl[i].atom);
           set_node_entry_color(nl[i],mask,clr);
@@ -67,8 +71,8 @@ inline void apply_color_op(TraceRendererBase* rend, TraceSubset& trace_subset, T
 
 } //ns
 
-TraceRendererBase::TraceRendererBase(BackboneTrace& trace, int n):
-  trace_(trace), trace_subset_(trace, n), sel_subset_(trace, n)
+TraceRendererBase::TraceRendererBase(BackboneTrace* trace, int n):
+  trace_(trace), trace_subset_(*trace), sel_subset_()
 {
 }
 
@@ -80,43 +84,37 @@ void TraceRendererBase::UpdateViews()
 {
   if (state_ & DIRTY_VIEW) {
     mol::EntityView view=this->GetEffectiveView();
-    trace_subset_.Update(view);
+    trace_subset_=trace_->CreateSubset(view);
     state_&=~DIRTY_VIEW;    
   }
   if (this->HasSelection() && (sel_state_ & DIRTY_VIEW)) {
-    sel_subset_.Update(sel_);
+    sel_subset_ = trace_->CreateSubset(sel_);
     sel_state_&=~DIRTY_VIEW;    
   }
 }
 
 geom::AlignedCuboid TraceRendererBase::GetBoundingBox() const
 {
-  geom::Vec3 mmin, mmax;
+  geom::Vec3 mmin(std::numeric_limits<float>::max(),
+		  std::numeric_limits<float>::max(),
+		  std::numeric_limits<float>::max());
+  geom::Vec3 mmax(-std::numeric_limits<float>::max(),
+		  -std::numeric_limits<float>::max(),
+		  -std::numeric_limits<float>::max());
+		  
   assert(!(state_ & DIRTY_VIEW));
-  bool empty=true;
-  for (int node_list=0; node_list<trace_subset_.GetSize(); ++node_list) {
-    // first build the spline
-    const NodeListSubset& nl=trace_subset_[node_list];
-    for (int i=0; i<nl.GetSize();++i) {
+  for (int node_list=0; node_list<trace_subset_.GetListCount(); ++node_list) {
+    const NodeEntryList& nl=trace_subset_.GetList(node_list);
+    for (unsigned int i=0; i<nl.size();++i) {
       const NodeEntry& entry=nl[i];      
-      empty=false;
       geom::Vec3 p=entry.atom.GetPos();
-      if (node_list+i==0) {
-        mmin=p;
-        mmax=p;
-      } else {
-        mmin=geom::Min(mmin, p);
-        mmax=geom::Max(mmax, p);
-      }
+      mmin=geom::Min(mmin, p);
+      mmax=geom::Max(mmax, p);
     }
   }  
-  if (empty) {
-    throw Error("Can't calculate bounding box of empty renderer");
-  }
   return geom::AlignedCuboid(mmin, mmax);
 }
 
-
 void TraceRendererBase::Apply(const gfx::ByElementColorOp& op)
 {
   apply_color_op(this,trace_subset_,ByElementGetCol(),op);
@@ -151,16 +149,16 @@ void TraceRendererBase::Apply(const gfx::EntityViewColorOp& op)
 bool TraceRendererBase::HasDataToRender() const
 {
   assert(!(state_ & DIRTY_VIEW));
-  return this->trace_subset_.GetSize()>0;
+  return this->trace_subset_.GetListCount()>0;
 }
 
 void TraceRendererBase::set_node_colors(const Color& col, const mol::Query& q, 
                                         ColorMask mask)
 {
   this->UpdateViews();
-  for (int node_list=0; node_list<trace_subset_.GetSize(); ++node_list) {
-    NodeListSubset& nl=trace_subset_[node_list];
-    for (int i=0; i<nl.GetSize();++i) {
+  for (int node_list=0; node_list<trace_subset_.GetListCount(); ++node_list) {
+    NodeEntryList& nl=trace_subset_.GetList(node_list);
+    for (unsigned int i=0; i<nl.size();++i) {
       if(q.IsAtomSelected(nl[i].atom)) {
         set_node_entry_color(nl[i],mask,col);
       }
@@ -169,13 +167,6 @@ void TraceRendererBase::set_node_colors(const Color& col, const mol::Query& q,
   state_|=DIRTY_VA;  
 }
 
-void TraceRendererBase::set_node_entry_color(NodeEntry& e, ColorMask mask, 
-                                             const Color& c)
-{
-  if (mask & MAIN_COLOR) e.color1=c;
-  if (mask & DETAIL_COLOR) e.color2=c;
-}
-
 void TraceRendererBase::PickAtom(const geom::Line3& line, Real line_width,
                                  mol::AtomHandle& picked_atom)
 {
@@ -189,9 +180,9 @@ void TraceRendererBase::PickAtom(const geom::Line3& line, Real line_width,
   }
 
   mol::AtomHandle atom;
-  for (int node_list=0; node_list<trace_subset_.GetSize(); ++node_list) {
-    NodeListSubset& nl=trace_subset_[node_list];
-    for (int i=0; i<nl.GetSize();++i) {
+  for (int node_list=0; node_list<trace_subset_.GetListCount(); ++node_list) {
+    NodeEntryList& nl=trace_subset_.GetList(node_list);
+    for (unsigned int i=0; i<nl.size();++i) {
       geom::Vec3 p=nl[i].atom.GetPos();
       float dist = geom::Distance(line, p);
       if(dist<=max_dist) {
diff --git a/modules/gfx/src/impl/trace_renderer_base.hh b/modules/gfx/src/impl/trace_renderer_base.hh
index b102e1cc2c78c5ad1f2881e8530f51fb21a1b205..36e3b960270fa1c1882ae67c9b288eb77ed3613a 100644
--- a/modules/gfx/src/impl/trace_renderer_base.hh
+++ b/modules/gfx/src/impl/trace_renderer_base.hh
@@ -20,8 +20,8 @@
 #define OST_GFX_IMPL_TRACE_RENDERER_BASE_HH
 
 /*
-  Author: Marco Biasini
- */
+  Authors: Marco Biasini, Ansgar Philippsen
+*/
 
 #include <ost/gfx/module_config.hh>
 #include <ost/gfx/impl/entity_renderer.hh>
@@ -35,11 +35,11 @@ namespace ost { namespace gfx { namespace impl {
 ///     \ref "line trace" LineTraceRenderer and 
 ///     \ref "smooth trace" SlineRenderer.
 /// 
-/// The trace-based entity renderer share a  common instance of BackboneTrace 
-/// that encapulates a smoothed C-alpha trace.
+/// All trace-based entity renderers share a  common instance of BackboneTrace
+/// (which is held by gfx::Entity); it encapulates a smoothed C-alpha trace.
 class DLLEXPORT_OST_GFX TraceRendererBase : public EntityRenderer {
 public:
-  TraceRendererBase(BackboneTrace& trace, int overshoot);
+  TraceRendererBase(BackboneTrace* trace, int overshoot);
   
   virtual geom::AlignedCuboid GetBoundingBox() const;  
   
@@ -63,12 +63,10 @@ public:
 protected:
   
   void set_node_colors(const Color& c, const mol::Query& q, ColorMask mask);
-  void set_node_entry_color(NodeEntry& e, ColorMask mask, const Color& c);
-  
 
-  BackboneTrace& trace_;
-  TraceSubset    trace_subset_;
-  TraceSubset    sel_subset_;
+  BackboneTrace* trace_;
+  BackboneTrace trace_subset_;
+  BackboneTrace sel_subset_;
 };
 
 }}}
diff --git a/modules/gfx/src/render_options/cpk_render_options.cc b/modules/gfx/src/render_options/cpk_render_options.cc
index 611db0f48b7de674a82ceb956bec2589bbb23dd8..797fcf760bcd87fd731d5b4eb82a05e3d7547abf 100644
--- a/modules/gfx/src/render_options/cpk_render_options.cc
+++ b/modules/gfx/src/render_options/cpk_render_options.cc
@@ -28,7 +28,7 @@ namespace gfx {
 
 CPKRenderOptions::CPKRenderOptions(): sphere_detail_(4) {
 #if OST_SHADER_SUPPORT_ENABLED
-  cpk_mode_=1;
+  cpk_mode_=0;
 #else
   cpk_mode_=0;
 #endif
diff --git a/modules/gfx/src/render_pass.hh b/modules/gfx/src/render_pass.hh
index dd7a34a330b0ed36b817ce61f4b5131bdd31385c..00c5f7c23846a4b381b54a0aafdbcbc3d4481e22 100644
--- a/modules/gfx/src/render_pass.hh
+++ b/modules/gfx/src/render_pass.hh
@@ -33,8 +33,10 @@ typedef enum {
   /// \brief renders objects with solid color as used for shadow map
   ///     generation
   OPAQUE_RENDER_PASS,
+  /// \ brief for transparent objects
+  TRANSPARENT_RENDER_PASS
 } RenderPass;
  
 }}
 
-#endif
\ No newline at end of file
+#endif
diff --git a/modules/gfx/src/vertex_array.cc b/modules/gfx/src/vertex_array.cc
index 8ba36be18b7427d2bd05085b110a979f8da2adcc..06d9123eee509c02fd87e4f564268cf216e6b308 100644
--- a/modules/gfx/src/vertex_array.cc
+++ b/modules/gfx/src/vertex_array.cc
@@ -562,13 +562,16 @@ void IndexedVertexArray::RenderGL()
 namespace {
   unsigned int col_to_index(float* c)
   {
-    return static_cast<unsigned int>(c[0]*7.0)*64+static_cast<unsigned int>(c[1]*7.0)*8+static_cast<unsigned int>(c[2]*7.0);
+    // don't look too closely - I am lacking sufficient caffeine to do this more elegantly
+    int ret= std::max(0,std::min<int>(511,static_cast<int>(round(c[0]*7.0f))*64+static_cast<int>(round(c[1]*7.0f))*8+static_cast<unsigned int>(round(c[2]*7.0f))));
+    return static_cast<unsigned int>(ret);
   }
 }
 
 void IndexedVertexArray::RenderPov(PovState& pov, const std::string& name)
 {
   if(entry_list_.empty()) return;
+
   pov.inc() << "mesh2 {\n";
 
   pov.inc() << " vertex_vectors { " << entry_list_.size() << ",\n";