soc-2008-mxcurioni: merged changes to revision 15441
authorMaxime Curioni <maxime.curioni@gmail.com>
Sat, 5 Jul 2008 13:30:48 +0000 (13:30 +0000)
committerMaxime Curioni <maxime.curioni@gmail.com>
Sat, 5 Jul 2008 13:30:48 +0000 (13:30 +0000)
27 files changed:
1  2 
extern/SConscript
release/scripts/vrml97_export.py
source/blender/blenkernel/intern/image.c
source/blender/blenkernel/intern/modifier.c
source/blender/blenkernel/intern/object.c
source/blender/blenlib/BLI_arithb.h
source/blender/blenlib/BLI_winstuff.h
source/blender/blenlib/intern/arithb.c
source/blender/blenloader/intern/readfile.c
source/blender/makesdna/DNA_scene_types.h
source/blender/python/BPY_interface.c
source/blender/render/intern/source/pipeline.c
source/blender/render/intern/source/rendercore.c
source/blender/src/buttons_editing.c
source/blender/src/buttons_object.c
source/blender/src/buttons_scene.c
source/blender/src/buttons_shading.c
source/blender/src/editcurve.c
source/blender/src/editmesh_lib.c
source/blender/src/editobject.c
source/blender/src/editseq.c
source/blender/src/sequence.c
source/blender/src/space.c
source/blender/src/usiblender.c
source/gameengine/GamePlayer/common/SConscript
source/gameengine/GamePlayer/ghost/SConscript
source/gameengine/PyDoc/KX_GameObject.py

diff --combined extern/SConscript
index 67472a1e090ef677e4893f30b6ee1ae5a9ba5508,6612d38f4cfc6f3bc55360679ea1aa557c04950b..76120c4f63d86e33796ea6c531eb22b43d69c05a
@@@ -2,6 -2,8 +2,8 @@@
  
  Import('env')
  
+ SConscript(['glew/SConscript'])
  if env['WITH_BF_GAMEENGINE']:
      SConscript(['qhull/SConscript',
              'solid/SConscript'])
  if env['WITH_BF_BULLET']:
      SConscript(['bullet2/src/SConscript'])
  
 +if env['WITH_BF_FREESTYLE']:
 +    SConscript(['freestyle/lib3ds/SConscript'])
 +    SConscript(['freestyle/swig/SConscript'])
 +
  if env['WITH_BF_INTERNATIONAL']:
      SConscript(['bFTGL/SConscript'])
  
index 57ffd243bfc0b69990a62943be247babfe5bff5b,b28c7f5bbdc615506c299afdc07f12d6e5624d30..a9b83a8d0a68a9ecb00238ca68644751eede60c8
@@@ -3,14 -3,11 +3,11 @@@
  Name: 'VRML97 (.wrl)...'
  Blender: 241
  Group: 'Export'
