Merged changes in the trunk up to revision 42116.
authorTamito Kajiyama <rd6t-kjym@asahi-net.or.jp>
Sat, 26 Nov 2011 13:11:55 +0000 (13:11 +0000)
committerTamito Kajiyama <rd6t-kjym@asahi-net.or.jp>
Sat, 26 Nov 2011 13:11:55 +0000 (13:11 +0000)
131 files changed:
1  2 
build_files/buildbot/master.cfg
build_files/buildbot/slave_pack.py
build_files/scons/tools/Blender.py
build_files/scons/tools/btools.py
doc/python_api/examples/bge.texture.1.py
doc/python_api/sphinx_doc_gen.py
extern/libmv/SConscript
intern/cycles/SConscript
intern/cycles/blender/CMakeLists.txt
intern/cycles/blender/addon/properties.py
intern/cycles/blender/addon/ui.py
intern/cycles/blender/addon/xml.py
release/scripts/modules/addon_utils.py
release/scripts/modules/bpy/utils.py
release/scripts/modules/console/complete_calltip.py
release/scripts/presets/camera/Nikon_D3S.py
release/scripts/startup/bl_operators/clip.py
release/scripts/startup/bl_ui/properties_data_modifier.py
release/scripts/startup/bl_ui/properties_render.py
release/scripts/startup/bl_ui/space_clip.py
release/scripts/startup/bl_ui/space_view3d.py
source/blender/blenfont/intern/blf_dir.c
source/blender/blenkernel/BKE_DerivedMesh.h
source/blender/blenkernel/BKE_image.h
source/blender/blenkernel/BKE_material.h
source/blender/blenkernel/BKE_particle.h
source/blender/blenkernel/BKE_pointcache.h
source/blender/blenkernel/intern/CCGSubSurf.c
source/blender/blenkernel/intern/DerivedMesh.c
source/blender/blenkernel/intern/blender.c
source/blender/blenkernel/intern/curve.c
source/blender/blenkernel/intern/dynamicpaint.c
source/blender/blenkernel/intern/image.c
source/blender/blenkernel/intern/material.c
source/blender/blenkernel/intern/movieclip.c
source/blender/blenkernel/intern/object.c
source/blender/blenkernel/intern/packedFile.c
source/blender/blenkernel/intern/particle.c
source/blender/blenkernel/intern/pointcache.c
source/blender/blenkernel/intern/scene.c
source/blender/blenkernel/intern/sequencer.c
source/blender/blenkernel/intern/subsurf_ccg.c
source/blender/blenkernel/intern/text.c
source/blender/blenlib/intern/DLRB_tree.c
source/blender/blenlib/intern/path_util.c
source/blender/blenlib/intern/pbvh.c
source/blender/blenlib/intern/storage.c
source/blender/blenlib/intern/winstuff.c
source/blender/blenloader/intern/readfile.c
source/blender/blenloader/intern/readfile.h
source/blender/blenloader/intern/writefile.c
source/blender/editors/gpencil/drawgpencil.c
source/blender/editors/gpencil/gpencil_paint.c
source/blender/editors/include/UI_interface.h
source/blender/editors/interface/interface.c
source/blender/editors/interface/interface_draw.c
source/blender/editors/interface/interface_handlers.c
source/blender/editors/interface/interface_icons.c
source/blender/editors/interface/interface_regions.c
source/blender/editors/interface/interface_style.c
source/blender/editors/mesh/editmesh_tools.c
source/blender/editors/object/object_add.c
source/blender/editors/physics/physics_fluid.c
source/blender/editors/physics/physics_pointcache.c
source/blender/editors/render/render_opengl.c
source/blender/editors/render/render_shading.c
source/blender/editors/screen/screendump.c
source/blender/editors/space_console/space_console.c
source/blender/editors/space_file/filelist.c
source/blender/editors/space_file/fsmenu.c
source/blender/editors/space_image/image_ops.c
source/blender/editors/space_nla/nla_buttons.c
source/blender/editors/space_node/node_draw.c
source/blender/editors/space_outliner/outliner_tools.c
source/blender/editors/space_sequencer/sequencer_draw.c
source/blender/editors/space_text/text_ops.c
source/blender/editors/space_view3d/drawobject.c
source/blender/editors/space_view3d/view3d_buttons.c
source/blender/editors/space_view3d/view3d_draw.c
source/blender/editors/transform/transform.c
source/blender/editors/util/ed_util.c
source/blender/editors/uvedit/uvedit_draw.c
source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.cpp
source/blender/freestyle/intern/python/BPy_Convert.cpp
source/blender/freestyle/intern/python/BPy_Freestyle.cpp
source/blender/gpu/CMakeLists.txt
source/blender/imbuf/intern/IMB_indexer.h
source/blender/imbuf/intern/indexer.c
source/blender/imbuf/intern/jpeg.c
source/blender/makesdna/DNA_curve_types.h
source/blender/makesdna/DNA_scene_types.h
source/blender/makesdna/DNA_userdef_types.h
source/blender/makesdna/intern/makesdna.c
source/blender/makesrna/RNA_access.h
source/blender/makesrna/RNA_define.h
source/blender/makesrna/RNA_enum_types.h
source/blender/makesrna/intern/rna_define.c
source/blender/makesrna/intern/rna_image_api.c
source/blender/makesrna/intern/rna_main_api.c
source/blender/makesrna/intern/rna_mesh.c
source/blender/makesrna/intern/rna_object_force.c
source/blender/makesrna/intern/rna_scene.c
source/blender/makesrna/intern/rna_tracking.c
source/blender/makesrna/intern/rna_userdef.c
source/blender/modifiers/intern/MOD_fluidsim_util.c
source/blender/nodes/composite/nodes/node_composite_mixrgb.c
source/blender/nodes/shader/nodes/node_shader_mixRgb.c
source/blender/nodes/texture/nodes/node_texture_bricks.c
source/blender/nodes/texture/nodes/node_texture_mixRgb.c
source/blender/nodes/texture/nodes/node_texture_proc.c
source/blender/nodes/texture/nodes/node_texture_texture.c
source/blender/python/intern/bpy_interface.c
source/blender/python/intern/bpy_rna.c
source/blender/python/mathutils/mathutils_Euler.c
source/blender/python/mathutils/mathutils_Matrix.c
source/blender/python/mathutils/mathutils_Quaternion.c
source/blender/render/extern/include/RE_pipeline.h
source/blender/render/intern/source/pipeline.c
source/blender/render/intern/source/pixelshading.c
source/blender/render/intern/source/render_texture.c
source/blender/render/intern/source/shadeoutput.c
source/blender/windowmanager/intern/wm_files.c
source/blender/windowmanager/intern/wm_gesture.c
source/blender/windowmanager/intern/wm_operators.c
source/blenderplayer/bad_level_call_stubs/stubs.c
source/creator/CMakeLists.txt
source/creator/creator.c
source/gameengine/GamePlayer/ghost/GPG_ghost.cpp
source/gameengine/Ketsji/KX_PythonInit.cpp
source/gameengine/VideoTexture/Texture.cpp
source/tests/pep8.py

@@@ -75,14 -75,14 +75,14 @@@ def svn_step(branch='')
          return SVN(baseURL='https://svn.blender.org/svnroot/bf-blender/%%BRANCH%%/blender', mode='update', defaultBranch='trunk', workdir='blender')
  
  
--def lib_svn_step(dir):
--    return SVN(name='lib svn', baseURL='https://svn.blender.org/svnroot/bf-blender/%%BRANCH%%/lib/' + dir, mode='update', defaultBranch='trunk', workdir='lib/' + dir)
++def lib_svn_step(libdir):
++    return SVN(name='lib svn', baseURL='https://svn.blender.org/svnroot/bf-blender/%%BRANCH%%/lib/' + libdir, mode='update', defaultBranch='trunk', workdir='lib/' + libdir)
  
  # generic builder
  
  
--def generic_builder(id, libdir='', branch=''):
--    filename = 'buildbot_upload_' + id + '.zip'
++def generic_builder(idname, libdir='', branch=''):
++    filename = 'buildbot_upload_' + idname + '.zip'
      compile_script = '../blender/build_files/buildbot/slave_compile.py'
      test_script = '../blender/build_files/buildbot/slave_test.py'
      pack_script = '../blender/build_files/buildbot/slave_pack.py'
      if libdir != '':
          f.addStep(lib_svn_step(libdir))
  
--    f.addStep(Compile(command=['python', compile_script, id]))
--    f.addStep(Test(command=['python', test_script, id]))
--    f.addStep(ShellCommand(name='package', command=['python', pack_script, id, branch], description='packaging', descriptionDone='packaged'))
--    if id.find('cmake') != -1:
++    f.addStep(Compile(command=['python', compile_script, idname]))
++    f.addStep(Test(command=['python', test_script, idname]))
++    f.addStep(ShellCommand(name='package', command=['python', pack_script, idname, branch], description='packaging', descriptionDone='packaged'))
++    if 'cmake' in idname:
          f.addStep(FileUpload(name='upload', slavesrc='buildbot_upload.zip', masterdest=filename, maxsize=100 * 1024 * 1024))
      else:
          f.addStep(FileUpload(name='upload', slavesrc='buildbot_upload.zip', masterdest=filename, maxsize=100 * 1024 * 1024, workdir='install'))
@@@ -84,12 -84,12 +84,12 @@@ if builder.find('scons') != -1
          sys.exit(retcode)
  
  # clean release directory if it already exists
--dir = 'release'
++release_dir = 'release'
  
--if os.path.exists(dir):
--    for f in os.listdir(dir):
--        if os.path.isfile(os.path.join(dir, f)):
--            os.remove(os.path.join(dir, f))
++if os.path.exists(release_dir):
++    for f in os.listdir(release_dir):
++        if os.path.isfile(os.path.join(release_dir, f)):
++            os.remove(os.path.join(release_dir, f))
  
  # create release package
  try:
@@@ -99,16 -99,16 +99,16 @@@ except Exception, ex
      sys.exit(1)
  
  # find release directory, must exist this time
--if not os.path.exists(dir):
--    sys.stderr.write("Failed to find release directory.\n")
++if not os.path.exists(release_dir):
++    sys.stderr.write("Failed to find release directory %r.\n" % release_dir)
      sys.exit(1)
  
  # find release package
  file = None
  filepath = None
  
--for f in os.listdir(dir):
--    rf = os.path.join(dir, f)
++for f in os.listdir(release_dir):
++    rf = os.path.join(release_dir, f)
      if os.path.isfile(rf) and f.startswith('blender'):
          file = f
          filepath = rf
@@@ -316,12 -316,9 +316,9 @@@ def propose_priorities()
  def creator(env):
      sources = ['creator.c']# + Blender.buildinfo(env, "dynamic") + Blender.resources
  
 -    incs = ['#/intern/guardedalloc', '#/source/blender/blenlib', '#/source/blender/blenkernel', '#/source/blender/editors/include', '#/source/blender/blenloader', '#/source/blender/imbuf', '#/source/blender/renderconverter', '#/source/blender/render/extern/include', '#/source/blender/windowmanager', '#/source/blender/makesdna', '#/source/blender/makesrna', '#/source/gameengine/BlenderRoutines', '#/extern/glew/include', '#/source/blender/gpu', env['BF_OPENGL_INC']]
 +    incs = ['#/intern/guardedalloc', '#/source/blender/blenlib', '#/source/blender/blenkernel', '#/source/blender/editors/include', '#/source/blender/blenloader', '#/source/blender/imbuf', '#/source/blender/renderconverter', '#/source/blender/render/extern/include', '#/source/blender/windowmanager', '#/source/blender/makesdna', '#/source/blender/makesrna', '#/source/gameengine/BlenderRoutines', '#/extern/glew/include', '#/source/blender/gpu', '#/source/blender/freestyle', env['BF_OPENGL_INC']]
  
      defs = []
-     if env['WITH_BF_QUICKTIME']:
-         incs.append(env['BF_QUICKTIME_INC'])
-         defs.append('WITH_QUICKTIME')
  
      if env['WITH_BF_BINRELOC']:
          incs.append('#/extern/binreloc/include')
@@@ -544,6 -544,6 +544,7 @@@ def read_opts(env, cfg, args)
  
      localopts.AddVariables(
          (BoolVariable('WITH_BF_CYCLES', 'Build with the Cycles engine', True)),
++        (BoolVariable('WITH_BF_CYCLES_BINARIES', 'Build with precompiled CUDA binaries', False)),
  
          (BoolVariable('WITH_BF_OIIO', 'Build with OpenImageIO', False)),
          (BoolVariable('WITH_BF_STATICOIIO', 'Staticly link to OpenImageIO', False)),
@@@ -11,13 -11,13 +11,13 @@@ from bge import textur
  
  def createTexture(cont):
      """Create a new Dynamic Texture"""
--    object = cont.owner
++    obj = cont.owner
  
      # get the reference pointer (ID) of the internal texture
--    ID = texture.materialID(object, 'IMoriginal.png')
++    ID = texture.materialID(obj, 'IMoriginal.png')
  
      # create a texture object
--    object_texture = texture.Texture(object, ID)
++    object_texture = texture.Texture(obj, ID)
  
      # create a new source with an external image
      url = logic.expandPath("//newtexture.jpg")
@@@ -111,6 -110,6 +111,12 @@@ INFO_DOCS = 
      ("info_gotcha.rst", "Gotcha's: some of the problems you may come up against when writing scripts"),
      )
  
++# only support for properties atm.
++RNA_BLACKLIST = {
++    # messes up PDF!, really a bug but for now just workaround.
++    "UserPreferencesSystem": {"language", },
++    }
++
  
  # -----------------------------------------------------------------------------
  # configure compile time options
@@@ -765,22 -757,22 +771,23 @@@ def pyrna2sphinx(BASEPATH)
          fw = file.write
  
          base_id = getattr(struct.base, "identifier", "")
++        struct_id = struct.identifier
  
          if _BPY_STRUCT_FAKE:
              if not base_id:
                  base_id = _BPY_STRUCT_FAKE
  
          if base_id:
--            title = "%s(%s)" % (struct.identifier, base_id)
++            title = "%s(%s)" % (struct_id, base_id)
          else:
--            title = struct.identifier
++            title = struct_id
  
          write_title(fw, title, "=")
  
          fw(".. module:: bpy.types\n\n")
  
          # docs first?, ok
--        write_example_ref("", fw, "bpy.types.%s" % struct.identifier)
++        write_example_ref("", fw, "bpy.types.%s" % struct_id)
  
          base_ids = [base.identifier for base in struct.get_bases()]
  
                  base_id = _BPY_STRUCT_FAKE
  
          if base_id:
--            fw(".. class:: %s(%s)\n\n" % (struct.identifier, base_id))
++            fw(".. class:: %s(%s)\n\n" % (struct_id, base_id))
          else:
--            fw(".. class:: %s\n\n" % struct.identifier)
++            fw(".. class:: %s\n\n" % struct_id)
  
          fw("   %s\n\n" % struct.description)
  
          sorted_struct_properties = struct.properties[:]
          sorted_struct_properties.sort(key=lambda prop: prop.identifier)
  
++        # support blacklisting props
++        struct_blacklist = RNA_BLACKLIST.get(struct_id, ())
++
          for prop in sorted_struct_properties:
++
++            # support blacklisting props
++            if prop.identifier in struct_blacklist:
++                continue
++
              type_descr = prop.get_type_description(class_fmt=":class:`%s`", collection_id=_BPY_PROP_COLLECTION_ID)
              # readonly properties use "data" directive, variables properties use "attribute" directive
              if 'readonly' in type_descr:
                          descr = prop.name
                      fw("         `%s`, %s, %s\n\n" % (prop.identifier, descr, type_descr))
  
--            write_example_ref("      ", fw, "bpy.types." + struct.identifier + "." + func.identifier)
++            write_example_ref("      ", fw, "bpy.types." + struct_id + "." + func.identifier)
  
              fw("\n")
  
          py_func = None
  
          for identifier, py_func in py_funcs:
--            py_c_func2sphinx("   ", fw, "bpy.types", struct.identifier, identifier, py_func, is_class=True)
++            py_c_func2sphinx("   ", fw, "bpy.types", struct_id, identifier, py_func, is_class=True)
  
          lines = []
  
              fw("\n")
  
          # docs last?, disable for now
--        # write_example_ref("", fw, "bpy.types.%s" % struct.identifier)
++        # write_example_ref("", fw, "bpy.types.%s" % struct_id)
          file.close()
  
      if "bpy.types" not in EXCLUDE_MODULES:
