Merge branch 'master' into blender2.8
authorBastien Montagne <montagne29@wanadoo.fr>
Sat, 6 Aug 2016 10:25:24 +0000 (12:25 +0200)
committerBastien Montagne <montagne29@wanadoo.fr>
Sat, 6 Aug 2016 10:45:03 +0000 (12:45 +0200)
Conflicts:
release/scripts/startup/bl_ui/properties_particle.py
release/scripts/startup/bl_ui/properties_physics_cloth.py
release/scripts/startup/bl_ui/properties_physics_dynamicpaint.py
release/scripts/startup/bl_ui/properties_physics_softbody.py
source/blender/blenkernel/BKE_library.h
source/blender/blenkernel/BKE_particle.h
source/blender/blenkernel/intern/cloth.c
source/blender/blenkernel/intern/library.c
source/blender/blenkernel/intern/library_query.c
source/blender/blenkernel/intern/particle_system.c
source/blender/blenkernel/intern/scene.c
source/blender/blenkernel/intern/softbody.c
source/blender/blenloader/intern/readfile.c
source/blender/blenloader/intern/versioning_270.c
source/blender/editors/space_file/filesel.c
source/blender/editors/space_outliner/outliner_intern.h
source/blender/makesdna/DNA_ID.h
source/blender/makesdna/DNA_object_force.h
source/blender/makesdna/DNA_particle_types.h
source/blender/makesrna/intern/rna_particle.c
source/blender/makesrna/intern/rna_sculpt_paint.c
source/blender/makesrna/intern/rna_smoke.c
source/blender/makesrna/intern/rna_space.c

90 files changed:
1  2 
intern/cycles/blender/addon/properties.py
intern/cycles/blender/addon/ui.py
intern/cycles/blender/blender_object.cpp
intern/cycles/blender/blender_util.h
intern/ghost/intern/GHOST_WindowCocoa.mm
intern/ghost/intern/GHOST_WindowX11.cpp
release/scripts/startup/bl_ui/properties_data_modifier.py
release/scripts/startup/bl_ui/properties_physics_cloth.py
release/scripts/startup/bl_ui/properties_physics_common.py
release/scripts/startup/bl_ui/properties_physics_dynamicpaint.py
release/scripts/startup/bl_ui/properties_physics_smoke.py
release/scripts/startup/bl_ui/properties_physics_softbody.py
release/scripts/startup/bl_ui/space_dopesheet.py
release/scripts/startup/bl_ui/space_view3d.py
release/scripts/startup/bl_ui/space_view3d_toolbar.py
source/blender/CMakeLists.txt
source/blender/blenkernel/BKE_cloth.h
source/blender/blenkernel/BKE_context.h
source/blender/blenkernel/BKE_library.h
source/blender/blenkernel/BKE_main.h
source/blender/blenkernel/CMakeLists.txt
source/blender/blenkernel/intern/anim_sys.c
source/blender/blenkernel/intern/bpath.c
source/blender/blenkernel/intern/cloth.c
source/blender/blenkernel/intern/context.c
source/blender/blenkernel/intern/depsgraph.c
source/blender/blenkernel/intern/idcode.c
source/blender/blenkernel/intern/library.c
source/blender/blenkernel/intern/library_query.c
source/blender/blenkernel/intern/library_remap.c
source/blender/blenkernel/intern/object_dupli.c
source/blender/blenkernel/intern/scene.c
source/blender/blenkernel/intern/smoke.c
source/blender/blenkernel/intern/softbody.c
source/blender/blenloader/intern/readfile.c
source/blender/blenloader/intern/versioning_270.c
source/blender/blenloader/intern/versioning_defaults.c
source/blender/blenloader/intern/writefile.c
source/blender/blentranslation/BLT_translation.h
source/blender/depsgraph/intern/builder/deg_builder_nodes.cc
source/blender/depsgraph/intern/builder/deg_builder_relations.cc
source/blender/editors/animation/anim_channels_defines.c
source/blender/editors/animation/anim_channels_edit.c
source/blender/editors/animation/anim_filter.c
source/blender/editors/include/ED_anim_api.h
source/blender/editors/interface/interface_icons.c
source/blender/editors/interface/interface_templates.c
source/blender/editors/object/object_add.c
source/blender/editors/object/object_relations.c
source/blender/editors/screen/screen_context.c
source/blender/editors/space_file/filesel.c
source/blender/editors/space_nla/nla_buttons.c
source/blender/editors/space_nla/nla_channels.c
source/blender/editors/space_outliner/outliner_draw.c
source/blender/editors/space_outliner/outliner_intern.h
source/blender/editors/space_outliner/outliner_tree.c
source/blender/editors/space_time/space_time.c
source/blender/editors/space_view3d/drawobject.c
source/blender/editors/space_view3d/view3d_edit.c
source/blender/editors/transform/transform.c
source/blender/editors/transform/transform.h
source/blender/editors/transform/transform_conversions.c
source/blender/editors/transform/transform_generics.c
source/blender/editors/transform/transform_manipulator.c
source/blender/editors/transform/transform_snap.c
source/blender/makesdna/DNA_ID.h
source/blender/makesdna/DNA_modifier_types.h
source/blender/makesdna/DNA_object_force.h
source/blender/makesdna/DNA_scene_types.h
source/blender/makesdna/DNA_space_types.h
source/blender/makesdna/intern/makesdna.c
source/blender/makesrna/RNA_access.h
source/blender/makesrna/RNA_enum_types.h
source/blender/makesrna/intern/CMakeLists.txt
source/blender/makesrna/intern/makesrna.c
source/blender/makesrna/intern/rna_ID.c
source/blender/makesrna/intern/rna_color.c
source/blender/makesrna/intern/rna_internal.h
source/blender/makesrna/intern/rna_main.c
source/blender/makesrna/intern/rna_main_api.c
source/blender/makesrna/intern/rna_modifier.c
source/blender/makesrna/intern/rna_object_force.c
source/blender/makesrna/intern/rna_scene.c
source/blender/makesrna/intern/rna_sculpt_paint.c
source/blender/makesrna/intern/rna_space.c
source/blender/modifiers/CMakeLists.txt
source/blender/modifiers/MOD_modifiertypes.h
source/blender/modifiers/intern/MOD_util.c
source/blender/render/intern/source/pipeline.c
source/blenderplayer/bad_level_call_stubs/stubs.c

@@@ -46,12 -46,6 +46,6 @@@ enum_displacement_methods = 
      ('BOTH', "Both", "Combination of displacement and bump mapping"),
      )
  