- Submenu: 'All Objects...' all
- Submenu: 'All Objects compressed...' comp
- Submenu: 'Selected Objects...' selected
  Tooltip: 'Export to VRML97 file (.wrl)'
  """
  
  __author__ = ("Rick Kimball", "Ken Miller", "Steve Matthews", "Bart")
 -__url__ = ["blender", "blenderartists.org",
 +__url__ = ["blender", "elysiun",
  "Author's (Rick) homepage, http://kimballsoftware.com/blender",
  "Author's (Bart) homepage, http://www.neeneenee.de/vrml"]
  __email__ = ["Bart, bart:neeneenee*de"]
@@@ -55,7 -52,7 +52,7 @@@ want to export only selected or all rel
  
  import Blender
  from Blender import Object, Mesh, Lamp, Draw, BGL, \
-        Image, Text, sys, Mathutils
+        Image, Text, sys, Mathutils, Registry
  from Blender.Scene import Render
  
  import math
@@@ -70,8 -67,9 +67,9 @@@ worldmat = Blender.Texture.Get(
  filename = Blender.Get('filename')
  _safeOverwrite = True
  extension = ''
- ARG=''
  
+ # Matrices below are used only when export_rotate_z_to_y.val:
+ #
  # Blender is Z up, VRML is Y up, both are right hand coordinate
  # systems, so to go from Blender coords to VRML coords we rotate
  # by 90 degrees around the X axis. In matrix notation, we have a
@@@ -456,6 -454,8 +454,8 @@@ class VRML2Export
                                if mat:
                                        if (mat.mode & Blender.Material.Modes['VCOL_PAINT']):
                                                self.vcolors = 1
+               else:
+                       self.vcolors = 0
                        
                # check if object is wireframe only
                if ob.drawType == Blender.Object.DrawTypes.WIRE:
                meshVertexList = me.verts
  
                for vertex in meshVertexList:
-                       blenvert = Mathutils.Vector(vertex.co)
-                       vrmlvert = M_blen2vrml * blenvert
+                       vrmlvert = blenvert = Mathutils.Vector(vertex.co)
+                       if export_rotate_z_to_y.val:
+                               vrmlvert = M_blen2vrml * vrmlvert
                        self.writeUnindented("%s %s %s\n " % \
                                                                 (vrmlvert[0], \
                                                                  vrmlvert[1], \
                                                                         round(uv[1], self.tp))
                                                j=j+1
                                        indexStr += "-1"
-                       texIndexList.append(indexStr)
-                       texCoordList.append(coordStr)
+                                       texIndexList.append(indexStr)
+                                       texCoordList.append(coordStr)
  
                self.writeIndented("texCoord TextureCoordinate {\n", 1)
                self.writeIndented("point [\n", 1)
                        return
  
                ob_matrix = Mathutils.Matrix(ob.getMatrix('worldspace'))
-               matrix = M_blen2vrml * ob_matrix * M_vrml2blen
+               if export_rotate_z_to_y.val:
+                       matrix = M_blen2vrml * ob_matrix * M_vrml2blen
+               else:
+                       matrix = ob_matrix
                e      = matrix.rotationPart().toEuler()
  
                v = matrix.translationPart()
                self.writeFog()
                self.proto = 0
                allObj = []
-               if ARG == 'selected':
+               if export_selection_only.val:
                        allObj = list(scene.objects.context)
                else:
                        allObj = list(scene.objects)
                for thisObj in allObj:
                        self.writeObject(thisObj)
  
-               if ARG != 'selected':
+               if not export_selection_only.val:
                        self.writeScript()
                self.cleanup()
  
@@@ -1213,26 -1217,54 +1217,54 @@@ def select_file(filename)
        wrlexport=VRML2Export(filename)
        wrlexport.export(scene, world, worldmat)
  
+ #########################################################
+ # UI and Registry utilities
+ #########################################################
+ export_selection_only = Draw.Create(0)
+ export_rotate_z_to_y = Draw.Create(1)
+ export_compressed = Draw.Create(0)
+ def save_to_registry():
+       d = {}
+       d['selection_only'] = export_selection_only.val
+       d['rotate_z_to_y'] = export_rotate_z_to_y.val
+       d['compressed'] = export_compressed.val
+       Registry.SetKey('vrml97_export', d, True)
+ def load_from_registry():
+       d = Registry.GetKey('vrml97_export', True)
+       if d:
+               try:
+                       export_selection_only.val = d['selection_only']
+                       export_rotate_z_to_y.val = d['rotate_z_to_y']
+                       export_compressed.val = d['compressed']
+               except: save_to_registry() # If data is not valid, rewrite it.
+ def show_popup():
+       pup_block = [
+               ('Selection Only', export_selection_only, 'Only export objects in visible selection. Else export whole scene.'),
+               ('Rotate +Z to +Y', export_rotate_z_to_y, 'Rotate such that +Z axis (Blender up) becomes +Y (VRML up).'),
+               ('Compress', export_compressed, 'Generate a .wrz file (normal VRML compressed by gzip).')
+               ]
+       return Draw.PupBlock('Export VRML 97...', pup_block) 
  
  #########################################################
  # main routine
  #########################################################
  
- try:
-       ARG = __script__['arg'] # user selected argument
- except:
-       print "older version"
- if Blender.Get('version') < 235:
-       print "Warning: VRML97 export failed, wrong blender version!"
-       print " You aren't running blender version 2.35 or greater"
-       print " download a newer version from http://blender3d.org/"
- else:
-       if ARG == 'comp':
+ load_from_registry()
+ # Note that show_popup must be done before Blender.Window.FileSelector,
+ # because export_compressed affects the suggested extension of resulting
+ # file.
+ if show_popup():
+       save_to_registry()
+       if export_compressed.val:
                extension=".wrz"
                from gzip import *
        else:
                extension=".wrl"
        Blender.Window.FileSelector(select_file, "Export VRML97", \
                                                                sys.makename(ext=extension))
index caabc0362905d3bc19d9d9f686931a2dcf07ef91,c73279746fb909110661db33a6a12c677b3e2c72..5f4644576df409ee4f3d8d28bb45ca54b9e7ec72
@@@ -281,15 -281,19 +281,15 @@@ static Image *image_alloc(const char *n
  /* get the ibuf from an image cache, local use here only */
  static ImBuf *image_get_ibuf(Image *ima, int index, int frame)
  {
 -      /* this function is intended to be thread safe. with IMA_NO_INDEX this
 -       * should be OK, but when iterating over the list this is more tricky
 -       * */
        if(index==IMA_NO_INDEX)
                return ima->ibufs.first;
        else {
                ImBuf *ibuf;
 -
 +              
                index= IMA_MAKE_INDEX(frame, index);
                for(ibuf= ima->ibufs.first; ibuf; ibuf= ibuf->next)
                        if(ibuf->index==index)
                                return ibuf;
 -
                return NULL;
        }
  }
@@@ -317,19 -321,16 +317,19 @@@ static void image_assign_ibuf(Image *im
                for(link= ima->ibufs.first; link; link= link->next)
                        if(link->index>=index)
                                break;
 -
 -              ibuf->index= index;
 -
 -              /* this function accepts link==NULL */
 -              BLI_insertlinkbefore(&ima->ibufs, link, ibuf);
 -
                /* now we don't want copies? */
 -              if(link && ibuf->index==link->index)
 +              if(link && ibuf->index==link->index) {
 +                      ImBuf *prev= ibuf->prev;
                        image_remove_ibuf(ima, link);
 +                      link= prev;
 +              }
 +              
 +              /* this function accepts link==NULL */
 +              BLI_insertlinkbefore(&ima->ibufs, link, ibuf);
 +              
 +              ibuf->index= index;
        }
 +      
  }
  
  /* checks if image was already loaded, then returns same image */
@@@ -856,8 -857,8 +856,8 @@@ void BKE_add_image_extension(char *stri
                        extension= ".bmp";
        }
        else if(G.have_libtiff && (imtype==R_TIFF)) {
-               if(!BLI_testextensie(string, ".tif"))
-                       extension= ".tif";
+               if(!BLI_testextensie(string, ".tif") && 
+                       !BLI_testextensie(string, ".tiff")) extension= ".tif";
        }
  #ifdef WITH_OPENEXR
        else if( ELEM(imtype, R_OPENEXR, R_MULTILAYER)) {
@@@ -1504,12 -1505,12 +1504,12 @@@ static ImBuf *image_load_sequence_file(
                        ibuf= NULL;
                }
                else {
 -                      image_initialize_after_load(ima, ibuf);
                        image_assign_ibuf(ima, ibuf, 0, frame);
 +                      image_initialize_after_load(ima, ibuf);
                }
  #else
 -              image_initialize_after_load(ima, ibuf);
                image_assign_ibuf(ima, ibuf, 0, frame);
 +              image_initialize_after_load(ima, ibuf);
  #endif
        }
        else
@@@ -1545,8 -1546,9 +1545,8 @@@ static ImBuf *image_load_sequence_multi
                        // if(oldrr) printf("freed previous result %p\n", oldrr);
                        if(oldrr) RE_FreeRenderResult(oldrr);
                }
 -              else {
 +              else
                        ima->rr= oldrr;
 -              }
  
        }
        if(ima->rr) {
                        ibuf->mall= IB_rectfloat;
                        ibuf->channels= rpass->channels;
                        
 -                      image_initialize_after_load(ima, ibuf);
                        image_assign_ibuf(ima, ibuf, iuser->multi_index, frame);
 +                      image_initialize_after_load(ima, ibuf);
                        
                }
                // else printf("pass not found\n");
@@@ -1608,8 -1610,8 +1608,8 @@@ static ImBuf *image_load_movie_file(Ima
                ibuf = IMB_anim_absolute(ima->anim, fra);
                
                if(ibuf) {
 -                      image_initialize_after_load(ima, ibuf);
                        image_assign_ibuf(ima, ibuf, 0, frame);
 +                      image_initialize_after_load(ima, ibuf);
                }
                else
                        ima->ok= 0;
@@@ -1628,6 -1630,7 +1628,6 @@@ static ImBuf *image_load_image_file(Ima
  {
        struct ImBuf *ibuf;
        char str[FILE_MAX];
 -      int assign = 0;
        
        /* always ensure clean ima */
        image_free_buffers(ima);
                        ibuf= NULL;
                }
                else {
 +                      image_assign_ibuf(ima, ibuf, IMA_NO_INDEX, 0);
                        image_initialize_after_load(ima, ibuf);
 -                      assign= 1;
  
                        /* check if the image is a font image... */
                        detectBitmapFont(ibuf);
        else
                ima->ok= 0;
        
 -      if(assign)
 -              image_assign_ibuf(ima, ibuf, IMA_NO_INDEX, 0);
 -
        if(iuser)
                iuser->ok= ima->ok;
        
@@@ -1700,12 -1706,13 +1700,12 @@@ static ImBuf *image_get_ibuf_multilayer
                if(rpass) {
                        ibuf= IMB_allocImBuf(ima->rr->rectx, ima->rr->recty, 32, 0, 0);
                        
 +                      image_assign_ibuf(ima, ibuf, iuser?iuser->multi_index:IMA_NO_INDEX, 0);
                        image_initialize_after_load(ima, ibuf);
                        
                        ibuf->rect_float= rpass->rect;
                        ibuf->flags |= IB_rectfloat;
                        ibuf->channels= rpass->channels;
 -
 -                      image_assign_ibuf(ima, ibuf, iuser?iuser->multi_index:IMA_NO_INDEX, 0);
                }
        }
        
@@@ -1792,118 -1799,171 +1792,118 @@@ static ImBuf *image_get_render_result(I
        return NULL;
  }
  
 -static ImBuf *image_get_ibuf_threadsafe(Image *ima, ImageUser *iuser, int *frame_r, int *index_r)
 +/* Checks optional ImageUser and verifies/creates ImBuf. */
 +/* returns ibuf */
 +ImBuf *BKE_image_get_ibuf(Image *ima, ImageUser *iuser)
  {
 -      ImBuf *ibuf = NULL;
 -      int frame = 0, index = 0;
 +      ImBuf *ibuf= NULL;
 +      float color[] = {0, 0, 0, 1};
  
 -      /* see if we already have an appropriate ibuf, with image source and type */
 +      /* quick reject tests */
 +      if(ima==NULL) 
 +              return NULL;
 +      if(iuser) {
 +              if(iuser->ok==0)
 +                      return NULL;
 +      }
 +      else if(ima->ok==0)
 +              return NULL;
 +      
 +      BLI_lock_thread(LOCK_IMAGE);
 +      
 +      /* handle image source and types */
        if(ima->source==IMA_SRC_MOVIE) {
 -              frame= iuser?iuser->framenr:ima->lastframe;
 +              /* source is from single file, use flipbook to store ibuf */
 +              int frame= iuser?iuser->framenr:ima->lastframe;
 +              
                ibuf= image_get_ibuf(ima, 0, frame);
 +              if(ibuf==NULL)
 +                      ibuf= image_load_movie_file(ima, iuser, frame);
        }
        else if(ima->source==IMA_SRC_SEQUENCE) {
 +              
                if(ima->type==IMA_TYPE_IMAGE) {
 -                      frame= iuser?iuser->framenr:ima->lastframe;
 +                      /* regular files, ibufs in flipbook, allows saving */
 +                      int frame= iuser?iuser->framenr:ima->lastframe;
 +                      
                        ibuf= image_get_ibuf(ima, 0, frame);
 +                      if(ibuf==NULL)
 +                              ibuf= image_load_sequence_file(ima, iuser, frame);
 +                      else
 +                              BLI_strncpy(ima->name, ibuf->name, sizeof(ima->name));
                }
 -              else if(ima->type==IMA_TYPE_MULTILAYER) {
 -                      frame= iuser?iuser->framenr:ima->lastframe;
 -                      index= iuser?iuser->multi_index:IMA_NO_INDEX;
 +              /* no else; on load the ima type can change */
 +              if(ima->type==IMA_TYPE_MULTILAYER) {
 +                      /* only 1 layer/pass stored in imbufs, no exrhandle anim storage, no saving */
 +                      int frame= iuser?iuser->framenr:ima->lastframe;
 +                      int index= iuser?iuser->multi_index:IMA_NO_INDEX;
 +                      
                        ibuf= image_get_ibuf(ima, index, frame);
 +                      if(G.rt) printf("seq multi fra %d id %d ibuf %p %s\n", frame, index, ibuf, ima->id.name);
 +                      if(ibuf==NULL)
 +                              ibuf= image_load_sequence_multilayer(ima, iuser, frame);
 +                      else
 +                              BLI_strncpy(ima->name, ibuf->name, sizeof(ima->name));
                }
 +
        }
        else if(ima->source==IMA_SRC_FILE) {
 -              if(ima->type==IMA_TYPE_IMAGE)
 +              
 +              if(ima->type==IMA_TYPE_IMAGE) {
                        ibuf= image_get_ibuf(ima, IMA_NO_INDEX, 0);
 -              else if(ima->type==IMA_TYPE_MULTILAYER)
 +                      if(ibuf==NULL)
 +                              ibuf= image_load_image_file(ima, iuser, G.scene->r.cfra);       /* cfra only for '#', this global is OK */
 +              }
 +              /* no else; on load the ima type can change */
 +              if(ima->type==IMA_TYPE_MULTILAYER) {
 +                      /* keeps render result, stores ibufs in listbase, allows saving */
                        ibuf= image_get_ibuf(ima, iuser?iuser->multi_index:IMA_NO_INDEX, 0);
 +                      if(ibuf==NULL)
 +                              ibuf= image_get_ibuf_multilayer(ima, iuser);
 +              }
 +                      
        }
        else if(ima->source == IMA_SRC_GENERATED) {
 +              /* generated is: ibuf is allocated dynamically */
                ibuf= image_get_ibuf(ima, IMA_NO_INDEX, 0);
 +              
 +              if(ibuf==NULL) {
 +                      if(ima->type==IMA_TYPE_VERSE) {
 +                              /* todo */
 +                      }
 +                      else { /* always fall back to IMA_TYPE_UV_TEST */
 +                              /* UV testgrid or black or solid etc */
 +                              if(ima->gen_x==0) ima->gen_x= 256;
 +                              if(ima->gen_y==0) ima->gen_y= 256;
 +                              ibuf= add_ibuf_size(ima->gen_x, ima->gen_y, ima->name, 0, ima->gen_type, color);
 +                              image_assign_ibuf(ima, ibuf, IMA_NO_INDEX, 0);
 +                              ima->ok= IMA_OK_LOADED;
 +                      }
 +              }
        }
        else if(ima->source == IMA_SRC_VIEWER) {
                if(ima->type==IMA_TYPE_R_RESULT) {
 -                      /* always verify entirely, not that this shouldn't happen
 -                       * during render anyway */
 +                      /* always verify entirely */
 +                      ibuf= image_get_render_result(ima, iuser);
                }
                else if(ima->type==IMA_TYPE_COMPOSITE) {
 -                      frame= iuser?iuser->framenr:0;
 +                      int frame= iuser?iuser->framenr:0;
 +                      
 +                      /* Composite Viewer, all handled in compositor */
                        ibuf= image_get_ibuf(ima, 0, frame);
 -              }
 -      }
 -
 -      *frame_r = frame;
 -      *index_r = index;
 -
 -      return ibuf;
 -}
 -
 -/* Checks optional ImageUser and verifies/creates ImBuf. */
 -/* returns ibuf */
 -ImBuf *BKE_image_get_ibuf(Image *ima, ImageUser *iuser)
 -{
 -      ImBuf *ibuf= NULL;
 -      float color[] = {0, 0, 0, 1};
 -      int frame= 0, index= 0;
 -
 -      /* This function is intended to be thread-safe. It postpones the mutex lock
 -       * until it needs to load the image, if the image is already there it
 -       * should just get the pointer and return. The reason is that a lot of mutex
 -       * locks appears to be very slow on certain multicore macs, causing a render
 -       * with image textures to actually slow down as more threads are used.
 -       *
 -       * Note that all the image loading functions should also make sure they do
 -       * things in a threadsafe way for image_get_ibuf_threadsafe to work correct.
 -       * That means, the last two steps must be, 1) add the ibuf to the list and
 -       * 2) set ima/iuser->ok to 0 to IMA_OK_LOADED */
 -
 -      /* quick reject tests */
 -      if(ima==NULL) 
 -              return NULL;
 -      if(iuser) {
 -              if(iuser->ok==0)
 -                      return NULL;
 -      }
 -      else if(ima->ok==0)
 -              return NULL;
 -      
 -      /* try to get the ibuf without locking */
 -      ibuf= image_get_ibuf_threadsafe(ima, iuser, &frame, &index);
 -
 -      if(ibuf == NULL) {
 -              /* couldn't get ibuf and image is not ok, so let's lock and try to
 -               * load the image */
 -              BLI_lock_thread(LOCK_IMAGE);
 -
 -              /* need to check ok flag and loading ibuf again, because the situation
 -               * might have changed in the meantime */
 -              if(iuser) {
 -                      if(iuser->ok==0) {
 -                              BLI_unlock_thread(LOCK_IMAGE);
 -                              return NULL;
 -                      }
 -              }
 -              else if(ima->ok==0) {
 -                      BLI_unlock_thread(LOCK_IMAGE);
 -                      return NULL;
 -              }
 -
 -              ibuf= image_get_ibuf_threadsafe(ima, iuser, &frame, &index);
 -
 -              if(ibuf == NULL) {
 -                      /* we are sure we have to load the ibuf, using source and type */
 -                      if(ima->source==IMA_SRC_MOVIE) {
 -                              /* source is from single file, use flipbook to store ibuf */
 -                              ibuf= image_load_movie_file(ima, iuser, frame);
 -                      }
 -                      else if(ima->source==IMA_SRC_SEQUENCE) {
 -                              if(ima->type==IMA_TYPE_IMAGE) {
 -                                      /* regular files, ibufs in flipbook, allows saving */
 -                                      ibuf= image_load_sequence_file(ima, iuser, frame);
 -                              }
 -                              /* no else; on load the ima type can change */
 -                              if(ima->type==IMA_TYPE_MULTILAYER) {
 -                                      /* only 1 layer/pass stored in imbufs, no exrhandle anim storage, no saving */
 -                                      ibuf= image_load_sequence_multilayer(ima, iuser, frame);
 -                              }
 -
 -                              if(ibuf)
 -                                      BLI_strncpy(ima->name, ibuf->name, sizeof(ima->name));
 -                      }
 -                      else if(ima->source==IMA_SRC_FILE) {
 -                              
 -                              if(ima->type==IMA_TYPE_IMAGE)
 -                                      ibuf= image_load_image_file(ima, iuser, G.scene->r.cfra);       /* cfra only for '#', this global is OK */
 -                              /* no else; on load the ima type can change */
 -                              if(ima->type==IMA_TYPE_MULTILAYER)
 -                                      /* keeps render result, stores ibufs in listbase, allows saving */
 -                                      ibuf= image_get_ibuf_multilayer(ima, iuser);
 -                                      
 -                      }
 -                      else if(ima->source == IMA_SRC_GENERATED) {
 -                              /* generated is: ibuf is allocated dynamically */
 -                              if(ima->type==IMA_TYPE_VERSE) {
 -                                      /* todo */
 -                              }
 -                              else { /* always fall back to IMA_TYPE_UV_TEST */
 -                                      /* UV testgrid or black or solid etc */
 -                                      if(ima->gen_x==0) ima->gen_x= 256;
 -                                      if(ima->gen_y==0) ima->gen_y= 256;
 -                                      ibuf= add_ibuf_size(ima->gen_x, ima->gen_y, ima->name, 0, ima->gen_type, color);
 -                                      image_assign_ibuf(ima, ibuf, IMA_NO_INDEX, 0);
 -                                      ima->ok= IMA_OK_LOADED;
 -                              }
 -                      }
 -                      else if(ima->source == IMA_SRC_VIEWER) {
 -                              if(ima->type==IMA_TYPE_R_RESULT) {
 -                                      /* always verify entirely */
 -                                      ibuf= image_get_render_result(ima, iuser);
 -                              }
 -                              else if(ima->type==IMA_TYPE_COMPOSITE) {
 -                                      /* Composite Viewer, all handled in compositor */
 -                                      /* fake ibuf, will be filled in compositor */
 -                                      ibuf= IMB_allocImBuf(256, 256, 32, IB_rect, 0);
 -                                      image_assign_ibuf(ima, ibuf, 0, frame);
 -                              }
 +                      if(ibuf==NULL) {
 +                              /* fake ibuf, will be filled in compositor */
 +                              ibuf= IMB_allocImBuf(256, 256, 32, IB_rect, 0);
 +                              image_assign_ibuf(ima, ibuf, 0, frame);
                        }
                }
 -
 -              BLI_unlock_thread(LOCK_IMAGE);
        }
  
 -      /* we assuming that if it is not rendering, it's also not multithreaded
 -       * (a somewhat weak assumption) */
        if(G.rendering==0)
                tag_image_time(ima);
  
 +      BLI_unlock_thread(LOCK_IMAGE);
 +
        return ibuf;
  }
  
index ce04e6da538a5d8fcadeaacbfbe988bfaf9d3752,a0841bb9f03907ed41d78049b95384c486dc5444..e9a89ba15c4f91318e209f68f72d21b08ca4da8d
@@@ -40,6 -40,7 +40,7 @@@
  #include "stdarg.h"
  #include "math.h"
  #include "float.h"
+ #include "ctype.h"
  
  #include "BLI_arithb.h"
  #include "BLI_blenlib.h"
@@@ -1269,7 -1270,7 +1270,7 @@@ static void mirrorModifier_initData(Mod
  {
        MirrorModifierData *mmd = (MirrorModifierData*) md;
  
-       mmd->flag |= MOD_MIR_AXIS_X;
+       mmd->flag |= (MOD_MIR_AXIS_X | MOD_MIR_VGROUP);
        mmd->tolerance = 0.001;
        mmd->mirror_ob = NULL;
  }
@@@ -1308,11 -1309,123 +1309,123 @@@ static void mirrorModifier_updateDepgra
        }
  }
  
+ /* finds the best possible flipped name. For renaming; check for unique names afterwards */
+ /* if strip_number: removes number extensions */
+ void vertgroup_flip_name (char *name, int strip_number)
+ {
+       int     len;
+       char    prefix[128]={""};   /* The part before the facing */
+       char    suffix[128]={""};   /* The part after the facing */
+       char    replace[128]={""};  /* The replacement string */
+       char    number[128]={""};   /* The number extension string */
+       char    *index=NULL;
+       len= strlen(name);
+       if(len<3) return; // we don't do names like .R or .L
+       /* We first check the case with a .### extension, let's find the last period */
+       if(isdigit(name[len-1])) {
+               index= strrchr(name, '.'); // last occurrance
+               if (index && isdigit(index[1]) ) { // doesnt handle case bone.1abc2 correct..., whatever!
+                       if(strip_number==0) 
+                               strcpy(number, index);
+                       *index= 0;
+                       len= strlen(name);
+               }
+       }
+       strcpy (prefix, name);
+ #define IS_SEPARATOR(a) ((a)=='.' || (a)==' ' || (a)=='-' || (a)=='_')
+       /* first case; separator . - _ with extensions r R l L  */
+       if( IS_SEPARATOR(name[len-2]) ) {
+               switch(name[len-1]) {
+                       case 'l':
+                               prefix[len-1]= 0;
+                               strcpy(replace, "r");
+                               break;
+                       case 'r':
+                               prefix[len-1]= 0;
+                               strcpy(replace, "l");
+                               break;
+                       case 'L':
+                               prefix[len-1]= 0;
+                               strcpy(replace, "R");
+                               break;
+                       case 'R':
+                               prefix[len-1]= 0;
+                               strcpy(replace, "L");
+                               break;
+               }
+       }
+       /* case; beginning with r R l L , with separator after it */
+       else if( IS_SEPARATOR(name[1]) ) {
+               switch(name[0]) {
+                       case 'l':
+                               strcpy(replace, "r");
+                               strcpy(suffix, name+1);
+                               prefix[0]= 0;
+                               break;
+                       case 'r':
+                               strcpy(replace, "l");
+                               strcpy(suffix, name+1);
+                               prefix[0]= 0;
+                               break;
+                       case 'L':
+                               strcpy(replace, "R");
+                               strcpy(suffix, name+1);
+                               prefix[0]= 0;
+                               break;
+                       case 'R':
+                               strcpy(replace, "L");
+                               strcpy(suffix, name+1);
+                               prefix[0]= 0;
+                               break;
+               }
+       }
+       else if(len > 5) {
+               /* hrms, why test for a separator? lets do the rule 'ultimate left or right' */
+               index = BLI_strcasestr(prefix, "right");
+               if (index==prefix || index==prefix+len-5) {
+                       if(index[0]=='r') 
+                               strcpy (replace, "left");
+                       else {
+                               if(index[1]=='I') 
+                                       strcpy (replace, "LEFT");
+                               else
+                                       strcpy (replace, "Left");
+                       }
+                       *index= 0;
+                       strcpy (suffix, index+5);
+               }
+               else {
+                       index = BLI_strcasestr(prefix, "left");
+                       if (index==prefix || index==prefix+len-4) {
+                               if(index[0]=='l') 
+                                       strcpy (replace, "right");
+                               else {
+                                       if(index[1]=='E') 
+                                               strcpy (replace, "RIGHT");
+                                       else
+                                               strcpy (replace, "Right");
+                               }
+                               *index= 0;
+                               strcpy (suffix, index+4);
+                       }
+               }
+       }
+ #undef IS_SEPARATOR
+       sprintf (name, "%s%s%s%s", prefix, replace, suffix, number);
+ }
  static DerivedMesh *doMirrorOnAxis(MirrorModifierData *mmd,
-                                  Object *ob,
-        DerivedMesh *dm,
-        int initFlags,
-        int axis)
+               Object *ob,
+               DerivedMesh *dm,
+               int initFlags,
+               int axis)
  {
        int i;
        float tolerance = mmd->tolerance;
        int maxVerts = dm->getNumVerts(dm);
        int maxEdges = dm->getNumEdges(dm);
        int maxFaces = dm->getNumFaces(dm);
+       int vector_size=0, j, a, b;
+       bDeformGroup *def, *defb;
+       bDeformGroup **vector_def = NULL;
        int (*indexMap)[2];
        float mtx[4][4], imtx[4][4];
  
  
        result = CDDM_from_template(dm, maxVerts * 2, maxEdges * 2, maxFaces * 2);
  
+       if (mmd->flag & MOD_MIR_VGROUP) {
+               /* calculate the number of deformedGroups */
+               for(vector_size = 0, def = ob->defbase.first; def;
+                   def = def->next, vector_size++);
+               /* load the deformedGroups for fast access */
+               vector_def =
+                   (bDeformGroup **)MEM_mallocN(sizeof(bDeformGroup*) * vector_size,
+                                                "group_index");
+               for(a = 0, def = ob->defbase.first; def; def = def->next, a++) {
+                       vector_def[a] = def;
+               }
+       }
        if (mmd->mirror_ob) {
                float obinv[4][4];
+               
                Mat4Invert(obinv, mmd->mirror_ob->obmat);
                Mat4MulMat4(mtx, ob->obmat, obinv);
                Mat4Invert(imtx, mtx);
                MVert *mv = CDDM_get_vert(result, numVerts);
                int isShared;
                float co[3];
+               
                dm->getVert(dm, i, &inMV);
+               
                VecCopyf(co, inMV.co);
+               
                if (mmd->mirror_ob) {
                        VecMat4MulVecfl(co, mtx, co);
                }
                isShared = ABS(co[axis])<=tolerance;
+               
                /* Because the topology result (# of vertices) must be the same if
                * the mesh data is overridden by vertex cos, have to calc sharedness
                * based on original coordinates. This is why we test before copy.
                DM_copy_vert_data(dm, result, i, numVerts, 1);
                *mv = inMV;
                numVerts++;
+               
                indexMap[i][0] = numVerts - 1;
                indexMap[i][1] = !isShared;
+               
                if(isShared) {
                        co[axis] = 0;
                        if (mmd->mirror_ob) {
                        mv->flag |= ME_VERT_MERGED;
                } else {
                        MVert *mv2 = CDDM_get_vert(result, numVerts);
+                       MDeformVert *dvert = NULL;
+                       
                        DM_copy_vert_data(dm, result, i, numVerts, 1);
                        *mv2 = *mv;
-                       numVerts++;
+                       
                        co[axis] = -co[axis];
                        if (mmd->mirror_ob) {
                                VecMat4MulVecfl(co, imtx, co);
                        }
                        VecCopyf(mv2->co, co);
+                       
+                       if (mmd->flag & MOD_MIR_VGROUP){
+                               dvert = DM_get_vert_data(result, numVerts, CD_MDEFORMVERT);
+                               
+                               if (dvert)
+                               {
+                                       for(j = 0; j < dvert[0].totweight; ++j)
+                                       {
+                                               char tmpname[32];
+                                               
+                                               if(dvert->dw[j].def_nr < 0 ||
+                                                  dvert->dw[j].def_nr >= vector_size)
+                                                       continue;
+                                               
+                                               def = vector_def[dvert->dw[j].def_nr];
+                                               strcpy(tmpname, def->name);
+                                               vertgroup_flip_name(tmpname,0);
+                                               
+                                               for(b = 0, defb = ob->defbase.first; defb;
+                                                   defb = defb->next, b++)
+                                               {
+                                                       if(!strcmp(defb->name, tmpname))
+                                                       {
+                                                               dvert->dw[j].def_nr = b;
+                                                               break;
+                                                       }
+                                               }
+                                       }
+                               }
+                       }
+                       
+                       numVerts++;
                }
        }
  
        for(i = 0; i < maxEdges; i++) {
                MEdge inMED;
                MEdge *med = CDDM_get_edge(result, numEdges);
+               
                dm->getEdge(dm, i, &inMED);
+               
                DM_copy_edge_data(dm, result, i, numEdges, 1);
                *med = inMED;
                numEdges++;
+               
                med->v1 = indexMap[inMED.v1][0];
                med->v2 = indexMap[inMED.v2][0];
                if(initFlags)
                        med->flag |= ME_EDGEDRAW | ME_EDGERENDER;
+               
                if(indexMap[inMED.v1][1] || indexMap[inMED.v2][1]) {
                        MEdge *med2 = CDDM_get_edge(result, numEdges);
+                       
                        DM_copy_edge_data(dm, result, i, numEdges, 1);
                        *med2 = *med;
                        numEdges++;
+                       
                        med2->v1 += indexMap[inMED.v1][1];
                        med2->v2 += indexMap[inMED.v2][1];
                }
        for(i = 0; i < maxFaces; i++) {
                MFace inMF;
                MFace *mf = CDDM_get_face(result, numFaces);
+               
                dm->getFace(dm, i, &inMF);
+               
                DM_copy_face_data(dm, result, i, numFaces, 1);
                *mf = inMF;
                numFaces++;
+               
                mf->v1 = indexMap[inMF.v1][0];
                mf->v2 = indexMap[inMF.v2][0];
                mf->v3 = indexMap[inMF.v3][0];
                                 || (mf->v4 && indexMap[inMF.v4][1])) {
                        MFace *mf2 = CDDM_get_face(result, numFaces);
                        static int corner_indices[4] = {2, 1, 0, 3};
+                       
                        DM_copy_face_data(dm, result, i, numFaces, 1);
                        *mf2 = *mf;
+                       
                        mf2->v1 += indexMap[inMF.v1][1];
                        mf2->v2 += indexMap[inMF.v2][1];
                        mf2->v3 += indexMap[inMF.v3][1];
                        if(inMF.v4) mf2->v4 += indexMap[inMF.v4][1];
+                       
                        /* mirror UVs if enabled */
                        if(mmd->flag & (MOD_MIR_MIRROR_U | MOD_MIR_MIRROR_V)) {
                                MTFace *tf = result->getFaceData(result, numFaces, CD_MTFACE);
                                        }
                                }
                        }
+                       
                        /* Flip face normal */
                        SWAP(int, mf2->v1, mf2->v3);
                        DM_swap_face_data(result, numFaces, corner_indices);
+                       
                        test_index_face(mf2, &result->faceData, numFaces, inMF.v4?4:3);
                        numFaces++;
-                                }
+               }
        }
  
+       if (vector_def) MEM_freeN(vector_def);
        MEM_freeN(indexMap);
  
        CDDM_lower_num_verts(result, numVerts);
  }
  
  static DerivedMesh *mirrorModifier__doMirror(MirrorModifierData *mmd,
-                                            Object *ob, DerivedMesh *dm,
-         int initFlags)
+                                           Object *ob, DerivedMesh *dm,
+                                               int initFlags)
  {
        DerivedMesh *result = dm;
  
@@@ -4360,13 -4525,13 +4525,13 @@@ static void castModifier_deformVertsEM
  
  /* Wave */
  
- static void waveModifier_initData(ModifierData *md) 
+ static void waveModifier_initData(ModifierData *md)
  {
        WaveModifierData *wmd = (WaveModifierData*) md; // whadya know, moved here from Iraq
-               
        wmd->flag |= (MOD_WAVE_X | MOD_WAVE_Y | MOD_WAVE_CYCL
                        | MOD_WAVE_NORM_X | MOD_WAVE_NORM_Y | MOD_WAVE_NORM_Z);
-       
        wmd->objectcenter = NULL;
        wmd->texture = NULL;
        wmd->map_object = NULL;
        wmd->narrow= 1.5f;
        wmd->lifetime= 0.0f;
        wmd->damp= 10.0f;
+       wmd->falloff= 0.0f;
        wmd->texmapping = MOD_WAV_MAP_LOCAL;
        wmd->defgrp_name[0] = 0;
  }
@@@ -4395,6 -4561,7 +4561,7 @@@ static void waveModifier_copyData(Modif
        twmd->starty = wmd->starty;
        twmd->timeoffs = wmd->timeoffs;
        twmd->width = wmd->width;
+       twmd->falloff = wmd->falloff;
        twmd->objectcenter = wmd->objectcenter;
        twmd->texture = wmd->texture;
        twmd->map_object = wmd->map_object;
@@@ -4605,7 -4772,7 +4772,7 @@@ static void waveModifier_do
  
                if(x > wmd->lifetime) {
                        lifefac = x - wmd->lifetime;
-                       
                        if(lifefac > wmd->damp) lifefac = 0.0;
                        else lifefac =
                                (float)(wmd->height * (1.0 - sqrt(lifefac / wmd->damp)));
                        float x = co[0] - wmd->startx;
                        float y = co[1] - wmd->starty;
                        float amplit= 0.0f;
+                       float dist = 0.0f;
+                       float falloff_fac = 0.0f;
                        TexResult texres;
                        MDeformWeight *def_weight = NULL;
  
                                get_texture_value(wmd->texture, tex_co[i], &texres);
                        }
  
+                       /*get dist*/
+                       if(wmd->flag & MOD_WAVE_X) {
+                               if(wmd->flag & MOD_WAVE_Y){
+                                       dist = (float)sqrt(x*x + y*y);
+                               }
+                               else{
+                                       dist = fabs(x);
+                               }
+                       }
+                       else if(wmd->flag & MOD_WAVE_Y) {
+                               dist = fabs(y);
+                       }
+                       falloff_fac = (1.0-(dist / wmd->falloff));
+                       CLAMP(falloff_fac,0,1);
  
                        if(wmd->flag & MOD_WAVE_X) {
                                if(wmd->flag & MOD_WAVE_Y) amplit = (float)sqrt(x*x + y*y);
                                else amplit = x;
                        }
-                       else if(wmd->flag & MOD_WAVE_Y) 
+                       else if(wmd->flag & MOD_WAVE_Y)
                                amplit= y;
-                       
                        /* this way it makes nice circles */
                        amplit -= (ctime - wmd->timeoffs) * wmd->speed;
  
                        if(amplit > -wmd->width && amplit < wmd->width) {
                                amplit = amplit * wmd->narrow;
                                amplit = (float)(1.0 / exp(amplit * amplit) - minfac);
+                               /*apply texture*/
                                if(wmd->texture)
                                        amplit = amplit * texres.tin;
  
+                               /*apply weight*/
                                if(def_weight)
                                        amplit = amplit * def_weight->weight;
  
+                               /*apply falloff*/
+                               if (wmd->falloff > 0)
+                                       amplit = amplit * falloff_fac;
                                if(mvert) {
                                        /* move along normals */
                                        if(wmd->flag & MOD_WAVE_NORM_X) {
@@@ -5877,6 -6068,8 +6068,6 @@@ static void explodeModifier_copyData(Mo
  
        temd->facepa = 0;
        temd->flag = emd->flag;
 -      temd->protect = emd->protect;
 -      temd->vgroup = emd->vgroup;
  }
  static int explodeModifier_dependsOnTime(ModifierData *md) 
  {
index 47dc12ecbd5fa1dba7557ecbb941854651f820ac,7b36e46d45e078011edac6d9c574155392bddc81..d232ebe8cb445f191a5ef860b0079777fec21de2
@@@ -732,6 -732,17 +732,17 @@@ void *add_lamp(char *name
        la->preview=NULL;
        la->falloff_type = LA_FALLOFF_INVLINEAR;
        la->curfalloff = curvemapping_add(1, 0.0f, 1.0f, 1.0f, 0.0f);
+       la->sun_effect_type = 0;
+       la->horizon_brightness = 1.0;
+       la->spread = 1.0;
+       la->sun_brightness = 1.0;
+       la->sun_size = 1.0;
+       la->backscattered_light = 1.0;
+       la->atm_turbidity = 2.0;
+       la->atm_inscattering_factor = 1.0;
+       la->atm_extinction_factor = 1.0;
+       la->atm_distance_factor = 1.0;
+       la->sun_intensity = 1.0;
        curvemapping_initialize(la->curfalloff);
        return la;
  }
@@@ -1100,6 -1111,8 +1111,8 @@@ static void copy_object_pose(Object *ob
  {
        bPoseChannel *chan;
        
+       /* note: need to clear obn->pose pointer first, so that copy_pose works (otherwise there's a crash) */
+       obn->pose= NULL;
        copy_pose(&obn->pose, ob->pose, 1);     /* 1 = copy constraints */
  
        for (chan = obn->pose->chanbase.first; chan; chan=chan->next){
@@@ -1220,6 -1233,7 +1233,6 @@@ Object *copy_object(Object *ob
  void expand_local_object(Object *ob)
  {
        bActionStrip *strip;
 -      ParticleSystem *psys;
        int a;
        
        id_lib_extern((ID *)ob->action);
        for (strip=ob->nlastrips.first; strip; strip=strip->next) {
                id_lib_extern((ID *)strip->act);
        }
 -      for(psys=ob->particlesystem.first; psys; psys=psys->next)
 -              id_lib_extern((ID *)psys->part);
 +
  }
  
  void make_local_object(Object *ob)
@@@ -1376,7 -1391,7 +1389,7 @@@ void object_make_proxy(Object *ob, Obje
                ob->mat = MEM_dupallocN(target->mat);
                for(i=0; i<target->totcol; i++) {
                        /* dont need to run test_object_materials since we know this object is new and not used elsewhere */
 -                      id_us_plus((ID *)ob->mat[i]); 
 +                      id_us_plus(ob->mat[i]); 
                }
        }
        
@@@ -2378,3 -2393,31 +2391,31 @@@ int give_obdata_texspace(Object *ob, in
        }
        return 1;
  }
+ /*
+  * Test a bounding box for ray intersection
+  * assumes the ray is already local to the boundbox space
+  */
+ int ray_hit_boundbox(struct BoundBox *bb, float ray_start[3], float ray_normal[3])
+ {
+       static int triangle_indexes[12][3] = {{0, 1, 2}, {0, 2, 3},
+                                                                                 {3, 2, 6}, {3, 6, 7},
+                                                                                 {1, 2, 6}, {1, 6, 5}, 
+                                                                                 {5, 6, 7}, {4, 5, 7},
+                                                                                 {0, 3, 7}, {0, 4, 7},
+                                                                                 {0, 1, 5}, {0, 4, 5}};
+       int result = 0;
+       int i;
+       
+       for (i = 0; i < 12 && result == 0; i++)
+       {
+               float lambda;
+               int v1, v2, v3;
+               v1 = triangle_indexes[i][0];
+               v2 = triangle_indexes[i][1];
+               v3 = triangle_indexes[i][2];
+               result = RayIntersectsTriangle(ray_start, ray_normal, bb->vec[v1], bb->vec[v2], bb->vec[v3], &lambda, NULL);
+       }
+       
+       return result;
+ }
index 5b4e380f88ea6853869c7f5591c75df4143cf114,c22b6f79e08f91c86eee4054db39a96808ec6b05..e8fe157744082d11a5e7147b0390456dd37a91c2
@@@ -50,6 -50,9 +50,9 @@@ extern "C" 
  #ifndef M_SQRT1_2
  #define M_SQRT1_2     0.70710678118654752440
  #endif
+ #ifndef M_1_PI
+ #define M_1_PI                0.318309886183790671538
+ #endif
  
  #ifdef WIN32
        #ifndef FREE_WINDOWS
@@@ -96,7 -99,7 +99,7 @@@ float CalcNormFloat4(float *v1, float *
  void CalcNormLong(int *v1, int *v2, int *v3, float *n);
  /* CalcNormShort: is ook uitprodukt - (translates as 'is also out/cross product') */
  void CalcNormShort(short *v1, short *v2, short *v3, float *n);
 -float power_of_2(float val);
 +
  
  /**
   * @section Euler conversion routines
@@@ -258,6 -261,7 +261,7 @@@ void Vec2Addf(float *v, float *v1, floa
  void Vec2Subf(float *v, float *v1, float *v2);
  void Vec2Copyf(float *v1, float *v2);
  
+ void AxisAngleToQuat(float *q, float *axis, float angle);
  void vectoquat(float *vec, short axis, short upflag, float *q);
  
  float VecAngle2(float *v1, float *v2);
@@@ -269,6 -273,8 +273,8 @@@ float NormalizedVecAngle2_2D(float *v1
  
  void euler_rot(float *beul, float ang, char axis);
        
+ void NormalShortToFloat(float *out, short *in);
+ void NormalFloatToShort(short *out, float *in);
  
  float DistVL2Dfl(float *v1, float *v2, float *v3);
  float PdistVL2Dfl(float *v1, float *v2, float *v3);
@@@ -320,6 -326,9 +326,9 @@@ void yuv_to_rgb(float y, float u, floa
  void ycc_to_rgb(float y, float cb, float cr, float *lr, float *lg, float *lb);
  void rgb_to_ycc(float r, float g, float b, float *ly, float *lcb, float *lcr);
  void rgb_to_hsv(float r, float g, float b, float *lh, float *ls, float *lv);
+ void xyz_to_rgb(float x, float y, float z, float *r, float *g, float *b);
+ int constrain_rgb(float *r, float *g, float *b);
+ void gamma_correct_rgb(float *r, float *g, float *b);
  unsigned int hsv_to_cpack(float h, float s, float v);
  unsigned int rgb_to_cpack(float r, float g, float b);
  void cpack_to_rgb(unsigned int col, float *r, float *g, float *b);
@@@ -371,7 -380,9 +380,9 @@@ void LocQuatSizeToMat4(float mat[][4], 
  void tubemap(float x, float y, float z, float *u, float *v);
  void spheremap(float x, float y, float z, float *u, float *v);
  
+ int LineIntersectLine(float v1[3], float v2[3], float v3[3], float v4[3], float i1[3], float i2[3]);
  int LineIntersectsTriangle(float p1[3], float p2[3], float v0[3], float v1[3], float v2[3], float *lambda, float *uv);
+ int RayIntersectsTriangle(float p1[3], float d[3], float v0[3], float v1[3], float v2[3], float *lambda, float *uv);
  int SweepingSphereIntersectsTriangleUV(float p1[3], float p2[3], float radius, float v0[3], float v1[3], float v2[3], float *lambda, float *ipoint);
  int AxialLineIntersectsTriangle(int axis, float co1[3], float co2[3], float v0[3], float v1[3], float v2[3], float *lambda);
  int AabbIntersectAabb(float min1[3], float max1[3], float min2[3], float max2[3]);
index 54d70626dd580b9938c06a556524f27f0344f5c2,11150075bac763f33cf821ae51e1c96f79645212..87d22bff4c7bd56e023b5a86e2c0ed4cf7a0c5f0
@@@ -73,6 -73,9 +73,9 @@@
  #ifndef M_SQRT1_2
  #define M_SQRT1_2     0.70710678118654752440
  #endif
+ #ifndef M_1_PI
+ #define M_1_PI                0.318309886183790671538
+ #endif
  
  #define MAXPATHLEN MAX_PATH
  
@@@ -110,7 -113,8 +113,7 @@@ void RegisterBlendExtension(char * str)
  DIR *opendir (const char *path);
  struct dirent *readdir(DIR *dp);
  int closedir (DIR *dp);
 -void get_default_root(char *root);
 -int check_file_chars(char *filename);
 +void get_default_root(char* root);
  
  #endif /* __WINSTUFF_H__ */
  
index 19a8d4f51527e9b533f05c5b6a4ffd08edddc744,c97ca3c6a8abd93c27fa6fab9d58cf60ffa52ac9..54a0e3d678d578c6a0ccd294db830af0d75c6717
@@@ -1335,6 -1335,22 +1335,22 @@@ void NormalQuat(float *q
        }
  }
  
+ void AxisAngleToQuat(float *q, float *axis, float angle)
+ {
+       float nor[3];
+       float si;
+       
+       VecCopyf(nor, axis);
+       Normalize(nor);
+       
+       angle /= 2;
+       si = (float)sin(angle);
+       q[0] = (float)cos(angle);
+       q[1] = nor[0] * si;
+       q[2] = nor[1] * si;
+       q[3] = nor[2] * si;     
+ }
  void vectoquat(float *vec, short axis, short upflag, float *q)
  {
        float q2[4], nor[3], *fp, mat[3][3], angle, si, co, x2, y2, z2, len1;
@@@ -2258,6 -2274,20 +2274,20 @@@ double Sqrt3d(double d
        else return exp(log(d)/3);
  }
  
+ void NormalShortToFloat(float *out, short *in)
+ {
+       out[0] = in[0] / 32767.0;
+       out[1] = in[1] / 32767.0;
+       out[2] = in[2] / 32767.0;
+ }
+ void NormalFloatToShort(short *out, float *in)
+ {
+       out[0] = (short)(in[0] * 32767.0);
+       out[1] = (short)(in[1] * 32767.0);
+       out[2] = (short)(in[2] * 32767.0);
+ }
  /* distance v1 to line v2-v3 */
  /* using Hesse formula, NO LINE PIECE! */
  float DistVL2Dfl( float *v1, float *v2, float *v3)  {
@@@ -3384,6 -3414,66 +3414,66 @@@ void rgb_to_hsv(float r, float g, floa
        *lv = v;
  }
  
+ /*http://brucelindbloom.com/index.html?Eqn_RGB_XYZ_Matrix.html
+  * SMPTE-C XYZ to RGB matrix*/
+ void xyz_to_rgb(float xc, float yc, float zc, float *r, float *g, float *b)
+ {
+       *r = (3.50570   * xc) + (-1.73964       * yc) + (-0.544011      * zc);
+       *g = (-1.06906  * xc) + (1.97781        * yc) + (0.0351720      * zc);
+       *b = (0.0563117 * xc) + (-0.196994      * yc) + (1.05005        * zc);
+ }
+ /*If the requested RGB shade contains a negative weight for
+   one of the primaries, it lies outside the colour gamut 
+   accessible from the given triple of primaries.  Desaturate
+   it by adding white, equal quantities of R, G, and B, enough
+   to make RGB all positive.  The function returns 1 if the
+   components were modified, zero otherwise.*/
+ int constrain_rgb(float *r, float *g, float *b)
+ {
+       float w;
+     /* Amount of white needed is w = - min(0, *r, *g, *b) */
+     
+     w = (0 < *r) ? 0 : *r;
+     w = (w < *g) ? w : *g;
+     w = (w < *b) ? w : *b;
+     w = -w;
+     /* Add just enough white to make r, g, b all positive. */
+     
+     if (w > 0) {
+         *r += w;  *g += w; *b += w;
+         return 1;                     /* Colour modified to fit RGB gamut */
+     }
+     return 0;                         /* Colour within RGB gamut */
+ }
+ /*Transform linear RGB values to nonlinear RGB values. Rec.
+   709 is ITU-R Recommendation BT. 709 (1990) ``Basic
+   Parameter Values for the HDTV Standard for the Studio and
+   for International Programme Exchange'', formerly CCIR Rec.
+   709.*/
+ void gamma_correct(float *c)
+ {
+       /* Rec. 709 gamma correction. */
+       float cc = 0.018;
+       
+       if (*c < cc) {
+           *c *= ((1.099 * pow(cc, 0.45)) - 0.099) / cc;
+       } else {
+           *c = (1.099 * pow(*c, 0.45)) - 0.099;
+       }
+ }
+ void gamma_correct_rgb(float *r, float *g, float *b)
+ {
+     gamma_correct(r);
+     gamma_correct(g);
+     gamma_correct(b);
+ }
  
  /* we define a 'cpack' here as a (3 byte color code) number that can be expressed like 0xFFAA66 or so.
     for that reason it is sensitive for endianness... with this function it works correctly
@@@ -3671,6 -3761,43 +3761,43 @@@ int LineIntersectsTriangle(float p1[3]
        return 1;
  }
  
+ /* moved from effect.c
+    test if the ray starting at p1 going in d direction intersects the triangle v0..v2
+    return non zero if it does 
+ */
+ int RayIntersectsTriangle(float p1[3], float d[3], float v0[3], float v1[3], float v2[3], float *lambda, float *uv)
+ {
+       float p[3], s[3], e1[3], e2[3], q[3];
+       float a, f, u, v;
+       
+       VecSubf(e1, v1, v0);
+       VecSubf(e2, v2, v0);
+       
+       Crossf(p, d, e2);
+       a = Inpf(e1, p);
+       if ((a > -0.000001) && (a < 0.000001)) return 0;
+       f = 1.0f/a;
+       
+       VecSubf(s, p1, v0);
+       
+       Crossf(q, s, e1);
+       *lambda = f * Inpf(e2, q);
+       if ((*lambda < 0.0)) return 0;
+       
+       u = f * Inpf(s, p);
+       if ((u < 0.0)||(u > 1.0)) return 0;
+       
+       v = f * Inpf(d, q);
+       if ((v < 0.0)||((u + v) > 1.0)) return 0;
+       if(uv) {
+               uv[0]= u;
+               uv[1]= v;
+       }
+       
+       return 1;
+ }
  /* Adapted from the paper by Kasper Fauerby */
  /* "Improved Collision detection and Response" */
  int SweepingSphereIntersectsTriangleUV(float p1[3], float p2[3], float radius, float v0[3], float v1[3], float v2[3], float *lambda, float *ipoint)
@@@ -3965,6 -4092,74 +4092,74 @@@ int AxialLineIntersectsTriangle(int axi
        return 1;
  }
  
+ /* Returns the number of point of interests
+  * 0 - lines are colinear
+  * 1 - lines are coplanar, i1 is set to intersection
+  * 2 - i1 and i2 are the nearest points on line 1 (v1, v2) and line 2 (v3, v4) respectively 
+  * */
+ int LineIntersectLine(float v1[3], float v2[3], float v3[3], float v4[3], float i1[3], float i2[3])
+ {
+       float a[3], b[3], c[3], ab[3], cb[3], dir1[3], dir2[3];
+       float d;
+       
+       VecSubf(c, v3, v1);
+       VecSubf(a, v2, v1);
+       VecSubf(b, v4, v3);
+       VecCopyf(dir1, a);
+       Normalize(dir1);
+       VecCopyf(dir2, b);
+       Normalize(dir2);
+       d = Inpf(dir1, dir2);
+       if (d == 1.0f || d == -1.0f) {
+               /* colinear */
+               return 0;
+       }
+       Crossf(ab, a, b);
+       d = Inpf(c, ab);
+       /* test if the two lines are coplanar */
+       if (d > -0.000001f && d < 0.000001f) {
+               Crossf(cb, c, b);
+               VecMulf(a, Inpf(cb, ab) / Inpf(ab, ab));
+               VecAddf(i1, v1, a);
+               VecCopyf(i2, i1);
+               
+               return 1; /* one intersection only */
+       }
+       /* if not */
+       else {
+               float n[3], t[3];
+               float v3t[3], v4t[3];
+               VecSubf(t, v1, v3);
+               /* offset between both plane where the lines lies */
+               Crossf(n, a, b);
+               Projf(t, t, n);
+               /* for the first line, offset the second line until it is coplanar */
+               VecAddf(v3t, v3, t);
+               VecAddf(v4t, v4, t);
+               
+               VecSubf(c, v3t, v1);
+               VecSubf(a, v2, v1);
+               VecSubf(b, v4t, v3);
+               Crossf(ab, a, b);
+               Crossf(cb, c, b);
+               VecMulf(a, Inpf(cb, ab) / Inpf(ab, ab));
+               VecAddf(i1, v1, a);
+               /* for the second line, just substract the offset from the first intersection point */
+               VecSubf(i2, i1, t);
+               
+               return 2; /* two nearest points */
+       }
+ } 
  int AabbIntersectAabb(float min1[3], float max1[3], float min2[3], float max2[3])
  {
        return (min1[0]<max2[0] && min1[1]<max2[1] && min1[2]<max2[2] &&
@@@ -4345,3 -4540,8 +4540,3 @@@ void tangent_from_uv(float *uv1, float 
        if ((ct[0]*n[0] + ct[1]*n[1] + ct[2]*n[2]) < 0.0f)
                VecMulf(tang, -1.0f);
  }
 -
 -/* used for zoom values*/
 -float power_of_2(float val) {
 -      return pow(2, ceil(log(val) / log(2)));
 -}
index 5fb18f2840c3f62e3295b82459f7a14342acafd3,3c629818b2dd0204fe899b1804aeeebd584ae36d..378af5f7a92a1e0c6676d3b99701780534ec0878
@@@ -720,7 -720,7 +720,7 @@@ BHead *blo_firstbhead(FileData *fd
  
  BHead *blo_prevbhead(FileData *fd, BHead *thisblock)
  {
 -      BHeadN *bheadn= (BHeadN *) (((char *) thisblock) - GET_INT_FROM_POINTER( &((BHeadN*)0)->bhead) );
 +      BHeadN *bheadn= (BHeadN *) (((char *) thisblock) - (int) (&((BHeadN*)0)->bhead));
        BHeadN *prev= bheadn->prev;
  
        return prev?&prev->bhead:NULL;
@@@ -734,7 -734,7 +734,7 @@@ BHead *blo_nextbhead(FileData *fd, BHea
        if (thisblock) {
                // bhead is actually a sub part of BHeadN
                // We calculate the BHeadN pointer from the BHead pointer below
 -              new_bhead = (BHeadN *) (((char *) thisblock) - GET_INT_FROM_POINTER( &((BHeadN*)0)->bhead) );
 +              new_bhead = (BHeadN *) (((char *) thisblock) - (int) (&((BHeadN*)0)->bhead));
  
                // get the next BHeadN. If it doesn't exist we read in the next one
                new_bhead = new_bhead->next;
@@@ -2991,6 -2991,10 +2991,10 @@@ static void lib_link_object(FileData *f
                                        bActionActuator *aa= act->data;
                                        aa->act= newlibadr(fd, ob->id.lib, aa->act);
                                }
+                               else if(act->type==ACT_SHAPEACTION) {
+                                       bActionActuator *aa= act->data;
+                                       aa->act= newlibadr(fd, ob->id.lib, aa->act);
+                               }
                                else if(act->type==ACT_PROPERTY) {
                                        bPropertyActuator *pa= act->data;
                                        pa->ob= newlibadr(fd, ob->id.lib, pa->ob);
                                        bParentActuator *parenta = act->data; 
                                        parenta->ob = newlibadr(fd, ob->id.lib, parenta->ob);
                                }
+                               else if(act->type==ACT_STATE) {
+                                       /* bStateActuator *statea = act->data; */
+                               }
                                act= act->next;
                        }
  
@@@ -3303,11 -3310,19 +3310,19 @@@ static void direct_link_object(FileDat
        direct_link_constraints(fd, &ob->constraints);
  
        link_glob_list(fd, &ob->controllers);
+       if (ob->init_state) {
+               /* if a known first state is specified, set it so that the game will start ok */
+               ob->state = ob->init_state;
+       } else if (!ob->state) {
+               ob->state = 1;
+       }
        cont= ob->controllers.first;
        while(cont) {
                cont->data= newdataadr(fd, cont->data);
                cont->links= newdataadr(fd, cont->links);
                test_pointer_array(fd, (void **)&cont->links);
+               if (cont->state_mask == 0)
+                       cont->state_mask = 1;
                cont= cont->next;
        }
  
@@@ -7631,6 -7646,24 +7646,24 @@@ static void do_versions(FileData *fd, L
                }
        }
  
+       /* sun/sky */
+       if ((main->versionfile < 246) ){
+               Lamp *la;
+               for(la=main->lamp.first; la; la= la->id.next) {
+                       la->sun_effect_type = 0;
+                       la->horizon_brightness = 1.0;
+                       la->spread = 1.0;
+                       la->sun_brightness = 1.0;
+                       la->sun_size = 1.0;
+                       la->backscattered_light = 1.0;
+                       la->atm_turbidity = 2.0;
+                       la->atm_inscattering_factor = 1.0;
+                       la->atm_extinction_factor = 1.0;
+                       la->atm_distance_factor = 1.0;
+                       la->sun_intensity = 1.0;
+               }
+       }
        /* WATCH IT!!!: pointers from libdata have not been converted yet here! */
        /* WATCH IT 2!: Userdef struct init has to be in src/usiblender.c! */
  
@@@ -8399,6 -8432,10 +8432,10 @@@ static void expand_object(FileData *fd
                        bActionActuator *aa= act->data;
                        expand_doit(fd, mainvar, aa->act);
                }
+               else if(act->type==ACT_SHAPEACTION) {
+                       bActionActuator *aa= act->data;
+                       expand_doit(fd, mainvar, aa->act);
+               }
                else if(act->type==ACT_PROPERTY) {
                        bPropertyActuator *pa= act->data;
                        expand_doit(fd, mainvar, pa->ob);
index 0b224a24d4d32e9ae5f88076f31df22edac3f6e5,75affbfa7f5133e7854fe540c031cc5e68838ce2..4818e6936579667730f4536709d6ee631db9b595
@@@ -134,7 -134,6 +134,7 @@@ typedef struct SceneRenderLayer 
  #define SCE_LAY_EDGE  8
  #define SCE_LAY_SKY           16
  #define SCE_LAY_STRAND        32
 +#define SCE_LAY_FRS           64
        /* flags between 32 and 0x8000 are set to 1 already, for future options */
  
  #define SCE_LAY_ALL_Z         0x8000
@@@ -544,8 -543,8 +544,8 @@@ typedef struct Scene 
        ListBase markers;
        ListBase transform_spaces;
        
-       short jumpframe, pad1;
-       short snap_flag, snap_target;
+       short jumpframe;
+       short snap_mode, snap_flag, snap_target;
        
        /* none of the dependancy graph  vars is mean to be saved */
        struct  DagForest *theDag;
  #define R_ORTHO                       0x0008
  #define R_ENVMAP              0x0010
  #define R_EDGE                        0x0020
 +#define R_EDGE_FRS            0x2000000 // will replace R_EDGE
  #define R_FIELDS              0x0040
  #define R_FIELDSTILL  0x0080
  #define R_RADIO                       0x0100
  /* yafray: renderer flag (not only exclusive to yafray) */
  #define R_INTERN      0
  #define R_YAFRAY      1
 +#define R_FREESTYLE   2
  
  /* scemode (int now) */
  #define R_DOSEQ                               0x0001
  
  /* scene->snap_flag */
  #define SCE_SNAP                              1
+ #define SCE_SNAP_ROTATE                       2
  /* scene->snap_target */
  #define SCE_SNAP_TARGET_CLOSEST       0
  #define SCE_SNAP_TARGET_CENTER        1
  #define SCE_SNAP_TARGET_MEDIAN        2
  #define SCE_SNAP_TARGET_ACTIVE        3
+ /* scene->snap_mode */
+ #define SCE_SNAP_MODE_VERTEX  0
+ #define SCE_SNAP_MODE_EDGE            1
+ #define SCE_SNAP_MODE_FACE            2
  
  /* sce->selectmode */
  #define SCE_SELECT_VERTEX     1 /* for mesh */
index 84ed6f9bf980d3ed1e79176a92e06f321c3c42f1,226657655fabb06ab053fe3044518b9193c35e3b..88fc5265a50d18c6ae423fe83ac601c18bf62c5e
@@@ -229,13 -229,6 +229,6 @@@ void BPY_start_python( int argc, char *
        /* Initialize thread support (also acquires lock) */
        PyEval_InitThreads();
  
-       /* Don't allow the Python Interpreter to release the GIL on
-        * its own, to guarantee PyNodes work properly. For Blender this
-        * is currently the best default behavior.
-        * The following code in C is equivalent in Python to:
-        * "import sys; sys.setcheckinterval(sys.maxint)" */
-       _Py_CheckInterval = PyInt_GetMax();
        //Overrides __import__
        init_ourImport(  );
        init_ourReload(  );
@@@ -435,19 -428,24 +428,19 @@@ void BPY_rebuild_syspath( void 
        if(U.pythondir[0] != '\0' ) {
                char modpath[FILE_MAX];
                int upyslen = strlen(U.pythondir);
 -              BLI_strncpy(dirpath, U.pythondir, FILE_MAX);
 -              
 +
                /* check if user pydir ends with a slash and, if so, remove the slash
                 * (for eventual implementations of c library's stat function that might
                 * not like it) */
 -#ifdef WIN32
 -              if (upyslen > 3) {
 -#else
 -              if (upyslen > 1) {
 -#endif
 -                      if (dirpath[upyslen-1] == '\\' || dirpath[upyslen-1] == '/') {
 -                              dirpath[upyslen-1] = '\0';
 -                      }
 +              if (upyslen > 2) { /* avoids doing anything if dir == '//' */
 +                      BLI_add_slash(U.pythondir);
                }
  
 +              BLI_strncpy(dirpath, U.pythondir, FILE_MAX);
                BLI_convertstringcode(dirpath, G.sce);
                syspath_append(dirpath);        /* append to module search path */
 -              BLI_join_dirfile( modpath, dirpath, "bpymodules" );
 +
 +              BLI_make_file_string("/", modpath, dirpath, "bpymodules");
                if (BLI_exists(modpath)) syspath_append(modpath);
        }
        
        PyGILState_Release(gilstate);
  }
  
 -int BPY_path_update( void )
 -{
 -      BPyMenu_RemoveAllEntries(); /* free old data */
 -      BPY_rebuild_syspath();
 -      if (BPyMenu_Init(1) == -1) { /* re-eval scripts registration in menus */
 -              return 0;
 -      }
 -      return 1;
 -}
 -
  /****************************************************************************
  * Description: This function finishes Python initialization in Blender.        
  
@@@ -629,11 -637,13 +622,11 @@@ int BPY_txt_do_python_Text( struct Tex
                if( !strcmp( script->id.name + 2, text->id.name + 2 ) ) {
                        /* if this text is already a running script, 
                         * just move to it: */
 -                      if (!G.background) {
 -                              SpaceScript *sc;
 -                              newspace( curarea, SPACE_SCRIPT );
 -                              sc = curarea->spacedata.first;
 -                              sc->script = script;
 -                              return 1;
 -                      }
 +                      SpaceScript *sc;
 +                      newspace( curarea, SPACE_SCRIPT );
 +                      sc = curarea->spacedata.first;
 +                      sc->script = script;
 +                      return 1;
                }
                script = script->id.next;
        }
@@@ -771,7 -781,6 +764,7 @@@ int BPY_run_script(Script *script
        Text *text = NULL;
        BPy_constant *info;
        int len;
 +      char *buffer=NULL, *s;
        
        FILE *fp = NULL;
        
                printf("Oops - weakref dict\n");
                free_libblock( &G.main->script, script );
                ReleaseGlobalDictionary( py_dict );
 +              MEM_freeN( buffer );
                PyGILState_Release(gilstate);
                return 0;
        }
                * 'FILE structs for different C libraries can be different and 
                * incompatible'.
                * So now we load the script file data to a buffer */
 -              char *buffer=NULL, *buffer_ofs=NULL, *b_to, *b_from;
 -              
 +      
                fseek( fp, 0L, SEEK_END );
                len = ftell( fp );
                fseek( fp, 0L, SEEK_SET );
        
 -              buffer = buffer_ofs = MEM_mallocN( len + 2, "pyfilebuf" );      /* len+2 to add '\n\0' */
 +              buffer = MEM_mallocN( len + 2, "pyfilebuf" );   /* len+2 to add '\n\0' */
                len = fread( buffer, 1, len, fp );
        
                buffer[len] = '\n';     /* fix syntax error in files w/o eol */
                buffer[len + 1] = '\0';
 -              
 -              
 -              /* fast clean-up of dos cr/lf line endings, remove convert '\r\n's to '\n' */
 -              if (*buffer_ofs == '\r' && *(buffer_ofs+1) == '\n') {
 -                      buffer_ofs++;
 -              }
 -              b_from = b_to = buffer_ofs;
 -              
 -              while(*b_from != '\0') {
 -                      if (*b_from == '\r' && *( b_from+1 ) == '\n') {
 -                              b_from++;
 -                      }
 -                      if (b_from != b_to) {
 -                              *b_to = *b_from;
 +      
 +              /* fast clean-up of dos cr/lf line endings: change '\r' to space */
 +      
 +              /* we also have to check for line splitters: '\\' */
 +              /* to avoid possible syntax errors on dos files on win */
 +              /**/
 +                      /* but first make sure we won't disturb memory below &buffer[0]: */
 +                      if( *buffer == '\r' )
 +                      *buffer = ' ';
 +      
 +              /* now handle the whole buffer */
 +              for( s = buffer + 1; *s != '\0'; s++ ) {
 +                      if( *s == '\r' ) {
 +                              if( *( s - 1 ) == '\\' ) {      /* special case: long lines split with '\': */
 +                                      *( s - 1 ) = ' ';       /* we write ' \', because '\ ' is a syntax error */
 +                                      *s = '\\';
 +                              } else
 +                                      *s = ' ';       /* not a split line, just replace '\r' with ' ' */
                        }
 -                      b_to++;
 -                      b_from++;
                }
 -              *b_to = '\0';
 -              /* done cleaning the string */
 -              
 +      
                fclose( fp );
                
 -              py_res = PyRun_String( buffer_ofs, Py_file_input, py_dict, py_dict );
 +              
 +              py_res = PyRun_String( buffer, Py_file_input, py_dict, py_dict );
                MEM_freeN( buffer );
        }
  
  
                        /* special case: called from the menu in the Scripts window
                         * we have to change sc->script pointer, since it'll be freed here.*/
 -                      if (!G.background) {
 -                              if( curarea->spacetype == SPACE_SCRIPT ) {
 -                                      SpaceScript *sc = curarea->spacedata.first;
 -                                      sc->script = G.main->script.first;      /* can be null, which is ok ... */
 -                                      /* ... meaning no other script is running right now. */
 -                              }
 +                      if( curarea->spacetype == SPACE_SCRIPT ) {
 +                              SpaceScript *sc = curarea->spacedata.first;
 +                              sc->script = G.main->script.first;      /* can be null, which is ok ... */
 +                              /* ... meaning no other script is running right now. */
                        }
  
                }
@@@ -1137,13 -1147,17 +1130,17 @@@ static void unlink_script( Script * scr
                                if( sl->spacetype == SPACE_SCRIPT ) {
                                        SpaceScript *sc = ( SpaceScript * ) sl;
  
-                                       if( sc->script == script ) {
+                                       if( sc->script == script ) {                                    
                                                sc->script = NULL;
  
-                                               if( sc ==
-                                                   area->spacedata.first ) {
-                                                       scrarea_queue_redraw
-                                                               ( area );
+                                               if( sc == area->spacedata.first ) {
+                                                       scrarea_queue_redraw( area );
+                                               }
+                                               
+                                               if (sc->but_refs) {
+                                                       BPy_Set_DrawButtonsList(sc->but_refs);
+                                                       BPy_Free_DrawButtonsList();
+                                                       sc->but_refs = NULL;
                                                }
                                        }
                                }
@@@ -2167,6 -2181,18 +2164,18 @@@ void BPY_do_all_scripts( short event 
  
        BPY_do_pyscript( &( G.scene->id ), event );
  
+       /* Don't allow the Python Interpreter to release the GIL on
+        * its own, to guarantee PyNodes work properly. For Blender this
+        * is currently the best default behavior.
+        * The following code in C is equivalent in Python to:
+        * "import sys; sys.setcheckinterval(sys.maxint)" */
+       if (event == SCRIPT_RENDER) {
+               _Py_CheckInterval = PyInt_GetMax();
+       }
+       else if (event == SCRIPT_POSTRENDER) {
+               _Py_CheckInterval = 100; /* Python default */
+       }
        return;
  }
  
@@@ -2249,9 -2275,9 +2258,9 @@@ void BPY_do_pyscript( ID * id, short ev
                        return;
                }
                
-               /* tell we're running a scriptlink.  The sum also tells if this script
-                * is running nested inside another.  Blender.Load needs this info to
-                * avoid trouble with invalid slink pointers. */
+               /* tell we're running a scriptlink.  The sum also tells if this
+                * script is running nested inside another.  Blender.Load needs
+                * this info to avoid trouble with invalid slink pointers. */
                during_slink++;
                disable_where_scriptlink( (short)during_slink );
  
index d91736e9a10feeafc68bbf308a85c26efb2c07ca,6a0af82b4d7373e0096786f9f3a5353314d52c90..93d2c12cbbe178fbf49814609c9b5fbdbecb292e
@@@ -70,9 -70,6 +70,9 @@@
  
  #endif /* disable yafray */
  
 +#include "FRS_freestyle.h"
 +
 +
  /* internal */
  #include "render_types.h"
  #include "renderpipeline.h"
@@@ -1621,7 -1618,7 +1621,7 @@@ void RE_TileProcessor(Render *re, int f
  
  static void do_render_3d(Render *re)
  {
 -      
 +      RenderLayer *rl;
  //    re->cfra= cfra; /* <- unused! */
        
        /* make render verts/faces/halos/lamps */
        
        threaded_tile_processor(re);
        
 +      /* Freestyle */
 +      if( re->r.mode & R_EDGE_FRS ) {
 +              FRS_prepare(re);
 +              FRS_execute(re,1);
 +      }
 +      
        /* do left-over 3d post effects (flares) */
        if(re->flag & R_HALO)
                if(!re->test_break())
@@@ -2198,34 -2189,6 +2198,34 @@@ static void do_render_composite_fields_
        re->display_draw(re->result, NULL);
  }
  
 +static void freestyleRender(Render *re)
 +{
 +      float mat[4][4];
 +      
 +      // init render result
 +      RE_FreeRenderResult(re->result);
 +      re->result = new_render_result(re, &re->disprect, 0, RR_USEMEM);
 +      
 +      // set camera
 +      RE_SetCamera(re, re->scene->camera);
 +      
 +      // set view
 +      Mat4Ortho(re->scene->camera->obmat);
 +      Mat4Invert(mat, re->scene->camera->obmat);
 +      RE_SetView(re, mat);
 +      
 +      // Freestyle initialization
 +      FRS_prepare(re);
 +      
 +      // run Freestyle
 +      re->i.starttime = PIL_check_seconds_timer();
 +      FRS_execute(re, 0);
 +      re->i.lastframetime = PIL_check_seconds_timer()- re->i.starttime;
 +      re->stats_draw(&re->i);
 +      
 +      RE_Database_Free(re);
 +}
 +
  #ifndef DISABLE_YAFRAY
  /* yafray: main yafray render/export call */
  static void yafrayRender(Render *re)
@@@ -2320,15 -2283,10 +2320,15 @@@ static void do_render_all_options(Rende
  #ifndef DISABLE_YAFRAY
                if(re->r.renderer==R_YAFRAY)
                        yafrayRender(re);
 +              else if(re->r.renderer==R_FREESTYLE)
 +                      freestyleRender(re);
                else
                        do_render_composite_fields_blur_3d(re);
  #else
 -              do_render_composite_fields_blur_3d(re);
 +              if(re->r.renderer==R_FREESTYLE)
 +                      freestyleRender(re);
 +              else
 +                      do_render_composite_fields_blur_3d(re);
  #endif
        }
        
@@@ -2441,7 -2399,7 +2441,7 @@@ static int is_rendering_allowed(Render 
        }
        
        /* renderer */
 -      if(!ELEM(re->r.renderer, R_INTERN, R_YAFRAY)) {
 +      if(!ELEM3(re->r.renderer, R_INTERN, R_YAFRAY, R_FREESTYLE)) {
                re->error("Unknown render engine set");
                return 0;
        }
@@@ -2717,9 -2675,9 +2717,9 @@@ void RE_set_max_threads(int threads
  
  void RE_init_threadcount(Render *re) 
  {
-       if ((re->r.mode & R_FIXED_THREADS)==0 || commandline_threads == 0) { /* Automatic threads */
+         if(commandline_threads >= 1) { /* only set as an arg in background mode */
+               re->r.threads= MIN2(commandline_threads, BLENDER_MAX_THREADS);
+       } else if ((re->r.mode & R_FIXED_THREADS)==0 || commandline_threads == 0) { /* Automatic threads */
                re->r.threads = BLI_system_thread_count();
-       } else if(commandline_threads >= 1 && commandline_threads<=BLENDER_MAX_THREADS) {
-               re->r.threads= commandline_threads;
        }
  }
index 337adf7275a8ad8c28b1c819a08ccc3fd5b82d43,67be0ce4c005f62ff24583887429bd85cf1c3fb8..95d934acfbeda1bfbfd3bbc618dde859c02a27ef
@@@ -47,6 -47,7 +47,7 @@@
  #include "DNA_lamp_types.h"
  #include "DNA_material_types.h"
  #include "DNA_meshdata_types.h"
+ #include "DNA_group_types.h"
  
  #include "BKE_global.h"
  #include "BKE_image.h"
@@@ -319,22 -320,27 +320,22 @@@ static void halo_tile(RenderPart *pa, R
  
  static void lamphalo_tile(RenderPart *pa, RenderLayer *rl)
  {
 -      RenderLayer *rlpp[RE_MAX_OSA];
        ShadeInput shi;
 -      float *pass;
 -      float fac, col[4];
 +      float *pass= rl->rectf;
 +      float fac;
        long *rd= pa->rectdaps;
 -      int *rz= pa->rectz;
 -      int x, y, sample, totsample, fullsample, od;
 +      int x, y, *rz= pa->rectz;
        
 -      totsample= get_sample_layers(pa, rl, rlpp);
 -      fullsample= (totsample > 1);
 -
        shade_input_initialize(&shi, pa, rl, 0); /* this zero's ShadeInput for us */
        
 -      for(od=0, y=pa->disprect.ymin; y<pa->disprect.ymax; y++) {
 -              for(x=pa->disprect.xmin; x<pa->disprect.xmax; x++, rz++, od++) {
 +      for(y=pa->disprect.ymin; y<pa->disprect.ymax; y++) {
 +              for(x=pa->disprect.xmin; x<pa->disprect.xmax; x++, rz++, pass+=4) {
                        
                        calc_view_vector(shi.view, x, y);
                        
                        if(rd && *rd) {
                                PixStr *ps= (PixStr *)*rd;
 -                              int count, totsamp= 0, mask= 0;
 +                              int samp, totsamp= 0;
                                
                                while(ps) {
                                        if(R.r.mode & R_ORTHO)
                                        else
                                                calc_renderco_zbuf(shi.co, shi.view, ps->z);
                                        
 -                                      totsamp+= count= count_mask(ps->mask);
 -                                      mask |= ps->mask;
 -
 -                                      col[0]= col[1]= col[2]= col[3]= 0.0f;
 -                                      renderspothalo(&shi, col, 1.0f);
 -
 -                                      if(fullsample) {
 -                                              for(sample=0; sample<totsample; sample++) {
 -                                                      if(ps->mask & (1 << sample)) {
 -                                                              pass= rlpp[sample]->rectf + od*4;
 -                                                              pass[0]+= col[0];
 -                                                              pass[1]+= col[1];
 -                                                              pass[2]+= col[2];
 -                                                              pass[3]+= col[3];
 -                                                              if(pass[3]>1.0f) pass[3]= 1.0f;
 -                                                      }
 -                                              }
 -                                      }
 -                                      else {
 -                                              fac= ((float)count)/(float)R.osa;
 -                                              pass= rl->rectf + od*4;
 -                                              pass[0]+= fac*col[0];
 -                                              pass[1]+= fac*col[1];
 -                                              pass[2]+= fac*col[2];
 -                                              pass[3]+= fac*col[3];
 -                                              if(pass[3]>1.0f) pass[3]= 1.0f;
 -                                      }
 -
 +                                      totsamp+= samp= count_mask(ps->mask);
 +                                      fac= ((float)samp)/(float)R.osa;
 +                                      renderspothalo(&shi, pass, fac);
                                        ps= ps->next;
                                }
 -
                                if(totsamp<R.osa) {
 +                                      fac= ((float)R.osa-totsamp)/(float)R.osa;
                                        shi.co[2]= 0.0f;
 -
 -                                      col[0]= col[1]= col[2]= col[3]= 0.0f;
 -                                      renderspothalo(&shi, col, 1.0f);
 -
 -                                      if(fullsample) {
 -                                              for(sample=0; sample<totsample; sample++) {
 -                                                      if(!(mask & (1 << sample))) {
 -                                                              pass= rlpp[sample]->rectf + od*4;
 -                                                              pass[0]+= col[0];
 -                                                              pass[1]+= col[1];
 -                                                              pass[2]+= col[2];
 -                                                              pass[3]+= col[3];
 -                                                              if(pass[3]>1.0f) pass[3]= 1.0f;
 -                                                      }
 -                                              }
 -                                      }
 -                                      else {
 -                                              fac= ((float)R.osa-totsamp)/(float)R.osa;
 -                                              pass= rl->rectf + od*4;
 -                                              pass[0]+= fac*col[0];
 -                                              pass[1]+= fac*col[1];
 -                                              pass[2]+= fac*col[2];
 -                                              pass[3]+= fac*col[3];
 -                                              if(pass[3]>1.0f) pass[3]= 1.0f;
 -                                      }
 +                                      renderspothalo(&shi, pass, fac);
                                }
                        }
                        else {
                                else
                                        calc_renderco_zbuf(shi.co, shi.view, *rz);
                                
 -                              col[0]= col[1]= col[2]= col[3]= 0.0f;
 -                              renderspothalo(&shi, col, 1.0f);
 -
 -                              for(sample=0; sample<totsample; sample++) {
 -                                      pass= rlpp[sample]->rectf + od*4;
 -                                      pass[0]+= col[0];
 -                                      pass[1]+= col[1];
 -                                      pass[2]+= col[2];
 -                                      pass[3]+= col[3];
 -                                      if(pass[3]>1.0f) pass[3]= 1.0f;
 -                              }
 +                              renderspothalo(&shi, pass, 1.0f);
                        }
                        
                        if(rd) rd++;
@@@ -601,6 -666,88 +602,88 @@@ static void sky_tile(RenderPart *pa, Re
        }
  }
  
+ static void atm_tile(RenderPart *pa, RenderLayer *rl)
+ {
+       RenderPass *zpass;
+       GroupObject *go;
+       LampRen *lar;
+       
+       int x, y;
+       short first_lamp;
+       float *zrect;
+       float *rgbrect;
+       float rgb[3]={0};
+       float tmp_rgb[3];
+       float fac;
+       float facm;
+       
+       fac = 0.5;
+       facm = 1.0 - fac;
+       
+       /* check that z pass is enabled */
+       if(pa->rectz==NULL) return;
+       for(zpass= rl->passes.first; zpass; zpass= zpass->next)
+               if(zpass->passtype==SCE_PASS_Z)
+                       break;
+       
+       if(zpass==NULL) return;
+       /* check for at least one sun lamp that its atmosphere flag is is enabled */
+       first_lamp = 1;
+       for(go=R.lights.first; go; go= go->next) {
+               lar= go->lampren;
+               if(lar->type==LA_SUN && lar->sunsky && 
+                               (lar->sunsky->effect_type & LA_SUN_EFFECT_AP)){
+                       first_lamp = 0;
+                       break;
+               }
+       }
+       /* do nothign and return if there is no sun lamp */
+       if(first_lamp)
+               return;
+       
+       zrect = zpass->rect;
+       rgbrect = rl->rectf;
+       /* for each x,y and sun lamp*/
+       for(y=pa->disprect.ymin; y<pa->disprect.ymax; y++) {
+               for(x=pa->disprect.xmin; x<pa->disprect.xmax; x++, zrect++, rgbrect+=4) {
+                       
+                       first_lamp = 1;
+                       for(go=R.lights.first; go; go= go->next) {
+                               lar= go->lampren;
+                               if(lar->type==LA_SUN && lar->sunsky)
+                                       
+                               {
+                                       /* if it's sky continue and don't apply atmosphere effect on it */
+                                       if(*zrect >= 9.9e10){
+                                               continue;
+                                       }
+                                       if(lar->sunsky->effect_type & LA_SUN_EFFECT_AP){        
+                                               VECCOPY(tmp_rgb, rgbrect);
+                                               shadeAtmPixel(lar->sunsky, tmp_rgb, x, y, *zrect);
+                                               
+                                               if(first_lamp){
+                                                       VECCOPY(rgb, tmp_rgb);
+                                                       first_lamp = 0;                                         
+                                               }
+                                               else{
+                                                       rgb[0] = facm*rgb[0] + fac*tmp_rgb[0];
+                                                       rgb[1] = facm*rgb[1] + fac*tmp_rgb[1];
+                                                       rgb[2] = facm*rgb[2] + fac*tmp_rgb[2];
+                                               }
+                                       }
+                               }
+                       }
+                       /* if at least for one sun lamp aerial perspective was applied*/
+                       if(first_lamp==0)
+                               VECCOPY(rgbrect, rgb);
+               }
+       }
+ }
  static void shadeDA_tile(RenderPart *pa, RenderLayer *rl)
  {
        RenderResult *rr= pa->result;
@@@ -1058,6 -1205,10 +1141,10 @@@ void zbufshadeDA_tile(RenderPart *pa
                        if(R.r.mode & R_EDGE) 
                                edge_enhance_add(pa, rl->rectf, edgerect);
                
+               /* sun/sky */
+               if(rl->layflag & SCE_LAY_SKY)
+                       atm_tile(pa, rl);
                if(rl->passflag & SCE_PASS_VECTOR)
                        reset_sky_speed(pa, rl);
                
@@@ -1218,6 -1369,10 +1305,10 @@@ void zbufshade_tile(RenderPart *pa
                                        edge_enhance_add(pa, rl->rectf, edgerect);
                }
                
+               /* sun/sky */
+               if(rl->layflag & SCE_LAY_SKY)
+                       atm_tile(pa, rl);
+                       
                if(rl->passflag & SCE_PASS_VECTOR)
                        reset_sky_speed(pa, rl);
                
@@@ -1366,19 -1521,8 +1457,19 @@@ static void shade_sample_sss(ShadeSampl
        /* texture blending */
        texfac= shi->mat->sss_texfac;
  
 -      alpha= shr.combined[3];
 +      alpha= shr.col[3];
        *area *= alpha;
 +
 +      if(texfac == 0.0f) {
 +              if(shr.col[0]!=0.0f) color[0] *= alpha/shr.col[0];
 +              if(shr.col[1]!=0.0f) color[1] *= alpha/shr.col[1];
 +              if(shr.col[2]!=0.0f) color[2] *= alpha/shr.col[2];
 +      }
 +      else if(texfac != 1.0f && (alpha > FLT_EPSILON)) {
 +              if(shr.col[0]!=0.0f) color[0] *= alpha*pow(shr.col[0]/alpha, texfac)/shr.col[0];
 +              if(shr.col[1]!=0.0f) color[1] *= alpha*pow(shr.col[1]/alpha, texfac)/shr.col[1];
 +              if(shr.col[2]!=0.0f) color[2] *= alpha*pow(shr.col[2]/alpha, texfac)/shr.col[2];
 +      }
  }
  
  static void zbufshade_sss_free(RenderPart *pa)
index 91c7b2b44a8c9a2c684134190787d7ff4e5358d9,7eff79fec88da0348d371a04e5bea787ab80792e..a4987c1a08fc839a70447fd6bd0c3deefcd77fe6
@@@ -1651,6 -1651,12 +1651,6 @@@ void modifiers_explodeFacepa(void *arg1
        emd->flag |= eExplodeFlag_CalcFaces;
  }
  
 -void modifiers_explodeDelVg(void *arg1, void *arg2)
 -{
 -      ExplodeModifierData *emd=arg1;
 -      emd->vgroup = 0;
 -}
 -
  static int modifier_is_fluid_particles(ModifierData *md) {
        if(md->type == eModifierType_ParticleSystem) {
                if(((ParticleSystemModifierData *)md)->psys->part->type == PART_FLUID)
@@@ -1761,7 -1767,7 +1761,7 @@@ static void draw_modifier(uiBlock *bloc
                } else if (md->type==eModifierType_Build) {
                        height = 86;
                } else if (md->type==eModifierType_Mirror) {
-                       height = 86;
+                       height = 105;
                } else if (md->type==eModifierType_Bevel) {
                        BevelModifierData *bmd = (BevelModifierData*) md;
                        height = 105; /* height = 124; */
                        height = 143;
                } else if (md->type==eModifierType_Wave) {
                        WaveModifierData *wmd = (WaveModifierData *)md;
-                       height = 294;
+                       height = 315;
                        if(wmd->texmapping == MOD_WAV_MAP_OBJECT ||
                           wmd->texmapping == MOD_WAV_MAP_UV)
                                height += 19;
                        uiDefButBitS(block, TOG, MOD_MIR_AXIS_Y, B_MODIFIER_RECALC, "Y",        lx+20,cy,20,19,    &mmd->flag, 0, 0, 0, 0, "Enable Y axis mirror");
                        uiDefButBitS(block, TOG, MOD_MIR_AXIS_Z, B_MODIFIER_RECALC, "Z",        lx+40,cy,20,19,    &mmd->flag, 0, 0, 0, 0, "Enable Z axis mirror");
                        uiDefButBitS(block, TOG, MOD_MIR_CLIPPING, B_MODIFIER_RECALC, "Do Clipping",    lx+60, cy, buttonWidth-60,19, &mmd->flag, 1, 2, 0, 0, "Prevents during Transform vertices to go through Mirror");
+                       uiDefButBitS(block, TOG, MOD_MIR_VGROUP, B_MODIFIER_RECALC, "Mirror Vgroups",   lx, (cy-=19), buttonWidth,19, &mmd->flag, 1, 2, 0, 0, "Mirror vertex groups (e.g. .R->.L)");
                        uiDefButBitS(block, TOG, MOD_MIR_MIRROR_U, B_MODIFIER_RECALC,
                                     "Mirror U",
                                     lx, (cy-=19), buttonWidth/2, 19,
                                uiDefButF(block, NUM, B_MODIFIER_RECALC, "Time end:",   lx,(cy-=19),buttonWidth,19, &wmd->timeoffs, -MAXFRAMEF, MAXFRAMEF, 100, 0, "Specify ending frame of the wave");
                        uiDefButF(block, NUM, B_MODIFIER_RECALC, "Lifetime:",   lx,(cy-=19),buttonWidth,19, &wmd->lifetime,  -MAXFRAMEF, MAXFRAMEF, 100, 0, "Specify the lifespan of the wave");
                        uiDefButF(block, NUM, B_MODIFIER_RECALC, "Damptime:",   lx,(cy-=19),buttonWidth,19, &wmd->damp,  -MAXFRAMEF, MAXFRAMEF, 100, 0, "Specify the dampingtime of the wave");
+                       uiDefButF(block, NUM, B_MODIFIER_RECALC, "Falloff:",    lx,(cy-=19),buttonWidth,19, &wmd->falloff,  0, 100, 100, 0, "Specify the falloff radius of the waves");
                        cy -= 9;
                        uiBlockBeginAlign(block);
                        uiDefButF(block, NUM, B_MODIFIER_RECALC, "Sta x:",              lx,(cy-=19),113,19, &wmd->startx, -100.0, 100.0, 100, 0, "Starting position for the X axis");
                                               &wmd->map_object,
                                               "Object to get texture coordinates from");
                        }
-             cy -= 9;
+                       cy -= 9;
                        uiBlockBeginAlign(block);
                        uiDefButF(block, NUMSLI, B_MODIFIER_RECALC, "Speed:",   lx,(cy-=19),220,19, &wmd->speed, -2.0, 2.0, 0, 0, "Specify the wave speed");
                        uiDefButF(block, NUMSLI, B_MODIFIER_RECALC, "Height:",  lx,(cy-=19),220,19, &wmd->height, -2.0, 2.0, 0, 0, "Specify the amplitude of the wave");
                                but= uiDefBut(block, BUT, B_MODIFIER_RECALC, "Bind", lx,(cy-=24), buttonWidth,19, 0, 0, 0, 0, 0, "Bind mesh to cage");
                                uiButSetFunc(but,modifiers_bindMeshDeform,ob,md);
                                uiDefButS(block, NUM, B_NOP, "Precision:", lx,(cy-19), buttonWidth/2 + 20,19, &mmd->gridsize, 2, 10, 0.5, 0, "The grid size for binding");
-                               uiDefButBitS(block, TOG, MOD_MDEF_DYNAMIC_BIND, B_MODIFIER_RECALC, "Dynamic", lx+(buttonWidth+1)/2 + 20, (cy-=19), buttonWidth/2 - 20,19, &mmd->flag, 0.0, 31.0, 0, 0, "Invert vertex group influence");
+                               uiDefButBitS(block, TOG, MOD_MDEF_DYNAMIC_BIND, B_MODIFIER_RECALC, "Dynamic", lx+(buttonWidth+1)/2 + 20, (cy-=19), buttonWidth/2 - 20,19, &mmd->flag, 0.0, 31.0, 0, 0, "Recompute binding dynamically on top of other deformers like Shape Keys (slower and more memory consuming!)");
                        }
                        uiBlockEndAlign(block);
                } else if (md->type==eModifierType_ParticleSystem) {
                        char *menustr= get_vertexgroup_menustr(ob);
                        int defCount=BLI_countlist(&ob->defbase);
                        if(defCount==0) emd->vgroup=0;
 -                      uiBlockBeginAlign(block);
 -                      but=uiDefButS(block, MENU, B_MODIFIER_RECALC, menustr,  lx, (cy-=19), buttonWidth-20,19, &emd->vgroup, 0, defCount, 0, 0, "Protect this vertex group");
 +
 +                      but=uiDefButS(block, MENU, B_MODIFIER_RECALC, menustr,  lx, (cy-=19), buttonWidth/2,19, &emd->vgroup, 0, defCount, 0, 0, "Protect this vertex group");
                        uiButSetFunc(but,modifiers_explodeFacepa,emd,0);
                        MEM_freeN(menustr);
 -                      
 -                      but=uiDefIconBut(block, BUT, B_MODIFIER_RECALC, ICON_X, (lx+buttonWidth)-20, cy, 20,19, 0, 0, 0, 0, 0, "Disable use of vertex group");
 -                      uiButSetFunc(but, modifiers_explodeDelVg, (void *)emd, (void *)NULL);
 -                      
  
 -                      but=uiDefButF(block, NUMSLI, B_MODIFIER_RECALC, "",     lx, (cy-=19), buttonWidth,19, &emd->protect, 0.0f, 1.0f, 0, 0, "Clean vertex group edges");
 +                      but=uiDefButF(block, NUMSLI, B_MODIFIER_RECALC, "",     lx+buttonWidth/2, cy, buttonWidth/2,19, &emd->protect, 0.0f, 1.0f, 0, 0, "Clean vertex group edges");
                        uiButSetFunc(but,modifiers_explodeFacepa,emd,0);
  
                        but=uiDefBut(block, BUT, B_MODIFIER_RECALC, "Refresh",  lx, (cy-=19), buttonWidth/2,19, 0, 0, 0, 0, 0, "Recalculate faces assigned to particles");
                        uiDefButBitS(block, TOG, eExplodeFlag_Unborn, B_MODIFIER_RECALC, "Unborn",      lx, (cy-=19), buttonWidth/3,19, &emd->flag, 0, 0, 0, 0, "Show mesh when particles are unborn");
                        uiDefButBitS(block, TOG, eExplodeFlag_Alive, B_MODIFIER_RECALC, "Alive",        lx+buttonWidth/3, cy, buttonWidth/3,19, &emd->flag, 0, 0, 0, 0, "Show mesh when particles are alive");
                        uiDefButBitS(block, TOG, eExplodeFlag_Dead, B_MODIFIER_RECALC, "Dead",  lx+buttonWidth*2/3, cy, buttonWidth/3,19, &emd->flag, 0, 0, 0, 0, "Show mesh when particles are dead");
 -                      uiBlockEndAlign(block);
                }
  
                uiBlockEndAlign(block);
@@@ -3060,7 -3074,6 +3063,7 @@@ static void editing_panel_font_type(Obj
  
  void do_curvebuts(unsigned short event)
  {
 +      extern Nurb *lastnu;
        extern ListBase editNurb;  /* from editcurve */
        Object *ob;
        Curve *cu;
                                if(isNurbsel(nu)) {
                                        if((nu->type & 7)==CU_NURBS) {
                                                if(event<B_UNIFV) {
 -                                                      nu->flagu &= CU_CYCLIC; /* disable all flags except for CU_CYCLIC */
 -                                                      nu->flagu |= ((event-B_UNIFU)<<1);
 -                                                      clamp_nurb_order_u(nu);
 +                                                      nu->flagu &= 1;
 +                                                      nu->flagu += ((event-B_UNIFU)<<1);
                                                        makeknots(nu, 1, nu->flagu>>1);
                                                }
                                                else if(nu->pntsv>1) {
 -                                                      nu->flagv &= CU_CYCLIC; /* disable all flags except for CU_CYCLIC */
 -                                                      nu->flagv |= ((event-B_UNIFV)<<1);
 -                                                      clamp_nurb_order_v(nu);
 +                                                      nu->flagv &= 1;
 +                                                      nu->flagv += ((event-B_UNIFV)<<1);
                                                        makeknots(nu, 2, nu->flagv>>1);
                                                }
                                        }
                break;
        case B_SETORDER:
                if(G.obedit) {
 -                      nu= get_actNurb();
 +                      nu= lastnu;
                        if(nu && (nu->type & 7)==CU_NURBS ) {
 -                              if(clamp_nurb_order_u(nu)) {
 +                              if(nu->orderu>nu->pntsu) {
 +                                      nu->orderu= nu->pntsu;
                                        scrarea_queue_winredraw(curarea);
                                }
                                makeknots(nu, 1, nu->flagu>>1);
 -                              if(clamp_nurb_order_v(nu)) {
 +                              if(nu->orderv>nu->pntsv) {
 +                                      nu->orderv= nu->pntsv;
                                        scrarea_queue_winredraw(curarea);
                                }
                                makeknots(nu, 2, nu->flagv>>1);
@@@ -3262,7 -3275,6 +3265,7 @@@ static void editing_panel_curve_tools(O
  {
        Nurb *nu;
        extern ListBase editNurb;  /* from editcurve */
 +      extern Nurb *lastnu;
        uiBlock *block;
        short *sp;
  
        uiBlockEndAlign(block);
  
        if(ob==G.obedit) {
 -              nu= get_actNurb();
 -              if(nu==NULL && editNurb.first) {
 -                      nu= editNurb.first;
 -                      set_actNurb(nu);
 -              }
 +              nu= lastnu;
 +              if(nu==NULL) nu= lastnu= editNurb.first;
                if(nu) {
                        if (ob->type==OB_CURVE) {
                                uiDefBut(block, LABEL, 0, "Tilt",
@@@ -4357,7 -4372,7 +4360,7 @@@ static void editing_panel_armature_bone
                        
                        /* bone types */
                        uiDefButBitI(block, TOG, BONE_HINGE, B_ARM_RECALCDATA, "Hinge",         -10,by-38,80,18, &curBone->flag, 1.0, 32.0, 0.0, 0.0, "Don't inherit rotation or scale from parent Bone");
 -                      uiDefButBitI(block, TOG, BONE_NO_SCALE, B_ARM_RECALCDATA, "S",          70,by-38,20,18, &curBone->flag, 1.0, 32.0, 0.0, 0.0, "Don't inherit scale from parent Bone");
 +                      uiDefButBitI(block, TOG, BONE_NO_SCALE, B_ARM_RECALCDATA, "S",          70,by-38,20,18, &curBone->flag, 1.0, 32.0, 0.0, 0.0, "Don't inherit rotation or scale from parent Bone");
                        uiDefButBitI(block, TOGN, BONE_NO_DEFORM, B_ARM_RECALCDATA, "Deform",   90, by-38, 80, 18, &curBone->flag, 0.0, 0.0, 0.0, 0.0, "Indicate if Bone deforms geometry");
                        uiDefButBitI(block, TOG, BONE_MULT_VG_ENV, B_ARM_RECALCDATA, "Mult", 170,by-38,80,18, &curBone->flag, 1.0, 32.0, 0.0, 0.0, "Multiply Bone Envelope with VertexGroup");
                        uiDefButBitI(block, TOG, BONE_HIDDEN_A, REDRAWVIEW3D, "Hide",   250,by-38,80,18, &curBone->flag, 0, 0, 0, 0, "Toggles display of this bone in Edit Mode");
@@@ -5070,7 -5085,7 +5073,7 @@@ static void editing_panel_mesh_tools1(O
        
        uiBlockEndAlign(block);
        
 -      uiDefButC(block, MENU, REDRAWBUTSEDIT, "Edge Alt-Select Mode%t|Loop Select%x0|Tag Edges (Seam)%x1|Tag Edges (Sharp)%x2|Tag Edges (Crease)%x3|Tag Edges (Bevel)%x4",1125,88,150,19, &G.scene->toolsettings->edge_mode, 0, 0, 0, 0, "Operation to use when Alt+RMB on edges, Use Alt+Shift+RMB to tag the shortest path from the active edge");
 +      uiDefButC(block, MENU, REDRAWBUTSEDIT, "Edge Alt-Select Mode%t|Loop Select%x0|Tag Edges (Seam)%x1|Tag Edges (Sharp)%x2|Tag Edges (Sharp)%x3|Tag Edges (Bevel)%x4",1125,88,150,19, &G.scene->toolsettings->edge_mode, 0, 0, 0, 0, "Operation to use when Alt+RMB on edges, Use Alt+Shift+RMB to tag the shortest path from the active edge");
        
        uiBlockBeginAlign(block);
        uiDefButBitI(block, TOG, G_ALLEDGES, 0, "All Edges",                    1125, 22,150,19, &G.f, 0, 0, 0, 0, "Displays all edges in object mode without optimization");
@@@ -6204,7 -6219,7 +6207,7 @@@ static void editing_panel_mesh_texface(
                uiDefButBitS(block, TOG, TF_TILES, B_REDR_3D_IMA, "Tiles",      660,160,60,19, &tf->mode, 0, 0, 0, 0, "Use tilemode for face");
                uiDefButBitS(block, TOG, TF_LIGHT, REDRAWVIEW3D, "Light",       720,160,60,19, &tf->mode, 0, 0, 0, 0, "Use light for face");
                uiDefButBitS(block, TOG, TF_INVISIBLE, REDRAWVIEW3D, "Invisible",780,160,60,19, &tf->mode, 0, 0, 0, 0, "Make face invisible");
-               uiDefButBitS(block, TOG, TF_DYNAMIC, REDRAWVIEW3D, "Collision", 840,160,60,19, &tf->mode, 0, 0, 0, 0, "Use face for collision detection");
+               uiDefButBitS(block, TOG, TF_DYNAMIC, REDRAWVIEW3D, "Collision", 840,160,60,19, &tf->mode, 0, 0, 0, 0, "Use face for collision and ray-sensor detection");
  
                uiBlockBeginAlign(block);
                uiDefButBitS(block, TOG, TF_SHAREDCOL, REDRAWVIEW3D, "Shared",  600,135,60,19, &tf->mode, 0, 0, 0, 0, "Blend vertex colors across face when vertices are shared");
                uiDefButC(block, ROW, REDRAWVIEW3D, "Opaque",   600,80,60,19, &tf->transp, 2.0, (float)TF_SOLID,0, 0, "Render color of textured face as color");
                uiDefButC(block, ROW, REDRAWVIEW3D, "Add",              660,80,60,19, &tf->transp, 2.0, (float)TF_ADD,  0, 0, "Render face transparent and add color of face");
                uiDefButC(block, ROW, REDRAWVIEW3D, "Alpha",    720,80,60,19, &tf->transp, 2.0, (float)TF_ALPHA,0, 0, "Render polygon transparent, depending on alpha channel of the texture");
+               uiDefButC(block, ROW, REDRAWVIEW3D, "Clip Alpha",       780,80,80,19, &tf->transp, 2.0, (float)TF_CLIP,0, 0, "Use the images alpha values clipped with no blending (binary alpha)");
        }
        else
                uiDefBut(block,LABEL,B_NOP, "(No Active Face)", 10,200,150,19,0,0,0,0,0,"");
index f564b671fb053aa6d857749eabd689f75e2d15a6,ba409723784c5b44673d3aa3d2ad7f22337eb8ee..ad98c253c94c1c683a8e1b22071624e938d1e318
@@@ -2130,7 -2130,6 +2130,7 @@@ void pointcache_bake(PTCacheID *pid, in
                        BKE_ptcache_id_time(pid, 0.0f, &cstart, &cend, NULL);
  
                        cache->flag &= ~PTCACHE_BAKING;
 +
                        BKE_ptcache_id_reset(pid, PTCACHE_RESET_OUTDATED);
                }
                else {
@@@ -2513,15 -2512,18 +2513,15 @@@ static uiBlock *add_groupmenu(void *arg
  
        uiDefBut(block, BUTM, B_NOP, "ADD NEW",         0, 20, 160, 19, NULL, 0.0, 0.0, 1, -1, "");
        for(group= G.main->group.first; group; group= group->id.next, index++) {
 +              if(group->id.lib) strcpy(str, "L  ");
 +              else strcpy(str, "   ");
 +              strcat(str, group->id.name+2);
 +              uiDefBut(block, BUTM, B_NOP, str,       xco*160, -20*yco, 160, 19, NULL, 0.0, 0.0, 1, index, "");
                
 -              /*if(group->id.lib) strcpy(str, "L  ");*/ /* we cant allow adding objects inside linked groups, it wont be saved anyway */
 -              if(group->id.lib==0) {
 -                      strcpy(str, "   ");
 -                      strcat(str, group->id.name+2);
 -                      uiDefBut(block, BUTM, B_NOP, str,       xco*160, -20*yco, 160, 19, NULL, 0.0, 0.0, 1, index, "");
 -                      
 -                      yco++;
 -                      if(yco>24) {
 -                              yco= 0;
 -                              xco++;
 -                      }
 +              yco++;
 +              if(yco>24) {
 +                      yco= 0;
 +                      xco++;
                }
        }
        
@@@ -2590,21 -2592,25 +2590,21 @@@ static void object_panel_object(Object 
                        xco= 160;
                        
                        uiBlockBeginAlign(block);
 -                      uiSetButLock(GET_INT_FROM_POINTER(group->id.lib), ERROR_LIBDATA_MESSAGE); /* We cant actually use this button */
                        but = uiDefBut(block, TEX, B_IDNAME, "GR:",     10, 120-yco, 150, 20, group->id.name+2, 0.0, 21.0, 0, 0, "Displays Group name. Click to change.");
                        uiButSetFunc(but, test_idbutton_cb, group->id.name, NULL);
 -                      uiClearButLock();
                        
                        if(group->id.lib) {
                                but= uiDefIconBut(block, BUT, B_NOP, ICON_PARLIB, 160, 120-yco, 20, 20, NULL, 0.0, 0.0, 0.0, 0.0, "Make Group local");
                                uiButSetFunc(but, group_local, group, NULL);
                                xco= 180;
 -                      } else { /* cant remove objects from linked groups */
 -                              but = uiDefIconBut(block, BUT, B_NOP, VICON_X, xco, 120-yco, 20, 20, NULL, 0.0, 0.0, 0.0, 0.0, "Remove Group membership");
 -                              uiButSetFunc(but, group_ob_rem, group, ob);
                        }
 +                      but = uiDefIconBut(block, BUT, B_NOP, VICON_X, xco, 120-yco, 20, 20, NULL, 0.0, 0.0, 0.0, 0.0, "Remove Group membership");
 +                      uiButSetFunc(but, group_ob_rem, group, ob);
                        
                        yco+= 20;
                        xco= 10;
                        
                        /* layers */
 -                      uiSetButLock(GET_INT_FROM_POINTER(group->id.lib), ERROR_LIBDATA_MESSAGE);
                        uiBlockBeginAlign(block);
                        for(a=0; a<5; a++)
                                uiDefButBitI(block, TOG, 1<<a, REDRAWVIEW3D, "",        (short)(xco+a*(dx/2)), 120-yco, (short)(dx/2), (short)(dy/2), (int *)&(group->layer), 0, 0, 0, 0, "");
                                uiDefButBitI(block, TOG, 1<<(a+10), REDRAWVIEW3D, "",   (short)(xco+a*(dx/2)), 105-yco, (short)(dx/2), (short)(dy/2), (int *)&(group->layer), 0, 0, 0, 0, "");
                        
                        uiBlockEndAlign(block);
 -                      uiClearButLock();
 -
 +                      
                        yco+= 40;
                }
        }
@@@ -3224,6 -3231,7 +3224,6 @@@ static void object_collision__enabletog
                {
                        md = modifier_new ( eModifierType_Collision );
                        BLI_addtail ( &ob->modifiers, md );
 -                      DAG_scene_sort(G.scene);
                        DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
                        allqueue(REDRAWBUTSEDIT, 0);
                        allqueue(REDRAWVIEW3D, 0);
        }
        else
        {
 -              DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
                BLI_remlink ( &ob->modifiers, md );
                modifier_free ( md );
 -              DAG_scene_sort(G.scene);
                allqueue(REDRAWBUTSEDIT, 0);
        }
  }
@@@ -4822,7 -4832,7 +4822,7 @@@ static void object_panel_particle_syste
                uiDefButS(block, NUM, B_PART_RECALC, "Segments:",       butx,(buty-=buth),butw,buth, &part->hair_step, 2.0, 50.0, 0, 0, "Amount of hair segments");
        }
        else {
-               uiDefButF(block, NUM, B_PART_INIT, "Sta:",              butx,(buty-=buth),butw,buth, &part->sta, 1.0, part->end, 100, 1, "Frame # to start emitting particles");
+               uiDefButF(block, NUM, B_PART_INIT, "Sta:",              butx,(buty-=buth),butw,buth, &part->sta, -MAXFRAMEF, part->end, 100, 1, "Frame # to start emitting particles");
                uiDefButF(block, NUM, B_PART_INIT, "End:",              butx,(buty-=buth),butw,buth, &part->end, part->sta, MAXFRAMEF, 100, 1, "Frame # to stop emitting particles");
        }
  
index 198f853393d9dcc1c3633cb82078aa09ef178fff,1c98950080a50a867f71481a85ca9bc4c1cf6796..f136599519cdf4eb15d09feb5844c6322f25d5c3
@@@ -900,7 -900,7 +900,7 @@@ static void seq_panel_filter_video(
                     "Convert input to float data");
  
        uiDefButBitI(block, TOG, SEQ_FILTERY, 
-                    B_SEQ_BUT_RELOAD, "FilterY",       
+                    B_SEQ_BUT_RELOAD_FILE, "De-Inter", 
                     170,110,80,19, &last_seq->flag, 
                     0.0, 21.0, 100, 0, 
                     "For video movies to remove fields");
@@@ -2108,8 -2108,7 +2108,8 @@@ static void render_panel_output(void
        /* Toon shading buttons */
        uiBlockBeginAlign(block);
        uiDefButBitI(block, TOG, R_EDGE, B_NOP,"Edge",   115, 89, 60, 20, &G.scene->r.mode, 0, 0, 0, 0, "Enable Toon Edge-enhance");
 -      uiDefBlockBut(block, edge_render_menu, NULL, "Edge Settings", 175, 89, 135, 20, "Display Edge settings");
 +      uiDefBlockBut(block, edge_render_menu, NULL, "Edge Settings", 175, 89, 75, 20, "Display Edge settings");
 +      uiDefButBitI(block, TOG, R_EDGE_FRS, B_NOP,"Freestyle",   250, 89, 60, 20, &G.scene->r.mode, 0, 0, 0, 0, "Enable Freestyle");
        uiBlockEndAlign(block);
        
        uiBlockBeginAlign(block);
@@@ -2210,10 -2209,10 +2210,10 @@@ static void render_panel_render(void
        uiDefBut(block, BUT,B_DORENDER,"RENDER",        369, 164, 191,37, 0, 0, 0, 0, 0, "Render the current frame (F12)");
  #ifndef DISABLE_YAFRAY
        /* yafray: on request, render engine menu is back again, and moved to Render panel */
 -      uiDefButS(block, MENU, B_SWITCHRENDER, "Rendering Engine %t|Blender Internal %x0|YafRay %x1", 
 +      uiDefButS(block, MENU, B_SWITCHRENDER, "Rendering Engine %t|Blender Internal %x0|YafRay %x1|Freestyle %x2", 
                                                                                                369, 142, 191, 20, &G.scene->r.renderer, 0, 0, 0, 0, "Choose rendering engine");        
  #else
 -      uiDefButS(block, MENU, B_SWITCHRENDER, "Rendering Engine %t|Blender Internal %x0", 
 +      uiDefButS(block, MENU, B_SWITCHRENDER, "Rendering Engine %t|Blender Internal %x0|Freestyle %x1", 
                                                                                                369, 142, 191, 20, &G.scene->r.renderer, 0, 0, 0, 0, "Choose rendering engine");        
  #endif /* disable yafray */
  
@@@ -3385,10 -3384,8 +3385,10 @@@ static void render_panel_layers(void
        uiDefButBitI(block, TOG, SCE_LAY_HALO, B_NOP,"Halo",    95,  85, 40, 20, &srl->layflag, 0, 0, 0, 0, "Render Halos in this Layer (on top of Solid)");    
        uiDefButBitI(block, TOG, SCE_LAY_ZTRA, B_NOP,"Ztra",    135, 85, 40, 20, &srl->layflag, 0, 0, 0, 0, "Render Z-Transparent faces in this Layer (On top of Solid and Halos)");    
        uiDefButBitI(block, TOG, SCE_LAY_SKY, B_NOP,"Sky",              175, 85, 40, 20, &srl->layflag, 0, 0, 0, 0, "Render Sky or backbuffer in this Layer");  
 -      uiDefButBitI(block, TOG, SCE_LAY_EDGE, B_NOP,"Edge",    215, 85, 45, 20, &srl->layflag, 0, 0, 0, 0, "Render Edge-enhance in this Layer (only works for Solid faces)");  
 -      uiDefButBitI(block, TOG, SCE_LAY_STRAND, B_NOP,"Strand",260, 85, 50, 20, &srl->layflag, 0, 0, 0, 0, "Render Strands in this Layer");    
 +      uiDefButBitI(block, TOG, SCE_LAY_EDGE, B_NOP,"Edge",    215, 85, 25, 20, &srl->layflag, 0, 0, 0, 0, "Render Edge-enhance in this Layer (only works for Solid faces)");
 +      uiDefButBitI(block, TOG, SCE_LAY_FRS, B_NOP,"FrSt",     240, 85, 30, 20, &srl->layflag, 0, 0, 0, 0, "Render Freestyle in this Layer");  
 +      uiDefButBitI(block, TOG, SCE_LAY_STRAND, B_NOP,"Strand",270, 85, 40, 20, &srl->layflag, 0, 0, 0, 0, "Render Strands in this Layer");    
 +      
        
        uiDefIDPoinBut(block, test_grouppoin_but, ID_GR, B_SET_PASS, "Light:",  50, 65, 130, 20, &(srl->light_override), "Name of Group to use as Lamps instead");
        uiDefIDPoinBut(block, test_matpoin_but, ID_MA, B_SET_PASS, "Mat:",      180, 65, 130, 20, &(srl->mat_override), "Name of Material to use as Materials instead");
index 80ad52a9b00b3075e8649257fd7d4ff68805ac51,ca6705b208457060d48ee192925b6105947d3e08..872dc6ae2672d794a399b6e0cb599a0ef77ab3b5
@@@ -2803,6 -2803,42 +2803,42 @@@ static void lamp_panel_yafray(Object *o
  
  }
  
+ static void lamp_panel_atmosphere(Object *ob, Lamp *la)
+ {
+       uiBlock *block;
+       int y;
+       block= uiNewBlock(&curarea->uiblocks, "lamp_panel_atm", UI_EMBOSS, UI_HELV, curarea->win);
+       uiNewPanelTabbed("Shadow and Spot", "Lamp");
+       if(uiNewPanel(curarea, block, "Sky/Atmosphere", "Lamp", 3*PANELX, PANELY, PANELW, PANELH)==0) return;
+       uiSetButLock(la->id.lib!=0, ERROR_LIBDATA_MESSAGE);
+       
+       uiDefButBitS(block, TOG, LA_SUN_EFFECT_SKY, REDRAWVIEW3D, "Sky", 10,205,BUTW2,20,&(la->sun_effect_type), 0, 0, 0, 0, "Apply sun light effect on sky.");
+       uiDefButBitS(block, TOG, LA_SUN_EFFECT_AP, REDRAWVIEW3D, "Atmosphere", 20+BUTW2,205,BUTW2,20,&(la->sun_effect_type), 0, 0, 0, 0, "Apply sun light effect on atmosphere.");
+       if(la->sun_effect_type & (LA_SUN_EFFECT_SKY|LA_SUN_EFFECT_AP)){
+               uiDefButF(block, NUM, B_LAMPREDRAW, "Turbidity:",10,180,BUTW1,19, &(la->atm_turbidity), 1.000f, 30.0f, 1, 0, "Sky Turbidity");
+       }
+       y = 180;
+       if(la->sun_effect_type & LA_SUN_EFFECT_SKY)
+       {
+               uiDefButF(block, NUM, B_LAMPREDRAW, "Hor.Bright:",10,y-25,BUTW2,19, &(la->horizon_brightness), 0.00f, 20.00f, 10, 0, "Sets horizon brightness.");
+               uiDefButF(block, NUM, B_LAMPREDRAW, "Hor.Spread:",10,y-50,BUTW2,19, &(la->spread), 0.00f, 10.00f, 10, 0, "Sets horizon spread.");
+               uiDefButF(block, NUM, B_LAMPREDRAW, "Sun Bright:",10,y-75,BUTW2,19, &(la->sun_brightness), 0.00f, 10.0f, 10, 0, "Sets sun brightness.");
+               uiDefButF(block, NUM, B_LAMPREDRAW, "Sun Size:",10,y-100,BUTW2,19, &(la->sun_size), 0.00f, 10.00f, 10, 0, "Sets sun size.");
+               uiDefButF(block, NUM, B_LAMPREDRAW, "Back Light:",10,y-125,BUTW2,19, &(la->backscattered_light), -1.00f, 1.00f, 10, 0, "Sets backscatter light.");
+       }
+       if(la->sun_effect_type & LA_SUN_EFFECT_AP)
+       {
+               uiDefButF(block, NUM, B_LAMPREDRAW, "Sun Intens.:",20+BUTW2,y-25,BUTW2,19, &(la->sun_intensity), 0.00f, 10.00f, 10, 0, "Sets sun intensity.");
+               uiDefButF(block, NUM, B_LAMPREDRAW, "Inscattering:",20+BUTW2,y-50,BUTW2,19, &(la->atm_inscattering_factor), 0.00f, 1.00f, 10, 0, "In Scattering Contribution Factor.");
+               uiDefButF(block, NUM, B_LAMPREDRAW, "Extinction:",20+BUTW2,y-75,BUTW2,19, &(la->atm_extinction_factor), 0.00f, 1.00f, 10, 0, "Extinction Scattering Contribution Factor.");
+               uiDefButF(block, NUM, B_LAMPREDRAW, "Distance:",20+BUTW2,y-100,BUTW2,19, &(la->atm_distance_factor), 0.000f, 500.0f, 10, 0, "Scale blender distance to real distance.");
+       }
+ }
  static void lamp_panel_falloff(Object *ob, Lamp *la)
  {
        uiBlock *block;
@@@ -3312,7 -3348,7 +3348,7 @@@ static void material_panel_map_to(Objec
                        uiDefButBitS(block, TOG3, MAP_RAYMIRR, B_MATPRV, "RayMir",      50,160,40,19, &(mtex->mapto), 0, 0, 0, 0, "Causes the texture to affect the ray-mirror value");
                        uiDefButBitS(block, TOG3, MAP_ALPHA, B_MATPRV, "Alpha",         90,160,40,19, &(mtex->mapto), 0, 0, 0, 0, "Causes the texture to affect the alpha value");
                        uiDefButBitS(block, TOG3, MAP_EMIT, B_MATPRV, "Emit",           130,160,50,19, &(mtex->mapto), 0, 0, 0, 0, "Causes the texture to affect the emit value");
 -                      uiDefButBitS(block, TOG3, MAP_TRANSLU, B_MATPRV, "TransLu",             180,160,40,19, &(mtex->mapto), 0, 0, 0, 0, "Causes the texture to affect the translucency value");
 +                      uiDefButBitS(block, TOG3, MAP_TRANSLU, B_MATPRV, "TransLu",             180,160,40,19, &(mtex->mapto), 0, 0, 0, 0, "Causes the texture to affect the layer blending value");
                        if(from_nodes==0)
                                uiDefButBitS(block, TOG3, MAP_DISPLACE, B_MATPRV, "Disp",               220,160,50,19, &(mtex->mapto), 0, 0, 0, 0, "Let the texture displace the surface");
                        uiBlockSetCol(block, TH_BUT_SETTING1);
                        uiDefButBitS(block, TOG3, MAP_RAYMIRR, B_MATPRV, "RayMir",      60,160,50,19, &(mtex->mapto), 0, 0, 0, 0, "Causes the texture to affect the ray-mirror value");
                        uiDefButBitS(block, TOG3, MAP_ALPHA, B_MATPRV, "Alpha",         110,160,50,19, &(mtex->mapto), 0, 0, 0, 0, "Causes the texture to affect the alpha value");
                        uiDefButBitS(block, TOG3, MAP_EMIT, B_MATPRV, "Emit",           160,160,45,19, &(mtex->mapto), 0, 0, 0, 0, "Causes the texture to affect the emit value");
 -                      uiDefButBitS(block, TOG3, MAP_TRANSLU, B_MATPRV, "TransLu",             205,160,60,19, &(mtex->mapto), 0, 0, 0, 0, "Causes the texture to affect the translucency value");
 +                      uiDefButBitS(block, TOG3, MAP_TRANSLU, B_MATPRV, "TransLu",             205,160,60,19, &(mtex->mapto), 0, 0, 0, 0, "Causes the texture to affect the layer blending value");
                        if(from_nodes==0)
                                uiDefButBitS(block, TOG3, MAP_DISPLACE, B_MATPRV, "Disp",               265,160,45,19, &(mtex->mapto), 0, 0, 0, 0, "Let the texture displace the surface");
                }
@@@ -3634,7 -3670,7 +3670,7 @@@ static void material_panel_tramir(Mater
        uiDefButF(block, NUMSLI, B_MATPRV, "IOR: ",
                X2CLM2, yco-=BUTH, BUTW2, BUTH, &(ma->ang), 1.0, 3.0, 100, 2, "Sets angular index of refraction for raytraced refraction");
        uiDefButF(block, NUMSLI, B_MATPRV, "Fresnel: ",
 -              X2CLM2, yco-=BUTH, BUTW2, BUTH, &(ma->fresnel_tra), 0.0, 5.0, 10, 2, "Power of Fresnel for transparency (Ray or ZTransp)");
 +              X2CLM2, yco-=BUTH, BUTW2, BUTH, &(ma->fresnel_tra), 0.0, 5.0, 10, 2, "Power of Fresnel for mirror reflection");
        uiDefButF(block, NUMSLI, B_MATPRV, "Fac: ",
                X2CLM2, yco-=BUTH, BUTW2, BUTH, &(ma->fresnel_tra_i), 1.0, 5.0, 10, 2, "Blending factor for Fresnel");
        uiBlockEndAlign(block);
@@@ -4165,7 -4201,7 +4201,7 @@@ static void material_panel_links(Objec
        if(ma) uiSetButLock(ma->id.lib!=NULL, ERROR_LIBDATA_MESSAGE);
        
        if(ma)
 -              uiDefButC(block, TOG, B_MAT_USENODES, "Nodes", xco+5,160,300-xco-5,20, &ma->use_nodes, 0.0f, 0.0f, 0, 0, "Enables as a Nodes Material");
 +              uiDefButC(block, TOG, B_MAT_USENODES, "Nodes", xco+5,160,300-xco-5,20, &ma->use_nodes, 0.0f, 0.0f, 0, 0, "");
                                  
        if(ob->actcol==0) ob->actcol= 1;        /* because of TOG|BIT button */
        
@@@ -4354,6 -4390,11 +4390,11 @@@ void lamp_panels(
                /* spherelight radius default is zero, so nothing to do */
                lamp_panel_yafray(ob, la);
        }
+       
+       if(la->type == LA_SUN){
+               lamp_panel_atmosphere(ob, ob->data);
+       }
        lamp_panel_texture(ob, ob->data);
        lamp_panel_mapto(ob, ob->data);
  
index 7572391b3838010c54b38753cddd38538eea2616,261bb26b0c4507d595e032587dfb09c3c0553598..7bc14bce48dccd5b269c447216faa8ee0495d1a5
@@@ -99,7 -99,7 +99,7 @@@
  
  ListBase editNurb;
  BPoint *lastselbp;
 -int actnu;            /* for selected */
 +Nurb *lastnu;         /* for selected */
  
  
  /*  void freeNurblist(ListBase *lb); already declared in the kernel */
@@@ -109,6 -109,23 +109,6 @@@ float nurbcircle[8][2]= 
        {0.0,  1.0}, { 1.0,  1.0}, { 1.0, 0.0}, { 1.0, -1.0}
  };
  
 -
 -/* this replaces the active flag used in uv/face mode */
 -void set_actNurb(Nurb *nu)
 -{
 -      if (nu==NULL) {
 -              actnu = -1;
 -      } else {
 -              actnu = BLI_findindex(&editNurb, nu);
 -      }
 -}
 -
 -Nurb * get_actNurb( void )
 -{
 -      return BLI_findlink(&editNurb, actnu);
 -}
 -
 -
  /* ******************* SELECTION FUNCTIONS ********************* */
  
  /* returns 1 in case (de)selection was successful */
@@@ -318,14 -335,14 +318,14 @@@ void load_editNurb(
                                BLI_addtail(&(cu->nurb), newnu);
                                
                                if((nu->type & 7)==CU_NURBS) {
 -                                      clamp_nurb_order_u(nu);
 +                                      if(nu->pntsu < nu->orderu) nu->orderu= nu->pntsu;
                                }
                        }
                }
                
        }
        
 -      set_actNurb(NULL);
 +      lastnu= NULL;   /* for selected */
  }
  
  void make_editNurb()
        else G.obedit= NULL;
        
        countall();
 -      set_actNurb(NULL);
 +      
 +      lastnu= NULL;   /* for selected */
  }
  
  void remake_editNurb()
@@@ -457,8 -473,7 +457,8 @@@ void separate_nurb(
        countall();
        allqueue(REDRAWVIEW3D, 0);
        allqueue(REDRAWBUTSEDIT, 0);
 -      set_actNurb(NULL);
 +
 +      lastnu= NULL;   /* for selected */
  }
  
  /* ******************* FLAGS ********************* */
@@@ -640,7 -655,7 +640,7 @@@ void deleteflagNurb(short flag
                }
                if(a==0) {
                        BLI_remlink(&editNurb, nu);
 -                      freeNurb(nu); nu=NULL;
 +                      freeNurb(nu);
                }
                else {
                        /* is nurb in U direction selected */
                                nu->pntsv= newv;
                                MEM_freeN(nu->bp);
                                nu->bp= newbp;
 -                              clamp_nurb_order_v(nu);
 +                              if(nu->orderv>nu->pntsv) nu->orderv= nu->pntsv;
  
                                makeknots(nu, 2, nu->flagv>>1);
                        }
                                                nu->pntsu= nu->pntsv;
                                                nu->pntsv= 1;
                                                SWAP(short, nu->orderu, nu->orderv);
 -                                              clamp_nurb_order_u(nu);
 +                                              if(nu->orderu>nu->pntsu) nu->orderu= nu->pntsu;
                                                if(nu->knotsv) MEM_freeN(nu->knotsv);
 -                                              nu->knotsv= NULL;
 +                                              nu->knotsv= 0;
                                        }
                                        else {
                                                nu->pntsu= newu;
 -                                              clamp_nurb_order_u(nu);
 +                                              if(nu->orderu>nu->pntsu) nu->orderu= nu->pntsu;
                                        }
                                        makeknots(nu, 1, nu->flagu>>1);
                                }
@@@ -878,7 -893,7 +878,7 @@@ void adduplicateflagNurb(short flag
                                        newnu = (Nurb*)MEM_mallocN(sizeof(Nurb), "adduplicateN");  
                                        memcpy(newnu, nu, sizeof(Nurb));
                                        BLI_addtail(&editNurb, newnu);
 -                                      set_actNurb(newnu);
 +                                      lastnu= newnu;
                                        newnu->pntsu= enda-starta+1;
                                        newnu->bezt=
                                                (BezTriple*)MEM_mallocN((enda - starta + 1) * sizeof(BezTriple), "adduplicateN");  
                                                bezt1++;
                                        }
  
 -                                      if(nu->flagu & CU_CYCLIC) {
 -                                              if(starta!=0 || enda!=nu->pntsu-1) {
 -                                                      newnu->flagu &= ~CU_CYCLIC;
 -                                              }
 +                                      if(nu->flagu & 1) {
 +                                              if(starta!=0 || enda!=nu->pntsu-1) newnu->flagu--;
                                        }
                                }
                                bezt++;
                                if(enda>=starta) {
                                        newnu = (Nurb*)MEM_mallocN(sizeof(Nurb), "adduplicateN3");  
                                        memcpy(newnu, nu, sizeof(Nurb));
 -                                      set_actNurb(newnu);
 +                                      lastnu= newnu;
                                        BLI_addtail(&editNurb, newnu);
                                        newnu->pntsu= enda-starta+1;
                                        newnu->bp = (BPoint*)MEM_mallocN((enda-starta+1) * sizeof(BPoint), "adduplicateN4");
                                                bp1++;
                                        }
  
 -                                      if(nu->flagu & CU_CYCLIC) {
 -                                              if(starta!=0 || enda!=nu->pntsu-1) {
 -                                                      newnu->flagu &= ~CU_CYCLIC;
 -                                              }
 +                                      if(nu->flagu & 1) {
 +                                              if(starta!=0 || enda!=nu->pntsu-1) newnu->flagu--;
                                        }
  
                                        /* knots */
 -                                      newnu->knotsu= NULL;
 +                                      newnu->knotsu= 0;
                                        makeknots(newnu, 1, newnu->flagu>>1);
                                }
                                bp++;
                                        newnu = (Nurb*)MEM_mallocN(sizeof(Nurb), "adduplicateN5");
                                        memcpy(newnu, nu, sizeof(Nurb));
                                        BLI_addtail(&editNurb, newnu);
 -                                      set_actNurb(newnu);
 +                                      lastnu= newnu;
                                        newnu->pntsu= newu;
                                        newnu->pntsv= newv;
                                        newnu->bp =
                                                (BPoint*)MEM_mallocN(newu * newv * sizeof(BPoint), "adduplicateN6");
 -                                      clamp_nurb_order_u(newnu);
 -                                      clamp_nurb_order_v(newnu);
 -                                      
 -                                      newnu->knotsu= newnu->knotsv= NULL;
 -                                      
 +                                      newnu->orderu= MIN2(nu->orderu, newu);
 +                                      newnu->orderv= MIN2(nu->orderv, newv);
 +
                                        bp= newnu->bp;
                                        bp1= nu->bp;
                                        for(a=0; a<nu->pntsv; a++) {
                                                        }
                                                }
                                        }
 -                                      if (check_valid_nurb_u(newnu)) {
 -                                              if(nu->pntsu==newnu->pntsu && nu->knotsu) {
 -                                                      newnu->knotsu= MEM_dupallocN( nu->knotsu );
 -                                              } else {
 -                                                      makeknots(newnu, 1, newnu->flagu>>1);
 -                                              }
 +                                      if(nu->pntsu==newnu->pntsu) {
 +                                              newnu->knotsu= MEM_mallocN(sizeof(float)*KNOTSU(nu), "adduplicateN6");
 +                                              memcpy(newnu->knotsu, nu->knotsu, sizeof(float)*KNOTSU(nu));
                                        }
 -                                      if (check_valid_nurb_v(newnu)) {
 -                                              if(nu->pntsv==newnu->pntsv && nu->knotsv) {
 -                                                      newnu->knotsv= MEM_dupallocN( nu->knotsv );
 -                                              } else {
 -                                                      makeknots(newnu, 2, newnu->flagv>>1);
 -                                              }
 +                                      else {
 +                                              newnu->knotsu= 0;
 +                                              makeknots(newnu, 1, newnu->flagu>>1);
                                        }
 +                                      if(nu->pntsv==newnu->pntsv) {
 +                                              newnu->knotsv= MEM_mallocN(sizeof(float)*KNOTSV(nu), "adduplicateN7");
 +                                              memcpy(newnu->knotsv, nu->knotsv, sizeof(float)*KNOTSV(nu));
 +                                      }
 +                                      else {
 +                                              newnu->knotsv= 0;
 +                                              makeknots(newnu, 2, newnu->flagv>>1);
 +                                      }
 +
                                }
                                MEM_freeN(usel);
                        }
                nu= nu->prev;
        }
        
 -      /* actnu changed */
 +      /* lastnu changed */
        allqueue(REDRAWBUTSEDIT, 0);
  }
  
@@@ -1140,6 -1158,62 +1140,62 @@@ void setradiusNurb( void 
        allqueue(REDRAWINFO, 1);        /* 1, because header->win==0! */
  }
  
+ void smoothNurb( void )
+ {
+       extern ListBase editNurb;
+       Nurb *nu;
+       BezTriple *bezt, *beztOrig;
+       BPoint *bp, *bpOrig;
+       int a, i, change = 0;
+       
+       /* floats for smoothing */
+       float val, newval, offset;
+       
+       for(nu= editNurb.first; nu; nu= nu->next) {
+               if(nu->bezt) {
+                       change = 0;
+                       beztOrig = MEM_dupallocN( nu->bezt );
+                       for(bezt=nu->bezt+1, a=1; a<nu->pntsu-1; a++, bezt++) {
+                               if(bezt->f2 & SELECT) {
+                                       for(i=0; i<3; i++) {
+                                               val = bezt->vec[1][i];
+                                               newval = ((beztOrig+(a-1))->vec[1][i] * 0.5) + ((beztOrig+(a+1))->vec[1][i] * 0.5);
+                                               offset = (val*((1.0/6.0)*5)) + (newval*(1.0/6.0)) - val;
+                                               /* offset handles */
+                                               bezt->vec[1][i] += offset;
+                                               bezt->vec[0][i] += offset;
+                                               bezt->vec[2][i] += offset;
+                                       }
+                                       change = 1;
+                               }
+                       }
+                       MEM_freeN(beztOrig);
+                       if (change)
+                               calchandlesNurb(nu);
+               } else if (nu->bp) {
+                       bpOrig = MEM_dupallocN( nu->bp );
+                       /* Same as above, keep these the same! */
+                       for(bp=nu->bp+1, a=1; a<nu->pntsu-1; a++, bp++) {
+                               if(bp->f1 & SELECT) {
+                                       for(i=0; i<3; i++) {
+                                               val = bp->vec[i];
+                                               newval = ((bpOrig+(a-1))->vec[i] * 0.5) + ((bpOrig+(a+1))->vec[i] * 0.5);
+                                               offset = (val*((1.0/6.0)*5)) + (newval*(1.0/6.0)) - val;
+                                       
+                                               bp->vec[i] += offset;
+                                       }
+                               }
+                       }
+                       MEM_freeN(bpOrig);
+               }
+       }
+       BIF_undo_push("Smooth Curve");
+       DAG_object_flush_update(G.scene, OBACT, OB_RECALC_DATA);
+       allqueue(REDRAWVIEW3D, 0);
+       allqueue(REDRAWBUTSALL, 0);
+       allqueue(REDRAWINFO, 1);        /* 1, because header->win==0! */
+ }
  
  /* TODO, make smoothing distance based */
  void smoothradiusNurb( void )
@@@ -1569,7 -1643,7 +1625,7 @@@ void subdivideNurb(
             newly created. Old points are discarded.
          */
                        /* count */
 -                      if(nu->flagu & CU_CYCLIC) {
 +                      if(nu->flagu & 1) {
                                a= nu->pntsu;
                                bezt= nu->bezt;
                                prevbezt= bezt+(a-1);
                                beztnew =
                                        (BezTriple*)MEM_mallocN((amount + nu->pntsu) * sizeof(BezTriple), "subdivNurb");
                                beztn= beztnew;
 -                              if(nu->flagu & CU_CYCLIC) {
 +                              if(nu->flagu & 1) {
                                        a= nu->pntsu;
                                        bezt= nu->bezt;
                                        prevbezt= bezt+(a-1);
                                                VecMidf(beztn->vec[1], vec+9, vec+12);
                                                VECCOPY(beztn->vec[2], vec+12);
                                                /* handle of next bezt */
 -                                              if(a==0 && (nu->flagu & CU_CYCLIC)) {VECCOPY(beztnew->vec[0], vec+6);}
 +                                              if(a==0 && (nu->flagu & 1)) {VECCOPY(beztnew->vec[0], vec+6);}
                                                else {VECCOPY(bezt->vec[0], vec+6);}
                                                
                                                beztn->radius = (prevbezt->radius + bezt->radius)/2.0f;
                                        bezt++;
                                }
                                /* last point */
 -                              if((nu->flagu & CU_CYCLIC)==0) memcpy(beztn, prevbezt, sizeof(BezTriple));
 +                              if((nu->flagu & 1)==0) memcpy(beztn, prevbezt, sizeof(BezTriple));
  
                                MEM_freeN(nu->bezt);
                                nu->bezt= beztnew;
             stable... nzc 30-5-'00
           */
                        /* count */
 -                      if(nu->flagu & CU_CYCLIC) {
 +                      if(nu->flagu & 1) {
                                a= nu->pntsu*nu->pntsv;
                                bp= nu->bp;
                                prevbp= bp+(a-1);
                                        (BPoint*)MEM_mallocN((amount + nu->pntsu) * sizeof(BPoint), "subdivNurb2");
                                bpn= bpnew;
  
 -                              if(nu->flagu & CU_CYCLIC) {
 +                              if(nu->flagu & 1) {
                                        a= nu->pntsu;
                                        bp= nu->bp;
                                        prevbp= bp+(a-1);
                                        prevbp= bp;
                                        bp++;
                                }
 -                              if((nu->flagu & CU_CYCLIC)==0) memcpy(bpn, prevbp, sizeof(BPoint));     /* last point */
 +                              if((nu->flagu & 1)==0) memcpy(bpn, prevbp, sizeof(BPoint));     /* last point */
  
                                MEM_freeN(nu->bp);
                                nu->bp= bpnew;
@@@ -2075,7 -2149,7 +2131,7 @@@ int convertspline(short type, Nurb *nu
                        nu->type &= ~7;
                        nu->type+= 4;
                        nu->orderu= 4;
 -                      nu->flagu &= CU_CYCLIC; /* disable all flags except for cyclic */
 +                      nu->flagu &= 1;
                        nu->flagu += 4;
                        makeknots(nu, 1, nu->flagu>>1);
                        a= nu->pntsu*nu->pntsv;
                        nu->orderv= 1;
                        nu->type &= ~7;
                        nu->type+= type;
 -                      if(nu->flagu & CU_CYCLIC) c= nu->orderu-1; 
 +                      if(nu->flagu & 1) c= nu->orderu-1; 
                        else c= 0;
                        if(type== 4) {
 -                              nu->flagu &= CU_CYCLIC; /* disable all flags except for cyclic */
 +                              nu->flagu &= 1;
                                nu->flagu += 4;
                                makeknots(nu, 1, nu->flagu>>1);
                        }
                if(type==0) {                   /* to Poly */
                        nu->type &= ~7;
                        if(nu->knotsu) MEM_freeN(nu->knotsu); /* python created nurbs have a knotsu of zero */
 -                      nu->knotsu= NULL;
 +                      nu->knotsu= 0;
                        if(nu->knotsv) MEM_freeN(nu->knotsv);
 -                      nu->knotsv= NULL;
 +                      nu->knotsv= 0;
                }
                else if(type==CU_BEZIER) {              /* to Bezier */
                        nr= nu->pntsu/3;
                                MEM_freeN(nu->bp);
                                nu->bp= 0;
                                MEM_freeN(nu->knotsu);
 -                              nu->knotsu= NULL;
 +                              nu->knotsu= 0;
                                nu->pntsu= nr;
                                nu->type &= ~7;
                                nu->type+= 1;
@@@ -2481,7 -2555,7 +2537,7 @@@ void merge_nurb(
        BLI_freelistN(&nsortbase);
        
        countall();
 -      set_actNurb(NULL);
 +      lastnu= NULL;
  
        DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA);
  
@@@ -2527,7 -2601,7 +2583,7 @@@ void addsegment_nurb(
        
        /* find both nurbs and points, nu1 will be put behind nu2 */
        for(nu= editNurb.first; nu; nu= nu->next) {
 -              if((nu->flagu & CU_CYCLIC)==0) {    /* not cyclic */
 +              if((nu->flagu & 1)==0) {    /* not cyclic */
                        if( (nu->type & 7)==CU_BEZIER ) {
                                bezt= nu->bezt;
                                if(nu1==0) {
                                nu1->bezt= bezt;
                                nu1->pntsu+= nu2->pntsu;
                                BLI_remlink(&editNurb, nu2);
 -                              freeNurb(nu2); nu2= NULL;
 +                              freeNurb(nu2);
                                calchandlesNurb(nu1);
                        }
                        else {
                                                }
                                        }
                                }
 -                              freeNurb(nu2); nu2= NULL;
 +                              freeNurb(nu2);
                        }
                }
                
 -              set_actNurb(NULL);      /* for selected */
 +              lastnu= NULL;   /* for selected */
  
                DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA);     
  
@@@ -2704,8 -2778,8 +2760,8 @@@ void mouse_nurb(
  
        rightmouse_transform();
        
 -      if(nu!=get_actNurb()) {
 -              set_actNurb(nu);
 +      if(nu!=lastnu) {
 +              lastnu= nu;
                allqueue(REDRAWBUTSEDIT, 0);
        }
        
@@@ -2808,7 -2882,7 +2864,7 @@@ static void spin_nurb(float *dvec, shor
                for(nu= editNurb.first; nu; nu= nu->next) {
                        if(isNurbsel(nu)) {
                                nu->orderv= 4;
 -                              nu->flagv |= CU_CYCLIC;
 +                              nu->flagv |= 1;
                                makeknots(nu, 2, nu->flagv>>1);
                        }
                }
@@@ -3006,8 -3080,8 +3062,8 @@@ void makecyclicNurb(
                                bp= nu->bp;
                                while(a--) {
                                        if( bp->f1 & SELECT ) {
 -                                              if(nu->flagu & CU_CYCLIC) nu->flagu &= ~CU_CYCLIC;
 -                                              else nu->flagu |= CU_CYCLIC;
 +                                              if(nu->flagu & CU_CYCLIC) nu->flagu--;
 +                                              else nu->flagu++;
                                                break;
                                        }
                                        bp++;
                                bezt= nu->bezt;
                                while(a--) {
                                        if( BEZSELECTED_HIDDENHANDLES(bezt) ) {
 -                                              if(nu->flagu & CU_CYCLIC) nu->flagu &= ~CU_CYCLIC;
 -                                              else nu->flagu |= CU_CYCLIC;
 +                                              if(nu->flagu & CU_CYCLIC) nu->flagu--;
 +                                              else nu->flagu++;
                                                break;
                                        }
                                        bezt++;
                                calchandlesNurb(nu);
                        }
                        else if(nu->pntsv==1 && (nu->type & 7)==CU_NURBS) {
 -                              if (nu->knotsu) { /* if check_valid_nurb_u fails the knotsu can be NULL */
 -                                      a= nu->pntsu;
 -                                      bp= nu->bp;
 -                                      while(a--) {
 -                                              if( bp->f1 & SELECT ) {
 -                                                      if(nu->flagu & CU_CYCLIC) nu->flagu &= ~CU_CYCLIC;
 -                                                      else {
 -                                                              nu->flagu |= CU_CYCLIC;
 -                                                              nu->flagu &= ~2;        /* endpoint flag, fixme */
 -                                                              fp= MEM_mallocN(sizeof(float)*KNOTSU(nu), "makecyclicN");
 -                                                              b= (nu->orderu+nu->pntsu);
 -                                                              memcpy(fp, nu->knotsu, sizeof(float)*b);
 -                                                              MEM_freeN(nu->knotsu);
 -                                                              nu->knotsu= fp;
 +                              a= nu->pntsu;
 +                              bp= nu->bp;
 +                              while(a--) {
 +                                      if( bp->f1 & SELECT ) {
 +                                              if(nu->flagu & CU_CYCLIC) nu->flagu--;
 +                                              else {
 +                                                      nu->flagu++;
 +                                                      nu->flagu &= ~2;        /* endpoint flag, fixme */
 +                                                      fp= MEM_mallocN(sizeof(float)*KNOTSU(nu), "makecyclicN");
 +                                                      b= (nu->orderu+nu->pntsu);
 +                                                      memcpy(fp, nu->knotsu, sizeof(float)*b);
 +                                                      MEM_freeN(nu->knotsu);
 +                                                      nu->knotsu= fp;
                                                        
 -                                                              makeknots(nu, 1, 0);    /* 1==u  0==uniform */
 +                                                      makeknots(nu, 1, 0);    /* 1==u  0==uniform */
                                                        
 -                                                      }
 -                                                      break;
                                                }
 -                                              bp++;
 +                                              break;
                                        }
 +                                      bp++;
                                }
                        }
                        else if(nu->type==CU_NURBS) {
        
                                        if( bp->f1 & SELECT) {
                                                if(cyclmode==1 && nu->pntsu>1) {
 -                                                      if(nu->flagu & CU_CYCLIC) nu->flagu &= ~CU_CYCLIC;
 +                                                      if(nu->flagu & CU_CYCLIC) nu->flagu--;
                                                        else {
 -                                                              nu->flagu |= CU_CYCLIC;
 -                                                              if (check_valid_nurb_u(nu)) {
 -                                                                      fp= MEM_mallocN(sizeof(float)*KNOTSU(nu), "makecyclicN");
 -                                                                      b= (nu->orderu+nu->pntsu);
 -                                                                      if (nu->knotsu) { /* null if check_valid_nurb_u failed before but is valid now */
 -                                                                              memcpy(fp, nu->knotsu, sizeof(float)*b);
 -                                                                              MEM_freeN(nu->knotsu);
 -                                                                      }
 -                                                                      nu->knotsu= fp;
 +                                                              nu->flagu++;
 +                                                              fp= MEM_mallocN(sizeof(float)*KNOTSU(nu), "makecyclicN");
 +                                                              b= (nu->orderu+nu->pntsu);
 +                                                              memcpy(fp, nu->knotsu, sizeof(float)*b);
 +                                                              MEM_freeN(nu->knotsu);
 +                                                              nu->knotsu= fp;
                                                                
 -                                                                      makeknots(nu, 1, 0);    /* 1==u  0==uniform */
 -                                                              }
 +                                                              makeknots(nu, 1, 0);    /* 1==u  0==uniform */
                                                        }
                                                }
                                                if(cyclmode==2 && nu->pntsv>1) {
                                                        if(nu->flagv & 1) nu->flagv--;
                                                        else {
                                                                nu->flagv++;
 -                                                              if (check_valid_nurb_v(nu)) {
 -                                                                      fp= MEM_mallocN(sizeof(float)*KNOTSV(nu), "makecyclicN");
 -                                                                      b= (nu->orderv+nu->pntsv);
 -                                                                      if (nu->knotsv) { /* null if check_valid_nurb_v failed before but is valid now */
 -                                                                              memcpy(fp, nu->knotsv, sizeof(float)*b);
 -                                                                              MEM_freeN(nu->knotsv);
 -                                                                      }
 -                                                                      nu->knotsv= fp;
 +                                                              fp= MEM_mallocN(sizeof(float)*KNOTSV(nu), "makecyclicN");
 +                                                              b= (nu->orderv+nu->pntsv);
 +                                                              memcpy(fp, nu->knotsv, sizeof(float)*b);
 +                                                              MEM_freeN(nu->knotsv);
 +                                                              nu->knotsv= fp;
                                                                
 -                                                                      makeknots(nu, 2, 0);    /* 2==v  0==uniform */
 -                                                              }
 +                                                              makeknots(nu, 2, 0);    /* 2==v  0==uniform */
                                                        }
                                                }
                                                break;
@@@ -3638,7 -3722,7 +3694,7 @@@ void delNurb(
                                        }
                                        if(a==0) {
                                                BLI_remlink(&editNurb, nu);
 -                                              freeNurb(nu); nu= NULL;
 +                                              freeNurb(nu);
                                        }
                                }
                        }
                                        }
                                        if(a==0) {
                                                BLI_remlink(&editNurb, nu);
 -                                              freeNurb(nu); nu= NULL;
 +                                              freeNurb(nu);
                                        }
                                }
                        }
                        
 -                      /* Never allow the order to exceed the number of points
 -                      - note, this is ok but changes unselected nurbs, disable for now */
 -                      /*
 -                      if ((nu!= NULL) && ((nu->type & 7)==CU_NURBS)) {
 -                              clamp_nurb_order_u(nu);
 +                      /* Never allow the order to exceed the number of points */
 +                      if ((nu->type & 7)==CU_NURBS && (nu->pntsu < nu->orderu)) {
 +                              nu->orderu = nu->pntsu;
                        }
 -                      */
                        nu= next;
                }
                /* 2nd loop, delete small pieces: just for curves */
                                        MEM_freeN(nu->bp);
                                        nu->bp= bp1;
                                        
 -                                      /* Never allow the order to exceed the number of points\
 -                                      - note, this is ok but changes unselected nurbs, disable for now */
 -                                      /*
 -                                      if ((nu->type & 7)==CU_NURBS) {
 -                                              clamp_nurb_order_u(nu);
 -                                      }*/
 +                                      /* Never allow the order to exceed the number of points */
 +                                      if ((nu->type & 7)==CU_NURBS && (nu->pntsu < nu->orderu)) {
 +                                              nu->orderu = nu->pntsu;
 +                                      }
                                }
                                makeknots(nu, 1, nu->flagu>>1);
                        }
                                                bezt2= bezt+1;
                                                if( (bezt2->f1 & SELECT) || (bezt2->f2 & SELECT) || (bezt2->f3 & SELECT) ) ;
                                                else {  /* maybe do not make cyclic */
 -                                                      if(a==0 && (nu->flagu & CU_CYCLIC) ) {
 +                                                      if(a==0 && (nu->flagu & 1) ) {
                                                                bezt2= bezt+(nu->pntsu-1);
                                                                if( (bezt2->f1 & SELECT) || (bezt2->f2 & SELECT) || (bezt2->f3 & SELECT) ) {
 -                                                                      nu->flagu &= ~CU_CYCLIC;
 +                                                                      nu->flagu--;
                                                                        DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA);
                                                                        allqueue(REDRAWVIEW3D, 0);
                                                                        allqueue(REDRAWBUTSEDIT, 0);
                                                bp2= bp+1;
                                                if( bp2->f1 & 1 ) ;
                                                else {  /* maybe do not make cyclic */
 -                                                      if(a==0 && (nu->flagu & CU_CYCLIC) ) {
 +                                                      if(a==0 && (nu->flagu & 1) ) {
                                                                bp2= bp+(nu->pntsu-1);
 -                                                              if( bp2->f1 & SELECT ) {
 -                                                                      nu->flagu &= ~CU_CYCLIC;
 +                                                              if( bp2->f1 & 1 ) {
 +                                                                      nu->flagu--;
                                                                        DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA);
                                                                        allqueue(REDRAWVIEW3D, 0);
                                                                        allqueue(REDRAWBUTSEDIT, 0);
                        if(bezt1) {
                                if(nu1->pntsu==2) {     /* remove completely */
                                        BLI_remlink(&editNurb, nu);
 -                                      freeNurb(nu); nu = NULL;
 +                                      freeNurb(nu);
                                }
 -                              else if(nu1->flagu & CU_CYCLIC) {       /* cyclic */
 +                              else if(nu1->flagu & 1) {       /* cyclic */
                                        bezt =
                                                (BezTriple*)MEM_mallocN((cut+1) * sizeof(BezTriple), "delNurb1");
                                        memcpy(bezt, nu1->bezt,(cut+1)*sizeof(BezTriple));
                                        a= nu1->pntsu-cut-1;
                                        memcpy(nu1->bezt, bezt2, a*sizeof(BezTriple));
                                        memcpy(nu1->bezt+a, bezt, (cut+1)*sizeof(BezTriple));
 -                                      nu1->flagu &= ~CU_CYCLIC;
 +                                      nu1->flagu--;
                                        MEM_freeN(bezt);
                                        calchandlesNurb(nu);
                                }
                        else if(bp1) {
                                if(nu1->pntsu==2) {     /* remove completely */
                                        BLI_remlink(&editNurb, nu);
 -                                      freeNurb(nu); nu= NULL;
 +                                      freeNurb(nu);
                                }
 -                              else if(nu1->flagu & CU_CYCLIC) {       /* cyclic */
 +                              else if(nu1->flagu & 1) {       /* cyclic */
                                        bp =
                                                (BPoint*)MEM_mallocN((cut+1) * sizeof(BPoint), "delNurb5");
                                        memcpy(bp, nu1->bp,(cut+1)*sizeof(BPoint));
                                        a= nu1->pntsu-cut-1;
                                        memcpy(nu1->bp, bp2, a*sizeof(BPoint));
                                        memcpy(nu1->bp+a, bp, (cut+1)*sizeof(BPoint));
 -                                      nu1->flagu &= ~CU_CYCLIC;
 +                                      nu1->flagu--;
                                        MEM_freeN(bp);
                                }
                                else {                  /* add new curve */
@@@ -4151,7 -4240,7 +4207,7 @@@ Nurb *addNurbprim(int type, int stype, 
                if((type & 7)==CU_BEZIER) {
                        nu->pntsu= 4;
                        nu->bezt= callocstructN(BezTriple, 4, "addNurbprim1");
 -                      nu->flagu= CU_CYCLIC;
 +                      nu->flagu= 1;
                        bezt= nu->bezt;
  
                        for(a=0;a<3;a++) {
                        nu->pntsv= 1;
                        nu->orderu= 4;
                        nu->bp= callocstructN(BPoint, 8, "addNurbprim6");
 -                      nu->flagu= CU_CYCLIC;
 +                      nu->flagu= 1;
                        bp= nu->bp;
  
                        for(a=0; a<8; a++) {
@@@ -4592,10 -4681,6 +4648,10 @@@ static void undoCurve_to_editCurve(voi
  {
        ListBase *lb= lbv;
        Nurb *nu, *newnu;
 +      int nr, lastnunr= 0;
 +
 +      /* we try to restore lastnu too, for buttons */
 +      for(nu= editNurb.first; nu; nu = nu->next, lastnunr++) if(nu==lastnu) break;
        
        freeNurblist(&editNurb);
  
                newnu= duplicateNurb(nu);
                BLI_addtail(&editNurb, newnu);
        }
 +      /* restore */
 +      for(nr=0, lastnu= editNurb.first; lastnu; lastnu = lastnu->next, nr++) if(nr==lastnunr) break;
 +      
  }
  
  static void *editCurve_to_undoCurve(void)
index 088c85edc5690e5bc5a95f6ed05c5d0176fc8fca,4d9679b6b8a172342067a7e40996f6a246e7f53e..4ca1bbfde59d6a28dcf2800b4aaff4beef22b396
@@@ -880,7 -880,7 +880,7 @@@ void EM_free_data_layer(CustomData *dat
  
  static void add_normal_aligned(float *nor, float *add)
  {
 -      if( INPR(nor, add) < -0.9999f)
 +      if( INPR(nor, add) < 0.0 ) 
                VecSubf(nor, nor, add);
        else
                VecAddf(nor, nor, add);
@@@ -2199,18 -2199,25 +2199,25 @@@ UvVertMap *make_uv_vert_map_EM(int sele
                if(!selected || ((!efa->h) && (efa->f & SELECT)))
                        totuv += (efa->v4)? 4: 3;
                
-       if(totuv==0)
+       if(totuv==0) {
+               if (do_face_idx_array)
+                       EM_free_index_arrays();
                return NULL;
-       
+       }
        vmap= (UvVertMap*)MEM_callocN(sizeof(*vmap), "UvVertMap");
-       if (!vmap)
+       if (!vmap) {
+               if (do_face_idx_array)
+                       EM_free_index_arrays();
                return NULL;
+       }
  
        vmap->vert= (UvMapVert**)MEM_callocN(sizeof(*vmap->vert)*totverts, "UvMapVert*");
        buf= vmap->buf= (UvMapVert*)MEM_callocN(sizeof(*vmap->buf)*totuv, "UvMapVert");
  
        if (!vmap->vert || !vmap->buf) {
                free_uv_vert_map(vmap);
+               if (do_face_idx_array)
+                       EM_free_index_arrays();
                return NULL;
        }
  
index 721fae8512f0e784ca3eb5896b376d59b3b9c72a,2e5785eaab89b88f1d8cd8d79328c6909e6b5dda..cde5a2f59184d2a78dca828bfb9276c25c8893b0
@@@ -2735,7 -2735,7 +2735,7 @@@ void special_editmenu(void
        }
        else if ELEM(G.obedit->type, OB_CURVE, OB_SURF) {
  
-               nr= pupmenu("Specials%t|Subdivide%x1|Switch Direction%x2|Set Goal Weight %x3|Set Radius %x4|Smooth Radius %x5");
+               nr= pupmenu("Specials%t|Subdivide%x1|Switch Direction%x2|Set Goal Weight%x3|Set Radius%x4|Smooth%x5|Smooth Radius%x6");
                
                switch(nr) {
                case 1:
                        setradiusNurb();
                        break;
                case 5:
+                       smoothNurb();
+                       break;
+               case 6:
                        smoothradiusNurb();
                        break;
                }
@@@ -4816,6 -4819,7 +4819,6 @@@ void make_local(int mode
        Base *base;
        Object *ob;
        bActionStrip *strip;
 -      ParticleSystem *psys;
        Material *ma, ***matarar;
        Lamp *la;
        Curve *cu;
                                        make_local_armature ((bArmature *)id);
                                        break;
                                }
 -
 -                              for(psys=ob->particlesystem.first; psys; psys=psys->next)
 -                                      make_local_particlesettings(psys->part);
                        }
                        id= (ID *)ob->ipo;
                        if(id && id->lib) make_local_ipo(ob->ipo);
                        id= (ID *)ob->action;
                        if(id && id->lib) make_local_action(ob->action);
                        
 -                      for(strip=ob->nlastrips.first; strip; strip=strip->next) {
 +                      for (strip=ob->nlastrips.first; strip; strip=strip->next) {
                                if(strip->act && strip->act->id.lib)
                                        make_local_action(strip->act);
                        }
 +                      
                }
                base= base->next;               
        }
@@@ -5936,7 -5942,7 +5939,7 @@@ void hide_objects(int select
        Base *base;
        short changed = 0, changed_act = 0;
        for(base = FIRSTBASE; base; base=base->next){
-               if(TESTBASELIB(base)==select){
+               if ((base->lay & G.vd->lay) && (TESTBASELIB(base)==select)) {
                        base->flag &= ~SELECT;
                        base->object->flag = base->flag;
                        base->object->restrictflag |= OB_RESTRICT_VIEW;
index 4873f5d6688992f14b3961ba6b265f471f88ca78,f9432f8e69a8ca0e5e26499fd6776127cb1e424b..bddca1bd0ca532eaf36d34e35deb4a32e31adfc0
@@@ -803,14 -803,13 +803,14 @@@ void mouse_select_seq(void
                /* select timeline marker */
                if (G.qual & LR_SHIFTKEY) {
                        oldflag= marker->flag;
 +                      deselect_markers(0, 0);
 +                      
                        if (oldflag & SELECT)
                                marker->flag &= ~SELECT;
                        else
                                marker->flag |= SELECT;
                }
                else {
 -                      deselect_markers(0, 0);
                        marker->flag |= SELECT;                         
                }
                allqueue(REDRAWMARKER, 0);
@@@ -2136,12 -2135,25 +2136,25 @@@ void del_seq(void
        Sequence *seq;
        MetaStack *ms;
        Editing *ed;
-       if(okee("Erase selected")==0) return;
+       int nothingSelected = TRUE;
  
        ed= G.scene->ed;
        if(ed==0) return;
  
+       seq=get_last_seq();
+       if (seq && seq->flag & SELECT) { /* avoid a loop since this is likely to be selected */
+               nothingSelected = FALSE;
+       } else {
+               for (seq = ed->seqbasep->first; seq; seq = seq->next) {
+                       if (seq->flag & SELECT) {
+                               nothingSelected = FALSE;
+                               break;
+                       }
+               }
+       }
+       
+       if(nothingSelected || okee("Erase selected")==0) return;
        /* free imbufs of all dependent strips */
        for(seq=ed->seqbasep->first; seq; seq=seq->next)
                if(seq->flag & SELECT)
@@@ -2635,12 -2647,13 +2648,13 @@@ void set_filter_seq(void
        ed= G.scene->ed;
        if(ed==0) return;
  
-       if(okee("Set FilterY")==0) return;
+       if(okee("Set Deinterlace")==0) return;
  
        WHILE_SEQ(ed->seqbasep) {
                if(seq->flag & SELECT) {
                        if(seq->type==SEQ_MOVIE) {
                                seq->flag |= SEQ_FILTERY;
+                               reload_sequence_new_file(seq);
                        }
  
                }
@@@ -3838,9 -3851,15 +3852,9 @@@ void seq_mute_sel(int mute) 
        if(!ed) return;
        
        for(seq= ed->seqbasep->first; seq; seq= seq->next) {
 -              if ((seq->flag & SEQ_LOCK)==0) {
 -                      if (mute==-1) { /* hide unselected */
 -                              if ((seq->flag & SELECT)==0) {
 -                                      seq->flag |= SEQ_MUTE;
 -                              }
 -                      } else if (seq->flag & SELECT) {
 -                              if (mute) seq->flag |= SEQ_MUTE;
 -                              else seq->flag &= ~SEQ_MUTE;
 -                      }
 +              if ((seq->flag & SELECT) && (seq->flag & SEQ_LOCK)==0) {
 +                      if (mute) seq->flag |= SEQ_MUTE;
 +                      else seq->flag &= ~SEQ_MUTE;
                }
        }
        BIF_undo_push(mute?"Mute Strips, Sequencer":"UnMute Strips, Sequencer");
index 1cff92b315f647fbd7e6c150f610c004c7450a5b,6851929bbc21fff352acecbb7e61521640d6c5e3..7f80de2aff8fe055023ee9c3c2e7669b6b8d40b9
@@@ -426,11 -426,9 +426,11 @@@ void reload_sequence_new_file(Sequence 
  
        if (seq->type != SEQ_SCENE && seq->type != SEQ_META &&
            seq->type != SEQ_IMAGE) {
 -              BLI_join_dirfile(str, seq->strip->dir, seq->strip->stripdata->name);
 +              strncpy(str, seq->strip->dir, FILE_MAXDIR-1);
 +              strncat(str, seq->strip->stripdata->name, FILE_MAXFILE-1);
 +
                BLI_convertstringcode(str, G.sce);
 -              BLI_convertstringframe(str, G.scene->r.cfra);
 +              BLI_convertstringframe(str, G.scene->r.cfra); /* TODO - is this needed? */
                
        }
  
                seq->strip->len = seq->len;
        } else if (seq->type == SEQ_MOVIE) {
                if(seq->anim) IMB_free_anim(seq->anim);
-               seq->anim = openanim(str, IB_rect);
+               seq->anim = openanim(
+                       str, IB_rect | 
+                       ((seq->flag & SEQ_FILTERY) 
+                        ? IB_animdeinterlace : 0));
  
                if (!seq->anim) {
                        return;
@@@ -1447,7 -1448,7 +1450,7 @@@ static void input_preprocess(Sequence 
        seq->strip->orx= se->ibuf->x;
        seq->strip->ory= se->ibuf->y;
  
-       if(seq->flag & SEQ_FILTERY) {
+       if((seq->flag & SEQ_FILTERY) && seq->type != SEQ_MOVIE) {
                IMB_filtery(se->ibuf);
        }
  
@@@ -1742,9 -1743,7 +1745,9 @@@ static void do_build_seq_ibuf(Sequence 
        } else if(seq->type == SEQ_IMAGE) {
                if(se->ok == STRIPELEM_OK && se->ibuf == 0) {
                        StripElem * s_elem = give_stripelem(seq, cfra);
 -                      BLI_join_dirfile(name, seq->strip->dir, s_elem->name);
 +                      
 +                      strncpy(name, seq->strip->dir, FILE_MAXDIR-1);
 +                      strncat(name, s_elem->name, FILE_MAXFILE-1);
                        BLI_convertstringcode(name, G.sce);
                        BLI_convertstringframe(name, G.scene->r.cfra);
                        if (!build_proxy_run) {
  
                        if (se->ibuf == 0) {
                                if(seq->anim==0) {
 -                                      BLI_join_dirfile(name, seq->strip->dir, seq->strip->stripdata->name);
 +                                      strncpy(name, seq->strip->dir, FILE_MAXDIR-1);
 +                                      strncat(name, seq->strip->stripdata->name, FILE_MAXFILE-1);
                                        BLI_convertstringcode(name, G.sce);
                                        BLI_convertstringframe(name, G.scene->r.cfra);
-                               
-                                       seq->anim = openanim(name, IB_rect);
+                                       
+                                       seq->anim = openanim(
+                                               name, IB_rect | 
+                                               ((seq->flag & SEQ_FILTERY) 
+                                                ? IB_animdeinterlace : 0));
                                }
                                if(seq->anim) {
                                        IMB_anim_set_preseek(seq->anim, seq->anim_preseek);
index f3d0d4f715ac1f6d856751235ea79a01b6cb5ffa,4422411b1c57bb561d36d28af821d9f7425d6cab..cb80d0b4fb04812e4ade5ba198f4f2ffc5732b40
@@@ -378,9 -378,6 +378,6 @@@ void space_set_commmandline_options(voi
                
        if ( (syshandle = SYS_GetSystem()) ) {
                /* User defined settings */
-               a= (U.gameflags & USER_VERTEX_ARRAYS);
-               SYS_WriteCommandLineInt(syshandle, "vertexarrays", a);
                a= (U.gameflags & USER_DISABLE_SOUND);
                SYS_WriteCommandLineInt(syshandle, "noaudio", a);
  
@@@ -437,9 -434,6 +434,6 @@@ static void SaveState(void
        if(G.f & G_TEXTUREPAINT)
                texpaint_enable_mipmap();
  
-       if(G.scene->camera==0 || G.scene->camera->type!=OB_CAMERA)
-               error("no (correct) camera");
        waitcursor(1);
  }
  
@@@ -2077,15 -2071,16 +2071,16 @@@ static void winqreadview3dspace(ScrAre
                                                        vgroup_operation_with_menu();
                                        }
                                }
-                               else if((G.qual==LR_SHIFTKEY))
+                               else if((G.qual==LR_SHIFTKEY)) {
                                        if(G.obedit) {
                                                if(G.obedit->type==OB_MESH)
                                                        select_mesh_group_menu();
                                        } 
                                        else if(ob && (ob->flag & OB_POSEMODE))
                                                pose_select_grouped_menu();
-                                       else
+                                       else if (ob)
                                                select_object_grouped_menu();
+                               }
                                else if((G.obedit==0) && G.qual==LR_ALTKEY) {
                                        if(okee("Clear location")) {
                                                clear_object('g');
@@@ -2974,8 -2969,11 +2969,11 @@@ static void winqreadipospace(ScrArea *s
                                do_ipo_selectbuttons();
                                doredraw= 1;
                        }
+                       else if(G.qual == LR_CTRLKEY) {
+                               if (sipo->showkey==0)
+                                       add_vert_ipo();
+                       }
                        else if(view2dmove(LEFTMOUSE)); /* only checks for sliders */
-                       else if((G.qual & LR_CTRLKEY) && (sipo->showkey==0)) add_vert_ipo();
                        else {
                                do {
                                        getmouseco_areawin(mval);
@@@ -3213,7 -3211,7 +3211,7 @@@ void initipo(ScrArea *sa
        sipo->v2d.min[0]= 0.01f;
        sipo->v2d.min[1]= 0.01f;
  
-       sipo->v2d.max[0]= 15000.0f;
+       sipo->v2d.max[0]= MAXFRAMEF;
        sipo->v2d.max[1]= 10000.0f;
        
        sipo->v2d.scroll= L_SCROLL+B_SCROLL;
@@@ -4254,15 -4252,11 +4252,11 @@@ void drawinfospace(ScrArea *sa, void *s
                uiDefButS(block, MENU, B_GLRESLIMITCHANGED, "GL Texture Clamp Off%x0|%l|GL Texture Clamp 8192%x8192|GL Texture Clamp 4096%x4096|GL Texture Clamp 2048%x2048|GL Texture Clamp 1024%x1024|GL Texture Clamp 512%x512|GL Texture Clamp 256%x256|GL Texture Clamp 128%x128",
                                                                                                        (xpos+edgsp+(5*mpref)+(5*midsp)),y4,mpref,buth, &(U.glreslimit), 0, 0, 0, 0, "Limit the texture size to save graphics memory");
                
-               uiDefButBitI(block, TOG, USER_VERTEX_ARRAYS, 0, "Vertex Arrays",
-                       (xpos+edgsp+(5*mpref)+(5*midsp)),y3,mpref,buth,
-                       &(U.gameflags), 0, 0, 0, 0, "Toggles between vertex arrays on (less reliable) and off (more reliable)");
                uiDefButI(block, NUM, 0, "Time Out ",
-                       (xpos+edgsp+(5*mpref)+(5*midsp)), y2, mpref, buth, 
+                       (xpos+edgsp+(5*mpref)+(5*midsp)), y3, mpref, buth, 
                        &U.textimeout, 0.0, 3600.0, 30, 2, "Time since last access of a GL texture in seconds after which it is freed. (Set to 0 to keep textures allocated)");
                uiDefButI(block, NUM, 0, "Collect Rate ",
-                       (xpos+edgsp+(5*mpref)+(5*midsp)), y1, mpref, buth, 
+                       (xpos+edgsp+(5*mpref)+(5*midsp)), y2, mpref, buth, 
                        &U.texcollectrate, 1.0, 3600.0, 30, 2, "Number of seconds between each run of the GL texture garbage collector.");
  
                /* *** */
@@@ -4922,7 -4916,7 +4916,7 @@@ static void winqreadseqspace(ScrArea *s
                        break;
                case HOMEKEY:
                        if((G.qual==0))
 -                              seq_home();
 +                              do_seq_buttons(B_SEQHOME);
                        break;
                case PADPERIOD: 
                        if(last_seq) {
                        }
                        break;
                case DKEY:
-                       if (G.qual == (LR_CTRLKEY|LR_SHIFTKEY))
+                       if (G.qual == (LR_CTRLKEY|LR_SHIFTKEY)) {
                                duplicate_marker();
-                       else if ((G.qual==LR_SHIFTKEY)) {
+                       else if ((G.qual==LR_SHIFTKEY)) {
                                if(sseq->mainb) break;
                                add_duplicate_seq();
+                       } else if (G.qual == 0) {
+                               set_filter_seq();
                        }
                        break;
                case EKEY:
                        if((G.qual==0))
                                transform_seq('e', 0);
                        break;
-               case FKEY:
-                       if((G.qual==0))
-                               set_filter_seq();
-                       break;
                case GKEY:
                        if (G.qual & LR_CTRLKEY)
                                transform_markers('g', 0);
                case HKEY: /* hide==mute? - not that nice but MKey us used for meta :/ */
                        if((G.qual==0)) {
                                seq_mute_sel(1);
 -                      } else if(G.qual==LR_ALTKEY) {
 +                      } else if((G.qual==LR_ALTKEY)) {
                                seq_mute_sel(0);
 -                      } else if(G.qual==LR_SHIFTKEY) {
 -                              seq_mute_sel(-1);
                        }
                        break;
                case XKEY:
                                        del_seq();
                        }
                        break;
 -              case PAD1: case PAD2: case PAD4: case PAD8:
 -                      seq_viewzoom(event, (G.qual & LR_SHIFTKEY)==0);
 -                      doredraw= 1;
 -                      break;
 -              }       
 +              }
        }
  
        if(doredraw) scrarea_queue_winredraw(curarea);
@@@ -5166,7 -5164,7 +5158,7 @@@ static void init_actionspace(ScrArea *s
        saction->v2d.min[0]= 0.0;
        saction->v2d.min[1]= 0.0;
  
-       saction->v2d.max[0]= 32000.0;
+       saction->v2d.max[0]= MAXFRAMEF;
        saction->v2d.max[1]= 1000.0;
        
        saction->v2d.minzoom= 0.01;
@@@ -5238,7 -5236,7 +5230,7 @@@ static void init_soundspace(ScrArea *sa
        ssound->v2d.min[0]= 1.0;
        ssound->v2d.min[1]= 259.0;
  
-       ssound->v2d.max[0]= 32000.0;
+       ssound->v2d.max[0]= MAXFRAMEF;
        ssound->v2d.max[1]= 259;
        
        ssound->v2d.minzoom= 0.1f;
@@@ -5968,7 -5966,7 +5960,7 @@@ static void init_nlaspace(ScrArea *sa
        snla->v2d.min[0]= 0.0;
        snla->v2d.min[1]= 0.0;
        
-       snla->v2d.max[0]= 1000.0;
+       snla->v2d.max[0]= MAXFRAMEF;
        snla->v2d.max[1]= 1000.0;
        
        snla->v2d.minzoom= 0.1F;
@@@ -6056,7 -6054,7 +6048,7 @@@ static void init_timespace(ScrArea *sa
        stime->v2d.min[0]= 1.0;
        stime->v2d.min[1]= (float)sa->winy;
        
-       stime->v2d.max[0]= 32000.0;
+       stime->v2d.max[0]= MAXFRAMEF;
        stime->v2d.max[1]= (float)sa->winy;
        
        stime->v2d.minzoom= 0.1f;
@@@ -6325,7 -6323,10 +6317,10 @@@ void duplicatespacelist(ScrArea *neware
                        SpaceNode *snode= (SpaceNode *)sl;
                        snode->nodetree= NULL;
                }
+               else if(sl->spacetype==SPACE_SCRIPT) {
+                       SpaceScript *sc = ( SpaceScript * ) sl;
+                       sc->but_refs = NULL;
+               }
                sl= sl->next;
        }
        
index b7029c3225be6bb20b6cf17cb3f479256a2c9a4a,2a4672e3052268b30c109e2f8414f4d5798e829a..3e85083ec39dd6da1feafad686b3eccd0cb26472
@@@ -641,6 -641,10 +641,6 @@@ int BIF_read_homefile(int from_memory
        BKE_reset_undo();
        BKE_write_undo("original");     /* save current state */
        
 -      /* if from memory, need to refresh python scripts */
 -      if (from_memory) {
 -              BPY_path_update();
 -      }
        return success;
  }
  
@@@ -921,7 -925,7 +921,7 @@@ void BIF_write_file(char *target
  
                writeBlog();
        } else {
-               error("%s", err);
+               error("failed to write blend file: %s", err);
        }
  
        waitcursor(0);
@@@ -936,7 -940,10 +936,10 @@@ void BIF_write_homefile(void
                
        /*  force save as regular blend file */
        write_flags = G.fileflags & ~(G_FILE_COMPRESS | G_FILE_LOCK | G_FILE_SIGN);
-       BLO_write_file(tstr, write_flags, &err);
+       
+       if (!BLO_write_file(tstr, write_flags, &err)) {
+               error("failed writing defaults: %s", err);
+       }
  }
  
  void BIF_write_autosave(void)
  
                /*  force save as regular blend file */
        write_flags = G.fileflags & ~(G_FILE_COMPRESS | G_FILE_LOCK | G_FILE_SIGN);
-       BLO_write_file(tstr, write_flags, &err);
+       if (!BLO_write_file(tstr, write_flags, &err)) {
+               fprintf(stderr, "failed to write autosave: %s\n", err); /* using error(...) is too annoying here */
+       }
  }
  
  /* remove temp files assosiated with this blend file when quitting, loading or saving in a new path */
@@@ -1029,6 -1038,7 +1034,7 @@@ void BIF_init(void
        BIF_filelist_init_icons();
  
        init_gl_stuff();        /* drawview.c, after homefile */
+       glewInit();
        readBlog();
        BLI_strncpy(G.lib, G.sce, FILE_MAX);
  }
index 944fcea3a519beb09953704b2c4cb39e91104f0a,3b2367d25927df9c9c0aee1a47490c4953b14f37..748ff96e58ef5ddfd59f53a62eebe3818872b127
@@@ -33,6 -33,7 +33,6 @@@ incs = ['.'
          '#source/blender',
          '#source/blender/include',
          '#source/blender/makesdna',
 -        '#source/gameengine/BlenderRoutines',
          '#source/gameengine/Rasterizer',
          '#source/gameengine/GameLogic',
          '#source/gameengine/Expressions',
@@@ -44,7 -45,8 +44,8 @@@
          '#source/gameengine/Network/LoopBackNetwork',
          '#source/gameengine/GamePlayer/ghost',
          '#source/blender/misc',
-         '#source/blender/blenloader']
+         '#source/blender/blenloader',
+               '#extern/glew/include']
                                  
  #This is all plugin stuff!
  #if sys.platform=='win32':
index cc2d7de8002795e865a9222c9c6877ada4bc01cb,f3cce6c7443a716818fb4d8f6ee2aef758a9fbbb..01058dc3c43ecb18fd7c9df705a3275007dff040
@@@ -27,6 -27,7 +27,6 @@@ incs = ['.'
          '#source/blender',
          '#source/blender/include',
          '#source/blender/makesdna',
 -        '#source/gameengine/BlenderRoutines',
          '#source/gameengine/Rasterizer',
          '#source/gameengine/GameLogic',
          '#source/gameengine/Expressions',
@@@ -38,7 -39,8 +38,8 @@@
          '#source/gameengine/Network/LoopBackNetwork',
          '#source/gameengine/GamePlayer/common',
          '#source/blender/misc',
-         '#source/blender/blenloader']
+         '#source/blender/blenloader',
+         '#extern/glew/include']
  
  incs += Split(env['BF_PYTHON_INC'])
  incs += Split(env['BF_SOLID_INC'])
index fbd896a55d13996faff54546bd901c0a1d0c897a,37c188b7f2249cdfa2ae8ded824f592b92d942de..cc2fdeb0ffe0c15aa3898def2a314ab84e46377c
@@@ -22,12 -22,38 +22,38 @@@ class KX_GameObject
        @type orientation: 3x3 Matrix [[float]]
        @ivar scaling: The object's scaling factor. list [sx, sy, sz]
        @type scaling: list [sx, sy, sz]
+       @ivar timeOffset: adjust the slowparent delay at runtime.
+       @type timeOffset: float
        """