@@@ -46,16 -46,16 +46,16 @@@ if env['OURPLATFORM'] in ('win32-vc', '
              defs.append('NDEBUG')
      else:
          if not env['BF_DEBUG']:
--            cflags_libmv = Split(env['REL_CFLAGS'])
--            ccflags_libmv = Split(env['REL_CCFLAGS'])
--            cxxflags_libmv = Split(env['REL_CXXFLAGS'])
++            cflags_libmv += Split(env['REL_CFLAGS'])
++            ccflags_libmv += Split(env['REL_CCFLAGS'])
++            cxxflags_libmv += Split(env['REL_CXXFLAGS'])
  else:
      src += env.Glob("third_party/glog/src/*.cc")
      incs += ' ./third_party/glog/src'
      if not env['BF_DEBUG']:
--        cflags_libmv = Split(env['REL_CFLAGS'])
--        ccflags_libmv = Split(env['REL_CCFLAGS'])
--        cxxflags_libmv = Split(env['REL_CXXFLAGS'])
++        cflags_libmv += Split(env['REL_CFLAGS'])
++        ccflags_libmv += Split(env['REL_CCFLAGS'])
++        cxxflags_libmv += Split(env['REL_CXXFLAGS'])
  
  incs += ' ./third_party/ssba ./third_party/ldl/Include ../colamd/Include'
  
@@@ -22,6 -22,6 +22,9 @@@ defs.append('WITH_OPENCL'
  defs.append('WITH_MULTI')
  defs.append('WITH_CUDA')
  
++if env['WITH_BF_CYCLES_BINARIES']:
++    defs.append('WITH_CUDA_BINARIES')
++
  incs.extend('. bvh render device kernel kernel/osl kernel/svm util subd'.split())
  incs.extend('#intern/guardedalloc #source/blender/makesrna #source/blender/makesdna'.split())
  incs.extend('#source/blender/blenloader ../../source/blender/makesrna/intern'.split())
@@@ -6,7 -6,7 +6,7 @@@ set(IN
        ../kernel/svm
        ../util
        ../subd
--      ../../../intern/guardedalloc
++      ../../guardedalloc
        ../../../source/blender/makesdna
        ../../../source/blender/makesrna
        ../../../source/blender/blenloader
  # <pep8 compliant>
  
  import bpy
--from bpy.props import *
++from bpy.props import (BoolProperty,
++                       EnumProperty,
++                       FloatProperty,
++                       IntProperty,
++                       PointerProperty)
  
  import math
  
@@@ -349,7 -349,7 +349,7 @@@ def find_node(material, nodetype)
          ntree = material.node_tree
  
          for node in ntree.nodes:
--            if hasattr(node, 'type') and node.type == nodetype:
++            if getattr(node, "type", None) == nodetype:
                  return node
  
      return None
@@@ -363,14 -363,14 +363,14 @@@ def find_node_input(node, name)
      return None
  
  
--def panel_node_draw(layout, id, output_type, input_name):
--    if not id.node_tree:
--        layout.prop(id, "use_nodes", icon='NODETREE')
++def panel_node_draw(layout, id_data, output_type, input_name):
++    if not id_data.node_tree:
++        layout.prop(id_data, "use_nodes", icon='NODETREE')
          return False
  
--    ntree = id.node_tree
++    ntree = id_data.node_tree
  
--    node = find_node(id, output_type)
++    node = find_node(id_data, output_type)
      if not node:
          layout.label(text="No output node.")
      else:
@@@ -61,12 -61,12 +61,12 @@@ class ExportCyclesXML(bpy.types.Operato
  
          # get mesh
          scene = context.scene
--        object = context.object
++        obj = context.object
  
--        if not object:
++        if not obj:
              raise Exception("No active object")
  
--        mesh = object.to_mesh(scene, True, 'PREVIEW')
++        mesh = obj.to_mesh(scene, True, 'PREVIEW')
  
          if not mesh:
              raise Exception("No mesh data in active object")
@@@ -168,7 -171,7 +171,9 @@@ def modules(module_cache)
                      mod = None
  
              if mod is None:
--                mod = fake_module(mod_name, mod_path, force_support=force_support)
++                mod = fake_module(mod_name,
++                                  mod_path,
++                                  force_support=force_support)
                  if mod:
                      module_cache[mod_name] = mod
  
@@@ -263,7 -263,7 +263,7 @@@ def user_script_path()
          return None
  
  
--def script_paths(subdir=None, user_pref=True, all=False):
++def script_paths(subdir=None, user_pref=True, check_all=False):
      """
      Returns a list of valid script paths.
  
      :type subdir: string
      :arg user_pref: Include the user preference script path.
      :type user_pref: bool
--    :arg all: Include local, user and system paths rather just the paths
++    :arg check_all: Include local, user and system paths rather just the paths
         blender uses.
--    :type all: bool
++    :type check_all: bool
      :return: script paths.
      :rtype: list
      """
      else:
          user_script_path = None
  
--    if all:
++    if check_all:
          # all possible paths
          base_paths = tuple(_os.path.join(resource_path(res), "scripts")
                             for res in ('LOCAL', 'USER', 'SYSTEM'))
@@@ -343,7 -343,7 +343,7 @@@ def preset_paths(subdir)
      :rtype: list
      """
      dirs = []
--    for path in script_paths("presets", all=True):
++    for path in script_paths("presets", check_all=True):
          directory = _os.path.join(path, subdir)
          if not directory.startswith(path):
              raise Exception("invalid subdir given %r" % subdir)
@@@ -432,9 -432,9 +432,9 @@@ def keyconfig_set(filepath)
      keyconfigs_old = keyconfigs[:]
  
      try:
--        file = open(filepath)
--        exec(compile(file.read(), filepath, 'exec'), {"__file__": filepath})
--        file.close()
++        keyfile = open(filepath)
++        exec(compile(keyfile.read(), filepath, 'exec'), {"__file__": filepath})
++        keyfile.close()
      except:
          import traceback
          traceback.print_exc()
@@@ -72,7 -72,7 +72,7 @@@ def reduce_spaces(text)
      return RE_SPACE.sub(' ', text)
  
  
--def get_doc(object):
++def get_doc(obj):
      """Get the doc string or comments for an object.
  
      :param object: object
@@@ -82,7 -82,7 +82,7 @@@
      >>> get_doc(abs)
      'abs(number) -> number\\n\\nReturn the absolute value of the argument.'
      """
--    result = inspect.getdoc(object) or inspect.getcomments(object)
++    result = inspect.getdoc(obj) or inspect.getcomments(obj)
      return result and RE_EMPTY_LINE.sub('', result.rstrip()) or ''
  
  
  # <pep8 compliant>
  import bpy
  import os
--import shutil
  from bpy.types import Operator
- from bpy_extras.io_utils import unpack_list
 -from bpy_extras.io_utils import unpack_list, unpack_face_list
+ from mathutils import Vector, Matrix
+ def CLIP_spacees_walk(context, all_screens, tarea, tspace, callback, *args):
+     screens = bpy.data.screens if all_screens else [context.screen]
+     for screen in screens:
+         for area in screen.areas:
+             if area.type == tarea:
+                 for space in area.spaces:
+                     if space.type == tspace:
+                         callback(space, *args)
+ def CLIP_set_viewport_background(context, all_screens, clip, clip_user):
+     def set_background(space_v3d, clip, user):
+         bgpic = None
+         for x in space_v3d.background_images:
+             if x.source == 'MOVIE':
+                 bgpic = x
+                 break
+         if not bgpic:
+             bgpic = space_v3d.background_images.new()
+         bgpic.source = 'MOVIE'
+         bgpic.clip = clip
+         bgpic.clip_user.proxy_render_size = user.proxy_render_size
+         bgpic.clip_user.use_render_undistorted = True
+         bgpic.use_camera_clip = False
+         bgpic.view_axis = 'CAMERA'
+         space_v3d.show_background_images = True
+     CLIP_spacees_walk(context, all_screens, 'VIEW_3D', 'VIEW_3D',
+                       set_background, clip, clip_user)
  
  
  def CLIP_track_view_selected(sc, track):
@@@ -90,6 -128,6 +126,8 @@@ class CLIP_OT_bundles_to_mesh(Operator)
          return (sc.type == 'CLIP_EDITOR') and sc.clip
  
      def execute(self, context):
++        from bpy_extras.io_utils import unpack_list
++
          sc = context.space_data
          clip = sc.clip
  
@@@ -133,6 -171,6 +171,8 @@@ class CLIP_OT_delete_proxy(Operator)
          return wm.invoke_confirm(self, event)
  
      def _rmproxy(self, abspath):
++        import shutil
++
          if not os.path.exists(abspath):
              return
  
@@@ -332,3 -344,430 +346,432 @@@ object's movement caused by this constr
                  self._bake_object(scene, ob)
  
          return {'FINISHED'}
+ class CLIP_OT_setup_tracking_scene(Operator):
+     """Prepare scene for compositing 3D objects into this footage"""
+     bl_idname = "clip.setup_tracking_scene"
+     bl_label = "Setup Tracking Scene"
+     bl_options = {'UNDO', 'REGISTER'}
+     @classmethod
+     def poll(cls, context):
+         sc = context.space_data
+         if sc.type != 'CLIP_EDITOR':
+             return False
+         clip = sc.clip
+         return clip and clip.tracking.reconstruction.is_valid
+     @staticmethod
+     def _setupScene(context):
+         scene = context.scene
+         scene.active_clip = context.space_data.clip
+     @staticmethod
+     def _setupWorld(context):
+         scene = context.scene
+         world = scene.world
+         if not world:
+             world = bpy.data.worlds.new(name="World")
+             scene.world = world
+         world.light_settings.use_ambient_occlusion = True
+         world.light_settings.ao_blend_type = 'MULTIPLY'
+         world.light_settings.use_environment_light = True
+         world.light_settings.environment_energy = 0.1
+         world.light_settings.distance = 1.0
+         world.light_settings.sample_method = 'ADAPTIVE_QMC'
+         world.light_settings.samples = 7
+         world.light_settings.threshold = 0.005
+     @staticmethod
+     def _findOrCreateCamera(context):
+         scene = context.scene
+         if scene.camera:
+             return scene.camera
+         cam = bpy.data.cameras.new(name="Camera")
+         camob = bpy.data.objects.new(name="Camera", object_data=cam)
+         scene.objects.link(camob)
+         scene.camera = camob
+         camob.matrix_local = (Matrix.Translation((7.481, -6.508, 5.344)) *
+             Matrix.Rotation(0.815, 4, 'Z') *
+             Matrix.Rotation(0.011, 4, 'Y') *
+             Matrix.Rotation(1.109, 4, 'X'))
+         return camob
+     @staticmethod
+     def _setupCamera(context):
+         camob = CLIP_OT_setup_tracking_scene._findOrCreateCamera(context)
+         # Remove all constraints to be sure motion is fine
+         camob.constraints.clear()
+         # Append camera solver constraint
+         con = camob.constraints.new(type='CAMERA_SOLVER')
+         con.use_active_clip = True
+         con.influence = 1.0
+     @staticmethod
+     def _setupViewport(context):
+         sc = context.space_data
+         CLIP_set_viewport_background(context, True, sc.clip, sc.clip_user)
+     @staticmethod
+     def _setupRenderLayers(context):
+         scene = context.scene
+         rlayers = scene.render.layers
+         if not scene.render.layers.get("Foreground"):
+             if len(rlayers) == 1:
+                 fg = rlayers[0]
+                 fg.name = 'Foreground'
+             else:
+                 fg = scene.render.layers.new('Foreground')
+             fg.use_sky = False
+             fg.layers = [True] + [False] * 19
+             fg.layers_zmask = [False] * 10 + [True] + [False] * 9
+             fg.use_pass_vector = True
+         if not scene.render.layers.get("Background"):
+             bg = scene.render.layers.new('Background')
+             bg.use_pass_shadow = True
+             bg.use_pass_ambient_occlusion = True
+             bg.layers = [False] * 10 + [True] + [False] * 9
+     @staticmethod
+     def _findNode(tree, type):
+         for node in tree.nodes:
+             if node.type == type:
+                 return node
+         return None
+     @staticmethod
+     def _findOrCreateNode(tree, type):
+         node = CLIP_OT_setup_tracking_scene._findNode(tree, type)
+         if not node:
+             node = tree.nodes.new(type=type)
+         return node
+     @staticmethod
+     def _needSetupNodes(context):
+         scene = context.scene
+         tree = scene.node_tree
+         if not tree:
+             # No compositor node tree found, time to create it!
+             return True
+         for node in tree.nodes:
+             if node.type in {'MOVIECLIP', 'MOVIEDISTORTION'}:
+                 return False
+         return True
+     @staticmethod
+     def _offsetNodes(tree):
+         for a in tree.nodes:
+             for b in tree.nodes:
+                 if a != b and a.location == b.location:
+                     b.location += Vector((40.0, 20.0))
+     def _setupNodes(self, context):
+         if not self._needSetupNodes(context):
+             # compositor nodes were already setup or even changes already
+             # do nothing to prevent nodes damage
+             return
+         # Enable backdrop for all compositor spaces
+         def setup_space(space):
+             space.show_backdrop = True
+         CLIP_spacees_walk(context, True, 'NODE_EDITOR', 'NODE_EDITOR',
+                           setup_space)
+         sc = context.space_data
+         scene = context.scene
+         scene.use_nodes = True
+         tree = scene.node_tree
+         clip = sc.clip
+         need_stabilization = False
+         # create nodes
+         rlayer_fg = self._findOrCreateNode(tree, 'R_LAYERS')
+         rlayer_bg = tree.nodes.new(type='R_LAYERS')
+         composite = self._findOrCreateNode(tree, 'COMPOSITE')
+         movieclip = tree.nodes.new(type='MOVIECLIP')
+         distortion = tree.nodes.new(type='MOVIEDISTORTION')
+         if need_stabilization:
+             stabilize = tree.nodes.new(type='STABILIZE2D')
+         scale = tree.nodes.new(type='SCALE')
+         invert = tree.nodes.new(type='INVERT')
+         add_ao = tree.nodes.new(type='MIX_RGB')
+         add_shadow = tree.nodes.new(type='MIX_RGB')
+         mul_shadow = tree.nodes.new(type='MIX_RGB')
+         mul_image = tree.nodes.new(type='MIX_RGB')
+         vector_blur = tree.nodes.new(type='VECBLUR')
+         alphaover = tree.nodes.new(type='ALPHAOVER')
+         viewer = tree.nodes.new(type='VIEWER')
+         # setup nodes
+         movieclip.clip = clip
+         distortion.clip = clip
+         distortion.distortion_type = 'UNDISTORT'
+         if need_stabilization:
+             stabilize.clip = clip
+         scale.space = 'RENDER_SIZE'
+         rlayer_bg.scene = scene
+         rlayer_bg.layer = "Background"
+         rlayer_fg.scene = scene
+         rlayer_fg.layer = "Foreground"
+         add_ao.blend_type = 'ADD'
+         add_shadow.blend_type = 'ADD'
+         mul_shadow.blend_type = 'MULTIPLY'
+         mul_shadow.inputs['Fac'].default_value = 0.8
+         mul_image.blend_type = 'MULTIPLY'
+         mul_image.inputs['Fac'].default_value = 0.8
+         vector_blur.factor = 0.75
+         # create links
+         tree.links.new(movieclip.outputs['Image'], distortion.inputs['Image'])
+         if need_stabilization:
+             tree.links.new(distortion.outputs['Image'],
+                 stabilize.inputs['Image'])
+             tree.links.new(stabilize.outputs['Image'], scale.inputs['Image'])
+         else:
+             tree.links.new(distortion.outputs['Image'], scale.inputs['Image'])
+         tree.links.new(rlayer_bg.outputs['Alpha'], invert.inputs['Color'])
+         tree.links.new(invert.outputs['Color'], add_shadow.inputs[1])
+         tree.links.new(rlayer_bg.outputs['Shadow'], add_shadow.inputs[2])
+         tree.links.new(invert.outputs['Color'], add_ao.inputs[1])
+         tree.links.new(rlayer_bg.outputs['AO'], add_ao.inputs[2])
+         tree.links.new(add_ao.outputs['Image'], mul_shadow.inputs[1])
+         tree.links.new(add_shadow.outputs['Image'], mul_shadow.inputs[2])
+         tree.links.new(scale.outputs['Image'], mul_image.inputs[1])
+         tree.links.new(mul_shadow.outputs['Image'], mul_image.inputs[2])
+         tree.links.new(rlayer_fg.outputs['Image'], vector_blur.inputs['Image'])
+         tree.links.new(rlayer_fg.outputs['Z'], vector_blur.inputs['Z'])
+         tree.links.new(rlayer_fg.outputs['Speed'], vector_blur.inputs['Speed'])
+         tree.links.new(mul_image.outputs['Image'], alphaover.inputs[1])
+         tree.links.new(vector_blur.outputs['Image'], alphaover.inputs[2])
+         tree.links.new(alphaover.outputs['Image'], composite.inputs['Image'])
+         tree.links.new(alphaover.outputs['Image'], viewer.inputs['Image'])
+         # place nodes
+         movieclip.location = Vector((-300.0, 350.0))
+         distortion.location = movieclip.location
+         distortion.location += Vector((200.0, 0.0))
+         if need_stabilization:
+             stabilize.location = distortion.location
+             stabilize.location += Vector((200.0, 0.0))
+             scale.location = stabilize.location
+             scale.location += Vector((200.0, 0.0))
+         else:
+             scale.location = distortion.location
+             scale.location += Vector((200.0, 0.0))
+         rlayer_bg.location = movieclip.location
+         rlayer_bg.location -= Vector((0.0, 350.0))
+         invert.location = rlayer_bg.location
+         invert.location += Vector((250.0, 50.0))
+         add_ao.location = invert.location
+         add_ao.location[0] += 200
+         add_ao.location[1] = rlayer_bg.location[1]
+         add_shadow.location = add_ao.location
+         add_shadow.location -= Vector((0.0, 250.0))
+         mul_shadow.location = add_ao.location
+         mul_shadow.location += Vector((200.0, -50.0))
+         mul_image.location = mul_shadow.location
+         mul_image.location += Vector((300.0, 200.0))
+         rlayer_fg.location = rlayer_bg.location
+         rlayer_fg.location -= Vector((0.0, 500.0))
+         vector_blur.location[0] = mul_image.location[0]
+         vector_blur.location[1] = rlayer_fg.location[1]
+         alphaover.location[0] = vector_blur.location[0] + 350
+         alphaover.location[1] = \
+             (vector_blur.location[1] + mul_image.location[1]) / 2
+         composite.location = alphaover.location
+         composite.location += Vector((200.0, -100.0))
+         viewer.location = composite.location
+         composite.location += Vector((0.0, 200.0))
+         # ensure no nodes were creates on position of existing node
+         self._offsetNodes(tree)
+     @staticmethod
+     def _createMesh(scene, name, vertices, faces):
++        from bpy_extras.io_utils import unpack_list, unpack_face_list
++
+         mesh = bpy.data.meshes.new(name=name)
+         mesh.vertices.add(len(vertices))
+         mesh.vertices.foreach_set("co", unpack_list(vertices))
+         mesh.faces.add(len(faces))
+         mesh.faces.foreach_set("vertices_raw", unpack_face_list(faces))
+         mesh.update(calc_edges=True)
+         ob = bpy.data.objects.new(name=name, object_data=mesh)
+         scene.objects.link(ob)
+         return ob
+     @staticmethod
+     def _getPlaneVertices(half_size, z):
+         return [(-half_size, -half_size, z),
+                 (-half_size, half_size, z),
+                 (half_size, half_size, z),
+                 (half_size, -half_size, z)]
+     def _createGround(self, scene):
+         vertices = self._getPlaneVertices(4.0, 0.0)
+         faces = [(0, 1, 2, 3)]
+         ob = self._createMesh(scene, "Ground", vertices, faces)
+         ob["is_ground"] = True
+         return ob
+     @staticmethod
+     def _findGround(context):
+         scene = context.scene
+         for ob in scene.objects:
+             if ob.type == 'MESH' and "is_ground" in ob:
+                 return ob
+         return None
+     @staticmethod
+     def _mergeLayers(layers_a, layers_b):
+         return [(layers_a[i] | layers_b[i]) for i in range(len(layers_a))]
+     @staticmethod
+     def _createLamp(scene):
+         lamp = bpy.data.lamps.new(name="Lamp", type='POINT')
+         lampob = bpy.data.objects.new(name="Lamp", object_data=lamp)
+         scene.objects.link(lampob)
+         lampob.matrix_local = Matrix.Translation((4.076, 1.005, 5.904))
+         lamp.distance = 30
+         lamp.shadow_method = 'RAY_SHADOW'
+         return lampob
+     def _createSampleObject(self, scene):
+         vertices = self._getPlaneVertices(1.0, -1.0) + \
+             self._getPlaneVertices(1.0, 1.0)
+         faces = ((0, 1, 2, 3),
+                  (4, 7, 6, 5),
+                  (0, 4, 5, 1),
+                  (1, 5, 6, 2),
+                  (2, 6, 7, 3),
+                  (3, 7, 4, 0))
+         return self._createMesh(scene, "Cube", vertices, faces)
+     def _setupObjects(self, context):
+         scene = context.scene
+         fg = scene.render.layers.get("Foreground")
+         bg = scene.render.layers.get("Background")
+         all_layers = self._mergeLayers(fg.layers, bg.layers)
+         # enshure all lamps are active on foreground and background
+         has_lamp = False
+         has_mesh = False
+         for ob in scene.objects:
+             if ob.type == 'LAMP':
+                 ob.layers = all_layers
+                 has_lamp = True
+             elif ob.type == 'MESH' and "is_ground" not in ob:
+                 has_mesh = True
+         # create sample lamp if there's no lamps in the scene
+         if not has_lamp:
+             lamp = self._createLamp(scene)
+             lamp.layers = all_layers
+         # create sample object if there's no meshes in the scene
+         if not has_mesh:
+             ob = self._createSampleObject(scene)
+             ob.layers = fg.layers
+         # create ground object if needed
+         ground = self._findGround(context)
+         if not ground:
+             ground = self._createGround(scene)
+             ground.layers = bg.layers
+         else:
+             # make sure ground is available on Background layer
+             ground.layers = self._mergeLayers(ground.layers, bg.layers)
+         # layers with background and foreground should be rendered
+         scene.layers = self._mergeLayers(scene.layers, all_layers)
+     def execute(self, context):
+         self._setupScene(context)
+         self._setupWorld(context)
+         self._setupCamera(context)
+         self._setupViewport(context)
+         self._setupRenderLayers(context)
+         self._setupNodes(context)
+         self._setupObjects(context)
+         return {'FINISHED'}
@@@ -454,15 -454,15 +454,15 @@@ class DATA_PT_modifiers(ModifierButtons
          layout.separator()
  
          layout.prop(md, "use_normals")
--        
++
          split = layout.split()
--        
++
          col = split.column()
          col.prop(md, "use_foam")
          sub = col.row()
          sub.active = md.use_foam
          sub.prop(md, "foam_coverage", text="Coverage")
--        
++
          col = split.column()
          col.active = md.use_foam
          col.label("Foam Data Layer Name:")
@@@ -972,66 -452,19 +972,19 @@@ class RENDER_PT_output(RenderButtonsPan
          layout = self.layout
  
          rd = context.scene.render
-         file_format = rd.file_format
+         image_settings = rd.image_settings
+         file_format = rd.image_settings.file_format
  
          layout.prop(rd, "filepath", text="")
 -        
 +
-         split = layout.split()
-         col = split.column()
-         col.prop(rd, "file_format", text="")
-         col.row().prop(rd, "color_mode", text="Color", expand=True)
-         col = split.column()
-         col.prop(rd, "use_file_extension")
-         col.prop(rd, "use_overwrite")
-         col.prop(rd, "use_placeholder")
-         if file_format in {'AVI_JPEG', 'JPEG'}:
-             layout.prop(rd, "file_quality", slider=True)
-         if file_format == 'PNG':
-             layout.prop(rd, "file_quality", slider=True, text="Compression")
-         if file_format in {'OPEN_EXR', 'MULTILAYER'}:
-             row = layout.row()
-             row.prop(rd, "exr_codec", text="Codec")
-             if file_format == 'OPEN_EXR':
-                 row = layout.row()
-                 row.prop(rd, "use_exr_half")
-                 row.prop(rd, "exr_zbuf")
-                 row.prop(rd, "exr_preview")
-         elif file_format == 'JPEG2000':
-             split = layout.split()
-             col = split.column()
-             col.label(text="Depth:")
-             col.row().prop(rd, "jpeg2k_depth", expand=True)
-             col = split.column()
-             col.prop(rd, "jpeg2k_preset", text="")
-             col.prop(rd, "jpeg2k_ycc")
-         elif file_format in {'CINEON', 'DPX'}:
-             split = layout.split()
-             split.label("FIXME: hard coded Non-Linear, Gamma:1.0")
-             '''
-             col = split.column()
-             col.prop(rd, "use_cineon_log", text="Convert to Log")
-             col = split.column(align=True)
-             col.active = rd.use_cineon_log
-             col.prop(rd, "cineon_black", text="Black")
-             col.prop(rd, "cineon_white", text="White")
-             col.prop(rd, "cineon_gamma", text="Gamma")
-             '''
+         flow = layout.column_flow()
+         flow.prop(rd, "use_overwrite")
+         flow.prop(rd, "use_placeholder")
+         flow.prop(rd, "use_file_extension")
  
-         elif file_format == 'TIFF':
-             layout.prop(rd, "use_tiff_16bit")
+         layout.template_image_settings(rd.image_settings)
  
-         elif file_format == 'QUICKTIME_CARBON':
+         if file_format == 'QUICKTIME_CARBON':
              layout.operator("scene.render_data_set_quicktime_codec")
  
          elif file_format == 'QUICKTIME_QTKIT':
@@@ -475,7 -475,7 +475,7 @@@ class CLIP_PT_stabilization(Panel)
  
      def draw_header(self, context):
          stab = context.space_data.clip.tracking.stabilization
--        
++
          self.layout.prop(stab, "use_2d_stabilization", text="")
  
      def draw(self, context):
@@@ -1767,7 -1758,7 +1768,7 @@@ class VIEW3D_MT_edit_curve_ctrlpoints(M
          edit_object = context.edit_object
  
          if edit_object.type == 'CURVE':
--            layout.operator("transform.transform", text="Tilt").mode = 'TILT'
++            layout.operator("transform.tilt")
              layout.operator("curve.tilt_clear")
              layout.operator("curve.separate")
  
@@@ -129,7 -129,7 +129,7 @@@ void BLF_dir_free(char **dirs, int coun
  char *blf_dir_search(const char *file)
  {
        DirBLF *dir;
--      char full_path[FILE_MAXDIR+FILE_MAXFILE];
++      char full_path[FILE_MAX];
        char *s= NULL;
  
        for(dir=global_font_dir.first; dir; dir= dir->next) {
@@@ -526,7 -526,7 +526,7 @@@ int editmesh_get_first_deform_matrices(
  int sculpt_get_deform_matrices(struct Scene *scene, struct Object *ob,
                                                                float (**deformmats)[3][3], float (**deformcos)[3]);
  
--void weight_to_rgb(float input, float *fr, float *fg, float *fb);
++void weight_to_rgb(float r_rgb[3], const float weight);
  
  /* convert layers requested by a GLSL material to actually available layers in
   * the DerivedMesh, with both a pointer for arrays and an offset for editmesh */
@@@ -50,13 -51,21 +51,22 @@@ void       free_image(struct Image *me)
  void  BKE_stamp_info(struct Scene *scene, struct Object *camera, struct ImBuf *ibuf);
  void  BKE_stamp_buf(struct Scene *scene, struct Object *camera, unsigned char *rect, float *rectf, int width, int height, int channels);
  int           BKE_alphatest_ibuf(struct ImBuf *ibuf);
- int           BKE_write_ibuf_stamp(struct Scene *scene, struct Object *camera, struct ImBuf *ibuf, const char *name, int imtype, int subimtype, int quality);
- int           BKE_write_ibuf(struct ImBuf *ibuf, const char *name, int imtype, int subimtype, int quality);
- void  BKE_makepicstring(char *string, const char *base, const char *relbase, int frame, int imtype, const short use_ext, const short use_frames);
- int           BKE_add_image_extension(char *string, int imtype);
- int           BKE_ftype_to_imtype(int ftype);
- int           BKE_imtype_to_ftype(int imtype);
- int           BKE_imtype_is_movie(int imtype);
+ int           BKE_write_ibuf_stamp(struct Scene *scene, struct Object *camera, struct ImBuf *ibuf, const char *name, struct ImageFormatData *imf);
+ int           BKE_write_ibuf(struct ImBuf *ibuf, const char *name, struct ImageFormatData *imf);
++int     BKE_write_ibuf_as(struct ImBuf *ibuf, const char *name, struct ImageFormatData *imf, const short is_copy);
+ void  BKE_makepicstring(char *string, const char *base, const char *relbase, int frame, char imtype, const short use_ext, const short use_frames);
+ int           BKE_add_image_extension(char *string, const char imtype);
+ char  BKE_ftype_to_imtype(const int ftype);
+ int           BKE_imtype_to_ftype(char imtype);
+ int           BKE_imtype_is_movie(const char imtype);
 -int           BKE_imtype_supports_alpha(const char imtype);
+ int           BKE_imtype_supports_zbuf(const char imtype);
+ int           BKE_imtype_supports_compress(const char imtype);
+ int           BKE_imtype_supports_quality(const char imtype);
++char    BKE_imtype_valid_channels(const char imtype);
+ char  BKE_imtype_valid_depths(const char imtype);
+ char    BKE_imtype_from_arg(const char *arg);
  
  struct anim *openanim(const char *name, int flags, int streamindex);
  
@@@ -105,6 -114,6 +115,10 @@@ struct RenderResult
        /* image-user gets a new image, check settings */
  #define IMA_SIGNAL_USER_NEW_IMAGE     6
  
++#define IMA_CHAN_FLAG_BW    1
++#define IMA_CHAN_FLAG_RGB   2
++#define IMA_CHAN_FLAG_ALPHA 4
++
  /* depending Image type, and (optional) ImageUser setting it returns ibuf */
  /* always call to make signals work */
  struct ImBuf *BKE_image_get_ibuf(struct Image *ima, struct ImageUser *iuser);
@@@ -91,7 -91,7 +91,7 @@@ void end_render_materials(struct Main *
  
  int material_in_material(struct Material *parmat, struct Material *mat);
  
--void ramp_blend(int type, float *r, float *g, float *b, float fac, const float col[3]);
++void  ramp_blend(int type, float r_col[3], const float fac, const float col[3]);
  
  /* copy/paste */
  void clear_matcopybuf(void);
@@@ -217,7 -217,7 +217,7 @@@ typedef struct ParticleDrawData 
        float *ndata, *nd;              /* normal data */
        float *cdata, *cd;              /* color data */
        float *vedata, *ved;    /* velocity data */
--      float *ma_r, *ma_g, *ma_b;
++      float *ma_col;
        int tot_vec_size, flag;
        int totpoint, totve;
  } ParticleDrawData;
@@@ -127,6 -127,6 +127,9 @@@ typedef struct PTCacheID 
        unsigned int stack_index;
        unsigned int flag;
  
++      unsigned int default_step;
++      unsigned int max_step;
++
        /* flags defined in DNA_object_force.h */
        unsigned int data_types, info_types;
  
@@@ -2301,14 -2301,14 +2301,16 @@@ CCGError ccgSubSurf_stitchFaces(CCGSubS
        /* zero */
        for (i=0; i<numEffectedV; i++) {
                CCGVert *v = effectedV[i];
--              VertDataZero(VERT_getCo(v, lvl));
++              if(v->numFaces)
++                      VertDataZero(VERT_getCo(v, lvl));
        }
  
        for (i=0; i<numEffectedE; i++) {
                CCGEdge *e = effectedE[i];
  
--              for (x=0; x<edgeSize; x++)
--                      VertDataZero(EDGE_getCo(e, lvl, x));
++              if(e->numFaces)
++                      for (x=0; x<edgeSize; x++)
++                              VertDataZero(EDGE_getCo(e, lvl, x));
        }
  
        /* add */
        /* average */
        for (i=0; i<numEffectedV; i++) {
                CCGVert *v = effectedV[i];
--              VertDataMulN(VERT_getCo(v, lvl), 1.0f/v->numFaces);
++              if(v->numFaces)
++                      VertDataMulN(VERT_getCo(v, lvl), 1.0f/v->numFaces);
        }
  
        for (i=0; i<numEffectedE; i++) {
                VertDataCopy(EDGE_getCo(e, lvl, 0), VERT_getCo(e->v0, lvl));
                VertDataCopy(EDGE_getCo(e, lvl, edgeSize-1), VERT_getCo(e->v1, lvl));
  
--              for (x=1; x<edgeSize-1; x++)
--                      VertDataMulN(EDGE_getCo(e, lvl, x), 1.0f/e->numFaces);
++              if(e->numFaces)
++                      for (x=1; x<edgeSize-1; x++)
++                              VertDataMulN(EDGE_getCo(e, lvl, x), 1.0f/e->numFaces);
        }
  
        /* copy */
@@@ -1777,31 -1775,31 +1777,29 @@@ static void add_orco_dm(Object *ob, Edi
   * happens on enter/exit wpaint.
   */
  
--void weight_to_rgb(float input, float *fr, float *fg, float *fb)
++void weight_to_rgb(float r_rgb[3], const float weight)
  {
--      float blend;
--      
--      blend= ((input/2.0f)+0.5f);
--      
--      if (input<=0.25f){      // blue->cyan
--              *fr= 0.0f;
--              *fg= blend*input*4.0f;
--              *fb= blend;
++      const float blend= ((weight/2.0f)+0.5f);
++
++      if (weight<=0.25f){     // blue->cyan
++              r_rgb[0]= 0.0f;
++              r_rgb[1]= blend*weight*4.0f;
++              r_rgb[2]= blend;
        }
--      else if (input<=0.50f){ // cyan->green
--              *fr= 0.0f;
--              *fg= blend;
--              *fb= blend*(1.0f-((input-0.25f)*4.0f)); 
++      else if (weight<=0.50f){        // cyan->green
++              r_rgb[0]= 0.0f;
++              r_rgb[1]= blend;
++              r_rgb[2]= blend*(1.0f-((weight-0.25f)*4.0f));
        }
--      else if (input <= 0.75f){       // green->yellow
--              *fr= blend * ((input-0.50f)*4.0f);
--              *fg= blend;
--              *fb= 0.0f;
++      else if (weight <= 0.75f){      // green->yellow
++              r_rgb[0]= blend * ((weight-0.50f)*4.0f);
++              r_rgb[1]= blend;
++              r_rgb[2]= 0.0f;
        }
--      else if (input <= 1.0f){ // yellow->red
--              *fr= blend;
--              *fg= blend * (1.0f-((input-0.75f)*4.0f)); 
--              *fb= 0.0f;
++      else if (weight <= 1.0f){ // yellow->red
++              r_rgb[0]= blend;
++              r_rgb[1]= blend * (1.0f-((weight-0.75f)*4.0f));
++              r_rgb[2]= 0.0f;
        }
  }
  
@@@ -1866,7 -1864,7 +1864,7 @@@ static void calc_weightpaint_vert_color
        if(coba)
                do_colorband(coba, input, colf);
        else
--              weight_to_rgb(input, colf, colf+1, colf+2);
++              weight_to_rgb(colf, input);
        
        col[3] = (unsigned char)(colf[0] * 255.0f);
        col[2] = (unsigned char)(colf[1] * 255.0f);
@@@ -451,7 -451,7 +451,7 @@@ int blender_test_break(void
  #define MAXUNDONAME   64
  typedef struct UndoElem {
        struct UndoElem *next, *prev;
--      char str[FILE_MAXDIR+FILE_MAXFILE];
++      char str[FILE_MAX];
        char name[MAXUNDONAME];
        MemFile memfile;
        uintptr_t undosize;
@@@ -536,7 -536,7 +536,7 @@@ void BKE_write_undo(bContext *C, const 
        /* disk save version */
        if(UNDO_DISK) {
                static int counter= 0;
--              char filepath[FILE_MAXDIR+FILE_MAXFILE];
++              char filepath[FILE_MAX];
                char numstr[32];
                int fileflags = G.fileflags & ~(G_FILE_HISTORY); /* don't do file history on undo */
  
@@@ -702,7 -702,7 +702,7 @@@ void BKE_undo_save_quit(void
        UndoElem *uel;
        MemFileChunk *chunk;
        int file;
--      char str[FILE_MAXDIR+FILE_MAXFILE];
++      char str[FILE_MAX];
        
        if( (U.uiflag & USER_GLOBALUNDO)==0) return;
        
@@@ -169,6 -169,6 +169,7 @@@ Curve *add_curve(const char *name, int 
        cu->texflag= CU_AUTOSPACE;
        cu->smallcaps_scale= 0.75f;
        cu->twist_mode= CU_TWIST_MINIMUM;       // XXX: this one seems to be the best one in most cases, at least for curve deform...
++      cu->type= type;
        
        cu->bb= unit_boundbox();
        
@@@ -303,16 -303,16 +304,23 @@@ ListBase *curve_editnurbs(Curve *cu
  short curve_type(Curve *cu)
  {
        Nurb *nu;
++      int type= cu->type;
++
        if(cu->vfont) {
                return OB_FONT;
        }
--      for (nu= cu->nurb.first; nu; nu= nu->next) {
--              if(nu->pntsv>1) {
--                      return OB_SURF;
++
++      if(!cu->type) {
++              type= OB_CURVE;
++
++              for (nu= cu->nurb.first; nu; nu= nu->next) {
++                      if(nu->pntsv>1) {
++                              type= OB_SURF;
++                      }
                }
        }
--      
--      return OB_CURVE;
++
++      return type;
  }
  
  void update_curve_dimension(Curve *cu)
@@@ -1681,7 -1681,7 +1681,7 @@@ static struct DerivedMesh *dynamicPaint
                                                                        for (; j<((mface[i].v4)?4:3); j++) {
                                                                                int index = (j==0)?mface[i].v1: (j==1)?mface[i].v2: (j==2)?mface[i].v3: mface[i].v4;
  
--                                                                              weight_to_rgb(weight[index], temp_color, temp_color+1, temp_color+2);
++                                                                              weight_to_rgb(temp_color, weight[index]);
                                                                                col[i*4+j].r = FTOCHAR(temp_color[2]);
                                                                                col[i*4+j].g = FTOCHAR(temp_color[1]);
                                                                                col[i*4+j].b = FTOCHAR(temp_color[0]);
@@@ -840,67 -840,179 +840,194 @@@ int BKE_imtype_to_ftype(const char imty
                return JPG|90;
  }
  
int BKE_ftype_to_imtype(int ftype)
char BKE_ftype_to_imtype(const int ftype)
  {
        if(ftype==0)
-               return TGA;
+               return R_IMF_IMTYPE_TARGA;
        else if(ftype == IMAGIC) 
-               return R_IRIS;
+               return R_IMF_IMTYPE_IRIS;
  #ifdef WITH_HDR
        else if (ftype & RADHDR)
-               return R_RADHDR;
+               return R_IMF_IMTYPE_RADHDR;
  #endif
        else if (ftype & PNG)
-               return R_PNG;
+               return R_IMF_IMTYPE_PNG;
  #ifdef WITH_DDS
        else if (ftype & DDS)
-               return R_DDS;
+               return R_IMF_IMTYPE_DDS;
  #endif
        else if (ftype & BMP)
-               return R_BMP;
+               return R_IMF_IMTYPE_BMP;
  #ifdef WITH_TIFF
        else if (ftype & TIF)
-               return R_TIFF;
+               return R_IMF_IMTYPE_TIFF;
  #endif
        else if (ftype & OPENEXR)
-               return R_OPENEXR;
+               return R_IMF_IMTYPE_OPENEXR;
  #ifdef WITH_CINEON
        else if (ftype & CINEON)
-               return R_CINEON;
+               return R_IMF_IMTYPE_CINEON;
        else if (ftype & DPX)
-               return R_DPX;
+               return R_IMF_IMTYPE_DPX;
  #endif
        else if (ftype & TGA)
-               return R_TARGA;
+               return R_IMF_IMTYPE_TARGA;
        else if(ftype & RAWTGA)
-               return R_RAWTGA;
+               return R_IMF_IMTYPE_RAWTGA;
  #ifdef WITH_OPENJPEG
        else if(ftype & JP2)
-               return R_JP2;
+               return R_IMF_IMTYPE_JP2;
  #endif
        else
-               return R_JPEG90;
+               return R_IMF_IMTYPE_JPEG90;
+ }
+ int BKE_imtype_is_movie(const char imtype)
+ {
+       switch(imtype) {
+       case R_IMF_IMTYPE_AVIRAW:
+       case R_IMF_IMTYPE_AVIJPEG:
+       case R_IMF_IMTYPE_AVICODEC:
+       case R_IMF_IMTYPE_QUICKTIME:
+       case R_IMF_IMTYPE_FFMPEG:
+       case R_IMF_IMTYPE_H264:
+       case R_IMF_IMTYPE_THEORA:
+       case R_IMF_IMTYPE_XVID:
+       case R_IMF_IMTYPE_FRAMESERVER:
+                       return 1;
+       }
+       return 0;
+ }
 -int BKE_imtype_supports_alpha(const char imtype)
 -{
 -      switch(imtype) {
 -      case R_IMF_IMTYPE_TARGA:
 -      case R_IMF_IMTYPE_IRIS:
 -      case R_IMF_IMTYPE_PNG:
 -      /* case R_IMF_IMTYPE_BMP: */ /* read but not write */
 -      case R_IMF_IMTYPE_RADHDR:
 -      case R_IMF_IMTYPE_TIFF:
 -      case R_IMF_IMTYPE_OPENEXR:
 -      case R_IMF_IMTYPE_MULTILAYER:
 -      case R_IMF_IMTYPE_DDS:
 -      case R_IMF_IMTYPE_JP2:
 -                      return 1;
 -      }
 -      return 0;
 -}
 -
+ int BKE_imtype_supports_zbuf(const char imtype)
+ {
+       switch(imtype) {
+       case R_IMF_IMTYPE_IRIZ:
+       case R_IMF_IMTYPE_OPENEXR: /* but not R_IMF_IMTYPE_MULTILAYER */
+                       return 1;
+       }
+       return 0;
  }
  
+ int BKE_imtype_supports_compress(const char imtype)
+ {
+       switch(imtype) {
+       case R_IMF_IMTYPE_PNG:
+                       return 1;
+       }
+       return 0;
+ }
  
- int BKE_imtype_is_movie(int imtype)
+ int BKE_imtype_supports_quality(const char imtype)
  {
        switch(imtype) {
-       case R_AVIRAW:
-       case R_AVIJPEG:
-       case R_AVICODEC:
-       case R_QUICKTIME:
-       case R_FFMPEG:
-       case R_H264:
-       case R_THEORA:
-       case R_XVID:
-       case R_FRAMESERVER:
+       case R_IMF_IMTYPE_JPEG90:
+       case R_IMF_IMTYPE_JP2:
+       case R_IMF_IMTYPE_AVIJPEG:
                        return 1;
        }
        return 0;
  }
  
- int BKE_add_image_extension(char *string, int imtype)
++char BKE_imtype_valid_channels(const char imtype)
++{
++      char chan_flag= IMA_CHAN_FLAG_RGB; /* assume all support rgb */
++
++      /* alpha */
++      switch(imtype) {
++      case R_IMF_IMTYPE_TARGA:
++      case R_IMF_IMTYPE_IRIS:
++      case R_IMF_IMTYPE_PNG:
++      /* case R_IMF_IMTYPE_BMP: */ /* read but not write */
++      case R_IMF_IMTYPE_RADHDR:
++      case R_IMF_IMTYPE_TIFF:
++      case R_IMF_IMTYPE_OPENEXR:
++      case R_IMF_IMTYPE_MULTILAYER:
++      case R_IMF_IMTYPE_DDS:
++      case R_IMF_IMTYPE_JP2:
++                      chan_flag |= IMA_CHAN_FLAG_ALPHA;
++      }
++
++      /* bw */
++      switch(imtype) {
++      case R_IMF_IMTYPE_PNG:
++      case R_IMF_IMTYPE_JPEG90:
++      case R_IMF_IMTYPE_TARGA:
++      case R_IMF_IMTYPE_RAWTGA:
++      case R_IMF_IMTYPE_TIFF:
++      case R_IMF_IMTYPE_IRIS:
++                      chan_flag |= IMA_CHAN_FLAG_BW;
++      }
++
++      return chan_flag;
++}
++
+ char BKE_imtype_valid_depths(const char imtype)
+ {
+       switch (imtype) {
+       case R_IMF_IMTYPE_RADHDR:
+               return R_IMF_CHAN_DEPTH_32;
+       case R_IMF_IMTYPE_TIFF:
+               return R_IMF_CHAN_DEPTH_8 | R_IMF_CHAN_DEPTH_16;
+       case R_IMF_IMTYPE_OPENEXR:
+               return R_IMF_CHAN_DEPTH_16 | R_IMF_CHAN_DEPTH_32;
+       case R_IMF_IMTYPE_MULTILAYER:
+               return R_IMF_CHAN_DEPTH_32;
+       /* eeh, cineone does some strange 10bits per channel */
+       case R_IMF_IMTYPE_DPX:
+       case R_IMF_IMTYPE_CINEON:
+               return R_IMF_CHAN_DEPTH_12;
+       case R_IMF_IMTYPE_JP2:
+               return R_IMF_CHAN_DEPTH_8 | R_IMF_CHAN_DEPTH_12 | R_IMF_CHAN_DEPTH_16;
+       /* most formats are 8bit only */
+       default:
+               return R_IMF_CHAN_DEPTH_8;
+       }
+ }
+ /* string is from command line --render-format arg, keep in sync with
+  * creator.c help info */
+ char BKE_imtype_from_arg(const char *imtype_arg)
+ {
+       if      (!strcmp(imtype_arg,"TGA")) return R_IMF_IMTYPE_TARGA;
+       else if (!strcmp(imtype_arg,"IRIS")) return R_IMF_IMTYPE_IRIS;
+ #ifdef WITH_DDS
+       else if (!strcmp(imtype_arg,"DDS")) return R_IMF_IMTYPE_DDS;
+ #endif
+       else if (!strcmp(imtype_arg,"JPEG")) return R_IMF_IMTYPE_JPEG90;
+       else if (!strcmp(imtype_arg,"IRIZ")) return R_IMF_IMTYPE_IRIZ;
+       else if (!strcmp(imtype_arg,"RAWTGA")) return R_IMF_IMTYPE_RAWTGA;
+       else if (!strcmp(imtype_arg,"AVIRAW")) return R_IMF_IMTYPE_AVIRAW;
+       else if (!strcmp(imtype_arg,"AVIJPEG")) return R_IMF_IMTYPE_AVIJPEG;
+       else if (!strcmp(imtype_arg,"PNG")) return R_IMF_IMTYPE_PNG;
+       else if (!strcmp(imtype_arg,"AVICODEC")) return R_IMF_IMTYPE_AVICODEC;
+       else if (!strcmp(imtype_arg,"QUICKTIME")) return R_IMF_IMTYPE_QUICKTIME;
+       else if (!strcmp(imtype_arg,"BMP")) return R_IMF_IMTYPE_BMP;
+ #ifdef WITH_HDR
+       else if (!strcmp(imtype_arg,"HDR")) return R_IMF_IMTYPE_RADHDR;
+ #endif
+ #ifdef WITH_TIFF
+       else if (!strcmp(imtype_arg,"TIFF")) return R_IMF_IMTYPE_TIFF;
+ #endif
+ #ifdef WITH_OPENEXR
+       else if (!strcmp(imtype_arg,"EXR")) return R_IMF_IMTYPE_OPENEXR;
+       else if (!strcmp(imtype_arg,"MULTILAYER")) return R_IMF_IMTYPE_MULTILAYER;
+ #endif
+       else if (!strcmp(imtype_arg,"MPEG")) return R_IMF_IMTYPE_FFMPEG;
+       else if (!strcmp(imtype_arg,"FRAMESERVER")) return R_IMF_IMTYPE_FRAMESERVER;
+ #ifdef WITH_CINEON
+       else if (!strcmp(imtype_arg,"CINEON")) return R_IMF_IMTYPE_CINEON;
+       else if (!strcmp(imtype_arg,"DPX")) return R_IMF_IMTYPE_DPX;
+ #endif
+ #ifdef WITH_OPENJPEG
+       else if (!strcmp(imtype_arg,"JP2")) return R_IMF_IMTYPE_JP2;
+ #endif
+       else return R_IMF_IMTYPE_INVALID;
+ }
+ int BKE_add_image_extension(char *string, const char imtype)
  {
        const char *extension= NULL;
        
@@@ -1371,10 -1483,13 +1498,15 @@@ int BKE_alphatest_ibuf(ImBuf *ibuf
        return FALSE;
  }
  
- int BKE_write_ibuf(ImBuf *ibuf, const char *name, int imtype, int subimtype, int quality)
++/* note: imf->planes is ignored here, its assumed the image channels
++ * are already set */
+ int BKE_write_ibuf(ImBuf *ibuf, const char *name, ImageFormatData *imf)
  {
+       char imtype= imf->imtype;
+       char compress= imf->compress;
+       char quality= imf->quality;
        int ok;
-       (void)subimtype; /* quies unused warnings */
  
        if(imtype == -1) {
                /* use whatever existing image type is set by 'ibuf' */
        }
  #endif
        else {
-               /* R_JPEG90, etc. default we save jpegs */
+               /* R_IMF_IMTYPE_JPEG90, etc. default we save jpegs */
                if(quality < 10) quality= 90;
                ibuf->ftype= JPG|quality;
-               if(ibuf->depth==32) ibuf->depth= 24;    /* unsupported feature only confuses other s/w */
 -              if(ibuf->planes==32) ibuf->planes= 24;  /* unsupported feature only confuses other s/w */
        }
        
        BLI_make_existing_file(name);
        return(ok);
  }
  
- int BKE_write_ibuf_stamp(Scene *scene, struct Object *camera, ImBuf *ibuf, const char *name, int imtype, int subimtype, int quality)
++/* same as BKE_write_ibuf_as but crappy workaround not to perminantly modify
++ * _some_, values in the imbuf */
++int BKE_write_ibuf_as(ImBuf *ibuf, const char *name, ImageFormatData *imf,
++                      const short save_copy)
++{
++      ImBuf ibuf_back= *ibuf;
++      int ok;
++
++      /* all data is rgba anyway,
++       * this just controls how to save for some formats */
++      ibuf->planes= imf->planes;
++
++      ok= BKE_write_ibuf(ibuf, name, imf);
++
++      if (save_copy) {
++              /* note that we are not restoring _all_ settings */
++              ibuf->planes= ibuf_back.planes;
++              ibuf->ftype=  ibuf_back.ftype;
++      }
++
++      return ok;
++}
++
+ int BKE_write_ibuf_stamp(Scene *scene, struct Object *camera, ImBuf *ibuf, const char *name, struct ImageFormatData *imf)
  {
        if(scene && scene->r.stamp & R_STAMP_ALL)
                BKE_stamp_info(scene, camera, ibuf);
@@@ -1181,129 -1180,129 +1181,129 @@@ int object_remove_material_slot(Object 
  
  /* r g b = current value, col = new value, fac==0 is no change */
  /* if g==NULL, it only does r channel */
--void ramp_blend(int type, float *r, float *g, float *b, float fac, const float col[3])
++void ramp_blend(int type, float r_col[3], const float fac, const float col[3])
  {
        float tmp, facm= 1.0f-fac;
        
        switch (type) {
                case MA_RAMP_BLEND:
--                      *r = facm*(*r) + fac*col[0];
--                      if(g) {
--                              *g = facm*(*g) + fac*col[1];
--                              *b = facm*(*b) + fac*col[2];
++                      r_col[0] = facm*(r_col[0]) + fac*col[0];
++                      if(r_col[1]) {
++                              r_col[1] = facm*(r_col[1]) + fac*col[1];
++                              r_col[2] = facm*(r_col[2]) + fac*col[2];
                        }
                                break;
                case MA_RAMP_ADD:
--                      *r += fac*col[0];
--                      if(g) {
--                              *g += fac*col[1];
--                              *b += fac*col[2];
++                      r_col[0] += fac*col[0];
++                      if(r_col[1]) {
++                              r_col[1] += fac*col[1];
++                              r_col[2] += fac*col[2];
                        }
                                break;
                case MA_RAMP_MULT:
--                      *r *= (facm + fac*col[0]);
--                      if(g) {
--                              *g *= (facm + fac*col[1]);
--                              *b *= (facm + fac*col[2]);
++                      r_col[0] *= (facm + fac*col[0]);
++                      if(r_col[1]) {
++                              r_col[1] *= (facm + fac*col[1]);
++                              r_col[2] *= (facm + fac*col[2]);
                        }
                                break;
                case MA_RAMP_SCREEN:
--                      *r = 1.0f - (facm + fac*(1.0f - col[0])) * (1.0f - *r);
--                      if(g) {
--                              *g = 1.0f - (facm + fac*(1.0f - col[1])) * (1.0f - *g);
--                              *b = 1.0f - (facm + fac*(1.0f - col[2])) * (1.0f - *b);
++                      r_col[0] = 1.0f - (facm + fac*(1.0f - col[0])) * (1.0f - r_col[0]);
++                      if(r_col[1]) {
++                              r_col[1] = 1.0f - (facm + fac*(1.0f - col[1])) * (1.0f - r_col[1]);
++                              r_col[2] = 1.0f - (facm + fac*(1.0f - col[2])) * (1.0f - r_col[2]);
                        }
                                break;
                case MA_RAMP_OVERLAY:
--                      if(*r < 0.5f)
--                              *r *= (facm + 2.0f*fac*col[0]);
++                      if(r_col[0] < 0.5f)
++                              r_col[0] *= (facm + 2.0f*fac*col[0]);
                        else
--                              *r = 1.0f - (facm + 2.0f*fac*(1.0f - col[0])) * (1.0f - *r);
--                      if(g) {
--                              if(*g < 0.5f)
--                                      *g *= (facm + 2.0f*fac*col[1]);
++                              r_col[0] = 1.0f - (facm + 2.0f*fac*(1.0f - col[0])) * (1.0f - r_col[0]);
++                      if(r_col[1]) {
++                              if(r_col[1] < 0.5f)
++                                      r_col[1] *= (facm + 2.0f*fac*col[1]);
                                else
--                                      *g = 1.0f - (facm + 2.0f*fac*(1.0f - col[1])) * (1.0f - *g);
--                              if(*b < 0.5f)
--                                      *b *= (facm + 2.0f*fac*col[2]);
++                                      r_col[1] = 1.0f - (facm + 2.0f*fac*(1.0f - col[1])) * (1.0f - r_col[1]);
++                              if(r_col[2] < 0.5f)
++                                      r_col[2] *= (facm + 2.0f*fac*col[2]);
                                else
--                                      *b = 1.0f - (facm + 2.0f*fac*(1.0f - col[2])) * (1.0f - *b);
++                                      r_col[2] = 1.0f - (facm + 2.0f*fac*(1.0f - col[2])) * (1.0f - r_col[2]);
                        }
                                break;
                case MA_RAMP_SUB:
--                      *r -= fac*col[0];
--                      if(g) {
--                              *g -= fac*col[1];
--                              *b -= fac*col[2];
++                      r_col[0] -= fac*col[0];
++                      if(r_col[1]) {
++                              r_col[1] -= fac*col[1];
++                              r_col[2] -= fac*col[2];
                        }
                                break;
                case MA_RAMP_DIV:
                        if(col[0]!=0.0f)
--                              *r = facm*(*r) + fac*(*r)/col[0];
--                      if(g) {
++                              r_col[0] = facm*(r_col[0]) + fac*(r_col[0])/col[0];
++                      if(r_col[1]) {
                                if(col[1]!=0.0f)
--                                      *g = facm*(*g) + fac*(*g)/col[1];
++                                      r_col[1] = facm*(r_col[1]) + fac*(r_col[1])/col[1];
                                if(col[2]!=0.0f)
--                                      *b = facm*(*b) + fac*(*b)/col[2];
++                                      r_col[2] = facm*(r_col[2]) + fac*(r_col[2])/col[2];
                        }
                                break;
                case MA_RAMP_DIFF:
--                      *r = facm*(*r) + fac*fabsf(*r-col[0]);
--                      if(g) {
--                              *g = facm*(*g) + fac*fabsf(*g-col[1]);
--                              *b = facm*(*b) + fac*fabsf(*b-col[2]);
++                      r_col[0] = facm*(r_col[0]) + fac*fabsf(r_col[0]-col[0]);
++                      if(r_col[1]) {
++                              r_col[1] = facm*(r_col[1]) + fac*fabsf(r_col[1]-col[1]);
++                              r_col[2] = facm*(r_col[2]) + fac*fabsf(r_col[2]-col[2]);
                        }
                                break;
                case MA_RAMP_DARK:
                        tmp=col[0]+((1-col[0])*facm); 
--                      if(tmp < *r) *r= tmp; 
--                      if(g) { 
++                      if(tmp < r_col[0]) r_col[0]= tmp;
++                      if(r_col[1]) {
                                tmp=col[1]+((1-col[1])*facm); 
--                              if(tmp < *g) *g= tmp; 
++                              if(tmp < r_col[1]) r_col[1]= tmp;
                                tmp=col[2]+((1-col[2])*facm); 
--                              if(tmp < *b) *b= tmp; 
++                              if(tmp < r_col[2]) r_col[2]= tmp;
                        } 
                                break; 
                case MA_RAMP_LIGHT:
                        tmp= fac*col[0];
--                      if(tmp > *r) *r= tmp; 
--                              if(g) {
++                      if(tmp > r_col[0]) r_col[0]= tmp;
++                              if(r_col[1]) {
                                        tmp= fac*col[1];
--                                      if(tmp > *g) *g= tmp; 
++                                      if(tmp > r_col[1]) r_col[1]= tmp;
                                        tmp= fac*col[2];
--                                      if(tmp > *b) *b= tmp; 
++                                      if(tmp > r_col[2]) r_col[2]= tmp;
                                }
                                        break;  
                case MA_RAMP_DODGE:                     
                        
                                
--                      if(*r !=0.0f){
++                      if(r_col[0] !=0.0f){
                                tmp = 1.0f - fac*col[0];
                                if(tmp <= 0.0f)
--                                      *r = 1.0f;
--                              else if ((tmp = (*r) / tmp)> 1.0f)
--                                      *r = 1.0f;
++                                      r_col[0] = 1.0f;
++                              else if ((tmp = (r_col[0]) / tmp)> 1.0f)
++                                      r_col[0] = 1.0f;
                                else 
--                                      *r = tmp;
++                                      r_col[0] = tmp;
                        }
--                      if(g) {
--                              if(*g !=0.0f){
++                      if(r_col[1]) {
++                              if(r_col[1] !=0.0f){
                                        tmp = 1.0f - fac*col[1];
                                        if(tmp <= 0.0f )
--                                              *g = 1.0f;
--                                      else if ((tmp = (*g) / tmp) > 1.0f )
--                                              *g = 1.0f;
++                                              r_col[1] = 1.0f;
++                                      else if ((tmp = (r_col[1]) / tmp) > 1.0f )
++                                              r_col[1] = 1.0f;
                                        else
--                                              *g = tmp;
++                                              r_col[1] = tmp;
                                }
--                              if(*b !=0.0f){
++                              if(r_col[2] !=0.0f){
                                        tmp = 1.0f - fac*col[2];
                                        if(tmp <= 0.0f)
--                                              *b = 1.0f;
--                                      else if ((tmp = (*b) / tmp) > 1.0f )
--                                              *b = 1.0f;
++                                              r_col[2] = 1.0f;
++                                      else if ((tmp = (r_col[2]) / tmp) > 1.0f )
++                                              r_col[2] = 1.0f;
                                        else
--                                              *b = tmp;
++                                              r_col[2] = tmp;
                                }
  
                        }
                        tmp = facm + fac*col[0];
                        
                        if(tmp <= 0.0f)
--                              *r = 0.0f;
--                      else if (( tmp = (1.0f - (1.0f - (*r)) / tmp )) < 0.0f)
--                                      *r = 0.0f;
++                              r_col[0] = 0.0f;
++                      else if (( tmp = (1.0f - (1.0f - (r_col[0])) / tmp )) < 0.0f)
++                                      r_col[0] = 0.0f;
                        else if (tmp > 1.0f)
--                              *r=1.0f;
++                              r_col[0]=1.0f;
                        else 
--                              *r = tmp; 
++                              r_col[0] = tmp;
  
--                      if(g) {
++                      if(r_col[1]) {
                                tmp = facm + fac*col[1];
                                if(tmp <= 0.0f)
--                                      *g = 0.0f;
--                              else if (( tmp = (1.0f - (1.0f - (*g)) / tmp )) < 0.0f )
--                                              *g = 0.0f;
++                                      r_col[1] = 0.0f;
++                              else if (( tmp = (1.0f - (1.0f - (r_col[1])) / tmp )) < 0.0f )
++                                              r_col[1] = 0.0f;
                                else if(tmp >1.0f)
--                                      *g=1.0f;
++                                      r_col[1]=1.0f;
                                else
--                                      *g = tmp;
++                                      r_col[1] = tmp;
  
                                        tmp = facm + fac*col[2];
                                        if(tmp <= 0.0f)
--                                      *b = 0.0f;
--                              else if (( tmp = (1.0f - (1.0f - (*b)) / tmp )) < 0.0f  )
--                                              *b = 0.0f;
++                                      r_col[2] = 0.0f;
++                              else if (( tmp = (1.0f - (1.0f - (r_col[2])) / tmp )) < 0.0f  )
++                                              r_col[2] = 0.0f;
                                else if(tmp >1.0f)
--                                      *b= 1.0f;
++                                      r_col[2]= 1.0f;
                                else
--                                      *b = tmp;
++                                      r_col[2] = tmp;
                        }
                                break;
                case MA_RAMP_HUE:               
--                      if(g){
++                      if(r_col[1]){
                                float rH,rS,rV;
                                float colH,colS,colV; 
                                float tmpr,tmpg,tmpb;
                                rgb_to_hsv(col[0],col[1],col[2],&colH,&colS,&colV);
                                if(colS!=0 ){
--                                      rgb_to_hsv(*r,*g,*b,&rH,&rS,&rV);
++                                      rgb_to_hsv(r_col[0],r_col[1],r_col[2],&rH,&rS,&rV);
                                        hsv_to_rgb( colH , rS, rV, &tmpr, &tmpg, &tmpb);
--                                      *r = facm*(*r) + fac*tmpr;  
--                                      *g = facm*(*g) + fac*tmpg; 
--                                      *b = facm*(*b) + fac*tmpb;
++                                      r_col[0] = facm*(r_col[0]) + fac*tmpr;
++                                      r_col[1] = facm*(r_col[1]) + fac*tmpg;
++                                      r_col[2] = facm*(r_col[2]) + fac*tmpb;
                                }
                        }
                                break;
                case MA_RAMP_SAT:               
--                      if(g){
++                      if(r_col[1]){
                                float rH,rS,rV;
                                float colH,colS,colV;
--                              rgb_to_hsv(*r,*g,*b,&rH,&rS,&rV);
++                              rgb_to_hsv(r_col[0],r_col[1],r_col[2],&rH,&rS,&rV);
                                if(rS!=0){
                                        rgb_to_hsv(col[0],col[1],col[2],&colH,&colS,&colV);
--                                      hsv_to_rgb( rH, (facm*rS +fac*colS), rV, r, g, b);
++                                      hsv_to_rgb( rH, (facm*rS +fac*colS), rV, r_col+0, r_col+1, r_col+2);
                                }
                        }
                                break;
                case MA_RAMP_VAL:               
--                      if(g){
++                      if(r_col[1]){
                                float rH,rS,rV;
                                float colH,colS,colV;
--                              rgb_to_hsv(*r,*g,*b,&rH,&rS,&rV);
++                              rgb_to_hsv(r_col[0],r_col[1],r_col[2],&rH,&rS,&rV);
                                rgb_to_hsv(col[0],col[1],col[2],&colH,&colS,&colV);
--                              hsv_to_rgb( rH, rS, (facm*rV +fac*colV), r, g, b);
++                              hsv_to_rgb( rH, rS, (facm*rV +fac*colV), r_col+0, r_col+1, r_col+2);
                        }
                                break;
                case MA_RAMP_COLOR:             
--                      if(g){
++                      if(r_col[1]){
                                float rH,rS,rV;
                                float colH,colS,colV;
                                float tmpr,tmpg,tmpb;
                                rgb_to_hsv(col[0],col[1],col[2],&colH,&colS,&colV);
                                if(colS!=0){
--                                      rgb_to_hsv(*r,*g,*b,&rH,&rS,&rV);
++                                      rgb_to_hsv(r_col[0],r_col[1],r_col[2],&rH,&rS,&rV);
                                        hsv_to_rgb( colH, colS, rV, &tmpr, &tmpg, &tmpb);
--                                      *r = facm*(*r) + fac*tmpr;
--                                      *g = facm*(*g) + fac*tmpg;
--                                      *b = facm*(*b) + fac*tmpb;
++                                      r_col[0] = facm*(r_col[0]) + fac*tmpr;
++                                      r_col[1] = facm*(r_col[1]) + fac*tmpg;
++                                      r_col[2] = facm*(r_col[2]) + fac*tmpb;
                                }
                        }
                                break;
                case MA_RAMP_SOFT: 
--                      if (g){ 
++                      if (r_col[1]){
                                float scr, scg, scb; 
  
                                /* first calculate non-fac based Screen mix */ 
--                              scr = 1.0f - (1.0f - col[0]) * (1.0f - *r); 
--                              scg = 1.0f - (1.0f - col[1]) * (1.0f - *g); 
--                              scb = 1.0f - (1.0f - col[2]) * (1.0f - *b); 
++                              scr = 1.0f - (1.0f - col[0]) * (1.0f - r_col[0]);
++                              scg = 1.0f - (1.0f - col[1]) * (1.0f - r_col[1]);
++                              scb = 1.0f - (1.0f - col[2]) * (1.0f - r_col[2]);
  
--                              *r = facm*(*r) + fac*(((1.0f - *r) * col[0] * (*r)) + (*r * scr)); 
--                              *g = facm*(*g) + fac*(((1.0f - *g) * col[1] * (*g)) + (*g * scg)); 
--                              *b = facm*(*b) + fac*(((1.0f - *b) * col[2] * (*b)) + (*b * scb)); 
++                              r_col[0] = facm*(r_col[0]) + fac*(((1.0f - r_col[0]) * col[0] * (r_col[0])) + (r_col[0] * scr));
++                              r_col[1] = facm*(r_col[1]) + fac*(((1.0f - r_col[1]) * col[1] * (r_col[1])) + (r_col[1] * scg));
++                              r_col[2] = facm*(r_col[2]) + fac*(((1.0f - r_col[2]) * col[2] * (r_col[2])) + (r_col[2] * scb));
                        } 
                                break; 
                case MA_RAMP_LINEAR: 
                        if (col[0] > 0.5f)  
--                              *r = *r + fac*(2.0f*(col[0]-0.5f)); 
++                              r_col[0] = r_col[0] + fac*(2.0f*(col[0]-0.5f));
                        else  
--                              *r = *r + fac*(2.0f*(col[0]) - 1.0f); 
--                      if (g){ 
++                              r_col[0] = r_col[0] + fac*(2.0f*(col[0]) - 1.0f);
++                      if (r_col[1]){
                                if (col[1] > 0.5f)  
--                                      *g = *g + fac*(2.0f*(col[1]-0.5f)); 
++                                      r_col[1] = r_col[1] + fac*(2.0f*(col[1]-0.5f));
                                else  
--                                      *g = *g + fac*(2.0f*(col[1]) -1.0f); 
++                                      r_col[1] = r_col[1] + fac*(2.0f*(col[1]) -1.0f);
                                if (col[2] > 0.5f)  
--                                      *b = *b + fac*(2.0f*(col[2]-0.5f)); 
++                                      r_col[2] = r_col[2] + fac*(2.0f*(col[2]-0.5f));
                                else  
--                                      *b = *b + fac*(2.0f*(col[2]) - 1.0f); 
++                                      r_col[2] = r_col[2] + fac*(2.0f*(col[2]) - 1.0f);
                        } 
                                break; 
        }       
@@@ -895,7 -895,7 +895,7 @@@ void BKE_movieclip_update_scopes(MovieC
  
  static void movieclip_build_proxy_ibuf(MovieClip *clip, ImBuf *ibuf, int cfra, int proxy_render_size, int undistorted)
  {
--      char name[FILE_MAXFILE+FILE_MAXDIR];
++      char name[FILE_MAX];
        int quality, rectx, recty;
        int size= size= rendersize_to_number(proxy_render_size);
        ImBuf *scaleibuf;
@@@ -168,7 -168,7 +168,7 @@@ PackedFile *newPackedFile(ReportList *r
  {
        PackedFile *pf = NULL;
        int file, filelen;
--      char name[FILE_MAXDIR+FILE_MAXFILE];
++      char name[FILE_MAX];
        void *data;
        
        /* render result has no filename and can be ignored
@@@ -245,7 -245,7 +245,7 @@@ void packAll(Main *bmain, ReportList *r
  
  static char *find_new_name(char *name)
  {
--      char tempname[FILE_MAXDIR + FILE_MAXFILE];
++      char tempname[FILE_MAX];
        char *newname;
        size_t len;
        
@@@ -268,8 -268,8 +268,8 @@@ int writePackedFile(ReportList *reports
  {
        int file, number, remove_tmp = FALSE;
        int ret_value = RET_OK;
--      char name[FILE_MAXDIR + FILE_MAXFILE];
--      char tempname[FILE_MAXDIR + FILE_MAXFILE];
++      char name[FILE_MAX];
++      char tempname[FILE_MAX];
  /*    void *data; */
        
        if (guimode) {} //XXX  waitcursor(1);
@@@ -337,7 -337,7 +337,7 @@@ int checkPackedFile(const char *filenam
        struct stat st;
        int ret_val, i, len, file;
        char buf[4096];
--      char name[FILE_MAXDIR + FILE_MAXFILE];
++      char name[FILE_MAX];
        
        BLI_strncpy(name, filename, sizeof(name));
        BLI_path_abs(name, G.main->name);
@@@ -394,8 -394,8 +394,8 @@@ char *unpackFile(ReportList *reports, c
        char *newname = NULL;
        const char *temp = NULL;
        
--      // char newabs[FILE_MAXDIR + FILE_MAXFILE];
--      // char newlocal[FILE_MAXDIR + FILE_MAXFILE];
++      // char newabs[FILE_MAX];
++      // char newlocal[FILE_MAX];
        
        if (pf != NULL) {
                switch (how) {
  
  int unpackVFont(ReportList *reports, VFont *vfont, int how)
  {
--      char localname[FILE_MAXDIR + FILE_MAXFILE], fi[FILE_MAXFILE];
++      char localname[FILE_MAX], fi[FILE_MAXFILE];
        char *newname;
        int ret_value = RET_ERROR;
        
@@@ -3170,13 -3170,13 +3170,13 @@@ void psys_cache_edit_paths(Scene *scene
                                float t2;
  
                                if(k==0) {
--                                      weight_to_rgb(pind.hkey[1]->weight, ca->col, ca->col+1, ca->col+2);
++                                      weight_to_rgb(ca->col, pind.hkey[1]->weight);
                                } else {
                                        float w1[3], w2[3];
                                        keytime = (t - (*pind.ekey[0]->time))/((*pind.ekey[1]->time) - (*pind.ekey[0]->time));
  
--                                      weight_to_rgb(pind.hkey[0]->weight, w1, w1+1, w1+2);
--                                      weight_to_rgb(pind.hkey[1]->weight, w2, w2+1, w2+2);
++                                      weight_to_rgb(w1, pind.hkey[0]->weight);
++                                      weight_to_rgb(w2, pind.hkey[1]->weight);
  
                                        interp_v3_v3v3(ca->col, w1, w2, keytime);
                                }
@@@ -770,6 -770,6 +770,9 @@@ void BKE_ptcache_id_from_softbody(PTCac
        pid->info_types= 0;
  
        pid->stack_index = pid->cache->index;
++
++      pid->default_step = 10;
++      pid->max_step = 20;
  }
  void BKE_ptcache_id_from_particles(PTCacheID *pid, Object *ob, ParticleSystem *psys)
  {
                pid->data_types|= (1<<BPHYS_DATA_ROTATION);
  
        pid->info_types= (1<<BPHYS_DATA_TIMES);
++
++      pid->default_step = 10;
++      pid->max_step = 20;
  }
  void BKE_ptcache_id_from_cloth(PTCacheID *pid, Object *ob, ClothModifierData *clmd)
  {
  
        pid->data_types= (1<<BPHYS_DATA_LOCATION) | (1<<BPHYS_DATA_VELOCITY) | (1<<BPHYS_DATA_XCONST);
        pid->info_types= 0;
++
++      pid->default_step = 1;
++      pid->max_step = 1;
  }
  void BKE_ptcache_id_from_smoke(PTCacheID *pid, struct Object *ob, struct SmokeModifierData *smd)
  {
                pid->data_types |= (1<<BPHYS_DATA_SMOKE_LOW);
        if(sds->wt)
                pid->data_types |= (1<<BPHYS_DATA_SMOKE_HIGH);
++
++      pid->default_step = 1;
++      pid->max_step = 1;
  }
  
  void BKE_ptcache_id_from_dynamicpaint(PTCacheID *pid, Object *ob, DynamicPaintSurface *surface)
        pid->info_types= 0;
  
        pid->stack_index = pid->cache->index;
++
++      pid->default_step = 1;
++      pid->max_step = 1;
  }
  
  void BKE_ptcache_ids_from_object(ListBase *lb, Object *ob, Scene *scene, int duplis)
  */
  
  #define MAX_PTCACHE_PATH FILE_MAX
--#define MAX_PTCACHE_FILE ((FILE_MAXDIR+FILE_MAXFILE)*2)
++#define MAX_PTCACHE_FILE ((FILE_MAX)*2)
  
  static int ptcache_path(PTCacheID *pid, char *filename)
  {
@@@ -1112,7 -1112,7 +1127,7 @@@ static PTCacheFile *ptcache_file_open(P
  {
        PTCacheFile *pf;
        FILE *fp = NULL;
--      char filename[(FILE_MAXDIR+FILE_MAXFILE)*2];
++      char filename[(FILE_MAX)*2];
  
  #ifndef DURIAN_POINTCACHE_LIB_OK
        /* don't allow writing for linked objects */
@@@ -652,7 -652,7 +652,7 @@@ void calc_sequence(Scene *scene, Sequen
  /* note: caller should run calc_sequence(scene, seq) after */
  void reload_sequence_new_file(Scene *scene, Sequence * seq, int lock_range)
  {
--      char str[FILE_MAXDIR+FILE_MAXFILE];
++      char str[FILE_MAX];
        int prev_startdisp=0, prev_enddisp=0;
        /* note: dont rename the strip, will break animation curves */
  
@@@ -1156,7 -1156,7 +1156,7 @@@ static IMB_Proxy_Size seq_rendersize_to
  
  static void seq_open_anim_file(Sequence * seq)
  {
--      char name[FILE_MAXDIR+FILE_MAXFILE];
++      char name[FILE_MAX];
        StripProxy * proxy;
  
        if(seq->anim != NULL) {
@@@ -2057,7 -2057,7 +2057,7 @@@ static ImBuf * seq_render_scene_strip_i
  static ImBuf * seq_render_strip(SeqRenderData context, Sequence * seq, float cfra)
  {
        ImBuf * ibuf = NULL;
--      char name[FILE_MAXDIR+FILE_MAXFILE];
++      char name[FILE_MAX];
        int use_preprocess = input_have_to_preprocess(context, seq, cfra);
        float nr = give_stripelem_index(seq, cfra);
        /* all effects are handled similarly with the exception of speed effect */
@@@ -237,12 -237,12 +237,12 @@@ int reopen_text(Text *text
        int i, llen, len;
        unsigned char *buffer;
        TextLine *tmp;
--      char str[FILE_MAXDIR+FILE_MAXFILE];
++      char str[FILE_MAX];
        struct stat st;
  
        if (!text || !text->name) return 0;
        
--      BLI_strncpy(str, text->name, FILE_MAXDIR+FILE_MAXFILE);
++      BLI_strncpy(str, text->name, FILE_MAX);
        BLI_path_abs(str, G.main->name);
        
        fp= fopen(str, "r");
@@@ -334,10 -334,10 +334,10 @@@ Text *add_text(const char *file, const 
        unsigned char *buffer;
        TextLine *tmp;
        Text *ta;
--      char str[FILE_MAXDIR+FILE_MAXFILE];
++      char str[FILE_MAX];
        struct stat st;
  
--      BLI_strncpy(str, file, FILE_MAXDIR+FILE_MAXFILE);
++      BLI_strncpy(str, file, FILE_MAX);
        if (relpath) /* can be NULL (bg mode) */
                BLI_path_abs(str, relpath);
        
@@@ -287,20 -287,20 +287,28 @@@ static DLRBT_Node *get_grandparent (DLR
                return NULL;
  }
  
--/* get the 'uncle' - the sibling of the parent - of the given node */
--static DLRBT_Node *get_uncle (DLRBT_Node *node)
++/* get the sibling node (e.g. if node is left child of parent, return right child of parent) */
++static DLRBT_Node *get_sibling(DLRBT_Node *node)
  {
--      DLRBT_Node *gpn= get_grandparent(node);
--      
--      /* return the child of the grandparent which isn't the node's parent */
--      if (gpn) {
--              if (gpn->left == node->parent)
--                      return gpn->right;
++      if (node && node->parent) {
++              if (node == node->parent->left)
++                      return node->parent->right;
                else
--                      return gpn->left;
++                      return node->parent->left;
        }
++
++      /* sibling not found */
++      return NULL;
++}
++
++/* get the 'uncle' - the sibling of the parent - of the given node */
++static DLRBT_Node *get_uncle (DLRBT_Node *node)
++{
++      if (node)
++              /* return the child of the grandparent which isn't the node's parent */
++              return get_sibling(node->parent);
        
--      /* not found */
++      /* uncle not found */
        return NULL;
  }
  
@@@ -416,8 -426,8 +426,8 @@@ void BLI_cleanup_file(const char *relab
  void BLI_path_rel(char *file, const char *relfile)
  {
        char * lslash;
--      char temp[FILE_MAXDIR+FILE_MAXFILE];
--      char res[FILE_MAXDIR+FILE_MAXFILE];
++      char temp[FILE_MAX];
++      char res[FILE_MAX];
        
        /* if file is already relative, bail out */
        if(file[0]=='/' && file[1]=='/') return;
                if (relfile[0] != '\\' && relfile[0] != '/') {
                        ptemp++;
                }
--              BLI_strncpy(ptemp, relfile, FILE_MAXDIR + FILE_MAXFILE-3);
++              BLI_strncpy(ptemp, relfile, FILE_MAX-3);
        } else {
--              BLI_strncpy(temp, relfile, FILE_MAXDIR + FILE_MAXFILE);
++              BLI_strncpy(temp, relfile, FILE_MAX);
        }
  
        if (BLI_strnlen(file, 3) > 2) {
@@@ -529,7 -539,7 +539,7 @@@ int BLI_has_parent(char *path
  int BLI_parent_dir(char *path)
  {
        static char parent_dir[]= {'.', '.', SEP, '\0'}; /* "../" or "..\\" */
--      char tmp[FILE_MAXDIR+FILE_MAXFILE+4];
++      char tmp[FILE_MAX+4];
        BLI_strncpy(tmp, path, sizeof(tmp)-4);
        BLI_add_slash(tmp);
        strcat(tmp, parent_dir);
@@@ -734,7 -744,7 +744,7 @@@ int BLI_path_cwd(char *path
  #endif
        
        if (wasrelative==1) {
--              char cwd[FILE_MAXDIR + FILE_MAXFILE]= "";
++              char cwd[FILE_MAX]= "";
                BLI_current_working_dir(cwd, sizeof(cwd)); /* incase the full path to the blend isnt used */
                
                if (cwd[0] == '\0') {
                        * blend file which isnt a feature we want to use in this case since were dealing
                        * with a path from the command line, rather than from inside Blender */
                        
--                      char origpath[FILE_MAXDIR + FILE_MAXFILE];
--                      BLI_strncpy(origpath, path, FILE_MAXDIR + FILE_MAXFILE);
++                      char origpath[FILE_MAX];
++                      BLI_strncpy(origpath, path, FILE_MAX);
                        
                        BLI_make_file_string(NULL, path, cwd, origpath); 
                }
@@@ -1246,7 -1256,7 +1256,7 @@@ void BLI_make_exist(char *dir
  
  void BLI_make_existing_file(const char *name)
  {
--      char di[FILE_MAXDIR+FILE_MAXFILE], fi[FILE_MAXFILE];
++      char di[FILE_MAX], fi[FILE_MAXFILE];
  
        BLI_strncpy(di, name, sizeof(di));
        BLI_splitdirstring(di, fi);
@@@ -1695,8 -1705,8 +1705,8 @@@ static int add_win32_extension(char *na
        type = BLI_exists(name);
        if ((type == 0) || S_ISDIR(type)) {
  #ifdef _WIN32
--              char filename[FILE_MAXDIR+FILE_MAXFILE];
--              char ext[FILE_MAXDIR+FILE_MAXFILE];
++              char filename[FILE_MAX];
++              char ext[FILE_MAX];
                const char *extensions = getenv("PATHEXT");
                if (extensions) {
                        char *temp;
  */
  static void bli_where_am_i(char *fullname, const size_t maxlen, const char *name)
  {
--      char filename[FILE_MAXDIR+FILE_MAXFILE];
++      char filename[FILE_MAX];
        const char *path = NULL, *temp;
  
  #ifdef _WIN32
@@@ -656,12 -656,12 +656,17 @@@ void BLI_pbvh_free(PBVH *bvh
                        /* if pbvh was deformed, new memory was allocated for verts/faces -- free it */
  
                        MEM_freeN(bvh->verts);
--                      MEM_freeN(bvh->faces);
++                      if(bvh->faces)
++                              MEM_freeN(bvh->faces);
                }
        }
  
--      MEM_freeN(bvh->nodes);
--      MEM_freeN(bvh->prim_indices);
++      if(bvh->nodes)
++              MEM_freeN(bvh->nodes);
++
++      if(bvh->prim_indices)
++              MEM_freeN(bvh->prim_indices);
++
        MEM_freeN(bvh);
  }
  
@@@ -1127,6 -1127,6 +1132,9 @@@ void BLI_pbvh_update(PBVH *bvh, int fla
        PBVHNode **nodes;
        int totnode;
  
++      if(!bvh->nodes)
++              return;
++
        BLI_pbvh_search_gather(bvh, update_search_cb, SET_INT_IN_POINTER(flag),
                &nodes, &totnode);
  
@@@ -442,18 -442,18 +442,18 @@@ int BLI_exists(const char *name
        /*  in Windows stat doesn't recognize dir ending on a slash 
                To not break code where the ending slash is expected we
                don't mess with the argument name directly here - elubie */
--      char tmp[FILE_MAXDIR+FILE_MAXFILE];
++      char tmp[FILE_MAX];
        int len, res;
--      BLI_strncpy(tmp, name, FILE_MAXDIR+FILE_MAXFILE);
++      BLI_strncpy(tmp, name, FILE_MAX);
        len = strlen(tmp);
        if (len > 3 && ( tmp[len-1]=='\\' || tmp[len-1]=='/') ) tmp[len-1] = '\0';
        res = _stat(tmp, &st);
        if (res == -1) return(0);
  #elif defined(__MINGW32__)
        struct _stati64 st;
--      char tmp[FILE_MAXDIR+FILE_MAXFILE];
++      char tmp[FILE_MAX];
        int len, res;
--      BLI_strncpy(tmp, name, FILE_MAXDIR+FILE_MAXFILE);
++      BLI_strncpy(tmp, name, FILE_MAX);
        len = strlen(tmp);
        if (len > 3 && ( tmp[len-1]=='\\' || tmp[len-1]=='/') ) tmp[len-1] = '\0';
        res = _stati64(tmp, &st);
  #define WIN32_SKIP_HKEY_PROTECTION            // need to use HKEY
  #include "BLI_winstuff.h"
  
-- /* FILE_MAXDIR + FILE_MAXFILE */
++ /* FILE_MAX */
  
  int BLI_getInstallationDir( char * str ) {
        char dir[FILE_MAXDIR];
        int a;
        
--      GetModuleFileName(NULL,str,FILE_MAXDIR+FILE_MAXFILE);
++      GetModuleFileName(NULL,str,FILE_MAX);
        BLI_split_dir_part(str, dir, sizeof(dir)); /* shouldn't be relative */
        a = strlen(dir);
        if(dir[a-1] == '\\') dir[a-1]=0;
@@@ -501,7 -500,7 +501,7 @@@ static Main *blo_find_main(FileData *fd
  {
        Main *m;
        Library *lib;
--      char name1[FILE_MAXDIR+FILE_MAXFILE];
++      char name1[FILE_MAX];
        
        BLI_strncpy(name1, filepath, sizeof(name1));
        cleanup_path(relabase, name1);
@@@ -12733,30 -12605,14 +12794,36 @@@ static void do_versions(FileData *fd, L
  
        /* put compatibility code here until next subversion bump */
        {
+               Scene *sce;
+               for(sce = main->scene.first; sce; sce = sce->id.next) {
+                       if (sce->r.im_format.depth == 0) {
+                               do_versions_image_settings_2_60(sce);
+                       }
+               }
        }
  
 +      /* default values in Freestyle settings */
 +      {
 +              Scene *sce;
 +              SceneRenderLayer *srl;
 +              FreestyleLineStyle *linestyle;
 +
 +              for(sce = main->scene.first; sce; sce = sce->id.next) {
 +                      for(srl= sce->r.layers.first; srl; srl= srl->next) {
 +                              if (srl->freestyleConfig.mode == 0)
 +                                      srl->freestyleConfig.mode= FREESTYLE_CONTROL_EDITOR_MODE;
 +                              if (srl->freestyleConfig.raycasting_algorithm == 0)
 +                                      srl->freestyleConfig.raycasting_algorithm= FREESTYLE_ALGO_CULLED_ADAPTIVE_CUMULATIVE;
 +                      }
 +              }
 +              for(linestyle = main->linestyle.first; linestyle; linestyle = linestyle->id.next) {
 +                      if (linestyle->chaining == 0)
 +                              linestyle->chaining= LS_CHAINING_PLAIN;
 +                      if (linestyle->rounds == 0)
 +                              linestyle->rounds= 3;
 +              }
 +      }
 +      
        /* WATCH IT!!!: pointers from libdata have not been converted yet here! */
        /* WATCH IT 2!: Userdef struct init has to be in editors/interface/resources.c! */
  
@@@ -59,7 -59,7 +59,7 @@@ typedef struct FileData 
        gzFile gzfiledes;
  
        // now only in use for library appending
--      char relabase[FILE_MAXDIR+FILE_MAXFILE];
++      char relabase[FILE_MAX];
        
        // variables needed for reading from stream
        char headerdone;
@@@ -1667,7 -1666,7 +1667,8 @@@ static void write_customdata(WriteData 
                                writestruct(wd, DATA, structname, datasize, layer->data);
                        }
                        else
--                              printf("error: this CustomDataLayer must not be written to file\n");
++                              printf("%s error: layer '%s':%d - can't be written to file\n",
++                                     __func__, structname, layer->type);
                }
        }
  
@@@ -2903,7 -2696,7 +2904,7 @@@ static int write_file_handle(Main *main
  /* return: success(0), failure(1) */
  static int do_history(const char *name, ReportList *reports)
  {
--      char tempname1[FILE_MAXDIR+FILE_MAXFILE], tempname2[FILE_MAXDIR+FILE_MAXFILE];
++      char tempname1[FILE_MAX], tempname2[FILE_MAX];
        int hisnr= U.versions;
        
        if(U.versions==0) return 0;
  /* return: success (1) */
  int BLO_write_file(Main *mainvar, const char *filepath, int write_flags, ReportList *reports, int *thumb)
  {
--      char userfilename[FILE_MAXDIR+FILE_MAXFILE];
--      char tempname[FILE_MAXDIR+FILE_MAXFILE+1];
++      char userfilename[FILE_MAX];
++      char tempname[FILE_MAX+1];
        int file, err, write_user_block;
  
        /* open temporary file, so we preserve the original in case we crash */
  
        /* remapping of relative paths to new file location */
        if(write_flags & G_FILE_RELATIVE_REMAP) {
--              char dir1[FILE_MAXDIR+FILE_MAXFILE];
--              char dir2[FILE_MAXDIR+FILE_MAXFILE];
++              char dir1[FILE_MAX];
++              char dir2[FILE_MAX];
                BLI_split_dir_part(filepath, dir1, sizeof(dir1));
                BLI_split_dir_part(mainvar->name, dir2, sizeof(dir2));
  
  
        if(write_flags & G_FILE_COMPRESS) {
                /* compressed files have the same ending as regular files... only from 2.4!!! */
--              char gzname[FILE_MAXDIR+FILE_MAXFILE+4];
++              char gzname[FILE_MAX+4];
                int ret;
  
                /* first write compressed to separate @.gz */
@@@ -107,7 -107,7 +107,7 @@@ static void gp_draw_stroke_buffer (tGPs
        if (totpoints == 1) {           
                /* draw point */
                glBegin(GL_POINTS);
--                      glVertex2f(points->x, points->y);
++                      glVertex2iv(&points->x);
                glEnd();
        }
        else if (sflag & GP_STROKE_ERASER) {
                                glBegin(GL_LINE_STRIP);
                                
                                /* need to roll-back one point to ensure that there are no gaps in the stroke */
--                              if (i != 0) {
--                                      pt--;
--                                      glVertex2f(pt->x, pt->y);
--                                      pt++;
--                              }
++                              if (i != 0) glVertex2iv(&(pt - 1)->x);
++
                                /* now the point we want... */
--                              glVertex2f(pt->x, pt->y);
++                              glVertex2iv(&pt->x);
                                
                                oldpressure = pt->pressure;
                        }
                        else
--                              glVertex2f(pt->x, pt->y);
++                              glVertex2iv(&pt->x);
                }
                glEnd();
  
@@@ -162,7 -162,7 +159,7 @@@ static void gp_draw_stroke_point (bGPDs
        /* draw point */
        if (sflag & GP_STROKE_3DSPACE) {
                glBegin(GL_POINTS);
--                      glVertex3f(points->x, points->y, points->z);
++                      glVertex3fv(&points->x);
                glEnd();
        }
        else {
@@@ -228,18 -228,18 +225,16 @@@ static void gp_draw_stroke_3d (bGPDspoi
                        glBegin(GL_LINE_STRIP);
                        
                        /* need to roll-back one point to ensure that there are no gaps in the stroke */
--                      if (i != 0) {
--                              pt--;
--                              glVertex3f(pt->x, pt->y, pt->z);
--                              pt++;
--                      }
++                      if (i != 0) glVertex3fv(&(pt - 1)->x);
++
                        /* now the point we want... */
--                      glVertex3f(pt->x, pt->y, pt->z);
++                      glVertex3fv(&pt->x);
                        
                        oldpressure = pt->pressure;
                }
--              else
--                      glVertex3f(pt->x, pt->y, pt->z);
++              else {
++                      glVertex3fv(&pt->x);
++              }
        }
        glEnd();
        
        if (debug) {
                glBegin(GL_POINTS);
                for (i=0, pt=points; i < totpoints && pt; i++, pt++)
--                      glVertex3f(pt->x, pt->y, pt->z);
++                      glVertex3fv(&pt->x);
                glEnd();
        }
  }
@@@ -461,7 -461,7 +456,7 @@@ static void gp_draw_stroke (bGPDspoint 
                glBegin(GL_POINTS);
                for (i=0, pt=points; i < totpoints && pt; i++, pt++) {
                        if (sflag & GP_STROKE_2DSPACE) {
--                              glVertex2f(pt->x, pt->y);
++                              glVertex2fv(&pt->x);
                        }
                        else if (sflag & GP_STROKE_2DIMAGE) {
                                const float x= (float)((pt->x * winx) + offsx);
@@@ -331,8 -331,8 +331,7 @@@ static short gp_stroke_addpoint (tGPsda
                        pt= (tGPspoint *)(gpd->sbuffer);
                        
                        /* store settings */
--                      pt->x= mval[0];
--                      pt->y= mval[1];
++                      copy_v2_v2_int(&pt->x, mval);
                        pt->pressure= pressure;
                        
                        /* increment buffer size */
                        pt= ((tGPspoint *)(gpd->sbuffer) + 1);
                        
                        /* store settings */
--                      pt->x= mval[0];
--                      pt->y= mval[1];
++                      copy_v2_v2_int(&pt->x, mval);
                        pt->pressure= pressure;
                        
                        /* if this is just the second point we've added, increment the buffer size
                pt= ((tGPspoint *)(gpd->sbuffer) + gpd->sbuffer_size);
                
                /* store settings */
--              pt->x= mval[0];
--              pt->y= mval[1];
++              copy_v2_v2_int(&pt->x, mval);
                pt->pressure= pressure;
                
                /* increment counters */
                pt= (tGPspoint *)(gpd->sbuffer);
  
                /* store settings */
--              pt->x= mval[0];
--              pt->y= mval[1];
++              copy_v2_v2_int(&pt->x, mval);
                pt->pressure= pressure;
  
                /* if there's stroke for this poly line session add (or replace last) point
@@@ -475,9 -475,9 +471,8 @@@ static void gp_stroke_smooth (tGPsdata 
        /* second pass: apply smoothed coordinates */
        for (i=0, spc=smoothArray; i < gpd->sbuffer_size; i++, spc++) {
                tGPspoint *pc= (((tGPspoint *)gpd->sbuffer) + i);
--              
--              pc->x = spc->x;
--              pc->y = spc->y;
++
++              copy_v2_v2_int(&pc->x, &spc->x);
        }
        
        /* free temp array */
@@@ -653,7 -653,7 +648,7 @@@ static void gp_stroke_newfrombuffer (tG
                        depth_arr= MEM_mallocN(sizeof(float) * gpd->sbuffer_size, "depth_points");
  
                        for (i=0, ptc=gpd->sbuffer; i < gpd->sbuffer_size; i++, ptc++, pt++) {
--                              mval[0]= ptc->x; mval[1]= ptc->y;
++                              copy_v2_v2_int(mval, &ptc->x);
  
                                if ((ED_view3d_autodist_depth(p->ar, mval, depth_margin, depth_arr+i) == 0) &&
                                        (i && (ED_view3d_autodist_depth_seg(p->ar, mval, mval_prev, depth_margin + 1, depth_arr+i) == 0))
@@@ -121,6 -122,6 +122,7 @@@ typedef struct uiLayout uiLayout
  #define UI_RETURN_OK        2       /* choice made */
  #define UI_RETURN_OUT       4       /* left the menu */
  #define UI_RETURN_UPDATE    8       /* update the button that opened */
++#define UI_RETURN_POPUP_OK  16      /* popup is ok to be handled */
  
        /* block->flag bits 12-15 are identical to but->flag bits */
  
@@@ -277,6 -278,6 +279,30 @@@ void uiDrawBoxVerticalShade(int mode, f
  #define UI_SCROLL_NO_OUTLINE  4
  void uiWidgetScrollDraw(struct uiWidgetColors *wcol, struct rcti *rect, struct rcti *slider, int state);
  
++/* Callbacks
++ *
++ * uiBlockSetHandleFunc/ButmFunc are for handling events through a callback.
++ * HandleFunc gets the retval passed on, and ButmFunc gets a2. The latter is
++ * mostly for compatibility with older code.
++ *
++ * uiButSetCompleteFunc is for tab completion.
++ *
++ * uiButSearchFunc is for name buttons, showing a popup with matches
++ *
++ * uiBlockSetFunc and uiButSetFunc are callbacks run when a button is used,
++ * in case events, operators or RNA are not sufficient to handle the button.
++ *
++ * uiButSetNFunc will free the argument with MEM_freeN. */
++
++typedef struct uiSearchItems uiSearchItems;
++
++typedef void (*uiButHandleFunc)(struct bContext *C, void *arg1, void *arg2);
++typedef void (*uiButHandleRenameFunc)(struct bContext *C, void *arg, char *origstr);
++typedef void (*uiButHandleNFunc)(struct bContext *C, void *argN, void *arg2);
++typedef void (*uiButCompleteFunc)(struct bContext *C, char *str, void *arg);
++typedef void (*uiButSearchFunc)(const struct bContext *C, void *arg, const char *str, uiSearchItems *items);
++typedef void (*uiBlockHandleFunc)(struct bContext *C, void *arg, int event);
++
  /* Menu Callbacks */
  
  typedef void (*uiMenuCreateFunc)(struct bContext *C, struct uiLayout *layout, void *arg1);
@@@ -312,7 -313,7 +338,7 @@@ typedef void (*uiBlockCancelFunc)(void 
  
  void uiPupBlock(struct bContext *C, uiBlockCreateFunc func, void *arg);
  void uiPupBlockO(struct bContext *C, uiBlockCreateFunc func, void *arg, const char *opname, int opcontext);
--void uiPupBlockEx(struct bContext *C, uiBlockCreateFunc func, uiBlockCancelFunc cancel_func, void *arg);
++void uiPupBlockEx(struct bContext *C, uiBlockCreateFunc func, uiBlockHandleFunc popup_func, uiBlockCancelFunc cancel_func, void *arg);
  /* void uiPupBlockOperator(struct bContext *C, uiBlockCreateFunc func, struct wmOperator *op, int opcontext); */ /* UNUSED */
  
  void uiPupBlockClose(struct bContext *C, uiBlock *block);
@@@ -527,30 -529,30 +554,6 @@@ void uiSetButLink(struct uiBut *but,  v
  void uiComposeLinks(uiBlock *block);
  uiBut *uiFindInlink(uiBlock *block, void *poin);
  
--/* Callbacks
-- *
-- * uiBlockSetHandleFunc/ButmFunc are for handling events through a callback.
-- * HandleFunc gets the retval passed on, and ButmFunc gets a2. The latter is
-- * mostly for compatibility with older code.
-- *
-- * uiButSetCompleteFunc is for tab completion.
-- *
-- * uiButSearchFunc is for name buttons, showing a popup with matches
-- *
-- * uiBlockSetFunc and uiButSetFunc are callbacks run when a button is used,
-- * in case events, operators or RNA are not sufficient to handle the button.
-- *
-- * uiButSetNFunc will free the argument with MEM_freeN. */
--
--typedef struct uiSearchItems uiSearchItems;
--
--typedef void (*uiButHandleFunc)(struct bContext *C, void *arg1, void *arg2);
--typedef void (*uiButHandleRenameFunc)(struct bContext *C, void *arg, char *origstr);
--typedef void (*uiButHandleNFunc)(struct bContext *C, void *argN, void *arg2);
--typedef void (*uiButCompleteFunc)(struct bContext *C, char *str, void *arg);
--typedef void (*uiButSearchFunc)(const struct bContext *C, void *arg, const char *str, uiSearchItems *items);
--typedef void (*uiBlockHandleFunc)(struct bContext *C, void *arg, int event);
--              
                /* use inside searchfunc to add items */
  int           uiSearchItemAdd(uiSearchItems *items, const char *name, void *poin, int iconid);
                /* bfunc gets search item *poin as arg2, or if NULL the old string */
@@@ -1018,7 -1027,7 +1027,7 @@@ void uiDrawBlock(const bContext *C, uiB
        glMatrixMode(GL_MODELVIEW);
        glPopMatrix();
  
--      if(multisample_enabled)
++      if(multisample_enabled)
                glEnable(GL_MULTISAMPLE_ARB);
        
        ui_draw_links(block);
  
  static void ui_is_but_sel(uiBut *but, double *value)
  {
--      short push=0, true=1;
++      short is_push=0, is_true=1;
  
--      if(ELEM3(but->type, TOGN, ICONTOGN, OPTIONN)) true= 0;
++      if(ELEM3(but->type, TOGN, ICONTOGN, OPTIONN)) is_true= 0;
  
        if( but->bit ) {
                int lvalue;
                UI_GET_BUT_VALUE_INIT(but, *value)
                lvalue= (int)*value;
--              if( BTST(lvalue, (but->bitnr)) ) push= true;
--              else push= !true;
++              if( BTST(lvalue, (but->bitnr)) ) is_push= is_true;
++              else is_push= !is_true;
        }
        else {
                switch(but->type) {
                case BUT:
--                      push= 2;
++                      is_push= 2;
                        break;
                case HOTKEYEVT:
                case KEYEVT:
--                      push= 2;
++                      is_push= 2;
                        break;
                case TOGBUT:
                case TOG:
                case ICONTOG:
                case OPTION:
                        UI_GET_BUT_VALUE_INIT(but, *value)
--                      if(*value != (double)but->hardmin) push= 1;
++                      if(*value != (double)but->hardmin) is_push= 1;
                        break;
                case ICONTOGN:
                case TOGN:
                case OPTIONN:
                        UI_GET_BUT_VALUE_INIT(but, *value)
--                      if(*value==0.0) push= 1;
++                      if(*value==0.0) is_push= 1;
                        break;
                case ROW:
                case LISTROW:
                        UI_GET_BUT_VALUE_INIT(but, *value)
                        /* support for rna enum buts */
                        if(but->rnaprop && (RNA_property_flag(but->rnaprop) & PROP_ENUM_FLAG)) {
--                              if((int)*value & (int)but->hardmax) push= 1;
++                              if((int)*value & (int)but->hardmax) is_push= 1;
                        }
                        else {
--                              if(*value == (double)but->hardmax) push= 1;
++                              if(*value == (double)but->hardmax) is_push= 1;
                        }
                        break;
                case COL:
--                      push= 2;
++                      is_push= 2;
                        break;
                default:
--                      push= 2;
++                      is_push= 2;
                        break;
                }
        }
        
--      if(push==2);
--      else if(push==1) but->flag |= UI_SELECT;
++      if(is_push==2);
++      else if(is_push==1) but->flag |= UI_SELECT;
        else but->flag &= ~UI_SELECT;
  }
  
@@@ -377,37 -377,37 +377,6 @@@ void uiRoundRect(float minx, float miny
        glDisable( GL_LINE_SMOOTH );
  }
  
--/* plain fake antialiased unfilled round rectangle */
--#if 0 /* UNUSED 2.5 */
--static void uiRoundRectFakeAA(float minx, float miny, float maxx, float maxy, float rad, float asp)
--{
--      float color[4], alpha;
--      float raddiff;
--      int i, passes=4;
--      
--      /* get the color and divide up the alpha */
--      glGetFloatv(GL_CURRENT_COLOR, color);
--      alpha = 1; //color[3];
--      color[3]= 0.5*alpha/(float)passes;
--      glColor4fv(color);
--      
--      /* set the 'jitter amount' */
--      raddiff = (1/(float)passes) * asp;
--      
--      glEnable( GL_BLEND );
--      
--      /* draw lots of lines on top of each other */
--      for (i=passes; i>=(-passes); i--) {
--              uiDrawBox(GL_LINE_LOOP, minx, miny, maxx, maxy, rad+(i*raddiff));
--      }
--      
--      glDisable( GL_BLEND );
--      
--      color[3] = alpha;
--      glColor4fv(color);
--}
--#endif
--
  /* (old, used in outliner) plain antialiased filled box */
  void uiRoundBox(float minx, float miny, float maxx, float maxy, float rad)
  {
@@@ -5853,14 -5861,14 +5861,14 @@@ static void ui_handle_button_return_sub
        menu= data->menu;
  
        /* copy over return values from the closing menu */
--      if(menu->menuretval == UI_RETURN_OK || menu->menuretval == UI_RETURN_UPDATE) {
++      if((menu->menuretval & UI_RETURN_OK) || (menu->menuretval & UI_RETURN_UPDATE)) {
                if(but->type == COL)
                        copy_v3_v3(data->vec, menu->retvec);
                else if(ELEM3(but->type, MENU, ICONROW, ICONTEXTROW))
                        data->value= menu->retvalue;
        }
  
--      if(menu->menuretval == UI_RETURN_UPDATE) {
++      if(menu->menuretval & UI_RETURN_UPDATE) {
                if(data->interactive) ui_apply_button(C, but->block, but, data, 1);
                else ui_check_but(but);
  
        }
        
        /* now change button state or exit, which will close the submenu */
--      if(ELEM(menu->menuretval, UI_RETURN_OK, UI_RETURN_CANCEL)) {
++      if((menu->menuretval & UI_RETURN_OK) || (menu->menuretval & UI_RETURN_CANCEL)) {
                if(menu->menuretval != UI_RETURN_OK)
                        data->cancel= 1;
  
                button_activate_exit(C, data, but, 1, 0);
        }
--      else if(menu->menuretval == UI_RETURN_OUT) {
++      else if(menu->menuretval & UI_RETURN_OUT) {
                if(event->type==MOUSEMOVE && ui_mouse_inside_button(data->region, but, event->x, event->y)) {
                        button_activate_state(C, but, BUTTON_STATE_HIGHLIGHT);
                }
@@@ -6089,7 -6097,7 +6097,7 @@@ static int ui_handle_menu_event(bContex
                                /* closing sublevels of pulldowns */
                                case LEFTARROWKEY:
                                        if(event->val==KM_PRESS && (block->flag & UI_BLOCK_LOOP))
--                                              if(BLI_countlist(&block->saferct) > 0)
++                                              if(block->saferct.first)
                                                        menu->menuretval= UI_RETURN_OUT;
  
                                        retval= WM_UI_HANDLER_BREAK;
                                /* enter will always close this block, we let the event
                                 * get handled by the button if it is activated, otherwise we cancel */
                                if(!ui_but_find_activated(ar))
--                                      menu->menuretval= UI_RETURN_CANCEL;
++                                      menu->menuretval= UI_RETURN_CANCEL | UI_RETURN_POPUP_OK;
                        }
                        else {
                                ui_mouse_motion_towards_check(block, menu, mx, my);
         * buttons inside this region. disabled inside check .. not sure
         * anymore why it was there? but it meant enter didn't work
         * for example when mouse was not over submenu */
--      if((/*inside &&*/ (!menu->menuretval || menu->menuretval == UI_RETURN_UPDATE) && retval == WM_UI_HANDLER_CONTINUE) || event->type == TIMER) {
++      if((/*inside &&*/ (!menu->menuretval || (menu->menuretval & UI_RETURN_UPDATE)) && retval == WM_UI_HANDLER_CONTINUE) || event->type == TIMER) {
                but= ui_but_find_activated(ar);
  
                if(but) {
@@@ -6411,14 -6419,14 +6419,14 @@@ static int ui_handle_menu_return_submen
        if(submenu->menuretval) {
                /* first decide if we want to close our own menu cascading, if
                 * so pass on the sub menu return value to our own menu handle */
--              if(ELEM(submenu->menuretval, UI_RETURN_OK, UI_RETURN_CANCEL)) {
++              if((submenu->menuretval & UI_RETURN_OK) || (submenu->menuretval & UI_RETURN_CANCEL)) {
                        if(!(block->flag & UI_BLOCK_KEEP_OPEN)) {
                                menu->menuretval= submenu->menuretval;
                                menu->butretval= data->retval;
                        }
                }
  
--              update= (submenu->menuretval == UI_RETURN_UPDATE);
++              update= (submenu->menuretval & UI_RETURN_UPDATE);
  
                /* now let activated button in this menu exit, which
                 * will actually close the submenu too */
@@@ -6591,7 -6599,7 +6599,7 @@@ static int ui_handler_popup(bContext *C
                ui_popup_block_free(C, menu);
                UI_remove_popup_handlers(&CTX_wm_window(C)->modalhandlers, menu);
  
--              if(temp.menuretval == UI_RETURN_OK) {
++              if((temp.menuretval & UI_RETURN_OK) || (temp.menuretval & UI_RETURN_POPUP_OK)) {
                        if(temp.popup_func)
                                temp.popup_func(C, temp.popup_arg, temp.retvalue);
                        if(temp.optype)
@@@ -509,7 -509,7 +509,7 @@@ static void init_internal_icons(void
        bTheme *btheme= UI_GetTheme();
        ImBuf *bbuf= NULL;
        int x, y, icontype;
--      char iconfilestr[FILE_MAXDIR+FILE_MAXFILE];
++      char iconfilestr[FILE_MAX];
        
        if ((btheme!=NULL) && btheme->tui.iconfile[0]) {
                char *icondir= BLI_get_folder(BLENDER_DATAFILES, "icons");
@@@ -2603,7 -2603,7 +2603,7 @@@ void uiPupBlock(bContext *C, uiBlockCre
        uiPupBlockO(C, func, arg, NULL, 0);
  }
  
--void uiPupBlockEx(bContext *C, uiBlockCreateFunc func, uiBlockCancelFunc cancel_func, void *arg)
++void uiPupBlockEx(bContext *C, uiBlockCreateFunc func, uiBlockHandleFunc popup_func, uiBlockCancelFunc cancel_func, void *arg)
  {
        wmWindow *window= CTX_wm_window(C);
        uiPopupBlockHandle *handle;
        handle->retvalue= 1;
  
        handle->popup_arg= arg;
--      // handle->popup_func= operator_cb;
++      handle->popup_func= popup_func;
        handle->cancel_func= cancel_func;
        // handle->opcontext= opcontext;
        
@@@ -124,6 -124,6 +124,7 @@@ static uiStyle *ui_style_new(ListBase *
        style->buttonspacex= 8;
        style->buttonspacey= 2;
        style->panelspace= 8;
++      style->panelouter= 4;
        
        return style;
  }
@@@ -1366,6 -1366,6 +1366,7 @@@ static int convert_exec(bContext *C, wm
                                makeDispListCurveTypes(scene, newob, 0);
  
                        newob->type= OB_CURVE;
++                      cu->type= OB_CURVE;
  
                        if(cu->vfont) {
                                cu->vfont->id.us--;
@@@ -637,7 -637,7 +637,7 @@@ static int fluid_init_filepaths(Object 
        FluidsimSettings *domainSettings= fluidmd->fss; 
        FILE *fileCfg;
        int dirExist = 0;
--      char newSurfdataPath[FILE_MAXDIR+FILE_MAXFILE]; // modified output settings
++      char newSurfdataPath[FILE_MAX]; // modified output settings
        const char *suffixConfig = FLUID_SUFFIX_CONFIG;
        int outStringsChanged = 0;
  
        }
        
        if(targetDir[0] == '\0' || (!dirExist)) {
--              char blendDir[FILE_MAXDIR+FILE_MAXFILE];
--              char blendFile[FILE_MAXDIR+FILE_MAXFILE];
++              char blendDir[FILE_MAX];
++              char blendFile[FILE_MAX];
                
                // invalid dir, reset to current/previous
--              BLI_strncpy(blendDir, G.main->name, FILE_MAXDIR+FILE_MAXFILE);
++              BLI_strncpy(blendDir, G.main->name, FILE_MAX);
                BLI_splitdirstring(blendDir, blendFile);
--              BLI_replace_extension(blendFile, FILE_MAXDIR+FILE_MAXFILE, ""); /* strip .blend */
++              BLI_replace_extension(blendFile, FILE_MAX, ""); /* strip .blend */
  
--              BLI_snprintf(newSurfdataPath, FILE_MAXDIR+FILE_MAXFILE ,"//fluidsimdata/%s_%s_", blendFile, fsDomain->id.name);
++              BLI_snprintf(newSurfdataPath, FILE_MAX ,"//fluidsimdata/%s_%s_", blendFile, fsDomain->id.name);
                
                BLI_snprintf(debugStrBuffer, 256, "fluidsimBake::error - warning resetting output dir to '%s'\n", newSurfdataPath);
                elbeemDebugOut(debugStrBuffer);
        // check if modified output dir is ok
  #if 0
        if(outStringsChanged) {
--              char dispmsg[FILE_MAXDIR+FILE_MAXFILE+256];
++              char dispmsg[FILE_MAX+256];
                int  selection=0;
                BLI_strncpy(dispmsg,"Output settings set to: '", sizeof(dispmsg));
                strcat(dispmsg, newSurfdataPath);
@@@ -810,9 -810,9 +810,9 @@@ static void fluidbake_free_data(FluidAn
  /* copied from rna_fluidsim.c: fluidsim_find_lastframe() */
  static void fluidsim_delete_until_lastframe(FluidsimSettings *fss, const char *relbase)
  {
--      char targetDir[FILE_MAXFILE+FILE_MAXDIR], targetFile[FILE_MAXFILE+FILE_MAXDIR];
--      char targetDirVel[FILE_MAXFILE+FILE_MAXDIR], targetFileVel[FILE_MAXFILE+FILE_MAXDIR];
--      char previewDir[FILE_MAXFILE+FILE_MAXDIR], previewFile[FILE_MAXFILE+FILE_MAXDIR];
++      char targetDir[FILE_MAX], targetFile[FILE_MAX];
++      char targetDirVel[FILE_MAX], targetFileVel[FILE_MAX];
++      char previewDir[FILE_MAX], previewFile[FILE_MAX];
        int curFrame = 1, exists = 0;
  
        BLI_join_dirfile(targetDir,    sizeof(targetDir),    fss->surfdataPath, OB_FLUIDSIM_SURF_FINAL_OBJ_FNAME);
@@@ -859,8 -859,8 +859,8 @@@ static int fluidsimBake(bContext *C, Re
        const char *suffixConfig = FLUID_SUFFIX_CONFIG;
        const char *suffixSurface = FLUID_SUFFIX_SURFACE;
  
--      char targetDir[FILE_MAXDIR+FILE_MAXFILE];  // store & modify output settings
--      char targetFile[FILE_MAXDIR+FILE_MAXFILE]; // temp. store filename from targetDir for access
++      char targetDir[FILE_MAX];  // store & modify output settings
++      char targetFile[FILE_MAX]; // temp. store filename from targetDir for access
        int  outStringsChanged = 0;             // modified? copy back before baking
  
        float domainMat[4][4];
@@@ -321,7 -321,7 +321,9 @@@ static int ptcache_add_new_exec(bContex
        
        for(pid=pidlist.first; pid; pid=pid->next) {
                if(pid->cache == cache) {
--                      *(pid->cache_ptr) = BKE_ptcache_add(pid->ptcaches);
++                      PointCache *cache = BKE_ptcache_add(pid->ptcaches);
++                      cache->step = pid->default_step;
++                      *(pid->cache_ptr) = cache;
                        break;
                }
        }
@@@ -392,7 -392,7 +392,7 @@@ static int screen_opengl_render_anim_st
        Scene *scene= oglrender->scene;
        ImBuf *ibuf;
        void *lock;
--      char name[FILE_MAXDIR+FILE_MAXFILE];
++      char name[FILE_MAX];
        int ok= 0;
        const short  view_context= (oglrender->v3d != NULL);
        Object *camera= NULL;
@@@ -160,8 -160,8 +160,8 @@@ static int screenshot_exec(bContext *C
  
                        /* BKE_add_image_extension() checks for if extension was already set */
                        if(scene->r.scemode & R_EXTENSION)
--                              if(strlen(path)<FILE_MAXDIR+FILE_MAXFILE-5)
-                                       BKE_add_image_extension(path, scene->r.imtype);
++                              if(strlen(path)<FILE_MAX-5)
+                                       BKE_add_image_extension(path, scene->r.im_format.imtype);
  
                        ibuf= IMB_allocImBuf(scd->dumpsx, scd->dumpsy, 24, 0);
                        ibuf->rect= scd->dumprect;
@@@ -294,14 -294,14 +294,14 @@@ static void screenshot_startjob(void *s
                                        break;
                        }
                        else {
-                               ImBuf *ibuf= IMB_allocImBuf(sj->dumpsx, sj->dumpsy, rd.planes, 0);
-                               char name[FILE_MAXDIR+FILE_MAXFILE];
+                               ImBuf *ibuf= IMB_allocImBuf(sj->dumpsx, sj->dumpsy, rd.im_format.planes, 0);
 -                              char name[FILE_MAXDIR+FILE_MAXFILE];
++                              char name[FILE_MAX];
                                int ok;
                                
-                               BKE_makepicstring(name, rd.pic, sj->bmain->name, cfra, rd.imtype, rd.scemode & R_EXTENSION, TRUE);
+                               BKE_makepicstring(name, rd.pic, sj->bmain->name, cfra, rd.im_format.imtype, rd.scemode & R_EXTENSION, TRUE);
                                
                                ibuf->rect= sj->dumprect;
-                               ok= BKE_write_ibuf(ibuf, name, rd.imtype, rd.subimtype, rd.quality);
+                               ok= BKE_write_ibuf(ibuf, name, &rd.im_format);
                                
                                if(ok==0) {
                                        printf("Write error: cannot save %s\n", name);
@@@ -192,7 -192,7 +192,7 @@@ static int path_drop_poll(bContext *UNU
  
  static void path_drop_copy(wmDrag *drag, wmDropBox *drop)
  {
--      char pathname[FILE_MAXDIR+FILE_MAXFILE+2];
++      char pathname[FILE_MAX+2];
        BLI_snprintf(pathname, sizeof(pathname), "\"%s\"", drag->path);
        RNA_string_set(drop->ptr, "text", pathname);
  }
@@@ -852,7 -852,7 +852,7 @@@ static void filelist_read_library(struc
                file = filelist->filelist;
                for(num=0; num<filelist->numfiles; num++, file++) {
                        if(BLO_has_bfile_extension(file->relname)) {
--                              char name[FILE_MAXDIR+FILE_MAXFILE];
++                              char name[FILE_MAX];
                        
                                BLI_strncpy(name, filelist->dir, sizeof(name));
                                strcat(name, file->relname);
@@@ -988,7 -988,7 +988,7 @@@ void filelist_from_library(struct FileL
        LinkNode *l, *names, *previews;
        struct ImBuf* ima;
        int ok, i, nprevs, nnames, idcode;
--      char filename[FILE_MAXDIR+FILE_MAXFILE];
++      char filename[FILE_MAX];
        char dir[FILE_MAX], group[GROUP_MAX];   
        
        /* name test */
@@@ -1180,7 -1179,7 +1180,7 @@@ void filelist_from_main(struct FileLis
                                        if(id->lib==NULL)
                                                files->relname= BLI_strdup(id->name+2);
                                        else {
--                                              files->relname= MEM_mallocN(FILE_MAXDIR+FILE_MAXFILE+32, "filename for lib");
++                                              files->relname= MEM_mallocN(FILE_MAX+32, "filename for lib");
                                                sprintf(files->relname, "%s | %s", id->lib->name, id->name+2);
                                        }
                                        files->type |= S_IFREG;
@@@ -326,13 -326,13 +326,13 @@@ void fsmenu_read_system(struct FSMenu* 
                for (i=1; err!=nsvErr; i++)
                {
                        FSRef dir;
--                      unsigned char path[FILE_MAXDIR+FILE_MAXFILE];
++                      unsigned char path[FILE_MAX];
                        
                        err = FSGetVolumeInfo(kFSInvalidVolumeRefNum, i, NULL, kFSVolInfoNone, NULL, NULL, &dir);
                        if (err != noErr)
                                continue;
                        
--                      FSRefMakePath(&dir, path, FILE_MAXDIR+FILE_MAXFILE);
++                      FSRefMakePath(&dir, path, FILE_MAX);
                        if (strcmp((char*)path, "/home") && strcmp((char*)path, "/net"))
                        { /* /net and /home are meaningless on OSX, home folders are stored in /Users */
                                fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM, (char *)path, 1, 0);
                        FSRef dir;
                        FSVolumeRefNum volRefNum;
                        struct GetVolParmsInfoBuffer volParmsBuffer;
--                      unsigned char path[FILE_MAXDIR+FILE_MAXFILE];
++                      unsigned char path[FILE_MAX];
                        
                        err = FSGetVolumeInfo(kFSInvalidVolumeRefNum, i, &volRefNum, kFSVolInfoNone, NULL, NULL, &dir);
                        if (err != noErr)
                                continue;
                        
                        
--                      FSRefMakePath(&dir, path, FILE_MAXDIR+FILE_MAXFILE);
++                      FSRefMakePath(&dir, path, FILE_MAX);
                        fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM, (char *)path, 1, 0);
                }
                
@@@ -1086,8 -1074,10 +1074,10 @@@ static void save_image_doit(bContext *C
                        }
                        BKE_image_release_renderresult(scene, ima);
                }
-               else if (BKE_write_ibuf(ibuf, simopts->filepath, simopts->imtype, simopts->subimtype, simopts->quality)) {
-                       ok= TRUE;
+               else {
 -                      if (BKE_write_ibuf(ibuf, simopts->filepath, &simopts->im_format)) {
++                      if (BKE_write_ibuf_as(ibuf, simopts->filepath, &simopts->im_format, save_copy)) {
+                               ok= TRUE;
+                       }
                }
  
                if (ok) {
@@@ -927,15 -933,15 +933,16 @@@ void drawnodespace(const bContext *C, A
        if(snode->nodetree) {
                bNode *node;
                
--              /* init ui blocks for opened node group trees first 
--               * so they're in the correct depth stack order */
++              node_uiblocks_init(C, snode->nodetree);
++              
++              /* uiBlocks must be initialized in drawing order for correct event clipping.
++               * Node group internal blocks added after the main group block.
++               */
                for(node= snode->nodetree->nodes.first; node; node= node->next) {
                        if(node->flag & NODE_GROUP_EDIT)
                                node_uiblocks_init(C, (bNodeTree *)node->id);
                }
                
--              node_uiblocks_init(C, snode->nodetree);
--              
                node_update_nodetree(C, snode->nodetree, 0.0f, 0.0f);
                node_draw_nodetree(C, ar, snode, snode->nodetree);
                
@@@ -297,8 -297,8 +297,6 @@@ static void object_delete_cb(bContext *
        if(base==NULL) 
                base= object_in_scene((Object *)tselem->id, scene);
        if(base) {
--              SpaceOops *soops= CTX_wm_space_outliner(C);
--
                // check also library later
                if(scene->obedit==base->object) 
                        ED_object_exit_editmode(C, EM_FREEDATA|EM_FREEUNDO|EM_WAITCURSOR|EM_DO_UNDO);
                ED_base_object_free_and_unlink(CTX_data_main(C), scene, base);
                te->directdata= NULL;
                tselem->id= NULL;
--
--              /* XXX: tree management normally happens from draw_outliner(), but when
--                      you're clicking to fast on Delete object from context menu in
--                      outliner several mouse events can be handled in one cycle without
--                      handling notifiers/redraw which leads to deleting the same object twice.
--                      cleanup tree here to prevent such cases. */
--              outliner_cleanup_tree(soops);
        }
--
  }
  
  static void id_local_cb(bContext *UNUSED(C), Scene *UNUSED(scene), TreeElement *UNUSED(te), TreeStoreElem *UNUSED(tsep), TreeStoreElem *tselem)
@@@ -579,6 -579,6 +569,14 @@@ static int outliner_object_operation_ex
        }
        else if(event==4) {
                outliner_do_object_operation(C, scene, soops, &soops->tree, object_delete_cb);
++
++              /* XXX: tree management normally happens from draw_outliner(), but when
++                      you're clicking to fast on Delete object from context menu in
++                      outliner several mouse events can be handled in one cycle without
++                      handling notifiers/redraw which leads to deleting the same object twice.
++                      cleanup tree here to prevent such cases. */
++              outliner_cleanup_tree(soops);
++
                DAG_scene_sort(bmain, scene);
                str= "Delete Objects";
                WM_event_add_notifier(C, NC_SCENE|ND_OB_ACTIVE, scene);
@@@ -512,7 -512,7 +512,7 @@@ static void draw_seq_extensions(Scene *
  static void draw_seq_text(View2D *v2d, Sequence *seq, float x1, float x2, float y1, float y2, const unsigned char background_col[3])
  {
        rctf rect;
--      char str[32 + FILE_MAXDIR+FILE_MAXFILE];
++      char str[32 + FILE_MAX];
        const char *name= seq->name+2;
        char col[4];
  
@@@ -449,9 -449,9 +449,9 @@@ static void txt_write_file(Text *text, 
        FILE *fp;
        TextLine *tmp;
        struct stat st;
--      char filepath[FILE_MAXDIR+FILE_MAXFILE];
++      char filepath[FILE_MAX];
        
--      BLI_strncpy(filepath, text->name, FILE_MAXDIR+FILE_MAXFILE);
++      BLI_strncpy(filepath, text->name, FILE_MAX);
        BLI_path_abs(filepath, G.main->name);
        
        fp= fopen(filepath, "w");
@@@ -3053,12 -3053,12 +3053,12 @@@ int text_file_modified(Text *text
  {
        struct stat st;
        int result;
--      char file[FILE_MAXDIR+FILE_MAXFILE];
++      char file[FILE_MAX];
  
        if(!text || !text->name)
                return 0;
  
--      BLI_strncpy(file, text->name, FILE_MAXDIR+FILE_MAXFILE);
++      BLI_strncpy(file, text->name, FILE_MAX);
        BLI_path_abs(file, G.main->name);
  
        if(!BLI_exists(file))
@@@ -3082,11 -3082,11 +3082,11 @@@ static void text_ignore_modified(Text *
  {
        struct stat st;
        int result;
--      char file[FILE_MAXDIR+FILE_MAXFILE];
++      char file[FILE_MAX];
  
        if(!text || !text->name) return;
  
--      BLI_strncpy(file, text->name, FILE_MAXDIR+FILE_MAXFILE);
++      BLI_strncpy(file, text->name, FILE_MAX);
        BLI_path_abs(file, G.main->name);
  
        if(!BLI_exists(file)) return;
        ((ELEM(vd->drawtype, OB_TEXTURE, OB_MATERIAL) && dt>OB_SOLID) ||          \
        (vd->drawtype==OB_SOLID && vd->flag2 & V3D_SOLID_TEX))
  
++typedef enum eWireDrawMode {
++      OBDRAW_WIRE_OFF= 0,
++      OBDRAW_WIRE_ON= 1,
++      OBDRAW_WIRE_ON_DEPTH= 2
++} eWireDrawMode;
++
  static void draw_bounding_volume(Scene *scene, Object *ob, char type);
  
  static void drawcube_size(float size);
@@@ -1093,7 -1093,7 +1099,12 @@@ static void drawlamp(Scene *scene, View
        /* cone can't be drawn for duplicated lamps, because duplilist would be freed to */
        /* the moment of view3d_draw_transp() call */
        const short is_view= (rv3d->persp==RV3D_CAMOB && v3d->camera == base->object);
--      const short drawcone= (dt>OB_WIRE && !(G.f & G_PICKSEL) && (la->type == LA_SPOT) && (la->mode & LA_SHOW_CONE) && !(base->flag & OB_FROMDUPLI) && !is_view);
++      const short drawcone= ((dt > OB_WIRE) &&
++                             !(G.f & G_PICKSEL) &&
++                             (la->type == LA_SPOT) &&
++                             (la->mode & LA_SHOW_CONE) &&
++                             !(base->flag & OB_FROMDUPLI) &&
++                             !is_view);
  
        if(drawcone && !v3d->transp) {
                /* in this case we need to draw delayed */
@@@ -1568,7 -1568,7 +1579,7 @@@ static void draw_viewport_reconstructio
  
                        glBegin(GL_LINE_STRIP);
                                for(a= 0; a<reconstruction->camnr; a++, camera++) {
--                                      glVertex3f(camera->mat[3][0], camera->mat[3][1], camera->mat[3][2]);
++                                      glVertex3fv(camera->mat[3]);
                                }
                        glEnd();
  
@@@ -1806,7 -1806,7 +1817,7 @@@ static void drawlattice__point(Lattice 
                float col[3];
                MDeformWeight *mdw= defvert_find_index (lt->dvert+index, use_wcol-1);
                
--              weight_to_rgb(mdw?mdw->weight:0.0f, col, col+1, col+2);
++              weight_to_rgb(col, mdw?mdw->weight:0.0f);
                glColor3fv(col);
  
        }
@@@ -2944,7 -2912,7 +2949,7 @@@ static void draw_mesh_fancy(Scene *scen
        Mesh *me = ob->data;
        Material *ma= give_current_material(ob, 1);
        const short hasHaloMat = (ma && (ma->material_type == MA_TYPE_HALO));
--      int draw_wire = 0;
++      eWireDrawMode draw_wire= OBDRAW_WIRE_OFF;
        int /* totvert,*/ totedge, totface;
        DerivedMesh *dm= mesh_get_derived_final(scene, ob, scene->customdata_mask);
        ModifierData *md = NULL;
                        }
                }
        }
--      
--      if (ob->dtx&OB_DRAWWIRE) {
--              draw_wire = 2; /* draw wire after solid using zoffset and depth buffer adjusment */
++
++      /* Unwanted combination */
++      if (draw_flags & DRAW_FACE_SELECT) {
++              draw_wire= OBDRAW_WIRE_OFF;
++      }
++      else if (ob->dtx & OB_DRAWWIRE) {
++              draw_wire= OBDRAW_WIRE_ON_DEPTH; /* draw wire after solid using zoffset and depth buffer adjusment */
        }
        
        /* totvert = dm->getNumVerts(dm); */ /*UNUSED*/
        /* vertexpaint, faceselect wants this, but it doesnt work for shaded? */
        glFrontFace((ob->transflag&OB_NEG_SCALE)?GL_CW:GL_CCW);
  
--              // Unwanted combination.
--      if (draw_flags & DRAW_FACE_SELECT) draw_wire = 0;
--
        if(dt==OB_BOUNDBOX) {
                if((v3d->flag2 & V3D_RENDER_OVERRIDE && v3d->drawtype >= OB_WIRE)==0)
                        draw_bounding_volume(scene, ob, ob->boundtype);
                glPointSize(1.0);
        }
        else if(dt==OB_WIRE || totface==0) {
--              draw_wire = 1; /* draw wire only, no depth buffer stuff  */
++              draw_wire= OBDRAW_WIRE_ON; /* draw wire only, no depth buffer stuff  */
        }
--      else if(        (draw_flags & DRAW_FACE_SELECT || (ob==OBACT && ob->mode & OB_MODE_TEXTURE_PAINT)) ||
--                              CHECK_OB_DRAWTEXTURE(v3d, dt))
++      else if ( (draw_flags & DRAW_FACE_SELECT || (ob==OBACT && ob->mode & OB_MODE_TEXTURE_PAINT)) ||
++                CHECK_OB_DRAWTEXTURE(v3d, dt))
        {
--              if ((v3d->flag&V3D_SELECT_OUTLINE) && ((v3d->flag2 & V3D_RENDER_OVERRIDE)==0) && (base->flag&SELECT) && !(G.f&G_PICKSEL || (draw_flags & DRAW_FACE_SELECT)) && !draw_wire) {
++              if ( (v3d->flag & V3D_SELECT_OUTLINE) &&
++                   ((v3d->flag2 & V3D_RENDER_OVERRIDE)==0) &&
++                   (base->flag & SELECT) &&
++                   !(G.f & G_PICKSEL || (draw_flags & DRAW_FACE_SELECT)) &&
++                   (draw_wire == OBDRAW_WIRE_OFF))
++              {
                        draw_mesh_object_outline(v3d, ob, dm);
                }
  
                        GPU_disable_material();
                        
                        /* since we already draw wire as wp guide, dont draw over the top */
--                      draw_wire= 0;
++                      draw_wire= OBDRAW_WIRE_OFF;
                }
                else if (draw_flags & DRAW_DYNAMIC_PAINT_PREVIEW) {
                        /* for object selection draws no shade */
                        }
                        else {
                                /* draw outline */
--                              if((v3d->flag&V3D_SELECT_OUTLINE) && ((v3d->flag2 & V3D_RENDER_OVERRIDE)==0) && (base->flag&SELECT) && !draw_wire && !ob->sculpt)
++                              if ( (v3d->flag & V3D_SELECT_OUTLINE) &&
++                                   ((v3d->flag2 & V3D_RENDER_OVERRIDE)==0) &&
++                                   (base->flag & SELECT) &&
++                                   (draw_wire == OBDRAW_WIRE_OFF) &&
++                                   (ob->sculpt == NULL))
++                              {
                                        draw_mesh_object_outline(v3d, ob, dm);
++                              }
  
                                /* materials arent compatible with vertex colors */
                                GPU_end_object_materials();
                else {
                        Paint *p;
  
--                      if((v3d->flag&V3D_SELECT_OUTLINE) && ((v3d->flag2 & V3D_RENDER_OVERRIDE)==0) && (base->flag&SELECT) && !draw_wire && !ob->sculpt)
++                      if ( (v3d->flag & V3D_SELECT_OUTLINE) &&
++                           ((v3d->flag2 & V3D_RENDER_OVERRIDE)==0) &&
++                           (base->flag & SELECT) &&
++                           (draw_wire == OBDRAW_WIRE_OFF) &&
++                           (ob->sculpt == NULL))
++                      {
                                draw_mesh_object_outline(v3d, ob, dm);
++                      }
  
                        glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, me->flag & ME_TWOSIDED );
  
                        }
                }
        }
--      if (draw_wire) {
++      if (draw_wire != OBDRAW_WIRE_OFF) {
  
                /* When using wireframe object traw in particle edit mode
                 * the mesh gets in the way of seeing the particles, fade the wire color
                 * if draw wire is 1 then just drawing wire, no need for depth buffer stuff,
                 * otherwise this wire is to overlay solid mode faces so do some depth buffer tricks.
                 */
--              if (dt!=OB_WIRE && draw_wire==2) {
++              if (dt!=OB_WIRE && (draw_wire == OBDRAW_WIRE_ON_DEPTH)) {
                        bglPolygonOffset(rv3d->dist, 1.0);
                        glDepthMask(0); // disable write in zbuffer, selected edge wires show better
                }
                if((v3d->flag2 & V3D_RENDER_OVERRIDE && v3d->drawtype >= OB_SOLID)==0)
                        dm->drawEdges(dm, (dt==OB_WIRE || totface==0), me->drawflag & ME_ALLEDGES);
  
--              if (dt!=OB_WIRE && draw_wire==2) {
++              if (dt!=OB_WIRE && (draw_wire == OBDRAW_WIRE_ON_DEPTH)) {
                        glDepthMask(1);
                        bglPolygonOffset(rv3d->dist, 0.0);
                }
@@@ -3267,15 -3235,15 +3290,11 @@@ static int draw_mesh_object(Scene *scen
  
                if(dt>OB_WIRE) {
                        glsl = draw_glsl_material(scene, ob, v3d, dt);
--                      check_alpha = check_material_alpha(base, glsl);
  
--                      GPU_begin_object_materials(v3d, rv3d, scene, ob, glsl,
--                                      (check_alpha)? &do_alpha_pass: NULL);
++                      GPU_begin_object_materials(v3d, rv3d, scene, ob, glsl, NULL);
                }
  
--              // transp in editmode makes the fancy draw over go bad
--              if (!do_alpha_pass)
--                      draw_em_fancy(scene, v3d, rv3d, ob, em, cageDM, finalDM, dt);
++              draw_em_fancy(scene, v3d, rv3d, ob, em, cageDM, finalDM, dt);
  
                GPU_end_object_materials();
  
@@@ -3728,19 -3696,19 +3747,15 @@@ static void draw_particle(ParticleKey *
        float vec[3], vec2[3];
        float *vd = NULL;
        float *cd = NULL;
--      float ma_r=0.0f;
--      float ma_g=0.0f;
--      float ma_b=0.0f;
++      float ma_col[3]= {0.0f, 0.0f, 0.0f};
  
        /* null only for PART_DRAW_CIRC */
        if(pdd) {
                vd = pdd->vd;
                cd = pdd->cd;
  
--              if(pdd->ma_r) {
--                      ma_r = *pdd->ma_r;
--                      ma_g = *pdd->ma_g;
--                      ma_b = *pdd->ma_b;
++              if(pdd->ma_col) {
++                      copy_v3_v3(ma_col, pdd->ma_col);
                }
        }
  
                                copy_v3_v3(vd,state->co); pdd->vd+=3;
                        }
                        if(cd) {
--                              cd[0]=ma_r;
--                              cd[1]=ma_g;
--                              cd[2]=ma_b;
++                              copy_v3_v3(cd, pdd->ma_col);
                                pdd->cd+=3;
                        }
                        break;
                        }
                        else {
                                if(cd) {
--                                      cd[0]=cd[3]=cd[6]=cd[9]=cd[12]=cd[15]=ma_r;
--                                      cd[1]=cd[4]=cd[7]=cd[10]=cd[13]=cd[16]=ma_g;
--                                      cd[2]=cd[5]=cd[8]=cd[11]=cd[14]=cd[17]=ma_b;
++                                      cd[0]=cd[3]=cd[6]=cd[ 9]=cd[12]=cd[15]= ma_col[0];
++                                      cd[1]=cd[4]=cd[7]=cd[10]=cd[13]=cd[16]= ma_col[1];
++                                      cd[2]=cd[5]=cd[8]=cd[11]=cd[14]=cd[17]= ma_col[2];
                                        pdd->cd+=18;
                                }
                                sub_v3_v3v3(vec2, state->co, vec);
                        madd_v3_v3v3fl(pdd->vd, state->co, vec, -draw_line[0]); pdd->vd+=3;
                        madd_v3_v3v3fl(pdd->vd, state->co, vec,  draw_line[1]); pdd->vd+=3;
                        if(cd) {
--                              cd[0]=cd[3]=ma_r;
--                              cd[1]=cd[4]=ma_g;
--                              cd[2]=cd[5]=ma_b;
++                              cd[0]=cd[3]= ma_col[0];
++                              cd[1]=cd[4]= ma_col[1];
++                              cd[2]=cd[5]= ma_col[2];
                                pdd->cd+=6;
                        }
                        break;
                {
                        float xvec[3], yvec[3], zvec[3], bb_center[3];
                        if(cd) {
--                              cd[0]=cd[3]=cd[6]=cd[9]=ma_r;
--                              cd[1]=cd[4]=cd[7]=cd[10]=ma_g;
--                              cd[2]=cd[5]=cd[8]=cd[11]=ma_b;
++                              cd[0]=cd[3]=cd[6]=cd[ 9]= ma_col[0];
++                              cd[1]=cd[4]=cd[7]=cd[10]= ma_col[1];
++                              cd[2]=cd[5]=cd[8]=cd[11]= ma_col[2];
                                pdd->cd+=12;
                        }
  
@@@ -3899,7 -3867,7 +3912,7 @@@ static void draw_new_particle_system(Sc
        float timestep, pixsize=1.0, pa_size, r_tilt, r_length;
        float pa_time, pa_birthtime, pa_dietime, pa_health, intensity;
        float cfra;
--      float ma_r=0.0f, ma_g=0.0f, ma_b=0.0f;
++      float ma_col[3]= {0.0f, 0.0f, 0.0f};
        int a, totpart, totpoint=0, totve=0, drawn, draw_as, totchild=0;
        int select=ob->flag&SELECT, create_cdata=0, need_v=0;
        GLint polygonmode[2];
  
        if((ma) && (part->draw_col == PART_DRAW_COL_MAT)) {
                rgb_float_to_byte(&(ma->r), tcol);
--
--              ma_r = ma->r;
--              ma_g = ma->g;
--              ma_b = ma->b;
++              copy_v3_v3(ma_col, &ma->r);
        }
  
        glColor3ubv(tcol);
        }
  
        if(pdd) {
--              pdd->ma_r = &ma_r;
--              pdd->ma_g = &ma_g;
--              pdd->ma_b = &ma_b;
++              pdd->ma_col= ma_col;
        }
  
        psys->lattice= psys_get_lattice(&sim);
                                                        intensity= 1.0f; /* should never happen */
                                        }
                                        CLAMP(intensity, 0.f, 1.f);
--                                      weight_to_rgb(intensity, &ma_r, &ma_g, &ma_b);
++                                      weight_to_rgb(ma_col, intensity);
                                }
                        }
                        else{
                }
  
                /* restore from select */
--              glColor3f(ma_r,ma_g,ma_b);
++              glColor3fv(ma_col);
                glPointSize(part->draw_size ? part->draw_size : 2.0);
                glLineWidth(1.0);
  
  
        if(pdd) {
                /* drop references to stack memory */
--              pdd->ma_r= pdd->ma_g= pdd->ma_b= NULL;
++              pdd->ma_col= NULL;
        }
  
        if( (base->flag & OB_FROMDUPLI) && (ob->flag & OB_FROMGROUP) ) {
@@@ -1365,142 -1365,142 +1365,6 @@@ static void view3d_panel_preview(bConte
  }
  #endif
  
--#if 0 // XXX not used
--static void delete_sketch_armature(bContext *C, void *arg1, void *arg2)
--{
--      BIF_deleteSketch(C);
--}
--
--static void convert_sketch_armature(bContext *C, void *arg1, void *arg2)
--{
--      BIF_convertSketch(C);
--}
--
--static void assign_template_sketch_armature(bContext *C, void *arg1, void *arg2)
--{
--      int index = *(int*)arg1;
--      BIF_setTemplate(C, index);
--}
--
--
--static int view3d_panel_bonesketch_spaces_poll(const bContext *C, PanelType *pt)
--{
--      Object *obedit = CTX_data_edit_object(C);
--
--      /* replace with check call to sketching lib */
--      return (obedit && obedit->type == OB_ARMATURE);
--}
--static void view3d_panel_bonesketch_spaces(const bContext *C, Panel *pa)
--{
--      Scene *scene = CTX_data_scene(C);
--      static int template_index;
--      static char joint_label[128];
--      uiBlock *block;
--      uiBut *but;
--      char *bone_name;
--      int yco = 130;
--      int nb_joints;
--      static char subdiv_tooltip[4][64] = {
--              "Subdivide arcs based on a fixed number of bones",
--              "Subdivide arcs in bones of equal length",
--              "Subdivide arcs based on correlation",
--              "Retarget template to stroke"
--              };
--
--      
--      block= uiLayoutAbsoluteBlock(pa->layout);
--      uiBlockSetHandleFunc(block, do_view3d_region_buttons, NULL);
--
--      uiBlockBeginAlign(block);
--      
--      /* use real flag instead of 1 */
--      uiDefButBitC(block, TOG, BONE_SKETCHING, B_REDR, "Use Bone Sketching", 10, yco, 160, 20, &scene->toolsettings->bone_sketching, 0, 0, 0, 0, "Use sketching to create and edit bones, (Ctrl snaps to mesh volume)");
--      uiDefButBitC(block, TOG, BONE_SKETCHING_ADJUST, B_REDR, "A", 170, yco, 20, 20, &scene->toolsettings->bone_sketching, 0, 0, 0, 0, "Adjust strokes by drawing near them");
--      uiDefButBitC(block, TOG, BONE_SKETCHING_QUICK, B_REDR, "Q", 190, yco, 20, 20, &scene->toolsettings->bone_sketching, 0, 0, 0, 0, "Automatically convert and delete on stroke end");
--      yco -= 20;
--      
--      but = uiDefBut(block, BUT, B_REDR, "Convert", 10,yco,100,20, 0, 0, 0, 0, 0, "Convert sketch to armature");
--      uiButSetFunc(but, convert_sketch_armature, NULL, NULL);
--
--      but = uiDefBut(block, BUT, B_REDR, "Delete", 110,yco,100,20, 0, 0, 0, 0, 0, "Delete sketch");
--      uiButSetFunc(but, delete_sketch_armature, NULL, NULL);
--      yco -= 20;
--      
--      uiBlockEndAlign(block);
--
--      uiBlockBeginAlign(block);
--      
--      uiDefButC(block, MENU, B_REDR, "Subdivision Method%t|Length%x1|Adaptative%x2|Fixed%x0|Template%x3", 10,yco,60,19, &scene->toolsettings->bone_sketching_convert, 0, 0, 0, 0, subdiv_tooltip[(unsigned char)scene->toolsettings->bone_sketching_convert]);
--
--      switch(scene->toolsettings->bone_sketching_convert)
--      {
--      case SK_CONVERT_CUT_LENGTH:
--              uiDefButF(block, NUM, B_REDR,                                   "Lim:",         70, yco, 140, 19, &scene->toolsettings->skgen_length_limit,0.1,50.0, 10, 0,             "Maximum length of the subdivided bones");
--              yco -= 20;
--              break;
--      case SK_CONVERT_CUT_ADAPTATIVE:
--              uiDefButF(block, NUM, B_REDR,                                   "Thres:",                       70, yco, 140, 19, &scene->toolsettings->skgen_correlation_limit,0.0, 1.0, 0.01, 0,      "Correlation threshold for subdivision");
--              yco -= 20;
--              break;
--      default:
--      case SK_CONVERT_CUT_FIXED:
--              uiDefButC(block, NUM, B_REDR,                                   "Num:",         70, yco, 140, 19, &scene->toolsettings->skgen_subdivision_number,1, 100, 1, 5,  "Number of subdivided bones");
--              yco -= 20;
--              break;
--      case SK_CONVERT_RETARGET:
--              uiDefButC(block, ROW, B_NOP, "No",                      70,  yco, 40,19, &scene->toolsettings->skgen_retarget_roll, 0, 0, 0, 0,                                                                 "No special roll treatment");
--              uiDefButC(block, ROW, B_NOP, "View",            110,  yco, 50,19, &scene->toolsettings->skgen_retarget_roll, 0, SK_RETARGET_ROLL_VIEW, 0, 0,                            "Roll bones perpendicular to view");
--              uiDefButC(block, ROW, B_NOP, "Joint",           160, yco, 50,19, &scene->toolsettings->skgen_retarget_roll, 0, SK_RETARGET_ROLL_JOINT, 0, 0,                            "Roll bones relative to joint bend");
--              yco -= 30;
--
--              uiBlockEndAlign(block);
--
--              uiBlockBeginAlign(block);
--              /* button here to select what to do (copy or not), template, ...*/
--
--              BIF_makeListTemplates(C);
--              template_index = BIF_currentTemplate(C);
--              
--              but = uiDefButI(block, MENU, B_REDR, BIF_listTemplates(C), 10,yco,200,19, &template_index, 0, 0, 0, 0, "Template");
--              uiButSetFunc(but, assign_template_sketch_armature, &template_index, NULL);
--              
--              yco -= 20;
--              
--              uiDefButF(block, NUM, B_NOP,                                                    "A:",                   10, yco, 66,19, &scene->toolsettings->skgen_retarget_angle_weight, 0, 10, 1, 0,         "Angle Weight");
--              uiDefButF(block, NUM, B_NOP,                                                    "L:",                   76, yco, 67,19, &scene->toolsettings->skgen_retarget_length_weight, 0, 10, 1, 0,                "Length Weight");
--              uiDefButF(block, NUM, B_NOP,                                                    "D:",           143,yco, 67,19, &scene->toolsettings->skgen_retarget_distance_weight, 0, 10, 1, 0,              "Distance Weight");
--              yco -= 20;
--              
--              uiDefBut(block, TEX,B_REDR,"S:",                                                        10,  yco, 90, 20, scene->toolsettings->skgen_side_string, 0.0, 8.0, 0, 0, "Text to replace &S with");
--              uiDefBut(block, TEX,B_REDR,"N:",                                                        100, yco, 90, 20, scene->toolsettings->skgen_num_string, 0.0, 8.0, 0, 0, "Text to replace &N with");
--              uiDefIconButBitC(block, TOG, SK_RETARGET_AUTONAME, B_NOP, ICON_AUTO,190,yco,20,20, &scene->toolsettings->skgen_retarget_options, 0, 0, 0, 0, "Use Auto Naming");        
--              yco -= 20;
--
--              /* auto renaming magic */
--              uiBlockEndAlign(block);
--              
--              nb_joints = BIF_nbJointsTemplate(C);
--
--              if (nb_joints == -1)
--              {
--                      //XXX
--                      //nb_joints = G.totvertsel;
--              }
--              
--              bone_name = BIF_nameBoneTemplate(C);
--              
--              BLI_snprintf(joint_label, 32, "%i joints: %s", nb_joints, bone_name);
--              
--              uiDefBut(block, LABEL, 1, joint_label,                                  10, yco, 200, 20, NULL, 0.0, 0.0, 0, 0, "");
--              yco -= 20;
--              break;
--      }
--
--      uiBlockEndAlign(block);
--}
--
--#endif // XXX not used
--
  void view3d_buttons_register(ARegionType *art)
  {
        PanelType *pt;
@@@ -1329,7 -1329,7 +1329,7 @@@ static void backdrawview3d(Scene *scene
        v3d->zbuf= FALSE; 
        glDisable(GL_DEPTH_TEST);
        glEnable(GL_DITHER);
--      if(multisample_enabled)
++      if(multisample_enabled)
                glEnable(GL_MULTISAMPLE_ARB);
  
        if(rv3d->rflag & RV3D_CLIPPING)
@@@ -164,7 -164,7 +164,7 @@@ void unpack_menu(bContext *C, const cha
        PointerRNA props_ptr;
        uiPopupMenu *pup;
        uiLayout *layout;
--      char line[FILE_MAXDIR + FILE_MAXFILE + 100];
++      char line[FILE_MAX + 100];
  
        pup= uiPupMenuBegin(C, "Unpack file", ICON_NONE);
        layout= uiPupMenuLayout(pup);
@@@ -219,7 -219,7 +219,7 @@@ static void draw_uvs_stretch(SpaceImag
                                                else
                                                        areadiff = 1.0f-(area/uvarea);
                                                
--                                              weight_to_rgb(areadiff, col, col+1, col+2);
++                                              weight_to_rgb(col, areadiff);
                                                glColor3fv(col);
                                                
                                                glBegin(efa->v4?GL_QUADS:GL_TRIANGLES);
                                                 * 1.0-powf((1.0-a), 2) */
                                                
                                                a = fabsf(uvang1-ang1)/(float)M_PI;
--                                              weight_to_rgb(1.0f-powf((1.0f-a), 2.0f), col, col+1, col+2);
++                                              weight_to_rgb(col, 1.0f-powf((1.0f-a), 2.0f));
                                                glColor3fv(col);
                                                glVertex2fv(tf->uv[0]);
                                                a = fabsf(uvang2-ang2)/(float)M_PI;
--                                              weight_to_rgb(1.0f-powf((1.0f-a), 2.0f), col, col+1, col+2);
++                                              weight_to_rgb(col, 1.0f-powf((1.0f-a), 2.0f));
                                                glColor3fv(col);
                                                glVertex2fv(tf->uv[1]);
                                                a = fabsf(uvang3-ang3)/(float)M_PI;
--                                              weight_to_rgb(1.0f-powf((1.0f-a), 2.0f), col, col+1, col+2);
++                                              weight_to_rgb(col, 1.0f-powf((1.0f-a), 2.0f));
                                                glColor3fv(col);
                                                glVertex2fv(tf->uv[2]);
                                                a = fabsf(uvang4-ang4)/(float)M_PI;
--                                              weight_to_rgb(1.0f-powf((1.0f-a), 2.0f), col, col+1, col+2);
++                                              weight_to_rgb(col, 1.0f-powf((1.0f-a), 2.0f));
                                                glColor3fv(col);
                                                glVertex2fv(tf->uv[3]);
                                                
                                                
                                                glBegin(GL_TRIANGLES);
                                                a = fabsf(uvang1-ang1)/(float)M_PI;
--                                              weight_to_rgb(1.0f-powf((1.0f-a), 2.0f), col, col+1, col+2);
++                                              weight_to_rgb(col, 1.0f-powf((1.0f-a), 2.0f));
                                                glColor3fv(col);
                                                glVertex2fv(tf->uv[0]);
                                                a = fabsf(uvang2-ang2)/(float)M_PI;
--                                              weight_to_rgb(1.0f-powf((1.0f-a), 2.0f), col, col+1, col+2);
++                                              weight_to_rgb(col, 1.0f-powf((1.0f-a), 2.0f));
                                                glColor3fv(col);
                                                glVertex2fv(tf->uv[1]);
                                                a = fabsf(uvang3-ang3)/(float)M_PI;
--                                              weight_to_rgb(1.0f-powf((1.0f-a), 2.0f), col, col+1, col+2);
++                                              weight_to_rgb(col, 1.0f-powf((1.0f-a), 2.0f));
                                                glColor3fv(col);
                                                glVertex2fv(tf->uv[2]);
                                        }
index 01d416e,0000000..103255d
mode 100644,000000..100644
--- /dev/null
@@@ -1,356 -1,0 +1,356 @@@
-       freestyle_scene->r.planes = R_PLANES32;
-       freestyle_scene->r.imtype = R_PNG;
 +# include "BlenderStrokeRenderer.h"
 +# include "../stroke/Canvas.h"
 +# include "../application/AppConfig.h"
 +
 +# include "BlenderTextureManager.h"
 +
 +#ifdef __cplusplus
 +extern "C" {
 +#endif
 +
 +#include "MEM_guardedalloc.h"
 +
 +#include "DNA_camera_types.h"
 +#include "DNA_customdata_types.h"
 +#include "DNA_listBase.h"
 +#include "DNA_mesh_types.h"
 +#include "DNA_meshdata_types.h"
 +#include "DNA_object_types.h"
 +#include "DNA_screen_types.h"
 +
 +#include "BKE_customdata.h"
 +#include "BKE_global.h"
 +#include "BKE_library.h" /* free_libblock */
 +#include "BKE_material.h"
 +#include "BKE_main.h" /* struct Main */
 +#include "BKE_object.h"
 +#include "BKE_scene.h"
 +
 +#include "RE_pipeline.h"
 +
 +#ifdef __cplusplus
 +}
 +#endif
 +
 +
 +BlenderStrokeRenderer::BlenderStrokeRenderer(Render* re, int render_count)
 +:StrokeRenderer(){
 +      
 +      // TEMPORARY - need a  texture manager
 +      _textureManager = new BlenderTextureManager;
 +      _textureManager->load();
 +
 +      _width = re->winx; _height = re->winy; // for stroke mesh generation
 +
 +      // Scene.New("FreestyleStrokes")
 +      old_scene = re->scene;
 +
 +      char name[22];
 +      snprintf(name, sizeof(name), "FRS%d_%s", render_count, re->scene->id.name+2);
 +      freestyle_scene = add_scene(name);
 +      freestyle_scene->r.cfra = old_scene->r.cfra;
 +      freestyle_scene->r.mode= old_scene->r.mode &
 +              ~( R_EDGE_FRS | R_SHADOW | R_SSS | R_PANORAMA | R_ENVMAP | R_MBLUR | R_BORDER );
 +      freestyle_scene->r.xsch= re->rectx; // old_scene->r.xsch
 +      freestyle_scene->r.ysch= re->recty; // old_scene->r.ysch
 +      freestyle_scene->r.xasp= old_scene->r.xasp;
 +      freestyle_scene->r.yasp= old_scene->r.yasp;
 +      freestyle_scene->r.xparts= old_scene->r.xparts;
 +      freestyle_scene->r.yparts= old_scene->r.yparts;
 +      freestyle_scene->r.size= 100; // old_scene->r.size
 +      freestyle_scene->r.maximsize= old_scene->r.maximsize;
 +      freestyle_scene->r.ocres = old_scene->r.ocres;
 +      freestyle_scene->r.color_mgt_flag = old_scene->r.color_mgt_flag;
 +      freestyle_scene->r.scemode= old_scene->r.scemode & ~( R_SINGLE_LAYER );
 +      freestyle_scene->r.flag= old_scene->r.flag;
 +      freestyle_scene->r.threads= old_scene->r.threads;
 +      freestyle_scene->r.border.xmin= old_scene->r.border.xmin;
 +      freestyle_scene->r.border.ymin= old_scene->r.border.ymin;
 +      freestyle_scene->r.border.xmax= old_scene->r.border.xmax;
 +      freestyle_scene->r.border.ymax= old_scene->r.border.ymax;
 +      strcpy(freestyle_scene->r.pic, old_scene->r.pic);
 +      freestyle_scene->r.safety.xmin= old_scene->r.safety.xmin;
 +      freestyle_scene->r.safety.ymin= old_scene->r.safety.ymin;
 +      freestyle_scene->r.safety.xmax= old_scene->r.safety.xmax;
 +      freestyle_scene->r.safety.ymax= old_scene->r.safety.ymax;
 +      freestyle_scene->r.osa= old_scene->r.osa;
 +      freestyle_scene->r.filtertype= old_scene->r.filtertype;
 +      freestyle_scene->r.gauss= old_scene->r.gauss;
 +      freestyle_scene->r.dither_intensity= old_scene->r.dither_intensity;
 +      BLI_strncpy(freestyle_scene->r.engine, old_scene->r.engine, sizeof(freestyle_scene->r.engine));
++      freestyle_scene->r.im_format.planes = R_IMF_PLANES_RGBA; 
++      freestyle_scene->r.im_format.imtype = R_IMF_IMTYPE_PNG;
 +      set_scene_bg( G.main, freestyle_scene );
 +
 +      // Camera
 +      Object* object_camera = add_object(freestyle_scene, OB_CAMERA);
 +      
 +      Camera* camera = (Camera *) object_camera->data;
 +      camera->type = CAM_ORTHO;
 +      camera->ortho_scale = max(re->rectx, re->recty);
 +    camera->clipsta = 0.1f;
 +    camera->clipend = 100.0f;
 +
 +    _z_delta = 0.00001f;
 +    _z = camera->clipsta + _z_delta;
 +
 +    // test
 +    //_z = 999.90f; _z_delta = 0.01f;
 +
 +      object_camera->loc[0] = re->disprect.xmin + 0.5f * re->rectx;
 +      object_camera->loc[1] = re->disprect.ymin + 0.5f * re->recty;
 +      object_camera->loc[2] = 1.f;
 +      
 +      freestyle_scene->camera = object_camera;
 +      
 +      // Material
 +      material = add_material("stroke_material");
 +      material->mode |= MA_VERTEXCOLP;
 +      material->mode |= MA_TRANSP;
 +      material->mode |= MA_SHLESS;
 +      material->vcol_alpha = 1;
 +}
 +
 +BlenderStrokeRenderer::~BlenderStrokeRenderer(){
 +      
 +      if(0 != _textureManager)
 +      {
 +              delete _textureManager;
 +              _textureManager = 0;
 +      }
 +
 +      // The freestyle_scene object is not released here.  Instead,
 +      // the scene is released in free_all_freestyle_renders() in
 +      // source/blender/render/intern/source/pipeline.c, after the
 +      // compositor has finished.
 +
 +      // release objects and data blocks
 +      Base *b = (Base *)freestyle_scene->base.first;
 +      while(b) {
 +              Object *ob = b->object;
 +              void *data = ob->data;
 +              char name[24];
 +              strcpy(name, ob->id.name);
 +              //cout << "removing " << name[0] << name[1] << ":" << (name+2) << endl;
 +              switch (ob->type) {
 +              case OB_MESH:
 +                      free_libblock( &G.main->object, ob );
 +                      free_libblock( &G.main->mesh, data );
 +                      break;
 +              case OB_CAMERA:
 +                      free_libblock( &G.main->object, ob );
 +                      free_libblock( &G.main->camera, data );
 +                      freestyle_scene->camera = NULL;
 +                      break;
 +              default:
 +                      cerr << "Warning: unexpected object in the scene: " << name[0] << name[1] << ":" << (name+2) << endl;
 +              }
 +              b = b->next;
 +      }
 +      BLI_freelistN( &freestyle_scene->base );
 +
 +      // release material
 +      free_libblock( &G.main->mat, material );
 +      
 +      set_scene_bg( G.main, old_scene );
 +}
 +
 +float BlenderStrokeRenderer::get_stroke_vertex_z(void) const {
 +    float z = _z;
 +    BlenderStrokeRenderer *self = const_cast<BlenderStrokeRenderer *>(this);
 +    if (!(_z < _z_delta * 100000.0f))
 +        self->_z_delta *= 10.0f;
 +    self->_z += _z_delta;
 +    return -z;
 +}
 +
 +void BlenderStrokeRenderer::RenderStrokeRep(StrokeRep *iStrokeRep) const{
 +  RenderStrokeRepBasic(iStrokeRep);
 +}
 +
 +void BlenderStrokeRenderer::RenderStrokeRepBasic(StrokeRep *iStrokeRep) const{
 +      
 +      ////////////////////
 +      //  Build up scene
 +      ////////////////////
 +      
 +        vector<Strip*>& strips = iStrokeRep->getStrips();
 +        Strip::vertex_container::iterator v[3];
 +        StrokeVertexRep *svRep[3];
 +        Vec3r color[3];
 +        unsigned int vertex_index;
 +        Vec2r p;
 +      
 +        for(vector<Strip*>::iterator s=strips.begin(), send=strips.end();
 +        s!=send;
 +        ++s){         
 +              
 +          Strip::vertex_container& strip_vertices = (*s)->vertices();
 +              int strip_vertex_count = (*s)->sizeStrip();
 +              int m, n, visible_faces, visible_segments;
 +              bool visible;
 +
 +              // iterate over all vertices and count visible faces and strip segments
 +              // (note: a strip segment is a series of visible faces, while two strip
 +              // segments are separated by one or more invisible faces)
 +              v[0] = strip_vertices.begin();
 +          v[1] = v[0]; ++(v[1]);
 +          v[2] = v[1]; ++(v[2]);
 +              visible_faces = visible_segments = 0;
 +              visible = false;
 +          for (n = 2; n < strip_vertex_count; n++)
 +              {
 +                      svRep[0] = *(v[0]);
 +                      svRep[1] = *(v[1]);
 +                      svRep[2] = *(v[2]);
 +                      m = 0;
 +                      for (int j = 0; j < 3; j++) {
 +                              p = svRep[j]->point2d();
 +                              if (p[0] < 0.0 || p[0] > _width || p[1] < 0.0 || p[1] > _height)
 +                                      m++;
 +                      }
 +                      if (m == 3) {
 +                              visible = false;
 +                      } else {
 +                              visible_faces++;
 +                              if (!visible)
 +                                      visible_segments++;
 +                              visible = true;
 +                      }
 +                      ++v[0]; ++v[1]; ++v[2];
 +              }
 +              if (visible_faces == 0)
 +                      continue;
 +
 +              // me = Mesh.New()
 +              Object* object_mesh = add_object(freestyle_scene, OB_MESH);
 +              Mesh* mesh = (Mesh *) object_mesh->data;
 +              MEM_freeN(mesh->bb);
 +              mesh->bb= NULL;
 +              mesh->id.us = 0;
 +              
 +#if 1
 +              // me.materials = [mat]
 +              mesh->mat = ( Material ** ) MEM_mallocN( 1 * sizeof( Material * ), "MaterialList" );
 +              mesh->mat[0] = material;
 +              mesh->totcol = 1;
 +              test_object_materials( (ID*) mesh );
 +#else
 +              assign_material(object_mesh, material, object_mesh->totcol+1);
 +              object_mesh->actcol= object_mesh->totcol;
 +#endif
 +              
 +              // vertices allocation
 +              mesh->totvert = visible_faces + visible_segments * 2;
 +              mesh->mvert = (MVert*) CustomData_add_layer( &mesh->vdata, CD_MVERT, CD_CALLOC, NULL, mesh->totvert);
 +                      
 +              // faces allocation
 +              mesh->totface = visible_faces;
 +              mesh->mface = (MFace*) CustomData_add_layer( &mesh->fdata, CD_MFACE, CD_CALLOC, NULL, mesh->totface);
 +              
 +              // colors allocation  - me.vertexColors = True
 +              mesh->mcol = (MCol *) CustomData_add_layer( &mesh->fdata, CD_MCOL, CD_CALLOC, NULL, mesh->totface );
 +
 +              ////////////////////
 +              //  Data copy
 +              ////////////////////
 +              
 +              MVert* vertices = mesh->mvert;
 +              MFace* faces = mesh->mface;
 +              MCol* colors = mesh->mcol;
 +              
 +          v[0] = strip_vertices.begin();
 +          v[1] = v[0]; ++(v[1]);
 +          v[2] = v[1]; ++(v[2]);
 +
 +              vertex_index = 0;
 +              visible = false;
 +              
 +          for (n = 2; n < strip_vertex_count; n++)
 +              {
 +                      svRep[0] = *(v[0]);
 +                      svRep[1] = *(v[1]);
 +                      svRep[2] = *(v[2]);
 +                      m = 0;
 +                      for (int j = 0; j < 3; j++) {
 +                              p = svRep[j]->point2d();
 +                              if (p[0] < 0.0 || p[0] > _width || p[1] < 0.0 || p[1] > _height)
 +                                      m++;
 +                      }
 +                      if (m == 3) {
 +                              visible = false;
 +                      } else {
 +                              if (!visible) {
 +                                      vertex_index += 2;
 +
 +                                      // first vertex
 +                                      vertices->co[0] = svRep[0]->point2d()[0];
 +                                      vertices->co[1] = svRep[0]->point2d()[1];
 +                                      vertices->co[2] = get_stroke_vertex_z();
 +                                      ++vertices;
 +                                      
 +                                      // second vertex
 +                                      vertices->co[0] = svRep[1]->point2d()[0];
 +                                      vertices->co[1] = svRep[1]->point2d()[1];
 +                                      vertices->co[2] = get_stroke_vertex_z();
 +                                      ++vertices;
 +                              }
 +                              visible = true;
 +
 +                              // vertex
 +                              vertices->co[0] = svRep[2]->point2d()[0];
 +                              vertices->co[1] = svRep[2]->point2d()[1];
 +                              vertices->co[2] = get_stroke_vertex_z();
 +                              
 +                              // faces
 +                              faces->v1 = vertex_index - 2;
 +                              faces->v2 = vertex_index - 1;
 +                              faces->v3 = vertex_index;
 +                              faces->v4 = 0;
 +                              
 +                              // colors
 +                              // red and blue are swapped - cf DNA_meshdata_types.h : MCol    
 +                              color[0] = svRep[0]->color();
 +                              color[1] = svRep[1]->color();
 +                              color[2] = svRep[2]->color();
 +
 +  &n