text: import numpy as np
  
  from fos import Actor
  import pyglet as pyglet
  from pyglet.gl import *
  import fos.core.collision as cll
  from fos.actor.primitives import AABBPrimitive
  
  class InteractiveCurves(Actor):
  
      def __init__(self,curves,colors=None,line_width=2.,affine=None):
              
          if affine is None:
              self.affine = np.eye(4, dtype = np.float32)
          else:
              self.affine = affine
          
          self.vertex_list =len(curves)*[None]
          self.len_vl=len(curves)
          self.range_vl=range(len(curves))
          self.selected=[]
          self.current=None        
          self.main_color=None
          self.updated=False
          self.line_width = line_width
  
          ccurves=np.concatenate(curves)
          self.min=np.min(ccurves,axis=0)
          self.max=np.max(ccurves,axis=0)
          self.mean=np.mean(ccurves,axis=0)
          self.position=(0,0,0)
                  
          coord1 = np.array([ccurves[:,0].min(),
                             ccurves[:,1].min(),
                             ccurves[:,2].min()], dtype = np.float32)
          
          coord2 = np.array([ccurves[:,0].max(),
                             ccurves[:,1].max(),
                             ccurves[:,2].max()], dtype = np.float32)
          
          self.make_aabb((coord1,coord2),10)
           #self.aabb=AABBPrimitive(np.array([-1000,-1000,1000]),np.array([1000,1000,-1000]),margin=0)
          print 'MBytes',ccurves.nbytes/2.**20
          self.curves_nbytes=ccurves.nbytes         
          self.curves=curves
          self.add_tracks(curves,colors)        
          
      def add_tracks(self,curves,colors=None):
          print 'adding tracks'
          if colors==None:
              main_color=np.array([1,1,1,1])
          for i,curve in enumerate(curves):
              curve=curve.astype('f')
              vertices=tuple(curve.ravel().tolist())
              if colors==None:
                  color=np.tile(main_color,(len(curve),1)).astype('f')
              else:
                  color=np.tile(colors[i],(len(curve),1)).astype('f')
              color=255*color
              color=np.round(color).astype('ubyte')
              color=tuple(color.ravel().tolist())                             
              self.vertex_list[i]= pyglet.graphics.vertex_list(len(curve),('v3f/static',vertices),('c4B/static',color))
          self.range_vl=range(len(curves))
          #print self.range_vl                
          self.compile_gl()
          
      def compile_gl(self):            
          index=glGenLists(1)
          glNewList( index,GL_COMPILE)
          [self.vertex_list[i].draw(GL_LINE_STRIP) for i in self.range_vl]
          glEndList()
          self.list_index=index       
  
      def draw(self):        
          self.set_state()        
          glCallList(self.list_index)        
          self.draw_aabb()
          self.unset_state()        
                    
      def update(self,dt):        
          cr=self.current
          if cr!=None:            
              if self.selected.count(cr)==0:
                  self.selected.append(cr)
                  color=self.vertex_list[cr].colors[:4]                
                  r,g,b,a=color                
                  ncolors=len(self.curves[cr])*(255,255,255,a)
                  self.vertex_list[cr].colors=ncolors            
              if self.selected.count(cr)>0:                
                  color=self.vertex_list[cr].colors[:4]
                  r,g,b,a=color               
                  ncolors=len(self.curves[cr])*(150,0,0,a)
                  self.vertex_list[cr].colors=ncolors
              self.current=None
              self.updated=True
  
      def process_pickray(self,near,far):        
                          
          min_dist_info=[ cll.mindistance_segment2track_info(near,far,xyz) \
                  for xyz in self.curves]
          A = np.array(min_dist_info)        
          dist=10**(-3)
          np.where(A[:,0]<dist)
          iA=np.where(A[:,0]<dist)
          minA=A[iA]
          if len(minA)==0:            
              iA=np.where(A[:,0]==A[:,0].min())
              minA = A[iA]        
          miniA=minA[:,1].argmin()        
          print 'track_id',iA[0][miniA]        
          self.current=iA[0][miniA]        
          if self.selected.count(self.current)==0:            
              self.selected.append(self.current)
          if self.selected.count(self.current)>0:
              self.selected.remove(self.current)
              
      def process_keys(self,symbol,modifiers):        
          #print symbol
          pass
          
      def process_mouse_motion(self,x,y,dx,dy):
          #print x,y
          pass
         
      def set_state(self):        
          glEnable(GL_DEPTH_TEST)
          glEnable(GL_BLEND)
          glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
          glEnable(GL_LINE_SMOOTH)        
          glHint(GL_LINE_SMOOTH_HINT, GL_NICEST)
          glLineWidth(self.line_width)
          
      def unset_state(self):
          glDisable(GL_DEPTH_TEST)
          glDisable(GL_BLEND)
          glDisable(GL_LINE_SMOOTH)
          glLineWidth(self.line_width)
  
      def delete(self):
          for i in range(len(self.vertex_list)):
              self.vertex_list[i].delete()
  