-       
+       def endObject(visible):
+               """
+               Delete this object, can be used inpace of the EndObject Actuator.
+               The actual removal of the object from the scene is delayed.
+               """     
+       def getVisible(visible):
+               """
+               Gets the game object's visible flag.
+               
+               @type visible: boolean
+               """     
        def setVisible(visible):
                """
                Sets the game object's visible flag.
                
+               @type visible: boolean
+               """
+       def getState():
+               """
+               Gets the game object's state bitmask.
+               
+               @rtype: int
+               @return: the objects state.
+               """     
+       def setState():
+               """
+               Sets the game object's visible flag.
+               The bitmasks for states from 1 to 30 can be set with (1<<0, 1<<1, 1<<2 ... 1<<29)
+               
                @type visible: boolean
                """
        def setPosition(pos):
                
                @type orn: 3x3 rotation matrix, or Quaternion.
                @param orn: a rotation matrix specifying the new rotation.
 -      def alignAxisToVect(vect, axis):
 -              """
 -              Aligns any of the game object's axis along the given vector.
 -              
 -              @type vect: 3d vector.
 -              @param vect: a vector to align the axis.
 -              @type axis: integer.
 -              @param axis:The axis you want to align
 -                                      - 0: X axis
 -                                      - 1: Y axis
 -                                      - 2: Z axis (default) 
 -              """