- enum_subdivision_types = (
-     ('NONE', "None", "No subdivision"),
-     ('LINEAR', "Linear", "Use linear subdivision"),
-     ('CATMULL_CLARK', "Catmull–Clark", "Use Catmull-Clark subdivision"),
-     )
  enum_bvh_types = (
      ('DYNAMIC_BVH', "Dynamic BVH", "Objects can be individually updated, at the cost of slower render time"),
      ('STATIC_BVH', "Static BVH", "Any object modification requires a complete BVH rebuild, but renders faster"),
@@@ -964,18 -958,6 +958,6 @@@ class CyclesMeshSettings(bpy.types.Prop
                  items=enum_displacement_methods,
                  default='BUMP',
                  )
-         cls.subdivision_type = EnumProperty(
-                 name="Subdivision Type",
-                 description="Type of subdivision to use",
-                 items=enum_subdivision_types,
-                 default='NONE',
-                 )
-         cls.dicing_rate = FloatProperty(
-                 name="Dicing Rate",
-                 description="Multiplier for scene dicing rate",
-                 min=0.1, max=1000.0,
-                 default=1.0,
-                 )
  
      @classmethod
      def unregister(cls):
          del bpy.types.MetaBall.cycles
  
  
- class CyclesObjectBlurSettings(bpy.types.PropertyGroup):
+ class CyclesObjectSettings(bpy.types.PropertyGroup):
      @classmethod
      def register(cls):
          bpy.types.Object.cycles = PointerProperty(
                  name="Cycles Object Settings",
                  description="Cycles object settings",
                  default=False,
                  )
  
+         cls.use_adaptive_subdivision = BoolProperty(
+                 name="Use Adaptive Subdivision",
+                 description="Use adaptive render time subdivision",
+                 default=False,
+                 )
+         cls.dicing_rate = FloatProperty(
+                 name="Dicing Rate",
+                 description="Multiplier for scene dicing rate",
+                 min=0.1, max=1000.0,
+                 default=1.0,
+                 )
      @classmethod
      def unregister(cls):
          del bpy.types.Object.cycles
@@@ -1085,6 -1078,49 +1078,6 @@@ class CyclesCurveRenderSettings(bpy.typ
          del bpy.types.Scene.cycles_curves
  
  
 -class CyclesCurveSettings(bpy.types.PropertyGroup):
 -    @classmethod
 -    def register(cls):
 -        bpy.types.ParticleSettings.cycles = PointerProperty(
 -                name="Cycles Hair Settings",
 -                description="Cycles hair settings",
 -                type=cls,
 -                )
 -        cls.radius_scale = FloatProperty(
 -                name="Radius Scaling",
 -                description="Multiplier of width properties",
 -                min=0.0, max=1000.0,
 -                default=0.01,
 -                )
 -        cls.root_width = FloatProperty(
 -                name="Root Size",
 -                description="Strand's width at root",
 -                min=0.0, max=1000.0,
 -                default=1.0,
 -                )
 -        cls.tip_width = FloatProperty(
 -                name="Tip Multiplier",
 -                description="Strand's width at tip",
 -                min=0.0, max=1000.0,
 -                default=0.0,
 -                )
 -        cls.shape = FloatProperty(
 -                name="Strand Shape",
 -                description="Strand shape parameter",
 -                min=-1.0, max=1.0,
 -                default=0.0,
 -                )
 -        cls.use_closetip = BoolProperty(
 -                name="Close tip",
 -                description="Set tip radius to zero",
 -                default=True,
 -                )
 -
 -    @classmethod
 -    def unregister(cls):
 -        del bpy.types.ParticleSettings.cycles
 -
 -
  def register():
      bpy.utils.register_class(CyclesRenderSettings)
      bpy.utils.register_class(CyclesCameraSettings)
      bpy.utils.register_class(CyclesWorldSettings)
      bpy.utils.register_class(CyclesVisibilitySettings)
      bpy.utils.register_class(CyclesMeshSettings)
+     bpy.utils.register_class(CyclesObjectSettings)
      bpy.utils.register_class(CyclesCurveRenderSettings)
 -    bpy.utils.register_class(CyclesCurveSettings)
  
  
  def unregister():
      bpy.utils.unregister_class(CyclesLampSettings)
      bpy.utils.unregister_class(CyclesWorldSettings)
      bpy.utils.unregister_class(CyclesMeshSettings)
+     bpy.utils.unregister_class(CyclesObjectSettings)
      bpy.utils.unregister_class(CyclesVisibilitySettings)
      bpy.utils.unregister_class(CyclesCurveRenderSettings)
 -    bpy.utils.unregister_class(CyclesCurveSettings)
@@@ -708,14 -708,6 +708,6 @@@ class Cycles_PT_mesh_displacement(Cycle
          sub.label(text="Displacement:")
          sub.prop(cdata, "displacement_method", text="")
  
-         col = split.column()
-         sub = col.column(align=True)
-         sub.label(text="Subdivision:")
-         sub.prop(cdata, "subdivision_type", text="")
-         if cdata.subdivision_type != 'NONE':
-             sub.prop(cdata, "dicing_rate")
  class CyclesObject_PT_motion_blur(CyclesButtonsPanel, Panel):
      bl_label = "Motion Blur"
      bl_context = "object"
@@@ -895,7 -887,7 +887,7 @@@ class CyclesLamp_PT_lamp(CyclesButtonsP
  
          lamp = context.lamp
          clamp = lamp.cycles
-         cscene = context.scene.cycles
+         cscene = context.scene.cycles
  
          layout.prop(lamp, "type", expand=True)
  
@@@ -1115,7 -1107,7 +1107,7 @@@ class CyclesWorld_PT_settings(CyclesBut
  
          world = context.world
          cworld = world.cycles
-         cscene = context.scene.cycles
+         cscene = context.scene.cycles
  
          split = layout.split()
  
@@@ -1386,6 -1378,37 +1378,6 @@@ class CyclesTexture_PT_colors(CyclesBut
              layout.template_color_ramp(mapping, "color_ramp", expand=True)
  
  
 -class CyclesParticle_PT_textures(CyclesButtonsPanel, Panel):
 -    bl_label = "Textures"
 -    bl_context = "particle"
 -    bl_options = {'DEFAULT_CLOSED'}
 -
 -    @classmethod
 -    def poll(cls, context):
 -        psys = context.particle_system
 -        return psys and CyclesButtonsPanel.poll(context)
 -
 -    def draw(self, context):
 -        layout = self.layout
 -
 -        psys = context.particle_system
 -        part = psys.settings
 -
 -        row = layout.row()
 -        row.template_list("TEXTURE_UL_texslots", "", part, "texture_slots", part, "active_texture_index", rows=2)
 -
 -        col = row.column(align=True)
 -        col.operator("texture.slot_move", text="", icon='TRIA_UP').type = 'UP'
 -        col.operator("texture.slot_move", text="", icon='TRIA_DOWN').type = 'DOWN'
 -        col.menu("TEXTURE_MT_specials", icon='DOWNARROW_HLT', text="")
 -
 -        if not part.active_texture:
 -            layout.template_ID(part, "active_texture", new="texture.new")
 -        else:
 -            slot = part.texture_slots[part.active_texture_index]
 -            layout.template_ID(slot, "texture", new="texture.new")
 -
 -
  class CyclesRender_PT_CurveRendering(CyclesButtonsPanel, Panel):
      bl_label = "Cycles Hair Rendering"
      bl_context = "particle"
@@@ -1534,6 -1557,37 +1526,6 @@@ class CyclesRender_PT_debug(CyclesButto
          col.prop(cscene, "debug_use_opencl_debug", text="Debug")
  
  
 -class CyclesParticle_PT_CurveSettings(CyclesButtonsPanel, Panel):
 -    bl_label = "Cycles Hair Settings"
 -    bl_context = "particle"
 -
 -    @classmethod
 -    def poll(cls, context):
 -        scene = context.scene
 -        ccscene = scene.cycles_curves
 -        psys = context.particle_system
 -        use_curves = ccscene.use_curves and psys
 -        return CyclesButtonsPanel.poll(context) and use_curves and psys.settings.type == 'HAIR'
 -
 -    def draw(self, context):
 -        layout = self.layout
 -
 -        psys = context.particle_settings
 -        cpsys = psys.cycles
 -
 -        row = layout.row()
 -        row.prop(cpsys, "shape", text="Shape")
 -
 -        layout.label(text="Thickness:")
 -        row = layout.row()
 -        row.prop(cpsys, "root_width", text="Root")
 -        row.prop(cpsys, "tip_width", text="Tip")
 -
 -        row = layout.row()
 -        row.prop(cpsys, "radius_scale", text="Scaling")
 -        row.prop(cpsys, "use_closetip", text="Close tip")
 -
 -
  class CyclesScene_PT_simplify(CyclesButtonsPanel, Panel):
      bl_label = "Simplify"
      bl_context = "scene"
          col = split.column()
          col.label(text="Viewport:")
          col.prop(rd, "simplify_subdivision", text="Subdivision")
 -        col.prop(rd, "simplify_child_particles", text="Child Particles")
  
          col = split.column()
          col.label(text="Render:")
          col.prop(rd, "simplify_subdivision_render", text="Subdivision")
 -        col.prop(rd, "simplify_child_particles_render", text="Child Particles")
  
          col = layout.column()
          col.prop(cscene, "use_camera_cull")
@@@ -253,8 -253,18 +253,18 @@@ static bool object_boundbox_clip(Scene 
                                       boundbox[3 * i + 1],
                                       boundbox[3 * i + 2]);
                p = transform_point(&tfm, p);
-               p = transform_perspective(&worldtondc, p);
-               if(p.z >= -margin) {
+               float4 b = make_float4(p.x, p.y, p.z, 1.0f);
+               float4 c = make_float4(dot(worldtondc.x, b),
+                                      dot(worldtondc.y, b),
+                                      dot(worldtondc.z, b),
+                                      dot(worldtondc.w, b));
+               p = float4_to_float3(c / c.w);
+               if(c.z < 0.0f) {
+                       p.x = 1.0f - p.x;
+                       p.y = 1.0f - p.y;
+               }
+               if(c.z >= -margin) {
                        all_behind = false;
                }
                bb_min = min(bb_min, p);
@@@ -385,8 -395,8 +395,8 @@@ Object *BlenderSync::sync_object(BL::Ob
                object->name = b_ob.name().c_str();
                object->pass_id = b_ob.pass_index();
                object->tfm = tfm;
-               object->motion.pre = tfm;
-               object->motion.post = tfm;
+               object->motion.pre = transform_empty();
+               object->motion.post = transform_empty();
                object->use_motion = false;
  
                /* motion blur */
@@@ -453,9 -463,29 +463,9 @@@ static bool object_render_hide(BL::Obje
                                 bool parent_hide,
                                 bool& hide_triangles)
  {
 -      /* check if we should render or hide particle emitter */
 -      BL::Object::particle_systems_iterator b_psys;
 -
 -      bool hair_present = false;
 -      bool show_emitter = false;
 -      bool hide_emitter = false;
        bool hide_as_dupli_parent = false;
        bool hide_as_dupli_child_original = false;
  
 -      for(b_ob.particle_systems.begin(b_psys); b_psys != b_ob.particle_systems.end(); ++b_psys) {
 -              if((b_psys->settings().render_type() == BL::ParticleSettings::render_type_PATH) &&
 -                 (b_psys->settings().type()==BL::ParticleSettings::type_HAIR))
 -                      hair_present = true;
 -
 -              if(b_psys->settings().use_render_emitter())
 -                      show_emitter = true;
 -              else
 -                      hide_emitter = true;
 -      }
 -
 -      if(show_emitter)
 -              hide_emitter = false;
 -
        /* duplicators hidden by default, except dupliframes which duplicate self */
        if(b_ob.is_duplicator())
                if(top_level || b_ob.dupli_type() != BL::Object::dupli_type_FRAMES)
                parent = parent.parent();
        }
        
 -      hide_triangles = hide_emitter;
 +      hide_triangles = false;
  
 -      if(show_emitter) {
 -              return false;
 -      }
 -      else if(hair_present) {
 -              return hide_as_dupli_child_original;
 -      }
 -      else {
 -              return (hide_as_dupli_parent || hide_as_dupli_child_original);
 -      }
 +      return (hide_as_dupli_parent || hide_as_dupli_child_original);
  }
  
  static bool object_render_hide_duplis(BL::Object& b_ob)
@@@ -500,6 -538,7 +510,6 @@@ void BlenderSync::sync_objects(BL::Spac
                light_map.pre_sync();
                mesh_map.pre_sync();
                object_map.pre_sync();
 -              particle_system_map.pre_sync();
                motion_times.clear();
        }
        else {
                                                        BL::Array<int, OBJECT_PERSISTENT_ID_SIZE> persistent_id = b_dup->persistent_id();
  
                                                        /* sync object and mesh or light data */
 -                                                      Object *object = sync_object(b_ob,
 -                                                                                   persistent_id.data,
 -                                                                                   *b_dup,
 -                                                                                   tfm,
 -                                                                                   ob_layer,
 -                                                                                   motion_time,
 -                                                                                   hide_tris,
 -                                                                                   use_camera_cull,
 -                                                                                   camera_cull_margin,
 -                                                                                   &use_portal);
 -
 -                                                      /* sync possible particle data, note particle_id
 -                                                       * starts counting at 1, first is dummy particle */
 -                                                      if(!motion && object) {
 -                                                              sync_dupli_particle(b_ob, *b_dup, object);
 -                                                      }
 -
 +                                                      sync_object(b_ob,
 +                                                                  persistent_id.data,
 +                                                                  *b_dup,
 +                                                                  tfm,
 +                                                                  ob_layer,
 +                                                                  motion_time,
 +                                                                  hide_tris,
 +                                                                  use_camera_cull,
 +                                                                  camera_cull_margin,
 +                                                                  &use_portal);
                                                }
                                        }
  
                        scene->mesh_manager->tag_update(scene);
                if(object_map.post_sync())
                        scene->object_manager->tag_update(scene);
 -              if(particle_system_map.post_sync())
 -                      scene->particle_system_manager->tag_update(scene);
        }
  
        if(motion)
@@@ -45,14 -45,39 +45,39 @@@ static inline BL::Mesh object_to_mesh(B
                                        BL::Scene& scene,
                                        bool apply_modifiers,
                                        bool render,
-                                       bool calc_undeformed)
+                                       bool calc_undeformed,
+                                       bool subdivision)
  {
+       bool subsurf_mod_show_render;
+       bool subsurf_mod_show_viewport;
+       if(subdivision) {
+               BL::Modifier subsurf_mod = object.modifiers[object.modifiers.length()-1];
+               subsurf_mod_show_render = subsurf_mod.show_render();
+               subsurf_mod_show_viewport = subsurf_mod.show_render();
+               subsurf_mod.show_render(false);
+               subsurf_mod.show_viewport(false);
+       }
        BL::Mesh me = data.meshes.new_from_object(scene, object, apply_modifiers, (render)? 2: 1, false, calc_undeformed);
+       if(subdivision) {
+               BL::Modifier subsurf_mod = object.modifiers[object.modifiers.length()-1];
+               subsurf_mod.show_render(subsurf_mod_show_render);
+               subsurf_mod.show_viewport(subsurf_mod_show_viewport);
+       }
        if((bool)me) {
                if(me.use_auto_smooth()) {
                        me.calc_normals_split();
                }
-               me.calc_tessface(true);
+               if(!subdivision) {
+                       me.calc_tessface(true);
+               }
        }
        return me;
  }
@@@ -705,6 -730,33 +730,6 @@@ struct ObjectKey 
        }
  };
  
 -/* Particle System Key */
 -
 -struct ParticleSystemKey {
 -      void *ob;
 -      int id[OBJECT_PERSISTENT_ID_SIZE];
 -
 -      ParticleSystemKey(void *ob_, int id_[OBJECT_PERSISTENT_ID_SIZE])
 -      : ob(ob_)
 -      {
 -              if(id_)
 -                      memcpy(id, id_, sizeof(id));
 -              else
 -                      memset(id, 0, sizeof(id));
 -      }
 -
 -      bool operator<(const ParticleSystemKey& k) const
 -      {
 -              /* first id is particle index, we don't compare that */
 -              if(ob < k.ob)
 -                      return true;
 -              else if(ob == k.ob)
 -                      return memcmp(id+1, k.id+1, sizeof(int)*(OBJECT_PERSISTENT_ID_SIZE-1)) < 0;
 -
 -              return false;
 -      }
 -};
 -
  CCL_NAMESPACE_END
  
  #endif /* __BLENDER_UTIL_H__ */
@@@ -622,8 -622,6 +622,6 @@@ GHOST_WindowCocoa::GHOST_WindowCocoa
                m_lionStyleFullScreen = true;
        }
        
-       [NSApp activateIgnoringOtherApps:YES]; // raise application to front, important for new blender instance animation play case
-       
        [pool drain];
  }
  
@@@ -1087,23 -1085,82 +1085,23 @@@ GHOST_TSuccess GHOST_WindowCocoa::setOr
  GHOST_Context *GHOST_WindowCocoa::newDrawingContext(GHOST_TDrawingContextType type)
  {
        if (type == GHOST_kDrawingContextTypeOpenGL) {
 -#if !defined(WITH_GL_EGL)
  
 -#if defined(WITH_GL_PROFILE_CORE)
 -              GHOST_Context *context = new GHOST_ContextCGL(
 -                      m_wantStereoVisual,
 -                      m_wantNumOfAASamples,
 -                      m_window,
 -                      m_openGLView,
 -                      GL_CONTEXT_CORE_PROFILE_BIT,
 -                      3, 2,
 -                      GHOST_OPENGL_CGL_CONTEXT_FLAGS,
 -                      GHOST_OPENGL_CGL_RESET_NOTIFICATION_STRATEGY);
 -#elif defined(WITH_GL_PROFILE_ES20)
                GHOST_Context *context = new GHOST_ContextCGL(
                        m_wantStereoVisual,
                        m_wantNumOfAASamples,
                        m_window,
                        m_openGLView,
 -                      CGL_CONTEXT_ES2_PROFILE_BIT_EXT,
 -                      2, 0,
 -                      GHOST_OPENGL_CGL_CONTEXT_FLAGS,
 -                      GHOST_OPENGL_CGL_RESET_NOTIFICATION_STRATEGY);
 -#elif defined(WITH_GL_PROFILE_COMPAT)
 -              GHOST_Context *context = new GHOST_ContextCGL(
 -                      m_wantStereoVisual,
 -                      m_wantNumOfAASamples,
 -                      m_window,
 -                      m_openGLView,
 -                      0, // profile bit
 -                      0, 0,
 -                      GHOST_OPENGL_CGL_CONTEXT_FLAGS,
 -                      GHOST_OPENGL_CGL_RESET_NOTIFICATION_STRATEGY);
 -#else
 -#  error
 -#endif
 -
 -#else
  
  #if defined(WITH_GL_PROFILE_CORE)
 -              GHOST_Context *context = new GHOST_ContextEGL(
 -                      m_wantStereoVisual,
 -                      m_wantNumOfAASamples,
 -                      m_window,
 -                      m_openGLView,
 -                      EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT,
 +                      GL_CONTEXT_CORE_PROFILE_BIT,
                        3, 2,
 -                      GHOST_OPENGL_EGL_CONTEXT_FLAGS,
 -                      GHOST_OPENGL_EGL_RESET_NOTIFICATION_STRATEGY,
 -                      EGL_OPENGL_API);
 -#elif defined(WITH_GL_PROFILE_ES20)
 -              GHOST_Context *context = new GHOST_ContextEGL(
 -                      m_wantStereoVisual,
 -                      m_wantNumOfAASamples,
 -                      m_window,
 -                      m_openGLView,
 -                      0, // profile bit
 -                      2, 0,
 -                      GHOST_OPENGL_EGL_CONTEXT_FLAGS,
 -                      GHOST_OPENGL_EGL_RESET_NOTIFICATION_STRATEGY,
 -                      EGL_OPENGL_ES_API);
 -#elif defined(WITH_GL_PROFILE_COMPAT)
 -              GHOST_Context *context = new GHOST_ContextEGL(
 -                      m_wantStereoVisual,
 -                      m_wantNumOfAASamples,
 -                      m_window,
 -                      m_openGLView,
 -                      0, // profile bit
 -                      0, 0,
 -                      GHOST_OPENGL_EGL_CONTEXT_FLAGS,
 -                      GHOST_OPENGL_EGL_RESET_NOTIFICATION_STRATEGY,
 -                      EGL_OPENGL_API);
  #else
 -#  error
 +                      0, // no profile bit
 +                      2, 1,
  #endif
 +                      GHOST_OPENGL_CGL_CONTEXT_FLAGS,
 +                      GHOST_OPENGL_CGL_RESET_NOTIFICATION_STRATEGY);
  
 -#endif
                if (context->initializeDrawingContext())
                        return context;
                else
  #  include "GHOST_ContextGLX.h"
  #endif
  
+ /* for XIWarpPointer */
+ #ifdef WITH_X11_XINPUT
+ #  include <X11/extensions/XInput2.h>
+ #endif
  #if defined(__sun__) || defined(__sun) || defined(__sparc) || defined(__sparc__) || defined(_AIX)
  #  include <strings.h>
  #endif
@@@ -1301,24 -1306,33 +1306,24 @@@ GHOST_WindowX11:
  GHOST_Context *GHOST_WindowX11::newDrawingContext(GHOST_TDrawingContextType type)
  {
        if (type == GHOST_kDrawingContextTypeOpenGL) {
 -#if !defined(WITH_GL_EGL)
  
 +              // During development:
 +              //   try 3.2 compatibility profile
 +              //   fall back to 3.0 if needed
 +              //
 +              // Final Blender 2.8:
 +              //   try 3.2 core profile
 +              //   no fallbacks
 +
 +              const int profile_mask =
  #if defined(WITH_GL_PROFILE_CORE)
 -              GHOST_Context *context = new GHOST_ContextGLX(
 -                      m_wantStereoVisual,
 -                      m_wantNumOfAASamples,
 -                      m_window,
 -                      m_display,
 -                      m_visualInfo,
 -                      (GLXFBConfig)m_fbconfig,
 -                      GLX_CONTEXT_CORE_PROFILE_BIT_ARB,
 -                      3, 2,
 -                      GHOST_OPENGL_GLX_CONTEXT_FLAGS | (m_is_debug_context ? GLX_CONTEXT_DEBUG_BIT_ARB : 0),
 -                      GHOST_OPENGL_GLX_RESET_NOTIFICATION_STRATEGY);
 -#elif defined(WITH_GL_PROFILE_ES20)
 -              GHOST_Context *context = new GHOST_ContextGLX(
 -                      m_wantStereoVisual,
 -                      m_wantNumOfAASamples,
 -                      m_window,
 -                      m_display,
 -                      m_visualInfo,
 -                      (GLXFBConfig)m_fbconfig,
 -                      GLX_CONTEXT_ES2_PROFILE_BIT_EXT,
 -                      2, 0,
 -                      GHOST_OPENGL_GLX_CONTEXT_FLAGS | (m_is_debug_context ? GLX_CONTEXT_DEBUG_BIT_ARB : 0),
 -                      GHOST_OPENGL_GLX_RESET_NOTIFICATION_STRATEGY);
 +                      GLX_CONTEXT_CORE_PROFILE_BIT_ARB;
  #elif defined(WITH_GL_PROFILE_COMPAT)
 +                      GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB;
 +#else
 +#  error // must specify either core or compat at build time
 +#endif
 +
                GHOST_Context *context = new GHOST_ContextGLX(
                        m_wantStereoVisual,
                        m_wantNumOfAASamples,
                        m_display,
                        m_visualInfo,
                        (GLXFBConfig)m_fbconfig,
 -                      0, // profile bit
 -                      0, 0,
 +                      profile_mask,
 +                      3, 2,
                        GHOST_OPENGL_GLX_CONTEXT_FLAGS | (m_is_debug_context ? GLX_CONTEXT_DEBUG_BIT_ARB : 0),
                        GHOST_OPENGL_GLX_RESET_NOTIFICATION_STRATEGY);
 -#else
 -#  error
 -#endif
 -
 -#else
  
 -#if defined(WITH_GL_PROFILE_CORE)
 -              GHOST_Context *context = new GHOST_ContextEGL(
 -                      m_wantStereoVisual,
 -                      m_wantNumOfAASamples,
 -                      m_window,
 -                      m_display,
 -                      EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT,
 -                      3, 2,
 -                      GHOST_OPENGL_EGL_CONTEXT_FLAGS,
 -                      GHOST_OPENGL_EGL_RESET_NOTIFICATION_STRATEGY,
 -                      EGL_OPENGL_API);
 -#elif defined(WITH_GL_PROFILE_ES20)
 -              GHOST_Context *context = new GHOST_ContextEGL(
 -                      m_wantStereoVisual,
 -                      m_wantNumOfAASamples,
 -                      m_window,
 -                      m_display,
 -                      0, // profile bit
 -                      2, 0,
 -                      GHOST_OPENGL_EGL_CONTEXT_FLAGS,
 -                      GHOST_OPENGL_EGL_RESET_NOTIFICATION_STRATEGY,
 -                      EGL_OPENGL_ES_API);
 -#elif defined(WITH_GL_PROFILE_COMPAT)
 -              GHOST_Context *context = new GHOST_ContextEGL(
 -                      m_wantStereoVisual,
 -                      m_wantNumOfAASamples,
 -                      m_window,
 -                      m_display,
 -                      0, // profile bit
 -                      0, 0,
 -                      GHOST_OPENGL_EGL_CONTEXT_FLAGS,
 -                      GHOST_OPENGL_EGL_RESET_NOTIFICATION_STRATEGY,
 -                      EGL_OPENGL_API);
 -#else
 -#  error
 -#endif
 -
 -#endif
                if (context->initializeDrawingContext())
                        return context;
 -              else
 +              else {
                        delete context;
 +
 +                      // since that failed try 3.0 (mostly for Mesa, which doesn't implement compatibility profile)
 +                      context = new GHOST_ContextGLX(
 +                              m_wantStereoVisual,
 +                              m_wantNumOfAASamples,
 +                              m_window,
 +                              m_display,
 +                              m_visualInfo,
 +                              (GLXFBConfig)m_fbconfig,
 +                              0, // no profile bit
 +                              3, 0,
 +                              GHOST_OPENGL_GLX_CONTEXT_FLAGS | (m_is_debug_context ? GLX_CONTEXT_DEBUG_BIT_ARB : 0),
 +                              GHOST_OPENGL_GLX_RESET_NOTIFICATION_STRATEGY);
 +
 +                      if (context->initializeDrawingContext())
 +                              return context;
 +                      else
 +                              delete context;
 +              }
        }
  
        return NULL;
@@@ -1487,7 -1525,21 +1492,21 @@@ setWindowCursorGrab
                        /* use to generate a mouse move event, otherwise the last event
                         * blender gets can be outside the screen causing menus not to show
                         * properly unless the user moves the mouse */
-                       XWarpPointer(m_display, None, None, 0, 0, 0, 0, 0, 0);
+ #ifdef WITH_X11_XINPUT
+                       if ((m_system->m_xinput_version.present) &&
+                           (m_system->m_xinput_version.major_version >= 2))
+                       {
+                               int device_id;
+                               if (XIGetClientPointer(m_display, None, &device_id) != False) {
+                                       XIWarpPointer(m_display, device_id, None, None, 0, 0, 0, 0, 0, 0);
+                               }
+                       }
+                       else
+ #endif
+                       {
+                               XWarpPointer(m_display, None, None, 0, 0, 0, 0, 0, 0);
+                       }
                }
  
                /* Almost works without but important otherwise the mouse GHOST location can be incorrect on exit */
@@@ -151,14 -151,15 +151,15 @@@ class DATA_PT_modifiers(ModifierButtons
          col = split.column()
          col.label(text="Operation:")
          col.prop(md, "operation", text="")
-         row = layout.row()
-         row.label("Solver:")
-         row.prop(md, "solver", expand=True)
  
          col = split.column()
          col.label(text="Object:")
          col.prop(md, "object", text="")
  
+         split = layout.split()
+         split.column().label(text="Solver:")
+         split.column().prop(md, "solver", text="")
          if md.solver == 'BMESH':
              layout.prop(md, "double_threshold")
  
          layout.prop(md, "cache_format")
          layout.prop(md, "filepath")
  
+         if md.cache_format == 'ABC':
+             layout.prop(md, "sub_object")
          layout.label(text="Evaluation:")
          layout.prop(md, "factor", slider=True)
          layout.prop(md, "deform_mode")
          row = split.row()
          row.prop(md, "flip_axis")
  
+     def MESH_SEQUENCE_CACHE(self, layout, ob, md):
+         layout.label(text="Cache File Properties:")
+         box = layout.box()
+         box.template_cache_file(md, "cache_file")
+         cache_file = md.cache_file
+         layout.label(text="Modifier Properties:")
+         box = layout.box()
+         if cache_file is not None:
+             box.prop_search(md, "object_path", cache_file, "object_paths")
+         if ob.type == 'MESH':
+             box.row().prop(md, "read_data")
      def CAST(self, layout, ob, md):
          split = layout.split(percentage=0.25)
  
  
          col = split.column()
  
 -    def PARTICLE_INSTANCE(self, layout, ob, md):
 -        layout.prop(md, "object")
 -        layout.prop(md, "particle_system_index", text="Particle System")
 -
 -        split = layout.split()
 -        col = split.column()
 -        col.label(text="Create From:")
 -        col.prop(md, "use_normal")
 -        col.prop(md, "use_children")
 -        col.prop(md, "use_size")
 -
 -        col = split.column()
 -        col.label(text="Show Particles When:")
 -        col.prop(md, "show_alive")
 -        col.prop(md, "show_unborn")
 -        col.prop(md, "show_dead")
 -
 -        layout.separator()
 -
 -        layout.prop(md, "use_path", text="Create Along Paths")
 -
 -        split = layout.split()
 -        split.active = md.use_path
 -        col = split.column()
 -        col.row().prop(md, "axis", expand=True)
 -        col.prop(md, "use_preserve_shape")
 -
 -        col = split.column()
 -        col.prop(md, "position", slider=True)
 -        col.prop(md, "random_position", text="Random", slider=True)
 -
 -    def PARTICLE_SYSTEM(self, layout, ob, md):
 -        layout.label(text="Settings can be found inside the Particle context")
 -
      def SCREW(self, layout, ob, md):
          split = layout.split()
  
  
          split = layout.split()
          col = split.column()
-         col.label(text="Subdivisions:")
-         col.prop(md, "levels", text="View")
-         col.prop(md, "render_levels", text="Render")
+         engine = bpy.context.scene.render.engine
+         if engine == "CYCLES" and md == ob.modifiers[-1] and bpy.context.scene.cycles.feature_set == "EXPERIMENTAL":
+             col.label(text="Preview:")
+             col.prop(md, "levels", text="Levels")
+             col.label(text="Render:")
+             col.prop(ob.cycles, "use_adaptive_subdivision", text="Adaptive")
+             if ob.cycles.use_adaptive_subdivision:
+                 col.prop(ob.cycles, "dicing_rate")
+             else:
+                 col.prop(md, "render_levels", text="Levels")
+         else:
+             col.label(text="Subdivisions:")
+             col.prop(md, "levels", text="View")
+             col.prop(md, "render_levels", text="Render")
  
          col = split.column()
          col.label(text="Options:")
@@@ -21,10 -21,15 +21,15 @@@ import bp
  from bpy.types import Menu, Panel
  
  from bl_ui.properties_physics_common import (
 -        point_cache_ui,
          effector_weights_ui,
          )
  
  
 -    return md.point_cache.is_baked is False
+ def cloth_panel_enabled(md):
++    return True
++    #return md.point_cache.is_baked is False
  class CLOTH_MT_presets(Menu):
      bl_label = "Cloth Presets"
      preset_subdir = "cloth"
@@@ -41,11 -46,12 +46,12 @@@ class PhysicButtonsPanel
      def poll(cls, context):
          ob = context.object
          rd = context.scene.render
-         return (ob and ob.type == 'MESH') and (not rd.use_game_engine) and (context.cloth)
+         return (ob and ob.type == 'MESH') and (rd.engine in cls.COMPAT_ENGINES) and (context.cloth)
  
  
  class PHYSICS_PT_cloth(PhysicButtonsPanel, Panel):
      bl_label = "Cloth"
+     COMPAT_ENGINES = {'BLENDER_RENDER'}
  
      def draw(self, context):
          layout = self.layout
          ob = context.object
          cloth = md.settings
  
-         split = layout.split()
+         layout.active = cloth_panel_enabled(md)
+         split = layout.split(percentage=0.25)
  
-         col.label(text="Presets:")
-         sub = col.row(align=True)
 +        col = split.column()
 +
+         split.label(text="Presets:")
+         sub = split.row(align=True)
          sub.menu("CLOTH_MT_presets", text=bpy.types.CLOTH_MT_presets.bl_label)
          sub.operator("cloth.preset_add", text="", icon='ZOOMIN')
          sub.operator("cloth.preset_add", text="", icon='ZOOMOUT').remove_active = True
  
-         col.label(text="Quality:")
-         col.prop(cloth, "quality", text="Steps", slider=True)
+         split = layout.split(percentage=0.25)
+         split.label(text="Quality:")
+         split.prop(cloth, "quality", text="Steps")
+         split = layout.split(percentage=0.25)
+         split.label(text="Speed:")
+         split.prop(cloth, "time_scale", text="Multiplier")
+         split = layout.split()
+         col = split.column()
  
          col.label(text="Material:")
          col.prop(cloth, "mass")
          col.prop(cloth, "air_damping", text="Air")
          col.prop(cloth, "vel_damping", text="Velocity")
  
-         col.prop(cloth, "use_pin_cloth", text="Pinning")
+         split = layout.split()
+         col = split.column()
+         col.prop(cloth, "use_pin_cloth", text="Pinning:")
          sub = col.column()
          sub.active = cloth.use_pin_cloth
          sub.prop_search(cloth, "vertex_group_mass", ob, "vertex_groups", text="")
              col.prop(cloth, "goal_friction", text="Friction")
          """
  
+         col = split.column()
+         col.prop(cloth, "use_dynamic_mesh", text="Dynamic Mesh")
          key = ob.data.shape_keys
  
          if key:
-             col.label(text="Rest Shape Key:")
-             col.prop_search(cloth, "rest_shape_key", key, "key_blocks", text="")
+             sub = col.column()
+             sub.active = not cloth.use_dynamic_mesh
+             sub.label(text="Rest Shape Key:")
+             sub.prop_search(cloth, "rest_shape_key", key, "key_blocks", text="")
  
  
 -class PHYSICS_PT_cloth_cache(PhysicButtonsPanel, Panel):
 -    bl_label = "Cloth Cache"
 -    bl_options = {'DEFAULT_CLOSED'}
 -    COMPAT_ENGINES = {'BLENDER_RENDER'}
 -
 -    def draw(self, context):
 -        md = context.cloth
 -        point_cache_ui(self, context, md.point_cache, cloth_panel_enabled(md), 'CLOTH')
 -
 -
  class PHYSICS_PT_cloth_collision(PhysicButtonsPanel, Panel):
      bl_label = "Cloth Collision"
      bl_options = {'DEFAULT_CLOSED'}
+     COMPAT_ENGINES = {'BLENDER_RENDER'}
  
      def draw_header(self, context):
          cloth = context.cloth.collision_settings
  
+         self.layout.active = cloth_panel_enabled(context.cloth)
          self.layout.prop(cloth, "use_collision", text="")
  
      def draw(self, context):
          md = context.cloth
          ob = context.object
  
-         layout.active = cloth.use_collision
+         layout.active = cloth.use_collision and cloth_panel_enabled(md)
  
          split = layout.split()
  
          col = split.column()
-         col.prop(cloth, "collision_quality", slider=True, text="Quality")
+         col.prop(cloth, "collision_quality", text="Quality")
          col.prop(cloth, "distance_min", slider=True, text="Distance")
          col.prop(cloth, "repel_force", slider=True, text="Repel")
          col.prop(cloth, "distance_repel", slider=True, text="Repel Distance")
          col.prop(cloth, "use_self_collision", text="Self Collision")
          sub = col.column()
          sub.active = cloth.use_self_collision
-         sub.prop(cloth, "self_collision_quality", slider=True, text="Quality")
+         sub.prop(cloth, "self_collision_quality", text="Quality")
          sub.prop(cloth, "self_distance_min", slider=True, text="Distance")
          sub.prop_search(cloth, "vertex_group_self_collisions", ob, "vertex_groups", text="")
  
  class PHYSICS_PT_cloth_stiffness(PhysicButtonsPanel, Panel):
      bl_label = "Cloth Stiffness Scaling"
      bl_options = {'DEFAULT_CLOSED'}
+     COMPAT_ENGINES = {'BLENDER_RENDER'}
  
      def draw_header(self, context):
          cloth = context.cloth.settings
  
+         self.layout.active = cloth_panel_enabled(context.cloth)
          self.layout.prop(cloth, "use_stiffness_scale", text="")
  
      def draw(self, context):
          ob = context.object
          cloth = context.cloth.settings
  
-         layout.active = cloth.use_stiffness_scale
+         layout.active = (cloth.use_stiffness_scale and cloth_panel_enabled(md))
  
          split = layout.split()
  
  class PHYSICS_PT_cloth_sewing(PhysicButtonsPanel, Panel):
      bl_label = "Cloth Sewing Springs"
      bl_options = {'DEFAULT_CLOSED'}
+     COMPAT_ENGINES = {'BLENDER_RENDER'}
  
      def draw_header(self, context):
          cloth = context.cloth.settings
  
+         self.layout.active = cloth_panel_enabled(context.cloth)
          self.layout.prop(cloth, "use_sewing_springs", text="")
  
      def draw(self, context):
          ob = context.object
          cloth = context.cloth.settings
  
-         layout.active = cloth.use_sewing_springs
+         layout.active = (cloth.use_sewing_springs and cloth_panel_enabled(md))
  
          layout.prop(cloth, "sewing_force_max", text="Sewing Force")
  
  class PHYSICS_PT_cloth_field_weights(PhysicButtonsPanel, Panel):
      bl_label = "Cloth Field Weights"
      bl_options = {'DEFAULT_CLOSED'}
+     COMPAT_ENGINES = {'BLENDER_RENDER'}
  
      def draw(self, context):
          cloth = context.cloth.settings
@@@ -31,7 -31,7 +31,7 @@@ class PhysicButtonsPanel
      @classmethod
      def poll(cls, context):
          rd = context.scene.render
-         return (context.object) and (not rd.use_game_engine)
+         return (context.object) and rd.engine in cls.COMPAT_ENGINES
  
  
  def physics_add(self, layout, md, name, type, typeicon, toggles):
@@@ -57,6 -57,7 +57,7 @@@ def physics_add_special(self, layout, d
  class PHYSICS_PT_add(PhysicButtonsPanel, Panel):
      bl_label = ""
      bl_options = {'HIDE_HEADER'}
+     COMPAT_ENGINES = {'BLENDER_RENDER'}
  
      def draw(self, context):
          obj = context.object
                              'CONSTRAINT')  # RB_TODO needs better icon
  
  
 -# cache-type can be 'PSYS' 'HAIR' 'SMOKE' etc
 -
 -def point_cache_ui(self, context, cache, enabled, cachetype):
 -    layout = self.layout
 -
 -    layout.context_pointer_set("point_cache", cache)
 -
 -    if not cachetype == 'RIGID_BODY':
 -        row = layout.row()
 -        row.template_list("UI_UL_list", "point_caches", cache, "point_caches",
 -                          cache.point_caches, "active_index", rows=1)
 -        col = row.column(align=True)
 -        col.operator("ptcache.add", icon='ZOOMIN', text="")
 -        col.operator("ptcache.remove", icon='ZOOMOUT', text="")
 -
 -    row = layout.row()
 -    if cachetype in {'PSYS', 'HAIR', 'SMOKE'}:
 -        row.prop(cache, "use_external")
 -
 -        if cachetype == 'SMOKE':
 -            row.prop(cache, "use_library_path", "Use Lib Path")
 -
 -    if cache.use_external:
 -        split = layout.split(percentage=0.35)
 -        col = split.column()
 -        col.label(text="Index Number:")
 -        col.label(text="File Path:")
 -
 -        col = split.column()
 -        col.prop(cache, "index", text="")
 -        col.prop(cache, "filepath", text="")
 -
 -        cache_info = cache.info
 -        if cache_info:
 -            layout.label(text=cache_info)
 -    else:
 -        if cachetype in {'SMOKE', 'DYNAMIC_PAINT'}:
 -            if not bpy.data.is_saved:
 -                layout.label(text="Cache is disabled until the file is saved")
 -                layout.enabled = False
 -
 -    if not cache.use_external or cachetype == 'SMOKE':
 -        row = layout.row(align=True)
 -
 -        if cachetype not in {'PSYS', 'DYNAMIC_PAINT'}:
 -            row.enabled = enabled
 -            row.prop(cache, "frame_start")
 -            row.prop(cache, "frame_end")
 -        if cachetype not in {'SMOKE', 'CLOTH', 'DYNAMIC_PAINT', 'RIGID_BODY'}:
 -            row.prop(cache, "frame_step")
 -
 -        if cachetype != 'SMOKE':
 -            layout.label(text=cache.info)
 -
 -        can_bake = True
 -
 -        if cachetype not in {'SMOKE', 'DYNAMIC_PAINT', 'RIGID_BODY'}:
 -            split = layout.split()
 -            split.enabled = enabled and bpy.data.is_saved
 -
 -            col = split.column()
 -            col.prop(cache, "use_disk_cache")
 -
 -            col = split.column()
 -            col.active = cache.use_disk_cache
 -            col.prop(cache, "use_library_path", "Use Lib Path")
 -
 -            row = layout.row()
 -            row.enabled = enabled and bpy.data.is_saved
 -            row.active = cache.use_disk_cache
 -            row.label(text="Compression:")
 -            row.prop(cache, "compression", expand=True)
 -
 -            layout.separator()
 -
 -            if cache.id_data.library and not cache.use_disk_cache:
 -                can_bake = False
 -
 -                col = layout.column(align=True)
 -                col.label(text="Linked object baking requires Disk Cache to be enabled", icon='INFO')
 -        else:
 -            layout.separator()
 -
 -        split = layout.split()
 -        split.active = can_bake
 -
 -        col = split.column()
 -
 -        if cache.is_baked is True:
 -            col.operator("ptcache.free_bake", text="Free Bake")
 -        else:
 -            col.operator("ptcache.bake", text="Bake").bake = True
 -
 -        sub = col.row()
 -        sub.enabled = (cache.is_frame_skip or cache.is_outdated) and enabled
 -        sub.operator("ptcache.bake", text="Calculate To Frame").bake = False
 -
 -        sub = col.column()
 -        sub.enabled = enabled
 -        sub.operator("ptcache.bake_from_cache", text="Current Cache to Bake")
 -
 -        col = split.column()
 -        col.operator("ptcache.bake_all", text="Bake All Dynamics").bake = True
 -        col.operator("ptcache.free_bake_all", text="Free All Bakes")
 -        col.operator("ptcache.bake_all", text="Update All To Frame").bake = False
 -
 -
  def effector_weights_ui(self, context, weights, weight_type):
      layout = self.layout
  
@@@ -21,6 -21,7 +21,6 @@@ import bp
  from bpy.types import Panel, UIList
  
  from bl_ui.properties_physics_common import (
 -        point_cache_ui,
          effector_weights_ui,
          )
  
@@@ -55,11 -56,12 +55,12 @@@ class PhysicButtonsPanel
      def poll(cls, context):
          ob = context.object
          rd = context.scene.render
-         return (ob and ob.type == 'MESH') and (not rd.use_game_engine) and context.dynamic_paint
+         return (ob and ob.type == 'MESH') and rd.engine in cls.COMPAT_ENGINES and context.dynamic_paint
  
  
  class PHYSICS_PT_dynamic_paint(PhysicButtonsPanel, Panel):
      bl_label = "Dynamic Paint"
+     COMPAT_ENGINES = {'BLENDER_RENDER'}
  
      def draw(self, context):
          layout = self.layout
  
                  col = split.column()
                  if not use_shading_nodes:
 -                    sub = col.column()
 -                    sub.active = (brush.paint_source != 'PARTICLE_SYSTEM')
 -                    sub.prop(brush, "use_material")
 -                if brush.use_material and brush.paint_source != 'PARTICLE_SYSTEM' and not use_shading_nodes:
 +                    col.prop(brush, "use_material")
 +                if brush.use_material and not use_shading_nodes:
                      col.prop(brush, "material", text="")
                      col.prop(brush, "paint_alpha", text="Alpha Factor")
                  else:
  
  class PHYSICS_PT_dp_advanced_canvas(PhysicButtonsPanel, Panel):
      bl_label = "Dynamic Paint Advanced"
+     COMPAT_ENGINES = {'BLENDER_RENDER'}
  
      @classmethod
      def poll(cls, context):
          md = context.dynamic_paint
          rd = context.scene.render
-         return md and md.ui_type == 'CANVAS' and md.canvas_settings and md.canvas_settings.canvas_surfaces.active and (not rd.use_game_engine)
+         return md and md.ui_type == 'CANVAS' and md.canvas_settings and md.canvas_settings.canvas_surfaces.active and rd.engine in cls.COMPAT_ENGINES
  
      def draw(self, context):
          layout = self.layout
  class PHYSICS_PT_dp_canvas_output(PhysicButtonsPanel, Panel):
      bl_label = "Dynamic Paint Output"
      bl_options = {'DEFAULT_CLOSED'}
+     COMPAT_ENGINES = {'BLENDER_RENDER'}
  
      @classmethod
      def poll(cls, context):
          surface = context.dynamic_paint.canvas_settings.canvas_surfaces.active
          return (surface and
                  (not (surface.surface_format == 'VERTEX' and (surface.surface_type in {'DISPLACE', 'WAVE'}))) and
-                 (not rd.use_game_engine))
+                 (rd.engine in cls.COMPAT_ENGINES))
  
      def draw(self, context):
          layout = self.layout
  class PHYSICS_PT_dp_canvas_initial_color(PhysicButtonsPanel, Panel):
      bl_label = "Dynamic Paint Initial Color"
      bl_options = {'DEFAULT_CLOSED'}
+     COMPAT_ENGINES = {'BLENDER_RENDER'}
  
      @classmethod
      def poll(cls, context):
          if not (md and md.ui_type == 'CANVAS' and md.canvas_settings):
              return 0
          surface = context.dynamic_paint.canvas_settings.canvas_surfaces.active
-         return (surface and surface.surface_type == 'PAINT') and (not rd.use_game_engine)
+         return (surface and surface.surface_type == 'PAINT') and (rd.engine in cls.COMPAT_ENGINES)
  
      def draw(self, context):
          layout = self.layout
  class PHYSICS_PT_dp_effects(PhysicButtonsPanel, Panel):
      bl_label = "Dynamic Paint Effects"
      bl_options = {'DEFAULT_CLOSED'}
+     COMPAT_ENGINES = {'BLENDER_RENDER'}
  
      @classmethod
      def poll(cls, context):
          if not (md and md.ui_type == 'CANVAS' and md.canvas_settings):
              return False
          surface = context.dynamic_paint.canvas_settings.canvas_surfaces.active
-         return (surface and surface.surface_type == 'PAINT') and (not rd.use_game_engine)
+         return (surface and surface.surface_type == 'PAINT') and (rd.engine in cls.COMPAT_ENGINES)
  
      def draw(self, context):
          layout = self.layout
              row.prop(surface, "shrink_speed")
  
  
 -class PHYSICS_PT_dp_cache(PhysicButtonsPanel, Panel):
 -    bl_label = "Dynamic Paint Cache"
 -    bl_options = {'DEFAULT_CLOSED'}
 -    COMPAT_ENGINES = {'BLENDER_RENDER'}
 -
 -    @classmethod
 -    def poll(cls, context):
 -        md = context.dynamic_paint
 -        rd = context.scene.render
 -        return (md and
 -                md.ui_type == 'CANVAS' and
 -                md.canvas_settings and
 -                md.canvas_settings.canvas_surfaces.active and
 -                md.canvas_settings.canvas_surfaces.active.is_cache_user and
 -                (rd.engine in cls.COMPAT_ENGINES))
 -
 -    def draw(self, context):
 -        surface = context.dynamic_paint.canvas_settings.canvas_surfaces.active
 -        cache = surface.point_cache
 -
 -        point_cache_ui(self, context, cache, (cache.is_baked is False), 'DYNAMIC_PAINT')
 -
 -
  class PHYSICS_PT_dp_brush_source(PhysicButtonsPanel, Panel):
      bl_label = "Dynamic Paint Source"
+     COMPAT_ENGINES = {'BLENDER_RENDER'}
  
      @classmethod
      def poll(cls, context):
          md = context.dynamic_paint
          rd = context.scene.render
-         return md and md.ui_type == 'BRUSH' and md.brush_settings and (not rd.use_game_engine)
+         return md and md.ui_type == 'BRUSH' and md.brush_settings and (rd.engine in cls.COMPAT_ENGINES)
  
      def draw(self, context):
          layout = self.layout
          col = split.column()
          col.prop(brush, "paint_source")
  
 -        if brush.paint_source == 'PARTICLE_SYSTEM':
 -            col.prop_search(brush, "particle_system", ob, "particle_systems", text="")
 -            if brush.particle_system:
 -                col.label(text="Particle effect:")
 -                sub = col.column()
 -                sub.active = not brush.use_particle_radius
 -                sub.prop(brush, "solid_radius", text="Solid Radius")
 -                col.prop(brush, "use_particle_radius", text="Use Particle's Radius")
 -                col.prop(brush, "smooth_radius", text="Smooth radius")
 -
          if brush.paint_source in {'DISTANCE', 'VOLUME_DISTANCE', 'POINT'}:
              col.prop(brush, "paint_distance", text="Paint Distance")
              split = layout.row().split(percentage=0.4)
  class PHYSICS_PT_dp_brush_velocity(PhysicButtonsPanel, Panel):
      bl_label = "Dynamic Paint Velocity"
      bl_options = {'DEFAULT_CLOSED'}
+     COMPAT_ENGINES = {'BLENDER_RENDER'}
  
      @classmethod
      def poll(cls, context):
          md = context.dynamic_paint
          rd = context.scene.render
-         return md and md.ui_type == 'BRUSH' and md.brush_settings and (not rd.use_game_engine)
+         return md and md.ui_type == 'BRUSH' and md.brush_settings and (rd.engine in cls.COMPAT_ENGINES)
  
      def draw(self, context):
          layout = self.layout
  class PHYSICS_PT_dp_brush_wave(PhysicButtonsPanel, Panel):
      bl_label = "Dynamic Paint Waves"
      bl_options = {'DEFAULT_CLOSED'}
+     COMPAT_ENGINES = {'BLENDER_RENDER'}
  
      @classmethod
      def poll(cls, context):
          md = context.dynamic_paint
          rd = context.scene.render
-         return md and md.ui_type == 'BRUSH' and md.brush_settings and (not rd.use_game_engine)
+         return md and md.ui_type == 'BRUSH' and md.brush_settings and (rd.engine in cls.COMPAT_ENGINES)
  
      def draw(self, context):
          layout = self.layout
@@@ -21,6 -21,7 +21,6 @@@ import bp
  from bpy.types import Panel
  
  from bl_ui.properties_physics_common import (
 -        point_cache_ui,
          effector_weights_ui,
          )
  
@@@ -34,11 -35,12 +34,12 @@@ class PhysicButtonsPanel
      def poll(cls, context):
          ob = context.object
          rd = context.scene.render
-         return (ob and ob.type == 'MESH') and (not rd.use_game_engine) and (context.smoke)
+         return (ob and ob.type == 'MESH') and (rd.engine in cls.COMPAT_ENGINES) and (context.smoke)
  
  
  class PHYSICS_PT_smoke(PhysicButtonsPanel, Panel):
      bl_label = "Smoke"
+     COMPAT_ENGINES = {'BLENDER_RENDER'}
  
      def draw(self, context):
          layout = self.layout
@@@ -53,6 -55,8 +54,6 @@@
  
              split = layout.split()
  
 -            split.enabled = not domain.point_cache.is_baked
 -
              col = split.column()
              col.label(text="Resolution:")
              col.prop(domain, "resolution_max", text="Divisions")
                  col = split.column()
                  col.label(text="Flow Source:")
                  col.prop(flow, "smoke_flow_source", expand=False, text="")
 -                if flow.smoke_flow_source == 'PARTICLES':
 -                    col.label(text="Particle System:")
 -                    col.prop_search(flow, "particle_system", ob, "particle_systems", text="")
 -                    col.prop(flow, "use_particle_size", text="Set Size")
 -                    sub = col.column()
 -                    sub.active = flow.use_particle_size
 -                    sub.prop(flow, "particle_size")
 -                else:
 +                if flow.smoke_flow_source == 'MESH':
                      col.prop(flow, "surface_distance")
                      col.prop(flow, "volume_density")
  
  class PHYSICS_PT_smoke_flow_advanced(PhysicButtonsPanel, Panel):
      bl_label = "Smoke Flow Advanced"
      bl_options = {'DEFAULT_CLOSED'}
+     COMPAT_ENGINES = {'BLENDER_RENDER'}
  
      @classmethod
      def poll(cls, context):
  class PHYSICS_PT_smoke_fire(PhysicButtonsPanel, Panel):
      bl_label = "Smoke Flames"
      bl_options = {'DEFAULT_CLOSED'}
+     COMPAT_ENGINES = {'BLENDER_RENDER'}
  
      @classmethod
      def poll(cls, context):
          domain = context.smoke.domain_settings
  
          split = layout.split()
 -        split.enabled = not domain.point_cache.is_baked
  
          col = split.column(align=True)
          col.label(text="Reaction:")
  class PHYSICS_PT_smoke_adaptive_domain(PhysicButtonsPanel, Panel):
      bl_label = "Smoke Adaptive Domain"
      bl_options = {'DEFAULT_CLOSED'}
+     COMPAT_ENGINES = {'BLENDER_RENDER'}
  
      @classmethod
      def poll(cls, context):
          layout.active = domain.use_adaptive_domain
  
          split = layout.split()
 -        split.enabled = (not domain.point_cache.is_baked)
  
          col = split.column(align=True)
          col.label(text="Resolution:")
  class PHYSICS_PT_smoke_highres(PhysicButtonsPanel, Panel):
      bl_label = "Smoke High Resolution"
      bl_options = {'DEFAULT_CLOSED'}
+     COMPAT_ENGINES = {'BLENDER_RENDER'}
  
      @classmethod
      def poll(cls, context):
          md = context.smoke
          rd = context.scene.render
-         return md and (md.smoke_type == 'DOMAIN') and (not rd.use_game_engine)
+         return md and (md.smoke_type == 'DOMAIN') and (rd.engine in cls.COMPAT_ENGINES)
  
      def draw_header(self, context):
          md = context.smoke.domain_settings
          layout.active = md.use_high_resolution
  
          split = layout.split()
 -        split.enabled = not md.point_cache.is_baked
  
          col = split.column()
          col.label(text="Resolution:")
  class PHYSICS_PT_smoke_groups(PhysicButtonsPanel, Panel):
      bl_label = "Smoke Groups"
      bl_options = {'DEFAULT_CLOSED'}
+     COMPAT_ENGINES = {'BLENDER_RENDER'}
  
      @classmethod
      def poll(cls, context):
          md = context.smoke
          rd = context.scene.render
-         return md and (md.smoke_type == 'DOMAIN') and (not rd.use_game_engine)
+         return md and (md.smoke_type == 'DOMAIN') and (rd.engine in cls.COMPAT_ENGINES)
  
      def draw(self, context):
          layout = self.layout
  class PHYSICS_PT_smoke_cache(PhysicButtonsPanel, Panel):
      bl_label = "Smoke Cache"
      bl_options = {'DEFAULT_CLOSED'}
+     COMPAT_ENGINES = {'BLENDER_RENDER'}
  
      @classmethod
      def poll(cls, context):
          md = context.smoke
          rd = context.scene.render
-         return md and (md.smoke_type == 'DOMAIN') and (not rd.use_game_engine)
+         return md and (md.smoke_type == 'DOMAIN') and (rd.engine in cls.COMPAT_ENGINES)
  
      def draw(self, context):
          layout = self.layout
  
          layout.prop(domain, "cache_file_format")
  
 -        if cache_file_format == 'POINTCACHE':
 -            layout.label(text="Compression:")
 -            layout.prop(domain, "point_cache_compress_type", expand=True)
 -        elif cache_file_format == 'OPENVDB':
 +        if cache_file_format == 'OPENVDB':
              if not bpy.app.build_options.openvdb:
                  layout.label("Built without OpenVDB support")
                  return
              row.label("Data Depth:")
              row.prop(domain, "data_depth", expand=True, text="Data Depth")
  
 -        cache = domain.point_cache
 -        point_cache_ui(self, context, cache, (cache.is_baked is False), 'SMOKE')
 -
  
  class PHYSICS_PT_smoke_field_weights(PhysicButtonsPanel, Panel):
      bl_label = "Smoke Field Weights"
      bl_options = {'DEFAULT_CLOSED'}
+     COMPAT_ENGINES = {'BLENDER_RENDER'}
  
      @classmethod
      def poll(cls, context):
          md = context.smoke
          rd = context.scene.render
-         return md and (md.smoke_type == 'DOMAIN') and (not rd.use_game_engine)
+         return md and (md.smoke_type == 'DOMAIN') and (rd.engine in cls.COMPAT_ENGINES)
  
      def draw(self, context):
          domain = context.smoke.domain_settings
@@@ -21,10 -21,15 +21,15 @@@ import bp
  from bpy.types import Panel
  
  from bl_ui.properties_physics_common import (
 -        point_cache_ui,
          effector_weights_ui,
          )
  
  
 -    return (md.point_cache.is_baked is False)
+ def softbody_panel_enabled(md):
++    return True
++    #return (md.point_cache.is_baked is False)
  class PhysicButtonsPanel:
      bl_space_type = 'PROPERTIES'
      bl_region_type = 'WINDOW'
      def poll(cls, context):
          ob = context.object
          rd = context.scene.render
-         return (ob and (ob.type == 'MESH' or ob.type == 'LATTICE'or ob.type == 'CURVE')) and (not rd.use_game_engine) and (context.soft_body)
+         return (ob and (ob.type == 'MESH' or ob.type == 'LATTICE'or ob.type == 'CURVE')) and (rd.engine in cls.COMPAT_ENGINES) and (context.soft_body)
  
  
  class PHYSICS_PT_softbody(PhysicButtonsPanel, Panel):
      bl_label = "Soft Body"
+     COMPAT_ENGINES = {'BLENDER_RENDER'}
  
      def draw(self, context):
          layout = self.layout
@@@ -50,6 -56,7 +56,7 @@@
  
          # General
          split = layout.split()
+         split.enabled = softbody_panel_enabled(md)
  
          col = split.column()
          col.label(text="Object:")
          col.label(text="Simulation:")
          col.prop(softbody, "speed")
  
+         layout.prop(softbody, "collision_group")
  
 -class PHYSICS_PT_softbody_cache(PhysicButtonsPanel, Panel):
 -    bl_label = "Soft Body Cache"
 -    bl_options = {'DEFAULT_CLOSED'}
 -    COMPAT_ENGINES = {'BLENDER_RENDER'}
 -
 -    def draw(self, context):
 -        md = context.soft_body
 -        point_cache_ui(self, context, md.point_cache, softbody_panel_enabled(md), 'SOFTBODY')
 -
 -
  class PHYSICS_PT_softbody_goal(PhysicButtonsPanel, Panel):
      bl_label = "Soft Body Goal"
      bl_options = {'DEFAULT_CLOSED'}
+     COMPAT_ENGINES = {'BLENDER_RENDER'}
  
      def draw_header(self, context):
          softbody = context.soft_body.settings
  
+         self.layout.active = softbody_panel_enabled(context.soft_body)
          self.layout.prop(softbody, "use_goal", text="")
  
      def draw(self, context):
@@@ -78,7 -99,7 +89,7 @@@
          softbody = md.settings
          ob = context.object
  
-         layout.active = softbody.use_goal
+         layout.active = softbody.use_goal and softbody_panel_enabled(md)
  
          split = layout.split()
  
  class PHYSICS_PT_softbody_edge(PhysicButtonsPanel, Panel):
      bl_label = "Soft Body Edges"
      bl_options = {'DEFAULT_CLOSED'}
+     COMPAT_ENGINES = {'BLENDER_RENDER'}
  
      def draw_header(self, context):
          softbody = context.soft_body.settings
  
+         self.layout.active = softbody_panel_enabled(context.soft_body)
          self.layout.prop(softbody, "use_edges", text="")
  
      def draw(self, context):
          softbody = md.settings
          ob = context.object
  
-         layout.active = softbody.use_edges
+         layout.active = softbody.use_edges and softbody_panel_enabled(md)
  
          split = layout.split()
  
  class PHYSICS_PT_softbody_collision(PhysicButtonsPanel, Panel):
      bl_label = "Soft Body Self Collision"
      bl_options = {'DEFAULT_CLOSED'}
+     COMPAT_ENGINES = {'BLENDER_RENDER'}
  
      def draw_header(self, context):
          softbody = context.soft_body.settings
  
+         self.layout.active = softbody_panel_enabled(context.soft_body)
          self.layout.prop(softbody, "use_self_collision", text="")
  
      def draw(self, context):
          md = context.soft_body
          softbody = md.settings
  
-         layout.active = softbody.use_self_collision
+         layout.active = softbody.use_self_collision and softbody_panel_enabled(md)
  
          layout.label(text="Collision Ball Size Calculation:")
          layout.prop(softbody, "collision_type", expand=True)
  class PHYSICS_PT_softbody_solver(PhysicButtonsPanel, Panel):
      bl_label = "Soft Body Solver"
      bl_options = {'DEFAULT_CLOSED'}
+     COMPAT_ENGINES = {'BLENDER_RENDER'}
  
      def draw(self, context):
          layout = self.layout
          md = context.soft_body
          softbody = md.settings
  
+         layout.active = softbody_panel_enabled(md)
          # Solver
          split = layout.split()
  
  class PHYSICS_PT_softbody_field_weights(PhysicButtonsPanel, Panel):
      bl_label = "Soft Body Field Weights"
      bl_options = {'DEFAULT_CLOSED'}
+     COMPAT_ENGINES = {'BLENDER_RENDER'}
  
      def draw(self, context):
          md = context.soft_body
@@@ -92,6 -92,8 +92,6 @@@ def dopesheet_filter(layout, context, g
                  row.prop(dopesheet, "show_lattices", text="")
              if bpy.data.armatures:
                  row.prop(dopesheet, "show_armatures", text="")
 -            if bpy.data.particles:
 -                row.prop(dopesheet, "show_particles", text="")
              if bpy.data.speakers:
                  row.prop(dopesheet, "show_speakers", text="")
              if bpy.data.linestyles:
  
              layout.prop(dopesheet, "use_datablock_sort", text="")
  
  #######################################
  # DopeSheet Editor - General/Standard UI
  
  # <pep8 compliant>
  import bpy
  from bpy.types import Header, Menu, Panel
- from bl_ui.properties_grease_pencil_common import GreasePencilDataPanel
+ from bl_ui.properties_grease_pencil_common import (
+         GreasePencilDataPanel,
+         GreasePencilPaletteColorPanel,
+         )
  from bl_ui.properties_paint_common import UnifiedPaintPanel
  from bpy.app.translations import contexts as i18n_contexts
  
@@@ -37,7 -40,6 +40,6 @@@ class VIEW3D_HT_header(Header)
  
          row = layout.row(align=True)
          row.template_header()
-         sub = row.row(align=True)
  
          VIEW3D_MT_editor_menus.draw_collapsible(context, layout)
  
  
          if obj:
              mode = obj.mode
 -            # Particle edit
 -            if mode == 'PARTICLE_EDIT':
 -                row.prop(toolsettings.particle_edit, "select_mode", text="", expand=True)
  
              # Occlude geometry
 -            if ((view.viewport_shade not in {'BOUNDBOX', 'WIREFRAME'} and (mode == 'PARTICLE_EDIT' or (mode == 'EDIT' and obj.type == 'MESH'))) or
 +            if ((view.viewport_shade not in {'BOUNDBOX', 'WIREFRAME'} and (mode == 'EDIT' and obj.type == 'MESH')) or
                      (mode == 'WEIGHT_PAINT')):
                  row.prop(view, "use_occlude_geometry", text="")
  
@@@ -59,7 -64,7 +61,7 @@@
                  row.prop(toolsettings, "proportional_edit", icon_only=True)
                  if toolsettings.proportional_edit != 'DISABLED':
                      row.prop(toolsettings, "proportional_edit_falloff", icon_only=True)
 -            elif mode in {'EDIT', 'PARTICLE_EDIT'}:
 +            elif mode == 'EDIT':
                  row = layout.row(align=True)
                  row.prop(toolsettings, "proportional_edit", icon_only=True)
                  if toolsettings.proportional_edit != 'DISABLED':
              row.operator("gpencil.copy", text="", icon='COPYDOWN')
              row.operator("gpencil.paste", text="", icon='PASTEDOWN')
  
-             layout.prop(context.gpencil_data, "use_onion_skinning", text="Onion Skins", icon='PARTICLE_PATH') # XXX: icon
-             layout.prop(context.tool_settings.gpencil_sculpt, "use_select_mask")
+             # XXX: icon
+             layout.prop(context.gpencil_data, "use_onion_skinning", text="Onion Skins", icon='PARTICLE_PATH')
  
+             row = layout.row(align=True)
+             row.prop(context.tool_settings.gpencil_sculpt, "use_select_mask")
+             row.prop(context.tool_settings.gpencil_sculpt, "selection_alpha", slider=True)
  
  
  class VIEW3D_MT_editor_menus(Menu):
@@@ -683,6 -689,35 +686,6 @@@ class VIEW3D_MT_select_pose(Menu)
          layout.operator("object.select_pattern", text="Select Pattern...")
  
  
 -class VIEW3D_MT_select_particle(Menu):
 -    bl_label = "Select"
 -
 -    def draw(self, context):
 -        layout = self.layout
 -
 -        layout.operator("view3d.select_border")
 -
 -        layout.separator()
 -
 -        layout.operator("particle.select_all").action = 'TOGGLE'
 -        layout.operator("particle.select_linked")
 -        layout.operator("particle.select_all", text="Inverse").action = 'INVERT'
 -
 -        layout.separator()
 -
 -        layout.operator("particle.select_more")
 -        layout.operator("particle.select_less")
 -
 -        layout.separator()
 -
 -        layout.operator("particle.select_random")
 -
 -        layout.separator()
 -
 -        layout.operator("particle.select_roots", text="Roots")
 -        layout.operator("particle.select_tips", text="Tips")
 -
 -
  class VIEW3D_MT_edit_mesh_select_similar(Menu):
      bl_label = "Select Similar"
  
@@@ -1473,14 -1508,14 +1476,14 @@@ class VIEW3D_MT_object_apply(Menu)
          props.location, props.rotation, props.scale = False, True, True
  
          layout.separator()
-         
          layout.operator("object.transforms_to_deltas", text="Location to Deltas", text_ctxt=i18n_contexts.default).mode = 'LOC'
          layout.operator("object.transforms_to_deltas", text="Rotation to Deltas", text_ctxt=i18n_contexts.default).mode = 'ROT'
          layout.operator("object.transforms_to_deltas", text="Scale to Deltas", text_ctxt=i18n_contexts.default).mode = 'SCALE'
-         
          layout.operator("object.transforms_to_deltas", text="All Transforms to Deltas", text_ctxt=i18n_contexts.default).mode = 'ALL'
          layout.operator("object.anim_transforms_to_deltas")
-         
          layout.separator()
  
          layout.operator("object.visual_transform_apply", text="Visual Transform", text_ctxt=i18n_contexts.default)
@@@ -1874,8 -1909,87 +1877,8 @@@ class VIEW3D_MT_hide_mask(Menu)
          props = layout.operator("paint.mask_lasso_gesture", text="Lasso Mask")
  
  
 -# ********** Particle menu **********
 -
 -
 -class VIEW3D_MT_particle(Menu):
 -    bl_label = "Particle"
 -
 -    def draw(self, context):
 -        layout = self.layout
 -
 -        particle_edit = context.tool_settings.particle_edit
 -
 -        layout.operator("ed.undo")
 -        layout.operator("ed.redo")
 -        layout.operator("ed.undo_history")
 -
 -        layout.separator()
 -
 -        layout.operator("particle.mirror")
 -
 -        layout.separator()
 -
 -        layout.operator("particle.remove_doubles")
 -        layout.operator("particle.delete")
 -
 -        if particle_edit.select_mode == 'POINT':
 -            layout.operator("particle.subdivide")
 -
          layout.operator("particle.unify_length")
 -        layout.operator("particle.rekey")
 -        layout.operator("particle.weight_set")
 -
 -        layout.separator()
 -
 -        layout.menu("VIEW3D_MT_particle_showhide")
 -
 -
 -class VIEW3D_MT_particle_specials(Menu):
 -    bl_label = "Specials"
 -
 -    def draw(self, context):
 -        layout = self.layout
 -
 -        particle_edit = context.tool_settings.particle_edit
 -
 -        layout.operator("particle.rekey")
 -        layout.operator("particle.delete")
 -        layout.operator("particle.remove_doubles")
          layout.operator("particle.unify_length")
 -
 -        if particle_edit.select_mode == 'POINT':
 -            layout.operator("particle.subdivide")
 -
 -        layout.operator("particle.weight_set")
 -        layout.separator()
 -
 -        layout.operator("particle.mirror")
 -
 -        if particle_edit.select_mode == 'POINT':
 -            layout.separator()
 -            layout.operator("particle.select_roots")
 -            layout.operator("particle.select_tips")
 -
 -            layout.separator()
 -
 -            layout.operator("particle.select_random")
 -
 -            layout.separator()
 -
 -            layout.operator("particle.select_more")
 -            layout.operator("particle.select_less")
 -
 -            layout.separator()
 -
 -            layout.operator("particle.select_all").action = 'TOGGLE'
 -            layout.operator("particle.select_linked")
 -            layout.operator("particle.select_all", text="Inverse").action = 'INVERT'
 -
 -
 -class VIEW3D_MT_particle_showhide(ShowHideMenu, Menu):
 -    _operator_name = "particle"
 -
  # ********** Pose Menu **********
  
  
@@@ -2966,6 -3080,13 +2969,13 @@@ class VIEW3D_MT_edit_gpencil_transform(
  class VIEW3D_PT_grease_pencil(GreasePencilDataPanel, Panel):
      bl_space_type = 'VIEW_3D'
      bl_region_type = 'UI'
+     # NOTE: this is just a wrapper around the generic GP Panel
+ class VIEW3D_PT_grease_pencil_palettecolor(GreasePencilPaletteColorPanel, Panel):
+     bl_space_type = 'VIEW_3D'
+     bl_region_type = 'UI'
  
      # NOTE: this is just a wrapper around the generic GP Panel
  
@@@ -22,7 -22,9 +22,9 @@@ from bpy.types import Menu, Panel, UILi
  from bl_ui.properties_grease_pencil_common import (
          GreasePencilDrawingToolsPanel,
          GreasePencilStrokeEditPanel,
-         GreasePencilStrokeSculptPanel
+         GreasePencilStrokeSculptPanel,
+         GreasePencilBrushPanel,
+         GreasePencilBrushCurvesPanel
          )
  from bl_ui.properties_paint_common import (
          UnifiedPaintPanel,
@@@ -605,6 -607,7 +607,7 @@@ class VIEW3D_PT_tools_curveedit_options
                  colsub = layout.column(align=True)
                  colsub.prop(cps, "surface_plane", expand=True)
  
  # ********** default tools for editmode_surface ****************
  
  class VIEW3D_PT_tools_transform_surface(View3DPanel, Panel):
@@@ -939,12 -942,37 +942,12 @@@ class VIEW3D_PT_tools_brush(Panel, View
          settings = self.paint_settings(context)
          brush = settings.brush
  
 -        if not context.particle_edit_object:
 -            col = layout.split().column()
 -            col.template_ID_preview(settings, "brush", new="brush.add", rows=3, cols=8)
 -
 -        # Particle Mode #
 -        if context.particle_edit_object:
 -            tool = settings.tool
 -
 -            layout.column().prop(settings, "tool", expand=True)
 -
 -            if tool != 'NONE':
 -                col = layout.column()
 -                col.prop(brush, "size", slider=True)
 -                if tool != 'ADD':
 -                    col.prop(brush, "strength", slider=True)
 -
 -            if tool == 'ADD':
 -                col.prop(brush, "count")
 -                col = layout.column()
 -                col.prop(settings, "use_default_interpolate")
 -                col.prop(brush, "steps", slider=True)
 -                col.prop(settings, "default_key_count", slider=True)
 -            elif tool == 'LENGTH':
 -                layout.prop(brush, "length_mode", expand=True)
 -            elif tool == 'PUFF':
 -                layout.prop(brush, "puff_mode", expand=True)
 -                layout.prop(brush, "use_puff_volume")
 +        col = layout.split().column()
 +        col.template_ID_preview(settings, "brush", new="brush.add", rows=3, cols=8)
  
          # Sculpt Mode #
  
 -        elif context.sculpt_object and brush:
 +        if context.sculpt_object and brush:
              capabilities = brush.sculpt_capabilities
  
              col = layout.column()
@@@ -1629,7 -1657,7 +1632,7 @@@ class VIEW3D_PT_tools_brush_appearance(
      @classmethod
      def poll(cls, context):
          settings = cls.paint_settings(context)
 -        return (settings is not None) and (not isinstance(settings, bpy.types.ParticleEdit))
 +        return (settings is not None)
  
      def draw(self, context):
          layout = self.layout
@@@ -1852,6 -1880,78 +1855,6 @@@ class VIEW3D_MT_tools_projectpaint_sten
              props.value = i
  
  
 -class VIEW3D_PT_tools_particlemode(View3DPanel, Panel):
 -    """Default tools for particle mode"""
 -    bl_context = "particlemode"
 -    bl_label = "Options"
 -    bl_category = "Tools"
 -
 -    def draw(self, context):
 -        layout = self.layout
 -
 -        pe = context.tool_settings.particle_edit
 -        ob = pe.object
 -
 -        layout.prop(pe, "type", text="")
 -
 -        ptcache = None
 -
 -        if pe.type == 'PARTICLES':
 -            if ob.particle_systems:
 -                if len(ob.particle_systems) > 1:
 -                    layout.template_list("UI_UL_list", "particle_systems", ob, "particle_systems",
 -                                         ob.particle_systems, "active_index", rows=2, maxrows=3)
 -
 -                ptcache = ob.particle_systems.active.point_cache
 -        else:
 -            for md in ob.modifiers:
 -                if md.type == pe.type:
 -                    ptcache = md.point_cache
 -
 -        if ptcache and len(ptcache.point_caches) > 1:
 -            layout.template_list("UI_UL_list", "particles_point_caches", ptcache, "point_caches",
 -                                 ptcache.point_caches, "active_index", rows=2, maxrows=3)
 -
 -        if not pe.is_editable:
 -            layout.label(text="Point cache must be baked")
 -            layout.label(text="in memory to enable editing!")
 -
 -        col = layout.column(align=True)
 -        if pe.is_hair:
 -            col.active = pe.is_editable
 -            col.prop(pe, "use_emitter_deflect", text="Deflect emitter")
 -            sub = col.row(align=True)
 -            sub.active = pe.use_emitter_deflect
 -            sub.prop(pe, "emitter_distance", text="Distance")
 -
 -        col = layout.column(align=True)
 -        col.active = pe.is_editable
 -        col.label(text="Keep:")
 -        col.prop(pe, "use_preserve_length", text="Lengths")
 -        col.prop(pe, "use_preserve_root", text="Root")
 -        if not pe.is_hair:
 -            col.label(text="Correct:")
 -            col.prop(pe, "use_auto_velocity", text="Velocity")
 -        col.prop(ob.data, "use_mirror_x")
 -
 -        col.prop(pe, "shape_object")
 -        col.operator("particle.shape_cut")
 -
 -        col = layout.column(align=True)
 -        col.active = pe.is_editable
 -        col.label(text="Draw:")
 -        col.prop(pe, "draw_step", text="Path Steps")
 -        if pe.is_hair:
 -            col.prop(pe, "show_particles", text="Children")
 -        else:
 -            if pe.type == 'PARTICLES':
 -                col.prop(pe, "show_particles", text="Particles")
 -            col.prop(pe, "use_fade_time")
 -            sub = col.row(align=True)
 -            sub.active = pe.use_fade_time
 -            sub.prop(pe, "fade_frames", slider=True)
 -
 -
  # Grease Pencil drawing tools
  class VIEW3D_PT_tools_grease_pencil_draw(GreasePencilDrawingToolsPanel, Panel):
      bl_space_type = 'VIEW_3D'
@@@ -1867,6 -1967,15 +1870,15 @@@ class VIEW3D_PT_tools_grease_pencil_scu
      bl_space_type = 'VIEW_3D'
  
  
+ # Grease Pencil drawing brushes
+ class VIEW3D_PT_tools_grease_pencil_brush(GreasePencilBrushPanel, Panel):
+     bl_space_type = 'VIEW_3D'
+ # Grease Pencil drawingcurves
+ class VIEW3D_PT_tools_grease_pencil_brushcurves(GreasePencilBrushCurvesPanel, Panel):
+     bl_space_type = 'VIEW_3D'
  # Note: moved here so that it's always in last position in 'Tools' panels!
  class VIEW3D_PT_tools_history(View3DPanel, Panel):
      bl_category = "Tools"
@@@ -29,7 -29,9 +29,8 @@@ set(SRC_DNA_IN
        ${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_actuator_types.h
        ${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_anim_types.h
        ${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_armature_types.h
 -      ${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_boid_types.h
        ${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_brush_types.h
+       ${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_cachefile_types.h
        ${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_camera_types.h
        ${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_cloth_types.h
        ${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_color_types.h
@@@ -66,6 -68,7 +67,6 @@@
        ${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_object_types.h
        ${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_outliner_types.h
        ${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_packedFile_types.h
 -      ${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_particle_types.h
        ${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_property_types.h
        ${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_rigidbody_types.h
        ${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_scene_types.h
@@@ -151,3 -154,6 +152,6 @@@ if(WITH_FREESTYLE
        add_subdirectory(freestyle)
  endif()
  
+ if(WITH_ALEMBIC)
+       add_subdirectory(alembic)
+ endif()
@@@ -171,6 -171,7 +171,7 @@@ typedef enum 
        CLOTH_SIMSETTINGS_FLAG_CCACHE_EDIT = (1 << 12), /* edit cache in editmode */
        CLOTH_SIMSETTINGS_FLAG_NO_SPRING_COMPRESS = (1 << 13), /* don't allow spring compression */
        CLOTH_SIMSETTINGS_FLAG_SEW = (1 << 14), /* pull ends of loose edges together */
+       CLOTH_SIMSETTINGS_FLAG_DYNAMIC_BASEMESH = (1 << 15), /* make simulation respect deformations in the base object */
  } CLOTH_SIMSETTINGS_FLAGS;
  
  /* COLLISION FLAGS */
@@@ -236,6 -237,9 +237,6 @@@ int cloth_uses_vgroup(struct ClothModif
  void bvhtree_update_from_cloth(struct ClothModifierData *clmd, bool moving);
  void bvhselftree_update_from_cloth(struct ClothModifierData *clmd, bool moving);
  
 -// needed for button_object.c
 -void cloth_clear_cache (struct Object *ob, struct ClothModifierData *clmd, float framenr );
 -
  // needed for cloth.c
  int cloth_add_spring (struct ClothModifierData *clmd, unsigned int indexA, unsigned int indexB, float restlength, int spring_type);
  
@@@ -39,6 -39,7 +39,7 @@@ extern "C" 
  
  struct ARegion;
  struct bScreen;
+ struct CacheFile;
  struct ListBase;
  struct Main;
  struct Object;
@@@ -58,6 -59,9 +59,9 @@@ struct bPoseChannel
  struct bGPdata;
  struct bGPDlayer;
  struct bGPDframe;
+ struct bGPDpalette;
+ struct bGPDpalettecolor;
+ struct bGPDbrush;
  struct wmWindow;
  struct wmWindowManager;
  struct SpaceText;
@@@ -105,6 -109,7 +109,6 @@@ enum 
        CTX_MODE_PAINT_WEIGHT,
        CTX_MODE_PAINT_VERTEX,
        CTX_MODE_PAINT_TEXTURE,
 -      CTX_MODE_PARTICLE,
        CTX_MODE_OBJECT
  };
  
@@@ -267,6 -272,8 +271,8 @@@ struct Text *CTX_data_edit_text(const b
  struct MovieClip *CTX_data_edit_movieclip(const bContext *C);
  struct Mask *CTX_data_edit_mask(const bContext *C);
  
+ struct CacheFile *CTX_data_edit_cachefile(const bContext *C);
  int CTX_data_selected_nodes(const bContext *C, ListBase *list);
  
  struct EditBone *CTX_data_active_bone(const bContext *C);
@@@ -282,6 -289,9 +288,9 @@@ int CTX_data_visible_pose_bones(const b
  struct bGPdata *CTX_data_gpencil_data(const bContext *C);
  struct bGPDlayer *CTX_data_active_gpencil_layer(const bContext *C);
  struct bGPDframe *CTX_data_active_gpencil_frame(const bContext *C);
+ struct bGPDpalette *CTX_data_active_gpencil_palette(const bContext *C);
+ struct bGPDpalettecolor *CTX_data_active_gpencil_palettecolor(const bContext *C);
+ struct bGPDbrush *CTX_data_active_gpencil_brush(const bContext *C);
  int CTX_data_visible_gpencil_layers(const bContext *C, ListBase *list);
  int CTX_data_editable_gpencil_layers(const bContext *C, ListBase *list);
  int CTX_data_editable_gpencil_strokes(const bContext *C, ListBase *list);
@@@ -94,7 -94,7 +94,7 @@@ void id_clear_lib_data_ex(struct Main *
  
  struct ListBase *which_libbase(struct Main *mainlib, short type);
  
- #define MAX_LIBARRAY    33
 -#define MAX_LIBARRAY    35
++#define MAX_LIBARRAY    34
  int set_listbasepointers(struct Main *main, struct ListBase *lb[MAX_LIBARRAY]);
  
  /* Main API */
@@@ -94,6 -94,7 +94,6 @@@ typedef struct Main 
        ListBase action;
        ListBase nodetree;
        ListBase brush;
 -      ListBase particle;
        ListBase palettes;
        ListBase paintcurves;
        ListBase wm;
        ListBase movieclip;
        ListBase mask;
        ListBase linestyle;
+       ListBase cachefiles;
  
        char id_tag_update[256];
  
@@@ -76,10 -76,12 +76,11 @@@ set(SR
        intern/blender_undo.c
        intern/blendfile.c
        intern/bmfont.c
 -      intern/boids.c
        intern/bpath.c
        intern/brush.c
        intern/bullet.c
        intern/bvhutils.c
+       intern/cachefile.c
        intern/camera.c
        intern/cdderivedmesh.c
        intern/cloth.c
        intern/outliner_treehash.c
        intern/packedFile.c
        intern/paint.c
 -      intern/particle.c
 -      intern/particle_child.c
 -      intern/particle_distribute.c
 -      intern/particle_system.c
        intern/pbvh.c
        intern/pbvh_bmesh.c
 -      intern/pointcache.c
        intern/property.c
        intern/report.c
        intern/rigidbody.c
        BKE_blendfile.h
        BKE_bmfont.h
        BKE_bmfont_types.h
 -      BKE_boids.h
        BKE_bpath.h
        BKE_brush.h
        BKE_bullet.h
        BKE_bvhutils.h
+       BKE_cachefile.h
        BKE_camera.h
        BKE_ccg.h
        BKE_cdderivedmesh.h
        BKE_outliner_treehash.h
        BKE_packedFile.h
        BKE_paint.h
 -      BKE_particle.h
        BKE_pbvh.h
 -      BKE_pointcache.h
        BKE_property.h
        BKE_report.h
        BKE_rigidbody.h
@@@ -491,6 -502,13 +493,13 @@@ if(WITH_FREESTYLE
        add_definitions(-DWITH_FREESTYLE)
  endif()
  
+ if(WITH_ALEMBIC)
+       list(APPEND INC
+               ../alembic
+       )
+       add_definitions(-DWITH_ALEMBIC)
+ endif()
  if(WITH_OPENSUBDIV)
        add_definitions(-DWITH_OPENSUBDIV)
        list(APPEND INC_SYS
@@@ -88,6 -88,7 +88,6 @@@ bool id_type_can_have_animdata(const sh
                case ID_OB:
                case ID_ME: case ID_MB: case ID_CU: case ID_AR: case ID_LT:
                case ID_KE:
 -              case ID_PA:
                case ID_MA: case ID_TE: case ID_NT:
                case ID_LA: case ID_CA: case ID_WO:
                case ID_LS:
@@@ -96,6 -97,7 +96,7 @@@
                case ID_MC:
                case ID_MSK:
                case ID_GD:
+               case ID_CF:
                        return true;
                
                /* no AnimData */
@@@ -1133,6 -1135,9 +1134,6 @@@ void BKE_animdata_main_cb(Main *mainptr
        /* meshes */
        ANIMDATA_IDS_CB(mainptr->mesh.first);
        
 -      /* particles */
 -      ANIMDATA_IDS_CB(mainptr->particle.first);
 -
        /* speakers */
        ANIMDATA_IDS_CB(mainptr->speaker.first);
  
        
        /* grease pencil */
        ANIMDATA_IDS_CB(mainptr->gpencil.first);
+       /* cache files */
+       ANIMDATA_IDS_CB(mainptr->cachefiles.first);
  }
  
  /* Fix all RNA-Paths throughout the database (directly access the Global.main version)
@@@ -1223,6 -1231,9 +1227,6 @@@ void BKE_animdata_fix_paths_rename_all(
        /* meshes */
        RENAMEFIX_ANIM_IDS(mainptr->mesh.first);
        
 -      /* particles */
 -      RENAMEFIX_ANIM_IDS(mainptr->particle.first);
 -
        /* speakers */
        RENAMEFIX_ANIM_IDS(mainptr->speaker.first);
  
        
        /* grease pencil */
        RENAMEFIX_ANIM_IDS(mainptr->gpencil.first);
+       /* cache files */
+       RENAMEFIX_ANIM_IDS(mainptr->cachefiles.first);
        
        /* scenes */
        RENAMEFIX_ANIM_NODETREE_IDS(mainptr->scene.first, Scene);
@@@ -1475,161 -1489,193 +1482,193 @@@ static bool animsys_remap_path(AnimMapp
        return false;
  }
  
+ static bool animsys_store_rna_setting(
+         PointerRNA *ptr, AnimMapper *remap,
+         /* typically 'fcu->rna_path', 'fcu->array_index' */
+         const char *rna_path, const int array_index,
+         PathResolvedRNA *r_result)
+ {
+       bool success = false;
+       char *path = NULL;
+       bool free_path;
+       /* get path, remapped as appropriate to work in its new environment */
+       free_path = animsys_remap_path(remap, (char *)rna_path, &path);
+       /* write value to setting */
+       if (path) {
+               /* get property to write to */
+               if (RNA_path_resolve_property(ptr, path, &r_result->ptr, &r_result->prop)) {
+                       if ((ptr->id.data == NULL) || RNA_property_animateable(&r_result->ptr, r_result->prop)) {
+                               int array_len = RNA_property_array_length(&r_result->ptr, r_result->prop);
+                               if (array_len && array_index >= array_len) {
+                                       if (G.debug & G_DEBUG) {
+                                               printf("Animato: Invalid array index. ID = '%s',  '%s[%d]', array length is %d\n",
+                                                      (ptr && ptr->id.data) ? (((ID *)ptr->id.data)->name + 2) : "<No ID>",
+                                                      path, array_index, array_len - 1);
+                                       }
+                               }
+                               else {
+                                       r_result->prop_index = array_len ? array_index : -1;
+                                       success = true;
+                               }
+                       }
+               }
+               else {
+                       /* failed to get path */
+                       /* XXX don't tag as failed yet though, as there are some legit situations (Action Constraint)
+                        * where some channels will not exist, but shouldn't lock up Action */
+                       if (G.debug & G_DEBUG) {
+                               printf("Animato: Invalid path. ID = '%s',  '%s[%d]'\n",
+                                      (ptr->id.data) ? (((ID *)ptr->id.data)->name + 2) : "<No ID>",
+                                      path, array_index);
+                       }
+               }
+       }
+       /* free temp path-info */
+       if (free_path) {
+               MEM_freeN((void *)path);
+       }
+       return success;
+ }
  
  /* less than 1.0 evaluates to false, use epsilon to avoid float error */
  #define ANIMSYS_FLOAT_AS_BOOL(value) ((value) > ((1.0f - FLT_EPSILON)))
  
  /* Write the given value to a setting using RNA, and return success */
- static bool animsys_write_rna_setting(PointerRNA *ptr, char *path, int array_index, float value)
+ static bool animsys_write_rna_setting(PathResolvedRNA *anim_rna, const float value)
  {
-       PropertyRNA *prop;
-       PointerRNA new_ptr;
+       PropertyRNA *prop = anim_rna->prop;
+       PointerRNA *ptr = &anim_rna->ptr;
+       int array_index = anim_rna->prop_index;
        
-       //printf("%p %s %i %f\n", ptr, path, array_index, value);
-       
-       /* get property to write to */
-       if (RNA_path_resolve_property(ptr, path, &new_ptr, &prop)) {
-               /* set value for animatable numerical values only
-                * HACK: some local F-Curves (e.g. those on NLA Strips) are evaluated
-                *       without an ID provided, which causes the animateable test to fail!
-                */
-               if (RNA_property_animateable(&new_ptr, prop) || (ptr->id.data == NULL)) {
-                       int array_len = RNA_property_array_length(&new_ptr, prop);
-                       bool written = false;
-                       
-                       if (array_len && array_index >= array_len) {
-                               if (G.debug & G_DEBUG) {
-                                       printf("Animato: Invalid array index. ID = '%s',  '%s[%d]', array length is %d\n",
-                                              (ptr && ptr->id.data) ? (((ID *)ptr->id.data)->name + 2) : "<No ID>",
-                                              path, array_index, array_len - 1);
+       /* caller must ensure this is animatable */
+       BLI_assert(RNA_property_animateable(ptr, prop) || ptr->id.data == NULL);
+       /* set value for animatable numerical values only
+        * HACK: some local F-Curves (e.g. those on NLA Strips) are evaluated
+        *       without an ID provided, which causes the animateable test to fail!
+        */
+       bool written = false;
+       switch (RNA_property_type(prop)) {
+               case PROP_BOOLEAN:
+               {
+                       const int value_coerce = ANIMSYS_FLOAT_AS_BOOL(value);
+                       if (array_index != -1) {
+                               if (RNA_property_boolean_get_index(ptr, prop, array_index) != value_coerce) {
+                                       RNA_property_boolean_set_index(ptr, prop, array_index, value_coerce);
+                                       written = true;
                                }
-                               
-                               return false;
                        }
-                       
-                       switch (RNA_property_type(prop)) {
-                               case PROP_BOOLEAN:
-                                       if (array_len) {
-                                               if (RNA_property_boolean_get_index(&new_ptr, prop, array_index) != ANIMSYS_FLOAT_AS_BOOL(value)) {
-                                                       RNA_property_boolean_set_index(&new_ptr, prop, array_index, ANIMSYS_FLOAT_AS_BOOL(value));
-                                                       written = true;
-                                               }
-                                       }
-                                       else {
-                                               if (RNA_property_boolean_get(&new_ptr, prop) != ANIMSYS_FLOAT_AS_BOOL(value)) {
-                                                       RNA_property_boolean_set(&new_ptr, prop, ANIMSYS_FLOAT_AS_BOOL(value));
-                                                       written = true;
-                                               }
-                                       }
-                                       break;
-                               case PROP_INT:
-                                       if (array_len) {
-                                               if (RNA_property_int_get_index(&new_ptr, prop, array_index) != (int)value) {
-                                                       RNA_property_int_set_index(&new_ptr, prop, array_index, (int)value);
-                                                       written = true;
-                                               }
-                                       }
-                                       else {
-                                               if (RNA_property_int_get(&new_ptr, prop) != (int)value) {
-                                                       RNA_property_int_set(&new_ptr, prop, (int)value);
-                                                       written = true;
-                                               }
-                                       }
-                                       break;
-                               case PROP_FLOAT:
-                                       if (array_len) {
-                                               if (RNA_property_float_get_index(&new_ptr, prop, array_index) != value) {
-                                                       RNA_property_float_set_index(&new_ptr, prop, array_index, value);
-                                                       written = true;
-                                               }
-                                       }
-                                       else {
-                                               if (RNA_property_float_get(&new_ptr, prop) != value) {
-                                                       RNA_property_float_set(&new_ptr, prop, value);
-                                                       written = true;
-                                               }
-                                       }
-                                       break;
-                               case PROP_ENUM:
-                                       if (RNA_property_enum_get(&new_ptr, prop) != (int)value) {
-                                               RNA_property_enum_set(&new_ptr, prop, (int)value);
-                                               written = true;
-                                       }
-                                       break;
-                               default:
-                                       /* nothing can be done here... so it is unsuccessful? */
-                                       return false;
+                       else {
+                               if (RNA_property_boolean_get(ptr, prop) != value_coerce) {
+                                       RNA_property_boolean_set(ptr, prop, value_coerce);
+                                       written = true;
+                               }
                        }
-                       
-                       /* RNA property update disabled for now - [#28525] [#28690] [#28774] [#28777] */
- #if 0
-                       /* buffer property update for later flushing */
-                       if (written && RNA_property_update_check(prop)) {
-                               short skip_updates_hack = 0;
-                               
-                               /* optimization hacks: skip property updates for those properties
-                                * for we know that which the updates in RNA were really just for
-                                * flushing property editing via UI/Py
-                                */
-                               if (new_ptr.type == &RNA_PoseBone) {
-                                       /* bone transforms - update pose (i.e. tag depsgraph) */
-                                       skip_updates_hack = 1;
+                       break;
+               }
+               case PROP_INT:
+               {
+                       const int value_coerce = (int)value;
+                       if (array_index != -1) {
+                               if (RNA_property_int_get_index(ptr, prop, array_index) != value_coerce) {
+                                       RNA_property_int_set_index(ptr, prop, array_index, value_coerce);
+                                       written = true;
                                }
-                               
-                               if (skip_updates_hack == 0)
-                                       RNA_property_update_cache_add(&new_ptr, prop);
                        }
- #endif
-                       /* as long as we don't do property update, we still tag datablock
-                        * as having been updated. this flag does not cause any updates to
-                        * be run, it's for e.g. render engines to synchronize data */
-                       if (written && new_ptr.id.data) {
-                               ID *id = new_ptr.id.data;
-                               /* for cases like duplifarmes it's only a temporary so don't
-                                * notify anyone of updates */
-                               if (!(id->tag & LIB_TAG_ANIM_NO_RECALC)) {
-                                       id->tag |= LIB_TAG_ID_RECALC;
-                                       DAG_id_type_tag(G.main, GS(id->name));
+                       else {
+                               if (RNA_property_int_get(ptr, prop) != value_coerce) {
+                                       RNA_property_int_set(ptr, prop, value_coerce);
+                                       written = true;
                                }
                        }
+                       break;
                }
-               
-               /* successful */
-               return true;
+               case PROP_FLOAT:
+               {
+                       if (array_index != -1) {
+                               if (RNA_property_float_get_index(ptr, prop, array_index) != value) {
+                                       RNA_property_float_set_index(ptr, prop, array_index, value);
+                                       written = true;
+                               }
+                       }
+                       else {
+                               if (RNA_property_float_get(ptr, prop) != value) {
+                                       RNA_property_float_set(ptr, prop, value);
+                                       written = true;
+                               }
+                       }
+                       break;
+               }
+               case PROP_ENUM:
+               {
+                       const int value_coerce = (int)value;
+                       if (RNA_property_enum_get(ptr, prop) != value_coerce) {
+                               RNA_property_enum_set(ptr, prop, value_coerce);
+                               written = true;
+                       }
+                       break;
+               }
+               default:
+                       /* nothing can be done here... so it is unsuccessful? */
+                       return false;
        }
-       else {
-               /* failed to get path */
-               /* XXX don't tag as failed yet though, as there are some legit situations (Action Constraint)
-                * where some channels will not exist, but shouldn't lock up Action */
-               if (G.debug & G_DEBUG) {
-                       printf("Animato: Invalid path. ID = '%s',  '%s[%d]'\n",
-                              (ptr->id.data) ? (((ID *)ptr->id.data)->name + 2) : "<No ID>",
-                              path, array_index);
+       /* RNA property update disabled for now - [#28525] [#28690] [#28774] [#28777] */
+ #if 0
+       /* buffer property update for later flushing */
+       if (written && RNA_property_update_check(prop)) {
+               short skip_updates_hack = 0;
+               /* optimization hacks: skip property updates for those properties
+                * for we know that which the updates in RNA were really just for
+                * flushing property editing via UI/Py
+                */
+               if (new_ptr.type == &RNA_PoseBone) {
+                       /* bone transforms - update pose (i.e. tag depsgraph) */
+                       skip_updates_hack = 1;
+               }
+               if (skip_updates_hack == 0)
+                       RNA_property_update_cache_add(ptr, prop);
+       }
+ #endif
+       /* as long as we don't do property update, we still tag datablock
+        * as having been updated. this flag does not cause any updates to
+        * be run, it's for e.g. render engines to synchronize data */
+       if (written && ptr->id.data) {
+               ID *id = ptr->id.data;
+               /* for cases like duplifarmes it's only a temporary so don't
+                * notify anyone of updates */
+               if (!(id->tag & LIB_TAG_ANIM_NO_RECALC)) {
+                       id->tag |= LIB_TAG_ID_RECALC;
+                       DAG_id_type_tag(G.main, GS(id->name));
                }
-               return false;
        }
+       /* successful */
+       return true;
  }
  
  /* Simple replacement based data-setting of the FCurve using RNA */
  bool BKE_animsys_execute_fcurve(PointerRNA *ptr, AnimMapper *remap, FCurve *fcu, float curval)
  {
-       char *path = NULL;
-       bool free_path = false;
+       PathResolvedRNA anim_rna;
        bool ok = false;
-       
-       /* get path, remapped as appropriate to work in its new environment */
-       free_path = animsys_remap_path(remap, fcu->rna_path, &path);
-       
-       /* write value to setting */
-       if (path)
-               ok = animsys_write_rna_setting(ptr, path, fcu->array_index, curval);
-       
-       /* free temp path-info */
-       if (free_path)
-               MEM_freeN(path);
-               
+       if (animsys_store_rna_setting(ptr, remap, fcu->rna_path, fcu->array_index, &anim_rna)) {
+               ok = animsys_write_rna_setting(&anim_rna, curval);
+       }
        /* return whether we were successful */
        return ok;
  }
@@@ -1647,8 -1693,11 +1686,11 @@@ static void animsys_evaluate_fcurves(Po
                if ((fcu->grp == NULL) || (fcu->grp->flag & AGRP_MUTED) == 0) {
                        /* check if this curve should be skipped */
                        if ((fcu->flag & (FCURVE_MUTED | FCURVE_DISABLED)) == 0) {
-                               const float curval = calculate_fcurve(fcu, ctime);
-                               BKE_animsys_execute_fcurve(ptr, remap, fcu, curval);
+                               PathResolvedRNA anim_rna;
+                               if (animsys_store_rna_setting(ptr, remap, fcu->rna_path, fcu->array_index, &anim_rna)) {
+                                       const float curval = calculate_fcurve(&anim_rna, fcu, ctime);
+                                       animsys_write_rna_setting(&anim_rna, curval);
+                               }
                        }
                }
        }
@@@ -1677,8 -1726,12 +1719,12 @@@ static void animsys_evaluate_drivers(Po
                                /* evaluate this using values set already in other places
                                 * NOTE: for 'layering' option later on, we should check if we should remove old value before adding
                                 *       new to only be done when drivers only changed */
-                               const float curval = calculate_fcurve(fcu, ctime);
-                               ok = BKE_animsys_execute_fcurve(ptr, NULL, fcu, curval);
+                               PathResolvedRNA anim_rna;
+                               if (animsys_store_rna_setting(ptr, NULL, fcu->rna_path, fcu->array_index, &anim_rna)) {
+                                       const float curval = calculate_fcurve(&anim_rna, fcu, ctime);
+                                       ok = animsys_write_rna_setting(&anim_rna, curval);
+                               }
                                
                                /* clear recalc flag */
                                driver->flag &= ~DRIVER_FLAG_RECALC;
@@@ -1746,8 -1799,11 +1792,11 @@@ void animsys_evaluate_action_group(Poin
        for (fcu = agrp->channels.first; (fcu) && (fcu->grp == agrp); fcu = fcu->next) {
                /* check if this curve should be skipped */
                if ((fcu->flag & (FCURVE_MUTED | FCURVE_DISABLED)) == 0) {
-                       const float curval = calculate_fcurve(fcu, ctime);
-                       BKE_animsys_execute_fcurve(ptr, remap, fcu, curval);
+                       PathResolvedRNA anim_rna;
+                       if (animsys_store_rna_setting(ptr, remap, fcu->rna_path, fcu->array_index, &anim_rna)) {
+                               const float curval = calculate_fcurve(&anim_rna, fcu, ctime);
+                               animsys_write_rna_setting(&anim_rna, curval);
+                       }
                }
        }
  }
@@@ -2605,8 -2661,12 +2654,12 @@@ static void animsys_evaluate_overrides(
        AnimOverride *aor;
        
        /* for each override, simply execute... */
-       for (aor = adt->overrides.first; aor; aor = aor->next)
-               animsys_write_rna_setting(ptr, aor->rna_path, aor->array_index, aor->value);
+       for (aor = adt->overrides.first; aor; aor = aor->next) {
+               PathResolvedRNA anim_rna;
+               if (animsys_store_rna_setting(ptr, NULL, aor->rna_path, aor->array_index, &anim_rna)) {
+                       animsys_write_rna_setting(&anim_rna, aor->value);
+               }
+       }
  }
  
  /* ***************************************** */
@@@ -2806,6 -2866,9 +2859,6 @@@ void BKE_animsys_evaluate_all_animation
        /* meshes */
        EVAL_ANIM_IDS(main->mesh.first, ADT_RECALC_ANIM);
        
 -      /* particles */
 -      EVAL_ANIM_IDS(main->particle.first, ADT_RECALC_ANIM);
 -      
        /* speakers */
        EVAL_ANIM_IDS(main->speaker.first, ADT_RECALC_ANIM);
  
        
        /* grease pencil */
        EVAL_ANIM_IDS(main->gpencil.first, ADT_RECALC_ANIM);
+       /* cache files */
+       EVAL_ANIM_IDS(main->cachefiles.first, ADT_RECALC_ANIM);
        
        /* objects */
        /* ADT_RECALC_ANIM doesn't need to be supplied here, since object AnimData gets
@@@ -2878,8 -2944,13 +2934,13 @@@ void BKE_animsys_eval_driver(Evaluation
                         * NOTE: for 'layering' option later on, we should check if we should remove old value before adding
                         *       new to only be done when drivers only changed */
                        //printf("\told val = %f\n", fcu->curval);
-                       const float curval = calculate_fcurve(fcu, eval_ctx->ctime);
-                       ok = BKE_animsys_execute_fcurve(&id_ptr, NULL, fcu, curval);
+                       PathResolvedRNA anim_rna;
+                       if (animsys_store_rna_setting(&id_ptr, NULL, fcu->rna_path, fcu->array_index, &anim_rna)) {
+                               const float curval = calculate_fcurve(&anim_rna, fcu, eval_ctx->ctime);
+                               ok = animsys_write_rna_setting(&anim_rna, curval);
+                       }
                        //printf("\tnew val = %f\n", fcu->curval);
  
                        /* clear recalc flag */
@@@ -48,6 -48,7 +48,7 @@@
  #include "MEM_guardedalloc.h"
  
  #include "DNA_brush_types.h"
+ #include "DNA_cachefile_types.h"
  #include "DNA_image_types.h"
  #include "DNA_mesh_types.h"
  #include "DNA_modifier_types.h"
@@@ -55,6 -56,7 +56,6 @@@
  #include "DNA_object_fluidsim.h"
  #include "DNA_object_force.h"
  #include "DNA_object_types.h"
 -#include "DNA_particle_types.h"
  #include "DNA_sequence_types.h"
  #include "DNA_sound_types.h"
  #include "DNA_text_types.h"
@@@ -461,6 -463,20 +462,6 @@@ void BKE_bpath_traverse_id(Main *bmain
                {
                        Object *ob = (Object *)id;
                        ModifierData *md;
 -                      ParticleSystem *psys;
 -
 -#define BPATH_TRAVERSE_POINTCACHE(ptcaches)                                    \
 -      {                                                                          \
 -              PointCache *cache;                                                     \
 -              for (cache = (ptcaches).first; cache; cache = cache->next) {           \
 -                      if (cache->flag & PTCACHE_DISK_CACHE) {                            \
 -                              rewrite_path_fixed(cache->path,                                \
 -                                                 visit_cb,                                   \
 -                                                 absbase,                                    \
 -                                                 bpath_user_data);                           \
 -                      }                                                                  \
 -              }                                                                      \
 -      } (void)0
  
                        /* do via modifiers instead */
  #if 0
                                                rewrite_path_fixed(fluidmd->fss->surfdataPath, visit_cb, absbase, bpath_user_data);
                                        }
                                }
 -                              else if (md->type == eModifierType_Smoke) {
 -                                      SmokeModifierData *smd = (SmokeModifierData *)md;
 -                                      if (smd->type & MOD_SMOKE_TYPE_DOMAIN) {
 -                                              BPATH_TRAVERSE_POINTCACHE(smd->domain->ptcaches[0]);
 -                                      }
 -                              }
 -                              else if (md->type == eModifierType_Cloth) {
 -                                      ClothModifierData *clmd = (ClothModifierData *) md;
 -                                      BPATH_TRAVERSE_POINTCACHE(clmd->ptcaches);
 -                              }
                                else if (md->type == eModifierType_Ocean) {
                                        OceanModifierData *omd = (OceanModifierData *) md;
                                        rewrite_path_fixed(omd->cachepath, visit_cb, absbase, bpath_user_data);
                                }
                        }
  
 -                      if (ob->soft) {
 -                              BPATH_TRAVERSE_POINTCACHE(ob->soft->ptcaches);
 -                      }
 -
 -                      for (psys = ob->particlesystem.first; psys; psys = psys->next) {
 -                              BPATH_TRAVERSE_POINTCACHE(psys->ptcaches);
 -                      }
 -
 -#undef BPATH_TRAVERSE_POINTCACHE
 -
                        break;
                }
                case ID_SO:
                        rewrite_path_fixed(clip->name, visit_cb, absbase, bpath_user_data);
                        break;
                }
+               case ID_CF:
+               {
+                       CacheFile *cache_file = (CacheFile *)id;
+                       rewrite_path_fixed(cache_file->filepath, visit_cb, absbase, bpath_user_data);
+                       break;
+               }
                default:
                        /* Nothing to do for other IDs that don't contain file paths. */
                        break;
@@@ -45,6 -45,7 +45,6 @@@
  #include "BKE_effect.h"
  #include "BKE_global.h"
  #include "BKE_modifier.h"
 -#include "BKE_pointcache.h"
  
  #include "BPH_mass_spring.h"
  
@@@ -57,6 -58,7 +57,7 @@@ static void cloth_to_object (Object *ob
  static void cloth_from_mesh ( ClothModifierData *clmd, DerivedMesh *dm );
  static int cloth_from_object(Object *ob, ClothModifierData *clmd, DerivedMesh *dm, float framenr, int first);
  static void cloth_update_springs( ClothModifierData *clmd );
+ static void cloth_update_verts( Object *ob, ClothModifierData *clmd, DerivedMesh *dm );
  static void cloth_update_spring_lengths( ClothModifierData *clmd, DerivedMesh *dm );
  static int cloth_build_springs ( ClothModifierData *clmd, DerivedMesh *dm );
  static void cloth_apply_vgroup ( ClothModifierData *clmd, DerivedMesh *dm );
@@@ -95,6 -97,7 +96,7 @@@ void cloth_init(ClothModifierData *clm
        clmd->sim_parms->avg_spring_len = 0.0;
        clmd->sim_parms->presets = 2; /* cotton as start setting */
        clmd->sim_parms->timescale = 1.0f; /* speed factor, describes how fast cloth moves */
+       clmd->sim_parms->time_scale = 1.0f; /* multiplies cloth speed */
        clmd->sim_parms->reset = 0;
        clmd->sim_parms->vel_damping = 1.0f; /* 1.0 = no damping, 0.0 = fully dampened */
        
  
        if (!clmd->sim_parms->effector_weights)
                clmd->sim_parms->effector_weights = BKE_add_effector_weights(NULL);
 -
 -      if (clmd->point_cache)
 -              clmd->point_cache->step = 1;
  }
  
  static BVHTree *bvhselftree_build_from_cloth (ClothModifierData *clmd, float epsilon)
@@@ -296,16 -302,35 +298,16 @@@ void bvhselftree_update_from_cloth(Clot
        }
  }
  
 -void cloth_clear_cache(Object *ob, ClothModifierData *clmd, float framenr)
 -{
 -      PTCacheID pid;
 -      
 -      BKE_ptcache_id_from_cloth(&pid, ob, clmd);
 -
 -      // don't do anything as long as we're in editmode!
 -      if (pid.cache->edit && ob->mode & OB_MODE_PARTICLE_EDIT)
 -              return;
 -      
 -      BKE_ptcache_id_clear(&pid, PTCACHE_CLEAR_AFTER, framenr);
 -}
 -
  static int do_init_cloth(Object *ob, ClothModifierData *clmd, DerivedMesh *result, int framenr)
  {
 -      PointCache *cache;
 -
 -      cache= clmd->point_cache;
 -
        /* initialize simulation data if it didn't exist already */
        if (clmd->clothObject == NULL) {
                if (!cloth_from_object(ob, clmd, result, framenr, 1)) {
 -                      BKE_ptcache_invalidate(cache);
                        modifier_setError(&(clmd->modifier), "Can't initialize cloth");
                        return 0;
                }
        
                if (clmd->clothObject == NULL) {
 -                      BKE_ptcache_invalidate(cache);
                        modifier_setError(&(clmd->modifier), "Null cloth object");
                        return 0;
                }
@@@ -343,12 -368,15 +345,15 @@@ static int do_step_cloth(Object *ob, Cl
                mul_m4_v3(ob->obmat, verts->xconst);
        }
  
 -      effectors = pdInitEffectors(clmd->scene, ob, NULL, clmd->sim_parms->effector_weights, true);
 +      effectors = pdInitEffectors(clmd->scene, ob, clmd->sim_parms->effector_weights, true);
  
+       if (clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_DYNAMIC_BASEMESH )
+               cloth_update_verts ( ob, clmd, result );
        /* Support for dynamic vertex groups, changing from frame to frame */
        cloth_apply_vgroup ( clmd, result );
  
-       if ( clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_SEW )
+       if ( clmd->sim_parms->flags & (CLOTH_SIMSETTINGS_FLAG_SEW | CLOTH_SIMSETTINGS_FLAG_DYNAMIC_BASEMESH) )
                cloth_update_spring_lengths ( clmd, result );
  
        cloth_update_springs( clmd );
   ************************************************/
  void clothModifier_do(ClothModifierData *clmd, Scene *scene, Object *ob, DerivedMesh *dm, float (*vertexCos)[3])
  {
 -      PointCache *cache;
 -      PTCacheID pid;
 -      float timescale;
 -      int framenr, startframe, endframe;
 -      int cache_result;
 +      int framenr = scene->r.cfra, startframe = scene->r.sfra, endframe = scene->r.efra;
  
        clmd->scene= scene;     /* nice to pass on later :) */
 -      framenr= (int)scene->r.cfra;
 -      cache= clmd->point_cache;
  
-       clmd->sim_parms->timescale= 1.0f;
 -      BKE_ptcache_id_from_cloth(&pid, ob, clmd);
 -      BKE_ptcache_id_time(&pid, scene, framenr, &startframe, &endframe, &timescale);
 -      clmd->sim_parms->timescale= timescale * clmd->sim_parms->time_scale;
++      clmd->sim_parms->timescale = 1.0f;
  
        if (clmd->sim_parms->reset || (clmd->clothObject && dm->getNumVerts(dm) != clmd->clothObject->mvert_num)) {
                clmd->sim_parms->reset = 0;
 -              cache->flag |= PTCACHE_OUTDATED;
 -              BKE_ptcache_id_reset(scene, &pid, PTCACHE_RESET_OUTDATED);
 -              BKE_ptcache_validate(cache, 0);
 -              cache->last_exact= 0;
 -              cache->flag &= ~PTCACHE_REDO_NEEDED;
        }
        
        // unused in the moment, calculated separately in implicit.c
  
        /* simulation is only active during a specific period */
        if (framenr < startframe) {
 -              BKE_ptcache_invalidate(cache);
                return;
        }
        else if (framenr > endframe) {
                return;
  
        if (framenr == startframe) {
 -              BKE_ptcache_id_reset(scene, &pid, PTCACHE_RESET_OUTDATED);
                do_init_cloth(ob, clmd, dm, framenr);
 -              BKE_ptcache_validate(cache, framenr);
 -              cache->flag &= ~PTCACHE_REDO_NEEDED;
                clmd->clothObject->last_frame= framenr;
                return;
        }
  
 -      /* try to read from cache */
 -      cache_result = BKE_ptcache_read(&pid, (float)framenr+scene->r.subframe);
 -
 -      if (cache_result == PTCACHE_READ_EXACT || cache_result == PTCACHE_READ_INTERPOLATED) {
 -              BKE_cloth_solver_set_positions(clmd);
 -              cloth_to_object (ob, clmd, vertexCos);
 -
 -              BKE_ptcache_validate(cache, framenr);
 -
 -              if (cache_result == PTCACHE_READ_INTERPOLATED && cache->flag & PTCACHE_REDO_NEEDED)
 -                      BKE_ptcache_write(&pid, framenr);
 -
 -              clmd->clothObject->last_frame= framenr;
 -
 -              return;
 -      }
 -      else if (cache_result==PTCACHE_READ_OLD) {
 -              BKE_cloth_solver_set_positions(clmd);
 -      }
 -      else if ( /*ob->id.lib ||*/ (cache->flag & PTCACHE_BAKED)) { /* 2.4x disabled lib, but this can be used in some cases, testing further - campbell */
 -              /* if baked and nothing in cache, do nothing */
 -              BKE_ptcache_invalidate(cache);
 -              return;
 -      }
 -
        if (framenr!=clmd->clothObject->last_frame+1)
                return;
  
 -      /* if on second frame, write cache for first frame */
 -      if (cache->simframe == startframe && (cache->flag & PTCACHE_OUTDATED || cache->last_exact==0))
 -              BKE_ptcache_write(&pid, startframe);
 -
 -      clmd->sim_parms->timescale *= framenr - cache->simframe;
 +      clmd->sim_parms->timescale *= 1.0f;
  
        /* do simulation */
 -      BKE_ptcache_validate(cache, framenr);
 -
 -      if (!do_step_cloth(ob, clmd, dm, framenr)) {
 -              BKE_ptcache_invalidate(cache);
 -      }
 -      else
 -              BKE_ptcache_write(&pid, framenr);
 +      do_step_cloth(ob, clmd, dm, framenr);
  
        cloth_to_object (ob, clmd, vertexCos);
        clmd->clothObject->last_frame= framenr;
@@@ -729,7 -809,7 +734,7 @@@ static int cloth_from_object(Object *ob
        clmd->clothObject->springs = NULL;
        clmd->clothObject->numsprings = -1;
  
-       if ( clmd->sim_parms->shapekey_rest )
+       if ( clmd->sim_parms->shapekey_rest && !(clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_DYNAMIC_BASEMESH ) )
                shapekey_rest = dm->getVertDataArray ( dm, CD_CLOTH_ORCO );
  
        mvert = dm->getVertArray (dm);
@@@ -1105,6 -1185,20 +1110,20 @@@ static void cloth_update_springs( Cloth
        cloth_hair_update_bending_targets(clmd);
  }
  
+ /* Update rest verts, for dynamically deformable cloth */
+ static void cloth_update_verts( Object *ob, ClothModifierData *clmd, DerivedMesh *dm )
+ {
+       unsigned int i = 0;
+       MVert *mvert = dm->getVertArray (dm);
+       ClothVertex *verts = clmd->clothObject->verts;
+       /* vertex count is already ensured to match */
+       for ( i = 0; i < dm->getNumVerts(dm); i++, verts++ ) {
+               copy_v3_v3(verts->xrest, mvert[i].co);
+               mul_m4_v3(ob->obmat, verts->xrest);
+       }
+ }
  /* Update spring rest lenght, for dynamically deformable cloth */
  static void cloth_update_spring_lengths( ClothModifierData *clmd, DerivedMesh *dm )
  {
@@@ -925,6 -925,7 +925,6 @@@ int CTX_data_mode_enum(const bContext *
                        else if (ob->mode & OB_MODE_WEIGHT_PAINT) return CTX_MODE_PAINT_WEIGHT;
                        else if (ob->mode & OB_MODE_VERTEX_PAINT) return CTX_MODE_PAINT_VERTEX;
                        else if (ob->mode & OB_MODE_TEXTURE_PAINT) return CTX_MODE_PAINT_TEXTURE;
 -                      else if (ob->mode & OB_MODE_PARTICLE_EDIT) return CTX_MODE_PARTICLE;
                }
        }
  
@@@ -1066,6 -1067,11 +1066,11 @@@ struct EditBone *CTX_data_active_bone(c
        return ctx_data_pointer_get(C, "active_bone");
  }
  
+ struct CacheFile *CTX_data_edit_cachefile(const bContext *C)
+ {
+       return ctx_data_pointer_get(C, "edit_cachefile");
+ }
  int CTX_data_selected_bones(const bContext *C, ListBase *list)
  {
        return ctx_data_collection_get(C, "selected_bones", list);
@@@ -1111,6 -1117,21 +1116,21 @@@ bGPDlayer *CTX_data_active_gpencil_laye
        return ctx_data_pointer_get(C, "active_gpencil_layer");
  }
  
+ bGPDpalette *CTX_data_active_gpencil_palette(const bContext *C)
+ {
+       return ctx_data_pointer_get(C, "active_gpencil_palette");
+ }
+ bGPDpalettecolor *CTX_data_active_gpencil_palettecolor(const bContext *C)
+ {
+       return ctx_data_pointer_get(C, "active_gpencil_palettecolor");
+ }
+ bGPDbrush *CTX_data_active_gpencil_brush(const bContext *C)
+ {
+       return ctx_data_pointer_get(C, "active_gpencil_brush");
+ }
  bGPDframe *CTX_data_active_gpencil_frame(const bContext *C)
  {
        return ctx_data_pointer_get(C, "active_gpencil_frame");
@@@ -46,6 -46,7 +46,7 @@@
  
  #include "DNA_anim_types.h"
  #include "DNA_camera_types.h"
+ #include "DNA_cachefile_types.h"
  #include "DNA_group_types.h"
  #include "DNA_lamp_types.h"
  #include "DNA_lattice_types.h"
@@@ -53,8 -54,6 +54,8 @@@
  #include "DNA_material_types.h"
  #include "DNA_mesh_types.h"
  #include "DNA_node_types.h"
 +#include "DNA_object_types.h"
 +#include "DNA_object_force.h"
  #include "DNA_scene_types.h"
  #include "DNA_screen_types.h"
  #include "DNA_windowmanager_types.h"
@@@ -78,6 -77,8 +79,6 @@@
  #include "BKE_modifier.h"
  #include "BKE_object.h"
  #include "BKE_paint.h"
 -#include "BKE_particle.h"
 -#include "BKE_pointcache.h"
  #include "BKE_scene.h"
  #include "BKE_screen.h"
  #include "BKE_tracking.h"
@@@ -462,6 -463,26 +463,6 @@@ static void check_and_create_collision_
  static void dag_add_collision_field_relation(DagForest *dag, Scene *scene, Object *ob, DagNode *node, int skip_forcefield, bool no_collision)
  {
        Base *base;
 -      ParticleSystem *particle_system;
 -
 -      for (particle_system = ob->particlesystem.first;
 -           particle_system;
 -           particle_system = particle_system->next)
 -      {
 -              EffectorWeights *effector_weights = particle_system->part->effector_weights;
 -              if (effector_weights->group) {
 -                      GroupObject *group_object;
 -
 -                      for (group_object = effector_weights->group->gobject.first;
 -                           group_object;
 -                           group_object = group_object->next)
 -                      {
 -                              if ((group_object->ob->lay & ob->lay)) {
 -                                      check_and_create_collision_relation(dag, ob, node, group_object->ob, skip_forcefield, no_collision);
 -                              }
 -                      }
 -              }
 -      }
  
        /* would be nice to have a list of colliders here
         * so for now walk all objects in scene check 'same layer rule' */
@@@ -480,6 -501,7 +481,6 @@@ static void build_dag_object(DagForest 
        DagNode *node2;
        DagNode *node3;
        Key *key;
 -      ParticleSystem *psys;
        int addtoroot = 1;
        
        node = dag_get_node(dag, ob);
  
        /* softbody collision  */
        if ((ob->type == OB_MESH) || (ob->type == OB_CURVE) || (ob->type == OB_LATTICE)) {
 -              if (ob->particlesystem.first ||
 -                  modifiers_isModifierEnabled(ob, eModifierType_Softbody) ||
 +              if (modifiers_isModifierEnabled(ob, eModifierType_Softbody) ||
                    modifiers_isModifierEnabled(ob, eModifierType_Cloth) ||
                    modifiers_isModifierEnabled(ob, eModifierType_DynamicPaint))
                {
                dag_add_lamp_driver_relations(dag, node, ob->data);
        }
        
 -      /* particles */
 -      psys = ob->particlesystem.first;
 -      if (psys) {
 -              GroupObject *go;
 -
 -              for (; psys; psys = psys->next) {
 -                      BoidRule *rule = NULL;
 -                      BoidState *state = NULL;
 -                      ParticleSettings *part = psys->part;
 -                      ListBase *effectors = NULL;
 -                      EffectorCache *eff;
 -
 -                      if (part->adt) {
 -                              dag_add_driver_relation(part->adt, dag, node, 1);
 -                      }
 -
 -                      dag_add_relation(dag, node, node, DAG_RL_OB_DATA, "Particle-Object Relation");
 -
 -                      if (!psys_check_enabled(ob, psys, G.is_rendering))
 -                              continue;
 -
 -                      if (ELEM(part->phystype, PART_PHYS_KEYED, PART_PHYS_BOIDS)) {
 -                              ParticleTarget *pt = psys->targets.first;
 -
 -                              for (; pt; pt = pt->next) {
 -                                      if (pt->ob && BLI_findlink(&pt->ob->particlesystem, pt->psys - 1)) {
 -                                              node2 = dag_get_node(dag, pt->ob);
 -                                              dag_add_relation(dag, node2, node, DAG_RL_DATA_DATA | DAG_RL_OB_DATA, "Particle Targets");
 -                                      }
 -                              }
 -                      }
 -
 -                      if (part->ren_as == PART_DRAW_OB && part->dup_ob) {
 -                              node2 = dag_get_node(dag, part->dup_ob);
 -                              /* note that this relation actually runs in the wrong direction, the problem
 -                               * is that dupli system all have this (due to parenting), and the render
 -                               * engine instancing assumes particular ordering of objects in list */
 -                              dag_add_relation(dag, node, node2, DAG_RL_OB_OB, "Particle Object Visualization");
 -                              if (part->dup_ob->type == OB_MBALL)
 -                                      dag_add_relation(dag, node, node2, DAG_RL_DATA_DATA, "Particle Object Visualization");
 -                      }
 -
 -                      if (part->ren_as == PART_DRAW_GR && part->dup_group) {
 -                              for (go = part->dup_group->gobject.first; go; go = go->next) {
 -                                      node2 = dag_get_node(dag, go->ob);
 -                                      dag_add_relation(dag, node2, node, DAG_RL_OB_OB, "Particle Group Visualization");
 -                              }
 -                      }
 -
 -                      effectors = pdInitEffectors(scene, ob, psys, part->effector_weights, false);
 -
 -                      if (effectors) {
 -                              for (eff = effectors->first; eff; eff = eff->next) {
 -                                      if (eff->psys) {
 -                                              node2 = dag_get_node(dag, eff->ob);
 -                                              dag_add_relation(dag, node2, node, DAG_RL_DATA_DATA | DAG_RL_OB_DATA, "Particle Field");
 -                                      }
 -                              }
 -                      }
 -
 -                      pdEndEffectors(&effectors);
 -
 -                      if (part->boids) {
 -                              for (state = part->boids->states.first; state; state = state->next) {
 -                                      for (rule = state->rules.first; rule; rule = rule->next) {
 -                                              Object *ruleob = NULL;
 -                                              if (rule->type == eBoidRuleType_Avoid)
 -                                                      ruleob = ((BoidRuleGoalAvoid *)rule)->ob;
 -                                              else if (rule->type == eBoidRuleType_FollowLeader)
 -                                                      ruleob = ((BoidRuleFollowLeader *)rule)->ob;
 -
 -                                              if (ruleob) {
 -                                                      node2 = dag_get_node(dag, ruleob);
 -                                                      dag_add_relation(dag, node2, node, DAG_RL_OB_DATA, "Boid Rule");
 -                                              }
 -                                      }
 -                              }
 -                      }
 -              }
 -      }
 -      
        /* object constraints */
        for (con = ob->constraints.first; con; con = con->next) {
                const bConstraintTypeInfo *cti = BKE_constraint_typeinfo_get(con);
@@@ -1795,6 -1899,38 +1796,6 @@@ static unsigned int flush_layer_node(Sc
        return node->lay;
  }
  
 -/* node was checked to have lasttime != curtime, and is of type ID_OB */
 -static void flush_pointcache_reset(Main *bmain, Scene *scene, DagNode *node,
 -                                   int curtime, unsigned int lay, bool reset)
 -{
 -      DagAdjList *itA;
 -      Object *ob;
 -      
 -      node->lasttime = curtime;
 -      
 -      for (itA = node->child; itA; itA = itA->next) {
 -              if (itA->node->type == ID_OB) {
 -                      if (itA->node->lasttime != curtime) {
 -                              ob = (Object *)(itA->node->ob);
 -
 -                              if (reset || (ob->recalc & OB_RECALC_ALL)) {
 -                                      if (BKE_ptcache_object_reset(scene, ob, PTCACHE_RESET_DEPSGRAPH)) {
 -                                              /* Don't tag nodes which are on invisible layer. */
 -                                              if (itA->node->lay & lay) {
 -                                                      ob->recalc |= OB_RECALC_DATA;
 -                                                      lib_id_recalc_data_tag(bmain, &ob->id);
 -                                              }
 -                                      }
 -
 -                                      flush_pointcache_reset(bmain, scene, itA->node, curtime, lay, true);
 -                              }
 -                              else
 -                                      flush_pointcache_reset(bmain, scene, itA->node, curtime, lay, false);
 -                      }
 -              }
 -      }
 -}
 -
  /* flush layer flags to dependencies */
  static void dag_scene_flush_layers(Scene *sce, int lay)
  {
@@@ -1872,6 -2008,7 +1873,6 @@@ void DAG_scene_flush_update(Main *bmain
  {
        DagNode *firstnode;
        DagAdjList *itA;
 -      Object *ob;
        int lasttime;
  
        if (!DEG_depsgraph_use_legacy()) {
        if (!time) {
                sce->theDag->time++;  /* so we know which nodes were accessed */
                lasttime = sce->theDag->time;
 -              for (itA = firstnode->child; itA; itA = itA->next) {
 -                      if (itA->node->lasttime != lasttime && itA->node->type == ID_OB) {
 -                              ob = (Object *)(itA->node->ob);
 -
 -                              if (ob->recalc & OB_RECALC_ALL) {
 -                                      if (BKE_ptcache_object_reset(sce, ob, PTCACHE_RESET_DEPSGRAPH)) {
 -                                              ob->recalc |= OB_RECALC_DATA;
 -                                              lib_id_recalc_data_tag(bmain, &ob->id);
 -                                      }
 -
 -                                      flush_pointcache_reset(bmain, sce, itA->node, lasttime,
 -                                                             lay, true);
 -                              }
 -                              else
 -                                      flush_pointcache_reset(bmain, sce, itA->node, lasttime,
 -                                                             lay, false);
 -                      }
 -              }
        }
        
        dag_tag_renderlayers(sce, lay);
@@@ -2019,7 -2174,12 +2020,12 @@@ static void dag_object_time_update_flag
                        
                        if (cti) {
                                /* special case for camera tracking -- it doesn't use targets to define relations */
-                               if (ELEM(cti->type, CONSTRAINT_TYPE_FOLLOWTRACK, CONSTRAINT_TYPE_CAMERASOLVER, CONSTRAINT_TYPE_OBJECTSOLVER)) {
+                               if (ELEM(cti->type,
+                                        CONSTRAINT_TYPE_FOLLOWTRACK,
+                                        CONSTRAINT_TYPE_CAMERASOLVER,
+                                        CONSTRAINT_TYPE_OBJECTSOLVER,
+                                        CONSTRAINT_TYPE_TRANSFORM_CACHE))
+                               {
                                        ob->recalc |= OB_RECALC_OB;
                                }
                                else if (cti->get_constraint_targets) {
                                                ob->recalc |= OB_RECALC_DATA;
                                        }
                                }
 -                              if (ob->particlesystem.first)
 -                                      ob->recalc |= OB_RECALC_DATA;
                                break;
                        case OB_CURVE:
                        case OB_SURF:
                        ob->recalc |= OB_RECALC_DATA;
                        adt->recalc |= ADT_RECALC_ANIM;
                }
 -
 -              if (ob->particlesystem.first) {
 -                      ParticleSystem *psys = ob->particlesystem.first;
 -
 -                      for (; psys; psys = psys->next) {
 -                              if (psys_check_enabled(ob, psys, G.is_rendering)) {
 -                                      ob->recalc |= OB_RECALC_DATA;
 -                                      break;
 -                              }
 -                      }
 -              }
        }
  
        if (ob->recalc & OB_RECALC_OB)
@@@ -2415,6 -2588,7 +2421,6 @@@ static void dag_id_flush_update(Main *b
        /* set flags & pointcache for object */
        if (GS(id->name) == ID_OB) {
                ob = (Object *)id;
 -              BKE_ptcache_object_reset(sce, ob, PTCACHE_RESET_DEPSGRAPH);
  
                /* So if someone tagged object recalc directly,
                 * id_tag_update bit-field stays relevant
                                if (!(ob && obt == ob) && obt->data == id) {
                                        obt->recalc |= OB_RECALC_DATA;
                                        lib_id_recalc_data_tag(bmain, &obt->id);
 -                                      BKE_ptcache_object_reset(sce, obt, PTCACHE_RESET_DEPSGRAPH);
                                }
                        }
                }
                                        obt->recalc |= OB_RECALC_DATA;
                                        lib_id_recalc_data_tag(bmain, &obt->id);
                                }
 -
 -                              /* particle settings can use the texture as well */
 -                              if (obt->particlesystem.first) {
 -                                      ParticleSystem *psys = obt->particlesystem.first;
 -                                      MTex **mtexp, *mtex;
 -                                      int a;
 -                                      for (; psys; psys = psys->next) {
 -                                              mtexp = psys->part->mtex;
 -                                              for (a = 0; a < MAX_MTEX; a++, mtexp++) {
 -                                                      mtex = *mtexp;
 -                                                      if (mtex && mtex->tex == (Tex *)id) {
 -                                                              obt->recalc |= OB_RECALC_DATA;
 -                                                              lib_id_recalc_data_tag(bmain, &obt->id);
 -
 -                                                              if (mtex->mapto & PAMAP_INIT)
 -                                                                      psys->recalc |= PSYS_RECALC_RESET;
 -                                                              if (mtex->mapto & PAMAP_CHILD)
 -                                                                      psys->recalc |= PSYS_RECALC_CHILD;
 -
 -                                                              BKE_ptcache_object_reset(sce, obt, PTCACHE_RESET_DEPSGRAPH);
 -                                                      }
 -                                              }
 -                                      }
 -                              }
                        }
                }
                
                                        obt->flag |= (OB_RECALC_OB | OB_RECALC_DATA);
                                        lib_id_recalc_tag(bmain, &obt->id);
                                        lib_id_recalc_data_tag(bmain, &obt->id);
 -                                      BKE_ptcache_object_reset(sce, obt, PTCACHE_RESET_DEPSGRAPH);
                                }
                        }
                }
                
 -              /* set flags based on particle settings */
 -              if (idtype == ID_PA) {
 -                      ParticleSystem *psys;
 -                      for (obt = bmain->object.first; obt; obt = obt->id.next)
 -                              for (psys = obt->particlesystem.first; psys; psys = psys->next)
 -                                      if (&psys->part->id == id)
 -                                              BKE_ptcache_object_reset(sce, obt, PTCACHE_RESET_DEPSGRAPH);
 -              }
 -
                if (ELEM(idtype, ID_MA, ID_TE)) {
                        obt = sce->basact ? sce->basact->object : NULL;
                        if (obt && obt->mode & OB_MODE_TEXTURE_PAINT) {
@@@ -2762,7 -2971,7 +2768,7 @@@ void DAG_id_tag_update_ex(Main *bmain, 
        if (flag) {
                if (flag & OB_RECALC_OB)
                        lib_id_recalc_tag(bmain, id);
 -              if (flag & (OB_RECALC_DATA | PSYS_RECALC))
 +              if (flag & OB_RECALC_DATA)
                        lib_id_recalc_data_tag(bmain, id);
        }
        else
                        ob = (Object *)id;
                        ob->recalc |= (flag & OB_RECALC_ALL);
                }
 -              else if (idtype == ID_PA) {
 -                      ParticleSystem *psys;
 -                      /* this is weak still, should be done delayed as well */
 -                      for (ob = bmain->object.first; ob; ob = ob->id.next) {
 -                              for (psys = ob->particlesystem.first; psys; psys = psys->next) {
 -                                      if (&psys->part->id == id) {
 -                                              ob->recalc |= (flag & OB_RECALC_ALL);
 -                                              psys->recalc |= (flag & PSYS_RECALC);
 -                                              lib_id_recalc_tag(bmain, &ob->id);
 -                                              lib_id_recalc_data_tag(bmain, &ob->id);
 -                                      }
 -                              }
 -                      }
 -              }
                else {
                        /* disable because this is called on various ID types automatically.
                         * where printing warning is not useful. for now just ignore */
                        /* BLI_assert(!"invalid flag for this 'idtype'"); */
                }
        }
+       else if (GS(id->name) == ID_CF) {
+               for (Object *ob = bmain->object.first; ob; ob = ob->id.next) {
+                       ModifierData *md = modifiers_findByType(ob, eModifierType_MeshSequenceCache);
+                       if (md) {
+                               MeshSeqCacheModifierData *mcmd = (MeshSeqCacheModifierData *)md;
+                               if (mcmd->cache_file && (&mcmd->cache_file->id == id)) {
+                                       ob->recalc |= OB_RECALC_DATA;
+                                       continue;
+                               }
+                       }
+                       for (bConstraint *con = ob->constraints.first; con; con = con->next) {
+                               if (con->type != CONSTRAINT_TYPE_TRANSFORM_CACHE) {
+                                       continue;
+                               }
+                               bTransformCacheConstraint *data = con->data;
+                               if (data->cache_file && (&data->cache_file->id == id)) {
+                                       ob->recalc |= OB_RECALC_DATA;
+                                       break;
+                               }
+                       }
+               }
+       }
  }
  
  void DAG_id_tag_update(ID *id, short flag)
@@@ -60,6 -60,7 +60,7 @@@ static IDType idtypes[] = 
        { ID_AR,   "Armature",           "armatures",       BLT_I18NCONTEXT_ID_ARMATURE,           IDTYPE_FLAGS_ISLINKABLE },
        { ID_BR,   "Brush",              "brushes",         BLT_I18NCONTEXT_ID_BRUSH,              IDTYPE_FLAGS_ISLINKABLE },
        { ID_CA,   "Camera",             "cameras",         BLT_I18NCONTEXT_ID_CAMERA,             IDTYPE_FLAGS_ISLINKABLE },
+       { ID_CF,   "CacheFile",          "cache_files",     BLT_I18NCONTEXT_ID_CACHEFILE,          IDTYPE_FLAGS_ISLINKABLE },
        { ID_CU,   "Curve",              "curves",          BLT_I18NCONTEXT_ID_CURVE,              IDTYPE_FLAGS_ISLINKABLE },
        { ID_GD,   "GPencil",            "grease_pencil",   BLT_I18NCONTEXT_ID_GPENCIL,            IDTYPE_FLAGS_ISLINKABLE }, /* rename gpencil */
        { ID_GR,   "Group",              "groups",          BLT_I18NCONTEXT_ID_GROUP,              IDTYPE_FLAGS_ISLINKABLE },
@@@ -77,6 -78,7 +78,6 @@@
        { ID_MSK,  "Mask",               "masks",           BLT_I18NCONTEXT_ID_MASK,               IDTYPE_FLAGS_ISLINKABLE },
        { ID_NT,   "NodeTree",           "node_groups",     BLT_I18NCONTEXT_ID_NODETREE,           IDTYPE_FLAGS_ISLINKABLE },
        { ID_OB,   "Object",             "objects",         BLT_I18NCONTEXT_ID_OBJECT,             IDTYPE_FLAGS_ISLINKABLE },
 -      { ID_PA,   "ParticleSettings",   "particles",       BLT_I18NCONTEXT_ID_PARTICLESETTINGS,   IDTYPE_FLAGS_ISLINKABLE },
        { ID_PAL,  "Palettes",           "palettes",        BLT_I18NCONTEXT_ID_PALETTE,            IDTYPE_FLAGS_ISLINKABLE },
        { ID_PC,   "PaintCurve",         "paint_curves",    BLT_I18NCONTEXT_ID_PAINTCURVE,         IDTYPE_FLAGS_ISLINKABLE },
        { ID_SCE,  "Scene",              "scenes",          BLT_I18NCONTEXT_ID_SCENE,              IDTYPE_FLAGS_ISLINKABLE },
@@@ -183,6 -185,7 +184,7 @@@ int BKE_idcode_to_idfilter(const short 
                CASE_IDFILTER(AR);
                CASE_IDFILTER(BR);
                CASE_IDFILTER(CA);
+               CASE_IDFILTER(CF);
                CASE_IDFILTER(CU);
                CASE_IDFILTER(GD);
                CASE_IDFILTER(GR);
                CASE_IDFILTER(MSK);
                CASE_IDFILTER(NT);
                CASE_IDFILTER(OB);
 -              CASE_IDFILTER(PA);
                CASE_IDFILTER(PAL);
                CASE_IDFILTER(PC);
                CASE_IDFILTER(SCE);
@@@ -225,6 -229,7 +227,7 @@@ short BKE_idcode_from_idfilter(const in
                CASE_IDFILTER(AR);
                CASE_IDFILTER(BR);
                CASE_IDFILTER(CA);
+               CASE_IDFILTER(CF);
                CASE_IDFILTER(CU);
                CASE_IDFILTER(GD);
                CASE_IDFILTER(GR);
                CASE_IDFILTER(MSK);
                CASE_IDFILTER(NT);
                CASE_IDFILTER(OB);
 -              CASE_IDFILTER(PA);
                CASE_IDFILTER(PAL);
                CASE_IDFILTER(PC);
                CASE_IDFILTER(SCE);
@@@ -45,6 -45,7 +45,7 @@@
  #include "DNA_anim_types.h"
  #include "DNA_armature_types.h"
  #include "DNA_brush_types.h"
+ #include "DNA_cachefile_types.h"
  #include "DNA_camera_types.h"
  #include "DNA_group_types.h"
  #include "DNA_gpencil_types.h"
@@@ -56,6 -57,7 +57,7 @@@
  #include "DNA_material_types.h"
  #include "DNA_mesh_types.h"
  #include "DNA_meta_types.h"
+ #include "DNA_modifier_types.h"
  #include "DNA_movieclip_types.h"
  #include "DNA_mask_types.h"
  #include "DNA_node_types.h"
@@@ -81,6 -83,7 +83,7 @@@
  #include "BKE_bpath.h"
  #include "BKE_brush.h"
  #include "BKE_camera.h"
+ #include "BKE_cachefile.h"
  #include "BKE_context.h"
  #include "BKE_curve.h"
  #include "BKE_depsgraph.h"
  #include "BKE_main.h"
  #include "BKE_mball.h"
  #include "BKE_mask.h"
+ #include "BKE_movieclip.h"
  #include "BKE_node.h"
  #include "BKE_object.h"
 -#include "BKE_particle.h"
+ #include "BKE_paint.h"
  #include "BKE_packedFile.h"
  #include "BKE_sound.h"
  #include "BKE_speaker.h"
@@@ -318,7 -324,6 +323,6 @@@ void BKE_id_make_local_generic(Main *bm
                        }
                }
        }
  }
  
  /**
   */
  bool id_make_local(Main *bmain, ID *id, const bool test, const bool lib_local)
  {
-       if (id->tag & LIB_TAG_INDIRECT)
+       /* We don't care whether ID is directly or indirectly linked in case we are making a whole lib local... */
+       if (!lib_local && (id->tag & LIB_TAG_INDIRECT)) {
                return false;
+       }
  
-       switch (GS(id->name)) {
+       switch ((ID_Type)GS(id->name)) {
                case ID_SCE:
                        /* Partially implemented (has no copy...). */
                        if (!test) BKE_scene_make_local(bmain, (Scene *)id, lib_local);
                        return true;
-               case ID_LI:
-                       return false; /* can't be linked */
                case ID_OB:
                        if (!test) BKE_object_make_local(bmain, (Object *)id, lib_local);
                        return true;
                case ID_SPK:
                        if (!test) BKE_speaker_make_local(bmain, (Speaker *)id, lib_local);
                        return true;
-               case ID_IP:
-                       return false; /* deprecated */
-               case ID_KE:
-                       return false; /* can't be linked */
                case ID_WO:
                        if (!test) BKE_world_make_local(bmain, (World *)id, lib_local);
                        return true;
-               case ID_SCR:
-                       return false; /* can't be linked */
                case ID_VF:
                        /* Partially implemented (has no copy...). */
                        if (!test) BKE_vfont_make_local(bmain, (VFont *)id, lib_local);
                case ID_BR:
                        if (!test) BKE_brush_make_local(bmain, (Brush *)id, lib_local);
                        return true;
-               case ID_WM:
-                       return false; /* can't be linked */
 -              case ID_PA:
 -                      if (!test) BKE_particlesettings_make_local(bmain, (ParticleSettings *)id, lib_local);
 -                      return true;
                case ID_GD:
                        if (!test) BKE_gpencil_make_local(bmain, (bGPdata *)id, lib_local);
                        return true;
+               case ID_MC:
+                       if (!test) BKE_movieclip_make_local(bmain, (MovieClip *)id, lib_local);
+                       return true;
                case ID_MSK:
                        if (!test) BKE_mask_make_local(bmain, (Mask *)id, lib_local);
                        return true;
                case ID_LS:
                        if (!test) BKE_linestyle_make_local(bmain, (FreestyleLineStyle *)id, lib_local);
                        return true;
+               case ID_PAL:
+                       if (!test) BKE_palette_make_local(bmain, (Palette *)id, lib_local);
+                       return true;
+               case ID_PC:
+                       if (!test) BKE_paint_curve_make_local(bmain, (PaintCurve *)id, lib_local);
+                       return true;
+               case ID_CF:
+                       if (!test) BKE_cachefile_make_local(bmain, (CacheFile *)id, lib_local);
+                       return true;
+               case ID_SCR:
+               case ID_LI:
+               case ID_KE:
+               case ID_WM:
+                       return false; /* can't be linked */
+               case ID_IP:
+                       return false; /* deprecated */
        }
  
        return false;
@@@ -437,11 -456,7 +452,7 @@@ bool id_copy(Main *bmain, ID *id, ID **
        /* conventions:
         * - make shallow copy, only this ID block
         * - id.us of the new ID is set to 1 */
-       switch (GS(id->name)) {
-               case ID_SCE:
-                       return false;  /* can't be copied from here */
-               case ID_LI:
-                       return false;  /* can't be copied from here */
+       switch ((ID_Type)GS(id->name)) {
                case ID_OB:
                        if (!test) *newid = (ID *)BKE_object_copy(bmain, (Object *)id);
                        return true;
                case ID_CA:
                        if (!test) *newid = (ID *)BKE_camera_copy(bmain, (Camera *)id);
                        return true;
-               case ID_IP:
-                       return false;  /* deprecated */
                case ID_KE:
                        if (!test) *newid = (ID *)BKE_key_copy(bmain, (Key *)id);
                        return true;
                case ID_WO:
                        if (!test) *newid = (ID *)BKE_world_copy(bmain, (World *)id);
                        return true;
-               case ID_SCR:
-                       return false;  /* can't be copied from here */
-               case ID_VF:
-                       return false;  /* not implemented */
                case ID_TXT:
                        if (!test) *newid = (ID *)BKE_text_copy(bmain, (Text *)id);
                        return true;
-               case ID_SO:
-                       return false;  /* not implemented */
                case ID_GR:
                        if (!test) *newid = (ID *)BKE_group_copy(bmain, (Group *)id);
                        return true;
                case ID_BR:
                        if (!test) *newid = (ID *)BKE_brush_copy(bmain, (Brush *)id);
                        return true;
-               case ID_WM:
-                       return false;  /* can't be copied from here */
 -              case ID_PA:
 -                      if (!test) *newid = (ID *)BKE_particlesettings_copy(bmain, (ParticleSettings *)id);
 -                      return true;
                case ID_GD:
-                       if (!test) *newid = (ID *)gpencil_data_duplicate(bmain, (bGPdata *)id, false);
+                       if (!test) *newid = (ID *)BKE_gpencil_data_duplicate(bmain, (bGPdata *)id, false);
+                       return true;
+               case ID_MC:
+                       if (!test) *newid = (ID *)BKE_movieclip_copy(bmain, (MovieClip *)id);
                        return true;
                case ID_MSK:
                        if (!test) *newid = (ID *)BKE_mask_copy(bmain, (Mask *)id);
                case ID_LS:
                        if (!test) *newid = (ID *)BKE_linestyle_copy(bmain, (FreestyleLineStyle *)id);
                        return true;
+               case ID_PAL:
+                       if (!test) *newid = (ID *)BKE_palette_copy(bmain, (Palette *)id);
+                       return true;
+               case ID_PC:
+                       if (!test) *newid = (ID *)BKE_paint_curve_copy(bmain, (PaintCurve *)id);
+                       return true;
+               case ID_CF:
+                       if (!test) *newid = (ID *)BKE_cachefile_copy(bmain, (CacheFile *)id);
+                       return true;
+               case ID_SCE:
+               case ID_LI:
+               case ID_SCR:
+               case ID_WM:
+                       return false;  /* can't be copied from here */
+               case ID_VF:
+               case ID_SO:
+                       return false;  /* not implemented */
+               case ID_IP:
+                       return false;  /* deprecated */
        }
        
        return false;
@@@ -553,7 -583,7 +576,7 @@@ bool id_single_user(bContext *C, ID *id
  
  ListBase *which_libbase(Main *mainlib, short type)
  {
-       switch (type) {
+       switch ((ID_Type)type) {
                case ID_SCE:
                        return &(mainlib->scene);
                case ID_LI:
                        return &(mainlib->nodetree);
                case ID_BR:
                        return &(mainlib->brush);
 -              case ID_PA:
 -                      return &(mainlib->particle);
                case ID_WM:
                        return &(mainlib->wm);
                case ID_GD:
                        return &(mainlib->palettes);
                case ID_PC:
                        return &(mainlib->paintcurves);
+               case ID_CF:
+                       return &(mainlib->cachefiles);
        }
        return NULL;
  }
@@@ -741,6 -775,7 +766,7 @@@ int set_listbasepointers(Main *main, Li
  
        lb[a++] = &(main->armature);
  
+       lb[a++] = &(main->cachefiles);
        lb[a++] = &(main->mesh);
        lb[a++] = &(main->curve);
        lb[a++] = &(main->mball);
        lb[a++] = &(main->palettes);
        lb[a++] = &(main->paintcurves);
        lb[a++] = &(main->brush);
 -      lb[a++] = &(main->particle);
        lb[a++] = &(main->speaker);
  
        lb[a++] = &(main->world);
@@@ -791,7 -827,7 +817,7 @@@ void *BKE_libblock_alloc_notest(short t
  {
        ID *id = NULL;
        
-       switch (type) {
+       switch ((ID_Type)type) {
                case ID_SCE:
                        id = MEM_callocN(sizeof(Scene), "scene");
                        break;
                case ID_BR:
                        id = MEM_callocN(sizeof(Brush), "brush");
                        break;
 -              case ID_PA:
 -                      id = MEM_callocN(sizeof(ParticleSettings), "ParticleSettings");
 -                      break;
                case ID_WM:
                        id = MEM_callocN(sizeof(wmWindowManager), "Window manager");
                        break;
                case ID_PC:
                        id = MEM_callocN(sizeof(PaintCurve), "Paint Curve");
                        break;
+               case ID_CF:
+                       id = MEM_callocN(sizeof(CacheFile), "Cache File");
+                       break;
        }
        return id;
  }
@@@ -925,7 -967,7 +954,7 @@@ void *BKE_libblock_alloc(Main *bmain, s
  void BKE_libblock_init_empty(ID *id)
  {
        /* Note that only ID types that are not valid when filled of zero should have a callback here. */
-       switch (GS(id->name)) {
+       switch ((ID_Type)GS(id->name)) {
                case ID_SCE:
                        BKE_scene_init((Scene *)id);
                        break;
                case ID_CA:
                        BKE_camera_init((Camera *)id);
                        break;
-               case ID_IP:
-                       /* Should not be needed - animation from lib pre-2.5 is broken anyway. */
-                       BLI_assert(0);
-                       break;
-               case ID_KE:
-                       /* Shapekeys are a complex topic too - they depend on their 'user' data type...
-                        * They are not linkable, though, so it should never reach here anyway. */
-                       BLI_assert(0);
-                       break;
                case ID_WO:
                        BKE_world_init((World *)id);
                        break;
                case ID_BR:
                        BKE_brush_init((Brush *)id);
                        break;
 -              case ID_PA:
 -                      /* Nothing to do. */
 -                      break;
                case ID_PC:
                        /* Nothing to do. */
                        break;
-               case ID_WM:
-                       /* We should never reach this. */
-                       BLI_assert(0);
-                       break;
                case ID_GD:
                        /* Nothing to do. */
                        break;
                case ID_LS:
                        BKE_linestyle_init((FreestyleLineStyle *)id);
                        break;
+               case ID_CF:
+                       BKE_cachefile_init((CacheFile *)id);
+                       break;
+               case ID_KE:
+                       /* Shapekeys are a complex topic too - they depend on their 'user' data type...
+                        * They are not linkable, though, so it should never reach here anyway. */
+                       BLI_assert(0);
+                       break;
+               case ID_WM:
+                       /* We should never reach this. */
+                       BLI_assert(0);
+                       break;
+               case ID_IP:
+                       /* Should not be needed - animation from lib pre-2.5 is broken anyway. */
+                       BLI_assert(0);
+                       break;
+               default:
+                       BLI_assert(0);  /* Should never reach this point... */
        }
  }
  
@@@ -1196,6 -1246,7 +1230,6 @@@ void BKE_main_free(Main *mainvar
                                case  31: BKE_libblock_free_ex(mainvar, id, false); break;
                                case  32: BKE_libblock_free_ex(mainvar, id, false); break;
                                case  33: BKE_libblock_free_ex(mainvar, id, false); break;
 -                              case  34: BKE_libblock_free_ex(mainvar, id, false); break;
                                default:
                                        BLI_assert(0);
                                        break;
@@@ -1607,7 -1658,13 +1641,13 @@@ void BKE_library_make_local(Main *bmain
        int a;
  
        for (a = set_listbasepointers(bmain, lbarray); a--; ) {
-               for (id = lbarray[a]->first; id; id = id_next) {
+               id = lbarray[a]->first;
+               /* Do not explicitly make local non-linkable IDs (shapekeys, in fact), they are assumed to be handled
+                * by real datablocks responsible of them. */
+               const bool do_skip = (id && BKE_idcode_is_linkable(GS(id->name)));
+               for (; id; id = id_next) {
                        id->newid = NULL;
                        id_next = id->next;  /* id is possibly being inserted again */
                        
                         * appending data, so any libdata already linked wont become local
                         * (very nasty to discover all your links are lost after appending)  
                         * */
-                       if (id->tag & (LIB_TAG_EXTERN | LIB_TAG_INDIRECT | LIB_TAG_NEW) &&
+                       if (!do_skip && id->tag & (LIB_TAG_EXTERN | LIB_TAG_INDIRECT | LIB_TAG_NEW) &&
                            ((untagged_only == false) || !(id->tag & LIB_TAG_PRE_EXISTING)))
                        {
                                if (lib == NULL || id->lib == lib) {
@@@ -51,7 -51,6 +51,7 @@@
  #include "DNA_mask_types.h"
  #include "DNA_node_types.h"
  #include "DNA_object_force.h"
 +#include "DNA_object_types.h"
  #include "DNA_rigidbody_types.h"
  #include "DNA_scene_types.h"
  #include "DNA_sensor_types.h"
@@@ -64,6 -63,7 +64,6 @@@
  #include "DNA_world_types.h"
  
  #include "BLI_utildefines.h"
 -#include "BLI_listbase.h"
  #include "BLI_ghash.h"
  #include "BLI_linklist_stack.h"
  
@@@ -74,6 -74,7 +74,6 @@@
  #include "BKE_library_query.h"
  #include "BKE_main.h"
  #include "BKE_modifier.h"
 -#include "BKE_particle.h"
  #include "BKE_rigidbody.h"
  #include "BKE_sca.h"
  #include "BKE_sequencer.h"
@@@ -166,6 -167,15 +166,6 @@@ static void library_foreach_constraintO
        FOREACH_FINALIZE_VOID;
  }
  
 -static void library_foreach_particlesystemsObjectLooper(
 -        ParticleSystem *UNUSED(psys), ID **id_pointer, void *user_data, int cd_flag)
 -{
 -      LibraryForeachIDData *data = (LibraryForeachIDData *) user_data;
 -      FOREACH_CALLBACK_INVOKE_ID_PP(data, id_pointer, cd_flag);
 -
 -      FOREACH_FINALIZE_VOID;
 -}
 -
  static void library_foreach_sensorsObjectLooper(
          bSensor *UNUSED(sensor), ID **id_pointer, void *user_data, int cd_flag)
  {
@@@ -295,7 -305,7 +295,7 @@@ void BKE_library_foreach_ID_link(ID *id
                        library_foreach_animationData(&data, adt);
                }
  
-               switch (GS(id->name)) {
+               switch ((ID_Type)GS(id->name)) {
                        case ID_LI:
                        {
                                Library *lib = (Library *) id;
                                if (toolsett) {
                                        CALLBACK_INVOKE(toolsett->skgen_template, IDWALK_NOP);
  
 -                                      CALLBACK_INVOKE(toolsett->particle.scene, IDWALK_NOP);
 -                                      CALLBACK_INVOKE(toolsett->particle.object, IDWALK_NOP);
 -                                      CALLBACK_INVOKE(toolsett->particle.shape_object, IDWALK_NOP);
 -
                                        library_foreach_paint(&data, &toolsett->imapaint.paint);
                                        CALLBACK_INVOKE(toolsett->imapaint.stencil, IDWALK_USER);
                                        CALLBACK_INVOKE(toolsett->imapaint.clone, IDWALK_USER);
                        case ID_OB:
                        {
                                Object *object = (Object *) id;
 -                              ParticleSystem *psys;
  
                                /* Object is special, proxies make things hard... */
                                const int data_cd_flag = data.cd_flag;
                                modifiers_foreachIDLink(object, library_foreach_modifiersForeachIDLink, &data);
                                BKE_constraints_id_loop(&object->constraints, library_foreach_constraintObjectLooper, &data);
  
 -                              for (psys = object->particlesystem.first; psys; psys = psys->next) {
 -                                      BKE_particlesystem_id_loop(psys, library_foreach_particlesystemsObjectLooper, &data);
 -                              }
 -
+                               if (object->soft) {
+                                       CALLBACK_INVOKE(object->soft->collision_group, IDWALK_NOP);
+                                       if (object->soft->effector_weights) {
+                                               CALLBACK_INVOKE(object->soft->effector_weights->group, IDWALK_NOP);
+                                       }
+                               }
                                BKE_sca_sensors_id_loop(&object->sensors, library_foreach_sensorsObjectLooper, &data);
                                BKE_sca_controllers_id_loop(&object->controllers, library_foreach_controllersObjectLooper, &data);
                                BKE_sca_actuators_id_loop(&object->actuators, library_foreach_actuatorsObjectLooper, &data);
  
                        case ID_KE:
                        {
+                               /* XXX Only ID pointer from shapekeys is the 'from' one, which is not actually ID usage.
+                                * Maybe we should even nuke it from here, not 100% sure yet...
+                                * (see also foreach_libblock_id_users_callback).
+                                */
                                Key *key = (Key *) id;
                                CALLBACK_INVOKE_ID(key->from, IDWALK_NOP);
                                break;
                                break;
                        }
  
 -                      case ID_PA:
 -                      {
 -                              ParticleSettings *psett = (ParticleSettings *) id;
 -                              CALLBACK_INVOKE(psett->dup_group, IDWALK_NOP);
 -                              CALLBACK_INVOKE(psett->dup_ob, IDWALK_NOP);
 -                              CALLBACK_INVOKE(psett->bb_ob, IDWALK_NOP);
 -                              CALLBACK_INVOKE(psett->collision_group, IDWALK_NOP);
 -
 -                              for (i = 0; i < MAX_MTEX; i++) {
 -                                      if (psett->mtex[i]) {
 -                                              library_foreach_mtex(&data, psett->mtex[i]);
 -                                      }
 -                              }
 -
 -                              if (psett->effector_weights) {
 -                                      CALLBACK_INVOKE(psett->effector_weights->group, IDWALK_NOP);
 -                              }
 -
 -                              if (psett->pd) {
 -                                      CALLBACK_INVOKE(psett->pd->tex, IDWALK_USER);
 -                                      CALLBACK_INVOKE(psett->pd->f_source, IDWALK_NOP);
 -                              }
 -                              if (psett->pd2) {
 -                                      CALLBACK_INVOKE(psett->pd2->tex, IDWALK_USER);
 -                                      CALLBACK_INVOKE(psett->pd2->f_source, IDWALK_NOP);
 -                              }
 -
 -                              if (psett->boids) {
 -                                      BoidState *state;
 -                                      BoidRule *rule;
 -
 -                                      for (state = psett->boids->states.first; state; state = state->next) {
 -                                              for (rule = state->rules.first; rule; rule = rule->next) {
 -                                                      if (rule->type == eBoidRuleType_Avoid) {
 -                                                              BoidRuleGoalAvoid *gabr = (BoidRuleGoalAvoid *)rule;
 -                                                              CALLBACK_INVOKE(gabr->ob, IDWALK_NOP);
 -                                                      }
 -                                                      else if (rule->type == eBoidRuleType_FollowLeader) {
 -                                                              BoidRuleFollowLeader *flbr = (BoidRuleFollowLeader *)rule;
 -                                                              CALLBACK_INVOKE(flbr->ob, IDWALK_NOP);
 -                                                      }
 -                                              }
 -                                      }
 -                              }
 -                              break;
 -                      }
 -
                        case ID_MC:
                        {
                                MovieClip *clip = (MovieClip *) id;
                                }
                                break;
                        }
+                       /* Nothing needed for those... */
+                       case ID_IM:
+                       case ID_VF:
+                       case ID_TXT:
+                       case ID_SO:
+                       case ID_AR:
+                       case ID_AC:
+                       case ID_GD:
+                       case ID_WM:
+                       case ID_PAL:
+                       case ID_PC:
+                       case ID_CF:
+                               break;
+                       /* Deprecated. */
+                       case ID_IP:
+                               break;
                }
        } while ((id = (flag & IDWALK_RECURSE) ? BLI_LINKSTACK_POP(data.ids_todo) : NULL));
  
@@@ -817,7 -914,7 +848,7 @@@ bool BKE_library_idtype_can_use_idtype(
                        /* Could be the following, but simpler to just always say 'yes' here. */
  #if 0
                        return ELEM(id_type_used, ID_ME, ID_CU, ID_MB, ID_LT, ID_SPK, ID_AR, ID_LA, ID_CA,  /* obdata */
 -                                                ID_OB, ID_MA, ID_GD, ID_GR, ID_TE, ID_PA, ID_TXT, ID_SO, ID_MC, ID_IM, ID_AC
 +                                                ID_OB, ID_MA, ID_GD, ID_GR, ID_TE, ID_TXT, ID_SO, ID_MC, ID_IM, ID_AC
                                                  /* + constraints, modifiers and game logic ID types... */);
  #else
                        return true;
  #endif
                case ID_BR:
                        return ELEM(id_type_used, ID_BR, ID_IM, ID_PC, ID_TE);
 -              case ID_PA:
 -                      return ELEM(id_type_used, ID_OB, ID_GR, ID_TE);
                case ID_MC:
                        return ELEM(id_type_used, ID_GD, ID_IM);
                case ID_MSK:
@@@ -880,10 -979,18 +911,18 @@@ typedef struct IDUsersIter 
        int count_direct, count_indirect;  /* Set by callback. */
  } IDUsersIter;
  
- static int foreach_libblock_id_users_callback(void *user_data, ID *UNUSED(self_id), ID **id_p, int cb_flag)
+ static int foreach_libblock_id_users_callback(void *user_data, ID *self_id, ID **id_p, int cb_flag)
  {
        IDUsersIter *iter = user_data;
  
+       /* XXX This is actually some kind of hack...
+        * Issue is, only ID pointer from shapekeys is the 'from' one, which is not actually ID usage.
+        * Maybe we should even nuke it from BKE_library_foreach_ID_link, not 100% sure yet...
+        */
+       if (GS(self_id->name) == ID_KE) {
+               return IDWALK_RET_NOP;
+       }
        if (*id_p && (*id_p == iter->id)) {
  #if 0
                printf("%s uses %s (refcounted: %d, userone: %d, used_one: %d, used_one_active: %d, indirect_usage: %d)\n",
@@@ -38,6 -38,7 +38,7 @@@
  #include "DNA_armature_types.h"
  #include "DNA_brush_types.h"
  #include "DNA_camera_types.h"
+ #include "DNA_cachefile_types.h"
  #include "DNA_group_types.h"
  #include "DNA_gpencil_types.h"
  #include "DNA_ipo_types.h"
@@@ -69,6 -70,7 +70,7 @@@
  #include "BKE_armature.h"
  #include "BKE_brush.h"
  #include "BKE_camera.h"
+ #include "BKE_cachefile.h"
  #include "BKE_curve.h"
  #include "BKE_depsgraph.h"
  #include "BKE_fcurve.h"
@@@ -96,6 -98,7 +98,6 @@@
  #include "BKE_node.h"
  #include "BKE_object.h"
  #include "BKE_paint.h"
 -#include "BKE_particle.h"
  #include "BKE_speaker.h"
  #include "BKE_sound.h"
  #include "BKE_screen.h"
@@@ -786,12 -789,15 +788,12 @@@ void BKE_libblock_free_ex(Main *bmain, 
                case ID_BR:
                        BKE_brush_free((Brush *)id);
                        break;
 -              case ID_PA:
 -                      BKE_particlesettings_free((ParticleSettings *)id);
 -                      break;
                case ID_WM:
                        if (free_windowmanager_cb)
                                free_windowmanager_cb(NULL, (wmWindowManager *)id);
                        break;
                case ID_GD:
-                       BKE_gpencil_free((bGPdata *)id);
+                       BKE_gpencil_free((bGPdata *)id, true);
                        break;
                case ID_MC:
                        BKE_movieclip_free((MovieClip *)id);
                case ID_PC:
                        BKE_paint_curve_free((PaintCurve *)id);
                        break;
+               case ID_CF:
+                       BKE_cachefile_free((CacheFile *)id);
+                       break;
        }
  
        /* avoid notifying on removed data */
@@@ -44,7 -44,6 +44,7 @@@
  #include "DNA_anim_types.h"
  #include "DNA_group_types.h"
  #include "DNA_mesh_types.h"
 +#include "DNA_object_types.h"
  #include "DNA_scene_types.h"
  #include "DNA_vfont_types.h"
  
@@@ -58,6 -57,7 +58,6 @@@
  #include "BKE_main.h"
  #include "BKE_mesh.h"
  #include "BKE_object.h"
 -#include "BKE_particle.h"
  #include "BKE_scene.h"
  #include "BKE_editmesh.h"
  #include "BKE_anim.h"
@@@ -80,7 -80,6 +80,6 @@@ typedef struct DupliContext 
  
        int persistent_id[MAX_DUPLI_RECUR];
        int level;
-       int index;
  
        const struct DupliGenerator *gen;
  
@@@ -818,6 -817,327 +817,6 @@@ const DupliGenerator gen_dupli_faces = 
      make_duplis_faces               /* make_duplis */
  };
  
 -/* OB_DUPLIPARTS */
 -static void make_duplis_particle_system(const DupliContext *ctx, ParticleSystem *psys)
 -{
 -      Scene *scene = ctx->scene;
 -      Object *par = ctx->object;
 -      bool for_render = ctx->eval_ctx->mode == DAG_EVAL_RENDER;
 -      bool use_texcoords = ELEM(ctx->eval_ctx->mode, DAG_EVAL_RENDER, DAG_EVAL_PREVIEW);
 -
 -      GroupObject *go;
 -      Object *ob = NULL, **oblist = NULL, obcopy, *obcopylist = NULL;
 -      DupliObject *dob;
 -      ParticleDupliWeight *dw;
 -      ParticleSettings *part;
 -      ParticleData *pa;
 -      ChildParticle *cpa = NULL;
 -      ParticleKey state;
 -      ParticleCacheKey *cache;
 -      float ctime, pa_time, scale = 1.0f;
 -      float tmat[4][4], mat[4][4], pamat[4][4], vec[3], size = 0.0;
 -      float (*obmat)[4];
 -      int a, b, hair = 0;
 -      int totpart, totchild, totgroup = 0 /*, pa_num */;
 -      const bool dupli_type_hack = !BKE_scene_use_new_shading_nodes(scene);
 -
 -      int no_draw_flag = PARS_UNEXIST;
 -
 -      if (psys == NULL) return;
 -
 -      part = psys->part;
 -
 -      if (part == NULL)
 -              return;
 -
 -      if (!psys_check_enabled(par, psys, (ctx->eval_ctx->mode == DAG_EVAL_RENDER)))
 -              return;
 -
 -      if (!for_render)
 -              no_draw_flag |= PARS_NO_DISP;
 -
 -      ctime = BKE_scene_frame_get(scene); /* NOTE: in old animsys, used parent object's timeoffset... */
 -
 -      totpart = psys->totpart;
 -      totchild = psys->totchild;
 -
 -      BLI_srandom((unsigned int)(31415926 + psys->seed));
 -
 -      if ((psys->renderdata || part->draw_as == PART_DRAW_REND) && ELEM(part->ren_as, PART_DRAW_OB, PART_DRAW_GR)) {
 -              ParticleSimulationData sim = {NULL};
 -              sim.scene = scene;
 -              sim.ob = par;
 -              sim.psys = psys;
 -              sim.psmd = psys_get_modifier(par, psys);
 -              /* make sure emitter imat is in global coordinates instead of render view coordinates */
 -              invert_m4_m4(par->imat, par->obmat);
 -
 -              /* first check for loops (particle system object used as dupli object) */
 -              if (part->ren_as == PART_DRAW_OB) {
 -                      if (ELEM(part->dup_ob, NULL, par))
 -                              return;
 -              }
 -              else { /*PART_DRAW_GR */
 -                      if (part->dup_group == NULL || BLI_listbase_is_empty(&part->dup_group->gobject))
 -                              return;
 -
 -                      if (BLI_findptr(&part->dup_group->gobject, par, offsetof(GroupObject, ob))) {
 -                              return;
 -                      }
 -              }
 -
 -              /* if we have a hair particle system, use the path cache */
 -              if (part->type == PART_HAIR) {
 -                      if (psys->flag & PSYS_HAIR_DONE)
 -                              hair = (totchild == 0 || psys->childcache) && psys->pathcache;
 -                      if (!hair)
 -                              return;
 -
 -                      /* we use cache, update totchild according to cached data */
 -                      totchild = psys->totchildcache;
 -                      totpart = psys->totcached;
 -              }
 -
 -              psys_check_group_weights(part);
 -
 -              psys->lattice_deform_data = psys_create_lattice_deform_data(&sim);
 -
 -              /* gather list of objects or single object */
 -              if (part->ren_as == PART_DRAW_GR) {
 -                      if (ctx->do_update) {
 -                              BKE_group_handle_recalc_and_update(ctx->eval_ctx, scene, par, part->dup_group);
 -                      }
 -
 -                      if (part->draw & PART_DRAW_COUNT_GR) {
 -                              for (dw = part->dupliweights.first; dw; dw = dw->next)
 -                                      totgroup += dw->count;
 -                      }
 -                      else {
 -                              for (go = part->dup_group->gobject.first; go; go = go->next)
 -                                      totgroup++;
 -                      }
 -
 -                      /* we also copy the actual objects to restore afterwards, since
 -                       * BKE_object_where_is_calc_time will change the object which breaks transform */
 -                      oblist = MEM_callocN((size_t)totgroup * sizeof(Object *), "dupgroup object list");
 -                      obcopylist = MEM_callocN((size_t)totgroup * sizeof(Object), "dupgroup copy list");
 -
 -                      if (part->draw & PART_DRAW_COUNT_GR && totgroup) {
 -                              dw = part->dupliweights.first;
 -
 -                              for (a = 0; a < totgroup; dw = dw->next) {
 -                                      for (b = 0; b < dw->count; b++, a++) {
 -                                              oblist[a] = dw->ob;
 -                                              obcopylist[a] = *dw->ob;
 -                                      }
 -                              }
 -                      }
 -                      else {
 -                              go = part->dup_group->gobject.first;
 -                              for (a = 0; a < totgroup; a++, go = go->next) {
 -                                      oblist[a] = go->ob;
 -                                      obcopylist[a] = *go->ob;
 -                              }
 -                      }
 -              }
 -              else {
 -                      ob = part->dup_ob;
 -                      obcopy = *ob;
 -              }
 -
 -              if (totchild == 0 || part->draw & PART_DRAW_PARENT)
 -                      a = 0;
 -              else
 -                      a = totpart;
 -
 -              for (pa = psys->particles; a < totpart + totchild; a++, pa++) {
 -                      if (a < totpart) {
 -                              /* handle parent particle */
 -                              if (pa->flag & no_draw_flag)
 -                                      continue;
 -
 -                              /* pa_num = pa->num; */ /* UNUSED */
 -                              pa_time = pa->time;
 -                              size = pa->size;
 -                      }
 -                      else {
 -                              /* handle child particle */
 -                              cpa = &psys->child[a - totpart];
 -
 -                              /* pa_num = a; */ /* UNUSED */
 -                              pa_time = psys->particles[cpa->parent].time;
 -                              size = psys_get_child_size(psys, cpa, ctime, NULL);
 -                      }
 -
 -                      /* some hair paths might be non-existent so they can't be used for duplication */
 -                      if (hair && psys->pathcache &&
 -                          ((a < totpart && psys->pathcache[a]->segments < 0) ||
 -                           (a >= totpart && psys->childcache[a - totpart]->segments < 0)))
 -                      {
 -                              continue;
 -                      }
 -
 -                      if (part->ren_as == PART_DRAW_GR) {
 -                              /* prevent divide by zero below [#28336] */
 -                              if (totgroup == 0)
 -                                      continue;
 -
 -                              /* for groups, pick the object based on settings */
 -                              if (part->draw & PART_DRAW_RAND_GR)
 -                                      b = BLI_rand() % totgroup;
 -                              else
 -                                      b = a % totgroup;
 -
 -                              ob = oblist[b];
 -                              obmat = oblist[b]->obmat;
 -                      }
 -                      else {
 -                              obmat = ob->obmat;
 -                      }
 -
 -                      if (hair) {
 -                              /* hair we handle separate and compute transform based on hair keys */
 -                              if (a < totpart) {
 -                                      cache = psys->pathcache[a];
 -                                      psys_get_dupli_path_transform(&sim, pa, NULL, cache, pamat, &scale);
 -                              }
 -                              else {
 -                                      cache = psys->childcache[a - totpart];
 -                                      psys_get_dupli_path_transform(&sim, NULL, cpa, cache, pamat, &scale);
 -                              }
 -
 -                              copy_v3_v3(pamat[3], cache->co);
 -                              pamat[3][3] = 1.0f;
 -
 -                      }
 -                      else {
 -                              /* first key */
 -                              state.time = ctime;
 -                              if (psys_get_particle_state(&sim, a, &state, 0) == 0) {
 -                                      continue;
 -                              }
 -                              else {
 -                                      float tquat[4];
 -                                      normalize_qt_qt(tquat, state.rot);
 -                                      quat_to_mat4(pamat, tquat);
 -                                      copy_v3_v3(pamat[3], state.co);
 -                                      pamat[3][3] = 1.0f;
 -                              }
 -                      }
 -
 -                      if (part->ren_as == PART_DRAW_GR && psys->part->draw & PART_DRAW_WHOLE_GR) {
 -                              for (go = part->dup_group->gobject.first, b = 0; go; go = go->next, b++) {
 -
 -                                      copy_m4_m4(tmat, oblist[b]->obmat);
 -                                      /* apply particle scale */
 -                                      mul_mat3_m4_fl(tmat, size * scale);
 -                                      mul_v3_fl(tmat[3], size * scale);
 -                                      /* group dupli offset, should apply after everything else */
 -                                      if (!is_zero_v3(part->dup_group->dupli_ofs))
 -                                              sub_v3_v3(tmat[3], part->dup_group->dupli_ofs);
 -                                      /* individual particle transform */
 -                                      mul_m4_m4m4(mat, pamat, tmat);
 -
 -                                      dob = make_dupli(ctx, go->ob, mat, a, false, false);
 -                                      dob->particle_system = psys;
 -                                      if (use_texcoords)
 -                                              psys_get_dupli_texture(psys, part, sim.psmd, pa, cpa, dob->uv, dob->orco);
 -                              }
 -                      }
 -                      else {
 -                              /* to give ipos in object correct offset */
 -                              BKE_object_where_is_calc_time(scene, ob, ctime - pa_time);
 -
 -                              copy_v3_v3(vec, obmat[3]);
 -                              obmat[3][0] = obmat[3][1] = obmat[3][2] = 0.0f;
 -
 -                              /* particle rotation uses x-axis as the aligned axis, so pre-rotate the object accordingly */
 -                              if ((part->draw & PART_DRAW_ROTATE_OB) == 0) {
 -                                      float xvec[3], q[4], size_mat[4][4], original_size[3];
 -
 -                                      mat4_to_size(original_size, obmat);
 -                                      size_to_mat4(size_mat, original_size);
 -
 -                                      xvec[0] = -1.f;
 -                                      xvec[1] = xvec[2] = 0;
 -                                      vec_to_quat(q, xvec, ob->trackflag, ob->upflag);
 -                                      quat_to_mat4(obmat, q);
 -                                      obmat[3][3] = 1.0f;
 -
 -                                      /* add scaling if requested */
 -                                      if ((part->draw & PART_DRAW_NO_SCALE_OB) == 0)
 -                                              mul_m4_m4m4(obmat, obmat, size_mat);
 -                              }
 -                              else if (part->draw & PART_DRAW_NO_SCALE_OB) {
 -                                      /* remove scaling */
 -                                      float size_mat[4][4], original_size[3];
 -
 -                                      mat4_to_size(original_size, obmat);
 -                                      size_to_mat4(size_mat, original_size);
 -                                      invert_m4(size_mat);
 -
 -                                      mul_m4_m4m4(obmat, obmat, size_mat);
 -                              }
 -
 -                              mul_m4_m4m4(tmat, pamat, obmat);
 -                              mul_mat3_m4_fl(tmat, size * scale);
 -
 -                              copy_m4_m4(mat, tmat);
 -
 -                              if (part->draw & PART_DRAW_GLOBAL_OB)
 -                                      add_v3_v3v3(mat[3], mat[3], vec);
 -
 -                              dob = make_dupli(ctx, ob, mat, a, false, false);
 -                              dob->particle_system = psys;
 -                              if (use_texcoords)
 -                                      psys_get_dupli_texture(psys, part, sim.psmd, pa, cpa, dob->uv, dob->orco);
 -                              /* XXX blender internal needs this to be set to dupligroup to render
 -                               * groups correctly, but we don't want this hack for cycles */
 -                              if (dupli_type_hack && ctx->group)
 -                                      dob->type = OB_DUPLIGROUP;
 -                      }
 -              }
 -
 -              /* restore objects since they were changed in BKE_object_where_is_calc_time */
 -              if (part->ren_as == PART_DRAW_GR) {
 -                      for (a = 0; a < totgroup; a++)
 -                              *(oblist[a]) = obcopylist[a];
 -              }
 -              else
 -                      *ob = obcopy;
 -      }
 -
 -      /* clean up */
 -      if (oblist)
 -              MEM_freeN(oblist);
 -      if (obcopylist)
 -              MEM_freeN(obcopylist);
 -
 -      if (psys->lattice_deform_data) {
 -              end_latt_deform(psys->lattice_deform_data);
 -              psys->lattice_deform_data = NULL;
 -      }
 -}
 -
 -static void make_duplis_particles(const DupliContext *ctx)
 -{
 -      ParticleSystem *psys;
 -      int psysid;
 -
 -      /* particle system take up one level in id, the particles another */
 -      for (psys = ctx->object->particlesystem.first, psysid = 0; psys; psys = psys->next, psysid++) {
 -              /* particles create one more level for persistent psys index */
 -              DupliContext pctx;
 -              copy_dupli_context(&pctx, ctx, ctx->object, NULL, psysid, false);
 -              make_duplis_particle_system(&pctx, psys);
 -      }
 -}
 -
 -const DupliGenerator gen_dupli_particles = {
 -    OB_DUPLIPARTS,                  /* type */
 -    make_duplis_particles           /* make_duplis */
 -};
 -
  /* ------------- */
  
  /* select dupli generator from given context */
@@@ -833,7 -1153,10 +832,7 @@@ static const DupliGenerator *get_dupli_
        if (ctx->eval_ctx->mode == DAG_EVAL_RENDER ? (restrictflag & OB_RESTRICT_RENDER) : (restrictflag & OB_RESTRICT_VIEW))
                return NULL;
  
 -      if (transflag & OB_DUPLIPARTS) {
 -              return &gen_dupli_particles;
 -      }
 -      else if (transflag & OB_DUPLIVERTS) {
 +      if (transflag & OB_DUPLIVERTS) {
                if (ctx->object->type == OB_MESH) {
                        return &gen_dupli_verts;
                }
@@@ -891,8 -1214,12 +890,8 @@@ int count_duplilist(Object *ob
                if (ob->transflag & OB_DUPLIVERTS) {
                        if (ob->type == OB_MESH) {
                                if (ob->transflag & OB_DUPLIVERTS) {
 -                                      ParticleSystem *psys = ob->particlesystem.first;
                                        int pdup = 0;
  
 -                                      for (; psys; psys = psys->next)
 -                                              pdup += psys->totpart;
 -
                                        if (pdup == 0) {
                                                Mesh *me = ob->data;
                                                return me->totvert;
@@@ -49,6 -49,7 +49,7 @@@
  #include "DNA_space_types.h"
  #include "DNA_view3d_types.h"
  #include "DNA_windowmanager_types.h"
+ #include "DNA_gpencil_types.h"
  
  #include "BLI_math.h"
  #include "BLI_blenlib.h"
@@@ -64,6 -65,7 +65,7 @@@
  #include "BKE_animsys.h"
  #include "BKE_action.h"
  #include "BKE_armature.h"
+ #include "BKE_cachefile.h"
  #include "BKE_colortools.h"
  #include "BKE_depsgraph.h"
  #include "BKE_editmesh.h"
@@@ -285,6 -287,14 +287,13 @@@ Scene *BKE_scene_copy(Main *bmain, Scen
                BKE_paint_copy(&ts->imapaint.paint, &ts->imapaint.paint);
                ts->imapaint.paintcursor = NULL;
                id_us_plus((ID *)ts->imapaint.stencil);
 -              ts->particle.paintcursor = NULL;
+               /* duplicate Grease Pencil Drawing Brushes */
+               BLI_listbase_clear(&ts->gp_brushes);
+               for (bGPDbrush *brush = sce->toolsettings->gp_brushes.first; brush; brush = brush->next) {
+                       bGPDbrush *newbrush = BKE_gpencil_brush_duplicate(brush);
+                       BLI_addtail(&ts->gp_brushes, newbrush);
+               }
        }
        
        /* make a private copy of the avicodecdata */
        /* grease pencil */
        if (scen->gpd) {
                if (type == SCE_COPY_FULL) {
-                       scen->gpd = gpencil_data_duplicate(bmain, scen->gpd, false);
+                       scen->gpd = BKE_gpencil_data_duplicate(bmain, scen->gpd, false);
                }
                else if (type == SCE_COPY_EMPTY) {
                        scen->gpd = NULL;
@@@ -431,6 -441,10 +440,10 @@@ void BKE_scene_free(Scene *sce
                        BKE_paint_free(&sce->toolsettings->uvsculpt->paint);
                        MEM_freeN(sce->toolsettings->uvsculpt);
                }
+               /* free Grease Pencil Drawing Brushes */
+               BKE_gpencil_free_brushes(&sce->toolsettings->gp_brushes);
+               BLI_freelistN(&sce->toolsettings->gp_brushes);
                BKE_paint_free(&sce->toolsettings->imapaint.paint);
  
                MEM_freeN(sce->toolsettings);
  
  void BKE_scene_init(Scene *sce)
  {
 -      ParticleEditSettings *pset;
 -      int a;
        const char *colorspace_name;
        SceneRenderView *srv;
        CurveMapping *mblur_shutter_curve;
  
        sce->unit.scale_length = 1.0f;
  
 -      pset = &sce->toolsettings->particle;
 -      pset->flag = PE_KEEP_LENGTHS | PE_LOCK_FIRST | PE_DEFLECT_EMITTER | PE_AUTO_VELOCITY;
 -      pset->emitterdist = 0.25f;
 -      pset->totrekey = 5;
 -      pset->totaddkey = 5;
 -      pset->brushtype = PE_BRUSH_NONE;
 -      pset->draw_step = 2;
 -      pset->fade_frames = 2;
 -      pset->selectmode = SCE_SELECT_PATH;
 -      for (a = 0; a < PE_TOT_BRUSH; a++) {
 -              pset->brush[a].strength = 0.5f;
 -              pset->brush[a].size = 50;
 -              pset->brush[a].step = 10;
 -              pset->brush[a].count = 10;
 -      }
 -      pset->brush[PE_BRUSH_CUT].strength = 1.0f;
 -
        sce->r.ffcodecdata.audio_mixrate = 48000;
        sce->r.ffcodecdata.audio_volume = 1.0f;
        sce->r.ffcodecdata.audio_bitrate = 192;
                gp_brush->strength = 0.5f;
                gp_brush->flag = GP_EDITBRUSH_FLAG_USE_FALLOFF;
                
+               gp_brush = &gset->brush[GP_EDITBRUSH_TYPE_STRENGTH];
+               gp_brush->size = 25;
+               gp_brush->strength = 0.5f;
+               gp_brush->flag = GP_EDITBRUSH_FLAG_USE_FALLOFF;
                gp_brush = &gset->brush[GP_EDITBRUSH_TYPE_GRAB];
                gp_brush->size = 50;
                gp_brush->strength = 0.3f;
@@@ -1889,6 -1927,9 +1907,9 @@@ void BKE_scene_update_for_newframe_ex(E
  
        BKE_mask_evaluate_all_masks(bmain, ctime, true);
  
+       /* Update animated cache files for modifiers. */
+       BKE_cachefile_update_frame(bmain, sce, ctime, (((double)sce->r.frs_sec) / (double)sce->r.frs_sec_base));
  #ifdef POSE_ANIMATION_WORKAROUND
        scene_armature_depsgraph_workaround(bmain);
  #endif
@@@ -56,8 -56,8 +56,8 @@@
  #include "DNA_lamp_types.h"
  #include "DNA_meshdata_types.h"
  #include "DNA_modifier_types.h"
 +#include "DNA_object_force.h"
  #include "DNA_object_types.h"
 -#include "DNA_particle_types.h"
  #include "DNA_scene_types.h"
  #include "DNA_smoke_types.h"
  
@@@ -77,6 -77,8 +77,6 @@@
  #include "BKE_main.h"
  #include "BKE_modifier.h"
  #include "BKE_object.h"
 -#include "BKE_particle.h"
 -#include "BKE_pointcache.h"
  #include "BKE_scene.h"
  #include "BKE_smoke.h"
  #include "BKE_texture.h"
@@@ -355,6 -357,9 +355,6 @@@ static void smokeModifier_freeDomain(Sm
                        MEM_freeN(smd->domain->effector_weights);
                smd->domain->effector_weights = NULL;
  
 -              BKE_ptcache_free_list(&(smd->domain->ptcaches[0]));
 -              smd->domain->point_cache[0] = NULL;
 -
                MEM_freeN(smd->domain);
                smd->domain = NULL;
        }
@@@ -479,6 -484,13 +479,6 @@@ void smokeModifier_createType(struct Sm
  
                        smd->domain->smd = smd;
  
 -                      smd->domain->point_cache[0] = BKE_ptcache_add(&(smd->domain->ptcaches[0]));
 -                      smd->domain->point_cache[0]->flag |= PTCACHE_DISK_CACHE;
 -                      smd->domain->point_cache[0]->step = 1;
 -
 -                      /* Deprecated */
 -                      smd->domain->point_cache[1] = NULL;
 -                      BLI_listbase_clear(&smd->domain->ptcaches[1]);
                        /* set some standard values */
                        smd->domain->fluid = NULL;
                        smd->domain->fluid_mutex = BLI_rw_mutex_alloc();
                        smd->domain->openvdb_comp = VDB_COMPRESSION_ZIP;
  #endif
                        smd->domain->data_depth = 0;
 -                      smd->domain->cache_file_format = PTCACHE_FILE_PTCACHE;
                }
                else if (smd->type & MOD_SMOKE_TYPE_FLOW)
                {
                        smd->flow->color[2] = 0.7f;
  
                        smd->flow->dm = NULL;
 -                      smd->flow->psys = NULL;
 -
                }
                else if (smd->type & MOD_SMOKE_TYPE_COLL)
                {
@@@ -616,6 -631,7 +616,6 @@@ void smokeModifier_copy(struct SmokeMod
                tsmd->domain->cache_file_format = smd->domain->cache_file_format;
        }
        else if (tsmd->flow) {
 -              tsmd->flow->psys = smd->flow->psys;
                tsmd->flow->noise_texture = smd->flow->noise_texture;
  
                tsmd->flow->vel_multi = smd->flow->vel_multi;
@@@ -691,6 -707,7 +691,7 @@@ typedef struct ObstaclesFromDMData 
        bool has_velocity;
        float *vert_vel;
        float *velocityX, *velocityY, *velocityZ;
+       int *num_obstacles;
  } ObstaclesFromDMData;
  
  static void obstacles_from_derivedmesh_task_cb(void *userdata, const int z)
                                /* tag obstacle cells */
                                data->obstacle_map[index] = 1;
  
-            &nbs