+               @note: When using this matrix with Blender.Mathutils.Matrix() types, it will need to be transposed.
+               """
+       def getAxisVect(vect):
+               """
+               Returns the axis vector rotates by the objects worldspace orientation.
+               This is the equivalent if multiplying the vector by the orientation matrix.
+               
+               @type vect: 3d vector.
+               @param vect: a vector to align the axis.
+               @rtype: 3d vector.
+               @return: The vector in relation to the objects rotation.
                """
        def getOrientation():
                """
                
                @rtype: 3x3 rotation matrix
                @return: The game object's rotation matrix
+               @note: When using this matrix with Blender.Mathutils.Matrix() types, it will need to be transposed.
                """
-       def getLinearVelocity(local):
+       def getLinearVelocity(local = 0):
                """
                Gets the game object's linear velocity.
                
                ie no angular velocity component.
                
                @type local: boolean
-               @param local: - False: you get the "global" velocity ie: relative to world orientation.
+               @param local: - False: you get the "global" velocity ie: relative to world orientation (default).
                              - True: you get the "local" velocity ie: relative to object orientation.
                @rtype: list [vx, vy, vz]
                @return: the object's linear velocity.
                """
+       def setLinearVelocity(velocity, local = 0):
+               """
+               Sets the game object's linear velocity.
+               
+               This method sets game object's velocity through it's centre of mass,
+               ie no angular velocity component.
+               
+               @type velocity: 3d vector.
+               @param velocity: linear velocity vector.
+               @type local: boolean
+               @param local: - False: you get the "global" velocity ie: relative to world orientation (default).
+                             - True: you get the "local" velocity ie: relative to object orientation.
+               """
        def getVelocity(point):
                """
                Gets the game object's velocity at the specified point.
        def restoreDynamics():
                """
                Resumes physics for this object.
+               @Note: The objects linear velocity will be applied from when the dynamics were suspended.
                """
        def enableRigidBody():
                """
                Enables rigid body physics for this object.
                
                Rigid body physics allows the object to roll on collisions.
+               @Note: This is not working with bullet physics yet.
                """
        def disableRigidBody():
                """
                Disables rigid body physics for this object.
+               @Note: This is not working with bullet physics yet. The angular is removed but rigid body physics can still rotate it later.
                """
        def getParent():
                """
                """
                Returns the user data object associated with this game object's physics controller.
                """
+       def getPropertyNames():
+               """
+               Gets a list of all property names.
+               @rtype: list
+               @return: All property names for this object.
+               """
        def getDistanceTo(other):
                """
                Returns the distance to another object or point.
                If is casted from/to object center or explicit [x,y,z] points.
                The ray does not have X-Ray capability: the first object hit (other than self object) stops the ray
                If a property was specified and the first object hit does not have that property, there is no hit
-               The     ray ignores collision-free objects
+               The     ray ignores collision-free objects and faces that dont have the collision flag enabled, you can however use ghost objects.
  
                @param to: [x,y,z] or object to which the ray is casted
                @type to: L{KX_GameObject} or 3-tuple
                @rtype: 3-tuple (L{KX_GameObject}, 3-tuple (x,y,z), 3-tuple (nx,ny,nz))
                @return: (object,hitpoint,hitnormal) or (None,None,None)
                """
 -
 -
 +