Merged changes in the trunk up to revision 51853.
authorTamito Kajiyama <rd6t-kjym@asahi-net.or.jp>
Sun, 4 Nov 2012 02:22:56 +0000 (02:22 +0000)
committerTamito Kajiyama <rd6t-kjym@asahi-net.or.jp>
Sun, 4 Nov 2012 02:22:56 +0000 (02:22 +0000)
Conflicts resolved:
source/blender/blenloader/intern/readfile.c
source/blender/bmesh/operators/bmo_utils.c

This commit also includes a fix of a bug identified during the merge and committed in revision 51853.
Thanks Thomas (dingto) for the timely fix!

32 files changed:
1  2 
doc/python_api/sphinx_doc_gen.py
release/scripts/startup/bl_ui/properties_render.py
release/scripts/startup/bl_ui/space_view3d.py
source/blender/blenkernel/intern/object.c
source/blender/blenkernel/intern/subsurf_ccg.c
source/blender/blenloader/intern/readfile.c
source/blender/blenloader/intern/writefile.c
source/blender/bmesh/intern/bmesh_operators.h
source/blender/bmesh/operators/bmo_similar.c
source/blender/editors/animation/anim_channels_defines.c
source/blender/editors/mesh/editmesh_select.c
source/blender/editors/mesh/editmesh_tools.c
source/blender/editors/mesh/mesh_intern.h
source/blender/editors/mesh/mesh_ops.c
source/blender/editors/space_file/filelist.c
source/blender/editors/space_view3d/drawobject.c
source/blender/editors/transform/transform.c
source/blender/makesrna/RNA_access.h
source/blender/makesrna/intern/makesrna.c
source/blender/makesrna/intern/rna_action.c
source/blender/makesrna/intern/rna_color.c
source/blender/makesrna/intern/rna_main.c
source/blender/makesrna/intern/rna_main_api.c
source/blender/makesrna/intern/rna_mesh.c
source/blender/makesrna/intern/rna_scene.c
source/blender/makesrna/intern/rna_space.c
source/blender/makesrna/intern/rna_userdef.c
source/blender/render/intern/source/convertblender.c
source/blender/windowmanager/WM_types.h
source/blender/windowmanager/intern/wm_files.c
source/blenderplayer/bad_level_call_stubs/stubs.c
source/creator/CMakeLists.txt

index bd2f3e8e3bf7327a7fa0f20168d572ba5abc777e,6f7d4f3582a51b398462f5406a4f6dd1f15cc9b0..a8e2275e1ae202c097a0ed919d28c5ef3a38ae54
@@@ -261,7 -261,6 +261,7 @@@ else
          "mathutils",
          "mathutils.geometry",
          "mathutils.noise",
 +        "Freestyle",
          ]
  
      # ------
@@@ -447,7 -446,6 +447,7 @@@ if ARGS.sphinx_build_pdf
  ClassMethodDescriptorType = type(dict.__dict__['fromkeys'])
  MethodDescriptorType = type(dict.get)
  GetSetDescriptorType = type(int.real)
 +StaticMethodType = type(staticmethod(lambda: None))
  from types import MemberDescriptorType
  
  _BPY_STRUCT_FAKE = "bpy_struct"
@@@ -908,16 -906,76 +908,82 @@@ def pymodule2sphinx(basepath, module_na
              if type(descr) == GetSetDescriptorType:
                  py_descr2sphinx("   ", fw, descr, module_name, type_name, key)
  
 +        for key, descr in descr_items:
 +            if type(descr) == StaticMethodType:
 +                descr = getattr(value, key)
 +                write_indented_lines("   ", fw, descr.__doc__ or "Undocumented", False)
 +                fw("\n")
 +
          fw("\n\n")
  
      file.close()
  
+ # Changes in blender will force errors here
+ context_type_map = {
+     "active_base": ("ObjectBase", False),
+     "active_bone": ("EditBone", False),
+     "active_object": ("Object", False),
+     "active_operator": ("Operator", False),
+     "active_pose_bone": ("PoseBone", False),
+     "active_node": ("Node", False),
+     "armature": ("Armature", False),
+     "bone": ("Bone", False),
+     "brush": ("Brush", False),
+     "camera": ("Camera", False),
+     "cloth": ("ClothModifier", False),
+     "collision": ("CollisionModifier", False),
+     "curve": ("Curve", False),
+     "dynamic_paint": ("DynamicPaintModifier", False),
+     "edit_bone": ("EditBone", False),
+     "edit_image": ("Image", False),
+     "edit_mask": ("Mask", False),
+     "edit_movieclip": ("MovieClip", False),
+     "edit_object": ("Object", False),
+     "edit_text": ("Text", False),
+     "editable_bones": ("EditBone", True),
+     "fluid": ("FluidSimulationModifier", False),
+     "image_paint_object": ("Object", False),
+     "lamp": ("Lamp", False),
+     "lattice": ("Lattice", False),
+     "material": ("Material", False),
+     "material_slot": ("MaterialSlot", False),
+     "mesh": ("Mesh", False),
+     "meta_ball": ("MetaBall", False),
+     "object": ("Object", False),
+     "particle_edit_object": ("Object", False),
+     "particle_settings": ("ParticleSettings", False),
+     "particle_system": ("ParticleSystem", False),
+     "particle_system_editable": ("ParticleSystem", False),
+     "pose_bone": ("PoseBone", False),
+     "scene": ("Scene", False),
+     "sculpt_object": ("Object", False),
+     "selectable_bases": ("ObjectBase", True),
+     "selectable_objects": ("Object", True),
+     "selected_bases": ("ObjectBase", True),
+     "selected_bones": ("EditBone", True),
+     "selected_editable_bases": ("ObjectBase", True),
+     "selected_editable_bones": ("EditBone", True),
+     "selected_editable_objects": ("Object", True),
+     "selected_editable_sequences": ("Sequence", True),
+     "selected_nodes": ("Node", True),
+     "selected_objects": ("Object", True),
+     "selected_pose_bones": ("PoseBone", True),
+     "selected_sequences": ("Sequence", True),
+     "sequences": ("Sequence", True),
+     "smoke": ("SmokeModifier", False),
+     "soft_body": ("SoftBodyModifier", False),
+     "speaker": ("Speaker", False),
+     "texture": ("Texture", False),
+     "texture_slot": ("MaterialTextureSlot", False),
+     "texture_user": ("ID", False),
+     "vertex_paint_object": ("Object", False),
+     "visible_bases": ("ObjectBase", True),
+     "visible_bones": ("EditBone", True),
+     "visible_objects": ("Object", True),
+     "visible_pose_bones": ("PoseBone", True),
+     "weight_paint_object": ("Object", False),
+     "world": ("World", False),
+ }
  
  def pycontext2sphinx(basepath):
      # Only use once. very irregular
          "sequencer_context_dir",
      )
  
-     # Changes in blender will force errors here
-     type_map = {
-         "active_base": ("ObjectBase", False),
-         "active_bone": ("Bone", False),
-         "active_object": ("Object", False),
-         "active_operator": ("Operator", False),
-         "active_pose_bone": ("PoseBone", False),
-         "active_node": ("Node", False),
-         "armature": ("Armature", False),
-         "bone": ("Bone", False),
-         "brush": ("Brush", False),
-         "camera": ("Camera", False),
-         "cloth": ("ClothModifier", False),
-         "collision": ("CollisionModifier", False),
-         "curve": ("Curve", False),
-         "dynamic_paint": ("DynamicPaintModifier", False),
-         "edit_bone": ("EditBone", False),
-         "edit_image": ("Image", False),
-         "edit_mask": ("Mask", False),
-         "edit_movieclip": ("MovieClip", False),
-         "edit_object": ("Object", False),
-         "edit_text": ("Text", False),
-         "editable_bones": ("EditBone", True),
-         "fluid": ("FluidSimulationModifier", False),
-         "image_paint_object": ("Object", False),
-         "lamp": ("Lamp", False),
-         "lattice": ("Lattice", False),
-         "material": ("Material", False),
-         "material_slot": ("MaterialSlot", False),
-         "mesh": ("Mesh", False),
-         "meta_ball": ("MetaBall", False),
-         "object": ("Object", False),
-         "particle_edit_object": ("Object", False),
-         "particle_settings": ("ParticleSettings", False),
-         "particle_system": ("ParticleSystem", False),
-         "particle_system_editable": ("ParticleSystem", False),
-         "pose_bone": ("PoseBone", False),
-         "scene": ("Scene", False),
-         "sculpt_object": ("Object", False),
-         "selectable_bases": ("ObjectBase", True),
-         "selectable_objects": ("Object", True),
-         "selected_bases": ("ObjectBase", True),
-         "selected_bones": ("Bone", True),
-         "selected_editable_bases": ("ObjectBase", True),
-         "selected_editable_bones": ("Bone", True),
-         "selected_editable_objects": ("Object", True),
-         "selected_editable_sequences": ("Sequence", True),
-         "selected_nodes": ("Node", True),
-         "selected_objects": ("Object", True),
-         "selected_pose_bones": ("PoseBone", True),
-         "selected_sequences": ("Sequence", True),
-         "sequences": ("Sequence", True),
-         "smoke": ("SmokeModifier", False),
-         "soft_body": ("SoftBodyModifier", False),
-         "speaker": ("Speaker", False),
-         "texture": ("Texture", False),
-         "texture_slot": ("MaterialTextureSlot", False),
-         "texture_user": ("ID", False),
-         "vertex_paint_object": ("Object", False),
-         "visible_bases": ("ObjectBase", True),
-         "visible_bones": ("Object", True),
-         "visible_objects": ("Object", True),
-         "visible_pose_bones": ("PoseBone", True),
-         "weight_paint_object": ("Object", False),
-         "world": ("World", False),
-     }
  
      unique = set()
      blend_cdll = ctypes.CDLL("")
          while char_array[i] is not None:
              member = ctypes.string_at(char_array[i]).decode(encoding="ascii")
              fw(".. data:: %s\n\n" % member)
-             member_type, is_seq = type_map[member]
+             member_type, is_seq = context_type_map[member]
              fw("   :type: %s :class:`bpy.types.%s`\n\n" % ("sequence of " if is_seq else "", member_type))
              unique.add(member)
              i += 1
      # generate typemap...
      # for member in sorted(unique):
      #     print('        "%s": ("", False),' % member)
-     if len(type_map) > len(unique):
-         raise Exception("Some types are not used: %s" % str([member for member in type_map if member not in unique]))
+     if len(context_type_map) > len(unique):
+         raise Exception("Some types are not used: %s" % str([member for member in context_type_map if member not in unique]))
      else:
          pass  # will have raised an error above
  
@@@ -1322,6 -1314,13 +1322,13 @@@ def pyrna2sphinx(basepath)
              fw(".. hlist::\n")
              fw("   :columns: 2\n\n")
  
+             # context does its own thing
+             # "active_base": ("ObjectBase", False),
+             for ref_attr, (ref_type, ref_is_seq) in sorted(context_type_map.items()):
+                 if ref_type == struct_id:
+                     fw("   * :mod:`bpy.context.%s`\n" % ref_attr)
+             del ref_attr, ref_type, ref_is_seq
              for ref in struct.references:
                  ref_split = ref.split(".")
                  if len(ref_split) > 2:
@@@ -1532,7 -1531,7 +1539,7 @@@ def write_rst_contents(basepath)
          # mathutils
          "mathutils", "mathutils.geometry", "mathutils.noise",
          # misc
 -        "bgl", "blf", "gpu", "aud", "bpy_extras",
 +        "Freestyle", "bgl", "blf", "gpu", "aud", "bpy_extras",
          # bmesh
          "bmesh", "bmesh.types", "bmesh.utils",
          )
@@@ -1676,7 -1675,6 +1683,7 @@@ def write_rst_importable_modules(basepa
          "mathutils"         : "Math Types & Utilities",
          "mathutils.geometry": "Geometry Utilities",
          "mathutils.noise"   : "Noise Utilities",
 +        "Freestyle"         : "Freestyle Data Types & Operators",
      }
      for mod_name, mod_descr in importable_modules.items():
          if mod_name not in EXCLUDE_MODULES:
index 33ce0e07f177ff13b4369c2e934e69ddd7b73088,abc2626ee1316583c5a6953af12beeba655ce639..aa7d78225d5be91e427ba355dc4f29ef27da0624
@@@ -71,6 -71,110 +71,6 @@@ class RENDER_PT_render(RenderButtonsPan
          layout.prop(rd, "display_mode", text="Display")
  
  
 -class RENDER_PT_layers(RenderButtonsPanel, Panel):
 -    bl_label = "Layers"
 -    bl_options = {'DEFAULT_CLOSED'}
 -    COMPAT_ENGINES = {'BLENDER_RENDER'}
 -
 -    def draw(self, context):
 -        layout = self.layout
 -
 -        scene = context.scene
 -        rd = scene.render
 -
 -        row = layout.row()
 -        row.template_list(rd, "layers", rd.layers, "active_index", rows=2)
 -
 -        col = row.column(align=True)
 -        col.operator("scene.render_layer_add", icon='ZOOMIN', text="")
 -        col.operator("scene.render_layer_remove", icon='ZOOMOUT', text="")
 -
 -        row = layout.row()
 -        rl = rd.layers.active
 -        if rl:
 -            row.prop(rl, "name")
 -        row.prop(rd, "use_single_layer", text="", icon_only=True)
 -
 -        split = layout.split()
 -
 -        col = split.column()
 -        col.prop(scene, "layers", text="Scene")
 -        col.label(text="")
 -        col.prop(rl, "light_override", text="Light")
 -        col.prop(rl, "material_override", text="Material")
 -
 -        col = split.column()
 -        col.prop(rl, "layers", text="Layer")
 -        col.label(text="Mask Layers:")
 -        col.prop(rl, "layers_zmask", text="")
 -
 -        layout.separator()
 -        layout.label(text="Include:")
 -
 -        split = layout.split()
 -
 -        col = split.column()
 -        col.prop(rl, "use_zmask")
 -        row = col.row()
 -        row.prop(rl, "invert_zmask", text="Negate")
 -        row.active = rl.use_zmask
 -        col.prop(rl, "use_all_z")
 -
 -        col = split.column()
 -        col.prop(rl, "use_solid")
 -        col.prop(rl, "use_halo")
 -        col.prop(rl, "use_ztransp")
 -
 -        col = split.column()
 -        col.prop(rl, "use_sky")
 -        col.prop(rl, "use_edge_enhance")
 -        col.prop(rl, "use_strand")
 -
 -        layout.separator()
 -
 -        split = layout.split()
 -
 -        col = split.column()
 -        col.label(text="Passes:")
 -        col.prop(rl, "use_pass_combined")
 -        col.prop(rl, "use_pass_z")
 -        col.prop(rl, "use_pass_vector")
 -        col.prop(rl, "use_pass_normal")
 -        col.prop(rl, "use_pass_uv")
 -        col.prop(rl, "use_pass_mist")
 -        col.prop(rl, "use_pass_object_index")
 -        col.prop(rl, "use_pass_material_index")
 -        col.prop(rl, "use_pass_color")
 -
 -        col = split.column()
 -        col.label()
 -        col.prop(rl, "use_pass_diffuse")
 -        row = col.row()
 -        row.prop(rl, "use_pass_specular")
 -        row.prop(rl, "exclude_specular", text="")
 -        row = col.row()
 -        row.prop(rl, "use_pass_shadow")
 -        row.prop(rl, "exclude_shadow", text="")
 -        row = col.row()
 -        row.prop(rl, "use_pass_emit")
 -        row.prop(rl, "exclude_emit", text="")
 -        row = col.row()
 -        row.prop(rl, "use_pass_ambient_occlusion")
 -        row.prop(rl, "exclude_ambient_occlusion", text="")
 -        row = col.row()
 -        row.prop(rl, "use_pass_environment")
 -        row.prop(rl, "exclude_environment", text="")
 -        row = col.row()
 -        row.prop(rl, "use_pass_indirect")
 -        row.prop(rl, "exclude_indirect", text="")
 -        row = col.row()
 -        row.prop(rl, "use_pass_reflection")
 -        row.prop(rl, "exclude_reflection", text="")
 -        row = col.row()
 -        row.prop(rl, "use_pass_refraction")
 -        row.prop(rl, "exclude_refraction", text="")
 -
 -
  class RENDER_PT_dimensions(RenderButtonsPanel, Panel):
      bl_label = "Dimensions"
      COMPAT_ENGINES = {'BLENDER_RENDER'}
@@@ -228,11 -332,13 +228,13 @@@ class RENDER_PT_performance(RenderButto
          split = layout.split()
  
          col = split.column()
-         col.label(text="Threads:")
-         col.row().prop(rd, "threads_mode", expand=True)
-         sub = col.column()
-         sub.enabled = rd.threads_mode == 'FIXED'
-         sub.prop(rd, "threads")
+         sub = col.column(align=True)
+         sub.label(text="Threads:")
+         sub.row().prop(rd, "threads_mode", expand=True)
+         subsub = sub.column()
+         subsub.enabled = rd.threads_mode == 'FIXED'
+         subsub.prop(rd, "threads")
+         
          sub = col.column(align=True)
          sub.label(text="Tiles:")
          sub.prop(rd, "parts_x", text="X")
@@@ -295,30 -401,6 +297,30 @@@ class RENDER_PT_post_processing(RenderB
          sub.prop(rd, "edge_color", text="")
  
  
 +class RENDER_PT_freestyle(RenderButtonsPanel, Panel):
 +    bl_label = "Freestyle"
 +    bl_options = {'DEFAULT_CLOSED'}
 +    COMPAT_ENGINES = {'BLENDER_RENDER'}
 +
 +    def draw_header(self, context):
 +        rd = context.scene.render
 +
 +        self.layout.prop(rd, "use_freestyle", text="")
 +
 +    def draw(self, context):
 +        rd = context.scene.render
 +
 +        layout = self.layout
 +        layout.enabled = rd.use_freestyle
 +
 +        row = layout.row()
 +        row.label(text="Line Thickness:")
 +        row.prop(rd, "line_thickness_mode", expand=True)
 +        row = layout.row()
 +        row.enabled = (rd.line_thickness_mode == "ABSOLUTE")
 +        row.prop(rd, "unit_line_thickness")
 +
 +
  class RENDER_PT_stamp(RenderButtonsPanel, Panel):
      bl_label = "Stamp"
      bl_options = {'DEFAULT_CLOSED'}
index 65e5b529487fa1ce7da0ada8e27778fef25021b2,6361a0dfc2711372c1c9a8db27f373ba01d31e86..5d949e89caa5cb963e34df2ad3c3352228461f19
@@@ -571,7 -571,7 +571,7 @@@ class VIEW3D_MT_select_edit_mesh(Menu)
          layout.separator()
  
          layout.operator("mesh.select_random", text="Random")
-         layout.operator("mesh.select_nth", text="Every N Number of Verts")
+         layout.operator("mesh.select_nth")
          layout.operator("mesh.edges_select_sharp", text="Sharp Edges")
          layout.operator("mesh.faces_select_linked_flat", text="Linked Flat Faces")
          layout.operator("mesh.select_interior_faces", text="Interior Faces")
  
          layout.separator()
  
-         layout.operator("mesh.select_by_number_vertices", text="By Number of Verts")
+         layout.operator("mesh.select_face_by_sides")
          if context.scene.tool_settings.mesh_select_mode[2] is False:
              layout.operator("mesh.select_non_manifold", text="Non Manifold")
          layout.operator("mesh.select_loose_verts", text="Loose Verts/Edges")
@@@ -968,8 -968,9 +968,9 @@@ class VIEW3D_MT_object_parent(Menu)
      def draw(self, context):
          layout = self.layout
  
-         layout.operator_menu_enum("object.parent_set", "type", text="Set")
-         layout.operator_menu_enum("object.parent_clear", "type", text="Clear")
+         layout.operator_enum("object.parent_set", "type")
+         layout.separator()
+         layout.operator_enum("object.parent_clear", "type")
  
  
  class VIEW3D_MT_object_track(Menu):
      def draw(self, context):
          layout = self.layout
  
-         layout.operator_menu_enum("object.track_set", "type", text="Set")
-         layout.operator_menu_enum("object.track_clear", "type", text="Clear")
+         layout.operator_enum("object.track_set", "type")
+         layout.separator()
+         layout.operator_enum("object.track_clear", "type")
  
  
  class VIEW3D_MT_object_group(Menu):
@@@ -1842,11 -1844,6 +1844,11 @@@ class VIEW3D_MT_edit_mesh_edges(Menu)
  
          layout.separator()
  
 +        layout.operator("mesh.mark_freestyle_edge").clear = False
 +        layout.operator("mesh.mark_freestyle_edge", text="Clear Freestyle Edge").clear = True
 +
 +        layout.separator()
 +
          layout.operator("mesh.edge_rotate", text="Rotate Edge CW").direction = 'CW'
          layout.operator("mesh.edge_rotate", text="Rotate Edge CCW").direction = 'CCW'
  
@@@ -1887,11 -1884,6 +1889,11 @@@ class VIEW3D_MT_edit_mesh_faces(Menu)
  
          layout.separator()
  
 +        layout.operator("mesh.mark_freestyle_face").clear = False
 +        layout.operator("mesh.mark_freestyle_face", text="Clear Freestyle Face").clear = True
 +
 +        layout.separator()
 +
          layout.operator("mesh.quads_convert_to_tris")
          layout.operator("mesh.tris_convert_to_quads")
  
@@@ -1951,10 -1943,6 +1953,6 @@@ class VIEW3D_MT_edit_mesh_dissolve(Menu
  
          layout.separator()
  
-         layout.operator_enum("mesh.dissolve", "type")
-         layout.separator()
          layout.operator("mesh.dissolve_limited")
  
  
@@@ -2499,8 -2487,6 +2497,8 @@@ class VIEW3D_PT_view3d_meshdisplay(Pane
          col.prop(mesh, "show_edge_bevel_weight", text="Bevel Weights")
          col.prop(mesh, "show_edge_seams", text="Seams")
          col.prop(mesh, "show_edge_sharp", text="Sharp")
 +        col.prop(mesh, "show_freestyle_edge_marks", text="Freestyle Edge Marks")
 +        col.prop(mesh, "show_freestyle_face_marks", text="Freestyle Face Marks")
  
          col.separator()
          col.label(text="Normals:")
index 549d4e2d12673d40fc49b35e1920a5b1e6b610ef,5b211d7f09aa113c452d37cd6b2cfd85388c7027..535400014976ad09760b1c230b6b0667aab7b2f7
  
  #include "GPU_material.h"
  
 +#include "FRS_freestyle.h"
 +
  /* Local function protos */
  float originmat[3][3];  /* after BKE_object_where_is_calc(), can be used in other functions (bad!) */
  
@@@ -306,7 -304,7 +306,7 @@@ void BKE_object_free(Object *ob
        if (ob->data) {
                ID *id = ob->data;
                id->us--;
-               if (id->us == 0 && id->lib==NULL) {
+               if (id->us == 0 && id->lib == NULL) {
                        switch (ob->type) {
                                case OB_MESH:
                                        BKE_mesh_unlink((Mesh *)id);
@@@ -632,14 -630,6 +632,14 @@@ void BKE_object_unlink(Object *ob
                                }
                                SEQ_END
                        }
 +
 +                      {
 +                              SceneRenderLayer *srl;
 +
 +                              for (srl= sce->r.layers.first; srl; srl= srl->next) {
 +                                      FRS_unlink_target_object(&srl->freestyleConfig, ob);
 +                              }
 +                      }
                }
  
                sce = sce->id.next;
@@@ -864,7 -854,9 +864,9 @@@ Object *BKE_object_add_only_object(int 
        ob->step_height = 0.15f;
        ob->jump_speed = 10.0f;
        ob->fall_speed = 55.0f;
-       
+       ob->col_group = 0x01;
+       ob->col_mask = 0xff;
        /* NT fluid sim defaults */
        ob->fluidsimSettings = NULL;
  
index 33350a80928014c1cc00abc6e99fbfd9fd3266de,8a669b89907707484b860dcfb5d875b15368de75..469b012f9c319d8254e6aa6ff2e4f5ad4830d5c9
@@@ -602,7 -602,7 +602,7 @@@ static void ss_sync_from_derivedmesh(CC
        }
  
        mp = mpoly;
-       index = DM_get_poly_data_layer(dm, CD_ORIGINDEX);
+       index = (int *)dm->getPolyDataArray(dm, CD_ORIGINDEX);
        for (i = 0; i < dm->numPolyData; i++, mp++) {
                CCGFace *f;
  
@@@ -964,7 -964,7 +964,7 @@@ static void ccgDM_getFinalEdge(DerivedM
  
                edgeFlag = (ccgdm->edgeFlags) ? &ccgdm->edgeFlags[i] : NULL;
                if (edgeFlag)
 -                      flags |= (*edgeFlag & (ME_SEAM | ME_SHARP)) | ME_EDGEDRAW | ME_EDGERENDER;
 +                      flags |= (*edgeFlag & (ME_SEAM | ME_SHARP | ME_FREESTYLE_EDGE)) | ME_EDGEDRAW | ME_EDGERENDER;
                else
                        flags |= ME_EDGEDRAW | ME_EDGERENDER;
  
@@@ -1228,7 -1228,7 +1228,7 @@@ static void ccgDM_copyFinalEdgeArray(De
  
                if (edgeFlags) {
                        if (edgeIdx != -1) {
 -                              flags |= ((edgeFlags[index] & (ME_SEAM | ME_SHARP)) | ME_EDGEDRAW | ME_EDGERENDER);
 +                              flags |= ((edgeFlags[index] & (ME_SEAM | ME_SHARP | ME_FREESTYLE_EDGE)) | ME_EDGEDRAW | ME_EDGERENDER);
                        }
                }
                else {
@@@ -2703,6 -2703,30 +2703,30 @@@ static void *ccgDM_get_edge_data_layer(
  }
  
  static void *ccgDM_get_tessface_data_layer(DerivedMesh *dm, int type)
+ {
+       if (type == CD_ORIGINDEX) {
+               /* create origindex on demand to save memory */
+               int *origindex;
+               /* Avoid re-creation if the layer exists already */
+               origindex = DM_get_tessface_data_layer(dm, CD_ORIGINDEX);
+               if (origindex) {
+                       return origindex;
+               }
+               DM_add_tessface_layer(dm, CD_ORIGINDEX, CD_CALLOC, NULL);
+               origindex = DM_get_tessface_data_layer(dm, CD_ORIGINDEX);
+               /* silly loop counting up */
+               range_vn_i(origindex, dm->getNumTessFaces(dm), 0);
+               return origindex;
+       }
+       return DM_get_tessface_data_layer(dm, type);
+ }
+ static void *ccgDM_get_poly_data_layer(DerivedMesh *dm, int type)
  {
        if (type == CD_ORIGINDEX) {
                /* create origindex on demand to save memory */
                int gridFaces = ccgSubSurf_getGridSize(ss) - 1;
  
                /* Avoid re-creation if the layer exists already */
-               origindex = DM_get_tessface_data_layer(dm, CD_ORIGINDEX);
+               origindex = DM_get_poly_data_layer(dm, CD_ORIGINDEX);
                if (origindex) {
                        return origindex;
                }
  
-               DM_add_tessface_layer(dm, CD_ORIGINDEX, CD_CALLOC, NULL);
-               origindex = DM_get_tessface_data_layer(dm, CD_ORIGINDEX);
+               DM_add_poly_layer(dm, CD_ORIGINDEX, CD_CALLOC, NULL);
+               origindex = DM_get_poly_data_layer(dm, CD_ORIGINDEX);
  
                totface = ccgSubSurf_getNumFaces(ss);
  
                return origindex;
        }
  
-       return DM_get_tessface_data_layer(dm, type);
+       return DM_get_poly_data_layer(dm, type);
  }
  
  static void *ccgDM_get_vert_data(DerivedMesh *dm, int index, int type)
@@@ -2768,6 -2792,16 +2792,16 @@@ static void *ccgDM_get_tessface_data(De
        return DM_get_tessface_data(dm, index, type);
  }
  
+ static void *ccgDM_get_poly_data(DerivedMesh *dm, int index, int type)
+ {
+       if (type == CD_ORIGINDEX) {
+               /* ensure creation of CD_ORIGINDEX layer */
+               ccgDM_get_tessface_data_layer(dm, type);
+       }
+       return DM_get_poly_data(dm, index, type);
+ }
  static int ccgDM_getNumGrids(DerivedMesh *dm)
  {
        CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm;
@@@ -3098,7 -3132,7 +3132,7 @@@ static CCGDerivedMesh *getCCGDerivedMes
        }
  
        /* We absolutely need that layer, else it's no valid tessellated data! */
-       polyidx = CustomData_add_layer(&ccgdm->dm.faceData, CD_POLYINDEX, CD_CALLOC,
+       polyidx = CustomData_add_layer(&ccgdm->dm.faceData, CD_ORIGINDEX, CD_CALLOC,
                                       NULL, ccgSubSurf_getNumFinalFaces(ss));
  
        ccgdm->dm.getMinMax = ccgDM_getMinMax;
        ccgdm->dm.getVertData = ccgDM_get_vert_data;
        ccgdm->dm.getEdgeData = ccgDM_get_edge_data;
        ccgdm->dm.getTessFaceData = ccgDM_get_tessface_data;
+       ccgdm->dm.getPolyData = ccgDM_get_poly_data;
        ccgdm->dm.getVertDataArray = ccgDM_get_vert_data_layer;
        ccgdm->dm.getEdgeDataArray = ccgDM_get_edge_data_layer;
        ccgdm->dm.getTessFaceDataArray = ccgDM_get_tessface_data_layer;
+       ccgdm->dm.getPolyDataArray = ccgDM_get_poly_data_layer;
        ccgdm->dm.getNumGrids = ccgDM_getNumGrids;
        ccgdm->dm.getGridSize = ccgDM_getGridSize;
        ccgdm->dm.getGridData = ccgDM_getGridData;
  
        vertOrigIndex = DM_get_vert_data_layer(&ccgdm->dm, CD_ORIGINDEX);
        /*edgeOrigIndex = DM_get_edge_data_layer(&ccgdm->dm, CD_ORIGINDEX);*/
-       faceOrigIndex = DM_get_tessface_data_layer(&ccgdm->dm, CD_ORIGINDEX);
  
+       faceOrigIndex = DM_get_tessface_data_layer(&ccgdm->dm, CD_ORIGINDEX);
        polyOrigIndex = DM_get_poly_data_layer(&ccgdm->dm, CD_ORIGINDEX);
  
  #if 0
                                        
                                        /*set original index data*/
                                        if (faceOrigIndex) {
-                                               *faceOrigIndex = origIndex;
+                                               /* reference the index in 'polyOrigIndex' */
+                                               *faceOrigIndex = faceNum;
                                                faceOrigIndex++;
                                        }
                                        if (polyOrigIndex) {
index 8929fa3ff7ad301df803e5de985309b8d95e6833,44561e7c0557deccde4b5849c6910ead14203819..0b9421d2b1275dcef7feb684c88d3bf75c02c453
@@@ -70,7 -70,6 +70,7 @@@
  #include "DNA_key_types.h"
  #include "DNA_lattice_types.h"
  #include "DNA_lamp_types.h"
 +#include "DNA_linestyle_types.h"
  #include "DNA_meta_types.h"
  #include "DNA_material_types.h"
  #include "DNA_mesh_types.h"
@@@ -819,7 -818,7 +819,7 @@@ static void decode_blender_header(FileD
                        /* is the file saved in a different endian
                         * than we need ?
                         */
 -                      if (((((char *)&remove_this_endian_test)[0] == 1) ? L_ENDIAN : B_ENDIAN) != ((header[8] == 'v') ? L_ENDIAN : B_ENDIAN)) {
 +                      if (((((char*)&remove_this_endian_test)[0]==1)?L_ENDIAN:B_ENDIAN) != ((header[8]=='v')?L_ENDIAN:B_ENDIAN)) {
                                fd->flags |= FD_FLAGS_SWITCH_ENDIAN;
                        }
                        
@@@ -941,7 -940,7 +941,7 @@@ static int fd_read_from_memfile(FileDat
                        if (chunkoffset+readsize > chunk->size)
                                readsize= chunk->size-chunkoffset;
                        
 -                      memcpy((char *)buffer + totread, chunk->buf + chunkoffset, readsize);
 +                      memcpy((char*)buffer + totread, chunk->buf + chunkoffset, readsize);
                        totread += readsize;
                        filedata->seek += readsize;
                        seek += readsize;
@@@ -983,7 -982,7 +983,7 @@@ static FileData *blo_decode_and_check(F
                        blo_freefiledata(fd);
                        fd = NULL;
                }
 -      }
 +      } 
        else {
                BKE_reportf(reports, RPT_ERROR, "Failed to read blend file '%s', not a blend file", fd->relabase);
                blo_freefiledata(fd);
@@@ -1130,7 -1129,7 +1130,7 @@@ int BLO_is_a_library(const char *path, 
                /* the last part of the dir is a .blend file, no group follows */
                *fd = '/'; /* put back the removed slash separating the dir and the .blend file name */
        }
 -      else {
 +      else {          
                char *gp = fd + 1; // in case we have a .blend file, gp points to the group
                
                /* Find the last slash */
@@@ -1839,7 -1838,7 +1839,7 @@@ static void lib_link_fcurves(FileData *
                        
                        for (dvar= driver->variables.first; dvar; dvar= dvar->next) {
                                DRIVER_TARGETS_LOOPER(dvar)
 -                              {
 +                              {       
                                        /* only relink if still used */
                                        if (tarIndex < dvar->num_targets)
                                                dtar->id = newlibadr(fd, id->lib, dtar->id); 
@@@ -2430,8 -2429,18 +2430,18 @@@ static void direct_link_nodetree(FileDa
                
                if (node->storage) {
                        /* could be handlerized at some point */
-                       if (ntree->type==NTREE_SHADER && (node->type==SH_NODE_CURVE_VEC || node->type==SH_NODE_CURVE_RGB))
+                       if (ntree->type==NTREE_SHADER) {
+                               if (node->type==SH_NODE_CURVE_VEC || node->type==SH_NODE_CURVE_RGB) {
 -                                      direct_link_curvemapping(fd, node->storage);
 +                              direct_link_curvemapping(fd, node->storage);
+                               }
+                               else if (node->type==SH_NODE_SCRIPT) {
+                                       NodeShaderScript *nss = (NodeShaderScript *) node->storage;
+                                       nss->bytecode = newdataadr(fd, nss->bytecode);
+                                       nss->prop = newdataadr(fd, nss->prop);
+                                       if (nss->prop)
+                                               IDP_DirectLinkProperty(nss->prop, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd);
+                               }
+                       }
                        else if (ntree->type==NTREE_COMPOSIT) {
                                if (ELEM4(node->type, CMP_NODE_TIME, CMP_NODE_CURVE_VEC, CMP_NODE_CURVE_RGB, CMP_NODE_HUECORRECT))
                                        direct_link_curvemapping(fd, node->storage);
@@@ -2806,7 -2815,7 +2816,7 @@@ static void switch_endian_keyblock(Key 
                        
                        cp += 2;
                }
 -              data += elemsize;
 +              data+= elemsize;
        }
  }
  
@@@ -2841,7 -2850,7 +2851,7 @@@ static void lib_link_mball(FileData *fd
                        if (mb->adt) lib_link_animdata(fd, &mb->id, mb->adt);
                        
                        for (a = 0; a < mb->totcol; a++) 
 -                              mb->mat[a] = newlibadr_us(fd, mb->id.lib, mb->mat[a]);
 +                              mb->mat[a]= newlibadr_us(fd, mb->id.lib, mb->mat[a]);
                        
                        mb->ipo = newlibadr_us(fd, mb->id.lib, mb->ipo); // XXX deprecated - old animation system
                        
@@@ -3079,7 -3088,7 +3089,7 @@@ static void lib_link_curve(FileData *fd
                        cu->taperobj = newlibadr(fd, cu->id.lib, cu->taperobj);
                        cu->textoncurve = newlibadr(fd, cu->id.lib, cu->textoncurve);
                        cu->vfont = newlibadr_us(fd, cu->id.lib, cu->vfont);
 -                      cu->vfontb = newlibadr_us(fd, cu->id.lib, cu->vfontb);
 +                      cu->vfontb = newlibadr_us(fd, cu->id.lib, cu->vfontb);                  
                        cu->vfonti = newlibadr_us(fd, cu->id.lib, cu->vfonti);
                        cu->vfontbi = newlibadr_us(fd, cu->id.lib, cu->vfontbi);
                        
@@@ -3113,7 -3122,7 +3123,7 @@@ static void direct_link_curve(FileData 
        cu->mat = newdataadr(fd, cu->mat);
        test_pointer_array(fd, (void **)&cu->mat);
        cu->str = newdataadr(fd, cu->str);
 -      cu->strinfo= newdataadr(fd, cu->strinfo);
 +      cu->strinfo= newdataadr(fd, cu->strinfo);       
        cu->tb = newdataadr(fd, cu->tb);
  
        if (cu->vfont == NULL) link_list(fd, &(cu->nurb));
                if (cu->tb) {
                        memcpy(tb, cu->tb, cu->totbox*sizeof(TextBox));
                        MEM_freeN(cu->tb);
 -                      cu->tb = tb;
 +                      cu->tb = tb;                    
                }
                else {
                        cu->totbox = 1;
                        cu->actbox = 1;
                        cu->tb = tb;
                        cu->tb[0].w = cu->linewidth;
 -              }
 +              }               
                if (cu->wordspace == 0.0f) cu->wordspace = 1.0f;
        }
  
@@@ -3300,7 -3309,7 +3310,7 @@@ static const char *ptcache_data_struct[
        "", // BPHYS_DATA_ROTATION
        "", // BPHYS_DATA_AVELOCITY / BPHYS_DATA_XCONST */
        "", // BPHYS_DATA_SIZE:
 -      "", // BPHYS_DATA_TIMES:
 +      "", // BPHYS_DATA_TIMES:        
        "BoidData" // case BPHYS_DATA_BOIDS:
  };
  static void direct_link_pointcache(FileData *fd, PointCache *cache)
@@@ -3409,7 -3418,7 +3419,7 @@@ static void lib_link_particlesettings(F
                                        /* special case for only one object in the group */
                                        index_ok = 1;
                                }
 -                              else {
 +                              else { 
                                        for (dw = part->dupliweights.first; dw; dw = dw->next) {
                                                if (dw->index > 0) {
                                                        index_ok = 1;
                                                }
                                        }
                                }
 -
 +                              
                                if (index_ok) {
                                        /* if we have indexes, let's use them */
                                        for (dw = part->dupliweights.first; dw; dw = dw->next) {
                                        /* otherwise try to get objects from own library (won't work on library linked groups) */
                                        for (dw = part->dupliweights.first; dw; dw = dw->next) {
                                                dw->ob = newlibadr(fd, part->id.lib, dw->ob);
 -                                      }
                                }
                        }
 +                      }
                        else {
                                part->dupliweights.first = part->dupliweights.last = NULL;
                        }
@@@ -3646,7 -3655,7 +3656,7 @@@ static void lib_link_mtface(FileData *f
  
  static void lib_link_customdata_mtface(FileData *fd, Mesh *me, CustomData *fdata, int totface)
  {
 -      int i;
 +      int i;  
        for (i = 0; i < fdata->totlayer; i++) {
                CustomDataLayer *layer = &fdata->layers[i];
                
@@@ -3671,11 -3680,11 +3681,11 @@@ static void lib_link_customdata_mtpoly(
                                tf->tpage = newlibadr(fd, me->id.lib, tf->tpage);
                                if (tf->tpage && tf->tpage->id.us == 0) {
                                        tf->tpage->id.us = 1;
 -                              }
                        }
                }
        }
  }
 +}
  
  static void lib_link_mesh(FileData *fd, Main *main)
  {
                        /*
                         * Re-tessellate, even if the polys were just created from tessfaces, this
                         * is important because it:
-                        *  - fill the CD_POLYINDEX layer
+                        *  - fill the CD_ORIGINDEX layer
                         *  - gives consistency of tessface between loading from a file and
                         *    converting an edited BMesh back into a mesh (i.e. it replaces
                         *    quad tessfaces in a loaded mesh immediately, instead of lazily
@@@ -3825,7 -3834,7 +3835,7 @@@ static void direct_link_customdata(File
        /* annoying workaround for bug [#31079] loading legacy files with
         * no polygons _but_ have stale customdata */
        if (UNLIKELY(count == 0 && data->layers == NULL && data->totlayer != 0)) {
-               memset(data, 0, sizeof(*data));
+               CustomData_reset(data);
                return;
        }
        
@@@ -4095,7 -4104,7 +4105,7 @@@ static void lib_link_object(FileData *f
                                if (paf->type == EFF_PARTICLE) {
                                        paf->group = newlibadr_us(fd, ob->id.lib, paf->group);
                                }
 -                      }
 +                      }                               
                        
                        for (sens = ob->sensors.first; sens; sens = sens->next) {
                                for (a = 0; a < sens->totlinks; a++)
@@@ -4627,7 -4636,7 +4637,7 @@@ static void direct_link_object(FileDat
        direct_link_partdeflect(ob->pd);
        ob->soft= newdataadr(fd, ob->soft);
        if (ob->soft) {
 -              SoftBody *sb = ob->soft;
 +              SoftBody *sb = ob->soft;                
                
                sb->bpoint = NULL;      // init pointers so it gets rebuilt nicely
                sb->bspring = NULL;
@@@ -4774,7 -4783,6 +4784,7 @@@ static void lib_link_scene(FileData *fd
        Base *base, *next;
        Sequence *seq;
        SceneRenderLayer *srl;
 +      FreestyleLineSet *fls;
        TimeMarker *marker;
        
        for (sce = main->scene.first; sce; sce = sce->id.next) {
                        for (srl = sce->r.layers.first; srl; srl = srl->next) {
                                srl->mat_override = newlibadr_us(fd, sce->id.lib, srl->mat_override);
                                srl->light_override = newlibadr_us(fd, sce->id.lib, srl->light_override);
 +                              for(fls=srl->freestyleConfig.linesets.first; fls; fls= fls->next) {
 +                                      fls->linestyle= newlibadr_us(fd, sce->id.lib, fls->linestyle);
 +                                      fls->group= newlibadr_us(fd, sce->id.lib, fls->group);
 +                              }
                        }
                        /*Game Settings: Dome Warp Text*/
                        sce->gm.dome.warptext = newlibadr(fd, sce->id.lib, sce->gm.dome.warptext);
@@@ -4950,7 -4954,6 +4960,7 @@@ static void direct_link_scene(FileData 
        Editing *ed;
        Sequence *seq;
        MetaStack *ms;
 +      SceneRenderLayer *srl;
        
        sce->theDag = NULL;
        sce->dagisvalid = 0;
                                        ed->seqbasep = (ListBase *)(poin+offset);
                                else
                                        ed->seqbasep = &ed->seqbase;
 -                      }
 +                      }                       
                        /* stack */
                        link_list(fd, &(ed->metastack));
                        
        }
        if (sce->r.ffcodecdata.properties) {
                sce->r.ffcodecdata.properties = newdataadr(fd, sce->r.ffcodecdata.properties);
 -              if (sce->r.ffcodecdata.properties) {
 +              if (sce->r.ffcodecdata.properties) { 
                        IDP_DirectLinkProperty(sce->r.ffcodecdata.properties, 
                                (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd);
                }
        link_list(fd, &(sce->markers));
        link_list(fd, &(sce->transform_spaces));
        link_list(fd, &(sce->r.layers));
 +
 +      for(srl = sce->r.layers.first; srl; srl = srl->next) {
 +              link_list(fd, &(srl->freestyleConfig.modules));
 +      }
 +      for(srl = sce->r.layers.first; srl; srl = srl->next) {
 +              link_list(fd, &(srl->freestyleConfig.linesets));
 +      }
        
        sce->nodetree = newdataadr(fd, sce->nodetree);
        if (sce->nodetree) {
@@@ -6389,177 -6385,6 +6399,177 @@@ static void lib_link_mask(FileData *fd
        }
  }
  
 +/* ************ READ LINE STYLE ***************** */
 +
 +static void lib_link_linestyle(FileData *fd, Main *main)
 +{
 +      FreestyleLineStyle *linestyle;
 +      LineStyleModifier *m;
 +
 +      linestyle = main->linestyle.first;
 +      while (linestyle) {
 +              if (linestyle->id.flag & LIB_NEED_LINK) {
 +                      linestyle->id.flag -= LIB_NEED_LINK;
 +
 +                      if (linestyle->id.properties) IDP_LibLinkProperty(linestyle->id.properties, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd);
 +                      if (linestyle->adt) lib_link_animdata(fd, &linestyle->id, linestyle->adt);
 +                      for (m = linestyle->color_modifiers.first; m; m = m->next) {
 +                              switch (m->type) {
 +                              case LS_MODIFIER_DISTANCE_FROM_OBJECT:
 +                                      {
 +                                              LineStyleColorModifier_DistanceFromObject *cm = (LineStyleColorModifier_DistanceFromObject *)m;
 +                                              cm->target = newlibadr(fd, linestyle->id.lib, cm->target);
 +                                      }
 +                                      break;
 +                              }
 +                      }
 +                      for (m = linestyle->alpha_modifiers.first; m; m = m->next){
 +                              switch (m->type) {
 +                              case LS_MODIFIER_DISTANCE_FROM_OBJECT:
 +                                      {
 +                                              LineStyleAlphaModifier_DistanceFromObject *am = (LineStyleAlphaModifier_DistanceFromObject *)m;
 +                                              am->target = newlibadr(fd, linestyle->id.lib, am->target);
 +                                      }
 +                                      break;
 +                              }
 +                      }
 +                      for (m = linestyle->thickness_modifiers.first; m; m = m->next){
 +                              switch (m->type) {
 +                              case LS_MODIFIER_DISTANCE_FROM_OBJECT:
 +                                      {
 +                                              LineStyleThicknessModifier_DistanceFromObject *tm = (LineStyleThicknessModifier_DistanceFromObject *)m;
 +                                              tm->target = newlibadr(fd, linestyle->id.lib, tm->target);
 +                                      }
 +                                      break;
 +                              }
 +                      }
 +              }
 +              linestyle = linestyle->id.next;
 +      }
 +}
 +
 +static void direct_link_linestyle_color_modifier(FileData *fd, LineStyleModifier *modifier)
 +{
 +      switch (modifier->type) {
 +      case LS_MODIFIER_ALONG_STROKE:
 +              {
 +                      LineStyleColorModifier_AlongStroke *m = (LineStyleColorModifier_AlongStroke *)modifier;
 +                      m->color_ramp = newdataadr(fd, m->color_ramp);
 +              }
 +              break;
 +      case LS_MODIFIER_DISTANCE_FROM_CAMERA:
 +              {
 +                      LineStyleColorModifier_DistanceFromCamera *m = (LineStyleColorModifier_DistanceFromCamera *)modifier;
 +                      m->color_ramp = newdataadr(fd, m->color_ramp);
 +              }
 +              break;
 +      case LS_MODIFIER_DISTANCE_FROM_OBJECT:
 +              {
 +                      LineStyleColorModifier_DistanceFromObject *m = (LineStyleColorModifier_DistanceFromObject *)modifier;
 +                      m->color_ramp = newdataadr(fd, m->color_ramp);
 +              }
 +              break;
 +      case LS_MODIFIER_MATERIAL:
 +              {
 +                      LineStyleColorModifier_Material *m = (LineStyleColorModifier_Material *)modifier;
 +                      m->color_ramp = newdataadr(fd, m->color_ramp);
 +              }
 +              break;
 +      }
 +}
 +
 +static void direct_link_linestyle_alpha_modifier(FileData *fd, LineStyleModifier *modifier)
 +{
 +      switch (modifier->type) {
 +      case LS_MODIFIER_ALONG_STROKE:
 +              {
 +                      LineStyleAlphaModifier_AlongStroke *m = (LineStyleAlphaModifier_AlongStroke *)modifier;
 +                      m->curve = newdataadr(fd, m->curve);
 +                      direct_link_curvemapping(fd, m->curve);
 +              }
 +              break;
 +      case LS_MODIFIER_DISTANCE_FROM_CAMERA:
 +              {
 +                      LineStyleAlphaModifier_DistanceFromCamera *m = (LineStyleAlphaModifier_DistanceFromCamera *)modifier;
 +                      m->curve = newdataadr(fd, m->curve);
 +                      direct_link_curvemapping(fd, m->curve);
 +              }
 +              break;
 +      case LS_MODIFIER_DISTANCE_FROM_OBJECT:
 +              {
 +                      LineStyleAlphaModifier_DistanceFromObject *m = (LineStyleAlphaModifier_DistanceFromObject *)modifier;
 +                      m->curve = newdataadr(fd, m->curve);
 +                      direct_link_curvemapping(fd, m->curve);
 +              }
 +              break;
 +      case LS_MODIFIER_MATERIAL:
 +              {
 +                      LineStyleAlphaModifier_Material *m = (LineStyleAlphaModifier_Material *)modifier;
 +                      m->curve = newdataadr(fd, m->curve);
 +                      direct_link_curvemapping(fd, m->curve);
 +              }
 +              break;
 +      }
 +}
 +
 +static void direct_link_linestyle_thickness_modifier(FileData *fd, LineStyleModifier *modifier)
 +{
 +      switch (modifier->type) {
 +      case LS_MODIFIER_ALONG_STROKE:
 +              {
 +                      LineStyleThicknessModifier_AlongStroke *m = (LineStyleThicknessModifier_AlongStroke *)modifier;
 +                      m->curve = newdataadr(fd, m->curve);
 +                      direct_link_curvemapping(fd, m->curve);
 +              }
 +              break;
 +      case LS_MODIFIER_DISTANCE_FROM_CAMERA:
 +              {
 +                      LineStyleThicknessModifier_DistanceFromCamera *m = (LineStyleThicknessModifier_DistanceFromCamera *)modifier;
 +                      m->curve = newdataadr(fd, m->curve);
 +                      direct_link_curvemapping(fd, m->curve);
 +              }
 +              break;
 +      case LS_MODIFIER_DISTANCE_FROM_OBJECT:
 +              {
 +                      LineStyleThicknessModifier_DistanceFromObject *m = (LineStyleThicknessModifier_DistanceFromObject *)modifier;
 +                      m->curve = newdataadr(fd, m->curve);
 +                      direct_link_curvemapping(fd, m->curve);
 +              }
 +              break;
 +      case LS_MODIFIER_MATERIAL:
 +              {
 +                      LineStyleThicknessModifier_Material *m = (LineStyleThicknessModifier_Material *)modifier;
 +                      m->curve = newdataadr(fd, m->curve);
 +                      direct_link_curvemapping(fd, m->curve);
 +              }
 +              break;
 +      }
 +}
 +
 +static void direct_link_linestyle_geometry_modifier(FileData *fd, LineStyleModifier *modifier)
 +{
 +}
 +
 +static void direct_link_linestyle(FileData *fd, FreestyleLineStyle *linestyle)
 +{
 +      LineStyleModifier *modifier;
 +
 +      linestyle->adt= newdataadr(fd, linestyle->adt);
 +      direct_link_animdata(fd, linestyle->adt);
 +      link_list(fd, &linestyle->color_modifiers);
 +      for(modifier=linestyle->color_modifiers.first; modifier; modifier= modifier->next)
 +              direct_link_linestyle_color_modifier(fd, modifier);
 +      link_list(fd, &linestyle->alpha_modifiers);
 +      for(modifier=linestyle->alpha_modifiers.first; modifier; modifier= modifier->next)
 +              direct_link_linestyle_alpha_modifier(fd, modifier);
 +      link_list(fd, &linestyle->thickness_modifiers);
 +      for(modifier=linestyle->thickness_modifiers.first; modifier; modifier= modifier->next)
 +              direct_link_linestyle_thickness_modifier(fd, modifier);
 +      link_list(fd, &linestyle->geometry_modifiers);
 +      for(modifier=linestyle->geometry_modifiers.first; modifier; modifier= modifier->next)
 +              direct_link_linestyle_geometry_modifier(fd, modifier);
 +}
 +
  /* ************** GENERAL & MAIN ******************** */
  
  
@@@ -6594,7 -6419,6 +6604,7 @@@ static const char *dataname(short id_co
                case ID_PA: return "Data from PA";
                case ID_GD: return "Data from GD";
                case ID_MC: return "Data from MC";
 +              case ID_LS: return "Data from LS";
        }
        return "Data from Lib Block";
        
@@@ -6771,9 -6595,6 +6781,9 @@@ static BHead *read_libblock(FileData *f
                case ID_MSK:
                        direct_link_mask(fd, (Mask *)id);
                        break;
 +              case ID_LS:
 +                      direct_link_linestyle(fd, (FreestyleLineStyle *)id);
 +                      break;
        }
        
        oldnewmap_free_unused(fd->datamap);
@@@ -7326,7 -7147,30 +7336,30 @@@ static void do_version_node_fix_interna
                }
        }
  }
 -      
 +
+ static void do_version_logic_264(ListBase *regionbase)
+ {
+       ARegion *ar;
+       
+       /* view settings for logic changed */
+       for (ar = regionbase->first; ar; ar = ar->next) {
+               if (ar->regiontype == RGN_TYPE_WINDOW) {
+                       if (ar->v2d.keeptot == 0) {
+                               ar->v2d.maxzoom = 1.5f;
+                               
+                               ar->v2d.keepzoom = V2D_KEEPZOOM | V2D_LIMITZOOM | V2D_KEEPASPECT;
+                               ar->v2d.keeptot = V2D_KEEPTOT_BOUNDS;
+                               ar->v2d.align = V2D_ALIGN_NO_POS_Y | V2D_ALIGN_NO_NEG_X;
+                               ar->v2d.keepofs = V2D_KEEPOFS_Y;
+                       }
+               }
+       }
+       
+ }
+       
  static void do_versions(FileData *fd, Library *lib, Main *main)
  {
        /* WATCH IT!!!: pointers from libdata have not been converted */
                                        if ( (ob->dsize[i] == 0.0f) || /* simple case, user never touched dsize */
                                             (ob->size[i]  == 0.0f))   /* cant scale the dsize to give a non zero result, so fallback to 1.0f */
                                        {
 -                                              ob->dscale[i] = 1.0f;
 +                                              ob->dscale[i]= 1.0f;
                                        }
                                        else {
 -                                              ob->dscale[i] = (ob->size[i] + ob->dsize[i]) / ob->size[i];
 +                                              ob->dscale[i]= (ob->size[i] + ob->dsize[i]) / ob->size[i];
                                        }
                                }
                        }
                {
                        Mesh *me;
                        for (me = main->mesh.first; me; me = me->id.next) {
+                               CustomData_update_typemap(&me->vdata);
                                CustomData_free_layers(&me->vdata, CD_MSTICKY, me->totvert);
                        }
                }
                        do_version_node_fix_internal_links_264(NULL, NULL, ntree);
                
        }
 -      
 +
+       if (main->versionfile < 264 || (main->versionfile == 264 && main->subversionfile < 6)) {
+               bScreen *sc;
+               
+               for (sc = main->screen.first; sc; sc = sc->id.next) {
+                       ScrArea *sa;
+                       for (sa = sc->areabase.first; sa; sa = sa->next) {
+                               SpaceLink *sl;
+                               if ( sa->spacetype == SPACE_LOGIC)
+                                       do_version_logic_264(&sa->regionbase);
+                               
+                               for (sl = sa->spacedata.first; sl; sl = sl->next) {
+                                       if (sl->spacetype == SPACE_LOGIC)
+                                               do_version_logic_264(&sl->regionbase);
+                               }
+                       }
+               }
+       }
+       
+       {
+               Object *ob;
+               for (ob = main->object.first; ob; ob = ob->id.next) {
+                       if (ob->col_group == 0) {
+                               ob->col_group = 0x01;
+                               ob->col_mask = 0xff;
+                       }
+               }
+       }
 +      /* default values in Freestyle settings */
 +      {
 +              Scene *sce;
 +              SceneRenderLayer *srl;
 +              FreestyleLineStyle *linestyle;
 +
 +              for(sce = main->scene.first; sce; sce = sce->id.next) {
 +                      if (sce->r.line_thickness_mode == 0) {
 +                              sce->r.line_thickness_mode= R_LINE_THICKNESS_ABSOLUTE;
 +                              sce->r.unit_line_thickness= 1.f;
 +                      }
 +                      for(srl= sce->r.layers.first; srl; srl= srl->next) {
 +                              if (srl->freestyleConfig.mode == 0)
 +                                      srl->freestyleConfig.mode= FREESTYLE_CONTROL_EDITOR_MODE;
 +                              if (srl->freestyleConfig.raycasting_algorithm == FREESTYLE_ALGO_CULLED_ADAPTIVE_CUMULATIVE ||
 +                                      srl->freestyleConfig.raycasting_algorithm == FREESTYLE_ALGO_CULLED_ADAPTIVE_TRADITIONAL) {
 +                                      srl->freestyleConfig.raycasting_algorithm= 0; /* deprecated */
 +                                      srl->freestyleConfig.flags |= FREESTYLE_CULLING;
 +                              }
 +                      }
 +              }
 +              for(linestyle = main->linestyle.first; linestyle; linestyle = linestyle->id.next) {
 +                      if (linestyle->thickness_position == 0) {
 +                              linestyle->thickness_position= LS_THICKNESS_CENTER;
 +                              linestyle->thickness_ratio= 0.5f;
 +                      }
 +                      if (linestyle->chaining == 0)
 +                              linestyle->chaining= LS_CHAINING_PLAIN;
 +                      if (linestyle->rounds == 0)
 +                              linestyle->rounds= 3;
 +              }
 +      }
 +
        /* WATCH IT!!!: pointers from libdata have not been converted yet here! */
        /* WATCH IT 2!: Userdef struct init has to be in editors/interface/resources.c! */
  
@@@ -8515,7 -8356,6 +8578,7 @@@ static void lib_link_all(FileData *fd, 
        lib_link_particlesettings(fd, main);
        lib_link_movieclip(fd, main);
        lib_link_mask(fd, main);
 +      lib_link_linestyle(fd, main);
  
        lib_link_mesh(fd, main);                /* as last: tpage images with users at zero */
        
@@@ -9126,7 -8966,7 +9189,7 @@@ static void expand_curve(FileData *fd, 
        }
        
        expand_doit(fd, mainvar, cu->vfont);
 -      expand_doit(fd, mainvar, cu->vfontb);
 +      expand_doit(fd, mainvar, cu->vfontb);   
        expand_doit(fd, mainvar, cu->vfonti);
        expand_doit(fd, mainvar, cu->vfontbi);
        expand_doit(fd, mainvar, cu->key);
@@@ -9430,7 -9270,6 +9493,7 @@@ static void expand_scene(FileData *fd, 
  {
        Base *base;
        SceneRenderLayer *srl;
 +      FreestyleLineSet *lineset;
        
        for (base = sce->base.first; base; base = base->next) {
                expand_doit(fd, mainvar, base->object);
        for (srl = sce->r.layers.first; srl; srl = srl->next) {
                expand_doit(fd, mainvar, srl->mat_override);
                expand_doit(fd, mainvar, srl->light_override);
 +
 +              for (lineset = srl->freestyleConfig.linesets.first; lineset; lineset = lineset->next) {
 +                      if (lineset->group)
 +                              expand_doit(fd, mainvar, lineset->group);
 +                      expand_doit(fd, mainvar, lineset->linestyle);
 +              }
        }
        
        if (sce->r.dometext)
@@@ -9550,26 -9383,6 +9613,26 @@@ static void expand_mask(FileData *fd, M
        }
  }
  
 +static void expand_linestyle(FileData *fd, Main *mainvar, FreestyleLineStyle *linestyle)
 +{
 +      LineStyleModifier *m;
 +
 +      if (linestyle->adt)
 +              expand_animdata(fd, mainvar, linestyle->adt);
 +      for (m = linestyle->color_modifiers.first; m; m = m->next) {
 +              if (m->type == LS_MODIFIER_DISTANCE_FROM_OBJECT)
 +                      expand_doit(fd, mainvar, ((LineStyleColorModifier_DistanceFromObject *)m)->target);
 +      }
 +      for (m = linestyle->alpha_modifiers.first; m; m = m->next){
 +              if (m->type == LS_MODIFIER_DISTANCE_FROM_OBJECT)
 +                      expand_doit(fd, mainvar, ((LineStyleAlphaModifier_DistanceFromObject *)m)->target);
 +      }
 +      for (m = linestyle->thickness_modifiers.first; m; m = m->next){
 +              if (m->type == LS_MODIFIER_DISTANCE_FROM_OBJECT)
 +                      expand_doit(fd, mainvar, ((LineStyleThicknessModifier_DistanceFromObject *)m)->target);
 +      }
 +}
 +
  static void expand_main(FileData *fd, Main *mainvar)
  {
        ListBase *lbarray[MAX_LIBARRAY];
                                        case ID_MSK:
                                                expand_mask(fd, mainvar, (Mask *)id);
                                                break;
 +                                      case ID_LS:
 +                                              expand_linestyle(fd, mainvar, (FreestyleLineStyle *)id);
 +                                              break;
                                        }
                                        
                                        do_it = TRUE;
@@@ -9978,7 -9788,7 +10041,7 @@@ static void library_append_end(const bC
        if ((*fd)->flags & FD_FLAGS_SWITCH_ENDIAN) {
                blo_freefiledata(*fd);
                *fd = NULL;
 -      }
 +      }       
  }
  
  void BLO_library_append_end(const bContext *C, struct Main *mainl, BlendHandle** bh, int idcode, short flag)
index ea8b566340d01a7255838342ee46eb2e2ecde0d6,d7c628370086ed790a4d32396f6a2a8505bc1b94..d67f45cde10405c71286373ab21c23ccd2199384
  #include "DNA_key_types.h"
  #include "DNA_lattice_types.h"
  #include "DNA_lamp_types.h"
 +#include "DNA_linestyle_types.h"
  #include "DNA_meta_types.h"
  #include "DNA_mesh_types.h"
  #include "DNA_meshdata_types.h"
@@@ -729,6 -728,16 +729,16 @@@ static void write_nodetree(WriteData *w
                        /* could be handlerized at some point, now only 1 exception still */
                        if (ntree->type==NTREE_SHADER && (node->type==SH_NODE_CURVE_VEC || node->type==SH_NODE_CURVE_RGB))
                                write_curvemapping(wd, node->storage);
+                       else if (ntree->type==NTREE_SHADER && node->type==SH_NODE_SCRIPT) {
+                               NodeShaderScript *nss = (NodeShaderScript *)node->storage;
+                               if (nss->bytecode)
+                                       writedata(wd, DATA, strlen(nss->bytecode)+1, nss->bytecode);
+                               /* Write ID Properties -- and copy this comment EXACTLY for easy finding
+                                * of library blocks that implement this.*/
+                               if (nss->prop)
+                                       IDP_WriteProperty(nss->prop, wd);
+                               writestruct(wd, DATA, node->typeinfo->storagename, 1, node->storage);
+                       }
                        else if (ntree->type==NTREE_COMPOSIT && ELEM4(node->type, CMP_NODE_TIME, CMP_NODE_CURVE_VEC, CMP_NODE_CURVE_RGB, CMP_NODE_HUECORRECT))
                                write_curvemapping(wd, node->storage);
                        else if (ntree->type==NTREE_TEXTURE && (node->type==TEX_NODE_CURVE_RGB || node->type==TEX_NODE_CURVE_TIME) )
@@@ -1732,9 -1741,10 +1742,10 @@@ static void write_customdata(WriteData 
  
                                writestruct(wd, DATA, structname, datasize, layer->data);
                        }
-                       else
+                       else {
                                printf("%s error: layer '%s':%d - can't be written to file\n",
                                       __func__, structname, layer->type);
+                       }
                }
        }
  
@@@ -1766,6 -1776,9 +1777,9 @@@ static void write_meshs(WriteData *wd, 
                                backup_mesh.totface = mesh->totface;
                                mesh->totface = 0;
                                /* -- */
+                               backup_mesh.fdata = mesh->fdata;
+                               memset(&mesh->fdata, 0, sizeof(mesh->fdata));
+                               /* -- */
  #endif /* USE_BMESH_SAVE_WITHOUT_MFACE */
  
                                writestruct(wd, ID_ME, "Mesh", 1, mesh);
                                mesh->mface = backup_mesh.mface;
                                /* -- */
                                mesh->totface = backup_mesh.totface;
+                               /* -- */
+                               mesh->fdata = backup_mesh.fdata;
  #endif /* USE_BMESH_SAVE_WITHOUT_MFACE */
  
                        }
@@@ -2144,8 -2159,6 +2160,8 @@@ static void write_scenes(WriteData *wd
        TimeMarker *marker;
        TransformOrientation *ts;
        SceneRenderLayer *srl;
 +      FreestyleModuleConfig *fmc;
 +      FreestyleLineSet *fls;
        ToolSettings *tos;
        
        sce= scebase->first;
                for (ts = sce->transform_spaces.first; ts; ts = ts->next)
                        writestruct(wd, DATA, "TransformOrientation", 1, ts);
                
 -              for (srl= sce->r.layers.first; srl; srl= srl->next)
 +              for (srl= sce->r.layers.first; srl; srl= srl->next) {
                        writestruct(wd, DATA, "SceneRenderLayer", 1, srl);
 +                      
 +                      for(fmc= srl->freestyleConfig.modules.first; fmc; fmc = fmc->next) {
 +                              writestruct(wd, DATA, "FreestyleModuleConfig", 1, fmc);
 +                      }
 +                      
 +                      for(fls= srl->freestyleConfig.linesets.first; fls; fls = fls->next) {
 +                              writestruct(wd, DATA, "FreestyleLineSet", 1, fls);
 +                      }
 +
 +              }
                
                if (sce->nodetree) {
                        writestruct(wd, DATA, "bNodeTree", 1, sce->nodetree);
@@@ -2865,205 -2868,6 +2881,205 @@@ static void write_masks(WriteData *wd, 
        mywrite(wd, MYWRITE_FLUSH, 0);
  }
  
 +static void write_linestyle_color_modifiers(WriteData *wd, ListBase *modifiers)
 +{
 +      LineStyleModifier *m;
 +      char *struct_name;
 +
 +      for (m = modifiers->first; m; m = m->next) {
 +              switch (m->type) {
 +              case LS_MODIFIER_ALONG_STROKE:
 +                      struct_name = "LineStyleColorModifier_AlongStroke";
 +                      break;
 +              case LS_MODIFIER_DISTANCE_FROM_CAMERA:
 +                      struct_name = "LineStyleColorModifier_DistanceFromCamera";
 +                      break;
 +              case LS_MODIFIER_DISTANCE_FROM_OBJECT:
 +                      struct_name = "LineStyleColorModifier_DistanceFromObject";
 +                      break;
 +              case LS_MODIFIER_MATERIAL:
 +                      struct_name = "LineStyleColorModifier_Material";
 +                      break;
 +              default:
 +                      struct_name = "LineStyleColorModifier"; // this should not happen
 +              }
 +              writestruct(wd, DATA, struct_name, 1, m);
 +      }
 +      for (m = modifiers->first; m; m = m->next) {
 +              switch (m->type) {
 +              case LS_MODIFIER_ALONG_STROKE:
 +                      writestruct(wd, DATA, "ColorBand", 1, ((LineStyleColorModifier_AlongStroke *)m)->color_ramp);
 +                      break;
 +              case LS_MODIFIER_DISTANCE_FROM_CAMERA:
 +                      writestruct(wd, DATA, "ColorBand", 1, ((LineStyleColorModifier_DistanceFromCamera *)m)->color_ramp);
 +                      break;
 +              case LS_MODIFIER_DISTANCE_FROM_OBJECT:
 +                      writestruct(wd, DATA, "ColorBand", 1, ((LineStyleColorModifier_DistanceFromObject *)m)->color_ramp);
 +                      break;
 +              case LS_MODIFIER_MATERIAL:
 +                      writestruct(wd, DATA, "ColorBand", 1, ((LineStyleColorModifier_Material *)m)->color_ramp);
 +                      break;
 +              }
 +      }
 +}
 +
 +static void write_linestyle_alpha_modifiers(WriteData *wd, ListBase *modifiers)
 +{
 +      LineStyleModifier *m;
 +      char *struct_name;
 +
 +      for (m = modifiers->first; m; m = m->next) {
 +              switch (m->type) {
 +              case LS_MODIFIER_ALONG_STROKE:
 +                      struct_name = "LineStyleAlphaModifier_AlongStroke";
 +                      break;
 +              case LS_MODIFIER_DISTANCE_FROM_CAMERA:
 +                      struct_name = "LineStyleAlphaModifier_DistanceFromCamera";
 +                      break;
 +              case LS_MODIFIER_DISTANCE_FROM_OBJECT:
 +                      struct_name = "LineStyleAlphaModifier_DistanceFromObject";
 +                      break;
 +              case LS_MODIFIER_MATERIAL:
 +                      struct_name = "LineStyleAlphaModifier_Material";
 +                      break;
 +              default:
 +                      struct_name = "LineStyleAlphaModifier"; // this should not happen
 +              }
 +              writestruct(wd, DATA, struct_name, 1, m);
 +      }
 +      for (m = modifiers->first; m; m = m->next) {
 +              switch (m->type) {
 +              case LS_MODIFIER_ALONG_STROKE:
 +                      write_curvemapping(wd, ((LineStyleAlphaModifier_AlongStroke *)m)->curve);
 +                      break;
 +              case LS_MODIFIER_DISTANCE_FROM_CAMERA:
 +                      write_curvemapping(wd, ((LineStyleAlphaModifier_DistanceFromCamera *)m)->curve);
 +                      break;
 +              case LS_MODIFIER_DISTANCE_FROM_OBJECT:
 +                      write_curvemapping(wd, ((LineStyleAlphaModifier_DistanceFromObject *)m)->curve);
 +                      break;
 +              case LS_MODIFIER_MATERIAL:
 +                      write_curvemapping(wd, ((LineStyleAlphaModifier_Material *)m)->curve);
 +                      break;
 +              }
 +      }
 +}
 +
 +static void write_linestyle_thickness_modifiers(WriteData *wd, ListBase *modifiers)
 +{
 +      LineStyleModifier *m;
 +      char *struct_name;
 +
 +      for (m = modifiers->first; m; m = m->next) {
 +              switch (m->type) {
 +              case LS_MODIFIER_ALONG_STROKE:
 +                      struct_name = "LineStyleThicknessModifier_AlongStroke";
 +                      break;
 +              case LS_MODIFIER_DISTANCE_FROM_CAMERA:
 +                      struct_name = "LineStyleThicknessModifier_DistanceFromCamera";
 +                      break;
 +              case LS_MODIFIER_DISTANCE_FROM_OBJECT:
 +                      struct_name = "LineStyleThicknessModifier_DistanceFromObject";
 +                      break;
 +              case LS_MODIFIER_MATERIAL:
 +                      struct_name = "LineStyleThicknessModifier_Material";
 +                      break;
 +              case LS_MODIFIER_CALLIGRAPHY:
 +                      struct_name = "LineStyleThicknessModifier_Calligraphy";
 +                      break;
 +              default:
 +                      struct_name = "LineStyleThicknessModifier"; // this should not happen
 +              }
 +              writestruct(wd, DATA, struct_name, 1, m);
 +      }
 +      for (m = modifiers->first; m; m = m->next) {
 +              switch (m->type) {
 +              case LS_MODIFIER_ALONG_STROKE:
 +                      write_curvemapping(wd, ((LineStyleThicknessModifier_AlongStroke *)m)->curve);
 +                      break;
 +              case LS_MODIFIER_DISTANCE_FROM_CAMERA:
 +                      write_curvemapping(wd, ((LineStyleThicknessModifier_DistanceFromCamera *)m)->curve);
 +                      break;
 +              case LS_MODIFIER_DISTANCE_FROM_OBJECT:
 +                      write_curvemapping(wd, ((LineStyleThicknessModifier_DistanceFromObject *)m)->curve);
 +                      break;
 +              case LS_MODIFIER_MATERIAL:
 +                      write_curvemapping(wd, ((LineStyleThicknessModifier_Material *)m)->curve);
 +                      break;
 +              }
 +      }
 +}
 +
 +static void write_linestyle_geometry_modifiers(WriteData *wd, ListBase *modifiers)
 +{
 +      LineStyleModifier *m;
 +      char *struct_name;
 +
 +      for (m = modifiers->first; m; m = m->next) {
 +              switch (m->type) {
 +              case LS_MODIFIER_SAMPLING:
 +                      struct_name = "LineStyleGeometryModifier_Sampling";
 +                      break;
 +              case LS_MODIFIER_BEZIER_CURVE:
 +                      struct_name = "LineStyleGeometryModifier_BezierCurve";
 +                      break;
 +              case LS_MODIFIER_SINUS_DISPLACEMENT:
 +                      struct_name = "LineStyleGeometryModifier_SinusDisplacement";
 +                      break;
 +              case LS_MODIFIER_SPATIAL_NOISE:
 +                      struct_name = "LineStyleGeometryModifier_SpatialNoise";
 +                      break;
 +              case LS_MODIFIER_PERLIN_NOISE_1D:
 +                      struct_name = "LineStyleGeometryModifier_PerlinNoise1D";
 +                      break;
 +              case LS_MODIFIER_PERLIN_NOISE_2D:
 +                      struct_name = "LineStyleGeometryModifier_PerlinNoise2D";
 +                      break;
 +              case LS_MODIFIER_BACKBONE_STRETCHER:
 +                      struct_name = "LineStyleGeometryModifier_BackboneStretcher";
 +                      break;
 +              case LS_MODIFIER_TIP_REMOVER:
 +                      struct_name = "LineStyleGeometryModifier_TipRemover";
 +                      break;
 +              case LS_MODIFIER_POLYGONIZATION:
 +                      struct_name = "LineStyleGeometryModifier_Polygonalization";
 +                      break;
 +              case LS_MODIFIER_GUIDING_LINES:
 +                      struct_name = "LineStyleGeometryModifier_GuidingLines";
 +                      break;
 +              case LS_MODIFIER_BLUEPRINT:
 +                      struct_name = "LineStyleGeometryModifier_Blueprint";
 +                      break;
 +              case LS_MODIFIER_2D_OFFSET:
 +                      struct_name = "LineStyleGeometryModifier_2DOffset";
 +                      break;
 +              case LS_MODIFIER_2D_TRANSFORM:
 +                      struct_name = "LineStyleGeometryModifier_2DTransform";
 +                      break;
 +              default:
 +                      struct_name = "LineStyleGeometryModifier"; // this should not happen
 +              }
 +              writestruct(wd, DATA, struct_name, 1, m);
 +      }
 +}
 +
 +static void write_linestyles(WriteData *wd, ListBase *idbase)
 +{
 +      FreestyleLineStyle *linestyle;
 +
 +      for(linestyle=idbase->first; linestyle; linestyle= linestyle->id.next) {
 +              if(linestyle->id.us>0 || wd->current) {
 +                      writestruct(wd, ID_LS, "FreestyleLineStyle", 1, linestyle);
 +                      if (linestyle->id.properties) IDP_WriteProperty(linestyle->id.properties, wd);
 +                      if (linestyle->adt) write_animdata(wd, linestyle->adt);
 +                      write_linestyle_color_modifiers(wd, &linestyle->color_modifiers);
 +                      write_linestyle_alpha_modifiers(wd, &linestyle->alpha_modifiers);
 +                      write_linestyle_thickness_modifiers(wd, &linestyle->thickness_modifiers);
 +                      write_linestyle_geometry_modifiers(wd, &linestyle->geometry_modifiers);
 +              }
 +      }
 +}
 +
  /* context is usually defined by WM, two cases where no WM is available:
   * - for forward compatibility, curscreen has to be saved
   * - for undofile, curscene needs to be saved */
@@@ -3174,7 -2978,6 +3190,7 @@@ static int write_file_handle(Main *main
        write_brushes  (wd, &mainvar->brush);
        write_scripts  (wd, &mainvar->script);
        write_gpencils (wd, &mainvar->gpencil);
 +      write_linestyles(wd, &mainvar->linestyle);
        write_libraries(wd,  mainvar->next);
  
        if (write_user_block) {
index 05113576ca45e78ae308104edbbf38c11b7b1ad1,14da93302b9c9526b11ef70c3d79f3dbd6765c8f..79b8c450fd9028b6997b506cccd0584d668149cd
@@@ -46,15 -46,21 +46,22 @@@ enum 
        SUBDIV_SELECT_LOOPCUT
  };
  
+ enum {
+       SIM_CMP_EQ = 0,
+       SIM_CMP_GT,
+       SIM_CMP_LT
+ };
  /* similar face selection slot values */
  enum {
        SIMFACE_MATERIAL = 201,
        SIMFACE_IMAGE,
        SIMFACE_AREA,
+       SIMFACE_SIDES,
        SIMFACE_PERIMETER,
        SIMFACE_NORMAL,
 -      SIMFACE_COPLANAR
 +      SIMFACE_COPLANAR,
 +      SIMFACE_FREESTYLE
  };
  
  /* similar edge selection slot values */
@@@ -66,8 -72,7 +73,8 @@@ enum 
        SIMEDGE_CREASE,
        SIMEDGE_BEVEL,
        SIMEDGE_SEAM,
 -      SIMEDGE_SHARP
 +      SIMEDGE_SHARP,
 +      SIMEDGE_FREESTYLE
  };
  
  /* similar vertex selection slot values */
index 0000000000000000000000000000000000000000,df03e50d2c4a126d7293a8bf6f5e4af4aad1b992..b4566f6c8a96f2b62c8d1b6a42457c9e1bd77cea
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,614 +1,620 @@@
+ /*
+  * ***** BEGIN GPL LICENSE BLOCK *****
+  *
+  * This program is free software; you can redistribute it and/or
+  * modify it under the terms of the GNU General Public License
+  * as published by the Free Software Foundation; either version 2
+  * of the License, or (at your option) any later version.
+  *
+  * This program is distributed in the hope that it will be useful,
+  * but WITHOUT ANY WARRANTY; without even the implied warranty of
+  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  * GNU General Public License for more details.
+  *
+  * You should have received a copy of the GNU General Public License
+  * along with this program; if not, write to the Free Software Foundation,
+  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+  *
+  * Contributor(s): Joseph Eagar, Campbell Barton
+  *
+  * ***** END GPL LICENSE BLOCK *****
+  */
+ /** \file blender/bmesh/operators/bmo_similar.c
+  *  \ingroup bmesh
+  *
+  * bmesh operators to select based on
+  * comparisons with the existing selection.
+  */
+ #include "MEM_guardedalloc.h"
+ #include "DNA_object_types.h"
+ #include "DNA_meshdata_types.h"
+ #include "BLI_math.h"
+ #include "BKE_customdata.h"
+ #include "BKE_deform.h"
+ #include "bmesh.h"
+ #include "intern/bmesh_operators_private.h"  /* own include */
+ /* in fact these could all be the same */
+ /*
+  * extra face data (computed data)
+  */
+ typedef struct SimSel_FaceExt {
+       BMFace  *f;             /* the face */
+       float    c[3];          /* center */
+       union {
+               float   area;       /* area */
+               float   perim;      /* perimeter */
+               float   d;          /* 4th component of plane (the first three being the normal) */
+               struct Image *t;    /* image pointer */
+       };
+ } SimSel_FaceExt;
+ static int bm_sel_similar_cmp_fl(const float delta, const float thresh, const int compare)
+ {
+       switch (compare) {
+               case SIM_CMP_EQ:
+                       return (fabsf(delta) <= thresh);
+               case SIM_CMP_GT:
+                       return ((delta + thresh) >= 0.0f);
+               case SIM_CMP_LT:
+                       return ((delta - thresh) <= 0.0f);
+               default:
+                       BLI_assert(0);
+                       return 0;
+       }
+ }
+ static int bm_sel_similar_cmp_i(const int delta, const int compare)
+ {
+       switch (compare) {
+               case SIM_CMP_EQ:
+                       return (delta == 0);
+               case SIM_CMP_GT:
+                       return (delta > 0);
+               case SIM_CMP_LT:
+                       return (delta < 0);
+               default:
+                       BLI_assert(0);
+                       return 0;
+       }
+ }
+ /*
+  * Select similar faces, the choices are in the enum in source/blender/bmesh/bmesh_operators.h
+  * We select either similar faces based on material, image, area, perimeter, normal, or the coplanar faces
+  */
+ void bmo_similar_faces_exec(BMesh *bm, BMOperator *op)
+ {
+ #define FACE_MARK     1
+       BMIter fm_iter;
+       BMFace *fs, *fm;
+       BMOIter fs_iter;
+       int num_sels = 0, num_total = 0, i = 0, idx = 0;
+       float angle = 0.0f;
+       SimSel_FaceExt *f_ext = NULL;
+       int *indices = NULL;
+       float t_no[3];  /* temporary normal */
+       const int type = BMO_slot_int_get(op, "type");
+       const float thresh = BMO_slot_float_get(op, "thresh");
+       const float thresh_radians = thresh * (float)M_PI;
+       const int compare = BMO_slot_int_get(op, "compare");
+       /* initial_elem - other_elem */
+       float delta_fl;
+       int   delta_i;
+       num_total = BM_mesh_elem_count(bm, BM_FACE);
+       /*
+        * The first thing to do is to iterate through all the the selected items and mark them since
+        * they will be in the selection anyway.
+        * This will increase performance, (especially when the number of originally selected faces is high)
+        * so the overall complexity will be less than $O(mn)$ where is the total number of selected faces,
+        * and n is the total number of faces
+        */
+       BMO_ITER (fs, &fs_iter, bm, op, "faces", BM_FACE) {
+               if (!BMO_elem_flag_test(bm, fs, FACE_MARK)) {   /* is this really needed ? */
+                       BMO_elem_flag_enable(bm, fs, FACE_MARK);
+                       num_sels++;
+               }
+       }
+       /* allocate memory for the selected faces indices and for all temporary faces */
+       indices = (int *)MEM_callocN(sizeof(int) * num_sels, "face indices util.c");
+       f_ext = (SimSel_FaceExt *)MEM_callocN(sizeof(SimSel_FaceExt) * num_total, "f_ext util.c");
+       /* loop through all the faces and fill the faces/indices structure */
+       BM_ITER_MESH (fm, &fm_iter, bm, BM_FACES_OF_MESH) {
+               f_ext[i].f = fm;
+               if (BMO_elem_flag_test(bm, fm, FACE_MARK)) {
+                       indices[idx] = i;
+                       idx++;
+               }
+               i++;
+       }
+       /*
+        * Save us some computation burden: In case of perimeter/area/coplanar selection we compute
+        * only once.
+        */
+       if (type == SIMFACE_PERIMETER || type == SIMFACE_AREA || type == SIMFACE_COPLANAR || type == SIMFACE_IMAGE) {
+               for (i = 0; i < num_total; i++) {
+                       switch (type) {
+                               case SIMFACE_PERIMETER:
+                                       /* set the perimeter */
+                                       f_ext[i].perim = BM_face_calc_perimeter(f_ext[i].f);
+                                       break;
+                               case SIMFACE_COPLANAR:
+                                       /* compute the center of the polygon */
+                                       BM_face_calc_center_mean(f_ext[i].f, f_ext[i].c);
+                                       /* normalize the polygon normal */
+                                       copy_v3_v3(t_no, f_ext[i].f->no);
+                                       normalize_v3(t_no);
+                                       /* compute the plane distance */
+                                       f_ext[i].d = dot_v3v3(t_no, f_ext[i].c);
+                                       break;
+                               case SIMFACE_AREA:
+                                       f_ext[i].area = BM_face_calc_area(f_ext[i].f);
+                                       break;
+                               case SIMFACE_IMAGE:
+                                       f_ext[i].t = NULL;
+                                       if (CustomData_has_layer(&(bm->pdata), CD_MTEXPOLY)) {
+                                               MTexPoly *mtpoly = CustomData_bmesh_get(&bm->pdata, f_ext[i].f->head.data, CD_MTEXPOLY);
+                                               f_ext[i].t = mtpoly->tpage;
+                                       }
+                                       break;
+                       }
+               }
+       }
+       /* now select the rest (if any) */
+       for (i = 0; i < num_total; i++) {
+               fm = f_ext[i].f;
+               if (!BMO_elem_flag_test(bm, fm, FACE_MARK) && !BM_elem_flag_test(fm, BM_ELEM_HIDDEN)) {
+                       int cont = TRUE;
+                       for (idx = 0; idx < num_sels && cont == TRUE; idx++) {
+                               fs = f_ext[indices[idx]].f;
+                               switch (type) {
+                                       case SIMFACE_MATERIAL:
+                                               if (fm->mat_nr == fs->mat_nr) {
+                                                       BMO_elem_flag_enable(bm, fm, FACE_MARK);
+                                                       cont = FALSE;
+                                               }
+                                               break;
+                                       case SIMFACE_IMAGE:
+                                               if (f_ext[i].t == f_ext[indices[idx]].t) {
+                                                       BMO_elem_flag_enable(bm, fm, FACE_MARK);
+                                                       cont = FALSE;
+                                               }
+                                               break;
+                                       case SIMFACE_NORMAL:
+                                               angle = angle_normalized_v3v3(fs->no, fm->no);  /* if the angle between the normals -> 0 */
+                                               if (angle <= thresh_radians) {
+                                                       BMO_elem_flag_enable(bm, fm, FACE_MARK);
+                                                       cont = FALSE;
+                                               }
+                                               break;
+                                       case SIMFACE_COPLANAR:
+                                               angle = angle_normalized_v3v3(fs->no, fm->no); /* angle -> 0 */
+                                               if (angle <= thresh_radians) { /* and dot product difference -> 0 */
+                                                       delta_fl = f_ext[i].d - f_ext[indices[idx]].d;
+                                                       if (bm_sel_similar_cmp_fl(delta_fl, thresh, compare)) {
+                                                               BMO_elem_flag_enable(bm, fm, FACE_MARK);
+                                                               cont = FALSE;
+                                                       }
+                                               }
+                                               break;
+                                       case SIMFACE_AREA:
+                                               delta_fl = f_ext[i].area - f_ext[indices[idx]].area;
+                                               if (bm_sel_similar_cmp_fl(delta_fl, thresh, compare)) {
+                                                       BMO_elem_flag_enable(bm, fm, FACE_MARK);
+                                                       cont = FALSE;
+                                               }
+                                               break;
+                                       case SIMFACE_SIDES:
+                                               delta_i = fm->len - fs->len;
+                                               if (bm_sel_similar_cmp_i(delta_i, compare)) {
+                                                       BMO_elem_flag_enable(bm, fm, FACE_MARK);
+                                                       cont = FALSE;
+                                               }
+                                               break;
+                                       case SIMFACE_PERIMETER:
+                                               delta_fl = f_ext[i].perim - f_ext[indices[idx]].perim;
+                                               if (bm_sel_similar_cmp_fl(delta_fl, thresh, compare)) {
+                                                       BMO_elem_flag_enable(bm, fm, FACE_MARK);
+                                                       cont = FALSE;
+                                               }
+                                               break;
+                                       default:
+                                               BLI_assert(0);
+                               }
+                       }
+               }
+       }
+       MEM_freeN(f_ext);
+       MEM_freeN(indices);
+       /* transfer all marked faces to the output slot */
+       BMO_slot_buffer_from_enabled_flag(bm, op, "faceout", BM_FACE, FACE_MARK);
+ #undef FACE_MARK
+ }
+ /**************************************************************************** *
+  * Similar Edges
+  **************************************************************************** */
+ /*
+  * extra edge information
+  */
+ typedef struct SimSel_EdgeExt {
+       BMEdge *e;
+       union {
+               float dir[3];
+               float angle;            /* angle between the face */
+       };
+       union {
+               float length;           /* edge length */
+               int   faces;            /* faces count */
+       };
+ } SimSel_EdgeExt;
+ /*
+  * select similar edges: the choices are in the enum in source/blender/bmesh/bmesh_operators.h
+  * choices are length, direction, face, ...
+  */
+ void bmo_similar_edges_exec(BMesh *bm, BMOperator *op)
+ {
+ #define EDGE_MARK     1
+       BMOIter es_iter;        /* selected edges iterator */
+       BMIter e_iter;          /* mesh edges iterator */
+       BMEdge *es;             /* selected edge */
+       BMEdge *e;              /* mesh edge */
+       int idx = 0, i = 0 /* , f = 0 */;
+       int *indices = NULL;
+       SimSel_EdgeExt *e_ext = NULL;
+       // float *angles = NULL;
+       float angle;
+       int num_sels = 0, num_total = 0;
+       const int type = BMO_slot_int_get(op, "type");
+       const float thresh = BMO_slot_float_get(op, "thresh");
+       const int compare = BMO_slot_int_get(op, "compare");
+       /* initial_elem - other_elem */
+       float delta_fl;
+       int   delta_i;
+       /* sanity checks that the data we need is available */
+       switch (type) {
+               case SIMEDGE_CREASE:
+                       if (!CustomData_has_layer(&bm->edata, CD_CREASE)) {
+                               return;
+                       }
+                       break;
+               case SIMEDGE_BEVEL:
+                       if (!CustomData_has_layer(&bm->edata, CD_BWEIGHT)) {
+                               return;
+                       }
+                       break;
+       }
+       num_total = BM_mesh_elem_count(bm, BM_EDGE);
+       /* iterate through all selected edges and mark them */
+       BMO_ITER (es, &es_iter, bm, op, "edges", BM_EDGE) {
+               BMO_elem_flag_enable(bm, es, EDGE_MARK);
+               num_sels++;
+       }
+       /* allocate memory for the selected edges indices and for all temporary edges */
+       indices = (int *)MEM_callocN(sizeof(int) * num_sels, __func__);
+       e_ext = (SimSel_EdgeExt *)MEM_callocN(sizeof(SimSel_EdgeExt) * num_total, __func__);
+       /* loop through all the edges and fill the edges/indices structure */
+       BM_ITER_MESH (e, &e_iter, bm, BM_EDGES_OF_MESH) {
+               e_ext[i].e = e;
+               if (BMO_elem_flag_test(bm, e, EDGE_MARK)) {
+                       indices[idx] = i;
+                       idx++;
+               }
+               i++;
+       }
+       /* save us some computation time by doing heavy computation once */
+       if (type == SIMEDGE_LENGTH || type == SIMEDGE_FACE || type == SIMEDGE_DIR || type == SIMEDGE_FACE_ANGLE) {
+               for (i = 0; i < num_total; i++) {
+                       switch (type) {
+                               case SIMEDGE_LENGTH:    /* compute the length of the edge */
+                                       e_ext[i].length = len_v3v3(e_ext[i].e->v1->co, e_ext[i].e->v2->co);
+                                       break;
+                               case SIMEDGE_DIR:               /* compute the direction */
+                                       sub_v3_v3v3(e_ext[i].dir, e_ext[i].e->v1->co, e_ext[i].e->v2->co);
+                                       normalize_v3(e_ext[i].dir);
+                                       break;
+                               case SIMEDGE_FACE:              /* count the faces around the edge */
+                                       e_ext[i].faces = BM_edge_face_count(e_ext[i].e);
+                                       break;
+                               case SIMEDGE_FACE_ANGLE:
+                                       e_ext[i].faces = BM_edge_face_count(e_ext[i].e);
+                                       if (e_ext[i].faces == 2)
+                                               e_ext[i].angle = BM_edge_calc_face_angle(e_ext[i].e);
+                                       break;
+                       }
+               }
+       }
+       /* select the edges if any */
+       for (i = 0; i < num_total; i++) {
+               e = e_ext[i].e;
+               if (!BMO_elem_flag_test(bm, e, EDGE_MARK) && !BM_elem_flag_test(e, BM_ELEM_HIDDEN)) {
+                       int cont = TRUE;
+                       for (idx = 0; idx < num_sels && cont == TRUE; idx++) {
+                               es = e_ext[indices[idx]].e;
+                               switch (type) {
+                                       case SIMEDGE_LENGTH:
+                                               delta_fl = e_ext[i].length - e_ext[indices[idx]].length;
+                                               if (bm_sel_similar_cmp_fl(delta_fl, thresh, compare)) {
+                                                       BMO_elem_flag_enable(bm, e, EDGE_MARK);
+                                                       cont = FALSE;
+                                               }
+                                               break;
+                                       case SIMEDGE_DIR:
+                                               /* compute the angle between the two edges */
+                                               angle = angle_normalized_v3v3(e_ext[i].dir, e_ext[indices[idx]].dir);
+                                               if (angle > (float)(M_PI / 2.0)) /* use the smallest angle between the edges */
+                                                       angle = fabsf(angle - (float)M_PI);
+                                               if (angle / (float)(M_PI / 2.0) <= thresh) {
+                                                       BMO_elem_flag_enable(bm, e, EDGE_MARK);
+                                                       cont = FALSE;
+                                               }
+                                               break;
+                                       case SIMEDGE_FACE:
+                                               delta_i = e_ext[i].faces - e_ext[indices[idx]].faces;
+                                               if (bm_sel_similar_cmp_i(delta_i, compare)) {
+                                                       BMO_elem_flag_enable(bm, e, EDGE_MARK);
+                                                       cont = FALSE;
+                                               }
+                                               break;
+                                       case SIMEDGE_FACE_ANGLE:
+                                               if (e_ext[i].faces == 2) {
+                                                       if (e_ext[indices[idx]].faces == 2) {
+                                                               if (fabsf(e_ext[i].angle - e_ext[indices[idx]].angle) <= thresh) {
+                                                                       BMO_elem_flag_enable(bm, e, EDGE_MARK);
+                                                                       cont = FALSE;
+                                                               }
+                                                       }
+                                               }
+                                               else {
+                                                       cont = FALSE;
+                                               }
+                                               break;
+                                       case SIMEDGE_CREASE:
+                                               {
+                                                       float *c1, *c2;
+                                                       c1 = CustomData_bmesh_get(&bm->edata, e->head.data, CD_CREASE);
+                                                       c2 = CustomData_bmesh_get(&bm->edata, es->head.data, CD_CREASE);
+                                                       delta_fl = *c1 - *c2;
+                                                       if (bm_sel_similar_cmp_fl(delta_fl, thresh, compare)) {
+                                                               BMO_elem_flag_enable(bm, e, EDGE_MARK);
+                                                               cont = FALSE;
+                                                       }
+                                               }
+                                               break;
+                                       case SIMEDGE_BEVEL:
+                                               {
+                                                       float *c1, *c2;
+                                                       c1 = CustomData_bmesh_get(&bm->edata, e->head.data, CD_BWEIGHT);
+                                                       c2 = CustomData_bmesh_get(&bm->edata, es->head.data, CD_BWEIGHT);
+                                                       delta_fl = *c1 - *c2;
+                                                       if (bm_sel_similar_cmp_fl(delta_fl, thresh, compare)) {
+                                                               BMO_elem_flag_enable(bm, e, EDGE_MARK);
+                                                               cont = FALSE;
+                                                       }
+                                               }
+                                               break;
+                                       case SIMEDGE_SEAM:
+                                               if (BM_elem_flag_test(e, BM_ELEM_SEAM) == BM_elem_flag_test(es, BM_ELEM_SEAM)) {
+                                                       BMO_elem_flag_enable(bm, e, EDGE_MARK);
+                                                       cont = FALSE;
+                                               }
+                                               break;
+                                       case SIMEDGE_SHARP:
+                                               if (BM_elem_flag_test(e, BM_ELEM_SMOOTH) == BM_elem_flag_test(es, BM_ELEM_SMOOTH)) {
+                                                       BMO_elem_flag_enable(bm, e, EDGE_MARK);
+                                                       cont = FALSE;
+                                               }
+                                               break;
++                                      case SIMEDGE_FREESTYLE:
++                                              if (BM_elem_flag_test(e, BM_ELEM_FREESTYLE) == BM_elem_flag_test(es, BM_ELEM_FREESTYLE)) {
++                                                      BMO_elem_flag_enable(bm, e, EDGE_MARK);
++                                                      cont = 0;
++                                              }
++                                              break;
+                                       default:
+                                               BLI_assert(0);
+                               }
+                       }
+               }
+       }
+       MEM_freeN(e_ext);
+       MEM_freeN(indices);
+       /* transfer all marked edges to the output slot */
+       BMO_slot_buffer_from_enabled_flag(bm, op, "edgeout", BM_EDGE, EDGE_MARK);
+ #undef EDGE_MARK
+ }
+ /**************************************************************************** *
+  * Similar Vertices
+  **************************************************************************** */
+ typedef struct SimSel_VertExt {
+       BMVert *v;
+       union {
+               int num_faces; /* adjacent faces */
+               int num_edges; /* adjacent edges */
+               MDeformVert *dvert; /* deform vertex */
+       };
+ } SimSel_VertExt;
+ /*
+  * select similar vertices: the choices are in the enum in source/blender/bmesh/bmesh_operators.h
+  * choices are normal, face, vertex group...
+  */
+ void bmo_similar_verts_exec(BMesh *bm, BMOperator *op)
+ {
+ #define VERT_MARK     1
+       BMOIter vs_iter;        /* selected verts iterator */
+       BMIter v_iter;          /* mesh verts iterator */
+       BMVert *vs;             /* selected vertex */
+       BMVert *v;                      /* mesh vertex */
+       SimSel_VertExt *v_ext = NULL;
+       int *indices = NULL;
+       int num_total = 0, num_sels = 0, i = 0, idx = 0;
+       const int type = BMO_slot_int_get(op, "type");
+       const float thresh = BMO_slot_float_get(op, "thresh");
+       const float thresh_radians = thresh * (float)M_PI;
+       const int compare = BMO_slot_int_get(op, "compare");
+       /* initial_elem - other_elem */
+ //    float delta_fl;
+       int   delta_i;
+       num_total = BM_mesh_elem_count(bm, BM_VERT);
+       /* iterate through all selected edges and mark them */
+       BMO_ITER (vs, &vs_iter, bm, op, "verts", BM_VERT) {
+               BMO_elem_flag_enable(bm, vs, VERT_MARK);
+               num_sels++;
+       }
+       /* allocate memory for the selected vertices indices and for all temporary vertices */
+       indices = (int *)MEM_mallocN(sizeof(int) * num_sels, "vertex indices");
+       v_ext = (SimSel_VertExt *)MEM_mallocN(sizeof(SimSel_VertExt) * num_total, "vertex extra");
+       /* loop through all the vertices and fill the vertices/indices structure */
+       BM_ITER_MESH (v, &v_iter, bm, BM_VERTS_OF_MESH) {
+               v_ext[i].v = v;
+               if (BMO_elem_flag_test(bm, v, VERT_MARK)) {
+                       indices[idx] = i;
+                       idx++;
+               }
+               switch (type) {
+                       case SIMVERT_FACE:
+                               /* calling BM_vert_face_count every time is time consumming, so call it only once per vertex */
+                               v_ext[i].num_faces = BM_vert_face_count(v);
+                               break;
+                       case SIMVERT_VGROUP:
+                               if (CustomData_has_layer(&(bm->vdata), CD_MDEFORMVERT)) {
+                                       v_ext[i].dvert = CustomData_bmesh_get(&bm->vdata, v_ext[i].v->head.data, CD_MDEFORMVERT);
+                               }
+                               else {
+                                       v_ext[i].dvert = NULL;
+                               }
+                               break;
+                       case SIMVERT_EDGE:
+                               v_ext[i].num_edges = BM_vert_edge_count(v);
+                               break;
+               }
+               i++;
+       }
+       /* select the vertices if any */
+       for (i = 0; i < num_total; i++) {
+               v = v_ext[i].v;
+               if (!BMO_elem_flag_test(bm, v, VERT_MARK) && !BM_elem_flag_test(v, BM_ELEM_HIDDEN)) {
+                       int cont = TRUE;
+                       for (idx = 0; idx < num_sels && cont == TRUE; idx++) {
+                               vs = v_ext[indices[idx]].v;
+                               switch (type) {
+                                       case SIMVERT_NORMAL:
+                                               /* compare the angle between the normals */
+                                               if (angle_normalized_v3v3(v->no, vs->no) <= thresh_radians) {
+                                                       BMO_elem_flag_enable(bm, v, VERT_MARK);
+                                                       cont = FALSE;
+                                               }
+                                               break;
+                                       case SIMVERT_FACE:
+                                               /* number of adjacent faces */
+                                               delta_i = v_ext[i].num_faces - v_ext[indices[idx]].num_faces;
+                                               if (bm_sel_similar_cmp_i(delta_i, compare)) {
+                                                       BMO_elem_flag_enable(bm, v, VERT_MARK);
+                                                       cont = FALSE;
+                                               }
+                                               break;
+                                       case SIMVERT_VGROUP:
+                                               if (v_ext[i].dvert != NULL && v_ext[indices[idx]].dvert != NULL) {
+                                                       if (defvert_find_shared(v_ext[i].dvert, v_ext[indices[idx]].dvert) != -1) {
+                                                               BMO_elem_flag_enable(bm, v, VERT_MARK);
+                                                               cont = FALSE;
+                                                       }
+                                               }
+                                               break;
+                                       case SIMVERT_EDGE:
+                                               /* number of adjacent edges */
+                                               delta_i = v_ext[i].num_edges - v_ext[indices[idx]].num_edges;
+                                               if (bm_sel_similar_cmp_i(delta_i, compare)) {
+                                                       BMO_elem_flag_enable(bm, v, VERT_MARK);
+                                                       cont = FALSE;
+                                               }
+                                               break;
+                                       default:
+                                               BLI_assert(0);
+                               }
+                       }
+               }
+       }
+       MEM_freeN(indices);
+       MEM_freeN(v_ext);
+       BMO_slot_buffer_from_enabled_flag(bm, op, "vertout", BM_VERT, VERT_MARK);
+ #undef VERT_MARK
+ }
index 81ebca7b2fbaea13fc59d78e18223d2229f90d88,9ceecd60bef85dc528f8840e0641eb49083645f4..c353b64607d4b53908ca0d114813f879e06732d3
@@@ -47,7 -47,6 +47,7 @@@
  #include "DNA_key_types.h"
  #include "DNA_lamp_types.h"
  #include "DNA_lattice_types.h"
 +#include "DNA_linestyle_types.h"
  #include "DNA_mesh_types.h"
  #include "DNA_material_types.h"
  #include "DNA_meta_types.h"
@@@ -753,7 -752,7 +753,7 @@@ static void acf_group_color(bAnimContex
                
                /* highlight only for active */
                if (ale->flag & AGRP_ACTIVE)
-                       copy_v3_v3_char((char *)cp, agrp->cs.active);
+                       copy_v3_v3_char((char *)cp, agrp->cs.select);
                else
                        copy_v3_v3_char((char *)cp, agrp->cs.solid);
                
@@@ -2011,83 -2010,6 +2011,83 @@@ static bAnimChannelType ACF_DSNTREE 
        acf_dsntree_setting_ptr                 /* pointer for setting */
  };
  
 +/* LineStyle Expander  ------------------------------------------- */
 +
 +// TODO: just get this from RNA?
 +static int acf_dslinestyle_icon(bAnimListElem *ale)
 +{
 +      return ICON_BRUSH_DATA; /* FIXME */
 +}
 +
 +/* get the appropriate flag(s) for the setting when it is valid  */
 +static int acf_dslinestyle_setting_flag(bAnimContext *ac, int setting, short *neg)
 +{
 +      /* clear extra return data first */
 +      *neg= 0;
 +      
 +      switch (setting) {
 +              case ACHANNEL_SETTING_EXPAND: /* expanded */
 +                      return LS_DS_EXPAND;
 +                      
 +              case ACHANNEL_SETTING_MUTE: /* mute (only in NLA) */
 +                      return ADT_NLA_EVAL_OFF;
 +                      
 +              case ACHANNEL_SETTING_VISIBLE: /* visible (only in Graph Editor) */
 +                      *neg= 1;
 +                      return ADT_CURVES_NOT_VISIBLE;
 +                      
 +              case ACHANNEL_SETTING_SELECT: /* selected */
 +                      return ADT_UI_SELECTED;
 +                      
 +              default: /* unsupported */
 +                      return 0;
 +      }
 +}
 +
 +/* get pointer to the setting */
 +static void *acf_dslinestyle_setting_ptr(bAnimListElem *ale, int setting, short *type)
 +{
 +      FreestyleLineStyle *linestyle= (FreestyleLineStyle *)ale->data;
 +      
 +      /* clear extra return data first */
 +      *type= 0;
 +      
 +      switch (setting) {
 +              case ACHANNEL_SETTING_EXPAND: /* expanded */
 +                      return GET_ACF_FLAG_PTR(linestyle->flag, type);
 +                      
 +              case ACHANNEL_SETTING_SELECT: /* selected */
 +              case ACHANNEL_SETTING_MUTE: /* muted (for NLA only) */
 +              case ACHANNEL_SETTING_VISIBLE: /* visible (for Graph Editor only) */
 +                      if (linestyle->adt)
 +                              return GET_ACF_FLAG_PTR(linestyle->adt->flag, type);
 +                      else
 +                              return NULL;
 +                      
 +              default: /* unsupported */
 +                      return NULL;
 +      }
 +}
 +
 +/* node tree expander type define */
 +static bAnimChannelType ACF_DSLINESTYLE= 
 +{
 +      "Line Style Expander",                  /* type name */
 +      
 +      acf_generic_dataexpand_color,   /* backdrop color */
 +      acf_generic_dataexpand_backdrop,/* backdrop */
 +      acf_generic_indention_1,                /* indent level */
 +      acf_generic_basic_offset,               /* offset */
 +      
 +      acf_generic_idblock_name,               /* name */
 +      acf_generic_idblock_nameprop,   /* name prop */
 +      acf_dslinestyle_icon,                   /* icon */
 +      
 +      acf_generic_dataexpand_setting_valid,   /* has setting */
 +      acf_dslinestyle_setting_flag,                   /* flag for setting */
 +      acf_dslinestyle_setting_ptr                             /* pointer for setting */
 +};
 +
  /* Mesh Expander  ------------------------------------------- */
  
  // TODO: just get this from RNA?
@@@ -2800,7 -2722,6 +2800,7 @@@ static void ANIM_init_channel_typeinfo_
                animchannelTypeInfo[type++] = &ACF_DSTEX;        /* Texture Channel */
                animchannelTypeInfo[type++] = &ACF_DSLAT;        /* Lattice Channel */
                animchannelTypeInfo[type++] = &ACF_DSSPK;        /* Speaker Channel */
 +              animchannelTypeInfo[type++] = &ACF_DSLINESTYLE;  /* LineStyle Channel */
                
                animchannelTypeInfo[type++] = &ACF_SHAPEKEY;     /* ShapeKey */
                
index 99eee19f66d431d700b4c1e5253f3069b4d61d3e,0379068afd9ba9313122c71c022888517ca9eb3d..3e985a9779cd3fd2a2f1aa6fb76f99872a212e1d
@@@ -671,6 -671,13 +671,13 @@@ static int unified_findnearest(ViewCont
  }
  
  /* ****************  SIMILAR "group" SELECTS. FACE, EDGE AND VERTEX ************** */
+ static EnumPropertyItem prop_similar_compare_types[] = {
+       {SIM_CMP_EQ, "EQUAL", 0, "Equal", ""},
+       {SIM_CMP_GT, "GREATER", 0, "Greater", ""},
+       {SIM_CMP_LT, "LESS", 0, "Less", ""},
+       {0, NULL, 0, NULL, NULL}
+ };
  
  static EnumPropertyItem prop_similar_types[] = {
        {SIMVERT_NORMAL, "NORMAL", 0, "Normal", ""},
        {SIMEDGE_BEVEL, "BEVEL", 0, "Bevel", ""},
        {SIMEDGE_SEAM, "SEAM", 0, "Seam", ""},
        {SIMEDGE_SHARP, "SHARP", 0, "Sharpness", ""},
 +      {SIMEDGE_FREESTYLE, "FREESTYLE_EDGE", 0, "Freestyle Edge Marks", ""},
  
        {SIMFACE_MATERIAL, "MATERIAL", 0, "Material", ""},
        {SIMFACE_IMAGE, "IMAGE", 0, "Image", ""},
        {SIMFACE_AREA, "AREA", 0, "Area", ""},
+       {SIMFACE_SIDES, "SIDES", 0, "Polygon Sides", ""},
        {SIMFACE_PERIMETER, "PERIMETER", 0, "Perimeter", ""},
        {SIMFACE_NORMAL, "NORMAL", 0, "Normal", ""},
        {SIMFACE_COPLANAR, "COPLANAR", 0, "Co-planar", ""},
 +      {SIMFACE_FREESTYLE, "FREESTYLE_FACE", 0, "Freestyle Face Marks", ""},
  
        {0, NULL, 0, NULL, NULL}
  };
@@@ -708,11 -714,14 +716,14 @@@ static int similar_face_select_exec(bCo
        BMOperator bmop;
  
        /* get the type from RNA */
-       int type = RNA_enum_get(op->ptr, "type");
-       float thresh = RNA_float_get(op->ptr, "threshold");
+       const int type = RNA_enum_get(op->ptr, "type");
+       const float thresh = RNA_float_get(op->ptr, "threshold");
+       const int compare = RNA_enum_get(op->ptr, "compare");
  
        /* initialize the bmop using EDBM api, which does various ui error reporting and other stuff */
-       EDBM_op_init(em, &bmop, op, "similar_faces faces=%hf type=%i thresh=%f", BM_ELEM_SELECT, type, thresh);
+       EDBM_op_init(em, &bmop, op,
+                    "similar_faces faces=%hf type=%i thresh=%f compare=%i",
+                    BM_ELEM_SELECT, type, thresh, compare);
  
        /* execute the operator */
        BMO_op_exec(em->bm, &bmop);
@@@ -746,11 -755,14 +757,14 @@@ static int similar_edge_select_exec(bCo
        BMOperator bmop;
  
        /* get the type from RNA */
-       int type = RNA_enum_get(op->ptr, "type");
-       float thresh = RNA_float_get(op->ptr, "threshold");
+       const int type = RNA_enum_get(op->ptr, "type");
+       const float thresh = RNA_float_get(op->ptr, "threshold");
+       const int compare = RNA_enum_get(op->ptr, "compare");
  
        /* initialize the bmop using EDBM api, which does various ui error reporting and other stuff */
-       EDBM_op_init(em, &bmop, op, "similar_edges edges=%he type=%i thresh=%f", BM_ELEM_SELECT, type, thresh);
+       EDBM_op_init(em, &bmop, op,
+                    "similar_edges edges=%he type=%i thresh=%f compare=%i",
+                    BM_ELEM_SELECT, type, thresh, compare);
  
        /* execute the operator */
        BMO_op_exec(em->bm, &bmop);
@@@ -787,11 -799,14 +801,14 @@@ static int similar_vert_select_exec(bCo
        BMEditMesh *em = BMEdit_FromObject(ob);
        BMOperator bmop;
        /* get the type from RNA */
-       int type = RNA_enum_get(op->ptr, "type");
+       const int type = RNA_enum_get(op->ptr, "type");
        float thresh = RNA_float_get(op->ptr, "threshold");
+       const int compare = RNA_enum_get(op->ptr, "compare");
  
        /* initialize the bmop using EDBM api, which does various ui error reporting and other stuff */
-       EDBM_op_init(em, &bmop, op, "similar_verts verts=%hv type=%i thresh=%f", BM_ELEM_SELECT, type, thresh);
+       EDBM_op_init(em, &bmop, op,
+                    "similar_verts verts=%hv type=%i thresh=%f compare=%i",
+                    BM_ELEM_SELECT, type, thresh, compare);
  
        /* execute the operator */
        BMO_op_exec(em->bm, &bmop);
@@@ -820,7 -835,7 +837,7 @@@ static int edbm_select_similar_exec(bCo
        ToolSettings *ts = CTX_data_tool_settings(C);
        PropertyRNA *prop = RNA_struct_find_property(op->ptr, "threshold");
  
-       int type = RNA_enum_get(op->ptr, "type");
+       const int type = RNA_enum_get(op->ptr, "type");
  
        if (!RNA_property_is_set(op->ptr, prop)) {
                RNA_property_float_set(op->ptr, prop, ts->select_thresh);
  
        if      (type < 100) return similar_vert_select_exec(C, op);
        else if (type < 200) return similar_edge_select_exec(C, op);
-       else return similar_face_select_exec(C, op);
+       else                 return similar_face_select_exec(C, op);
  }
  
  static EnumPropertyItem *select_similar_type_itemf(bContext *C, PointerRNA *UNUSED(ptr), PropertyRNA *UNUSED(prop),
                        }
                }
                else if (em->selectmode & SCE_SELECT_FACE) {
 -                      for (a = SIMFACE_MATERIAL; a <= SIMFACE_COPLANAR; a++) {
 +                      for (a = SIMFACE_MATERIAL; a <= SIMFACE_FREESTYLE; a++) {
                                RNA_enum_items_add_value(&item, &totitem, prop_similar_types, a);
                        }
                }
@@@ -895,7 -910,9 +912,9 @@@ void MESH_OT_select_similar(wmOperatorT
        prop = ot->prop = RNA_def_enum(ot->srna, "type", prop_similar_types, SIMVERT_NORMAL, "Type", "");
        RNA_def_enum_funcs(prop, select_similar_type_itemf);
  
-       RNA_def_float(ot->srna, "threshold", 0.0, 0.0, 1.0, "Threshold", "", 0.01, 1.0);
+       RNA_def_enum(ot->srna, "compare", prop_similar_compare_types, SIM_CMP_EQ, "Compare", "");
+       RNA_def_float(ot->srna, "threshold", 0.0, 0.0, 1.0, "Threshold", "", 0.0, 1.0);
  }
  
  /* ***************************************************** */
@@@ -1220,9 -1237,6 +1239,9 @@@ static void edgetag_context_set(BMEditM
                case EDGE_MODE_TAG_SHARP:
                        BM_elem_flag_set(e, BM_ELEM_SMOOTH, !val);
                        break;
 +              case EDGE_MODE_TAG_FREESTYLE:
 +                      BM_elem_flag_set(e, BM_ELEM_FREESTYLE, val);
 +                      break;
                case EDGE_MODE_TAG_CREASE:
                {
                        float *crease = CustomData_bmesh_get(&em->bm->edata, e->head.data, CD_CREASE);
@@@ -1247,8 -1261,6 +1266,8 @@@ static int edgetag_context_check(Scene 
                        return BM_elem_flag_test(e, BM_ELEM_SEAM);
                case EDGE_MODE_TAG_SHARP:
                        return !BM_elem_flag_test(e, BM_ELEM_SMOOTH);
 +              case EDGE_MODE_TAG_FREESTYLE:
 +                      return !BM_elem_flag_test(e, BM_ELEM_FREESTYLE);
                case EDGE_MODE_TAG_CREASE:
                        return BM_elem_float_data_get(&em->bm->edata, e, CD_CREASE) ? 1 : 0;
                case EDGE_MODE_TAG_BEVEL:
@@@ -1450,9 -1462,6 +1469,9 @@@ static int mouse_mesh_shortest_path(bCo
                        case EDGE_MODE_TAG_BEVEL:
                                me->drawflag |= ME_DRAWBWEIGHTS;
                                break;
 +                      case EDGE_MODE_TAG_FREESTYLE:
 +                              me->drawflag |= ME_DRAW_FREESTYLE_EDGE;
 +                              break;
                }
                
                EDBM_update_generic(C, em, FALSE);
@@@ -2299,9 -2308,9 +2318,9 @@@ static int edbm_select_nth_exec(bContex
  void MESH_OT_select_nth(wmOperatorType *ot)
  {
        /* identifiers */
-       ot->name = "Select Nth";
+       ot->name = "Checker Deselect";
        ot->idname = "MESH_OT_select_nth";
-       ot->description = "Select every Nth element starting from a selected vertex, edge or face";
+       ot->description = "Deselect every Nth element starting from a selected vertex, edge or face";
  
        /* api callbacks */
        ot->exec = edbm_select_nth_exec;
index 9d3cc7b7c76974f802bb90a5e62f180c0762121f,f10faddc169e10153314809edf700d742a260b44..df22cbcb294b2ae257d61bd07f75d86c8599f4fd
@@@ -1267,11 -1267,11 +1267,11 @@@ static int edbm_vert_connect(bContext *
        }
        else {
                EDBM_selectmode_flush(em);  /* so newly created edges get the selection state from the vertex */
 +      
 +      EDBM_update_generic(C, em, TRUE);
  
 -              EDBM_update_generic(C, em, TRUE);
 -
 -              return len ? OPERATOR_FINISHED : OPERATOR_CANCELLED;
 -      }
 +      return len ? OPERATOR_FINISHED : OPERATOR_CANCELLED;
 +}
  }
  
  void MESH_OT_vert_connect(wmOperatorType *ot)
@@@ -3808,30 -3808,36 +3808,36 @@@ void MESH_OT_screw(wmOperatorType *ot
                             "Axis", "Axis in global view space", -1.0f, 1.0f);
  }
  
- static int edbm_select_by_number_vertices_exec(bContext *C, wmOperator *op)
+ static int edbm_select_face_by_sides_exec(bContext *C, wmOperator *op)
  {
        Object *obedit = CTX_data_edit_object(C);
        BMEditMesh *em = BMEdit_FromObject(obedit);
        BMFace *efa;
        BMIter iter;
-       int numverts = RNA_int_get(op->ptr, "number");
-       int type = RNA_enum_get(op->ptr, "type");
+       const int numverts = RNA_int_get(op->ptr, "number");
+       const int type = RNA_enum_get(op->ptr, "type");
  
        BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
  
-               int select = 0;
+               int select;
  
-               if (type == 0 && efa->len < numverts) {
-                       select = 1;
-               }
-               else if (type == 1 && efa->len == numverts) {
-                       select = 1;
-               }
-               else if (type == 2 && efa->len > numverts) {
-                       select = 1;
-               }
-               else if (type == 3 && efa->len != numverts) {
-                       select = 1;
+               switch (type) {
+                       case 0:
+                               select = (efa->len < numverts);
+                               break;
+                       case 1:
+                               select = (efa->len == numverts);
+                               break;
+                       case 2:
+                               select = (efa->len > numverts);
+                               break;
+                       case 3:
+                               select = (efa->len != numverts);
+                               break;
+                       default:
+                               BLI_assert(0);
+                               select = FALSE;
+                               break;
                }
  
                if (select) {
        return OPERATOR_FINISHED;
  }
  
- void MESH_OT_select_by_number_vertices(wmOperatorType *ot)
+ void MESH_OT_select_face_by_sides(wmOperatorType *ot)
  {
        static const EnumPropertyItem type_items[] = {
                {0, "LESS", 0, "Less Than", ""},
        };
  
        /* identifiers */
-       ot->name = "Select by Number of Vertices";
-       ot->description = "Select vertices or faces by vertex count";
-       ot->idname = "MESH_OT_select_by_number_vertices";
+       ot->name = "Select Faces by Sides";
+       ot->description = "Select vertices or faces by the number of polygon sides";
+       ot->idname = "MESH_OT_select_face_by_sides";
        
        /* api callbacks */
-       ot->exec = edbm_select_by_number_vertices_exec;
+       ot->exec = edbm_select_face_by_sides_exec;
        ot->poll = ED_operator_editmesh;
        
        /* flags */
@@@ -5617,107 -5623,3 +5623,107 @@@ void MESH_OT_symmetrize(struct wmOperat
                                BMO_SYMMETRIZE_NEGATIVE_X,
                                "Direction", "Which sides to copy from and to");
  }
 +
 +static int edbm_mark_freestyle_edge(bContext *C, wmOperator *op)
 +{
 +      Object *obedit = CTX_data_edit_object(C);
 +      Mesh *me = ((Mesh *)obedit->data);
 +      BMEditMesh *em = ((Mesh *)obedit->data)->edit_btmesh;
 +      BMEdge *eed;
 +      BMIter iter;
 +      int clear = RNA_boolean_get(op->ptr, "clear");
 +
 +      if (em == NULL) return OPERATOR_FINISHED;
 +
 +      /* auto-enable seams drawing */
 +      if (clear == 0) {
 +              me->drawflag |= ME_DRAW_FREESTYLE_EDGE;
 +      }
 +
 +      if (clear) {
 +              BM_ITER_MESH (eed, &iter, em->bm, BM_EDGES_OF_MESH) {
 +                      if (BM_elem_flag_test(eed, BM_ELEM_SELECT) && !BM_elem_flag_test(eed, BM_ELEM_HIDDEN))
 +                              BM_elem_flag_disable(eed, BM_ELEM_FREESTYLE);
 +              }
 +      }
 +      else {
 +              BM_ITER_MESH (eed, &iter, em->bm, BM_EDGES_OF_MESH) {
 +                      if (BM_elem_flag_test(eed, BM_ELEM_SELECT) && !BM_elem_flag_test(eed, BM_ELEM_HIDDEN))
 +                              BM_elem_flag_enable(eed, BM_ELEM_FREESTYLE);
 +              }
 +      }
 +
 +      DAG_id_tag_update(obedit->data, OB_RECALC_DATA);
 +      WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data);
 +
 +      return OPERATOR_FINISHED;
 +}
 +
 +void MESH_OT_mark_freestyle_edge(wmOperatorType *ot)
 +{
 +      /* identifiers */
 +      ot->name = "Mark Freestyle Edge";
 +      ot->description = "(un)mark selected edges as Freestyle feature edges";
 +      ot->idname = "MESH_OT_mark_freestyle_edge";
 +
 +      /* api callbacks */
 +      ot->exec = edbm_mark_freestyle_edge;
 +      ot->poll = ED_operator_editmesh;
 +
 +      /* flags */
 +      ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO;
 +
 +      RNA_def_boolean(ot->srna, "clear", 0, "Clear", "");
 +}
 +
 +static int edbm_mark_freestyle_face_exec(bContext *C, wmOperator *op)
 +{
 +      Object *obedit = CTX_data_edit_object(C);
 +      Mesh *me = ((Mesh *)obedit->data);
 +      BMEditMesh *em = ((Mesh *)obedit->data)->edit_btmesh;
 +      BMFace *efa;
 +      BMIter iter;
 +      int clear = RNA_boolean_get(op->ptr, "clear");
 +
 +      if (em == NULL) return OPERATOR_FINISHED;
 +
 +      /* auto-enable Freestyle face mark drawing */
 +      if(!clear) {
 +              me->drawflag |= ME_DRAW_FREESTYLE_FACE;
 +      }
 +
 +      if(clear) {
 +              BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
 +                      if (BM_elem_flag_test(efa, BM_ELEM_SELECT) && !BM_elem_flag_test(efa, BM_ELEM_HIDDEN))
 +                              BM_elem_flag_disable(efa, BM_ELEM_FREESTYLE);
 +              }
 +      } else {
 +              BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
 +                      if (BM_elem_flag_test(efa, BM_ELEM_SELECT) && !BM_elem_flag_test(efa, BM_ELEM_HIDDEN))
 +                              BM_elem_flag_enable(efa, BM_ELEM_FREESTYLE);
 +              }
 +      }
 +
 +      DAG_id_tag_update(obedit->data, OB_RECALC_DATA);
 +      WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data);
 +
 +      return OPERATOR_FINISHED;
 +}
 +
 +void MESH_OT_mark_freestyle_face(wmOperatorType *ot)
 +{
 +      /* identifiers */
 +      ot->name = "Mark Freestyle Face";
 +      ot->description = "(un)mark selected faces for exclusion from Freestyle feature edge detection";
 +      ot->idname = "MESH_OT_mark_freestyle_face";
 +
 +      /* api callbacks */
 +      ot->exec = edbm_mark_freestyle_face_exec;
 +      ot->poll = ED_operator_editmesh;
 +
 +      /* flags */
 +      ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO;
 +
 +      RNA_def_boolean(ot->srna, "clear", 0, "Clear", "");
 +}
 +
index 65701663df4a589f613197ad124a794e14676a6e,82b785e5785b96434ccb1b0e5197c66ef787869b..881e4bc02e22f3edae5dd1700e2cee7fcb36897c
@@@ -121,7 -121,7 +121,7 @@@ void MESH_OT_select_linked(struct wmOpe
  void MESH_OT_select_linked_pick(struct wmOperatorType *ot);
  void MESH_OT_hide(struct wmOperatorType *ot);
  void MESH_OT_reveal(struct wmOperatorType *ot);
- void MESH_OT_select_by_number_vertices(struct wmOperatorType *ot);
+ void MESH_OT_select_face_by_sides(struct wmOperatorType *ot);
  void MESH_OT_select_loose_verts(struct wmOperatorType *ot);
  void MESH_OT_select_mirror(struct wmOperatorType *ot);
  void MESH_OT_normals_make_consistent(struct wmOperatorType *ot);
@@@ -133,7 -133,6 +133,7 @@@ void MESH_OT_select_random(struct wmOpe
  void MESH_OT_loop_multi_select(struct wmOperatorType *ot);
  void MESH_OT_mark_seam(struct wmOperatorType *ot);
  void MESH_OT_mark_sharp(struct wmOperatorType *ot);
 +void MESH_OT_mark_freestyle_edge(struct wmOperatorType *ot);
  void MESH_OT_vertices_smooth(struct wmOperatorType *ot);
  void MESH_OT_vertices_smooth_laplacian(struct wmOperatorType *ot);
  void MESH_OT_noise(struct wmOperatorType *ot);
@@@ -183,7 -182,6 +183,7 @@@ void MESH_OT_rip(struct wmOperatorType 
  void MESH_OT_shape_propagate_to_all(struct wmOperatorType *ot);
  void MESH_OT_blend_from_shape(struct wmOperatorType *ot);
  void MESH_OT_sort_elements(struct wmOperatorType *ot);
 +void MESH_OT_mark_freestyle_face(struct wmOperatorType *ot);
  
  /* ******************* mesh_data.c */
  
index 64e61d436eeb68d850e7dbd0e332a62d770014f1,d319fdcca262ddc242357ef5c2b718c904ad507b..4036e0c68223efa8aca2c262fe981653b62faa74
@@@ -68,7 -68,7 +68,7 @@@ void ED_operatortypes_mesh(void
        WM_operatortype_append(MESH_OT_select_random);
        WM_operatortype_append(MESH_OT_hide);
        WM_operatortype_append(MESH_OT_reveal);
-       WM_operatortype_append(MESH_OT_select_by_number_vertices);
+       WM_operatortype_append(MESH_OT_select_face_by_sides);
        WM_operatortype_append(MESH_OT_select_loose_verts);
        WM_operatortype_append(MESH_OT_select_mirror);
        WM_operatortype_append(MESH_OT_normals_make_consistent);
        WM_operatortype_append(MESH_OT_faces_shade_smooth);
        WM_operatortype_append(MESH_OT_faces_shade_flat);
        WM_operatortype_append(MESH_OT_sort_elements);
 +      WM_operatortype_append(MESH_OT_mark_freestyle_face);
  
        WM_operatortype_append(MESH_OT_delete);
        WM_operatortype_append(MESH_OT_edge_collapse);
        WM_operatortype_append(MESH_OT_loop_multi_select);
        WM_operatortype_append(MESH_OT_mark_seam);
        WM_operatortype_append(MESH_OT_mark_sharp);
 +      WM_operatortype_append(MESH_OT_mark_freestyle_edge);
        WM_operatortype_append(MESH_OT_vertices_smooth);
        WM_operatortype_append(MESH_OT_vertices_smooth_laplacian);
        WM_operatortype_append(MESH_OT_noise);
index b505fed7baa49e16b6fac1d10cecd2071780e5d8,d8e6510a2691822cafa54ee9c857d6b77df0bfd7..0b5f636ceddfde85e433af21959e05b909bfd4e1
@@@ -785,6 -785,7 +785,7 @@@ static int file_extension_type(const ch
        }
        else if (BLI_testextensie(relname, ".txt")  ||
                 BLI_testextensie(relname, ".glsl") ||
+                        BLI_testextensie(relname, ".osl")  ||
                 BLI_testextensie(relname, ".data"))
        {
                return TEXTFILE;
@@@ -1160,7 -1161,7 +1161,7 @@@ void filelist_from_main(struct FileLis
        if (filelist->dir[0] == 0) {
                
                /* make directories */
 -              filelist->numfiles = 24;
 +              filelist->numfiles = 25;
                filelist->filelist = (struct direntry *)malloc(filelist->numfiles * sizeof(struct direntry));
                
                for (a = 0; a < filelist->numfiles; a++) {
                filelist->filelist[21].relname = BLI_strdup("Action");
                filelist->filelist[22].relname = BLI_strdup("NodeTree");
                filelist->filelist[23].relname = BLI_strdup("Speaker");
 +              filelist->filelist[24].relname= BLI_strdup("FreestyleLineStyle");
                filelist_sort(filelist, FILE_SORT_ALPHA);
        }
        else {
index 27a660eac2bc16bf95fce96013a43f5604b42ac7,f100f003ff553e6cba1349eaa10faf5e6ea76eb2..d46eb51f2c5ea40b868e1bd2fb3f6fb087aa0f74
@@@ -126,13 -126,14 +126,14 @@@ typedef struct drawDMEdgesSel_userData 
  } drawDMEdgesSel_userData;
  
  typedef struct drawDMFacesSel_userData {
 -      unsigned char *cols[3];
 +      unsigned char *cols[4];
  
        DerivedMesh *dm; /* BMESH BRANCH ONLY */
        BMEditMesh *em;  /* BMESH BRANCH ONLY */
  
        BMFace *efa_act;
-       int *orig_index;
+       int *orig_index_mf_to_mpoly;
+       int *orig_index_mp_to_orig;
  } drawDMFacesSel_userData;
  
  typedef struct drawDMNormal_userData {
@@@ -233,12 -234,13 +234,13 @@@ static int check_alpha_pass(Base *base
  }
  
  /***/
- static unsigned int colortab[24] =
- {0x0,       0xFF88FF, 0xFFBBFF,
-  0x403000,  0xFFFF88, 0xFFFFBB,
-  0x104040,  0x66CCCC, 0x77CCCC,
-  0x104010,  0x55BB55, 0x66FF66,
-  0xFFFFFF};
+ static unsigned int colortab[24] = {
+       0x0,      0xFF88FF, 0xFFBBFF,
+       0x403000, 0xFFFF88, 0xFFFFBB,
+       0x104040, 0x66CCCC, 0x77CCCC,
+       0x104010, 0x55BB55, 0x66FF66,
+       0xFFFFFF
+ };
  
  
  static float cube[8][3] = {
@@@ -2273,21 -2275,6 +2275,21 @@@ static void draw_dm_edges_sharp(BMEditM
        dm->drawMappedEdges(dm, draw_dm_edges_sharp__setDrawOptions, em);
  }
  
 +/* Draw only Freestyle feature edges */
 +static DMDrawOption draw_dm_edges_freestyle__setDrawOptions(void *userData, int index)
 +{
 +      BMEdge *eed = EDBM_edge_at_index(userData, index);
 +
 +      if (!BM_elem_flag_test(eed, BM_ELEM_HIDDEN) && BM_elem_flag_test(eed, BM_ELEM_FREESTYLE))
 +              return DM_DRAW_OPTION_NORMAL;
 +      else
 +              return DM_DRAW_OPTION_SKIP;
 +}
 +
 +static void draw_dm_edges_freestyle(BMEditMesh *em, DerivedMesh *dm)
 +{
 +      dm->drawMappedEdges(dm, draw_dm_edges_freestyle__setDrawOptions, em);
 +}
  
  /* Draw faces with color set based on selection
   * return 2 for the active face so it renders with stipple enabled */
@@@ -2302,11 -2289,11 +2304,11 @@@ static DMDrawOption draw_dm_faces_sel__
        
        if (!BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) {
                if (efa == data->efa_act) {
 -                      glColor4ubv(data->cols[2]);
 +                      glColor4ubv(data->cols[3]);
                        return DM_DRAW_OPTION_STIPPLE;
                }
                else {
 -                      col = data->cols[BM_elem_flag_test(efa, BM_ELEM_SELECT) ? 1 : 0];
 +                      col = data->cols[BM_elem_flag_test(efa, BM_ELEM_SELECT) ? 1 : BM_elem_flag_test(efa, BM_ELEM_FREESTYLE) ? 2 : 0];
                        if (col[3] == 0)
                                return DM_DRAW_OPTION_SKIP;
                        glColor4ubv(col);
@@@ -2325,11 -2312,11 +2327,11 @@@ static int draw_dm_faces_sel__compareDr
  
        unsigned char *col, *next_col;
  
-       if (!data->orig_index)
+       if (!data->orig_index_mf_to_mpoly)
                return 0;
  
-       efa = EDBM_face_at_index(data->em, data->orig_index[index]);
-       next_efa = EDBM_face_at_index(data->em, data->orig_index[next_index]);
+       efa = EDBM_face_at_index(data->em, DM_origindex_mface_mpoly(data->orig_index_mf_to_mpoly, data->orig_index_mp_to_orig, index));
+       next_efa = EDBM_face_at_index(data->em, DM_origindex_mface_mpoly(data->orig_index_mf_to_mpoly, data->orig_index_mp_to_orig, next_index));
  
        if (efa == next_efa)
                return 1;
        if (efa == data->efa_act || next_efa == data->efa_act)
                return 0;
  
 -      col = data->cols[BM_elem_flag_test(efa, BM_ELEM_SELECT) ? 1 : 0];
 -      next_col = data->cols[BM_elem_flag_test(next_efa, BM_ELEM_SELECT) ? 1 : 0];
 +      col = data->cols[BM_elem_flag_test(efa, BM_ELEM_SELECT) ? 1 : BM_elem_flag_test(efa, BM_ELEM_FREESTYLE) ? 2 : 0];
 +      next_col = data->cols[BM_elem_flag_test(next_efa, BM_ELEM_SELECT) ? 1 : BM_elem_flag_test(next_efa, BM_ELEM_FREESTYLE) ? 2 : 0];
  
        if (col[3] == 0 || next_col[3] == 0)
                return 0;
  
  /* also draws the active face */
  static void draw_dm_faces_sel(BMEditMesh *em, DerivedMesh *dm, unsigned char *baseCol,
 -                              unsigned char *selCol, unsigned char *actCol, BMFace *efa_act)
 +                              unsigned char *selCol, unsigned char *markCol, unsigned char *actCol, BMFace *efa_act)
  {
        drawDMFacesSel_userData data;
        data.dm = dm;
        data.cols[0] = baseCol;
        data.em = em;
        data.cols[1] = selCol;
 -      data.cols[2] = actCol;
 +      data.cols[2] = markCol;
 +      data.cols[3] = actCol;
        data.efa_act = efa_act;
-       data.orig_index = DM_get_tessface_data_layer(dm, CD_ORIGINDEX);
+       /* double lookup */
+       data.orig_index_mf_to_mpoly = DM_get_tessface_data_layer(dm, CD_ORIGINDEX);
+       data.orig_index_mp_to_orig  = DM_get_poly_data_layer(dm, CD_ORIGINDEX);
+       if ((data.orig_index_mf_to_mpoly && data.orig_index_mp_to_orig) == FALSE) {
+               data.orig_index_mf_to_mpoly = data.orig_index_mp_to_orig = NULL;
+       }
  
        dm->drawMappedFaces(dm, draw_dm_faces_sel__setDrawOptions, GPU_enable_material, draw_dm_faces_sel__compareDrawOptions, &data, 0);
  }
@@@ -2888,12 -2879,11 +2895,12 @@@ static void draw_em_fancy(Scene *scene
        }
        
        if (me->drawflag & ME_DRAWFACES) {  /* transp faces */
 -              unsigned char col1[4], col2[4], col3[4];
 +              unsigned char col1[4], col2[4], col3[4], col4[4];
  
                UI_GetThemeColor4ubv(TH_FACE, col1);
                UI_GetThemeColor4ubv(TH_FACE_SELECT, col2);
 -              UI_GetThemeColor4ubv(TH_EDITMESH_ACTIVE, col3);
 +              UI_GetThemeColor4ubv(TH_FREESTYLE_FACE_MARK, col3);
 +              UI_GetThemeColor4ubv(TH_EDITMESH_ACTIVE, col4);
  
                glEnable(GL_BLEND);
                glDepthMask(0);  /* disable write in zbuffer, needed for nice transp */
                if (check_object_draw_texture(scene, v3d, dt))
                        col1[3] = 0;
  
 -              draw_dm_faces_sel(em, cageDM, col1, col2, col3, efa_act);
 +              if (!(me->drawflag & ME_DRAW_FREESTYLE_FACE))
 +                      col3[3] = 0;
 +
 +              draw_dm_faces_sel(em, cageDM, col1, col2, col3, col4, efa_act);
  
                glDisable(GL_BLEND);
                glDepthMask(1);  /* restore write in zbuffer */
                /* even if draw faces is off it would be nice to draw the stipple face
                 * Make all other faces zero alpha except for the active
                 * */
 -              unsigned char col1[4], col2[4], col3[4];
 -              col1[3] = col2[3] = 0; /* don't draw */
 -              UI_GetThemeColor4ubv(TH_EDITMESH_ACTIVE, col3);
 +              unsigned char col1[4], col2[4], col3[4], col4[4];
 +              col1[3] = col2[3] = col3[3] = 0; /* don't draw */
 +              UI_GetThemeColor4ubv(TH_EDITMESH_ACTIVE, col4);
  
                glEnable(GL_BLEND);
                glDepthMask(0);  /* disable write in zbuffer, needed for nice transp */
  
 -              draw_dm_faces_sel(em, cageDM, col1, col2, col3, efa_act);
 +              draw_dm_faces_sel(em, cageDM, col1, col2, col3, col4, efa_act);
  
                glDisable(GL_BLEND);
                glDepthMask(1);  /* restore write in zbuffer */
                        glLineWidth(1);
                }
  
 +              if(me->drawflag & ME_DRAW_FREESTYLE_EDGE) {
 +                      UI_ThemeColor(TH_FREESTYLE_EDGE_MARK);
 +                      glLineWidth(2);
 +      
 +                      draw_dm_edges_freestyle(em, cageDM);
 +      
 +                      glColor3ub(0,0,0);
 +                      glLineWidth(1);
 +              }
 +      
                if (me->drawflag & ME_DRAWCREASES && CustomData_has_layer(&em->bm->edata, CD_CREASE)) {
                        draw_dm_creases(em, cageDM);
                }
index 1537b4f61ce7051fb9d9bfe1aa5494ed98b95b77,2cf1cf8ffd7967e342602b29fab7d07ba4858c4a..76296b6d3e0a23341c264d478f839037a4aca3f0
@@@ -832,6 -832,9 +832,6 @@@ int transformEvent(TransInfo *t, wmEven
        t->redraw |= handleMouseInput(t, &t->mouse, event);
  
        if (event->type == MOUSEMOVE) {
 -              if (t->modifiers & MOD_CONSTRAINT_SELECT)
 -                      t->con.mode |= CON_SELECT;
 -
                copy_v2_v2_int(t->mval, event->mval);
  
                // t->redraw |= TREDRAW_SOFT; /* Use this for soft redraw. Might cause flicker in object mode */
@@@ -2017,9 -2020,6 +2017,9 @@@ void transformApply(bContext *C, TransI
        t->context = C;
  
        if ((t->redraw & TREDRAW_HARD) || (t->draw_handle_apply == NULL && (t->redraw & TREDRAW_SOFT))) {
 +              if (t->modifiers & MOD_CONSTRAINT_SELECT)
 +                      t->con.mode |= CON_SELECT;
 +
                selectConstraint(t);
                if (t->transform) {
                        t->transform(t, t->mval);  // calls recalcData()
@@@ -4793,8 -4793,7 +4793,7 @@@ static BMLoop *get_next_loop(BMVert *v
                                cross_v3_v3v3(a, f2, l->f->no);
                                mul_v3_fl(a, -1.0f);
  
-                               add_v3_v3(a, f3);
-                               mul_v3_fl(a, 0.5f);
+                               mid_v3_v3v3(a, a, f3);
                        }
                        
                        copy_v3_v3(vec, a);
index 8c81a63ed4c38cf5ad4dd8b0cec0175a18cfd328,5f667db442545fd5b4a6a159c310cab088145136..c327319c4030396509b7f3892a24beddf0753a0e
@@@ -239,10 -239,6 +239,10 @@@ extern StructRNA RNA_FluidFluidSettings
  extern StructRNA RNA_FluidSettings;
  extern StructRNA RNA_FluidSimulationModifier;
  extern StructRNA RNA_FollowPathConstraint;
 +extern StructRNA RNA_FreestyleLineStyle;
 +extern StructRNA RNA_FreestyleLineSet;
 +extern StructRNA RNA_FreestyleModuleSettings;
 +extern StructRNA RNA_FreestyleSettings;
  extern StructRNA RNA_Function;
  extern StructRNA RNA_GPencilFrame;
  extern StructRNA RNA_GPencilLayer;
@@@ -299,37 -295,6 +299,37 @@@ extern StructRNA RNA_LimitDistanceConst
  extern StructRNA RNA_LimitLocationConstraint;
  extern StructRNA RNA_LimitRotationConstraint;
  extern StructRNA RNA_LimitScaleConstraint;
 +extern StructRNA RNA_LineStyleAlphaModifier;
 +extern StructRNA RNA_LineStyleAlphaModifier_AlongStroke;
 +extern StructRNA RNA_LineStyleAlphaModifier_DistanceFromCamera;
 +extern StructRNA RNA_LineStyleAlphaModifier_DistanceFromObject;
 +extern StructRNA RNA_LineStyleAlphaModifier_Material;
 +extern StructRNA RNA_LineStyleColorModifier;
 +extern StructRNA RNA_LineStyleColorModifier_AlongStroke;
 +extern StructRNA RNA_LineStyleColorModifier_DistanceFromCamera;
 +extern StructRNA RNA_LineStyleColorModifier_DistanceFromObject;
 +extern StructRNA RNA_LineStyleColorModifier_Material;
 +extern StructRNA RNA_LineStyleGeometryModifier;
 +extern StructRNA RNA_LineStyleGeometryModifier_2DOffset;
 +extern StructRNA RNA_LineStyleGeometryModifier_2DTransform;
 +extern StructRNA RNA_LineStyleGeometryModifier_BackboneStretcher;
 +extern StructRNA RNA_LineStyleGeometryModifier_BezierCurve;
 +extern StructRNA RNA_LineStyleGeometryModifier_Blueprint;
 +extern StructRNA RNA_LineStyleGeometryModifier_GuidingLines;
 +extern StructRNA RNA_LineStyleGeometryModifier_PerlinNoise1D;
 +extern StructRNA RNA_LineStyleGeometryModifier_PerlinNoise2D;
 +extern StructRNA RNA_LineStyleGeometryModifier_Polygonalization;
 +extern StructRNA RNA_LineStyleGeometryModifier_Sampling;
 +extern StructRNA RNA_LineStyleGeometryModifier_SinusDisplacement;
 +extern StructRNA RNA_LineStyleGeometryModifier_SpatialNoise;
 +extern StructRNA RNA_LineStyleGeometryModifier_TipRemover;
 +extern StructRNA RNA_LineStyleModifier;
 +extern StructRNA RNA_LineStyleThicknessModifier;
 +extern StructRNA RNA_LineStyleThicknessModifier_AlongStroke;
 +extern StructRNA RNA_LineStyleThicknessModifier_Calligraphy;
 +extern StructRNA RNA_LineStyleThicknessModifier_DistanceFromCamera;
 +extern StructRNA RNA_LineStyleThicknessModifier_DistanceFromObject;
 +extern StructRNA RNA_LineStyleThicknessModifier_Material;
  extern StructRNA RNA_LockedTrackConstraint;
  extern StructRNA RNA_Macro;
  extern StructRNA RNA_MagicTexture;
@@@ -492,6 -457,7 +492,7 @@@ extern StructRNA RNA_ShaderNodeMath
  extern StructRNA RNA_ShaderNodeMixRGB;
  extern StructRNA RNA_ShaderNodeNormal;
  extern StructRNA RNA_ShaderNodeOutput;
+ extern StructRNA RNA_ShaderNodeScript;
  extern StructRNA RNA_ShaderNodeRGB;
  extern StructRNA RNA_ShaderNodeRGBCurve;
  extern StructRNA RNA_ShaderNodeRGBToBW;
@@@ -1067,6 -1033,13 +1068,13 @@@ short RNA_type_to_ID_code(StructRNA *ty
  StructRNA *ID_code_to_RNA_type(short idcode);
  
  
+ #define RNA_POINTER_INVALIDATE(ptr) {                                         \
+       /* this is checked for validity */                                        \
+       (ptr)->type =                                                             \
+       /* should not be needed but prevent bad pointer access, just in case */   \
+       (ptr)->id.data = NULL;                                                    \
+ } (void)0
  /* macro which inserts the function name */
  #if defined __GNUC__ || defined __sun
  #  define RNA_warning(format, args ...) _RNA_warning("%s: " format "\n", __func__, ##args)
index d7a7452be0538abe8eb96acd88ec93d0fc679b49,7c4ce3d18d7fc67a3bdb19810f412d2e8277fb40..317204b36dcf0d05b8f9bcc56f9cf1b6a6d88684
@@@ -1661,6 -1661,7 +1661,7 @@@ static void rna_def_property_funcs_head
                case PROP_STRING:
                {
                        fprintf(f, "\tinline std::string %s(void);", rna_safe_id(prop->identifier));
+                       fprintf(f, "\tinline void %s(const std::string& value);", rna_safe_id(prop->identifier));
                        break;
                }
                case PROP_POINTER:
                case PROP_COLLECTION:
                {
                        CollectionPropertyRNA *cprop = (CollectionPropertyRNA *)dp->prop;
+                       const char *collection_funcs = "DefaultCollectionFunctions";
+                       if (!(dp->prop->flag & (PROP_IDPROPERTY | PROP_BUILTIN)) && cprop->property.srna)
+                               collection_funcs  = (char*)cprop->property.srna;
  
                        if (cprop->item_type)
-                               fprintf(f, "\tCOLLECTION_PROPERTY(%s, %s, %s, %s, %s, %s)", (const char *)cprop->item_type, srna->identifier,
+                               fprintf(f, "\tCOLLECTION_PROPERTY(%s, %s, %s, %s, %s, %s, %s)", collection_funcs, (const char *)cprop->item_type, srna->identifier,
                                        rna_safe_id(prop->identifier), (cprop->length ? "TRUE" : "FALSE"),
                                        (cprop->lookupint ? "TRUE" : "FALSE"), (cprop->lookupstring ? "TRUE" : "FALSE"));
                        else
-                               fprintf(f, "\tCOLLECTION_PROPERTY(%s, %s, %s, %s, %s, %s)", "UnknownType", srna->identifier,
+                               fprintf(f, "\tCOLLECTION_PROPERTY(%s, %s, %s, %s, %s, %s, %s)", collection_funcs, "UnknownType", srna->identifier,
                                        rna_safe_id(prop->identifier), (cprop->length ? "TRUE" : "FALSE"),
                                        (cprop->lookupint ? "TRUE" : "FALSE"), (cprop->lookupstring ? "TRUE" : "FALSE"));
                        break;
@@@ -1730,9 -1735,6 +1735,6 @@@ static void rna_def_struct_function_pro
        if (func->flag & FUNC_USE_CONTEXT)
                WRITE_PARAM("Context C");
  
-       if (func->flag & FUNC_USE_REPORTS)
-               WRITE_PARAM("void *reports");
        for (dp = dfunc->cont.properties.first; dp; dp = dp->next) {
                int type, flag, pout;
                const char *ptrstr;
  
                if (type == PROP_POINTER)
                        ptrstr = "";
+               else if ((type == PROP_POINTER) && (flag & PROP_RNAPTR) && !(flag & PROP_THICK_WRAP))
+                       ptrstr = "*";
                else if (type == PROP_POINTER || dp->prop->arraydimension)
                        ptrstr = "*";
                else if (type == PROP_STRING && (flag & PROP_THICK_WRAP))
@@@ -1905,7 -1909,7 +1909,7 @@@ static void rna_def_struct_function_cal
                WRITE_PARAM("(::bContext *) C.ptr.data");
  
        if (func->flag & FUNC_USE_REPORTS)
-               WRITE_PARAM("(::ReportList *) reports");
+               WRITE_PARAM("NULL");
  
        dp = dfunc->cont.properties.first;
        for (; dp; dp = dp->next) {
                        fprintf(f, "%s_len, ", dp->prop->identifier);
  
                if (dp->prop->type == PROP_POINTER)
-                       fprintf(f, "(::%s *) %s.ptr.data", rna_parameter_type_name(dp->prop), rna_safe_id(dp->prop->identifier));
+                       if ((dp->prop->flag & PROP_RNAPTR) && !(dp->prop->flag & PROP_THICK_WRAP))
+                               fprintf(f, "(::%s *) &%s.ptr", rna_parameter_type_name(dp->prop), rna_safe_id(dp->prop->identifier));
+                       else
+                               fprintf(f, "(::%s *) %s.ptr.data", rna_parameter_type_name(dp->prop), rna_safe_id(dp->prop->identifier));
                else
                        fprintf(f, "%s", rna_safe_id(dp->prop->identifier));
        }
@@@ -1946,23 -1953,23 +1953,23 @@@ static void rna_def_struct_function_imp
                if (dp->prop->type == PROP_POINTER) {
                        pprop = (PointerPropertyRNA *) dp->prop;
  
-                       fprintf(f, "\t\tPointerRNA ptr;\n");
+                       fprintf(f, "\t\tPointerRNA result;\n");
  
                        if ((dp->prop->flag & PROP_RNAPTR) == 0) {
                                StructRNA *ret_srna = rna_find_struct((const char *) pprop->type);
                                fprintf(f, "\t\t::%s *retdata = ", rna_parameter_type_name(dp->prop));
                                rna_def_struct_function_call_impl_cpp(f, srna, dfunc);
                                if (ret_srna->flag & STRUCT_ID)
-                                       fprintf(f, "\t\tRNA_id_pointer_create((::ID *) retdata, &ptr);\n");
+                                       fprintf(f, "\t\tRNA_id_pointer_create((::ID *) retdata, &result);\n");
                                else
-                                       fprintf(f, "\t\tRNA_pointer_create(NULL, &RNA_%s, retdata, &ptr);\n", (const char *) pprop->type);
+                                       fprintf(f, "\t\tRNA_pointer_create((::ID *) ptr.id.data, &RNA_%s, retdata, &result);\n", (const char *) pprop->type);
                        }
                        else {
-                               fprintf(f, "\t\tptr = ");
+                               fprintf(f, "\t\tresult = ");
                                rna_def_struct_function_call_impl_cpp(f, srna, dfunc);
                        }
  
-                       fprintf(f, "\t\treturn %s(ptr);\n", (const char *) pprop->type);
+                       fprintf(f, "\t\treturn %s(result);\n", (const char *) pprop->type);
                }
                else {
                        fprintf(f, "\t\treturn ");
@@@ -2095,6 -2102,8 +2102,8 @@@ static void rna_def_function_funcs(FIL
                /* fixed size arrays and RNA pointers are pre-allocated on the ParameterList stack, pass a pointer to it */
                else if (type == PROP_POINTER || dparm->prop->arraydimension)
                        ptrstr = "*";
+               else if ((type == PROP_POINTER) && (flag & PROP_RNAPTR) && !(flag & PROP_THICK_WRAP))
+                       ptrstr = "*";
                /* PROP_THICK_WRAP strings are pre-allocated on the ParameterList stack,
                 * but type name for string props is already char*, so leave empty */
                else if (type == PROP_STRING && (flag & PROP_THICK_WRAP))
                                ptrstr = "**";
                                valstr = "*";
                        }
+                       else if ((type == PROP_POINTER) && !(flag & PROP_THICK_WRAP)) {
+                               ptrstr = "**";
+                               valstr = "*";
+                       }
                        else if (type == PROP_POINTER || dparm->prop->arraydimension) {
                                ptrstr = "*";
                                valstr = "";
@@@ -3101,7 -3114,6 +3114,7 @@@ static RNAProcessItem PROCESS_ITEMS[] 
        {"rna_key.c", NULL, RNA_def_key},
        {"rna_lamp.c", NULL, RNA_def_lamp},
        {"rna_lattice.c", NULL, RNA_def_lattice},
 +      {"rna_linestyle.c", NULL, RNA_def_linestyle},
        {"rna_main.c", "rna_main_api.c", RNA_def_main},
        {"rna_material.c", "rna_material_api.c", RNA_def_material},
        {"rna_mesh.c", "rna_mesh_api.c", RNA_def_mesh},
@@@ -3349,6 -3361,8 +3362,8 @@@ static const char *cpp_classes = "
  "             int len= sname##_##identifier##_length(&ptr); \\\n"
  "             std::string str; str.resize(len); \\\n"
  "             sname##_##identifier##_get(&ptr, &str[0]); return str; } \\\n"
+ "     inline void sname::identifier(const std::string& value) { \\\n"
+ "             sname##_##identifier##_set(&ptr, value.c_str()); } \\\n"
  "\n"
  "#define POINTER_PROPERTY(type, sname, identifier) \\\n"
  "     inline type sname::identifier(void) { return type(sname##_##identifier##_get(&ptr)); }\n"
  "     inline static int sname##_##identifier##_lookup_int_wrap(PointerRNA *ptr, int key, PointerRNA *r_ptr) \\\n"
  "     { \\\n"
  "             CollectionPropertyIterator iter; \\\n"
- "             int i = 0; \\\n"
+ "             int i = 0, found = 0; \\\n"
  "             sname##_##identifier##_begin(&iter, ptr); \\\n"
  "             while (iter.valid) { \\\n"
  "                     if (i == key) { \\\n"
  "                             *r_ptr = iter.ptr; \\\n"
+ "                             found = 1; \\\n"
  "                             break; \\\n"
  "                     } \\\n"
  "                     sname##_##identifier##_next(&iter); \\\n"
  "                     ++i; \\\n"
  "             } \\\n"
  "             sname##_##identifier##_end(&iter); \\\n"
- "             if (!iter.valid) \\\n"
+ "             if (!found) \\\n"
  "                     memset(r_ptr, 0, sizeof(*r_ptr)); \\\n"
- "             return iter.valid; \\\n"
+ "             return found; \\\n"
  "     } \n"
  "#define COLLECTION_PROPERTY_LOOKUP_INT_TRUE(sname, identifier) \\\n"
  "     inline static int sname##_##identifier##_lookup_int_wrap(PointerRNA *ptr, int key, PointerRNA *r_ptr) \\\n"
  "     inline static int sname##_##identifier##_lookup_string_wrap(PointerRNA *ptr, const char *key, PointerRNA *r_ptr) \\\n"
  "     { return sname##_##identifier##_lookup_string(ptr, key, r_ptr); } \n"
  "\n"
- "#define COLLECTION_PROPERTY(type, sname, identifier, has_length, has_lookup_int, has_lookup_string) \\\n"
+ "#define COLLECTION_PROPERTY(collection_funcs, type, sname, identifier, has_length, has_lookup_int, has_lookup_string) \\\n"
  "     typedef CollectionIterator<type, sname##_##identifier##_begin, \\\n"
  "             sname##_##identifier##_next, sname##_##identifier##_end> identifier##_iterator; \\\n"
  "     COLLECTION_PROPERTY_LENGTH_##has_length(sname, identifier) \\\n"
  "     Collection<sname, type, sname##_##identifier##_begin, \\\n"
  "             sname##_##identifier##_next, sname##_##identifier##_end, \\\n"
  "             sname##_##identifier##_length_wrap, \\\n"
- "             sname##_##identifier##_lookup_int_wrap, sname##_##identifier##_lookup_string_wrap> identifier;\n"
+ "             sname##_##identifier##_lookup_int_wrap, sname##_##identifier##_lookup_string_wrap, collection_funcs> identifier;\n"
  "\n"
  "class Pointer {\n"
  "public:\n"
  "};\n"
  "\n"
  "template<typename Tp, typename T, TBeginFunc Tbegin, TNextFunc Tnext, TEndFunc Tend,\n"
- "         TLengthFunc Tlength, TLookupIntFunc Tlookup_int, TLookupStringFunc Tlookup_string>\n"
- "class Collection {\n"
+ "         TLengthFunc Tlength, TLookupIntFunc Tlookup_int, TLookupStringFunc Tlookup_string,\n"
+ "         typename Tcollection_funcs>\n"
+ "class Collection : public Tcollection_funcs {\n"
  "public:\n"
- "     Collection(const PointerRNA &p) : ptr(p) {}\n"
+ "     Collection(const PointerRNA &p) : Tcollection_funcs(p), ptr(p)  {}\n"
  "\n"
  "     void begin(CollectionIterator<T, Tbegin, Tnext, Tend>& iter)\n"
  "     { iter.begin(ptr); }\n"
  ""
  "     int length()\n"
  "     { return Tlength(&ptr); }\n"
- "     T& operator[](int key)\n"
- "     { PointerRNA r_ptr; Tlookup_int(&ptr, key, &r_ptr); return *(T*)r_ptr.data; }\n"
- "     T& operator[](const std::string &key)\n"
- "     { PointerRNA r_ptr; Tlookup_string(&ptr, key.c_str(), &r_ptr); return *(T*)r_ptr.data; }\n"
+ "     T operator[](int key)\n"
+ "     { PointerRNA r_ptr; Tlookup_int(&ptr, key, &r_ptr); return T(r_ptr); }\n"
+ "     T operator[](const std::string &key)\n"
+ "     { PointerRNA r_ptr; Tlookup_string(&ptr, key.c_str(), &r_ptr); return T(r_ptr); }\n"
  "\n"
  "private:\n"
  "     PointerRNA ptr;\n"
  "};\n"
+ "\n"
+ "class DefaultCollectionFunctions {\n"
+ "public:\n"
+ "     DefaultCollectionFunctions(const PointerRNA &p) {}\n"
+ "};\n"
+ "\n"
  "\n";
  
+ static int rna_is_collection_prop(PropertyRNA *prop)
+ {
+       if (!(prop->flag & (PROP_IDPROPERTY | PROP_BUILTIN)))
+               if (prop->type == PROP_COLLECTION)
+                       return 1;
+       return 0;
+ }
+ static int rna_is_collection_functions_struct(const char **collection_structs, const char *struct_name)
+ {
+       int a = 0, found = 0;
+       while (collection_structs[a]) {
+               if (!strcmp(collection_structs[a], struct_name)) {
+                       found = 1;
+                       break;
+               }
+               a++;
+       }
+       return found;
+ }
+ static void rna_generate_header_class_cpp(StructDefRNA *ds, FILE *f)
+ {
+       StructRNA *srna = ds->srna;
+       PropertyDefRNA *dp;
+       FunctionDefRNA *dfunc;
+       fprintf(f, "/**************** %s ****************/\n\n", srna->name);
+       fprintf(f, "class %s : public %s {\n", srna->identifier, (srna->base) ? srna->base->identifier : "Pointer");
+       fprintf(f, "public:\n");
+       fprintf(f, "\t%s(const PointerRNA &ptr_arg) :\n\t\t%s(ptr_arg)", srna->identifier,
+                       (srna->base) ? srna->base->identifier : "Pointer");
+       for (dp = ds->cont.properties.first; dp; dp = dp->next)
+               if (rna_is_collection_prop(dp->prop))
+                               fprintf(f, ",\n\t\t%s(ptr_arg)", dp->prop->identifier);
+       fprintf(f, "\n\t\t{}\n\n");
+       for (dp = ds->cont.properties.first; dp; dp = dp->next)
+               rna_def_property_funcs_header_cpp(f, ds->srna, dp);
+       fprintf(f, "\n");
+       for (dfunc = ds->functions.first; dfunc; dfunc = dfunc->cont.next)
+               rna_def_struct_function_header_cpp(f, srna, dfunc);
+       fprintf(f, "};\n\n");
+ }
  static void rna_generate_header_cpp(BlenderRNA *UNUSED(brna), FILE *f)
  {
        StructDefRNA *ds;
        PropertyDefRNA *dp;
        StructRNA *srna;
        FunctionDefRNA *dfunc;
+       const char *first_collection_func_struct = NULL;
+       const char *collection_func_structs[256] = {NULL};
+       int all_collection_func_structs = 0;
+       int max_collection_func_structs = sizeof(collection_func_structs) / sizeof(collection_func_structs[0]) - 1;
  
        fprintf(f, "\n#ifndef __RNA_BLENDER_CPP_H__\n");
        fprintf(f, "#define __RNA_BLENDER_CPP_H__\n\n");
  
        fprintf(f, "/**************** Declarations ****************/\n\n");
  
-       for (ds = DefRNA.structs.first; ds; ds = ds->cont.next)
+       for (ds = DefRNA.structs.first; ds; ds = ds->cont.next) {
                fprintf(f, "class %s;\n", ds->srna->identifier);
+       }
        fprintf(f, "\n");
  
+       /* first get list of all structures used as collection functions, so they'll be declared first */
        for (ds = DefRNA.structs.first; ds; ds = ds->cont.next) {
-               srna = ds->srna;
+               for (dp = ds->cont.properties.first; dp; dp = dp->next) {
+                       if (rna_is_collection_prop(dp->prop)) {
+                               PropertyRNA *prop = dp->prop;
+                               if (prop->srna) {
+                                       /* store name of structure which first uses custom functions for collections */
+                                       if (first_collection_func_struct == NULL)
+                                               first_collection_func_struct = ds->srna->identifier;
+                                       if (!rna_is_collection_functions_struct(collection_func_structs, (char*)prop->srna)) {
+                                               if (all_collection_func_structs >= max_collection_func_structs) {
+                                                       printf("Array size to store all collection structures names is too small\n");
+                                                       exit(1);
+                                               }
  
-               fprintf(f, "/**************** %s ****************/\n\n", srna->name);
+                                               collection_func_structs[all_collection_func_structs++] = (char*)prop->srna;
+                                       }
+                               }
+                       }
+               }
+       }
  
-               fprintf(f, "class %s : public %s {\n", srna->identifier, (srna->base) ? srna->base->identifier : "Pointer");
-               fprintf(f, "public:\n");
-               fprintf(f, "\t%s(const PointerRNA &ptr_arg) :\n\t\t%s(ptr_arg)", srna->identifier,
-                       (srna->base) ? srna->base->identifier : "Pointer");
-               for (dp = ds->cont.properties.first; dp; dp = dp->next)
-                       if (!(dp->prop->flag & (PROP_IDPROPERTY | PROP_BUILTIN)))
-                               if (dp->prop->type == PROP_COLLECTION)
-                                       fprintf(f, ",\n\t\t%s(ptr_arg)", dp->prop->identifier);
-               fprintf(f, "\n\t\t{}\n\n");
+       /* declare all structures in such order:
+        * - first N structures which doesn't use custom functions for collections
+        * - all structures used for custom functions in collections
+        * - all the rest structures
+        * such an order prevents usage of non-declared classes
+        */
+       for (ds = DefRNA.structs.first; ds; ds = ds->cont.next) {
+               srna = ds->srna;
  
-               for (dp = ds->cont.properties.first; dp; dp = dp->next)
-                       rna_def_property_funcs_header_cpp(f, ds->srna, dp);
+               if (!strcmp(srna->identifier, first_collection_func_struct)) {
+                       StructDefRNA *ds2;
+                       StructRNA *srna2;
  
-               fprintf(f, "\n");
-               for (dfunc = ds->functions.first; dfunc; dfunc = dfunc->cont.next)
-                       rna_def_struct_function_header_cpp(f, srna, dfunc);
+                       for (ds2 = DefRNA.structs.first; ds2; ds2 = ds2->cont.next) {
+                               srna2 = ds2->srna;
+                               if (rna_is_collection_functions_struct(collection_func_structs, srna2->identifier)) {
+                                       rna_generate_header_class_cpp(ds2, f);
+                               }
+                       }
+               }
  
-               fprintf(f, "};\n\n");
+               if (!rna_is_collection_functions_struct(collection_func_structs, srna->identifier))
+                       rna_generate_header_class_cpp(ds, f);
        }
  
        fprintf(f, "} /* namespace BL */\n");
index 739b02ef0426f69421a08303d18be2a28940f7a8,ba1aca2babab047efd58b3b8fa268fd14f82a2b5..07b8072076eb9fc2dd8ea9cb97819fad5e9d86cb
@@@ -27,6 -27,7 +27,7 @@@
  
  #include <stdlib.h>
  
+ #include "RNA_access.h"
  #include "RNA_define.h"
  #include "RNA_enum_types.h"
  
@@@ -68,12 -69,13 +69,13 @@@ static bActionGroup *rna_Action_groups_
        return action_groups_add_new(act, name);
  }
  
- static void rna_Action_groups_remove(bAction *act, ReportList *reports, bActionGroup *agrp)
+ static void rna_Action_groups_remove(bAction *act, ReportList *reports, PointerRNA *agrp_ptr)
  {
+       bActionGroup *agrp = agrp_ptr->data;
        FCurve *fcu, *fcn;
        
        /* try to remove the F-Curve from the action */
-       if (!BLI_remlink_safe(&act->groups, agrp)) {
+       if (BLI_remlink_safe(&act->groups, agrp) == FALSE) {
                BKE_reportf(reports, RPT_ERROR, "Action group '%s' not found in action '%s'", agrp->name, act->id.name + 2);
                return;
        }
        /* move every one one of the group's F-Curves out into the Action again */
        for (fcu = agrp->channels.first; (fcu) && (fcu->grp == agrp); fcu = fcn) {
                fcn = fcu->next;
-               
                /* remove from group */
                action_groups_remove_channel(act, fcu);
-               
                /* tack onto the end */
                BLI_addtail(&act->curves, fcu);
        }
-       
-       /* XXX, invalidates PyObject */
        MEM_freeN(agrp);
+       RNA_POINTER_INVALIDATE(agrp_ptr);
  }
  
  static FCurve *rna_Action_fcurve_new(bAction *act, ReportList *reports, const char *data_path,
        return verify_fcurve(act, group, NULL, data_path, index, 1);
  }
  
- static void rna_Action_fcurve_remove(bAction *act, ReportList *reports, FCurve *fcu)
+ static void rna_Action_fcurve_remove(bAction *act, ReportList *reports, PointerRNA *fcu_ptr)
  {
+       FCurve *fcu = fcu_ptr->data;
        if (fcu->grp) {
                if (BLI_findindex(&act->groups, fcu->grp) == -1) {
                        BKE_reportf(reports, RPT_ERROR, "F-Curve's action group '%s' not found in action '%s'",
                
                action_groups_remove_channel(act, fcu);
                free_fcurve(fcu);
+               RNA_POINTER_INVALIDATE(fcu_ptr);
        }
        else {
                if (BLI_findindex(&act->curves, fcu) == -1) {
                
                BLI_remlink(&act->curves, fcu);
                free_fcurve(fcu);
+               RNA_POINTER_INVALIDATE(fcu_ptr);
        }
  }
  
@@@ -145,15 -150,16 +150,16 @@@ static TimeMarker *rna_Action_pose_mark
        return marker;
  }
  
- static void rna_Action_pose_markers_remove(bAction *act, ReportList *reports, TimeMarker *marker)
+ static void rna_Action_pose_markers_remove(bAction *act, ReportList *reports, PointerRNA *marker_ptr)
  {
-       if (!BLI_remlink_safe(&act->markers, marker)) {
+       TimeMarker *marker = marker_ptr->data;
+       if (BLI_remlink_safe(&act->markers, marker) == FALSE) {
                BKE_reportf(reports, RPT_ERROR, "Timeline marker '%s' not found in action '%s'", marker->name, act->id.name + 2);
                return;
        }
  
-       /* XXX, invalidates PyObject */
        MEM_freeN(marker);
+       RNA_POINTER_INVALIDATE(marker_ptr);
  }
  
  static PointerRNA rna_Action_active_pose_marker_get(PointerRNA *ptr)
@@@ -386,12 -392,6 +392,12 @@@ static void rna_def_dopesheet(BlenderRN
        RNA_def_property_ui_icon(prop, ICON_LAMP_DATA, 0);
        RNA_def_property_update(prop, NC_ANIMATION | ND_ANIMCHAN | NA_EDITED, NULL);
        
 +      prop = RNA_def_property(srna, "show_linestyles", PROP_BOOLEAN, PROP_NONE);
 +      RNA_def_property_boolean_negative_sdna(prop, NULL, "filterflag", ADS_FILTER_NOLINESTYLE);
 +      RNA_def_property_ui_text(prop, "Display Line Style", "Include visualization of Line Style related Animation data");
 +      RNA_def_property_ui_icon(prop, ICON_BRUSH_DATA, 0); /* FIXME */
 +      RNA_def_property_update(prop, NC_ANIMATION|ND_ANIMCHAN|NA_EDITED, NULL);
 +      
        prop = RNA_def_property(srna, "show_textures", PROP_BOOLEAN, PROP_NONE);
        RNA_def_property_boolean_negative_sdna(prop, NULL, "filterflag", ADS_FILTER_NOTEX);
        RNA_def_property_ui_text(prop, "Display Texture", "Include visualization of texture related animation data");
@@@ -522,7 -522,8 +528,8 @@@ static void rna_def_action_groups(Blend
        RNA_def_function_ui_description(func, "Remove action group");
        RNA_def_function_flag(func, FUNC_USE_REPORTS);
        parm = RNA_def_pointer(func, "action_group", "ActionGroup", "", "Action group to remove");
-       RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL);
+       RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL | PROP_RNAPTR);
+       RNA_def_property_clear_flag(parm, PROP_THICK_WRAP);
  }
  
  static void rna_def_action_fcurves(BlenderRNA *brna, PropertyRNA *cprop)
        RNA_def_function_ui_description(func, "Remove action group");
        RNA_def_function_flag(func, FUNC_USE_REPORTS);
        parm = RNA_def_pointer(func, "fcurve", "FCurve", "", "F-Curve to remove");
-       RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL);
+       RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL | PROP_RNAPTR);
+       RNA_def_property_clear_flag(parm, PROP_THICK_WRAP);
  }
  
  static void rna_def_action_pose_markers(BlenderRNA *brna, PropertyRNA *cprop)
        RNA_def_function_ui_description(func, "Remove a timeline marker");
        RNA_def_function_flag(func, FUNC_USE_REPORTS);
        parm = RNA_def_pointer(func, "marker", "TimelineMarker", "", "Timeline marker to remove");
-       RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL);
+       RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL | PROP_RNAPTR);
+       RNA_def_property_clear_flag(parm, PROP_THICK_WRAP);
        
        prop = RNA_def_property(srna, "active", PROP_POINTER, PROP_NONE);
        RNA_def_property_struct_type(prop, "TimelineMarker");
index f4afaf11d277a69bece7c1efeb7629a83728d80b,c93d2ef15cf3cb423d042e818814d47c0bec42df..f3a3b5c43f85b34a4c1f0533785f1cb430f227d8
@@@ -54,7 -54,6 +54,7 @@@
  #include "BKE_movieclip.h"
  #include "BKE_node.h"
  #include "BKE_texture.h"
 +#include "BKE_linestyle.h"
  
  #include "ED_node.h"
  
@@@ -187,14 -186,6 +187,14 @@@ static char *rna_ColorRamp_path(Pointer
                                /* everything else just uses 'color_ramp' */
                                path = BLI_strdup("color_ramp");
                                break;
 +
 +                      case ID_LS:
 +                      {
 +                              char *path = FRS_path_from_ID_to_color_ramp((FreestyleLineStyle *)id, (ColorBand *)ptr->data);
 +                              if (path)
 +                                      return path;
 +                      }
 +                              break;
                }
        }
        else {
@@@ -266,20 -257,6 +266,20 @@@ static char *rna_ColorRampElement_path(
                        }
                        break;
                                
 +                      case ID_LS:
 +                      {
 +                              ListBase listbase;
 +                              LinkData *link;
 +
 +                              FRS_list_modifier_color_ramps((FreestyleLineStyle *)id, &listbase);
 +                              for (link = (LinkData *)listbase.first; link; link = link->next) {
 +                                      RNA_pointer_create(id, &RNA_ColorRamp, link->data, &ramp_ptr);
 +                                      COLRAMP_GETPATH;
 +                              }
 +                              BLI_freelistN(&listbase);
 +                      }
 +                              break;
 +
                        default: /* everything else should have a "color_ramp" property */
                        {
                                /* create pointer to the ID block, and try to resolve "color_ramp" pointer */
@@@ -331,13 -308,6 +331,13 @@@ static void rna_ColorRamp_update(Main *
                                WM_main_add_notifier(NC_TEXTURE, tex);
                        }
                        break;
 +                      case ID_LS:
 +                      {
 +                              FreestyleLineStyle *linestyle= ptr->id.data;
 +
 +                              WM_main_add_notifier(NC_LINESTYLE, linestyle);
 +                      }
 +                              break;
                        default:
                                break;
                }
@@@ -359,12 -329,27 +359,27 @@@ static CBData *rna_ColorRampElement_new
        return element;
  }
  
- static void rna_ColorRampElement_remove(struct ColorBand *coba, ReportList *reports, CBData *element)
+ static void rna_ColorRampElement_remove(struct ColorBand *coba, ReportList *reports, PointerRNA *element_ptr)
  {
+       CBData *element = element_ptr->data;
        int index = (int)(element - coba->data);
-       if (colorband_element_remove(coba, index) == 0)
+       if (colorband_element_remove(coba, index) == FALSE) {
                BKE_report(reports, RPT_ERROR, "Element not found in element collection or last element");
+               return;
+       }
  
+       RNA_POINTER_INVALIDATE(element_ptr);
+ }
+ void rna_CurveMap_remove_point(CurveMap *cuma, ReportList *reports, PointerRNA *point_ptr)
+ {
+       CurveMapPoint *point = point_ptr->data;
+       if (curvemap_remove_point(cuma, point) == FALSE) {
+               BKE_report(reports, RPT_ERROR, "Unable to remove curve point");
+               return;
+       }
+       RNA_POINTER_INVALIDATE(point_ptr);
  }
  
  static void rna_Scopes_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr)
@@@ -589,10 -574,12 +604,12 @@@ static void rna_def_curvemap_points_api
        parm = RNA_def_pointer(func, "point", "CurveMapPoint", "", "New point");
        RNA_def_function_return(func, parm);
  
-       func = RNA_def_function(srna, "remove", "curvemap_remove_point");
+       func = RNA_def_function(srna, "remove", "rna_CurveMap_remove_point");
+       RNA_def_function_flag(func, FUNC_USE_REPORTS);
        RNA_def_function_ui_description(func, "Delete point from CurveMap");
        parm = RNA_def_pointer(func, "point", "CurveMapPoint", "", "PointElement to remove");
-       RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL);
+       RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL | PROP_RNAPTR);
+       RNA_def_property_clear_flag(parm, PROP_THICK_WRAP);
  }
  
  static void rna_def_curvemap(BlenderRNA *brna)
@@@ -741,7 -728,8 +758,8 @@@ static void rna_def_color_ramp_element_
        RNA_def_function_ui_description(func, "Delete element from ColorRamp");
        RNA_def_function_flag(func, FUNC_USE_REPORTS);
        parm = RNA_def_pointer(func, "element", "ColorRampElement", "", "Element to remove");
-       RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL);
+       RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL | PROP_RNAPTR);
+       RNA_def_property_clear_flag(parm, PROP_THICK_WRAP);
  }
  
  static void rna_def_color_ramp(BlenderRNA *brna)
index 78e0fde5715a958f499df8ed7efd7c02a44add42,04b8d2fa3dfca40f2d6e99e0489f538400ee360e..7783a64bf9ffdef22c20e271a12a164bbc5fae0f
@@@ -51,7 -51,7 +51,7 @@@ static int rna_Main_is_dirty_get(Pointe
        /* XXX, not totally nice to do it this way, should store in main ? */
        Main *bmain = (Main *)ptr->data;
        wmWindowManager *wm;
-       for (wm = bmain->wm.first; wm; wm = wm->id.next) {
+       if ((wm = bmain->wm.first)) {
                return !wm->file_saved;
        }
  
@@@ -258,12 -258,6 +258,12 @@@ static void rna_Main_masks_begin(Collec
        rna_iterator_listbase_begin(iter, &bmain->mask, NULL);
  }
  
 +static void rna_Main_linestyle_begin(CollectionPropertyIterator *iter, PointerRNA *ptr)
 +{
 +      Main *bmain= (Main*)ptr->data;
 +      rna_iterator_listbase_begin(iter, &bmain->linestyle, NULL);
 +}
 +
  #ifdef UNIT_TEST
  
  static PointerRNA rna_Test_test_get(PointerRNA *ptr)
@@@ -328,7 -322,6 +328,7 @@@ void RNA_def_main(BlenderRNA *brna
                {"grease_pencil", "GreasePencil", "rna_Main_gpencil_begin", "Grease Pencil", "Grease Pencil datablocks", RNA_def_main_gpencil},
                {"movieclips", "MovieClip", "rna_Main_movieclips_begin", "Movie Clips", "Movie Clip datablocks", RNA_def_main_movieclips},
                {"masks", "Mask", "rna_Main_masks_begin", "Masks", "Masks datablocks", RNA_def_main_masks},
 +              {"linestyles", "FreestyleLineStyle", "rna_Main_linestyle_begin", "Line Styles", "Line Style datablocks", RNA_def_main_linestyles},
                {NULL, NULL, NULL, NULL, NULL, NULL}
        };
  
index e38b64a09db0e6ac9a846876072bc76920f5550f,cf9415a75e77825a00ae5f6d4b370f4ebbc5c4e5..5edb5da3e7c890c5effafa0105973cdc4a57b48e
@@@ -72,7 -72,6 +72,7 @@@
  #include "BKE_movieclip.h"
  #include "BKE_mask.h"
  #include "BKE_gpencil.h"
 +#include "BKE_linestyle.h"
  
  #include "DNA_armature_types.h"
  #include "DNA_camera_types.h"
@@@ -106,39 -105,43 +106,43 @@@ static Camera *rna_Main_cameras_new(Mai
        id_us_min(id);
        return (Camera *)id;
  }
- static void rna_Main_cameras_remove(Main *bmain, ReportList *reports, struct Camera *camera)
+ static void rna_Main_cameras_remove(Main *bmain, ReportList *reports, PointerRNA *camera_ptr)
  {
-       if (ID_REAL_USERS(camera) <= 0)
+       Camera *camera = camera_ptr->data;
+       if (ID_REAL_USERS(camera) <= 0) {
                BKE_libblock_free(&bmain->camera, camera);
-       else
+               RNA_POINTER_INVALIDATE(camera_ptr);
+       }
+       else {
                BKE_reportf(reports, RPT_ERROR, "Camera '%s' must have zero users to be removed, found %d",
                            camera->id.name + 2, ID_REAL_USERS(camera));
-       /* XXX python now has invalid pointer? */
+       }
  }
  
  static Scene *rna_Main_scenes_new(Main *UNUSED(bmain), const char *name)
  {
        return BKE_scene_add(name);
  }
- static void rna_Main_scenes_remove(Main *bmain, bContext *C, ReportList *reports, struct Scene *scene)
+ static void rna_Main_scenes_remove(Main *bmain, bContext *C, ReportList *reports, PointerRNA *scene_ptr)
  {
        /* don't call BKE_libblock_free(...) directly */
-       Scene *newscene;
+       Scene *scene = scene_ptr->data;
+       Scene *scene_new;
+       if ((scene_new = scene->id.prev) ||
+           (scene_new = scene->id.next))
+       {
+               bScreen *sc = CTX_wm_screen(C);
+               if (sc->scene == scene) {
+                       ED_screen_set_scene(C, sc, scene_new);
+               }
  
-       if (scene->id.prev)
-               newscene = scene->id.prev;
-       else if (scene->id.next)
-               newscene = scene->id.next;
+               BKE_scene_unlink(bmain, scene, scene_new);
+               RNA_POINTER_INVALIDATE(scene_ptr);
+       }
        else {
                BKE_reportf(reports, RPT_ERROR, "Scene '%s' is the last, cannot be removed", scene->id.name + 2);
-               return;
        }
-       if (CTX_wm_screen(C)->scene == scene)
-               ED_screen_set_scene(C, CTX_wm_screen(C), newscene);
-       BKE_scene_unlink(bmain, scene, newscene);
  }
  
  static Object *rna_Main_objects_new(Main *UNUSED(bmain), ReportList *reports, const char *name, ID *data)
                                type = OB_MESH;
                                break;
                        case ID_CU:
-                               type = BKE_curve_type_get((struct Curve *)data);
+                               type = BKE_curve_type_get((Curve *)data);
                                break;
                        case ID_MB:
                                type = OB_MBALL;
        return ob;
  }
  
- static void rna_Main_objects_remove(Main *bmain, ReportList *reports, struct Object *object)
+ static void rna_Main_objects_remove(Main *bmain, ReportList *reports, PointerRNA *object_ptr)
  {
+       Object *object = object_ptr->data;
        if (ID_REAL_USERS(object) <= 0) {
                BKE_object_unlink(object); /* needed or ID pointers to this are not cleared */
                BKE_libblock_free(&bmain->object, object);
+               RNA_POINTER_INVALIDATE(object_ptr);
        }
        else {
                BKE_reportf(reports, RPT_ERROR, "Object '%s' must have zero users to be removed, found %d",
@@@ -213,15 -218,17 +219,17 @@@ static Material *rna_Main_materials_new
        id_us_min(id);
        return (Material *)id;
  }
- static void rna_Main_materials_remove(Main *bmain, ReportList *reports, struct Material *material)
+ static void rna_Main_materials_remove(Main *bmain, ReportList *reports, PointerRNA *material_ptr)
  {
-       if (ID_REAL_USERS(material) <= 0)
+       Material *material = material_ptr->data;
+       if (ID_REAL_USERS(material) <= 0) {
                BKE_libblock_free(&bmain->mat, material);
-       else
+               RNA_POINTER_INVALIDATE(material_ptr);
+       }
+       else {
                BKE_reportf(reports, RPT_ERROR, "Material '%s' must have zero users to be removed, found %d",
                            material->id.name + 2, ID_REAL_USERS(material));
-       /* XXX python now has invalid pointer? */
+       }
  }
  
  static bNodeTree *rna_Main_nodetree_new(Main *UNUSED(bmain), const char *name, int type)
        id_us_min(&tree->id);
        return tree;
  }
- static void rna_Main_nodetree_remove(Main *bmain, ReportList *reports, struct bNodeTree *tree)
+ static void rna_Main_nodetree_remove(Main *bmain, ReportList *reports, PointerRNA *tree_ptr)
  {
-       if (ID_REAL_USERS(tree) <= 0)
+       bNodeTree *tree = tree_ptr->data;
+       if (ID_REAL_USERS(tree) <= 0) {
                BKE_libblock_free(&bmain->nodetree, tree);
-       else
+               RNA_POINTER_INVALIDATE(tree_ptr);
+       }
+       else {
                BKE_reportf(reports, RPT_ERROR, "Node tree '%s' must have zero users to be removed, found %d",
                            tree->id.name + 2, ID_REAL_USERS(tree));
-       /* XXX python now has invalid pointer? */
+       }
  }
  
  static Mesh *rna_Main_meshes_new(Main *UNUSED(bmain), const char *name)
        id_us_min(&me->id);
        return me;
  }
- static void rna_Main_meshes_remove(Main *bmain, ReportList *reports, Mesh *mesh)
+ static void rna_Main_meshes_remove(Main *bmain, ReportList *reports, PointerRNA *mesh_ptr)
  {
-       if (ID_REAL_USERS(mesh) <= 0)
+       Mesh *mesh = mesh_ptr->data;
+       if (ID_REAL_USERS(mesh) <= 0) {
                BKE_libblock_free(&bmain->mesh, mesh);
-       else
+               RNA_POINTER_INVALIDATE(mesh_ptr);
+       }
+       else {
                BKE_reportf(reports, RPT_ERROR, "Mesh '%s' must have zero users to be removed, found %d",
                            mesh->id.name + 2, ID_REAL_USERS(mesh));
-       /* XXX python now has invalid pointer? */
+       }
  }
  
  static Lamp *rna_Main_lamps_new(Main *UNUSED(bmain), const char *name, int type)
        id_us_min(&lamp->id);
        return lamp;
  }
- static void rna_Main_lamps_remove(Main *bmain, ReportList *reports, Lamp *lamp)
+ static void rna_Main_lamps_remove(Main *bmain, ReportList *reports, PointerRNA *lamp_ptr)
  {
-       if (ID_REAL_USERS(lamp) <= 0)
+       Lamp *lamp = lamp_ptr->data;
+       if (ID_REAL_USERS(lamp) <= 0) {
                BKE_libblock_free(&bmain->lamp, lamp);
-       else
+               RNA_POINTER_INVALIDATE(lamp_ptr);
+       }
+       else {
                BKE_reportf(reports, RPT_ERROR, "Lamp '%s' must have zero users to be removed, found %d",
                            lamp->id.name + 2, ID_REAL_USERS(lamp));
-       /* XXX python now has invalid pointer? */
+       }
  }
  
  static Image *rna_Main_images_new(Main *UNUSED(bmain), const char *name, int width, int height, int alpha, int float_buffer)
@@@ -291,21 -304,24 +305,24 @@@ static Image *rna_Main_images_load(Mai
        errno = 0;
        ima = BKE_image_load(filepath);
  
-       if (!ima)
+       if (!ima) {
                BKE_reportf(reports, RPT_ERROR, "Cannot read '%s': %s", filepath,
                            errno ? strerror(errno) : TIP_("unsupported image format"));
+       }
  
        return ima;
  }
- static void rna_Main_images_remove(Main *bmain, ReportList *reports, Image *image)
+ static void rna_Main_images_remove(Main *bmain, ReportList *reports, PointerRNA *image_ptr)
  {
-       if (ID_REAL_USERS(image) <= 0)
+       Image *image = image_ptr->data;
+       if (ID_REAL_USERS(image) <= 0) {
                BKE_libblock_free(&bmain->image, image);
-       else
+               RNA_POINTER_INVALIDATE(image_ptr);
+       }
+       else {
                BKE_reportf(reports, RPT_ERROR, "Image '%s' must have zero users to be removed, found %d",
                            image->id.name + 2, ID_REAL_USERS(image));
-       /* XXX python now has invalid pointer? */
+       }
  }
  
  static Lattice *rna_Main_lattices_new(Main *UNUSED(bmain), const char *name)
        id_us_min(&lt->id);
        return lt;
  }
- static void rna_Main_lattices_remove(Main *bmain, ReportList *reports, struct Lattice *lt)
+ static void rna_Main_lattices_remove(Main *bmain, ReportList *reports, PointerRNA *lt_ptr)
  {
-       if (ID_REAL_USERS(lt) <= 0)
+       Lattice *lt = lt_ptr->data;
+       if (ID_REAL_USERS(lt) <= 0) {
                BKE_libblock_free(&bmain->latt, lt);
-       else
+               RNA_POINTER_INVALIDATE(lt_ptr);
+       }
+       else {
                BKE_reportf(reports, RPT_ERROR, "Lattice '%s' must have zero users to be removed, found %d",
                            lt->id.name + 2, ID_REAL_USERS(lt));
+       }
  }
  
  static Curve *rna_Main_curves_new(Main *UNUSED(bmain), const char *name, int type)
        id_us_min(&cu->id);
        return cu;
  }
- static void rna_Main_curves_remove(Main *bmain, ReportList *reports, struct Curve *cu)
+ static void rna_Main_curves_remove(Main *bmain, ReportList *reports, PointerRNA *cu_ptr)
  {
-       if (ID_REAL_USERS(cu) <= 0)
+       Curve *cu = cu_ptr->data;
+       if (ID_REAL_USERS(cu) <= 0) {
                BKE_libblock_free(&bmain->curve, cu);
-       else
+               RNA_POINTER_INVALIDATE(cu_ptr);
+       }
+       else {
                BKE_reportf(reports, RPT_ERROR, "Curve '%s' must have zero users to be removed, found %d",
                            cu->id.name + 2, ID_REAL_USERS(cu));
+       }
  }
  
  static MetaBall *rna_Main_metaballs_new(Main *UNUSED(bmain), const char *name)
        id_us_min(&mb->id);
        return mb;
  }
- static void rna_Main_metaballs_remove(Main *bmain, ReportList *reports, struct MetaBall *mb)
+ static void rna_Main_metaballs_remove(Main *bmain, ReportList *reports, PointerRNA *mb_ptr)
  {
-       if (ID_REAL_USERS(mb) <= 0)
+       MetaBall *mb = mb_ptr->data;
+       if (ID_REAL_USERS(mb) <= 0) {
                BKE_libblock_free(&bmain->mball, mb);
-       else
+               RNA_POINTER_INVALIDATE(mb_ptr);
+       }
+       else {
                BKE_reportf(reports, RPT_ERROR, "Metaball '%s' must have zero users to be removed, found %d",
                            mb->id.name + 2, ID_REAL_USERS(mb));
+       }
  }
  
  static VFont *rna_Main_fonts_load(Main *bmain, ReportList *reports, const char *filepath)
        return font;
  
  }
- static void rna_Main_fonts_remove(Main *bmain, ReportList *reports, VFont *vfont)
+ static void rna_Main_fonts_remove(Main *bmain, ReportList *reports, PointerRNA *vfont_ptr)
  {
-       if (ID_REAL_USERS(vfont) <= 0)
+       VFont *vfont = vfont_ptr->data;
+       if (ID_REAL_USERS(vfont) <= 0) {
                BKE_libblock_free(&bmain->vfont, vfont);
-       else
+               RNA_POINTER_INVALIDATE(vfont_ptr);
+       }
+       else {
                BKE_reportf(reports, RPT_ERROR, "Font '%s' must have zero users to be removed, found %d",
                            vfont->id.name + 2, ID_REAL_USERS(vfont));
-       /* XXX python now has invalid pointer? */
+       }
  }
  
  static Tex *rna_Main_textures_new(Main *UNUSED(bmain), const char *name, int type)
        id_us_min(&tex->id);
        return tex;
  }
- static void rna_Main_textures_remove(Main *bmain, ReportList *reports, struct Tex *tex)
+ static void rna_Main_textures_remove(Main *bmain, ReportList *reports, PointerRNA *tex_ptr)
  {
-       if (ID_REAL_USERS(tex) <= 0)
+       Tex *tex = tex_ptr->data;
+       if (ID_REAL_USERS(tex) <= 0) {
                BKE_libblock_free(&bmain->tex, tex);
-       else
+               RNA_POINTER_INVALIDATE(tex_ptr);
+       }
+       else {
                BKE_reportf(reports, RPT_ERROR, "Texture '%s' must have zero users to be removed, found %d",
                            tex->id.name + 2, ID_REAL_USERS(tex));
+       }
  }
  
  static Brush *rna_Main_brushes_new(Main *UNUSED(bmain), const char *name)
        id_us_min(&brush->id);
        return brush;
  }
- static void rna_Main_brushes_remove(Main *bmain, ReportList *reports, struct Brush *brush)
+ static void rna_Main_brushes_remove(Main *bmain, ReportList *reports, PointerRNA *brush_ptr)
  {
-       if (ID_REAL_USERS(brush) <= 0)
+       Brush *brush = brush_ptr->data;
+       if (ID_REAL_USERS(brush) <= 0) {
                BKE_libblock_free(&bmain->brush, brush);
-       else
+               RNA_POINTER_INVALIDATE(brush_ptr);
+       }
+       else {
                BKE_reportf(reports, RPT_ERROR, "Brush '%s' must have zero users to be removed, found %d",
                            brush->id.name + 2, ID_REAL_USERS(brush));
+       }
  }
  
  static World *rna_Main_worlds_new(Main *UNUSED(bmain), const char *name)
        id_us_min(&world->id);
        return world;
  }
- static void rna_Main_worlds_remove(Main *bmain, ReportList *reports, struct World *world)
+ static void rna_Main_worlds_remove(Main *bmain, ReportList *reports, PointerRNA *world_ptr)
  {
-       if (ID_REAL_USERS(world) <= 0)
+       Group *world = world_ptr->data;
+       if (ID_REAL_USERS(world) <= 0) {
                BKE_libblock_free(&bmain->world, world);
-       else
+               RNA_POINTER_INVALIDATE(world_ptr);
+       }
+       else {
                BKE_reportf(reports, RPT_ERROR, "World '%s' must have zero users to be removed, found %d",
                            world->id.name + 2, ID_REAL_USERS(world));
+       }
  }
  
  static Group *rna_Main_groups_new(Main *UNUSED(bmain), const char *name)
  {
        return add_group(name);
  }
- static void rna_Main_groups_remove(Main *bmain, Group *group)
+ static void rna_Main_groups_remove(Main *bmain, PointerRNA *group_ptr)
  {
+       Group *group = group_ptr->data;
        BKE_group_unlink(group);
        BKE_libblock_free(&bmain->group, group);
-       /* XXX python now has invalid pointer? */
+       RNA_POINTER_INVALIDATE(group_ptr);
  }
  
  static Speaker *rna_Main_speakers_new(Main *UNUSED(bmain), const char *name)
        id_us_min(&speaker->id);
        return speaker;
  }
- static void rna_Main_speakers_remove(Main *bmain, ReportList *reports, Speaker *speaker)
+ static void rna_Main_speakers_remove(Main *bmain, ReportList *reports, PointerRNA *speaker_ptr)
  {
-       if (ID_REAL_USERS(speaker) <= 0)
+       Speaker *speaker = speaker_ptr->data;
+       if (ID_REAL_USERS(speaker) <= 0) {
                BKE_libblock_free(&bmain->speaker, speaker);
-       else
+               RNA_POINTER_INVALIDATE(speaker_ptr);
+       }
+       else {
                BKE_reportf(reports, RPT_ERROR, "Speaker '%s' must have zero users to be removed, found %d",
                            speaker->id.name + 2, ID_REAL_USERS(speaker));
-       /* XXX python now has invalid pointer? */
+       }
  }
  
  static Text *rna_Main_texts_new(Main *UNUSED(bmain), const char *name)
  {
        return BKE_text_add(name);
  }
- static void rna_Main_texts_remove(Main *bmain, Text *text)
+ static void rna_Main_texts_remove(Main *bmain, PointerRNA *text_ptr)
  {
+       Text *text = text_ptr->data;
        BKE_text_unlink(bmain, text);
        BKE_libblock_free(&bmain->text, text);
-       /* XXX python now has invalid pointer? */
+       RNA_POINTER_INVALIDATE(text_ptr);
  }
  
  static Text *rna_Main_texts_load(Main *bmain, ReportList *reports, const char *filepath)
@@@ -483,15 -529,17 +530,17 @@@ static bArmature *rna_Main_armatures_ne
        id_us_min(&arm->id);
        return arm;
  }
- static void rna_Main_armatures_remove(Main *bmain, ReportList *reports, bArmature *arm)
+ static void rna_Main_armatures_remove(Main *bmain, ReportList *reports, PointerRNA *arm_ptr)
  {
-       if (ID_REAL_USERS(arm) <= 0)
+       bArmature *arm = arm_ptr->data;
+       if (ID_REAL_USERS(arm) <= 0) {
                BKE_libblock_free(&bmain->armature, arm);
-       else
+               RNA_POINTER_INVALIDATE(arm_ptr);
+       }
+       else {
                BKE_reportf(reports, RPT_ERROR, "Armature '%s' must have zero users to be removed, found %d",
                            arm->id.name + 2, ID_REAL_USERS(arm));
-       /* XXX python now has invalid pointer? */
+       }
  }
  
  static bAction *rna_Main_actions_new(Main *UNUSED(bmain), const char *name)
        act->id.flag &= ~LIB_FAKEUSER;
        return act;
  }
- static void rna_Main_actions_remove(Main *bmain, ReportList *reports, bAction *act)
+ static void rna_Main_actions_remove(Main *bmain, ReportList *reports, PointerRNA *act_ptr)
  {
-       if (ID_REAL_USERS(act) <= 0)
+       bAction *act = act_ptr->data;
+       if (ID_REAL_USERS(act) <= 0) {
                BKE_libblock_free(&bmain->action, act);
-       else
+               RNA_POINTER_INVALIDATE(act_ptr);
+       }
+       else {
                BKE_reportf(reports, RPT_ERROR, "Action '%s' must have zero users to be removed, found %d",
                            act->id.name + 2, ID_REAL_USERS(act));
-       /* XXX python now has invalid pointer? */
+       }
  }
  
  static ParticleSettings *rna_Main_particles_new(Main *bmain, const char *name)
        id_us_min(&part->id);
        return part;
  }
- static void rna_Main_particles_remove(Main *bmain, ReportList *reports, ParticleSettings *part)
+ static void rna_Main_particles_remove(Main *bmain, ReportList *reports, PointerRNA *part_ptr)
  {
-       if (ID_REAL_USERS(part) <= 0)
+       ParticleSettings *part = part_ptr->data;
+       if (ID_REAL_USERS(part) <= 0) {
                BKE_libblock_free(&bmain->particle, part);
-       else
+               RNA_POINTER_INVALIDATE(part_ptr);
+       }
+       else {
                BKE_reportf(reports, RPT_ERROR, "Particle settings '%s' must have zero users to be removed, found %d",
                            part->id.name + 2, ID_REAL_USERS(part));
-       /* XXX python now has invalid pointer? */
+       }
  }
  
  static MovieClip *rna_Main_movieclip_load(Main *UNUSED(bmain), ReportList *reports, const char *filepath)
        return clip;
  }
  
- static void rna_Main_movieclips_remove(Main *bmain, MovieClip *clip)
+ static void rna_Main_movieclips_remove(Main *bmain, PointerRNA *clip_ptr)
  {
+       MovieClip *clip = clip_ptr->data;
        BKE_movieclip_unlink(bmain, clip);
        BKE_libblock_free(&bmain->movieclip, clip);
-       /* XXX python now has invalid pointer? */
+       RNA_POINTER_INVALIDATE(clip_ptr);
  }
  
  static Mask *rna_Main_mask_new(Main *UNUSED(bmain), const char *name)
        return mask;
  }
  
- static void rna_Main_masks_remove(Main *bmain, Mask *mask)
+ static void rna_Main_masks_remove(Main *bmain, PointerRNA *mask_ptr)
  {
+       Mask *mask = mask_ptr->data;
        BKE_mask_free(bmain, mask);
        BKE_libblock_free(&bmain->mask, mask);
-       /* XXX python now has invalid pointer? */
+       RNA_POINTER_INVALIDATE(mask_ptr);
  }
  
- static void rna_Main_grease_pencil_remove(Main *bmain, ReportList *reports, bGPdata *gpd)
+ static void rna_Main_grease_pencil_remove(Main *bmain, ReportList *reports, PointerRNA *gpd_ptr)
  {
+       bGPdata *gpd = gpd_ptr->data;
        if (ID_REAL_USERS(gpd) <= 0) {
                BKE_gpencil_free(gpd);
                BKE_libblock_free(&bmain->gpencil, gpd);
+               RNA_POINTER_INVALIDATE(gpd_ptr);
        }
        else
                BKE_reportf(reports, RPT_ERROR, "Grease pencil '%s' must have zero users to be removed, found %d",
                            gpd->id.name + 2, ID_REAL_USERS(gpd));
-       /* XXX python now has invalid pointer? */
  }
  
 +FreestyleLineStyle *rna_Main_linestyles_new(Main *bmain, const char* name)
 +{
 +      FreestyleLineStyle *linestyle = FRS_new_linestyle(name, bmain);
 +      id_us_min(&linestyle->id);
 +      return linestyle;
 +}
 +
 +void rna_Main_linestyles_remove(Main *bmain, ReportList *reports, FreestyleLineStyle *linestyle)
 +{
 +      if(ID_REAL_USERS(linestyle) <= 0)
 +              BKE_libblock_free(&bmain->linestyle, linestyle);
 +      else
 +              BKE_reportf(reports, RPT_ERROR, "Line style \"%s\" must have zero users to be removed, found %d.", linestyle->id.name+2, ID_REAL_USERS(linestyle));
 +
 +      /* XXX python now has invalid pointer? */
 +}
 +
  /* tag functions, all the same */
  static void rna_Main_cameras_tag(Main *bmain, int value) { tag_main_lb(&bmain->camera, value); }
  static void rna_Main_scenes_tag(Main *bmain, int value) { tag_main_lb(&bmain->scene, value); }
@@@ -627,7 -664,6 +682,7 @@@ static void rna_Main_particles_tag(Mai
  static void rna_Main_gpencil_tag(Main *bmain, int value) { tag_main_lb(&bmain->gpencil, value); }
  static void rna_Main_movieclips_tag(Main *bmain, int value) { tag_main_lb(&bmain->movieclip, value); }
  static void rna_Main_masks_tag(Main *bmain, int value) { tag_main_lb(&bmain->mask, value); }
 +void rna_Main_linestyle_tag(Main *bmain, int value) { tag_main_lb(&bmain->linestyle, value); }
  
  static int rna_Main_cameras_is_updated_get(PointerRNA *ptr) { return DAG_id_type_tagged(ptr->data, ID_CA); }
  static int rna_Main_scenes_is_updated_get(PointerRNA *ptr) { return DAG_id_type_tagged(ptr->data, ID_SCE); }
@@@ -700,7 -736,8 +755,8 @@@ void RNA_def_main_cameras(BlenderRNA *b
        RNA_def_function_flag(func, FUNC_USE_REPORTS);
        RNA_def_function_ui_description(func, "Remove a camera from the current blendfile");
        parm = RNA_def_pointer(func, "camera", "Camera", "", "Camera to remove");
-       RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL);
+       RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL | PROP_RNAPTR);
+       RNA_def_property_clear_flag(parm, PROP_THICK_WRAP);
  
        func = RNA_def_function(srna, "tag", "rna_Main_cameras_tag");
        parm = RNA_def_boolean(func, "value", 0, "Value", "");
@@@ -735,7 -772,8 +791,8 @@@ void RNA_def_main_scenes(BlenderRNA *br
        RNA_def_function_flag(func, FUNC_USE_CONTEXT | FUNC_USE_REPORTS);
        RNA_def_function_ui_description(func, "Remove a scene from the current blendfile");
        parm = RNA_def_pointer(func, "scene", "Scene", "", "Scene to remove");
-       RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL);
+       RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL | PROP_RNAPTR);
+       RNA_def_property_clear_flag(parm, PROP_THICK_WRAP);
  
        func = RNA_def_function(srna, "tag", "rna_Main_scenes_tag");
        parm = RNA_def_boolean(func, "value", 0, "Value", "");
@@@ -774,7 -812,8 +831,8 @@@ void RNA_def_main_objects(BlenderRNA *b
        RNA_def_function_ui_description(func, "Remove a object from the current blendfile");
        RNA_def_function_flag(func, FUNC_USE_REPORTS);
        parm = RNA_def_pointer(func, "object", "Object", "", "Object to remove");
-       RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL);
+       RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL | PROP_RNAPTR);
+       RNA_def_property_clear_flag(parm, PROP_THICK_WRAP);
  
        func = RNA_def_function(srna, "tag", "rna_Main_objects_tag");
        parm = RNA_def_boolean(func, "value", 0, "Value", "");
@@@ -809,7 -848,8 +867,8 @@@ void RNA_def_main_materials(BlenderRNA 
        RNA_def_function_flag(func, FUNC_USE_REPORTS);
        RNA_def_function_ui_description(func, "Remove a material from the current blendfile");
        parm = RNA_def_pointer(func, "material", "Material", "", "Material to remove");
-       RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL);
+       RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL | PROP_RNAPTR);
+       RNA_def_property_clear_flag(parm, PROP_THICK_WRAP);
  
        func = RNA_def_function(srna, "tag", "rna_Main_materials_tag");
        parm = RNA_def_boolean(func, "value", 0, "Value", "");
@@@ -852,7 -892,8 +911,8 @@@ void RNA_def_main_node_groups(BlenderRN
        RNA_def_function_flag(func, FUNC_USE_REPORTS);
        RNA_def_function_ui_description(func, "Remove a node tree from the current blendfile");
        parm = RNA_def_pointer(func, "tree", "NodeTree", "", "Node tree to remove");
-       RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL);
+       RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL | PROP_RNAPTR);
+       RNA_def_property_clear_flag(parm, PROP_THICK_WRAP);
  
        func = RNA_def_function(srna, "tag", "rna_Main_node_groups_tag");
        parm = RNA_def_boolean(func, "value", 0, "Value", "");
@@@ -886,7 -927,8 +946,8 @@@ void RNA_def_main_meshes(BlenderRNA *br
        RNA_def_function_flag(func, FUNC_USE_REPORTS);
        RNA_def_function_ui_description(func, "Remove a mesh from the current blendfile");
        parm = RNA_def_pointer(func, "mesh", "Mesh", "", "Mesh to remove");
-       RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL);
+       RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL | PROP_RNAPTR);
+       RNA_def_property_clear_flag(parm, PROP_THICK_WRAP);
  
        func = RNA_def_function(srna, "tag", "rna_Main_meshes_tag");
        parm = RNA_def_boolean(func, "value", 0, "Value", "");
@@@ -922,7 -964,8 +983,8 @@@ void RNA_def_main_lamps(BlenderRNA *brn
        RNA_def_function_flag(func, FUNC_USE_REPORTS);
        RNA_def_function_ui_description(func, "Remove a lamp from the current blendfile");
        parm = RNA_def_pointer(func, "lamp", "Lamp", "", "Lamp to remove");
-       RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL);
+       RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL | PROP_RNAPTR);
+       RNA_def_property_clear_flag(parm, PROP_THICK_WRAP);
  
        func = RNA_def_function(srna, "tag", "rna_Main_lamps_tag");
        parm = RNA_def_boolean(func, "value", 0, "Value", "");
@@@ -1034,7 -1077,8 +1096,8 @@@ void RNA_def_main_images(BlenderRNA *br
        RNA_def_function_flag(func, FUNC_USE_REPORTS);
        RNA_def_function_ui_description(func, "Remove an image from the current blendfile");
        parm = RNA_def_pointer(func, "image", "Image", "", "Image to remove");
-       RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL);
+       RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL | PROP_RNAPTR);
+       RNA_def_property_clear_flag(parm, PROP_THICK_WRAP);
  
        func = RNA_def_function(srna, "tag", "rna_Main_images_tag");
        parm = RNA_def_boolean(func, "value", 0, "Value", "");
@@@ -1069,7 -1113,8 +1132,8 @@@ void RNA_def_main_lattices(BlenderRNA *
        RNA_def_function_flag(func, FUNC_USE_REPORTS);
        RNA_def_function_ui_description(func, "Remove a lattice from the current blendfile");
        parm = RNA_def_pointer(func, "lattice", "Lattice", "", "Lattice to remove");
-       RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL);
+       RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL | PROP_RNAPTR);
+       RNA_def_property_clear_flag(parm, PROP_THICK_WRAP);
  
        func = RNA_def_function(srna, "tag", "rna_Main_lattices_tag");
        parm = RNA_def_boolean(func, "value", 0, "Value", "");
@@@ -1105,7 -1150,8 +1169,8 @@@ void RNA_def_main_curves(BlenderRNA *br
        RNA_def_function_flag(func, FUNC_USE_REPORTS);
        RNA_def_function_ui_description(func, "Remove a curve from the current blendfile");
        parm = RNA_def_pointer(func, "curve", "Curve", "", "Curve to remove");
-       RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL);
+       RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL | PROP_RNAPTR);
+       RNA_def_property_clear_flag(parm, PROP_THICK_WRAP);
  
        func = RNA_def_function(srna, "tag", "rna_Main_curves_tag");
        parm = RNA_def_boolean(func, "value", 0, "Value", "");
@@@ -1139,7 -1185,8 +1204,8 @@@ void RNA_def_main_metaballs(BlenderRNA 
        RNA_def_function_flag(func, FUNC_USE_REPORTS);
        RNA_def_function_ui_description(func, "Remove a metaball from the current blendfile");
        parm = RNA_def_pointer(func, "metaball", "MetaBall", "", "Metaball to remove");
-       RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL);
+       RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL | PROP_RNAPTR);
+       RNA_def_property_clear_flag(parm, PROP_THICK_WRAP);
  
        func = RNA_def_function(srna, "tag", "rna_Main_metaballs_tag");
        parm = RNA_def_boolean(func, "value", 0, "Value", "");
@@@ -1174,7 -1221,8 +1240,8 @@@ void RNA_def_main_fonts(BlenderRNA *brn
        RNA_def_function_flag(func, FUNC_USE_REPORTS);
        RNA_def_function_ui_description(func, "Remove a font from the current blendfile");
        parm = RNA_def_pointer(func, "vfont", "VectorFont", "", "Font to remove");
-       RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL);
+       RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL | PROP_RNAPTR);
+       RNA_def_property_clear_flag(parm, PROP_THICK_WRAP);
  
        func = RNA_def_function(srna, "tag", "rna_Main_fonts_tag");
        parm = RNA_def_boolean(func, "value", 0, "Value", "");
@@@ -1210,7 -1258,8 +1277,8 @@@ void RNA_def_main_textures(BlenderRNA *
        RNA_def_function_flag(func, FUNC_USE_REPORTS);
        RNA_def_function_ui_description(func, "Remove a texture from the current blendfile");
        parm = RNA_def_pointer(func, "texture", "Texture", "", "Texture to remove");
-       RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL);
+       RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL | PROP_RNAPTR);
+       RNA_def_property_clear_flag(parm, PROP_THICK_WRAP);
  
        func = RNA_def_function(srna, "tag", "rna_Main_textures_tag");
        parm = RNA_def_boolean(func, "value", 0, "Value", "");
@@@ -1244,7 -1293,8 +1312,8 @@@ void RNA_def_main_brushes(BlenderRNA *b
        RNA_def_function_flag(func, FUNC_USE_REPORTS);
        RNA_def_function_ui_description(func, "Remove a brush from the current blendfile");
        parm = RNA_def_pointer(func, "brush", "Brush", "", "Brush to remove");
-       RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL);
+       RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL | PROP_RNAPTR);
+       RNA_def_property_clear_flag(parm, PROP_THICK_WRAP);
  
        func = RNA_def_function(srna, "tag", "rna_Main_brushes_tag");
        parm = RNA_def_boolean(func, "value", 0, "Value", "");
@@@ -1279,7 -1329,8 +1348,8 @@@ void RNA_def_main_worlds(BlenderRNA *br
        RNA_def_function_flag(func, FUNC_USE_REPORTS);
        RNA_def_function_ui_description(func, "Remove a world from the current blendfile");
        parm = RNA_def_pointer(func, "world", "World", "", "World to remove");
-       RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL);
+       RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL | PROP_RNAPTR);
+       RNA_def_property_clear_flag(parm, PROP_THICK_WRAP);
  
        func = RNA_def_function(srna, "tag", "rna_Main_worlds_tag");
        parm = RNA_def_boolean(func, "value", 0, "Value", "");
@@@ -1313,7 -1364,8 +1383,8 @@@ void RNA_def_main_groups(BlenderRNA *br
        func = RNA_def_function(srna, "remove", "rna_Main_groups_remove");
        RNA_def_function_ui_description(func, "Remove a group from the current blendfile");
        parm = RNA_def_pointer(func, "group", "Group", "", "Group to remove");
-       RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL);
+       RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL | PROP_RNAPTR);
+       RNA_def_property_clear_flag(parm, PROP_THICK_WRAP);
  
        func = RNA_def_function(srna, "tag", "rna_Main_groups_tag");
        parm = RNA_def_boolean(func, "value", 0, "Value", "");
@@@ -1348,7 -1400,8 +1419,8 @@@ void RNA_def_main_speakers(BlenderRNA *
        RNA_def_function_flag(func, FUNC_USE_REPORTS);
        RNA_def_function_ui_description(func, "Remove a speaker from the current blendfile");
        parm = RNA_def_pointer(func, "speaker", "Speaker", "", "Speaker to remove");
-       RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL);
+       RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL | PROP_RNAPTR);
+       RNA_def_property_clear_flag(parm, PROP_THICK_WRAP);
  
        func = RNA_def_function(srna, "tag", "rna_Main_speakers_tag");
        parm = RNA_def_boolean(func, "value", 0, "Value", "");
@@@ -1382,7 -1435,8 +1454,8 @@@ void RNA_def_main_texts(BlenderRNA *brn
        func = RNA_def_function(srna, "remove", "rna_Main_texts_remove");
        RNA_def_function_ui_description(func, "Remove a text from the current blendfile");
        parm = RNA_def_pointer(func, "text", "Text", "", "Text to remove");
-       RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL);
+       RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL | PROP_RNAPTR);
+       RNA_def_property_clear_flag(parm, PROP_THICK_WRAP);
  
        /* load func */
        func = RNA_def_function(srna, "load", "rna_Main_texts_load");
@@@ -1450,7 -1504,8 +1523,8 @@@ void RNA_def_main_armatures(BlenderRNA 
        RNA_def_function_flag(func, FUNC_USE_REPORTS);
        RNA_def_function_ui_description(func, "Remove a armature from the current blendfile");
        parm = RNA_def_pointer(func, "armature", "Armature", "", "Armature to remove");
-       RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL);
+       RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL | PROP_RNAPTR);
+       RNA_def_property_clear_flag(parm, PROP_THICK_WRAP);
  
        func = RNA_def_function(srna, "tag", "rna_Main_armatures_tag");
        parm = RNA_def_boolean(func, "value", 0, "Value", "");
@@@ -1484,7 -1539,8 +1558,8 @@@ void RNA_def_main_actions(BlenderRNA *b
        RNA_def_function_flag(func, FUNC_USE_REPORTS);
        RNA_def_function_ui_description(func, "Remove a action from the current blendfile");
        parm = RNA_def_pointer(func, "action", "Action", "", "Action to remove");
-       RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL);
+       RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL | PROP_RNAPTR);
+       RNA_def_property_clear_flag(parm, PROP_THICK_WRAP);
  
        func = RNA_def_function(srna, "tag", "rna_Main_actions_tag");
        parm = RNA_def_boolean(func, "value", 0, "Value", "");
@@@ -1518,7 -1574,8 +1593,8 @@@ void RNA_def_main_particles(BlenderRNA 
        RNA_def_function_flag(func, FUNC_USE_REPORTS);
        RNA_def_function_ui_description(func, "Remove a particle settings instance from the current blendfile");
        parm = RNA_def_pointer(func, "particle", "ParticleSettings", "", "Particle Settings to remove");
-       RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL);
+       RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL | PROP_RNAPTR);
+       RNA_def_property_clear_flag(parm, PROP_THICK_WRAP);
  
        func = RNA_def_function(srna, "tag", "rna_Main_particles_tag");
        parm = RNA_def_boolean(func, "value", 0, "Value", "");
@@@ -1557,7 -1614,8 +1633,8 @@@ void RNA_def_main_gpencil(BlenderRNA *b
        RNA_def_function_flag(func, FUNC_USE_REPORTS);
        RNA_def_function_ui_description(func, "Remove a grease pencil instance from the current blendfile");
        parm = RNA_def_pointer(func, "grease_pencil", "GreasePencil", "", "Grease Pencil to remove");
-       RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL);
+       RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL | PROP_RNAPTR);
+       RNA_def_property_clear_flag(parm, PROP_THICK_WRAP);
  
        prop = RNA_def_property(srna, "is_updated", PROP_BOOLEAN, PROP_NONE);
        RNA_def_property_clear_flag(prop, PROP_EDITABLE);
@@@ -1582,7 -1640,8 +1659,8 @@@ void RNA_def_main_movieclips(BlenderRN
        func = RNA_def_function(srna, "remove", "rna_Main_movieclips_remove");
        RNA_def_function_ui_description(func, "Remove a movie clip from the current blendfile.");
        parm = RNA_def_pointer(func, "clip", "MovieClip", "", "Movie clip to remove");
-       RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL);
+       RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL | PROP_RNAPTR);
+       RNA_def_property_clear_flag(parm, PROP_THICK_WRAP);
  
        /* load func */
        func = RNA_def_function(srna, "load", "rna_Main_movieclip_load");
@@@ -1613,7 -1672,7 +1691,7 @@@ void RNA_def_main_masks(BlenderRNA *brn
        /* new func */
        func = RNA_def_function(srna, "new", "rna_Main_mask_new");
        RNA_def_function_ui_description(func, "Add a new mask with a given name to the main database");
-       parm = RNA_def_string_file_path(func, "name", "", MAX_ID_NAME - 2, "Mask", "Name of new mask datablock");
+       RNA_def_string_file_path(func, "name", "", MAX_ID_NAME - 2, "Mask", "Name of new mask datablock");
        /* return type */
        parm = RNA_def_pointer(func, "mask", "Mask", "", "New mask datablock");
        RNA_def_function_return(func, parm);
        func = RNA_def_function(srna, "remove", "rna_Main_masks_remove");
        RNA_def_function_ui_description(func, "Remove a masks from the current blendfile.");
        parm = RNA_def_pointer(func, "mask", "Mask", "", "Mask to remove");
-       RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL);
+       RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL | PROP_RNAPTR);
+       RNA_def_property_clear_flag(parm, PROP_THICK_WRAP);
  }
  
 +void RNA_def_main_linestyles(BlenderRNA *brna, PropertyRNA *cprop)
 +{
 +      StructRNA *srna;
 +      FunctionRNA *func;
 +      PropertyRNA *parm;
 +
 +      RNA_def_property_srna(cprop, "BlendDataLineStyles");
 +      srna= RNA_def_struct(brna, "BlendDataLineStyles", NULL);
 +      RNA_def_struct_sdna(srna, "Main");
 +      RNA_def_struct_ui_text(srna, "Main Line Styles", "Collection of line styles");
 +
 +      func= RNA_def_function(srna, "new", "rna_Main_linestyles_new");
 +      RNA_def_function_ui_description(func, "Add a new line style instance to the main database");
 +      parm= RNA_def_string(func, "name", "FreestyleLineStyle", 0, "", "New name for the datablock");
 +      RNA_def_property_flag(parm, PROP_REQUIRED);
 +      /* return type */
 +      parm= RNA_def_pointer(func, "linestyle", "FreestyleLineStyle", "", "New line style datablock");
 +      RNA_def_function_return(func, parm);
 +
 +      func= RNA_def_function(srna, "remove", "rna_Main_linestyles_remove");
 +      RNA_def_function_flag(func, FUNC_USE_REPORTS);
 +      RNA_def_function_ui_description(func, "Remove a line style instance from the current blendfile");
 +      parm= RNA_def_pointer(func, "linestyle", "FreestyleLineStyle", "", "Line style to remove");
 +      RNA_def_property_flag(parm, PROP_REQUIRED);
 +}
 +
  #endif
index 5ddf2073f195dba4c2278d6a97ab6b440624395f,f0b84332d07f0b1ac60f9c80f77d66f9603beb1b..ec7f92374a727227a123500eecffeb7622898301
@@@ -1551,11 -1551,6 +1551,11 @@@ static void rna_def_medge(BlenderRNA *b
        RNA_def_property_ui_text(prop, "Sharp", "Sharp edge for the EdgeSplit modifier");
        RNA_def_property_update(prop, 0, "rna_Mesh_update_data");
  
 +      prop = RNA_def_property(srna, "use_freestyle_edge_mark", PROP_BOOLEAN, PROP_NONE);
 +      RNA_def_property_boolean_sdna(prop, NULL, "flag", ME_FREESTYLE_EDGE);
 +      RNA_def_property_ui_text(prop, "Freestyle Edge Mark", "Edge mark for Freestyle feature edge detection");
 +      RNA_def_property_update(prop, 0, "rna_Mesh_update_data");
 +
        prop = RNA_def_property(srna, "is_loose", PROP_BOOLEAN, PROP_NONE);
        RNA_def_property_boolean_sdna(prop, NULL, "flag", ME_LOOSEEDGE);
        RNA_def_property_ui_text(prop, "Loose", "Loose edge");
@@@ -1611,11 -1606,6 +1611,11 @@@ static void rna_def_mface(BlenderRNA *b
        RNA_def_property_boolean_sdna(prop, NULL, "flag", ME_SMOOTH);
        RNA_def_property_ui_text(prop, "Smooth", "");
        RNA_def_property_update(prop, 0, "rna_Mesh_update_data");
 +      
 +      prop = RNA_def_property(srna, "use_freestyle_face_mark", PROP_BOOLEAN, PROP_NONE);
 +      RNA_def_property_boolean_sdna(prop, NULL, "flag", ME_FREESTYLE_FACE);
 +      RNA_def_property_ui_text(prop, "Freestyle Face Mark", "Face mark for Freestyle feature edge detection");
 +      RNA_def_property_update(prop, 0, "rna_Mesh_update_data");
  
        prop = RNA_def_property(srna, "normal", PROP_FLOAT, PROP_DIRECTION);
        RNA_def_property_array(prop, 3);
@@@ -1714,11 -1704,6 +1714,11 @@@ static void rna_def_mpolygon(BlenderRN
        RNA_def_property_ui_text(prop, "Smooth", "");
        RNA_def_property_update(prop, 0, "rna_Mesh_update_data");
  
 +      prop = RNA_def_property(srna, "use_freestyle_face_mark", PROP_BOOLEAN, PROP_NONE);
 +      RNA_def_property_boolean_sdna(prop, NULL, "flag", ME_FREESTYLE_FACE);
 +      RNA_def_property_ui_text(prop, "Freestyle Face Mark", "Face mark for Freestyle feature edge detection");
 +      RNA_def_property_update(prop, 0, "rna_Mesh_update_data");
 +
        prop = RNA_def_property(srna, "normal", PROP_FLOAT, PROP_DIRECTION);
        RNA_def_property_array(prop, 3);
        RNA_def_property_range(prop, -1.0f, 1.0f);
@@@ -2409,7 -2394,8 +2409,8 @@@ static void rna_def_loop_colors(Blender
        RNA_def_function_ui_description(func, "Remove a vertex color layer");
        RNA_def_function_flag(func, FUNC_USE_REPORTS);
        parm = RNA_def_pointer(func, "layer", "Layer", "", "The layer to remove");
-       RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL);
+       RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL | PROP_RNAPTR);
+       RNA_def_property_clear_flag(parm, PROP_THICK_WRAP);
  #endif
  
        prop = RNA_def_property(srna, "active", PROP_POINTER, PROP_UNSIGNED);
@@@ -2586,7 -2572,8 +2587,8 @@@ static void rna_def_uv_textures(Blender
        RNA_def_function_ui_description(func, "Remove a vertex color layer");
        RNA_def_function_flag(func, FUNC_USE_REPORTS);
        parm = RNA_def_pointer(func, "layer", "Layer", "", "The layer to remove");
-       RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL);
+       RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL | PROP_RNAPTR);
+       RNA_def_property_clear_flag(parm, PROP_THICK_WRAP);
  #endif
  
        prop = RNA_def_property(srna, "active", PROP_POINTER, PROP_UNSIGNED);
@@@ -2933,16 -2920,6 +2935,16 @@@ static void rna_def_mesh(BlenderRNA *br
        RNA_def_property_ui_text(prop, "Draw Sharp", "Display sharp edges, used with the EdgeSplit modifier");
        RNA_def_property_update(prop, 0, "rna_Mesh_update_draw");
  
 +      prop = RNA_def_property(srna, "show_freestyle_edge_marks", PROP_BOOLEAN, PROP_NONE);
 +      RNA_def_property_boolean_sdna(prop, NULL, "drawflag", ME_DRAW_FREESTYLE_EDGE);
 +      RNA_def_property_ui_text(prop, "Draw Freestyle Edge Marks", "Display Freestyle edge marks, used with the Freestyle renderer");
 +      RNA_def_property_update(prop, 0, "rna_Mesh_update_draw");
 +
 +      prop = RNA_def_property(srna, "show_freestyle_face_marks", PROP_BOOLEAN, PROP_NONE);
 +      RNA_def_property_boolean_sdna(prop, NULL, "drawflag", ME_DRAW_FREESTYLE_FACE);
 +      RNA_def_property_ui_text(prop, "Draw Freestyle Face Marks", "Display Freestyle face marks, used with the Freestyle renderer");
 +      RNA_def_property_update(prop, 0, "rna_Mesh_update_draw");
 +
        prop = RNA_def_property(srna, "show_extra_edge_length", PROP_BOOLEAN, PROP_NONE);
        RNA_def_property_boolean_sdna(prop, NULL, "drawflag", ME_DRAWEXTRA_EDGELEN);
        RNA_def_property_ui_text(prop, "Edge Length",
index b71aa507591062c3731eb9f5a7c7f7e874969f3e,df50f84add7c06a207bf2d2f5ad56e5947f89450..42fb712786ccf98c805293f0d9eabfce78ccfcc3
@@@ -38,7 -38,6 +38,7 @@@
  #include "DNA_scene_types.h"
  #include "DNA_userdef_types.h"
  #include "DNA_world_types.h"
 +#include "DNA_linestyle_types.h"
  
  #include "BLI_math.h"
  
@@@ -325,8 -324,6 +325,8 @@@ EnumPropertyItem image_color_depth_item
  
  #include "RE_engine.h"
  
 +#include "FRS_freestyle.h"
 +
  static void rna_SpaceImageEditor_uv_sculpt_update(Main *bmain, Scene *scene, PointerRNA *UNUSED(ptr))
  {
        ED_space_image_uv_sculpt_update(bmain->wm.first, scene->toolsettings);
@@@ -1036,17 -1033,20 +1036,20 @@@ static SceneRenderLayer *rna_RenderLaye
  }
  
  static void rna_RenderLayer_remove(ID *id, RenderData *UNUSED(rd), Main *bmain, ReportList *reports,
-                                    SceneRenderLayer *srl)
+                                    PointerRNA *srl_ptr)
  {
+       SceneRenderLayer *srl = srl_ptr->data;
        Scene *scene = (Scene *)id;
  
        if (!BKE_scene_remove_render_layer(bmain, scene, srl)) {
                BKE_reportf(reports, RPT_ERROR, "Render layer '%s' could not be removed from scene '%s'",
                            srl->name, scene->id.name + 2);
+               return;
        }
-       else {
-               WM_main_add_notifier(NC_SCENE | ND_RENDER_OPTIONS, NULL);
-       }
+       RNA_POINTER_INVALIDATE(srl_ptr);
+       WM_main_add_notifier(NC_SCENE | ND_RENDER_OPTIONS, NULL);
  }
  
  static void rna_RenderSettings_engine_set(PointerRNA *ptr, int value)
@@@ -1336,15 -1336,16 +1339,16 @@@ static TimeMarker *rna_TimeLine_add(Sce
        return marker;
  }
  
- static void rna_TimeLine_remove(Scene *scene, ReportList *reports, TimeMarker *marker)
+ static void rna_TimeLine_remove(Scene *scene, ReportList *reports, PointerRNA *marker_ptr)
  {
-       if (!BLI_remlink_safe(&scene->markers, marker)) {
+       TimeMarker *marker = marker_ptr->data;
+       if (BLI_remlink_safe(&scene->markers, marker) == FALSE) {
                BKE_reportf(reports, RPT_ERROR, "Timeline marker '%s' not found in scene '%s'", marker->name, scene->id.name + 2);
                return;
        }
  
-       /* XXX, invalidates PyObject */
        MEM_freeN(marker);
+       RNA_POINTER_INVALIDATE(marker_ptr);
  
        WM_main_add_notifier(NC_SCENE | ND_MARKERS, NULL);
        WM_main_add_notifier(NC_ANIMATION | ND_MARKERS, NULL);
@@@ -1423,49 -1424,6 +1427,49 @@@ static void rna_SceneSequencer_update(M
        BKE_sequencer_preprocessed_cache_cleanup();
  }
  
 +static PointerRNA rna_FreestyleLineSet_linestyle_get(PointerRNA *ptr)
 +{
 +      FreestyleLineSet *lineset= (FreestyleLineSet *)ptr->data;
 +
 +      return rna_pointer_inherit_refine(ptr, &RNA_FreestyleLineStyle, lineset->linestyle);
 +}
 +
 +static void rna_FreestyleLineSet_linestyle_set(PointerRNA *ptr, PointerRNA value)
 +{
 +      FreestyleLineSet *lineset= (FreestyleLineSet*)ptr->data;
 +
 +      lineset->linestyle->id.us--;
 +      lineset->linestyle = (FreestyleLineStyle *)value.data;
 +      lineset->linestyle->id.us++;
 +}
 +
 +static PointerRNA rna_FreestyleSettings_active_lineset_get(PointerRNA *ptr)
 +{
 +      FreestyleConfig *config= (FreestyleConfig *)ptr->data;
 +      FreestyleLineSet *lineset= FRS_get_active_lineset(config);
 +      return rna_pointer_inherit_refine(ptr, &RNA_FreestyleLineSet, lineset);
 +}
 +
 +static void rna_FreestyleSettings_active_lineset_index_range(PointerRNA *ptr, int *min, int *max)
 +{
 +      FreestyleConfig *config= (FreestyleConfig *)ptr->data;
 +      *min= 0;
 +      *max= BLI_countlist(&config->linesets)-1;
 +      *max= MAX2(0, *max);
 +}
 +
 +static int rna_FreestyleSettings_active_lineset_index_get(PointerRNA *ptr)
 +{
 +      FreestyleConfig *config= (FreestyleConfig *)ptr->data;
 +      return FRS_get_active_lineset_index(config);
 +}
 +
 +static void rna_FreestyleSettings_active_lineset_index_set(PointerRNA *ptr, int value)
 +{
 +      FreestyleConfig *config= (FreestyleConfig *)ptr->data;
 +      FRS_set_active_lineset_index(config, value);
 +}
 +
  #else
  
  static void rna_def_transform_orientation(BlenderRNA *brna)
@@@ -1533,7 -1491,6 +1537,7 @@@ static void rna_def_tool_settings(Blend
                {EDGE_MODE_TAG_SHARP, "SHARP", 0, "Tag Sharp", ""},
                {EDGE_MODE_TAG_CREASE, "CREASE", 0, "Tag Crease", ""},
                {EDGE_MODE_TAG_BEVEL, "BEVEL", 0, "Tag Bevel", ""},
 +              {EDGE_MODE_TAG_FREESTYLE, "FREESTYLE", 0, "Tag Freestyle Edge Mark", ""},
                {0, NULL, 0, NULL, NULL}
        };
  
                                 "Project individual elements on the surface of other objects");
        RNA_def_property_ui_icon(prop, ICON_RETOPO, 0);
        RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL); /* header redraw */
 -
 +      
        prop = RNA_def_property(srna, "use_snap_self", PROP_BOOLEAN, PROP_NONE);
        RNA_def_property_boolean_negative_sdna(prop, NULL, "snap_flag", SCE_SNAP_NO_SELF);
        RNA_def_property_ui_text(prop, "Project to Self", "Snap onto itself (editmode)");
@@@ -2075,12 -2032,6 +2079,12 @@@ void rna_def_render_layer_common(Struct
        if (scene) RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL);
        else RNA_def_property_clear_flag(prop, PROP_EDITABLE);
  
 +      prop= RNA_def_property(srna, "use_freestyle", PROP_BOOLEAN, PROP_NONE);
 +      RNA_def_property_boolean_sdna(prop, NULL, "layflag", SCE_LAY_FRS);
 +      RNA_def_property_ui_text(prop, "Freestyle", "Render stylized strokes in this Layer");
 +      if(scene) RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, NULL);
 +      else RNA_def_property_clear_flag(prop, PROP_EDITABLE);
 +
        /* passes */
        prop = RNA_def_property(srna, "use_pass_combined", PROP_BOOLEAN, PROP_NONE);
        RNA_def_property_boolean_sdna(prop, NULL, "passflag", SCE_PASS_COMBINED);
        else RNA_def_property_clear_flag(prop, PROP_EDITABLE);
  }
  
 +static void rna_def_freestyle_linesets(BlenderRNA *brna, PropertyRNA *cprop)
 +{
 +      StructRNA *srna;
 +      PropertyRNA *prop;
 +
 +      RNA_def_property_srna(cprop, "Linesets");
 +      srna= RNA_def_struct(brna, "Linesets", NULL);
 +      RNA_def_struct_sdna(srna, "FreestyleSettings");
 +      RNA_def_struct_ui_text(srna, "Line Sets", "Line sets for associating lines and style parameters");
 +
 +      prop= RNA_def_property(srna, "active", PROP_POINTER, PROP_NONE);
 +      RNA_def_property_struct_type(prop, "FreestyleLineSet");
 +      RNA_def_property_pointer_funcs(prop, "rna_FreestyleSettings_active_lineset_get", NULL, NULL, NULL);
 +      RNA_def_property_ui_text(prop, "Active Line Set", "Active line set being displayed");
 +      RNA_def_property_update(prop, NC_SCENE, NULL);
 +
 +      prop= RNA_def_property(srna, "active_index", PROP_INT, PROP_UNSIGNED);
 +      RNA_def_property_int_funcs(prop, "rna_FreestyleSettings_active_lineset_index_get", "rna_FreestyleSettings_active_lineset_index_set", "rna_FreestyleSettings_active_lineset_index_range");
 +      RNA_def_property_ui_text(prop, "Active Line Set Index", "Index of active line set slot");
 +      RNA_def_property_update(prop, NC_SCENE, NULL);
 +}
 +
 +static void rna_def_freestyle_settings(BlenderRNA *brna)
 +{
 +      StructRNA *srna;
 +      PropertyRNA *prop;
 +
 +      static EnumPropertyItem edge_type_negation_items[] = {
 +              {0, "INCLUSIVE", 0, "Inclusive", "Select feature edges satisfying the given edge type conditions"},
 +              {FREESTYLE_LINESET_FE_NOT, "EXCLUSIVE", 0, "Exclusive", "Select feature edges not satisfying the given edge type conditions"},
 +              {0, NULL, 0, NULL, NULL}};
 +
 +      static EnumPropertyItem edge_type_combination_items[] = {
 +              {0, "OR", 0, "Logical OR", "Combine feature edge type conditions by logical OR (logical disjunction)"},
 +              {FREESTYLE_LINESET_FE_AND, "AND", 0, "Logical AND", "Combine feature edge type conditions by logical AND (logical conjunction)"},
 +              {0, NULL, 0, NULL, NULL}};
 +
 +      static EnumPropertyItem group_negation_items[] = {
 +              {0, "INCLUSIVE", 0, "Inclusive", "Select feature edges belonging to some object in the group"},
 +              {FREESTYLE_LINESET_GR_NOT, "EXCLUSIVE", 0, "Exclusive", "Select feature edges not belonging to any object in the group"},
 +              {0, NULL, 0, NULL, NULL}};
 +
 +      static EnumPropertyItem face_mark_negation_items[] = {
 +              {0, "INCLUSIVE", 0, "Inclusive", "Select feature edges satisfying the given face mark conditions"},
 +              {FREESTYLE_LINESET_FM_NOT, "EXCLUSIVE", 0, "Exclusive", "Select feature edges not satisfying the given face mark conditions"},
 +              {0, NULL, 0, NULL, NULL}};
 +
 +      static EnumPropertyItem face_mark_condition_items[] = {
 +              {0, "ONE", 0, "One Face", "Select feature edges if one of faces on the right and left has a face mark"},
 +              {FREESTYLE_LINESET_FM_BOTH, "BOTH", 0, "Both Faces", "Select feature edges if both faces on the right and left faces have a face mark"},
 +              {0, NULL, 0, NULL, NULL}};
 +
 +      static EnumPropertyItem freestyle_ui_mode_items[] = {
 +              {FREESTYLE_CONTROL_SCRIPT_MODE, "SCRIPT", 0, "Python Scripting Mode", "Advanced mode for using style modules in Python"},
 +              {FREESTYLE_CONTROL_EDITOR_MODE, "EDITOR", 0, "Parameter Editor Mode", "Basic mode for interactive style parameter editing"},
 +              {0, NULL, 0, NULL, NULL}};
 +
 +      static EnumPropertyItem visibility_items[] ={
 +              {FREESTYLE_QI_VISIBLE, "VISIBLE", 0, "Visible", "Select visible feature edges"},
 +              {FREESTYLE_QI_HIDDEN, "HIDDEN", 0, "Hidden", "Select hidden feature edges"},
 +              {FREESTYLE_QI_RANGE, "RANGE", 0, "QI Range", "Select feature edges within a range of quantitative invisibility (QI) values"},
 +              {0, NULL, 0, NULL, NULL}};
 +
 +      static EnumPropertyItem freestyle_raycasting_algorithm_items[] = {
 +              {FREESTYLE_ALGO_REGULAR, "REGULAR", 0, "Normal Ray Casting", "Consider all FEdges in each ViewEdge"},
 +              {FREESTYLE_ALGO_FAST, "FAST", 0, "Fast Ray Casting", "Sample some FEdges in each ViewEdge"},
 +              {FREESTYLE_ALGO_VERYFAST, "VERYFAST", 0, "Very Fast Ray Casting", "Sample one FEdge in each ViewEdge; do not save list of occluders"},
 +              {FREESTYLE_ALGO_CULLED_ADAPTIVE_TRADITIONAL, "CULLEDADAPTIVETRADITIONAL", 0, "Culled Traditional Visibility Detection", "Culled adaptive grid with heuristic density and traditional QI calculation"},
 +              {FREESTYLE_ALGO_ADAPTIVE_TRADITIONAL, "ADAPTIVETRADITIONAL", 0, "Unculled Traditional Visibility Detection", "Adaptive grid with heuristic density and traditional QI calculation"},
 +              {FREESTYLE_ALGO_CULLED_ADAPTIVE_CUMULATIVE, "CULLEDADAPTIVECUMULATIVE", 0, "Culled Cumulative Visibility Detection", "Culled adaptive grid with heuristic density and cumulative QI calculation"},
 +              {FREESTYLE_ALGO_ADAPTIVE_CUMULATIVE, "ADAPTIVECUMULATIVE", 0, "Unculled Cumulative Visibility Detection", "Adaptive grid with heuristic density and cumulative QI calculation"},
 +              {0, NULL, 0, NULL, NULL}};
 +
 +
 +      /* FreestyleLineSet */
 +
 +      srna= RNA_def_struct(brna, "FreestyleLineSet", NULL);
 +      RNA_def_struct_ui_text(srna, "Freestyle Line Set", "Line set for associating lines and style parameters");
 +
 +      /* access to line style settings is redirected through functions */
 +      /* to allow proper id-buttons functionality */
 +      prop= RNA_def_property(srna, "linestyle", PROP_POINTER, PROP_NONE);
 +      RNA_def_property_struct_type(prop, "FreestyleLineStyle");
 +      RNA_def_property_flag(prop, PROP_EDITABLE|PROP_NEVER_NULL);
 +      RNA_def_property_pointer_funcs(prop, "rna_FreestyleLineSet_linestyle_get", "rna_FreestyleLineSet_linestyle_set", NULL, NULL);
 +      RNA_def_property_ui_text(prop, "Line Style", "Line style settings");
 +      RNA_def_property_update(prop, NC_SCENE, NULL);
 +
 +      prop= RNA_def_property(srna, "name", PROP_STRING, PROP_NONE);
 +      RNA_def_property_string_sdna(prop, NULL, "name");
 +      RNA_def_property_ui_text(prop, "Line Set Name", "Line set name");
 +      RNA_def_property_update(prop, NC_SCENE, NULL);
 +      RNA_def_struct_name_property(srna, prop);
 +
 +      prop= RNA_def_property(srna, "use", PROP_BOOLEAN, PROP_NONE);
 +      RNA_def_property_boolean_sdna(prop, NULL, "flags", FREESTYLE_LINESET_ENABLED);
 +      RNA_def_property_ui_text(prop, "Use", "Enable or disable this line set during stroke rendering");
 +      RNA_def_property_update(prop, NC_SCENE, NULL);
 +
 +      prop= RNA_def_property(srna, "select_by_visibility", PROP_BOOLEAN, PROP_NONE);
 +      RNA_def_property_boolean_sdna(prop, NULL, "selection", FREESTYLE_SEL_VISIBILITY);
 +      RNA_def_property_ui_text(prop, "Selection by Visibility", "Select feature edges based on visibility");
 +      RNA_def_property_update(prop, NC_SCENE, NULL);
 +
 +      prop= RNA_def_property(srna, "select_by_edge_types", PROP_BOOLEAN, PROP_NONE);
 +      RNA_def_property_boolean_sdna(prop, NULL, "selection", FREESTYLE_SEL_EDGE_TYPES);
 +      RNA_def_property_ui_text(prop, "Selection by Edge Types", "Select feature edges based on edge types");
 +      RNA_def_property_update(prop, NC_SCENE, NULL);
 +
 +      prop= RNA_def_property(srna, "select_by_group", PROP_BOOLEAN, PROP_NONE);
 +      RNA_def_property_boolean_sdna(prop, NULL, "selection", FREESTYLE_SEL_GROUP);
 +      RNA_def_property_ui_text(prop, "Selection by Group", "Select feature edges based on a group of objects");
 +      RNA_def_property_update(prop, NC_SCENE, NULL);
 +
 +      prop= RNA_def_property(srna, "select_by_image_border", PROP_BOOLEAN, PROP_NONE);
 +      RNA_def_property_boolean_sdna(prop, NULL, "selection", FREESTYLE_SEL_IMAGE_BORDER);
 +      RNA_def_property_ui_text(prop, "Selection by Image Border", "Select feature edges by image border (less memory consumption)");
 +      RNA_def_property_update(prop, NC_SCENE, NULL);
 +
 +      prop= RNA_def_property(srna, "select_by_face_marks", PROP_BOOLEAN, PROP_NONE);
 +      RNA_def_property_boolean_sdna(prop, NULL, "selection", FREESTYLE_SEL_FACE_MARK);
 +      RNA_def_property_ui_text(prop, "Selection by Face Marks", "Select feature edges by face marks");
 +      RNA_def_property_update(prop, NC_SCENE, NULL);
 +
 +      prop= RNA_def_property(srna, "edge_type_negation", PROP_ENUM, PROP_NONE);
 +      RNA_def_property_enum_bitflag_sdna(prop, NULL, "flags");
 +      RNA_def_property_enum_items(prop, edge_type_negation_items);
 +      RNA_def_property_ui_text(prop, "Edge Type Negation", "Set the negation operation for conditions on feature edge types");
 +      RNA_def_property_update(prop, NC_SCENE, NULL);
 +
 +      prop= RNA_def_property(srna, "edge_type_combination", PROP_ENUM, PROP_NONE);
 +      RNA_def_property_enum_bitflag_sdna(prop, NULL, "flags");
 +      RNA_def_property_enum_items(prop, edge_type_combination_items);
 +      RNA_def_property_ui_text(prop, "Edge Type Combination", "Set the combination operation for conditions on feature edge types");
 +      RNA_def_property_update(prop, NC_SCENE, NULL);
 +
 +      prop= RNA_def_property(srna, "group", PROP_POINTER, PROP_NONE);
 +      RNA_def_property_pointer_sdna(prop, NULL, "group");
 +      RNA_def_property_struct_type(prop, "Group");
 +      RNA_def_property_flag(prop, PROP_EDITABLE);
 +      RNA_def_property_ui_text(prop, "Group", "A group of objects based on which feature edges are selected");
 +      RNA_def_property_update(prop, NC_SCENE, NULL);
 +
 +      prop= RNA_def_property(srna, "group_negation", PROP_ENUM, PROP_NONE);
 +      RNA_def_property_enum_bitflag_sdna(prop, NULL, "flags");
 +      RNA_def_property_enum_items(prop, group_negation_items);
 +      RNA_def_property_ui_text(prop, "Group Negation", "Set the negation operation for conditions on feature edge types");
 +      RNA_def_property_update(prop, NC_SCENE, NULL);
 +
 +      prop= RNA_def_property(srna, "face_mark_negation", PROP_ENUM, PROP_NONE);
 +      RNA_def_property_enum_bitflag_sdna(prop, NULL, "flags");
 +      RNA_def_property_enum_items(prop, face_mark_negation_items);
 +      RNA_def_property_ui_text(prop, "Face Mark Negation", "Set the negation operation for the condition on face marks");
 +      RNA_def_property_update(prop, NC_SCENE, NULL);
 +
 +      prop= RNA_def_property(srna, "face_mark_condition", PROP_ENUM, PROP_NONE);
 +      RNA_def_property_enum_bitflag_sdna(prop, NULL, "flags");
 +      RNA_def_property_enum_items(prop, face_mark_condition_items);
 +      RNA_def_property_ui_text(prop, "Face Mark Condition", "Set a feature edge selection condition on face marks");
 +      RNA_def_property_update(prop, NC_SCENE, NULL);
 +
 +      prop= RNA_def_property(srna, "select_silhouette", PROP_BOOLEAN, PROP_NONE);
 +      RNA_def_property_boolean_sdna(prop, NULL, "edge_types", FREESTYLE_FE_SILHOUETTE);
 +      RNA_def_property_ui_text(prop, "Silhouette", "Select silhouette edges");
 +      RNA_def_property_update(prop, NC_SCENE, NULL);
 +
 +      prop= RNA_def_property(srna, "select_border", PROP_BOOLEAN, PROP_NONE);
 +      RNA_def_property_boolean_sdna(prop, NULL, "edge_types", FREESTYLE_FE_BORDER);
 +      RNA_def_property_ui_text(prop, "Border", "Select border edges");
 +      RNA_def_property_update(prop, NC_SCENE, NULL);
 +
 +      prop= RNA_def_property(srna, "select_crease", PROP_BOOLEAN, PROP_NONE);
 +      RNA_def_property_boolean_sdna(prop, NULL, "edge_types", FREESTYLE_FE_CREASE);
 +      RNA_def_property_ui_text(prop, "Crease", "Select crease edges");
 +      RNA_def_property_update(prop, NC_SCENE, NULL);
 +
 +      prop= RNA_def_property(srna, "select_ridge_valley", PROP_BOOLEAN, PROP_NONE);
 +      RNA_def_property_boolean_sdna(prop, NULL, "edge_types", FREESTYLE_FE_RIDGE_VALLEY);
 +      RNA_def_property_ui_text(prop, "Ridge & Valley", "Select ridges and valleys");
 +      RNA_def_property_update(prop, NC_SCENE, NULL);
 +
 +      prop= RNA_def_property(srna, "select_suggestive_contour", PROP_BOOLEAN, PROP_NONE);
 +      RNA_def_property_boolean_sdna(prop, NULL, "edge_types", FREESTYLE_FE_SUGGESTIVE_CONTOUR);
 +      RNA_def_property_ui_text(prop, "Suggestive Contour", "Select suggestive contours");
 +      RNA_def_property_update(prop, NC_SCENE, NULL);
 +
 +      prop= RNA_def_property(srna, "select_material_boundary", PROP_BOOLEAN, PROP_NONE);
 +      RNA_def_property_boolean_sdna(prop, NULL, "edge_types", FREESTYLE_FE_MATERIAL_BOUNDARY);
 +      RNA_def_property_ui_text(prop, "Material Boundary", "Select edges at material boundaries");
 +      RNA_def_property_update(prop, NC_SCENE, NULL);
 +
 +      prop= RNA_def_property(srna, "select_contour", PROP_BOOLEAN, PROP_NONE);
 +      RNA_def_property_boolean_sdna(prop, NULL, "edge_types", FREESTYLE_FE_CONTOUR);
 +      RNA_def_property_ui_text(prop, "Contour", "Select contours");
 +      RNA_def_property_update(prop, NC_SCENE, NULL);
 +
 +      prop= RNA_def_property(srna, "select_external_contour", PROP_BOOLEAN, PROP_NONE);
 +      RNA_def_property_boolean_sdna(prop, NULL, "edge_types", FREESTYLE_FE_EXTERNAL_CONTOUR);
 +      RNA_def_property_ui_text(prop, "External Contour", "Select external contours");
 +      RNA_def_property_update(prop, NC_SCENE, NULL);
 +
 +      prop= RNA_def_property(srna, "select_edge_mark", PROP_BOOLEAN, PROP_NONE);
 +      RNA_def_property_boolean_sdna(prop, NULL, "edge_types", FREESTYLE_FE_EDGE_MARK);
 +      RNA_def_property_ui_text(prop, "Edge Mark", "Select edge marks");
 +      RNA_def_property_update(prop, NC_SCENE, NULL);
 +
 +      prop= RNA_def_property(srna, "exclude_silhouette", PROP_BOOLEAN, PROP_NONE);
 +      RNA_def_property_boolean_sdna(prop, NULL, "exclude_edge_types", FREESTYLE_FE_SILHOUETTE);
 +      RNA_def_property_ui_text(prop, "Silhouette", "Exclude silhouette edges");
 +      RNA_def_property_ui_icon(prop, ICON_X, 0);
 +      RNA_def_property_update(prop, NC_SCENE, NULL);
 +
 +      prop= RNA_def_property(srna, "exclude_border", PROP_BOOLEAN, PROP_NONE);
 +      RNA_def_property_boolean_sdna(prop, NULL, "exclude_edge_types", FREESTYLE_FE_BORDER);
 +      RNA_def_property_ui_text(prop, "Border", "Exclude border edges");
 +      RNA_def_property_ui_icon(prop, ICON_X, 0);
 +      RNA_def_property_update(prop, NC_SCENE, NULL);
 +
 +      prop= RNA_def_property(srna, "exclude_crease", PROP_BOOLEAN, PROP_NONE);
 +      RNA_def_property_boolean_sdna(prop, NULL, "exclude_edge_types", FREESTYLE_FE_CREASE);
 +      RNA_def_property_ui_text(prop, "Crease", "Exclude crease edges");
 +      RNA_def_property_ui_icon(prop, ICON_X, 0);
 +      RNA_def_property_update(prop, NC_SCENE, NULL);
 +
 +      prop= RNA_def_property(srna, "exclude_ridge_valley", PROP_BOOLEAN, PROP_NONE);
 +      RNA_def_property_boolean_sdna(prop, NULL, "exclude_edge_types", FREESTYLE_FE_RIDGE_VALLEY);
 +      RNA_def_property_ui_text(prop, "Ridge & Valley", "Exclude ridges and valleys");
 +      RNA_def_property_ui_icon(prop, ICON_X, 0);
 +      RNA_def_property_update(prop, NC_SCENE, NULL);
 +
 +      prop= RNA_def_property(srna, "exclude_suggestive_contour", PROP_BOOLEAN, PROP_NONE);
 +      RNA_def_property_boolean_sdna(prop, NULL, "exclude_edge_types", FREESTYLE_FE_SUGGESTIVE_CONTOUR);
 +      RNA_def_property_ui_text(prop, "Suggestive Contour", "Exclude suggestive contours");
 +      RNA_def_property_ui_icon(prop, ICON_X, 0);
 +      RNA_def_property_update(prop, NC_SCENE, NULL);
 +
 +      prop= RNA_def_property(srna, "exclude_material_boundary", PROP_BOOLEAN, PROP_NONE);
 +      RNA_def_property_boolean_sdna(prop, NULL, "exclude_edge_types", FREESTYLE_FE_MATERIAL_BOUNDARY);
 +      RNA_def_property_ui_text(prop, "Material Boundary", "Exclude edges at material boundaries");
 +      RNA_def_property_ui_icon(prop, ICON_X, 0);
 +      RNA_def_property_update(prop, NC_SCENE, NULL);
 +
 +      prop= RNA_def_property(srna, "exclude_contour", PROP_BOOLEAN, PROP_NONE);
 +      RNA_def_property_boolean_sdna(prop, NULL, "exclude_edge_types", FREESTYLE_FE_CONTOUR);
 +      RNA_def_property_ui_text(prop, "Contour", "Exclude contours");
 +      RNA_def_property_ui_icon(prop, ICON_X, 0);
 +      RNA_def_property_update(prop, NC_SCENE, NULL);
 +
 +      prop= RNA_def_property(srna, "exclude_external_contour", PROP_BOOLEAN, PROP_NONE);
 +      RNA_def_property_boolean_sdna(prop, NULL, "exclude_edge_types", FREESTYLE_FE_EXTERNAL_CONTOUR);
 +      RNA_def_property_ui_text(prop, "External Contour", "Exclude external contours");
 +      RNA_def_property_ui_icon(prop, ICON_X, 0);
 +      RNA_def_property_update(prop, NC_SCENE, NULL);
 +
 +      prop= RNA_def_property(srna, "exclude_edge_mark", PROP_BOOLEAN, PROP_NONE);
 +      RNA_def_property_boolean_sdna(prop, NULL, "exclude_edge_types", FREESTYLE_FE_EDGE_MARK);
 +      RNA_def_property_ui_text(prop, "Edge Mark", "Exclude edge marks");
 +      RNA_def_property_ui_icon(prop, ICON_X, 0);
 +      RNA_def_property_update(prop, NC_SCENE, NULL);
 +
 +      prop= RNA_def_property(srna, "visibility", PROP_ENUM, PROP_NONE);
 +      RNA_def_property_enum_sdna(prop, NULL, "qi");
 +      RNA_def_property_enum_items(prop, visibility_items);
 +      RNA_def_property_ui_text(prop, "Visibility", "Determine how to use visibility for feature edge selection");
 +      RNA_def_property_update(prop, NC_SCENE, NULL);
 +
 +      prop= RNA_def_property(srna, "qi_start", PROP_INT, PROP_UNSIGNED);
 +      RNA_def_property_int_sdna(prop, NULL, "qi_start");
 +      RNA_def_property_range(prop, 0, INT_MAX);
 +      RNA_def_property_ui_text(prop, "Start", "First QI value of the QI range");
 +      RNA_def_property_update(prop, NC_SCENE, NULL);
 +
 +      prop= RNA_def_property(srna, "qi_end", PROP_INT, PROP_UNSIGNED);
 +      RNA_def_property_int_sdna(prop, NULL, "qi_end");
 +      RNA_def_property_range(prop, 0, INT_MAX);
 +      RNA_def_property_ui_text(prop, "End", "Last QI value of the QI range");
 +      RNA_def_property_update(prop, NC_SCENE, NULL);
 +
 +      /* FreestyleModuleSettings */
 +
 +      srna= RNA_def_struct(brna, "FreestyleModuleSettings", NULL);
 +      RNA_def_struct_sdna(srna, "FreestyleModuleConfig");
 +      RNA_def_struct_ui_text(srna, "Freestyle Module", "Style module configuration for specifying a style module");
 +
 +      prop= RNA_def_property(srna, "module_path", PROP_STRING, PROP_FILEPATH);
 +      RNA_def_property_string_sdna(prop, NULL, "module_path");
 +      RNA_def_property_ui_text(prop, "Module Path", "Path to a style module file");
 +      RNA_def_property_update(prop, NC_SCENE, NULL);
 +
 +      prop= RNA_def_property(srna, "use", PROP_BOOLEAN, PROP_NONE);
 +      RNA_def_property_boolean_sdna(prop, NULL, "is_displayed", 1);
 +      RNA_def_property_ui_text(prop, "Use", "Enable or disable this style module during stroke rendering");
 +      RNA_def_property_update(prop, NC_SCENE, NULL);
 +
 +      /* FreestyleSettings */
 +
 +      srna= RNA_def_struct(brna, "FreestyleSettings", NULL);
 +      RNA_def_struct_sdna(srna, "FreestyleConfig");
 +      RNA_def_struct_nested(brna, srna, "SceneRenderLayer");
 +      RNA_def_struct_ui_text(srna, "Frestyle Settings", "Freestyle settings for a SceneRenderLayer datablock");
 +
 +      prop= RNA_def_property(srna, "modules", PROP_COLLECTION, PROP_NONE);
 +      RNA_def_property_collection_sdna(prop, NULL, "modules", NULL);
 +      RNA_def_property_struct_type(prop, "FreestyleModuleSettings");
 +      RNA_def_property_ui_text(prop, "Style modules", "A list of style modules (to be applied from top to bottom)");
 +
 +      prop= RNA_def_property(srna, "mode", PROP_ENUM, PROP_NONE);
 +      RNA_def_property_enum_sdna(prop, NULL, "mode");
 +      RNA_def_property_enum_items(prop, freestyle_ui_mode_items);
 +      RNA_def_property_ui_text(prop, "Control Mode", "Select the Freestyle control mode");
 +      RNA_def_property_update(prop, NC_SCENE, NULL);
 +
 +      prop= RNA_def_property(srna, "raycasting_algorithm", PROP_ENUM, PROP_NONE);
 +      RNA_def_property_enum_sdna(prop, NULL, "raycasting_algorithm");
 +      RNA_def_property_enum_items(prop, freestyle_raycasting_algorithm_items);
 +      RNA_def_property_ui_text(prop, "Raycasting Algorithm", "Select the Freestyle raycasting algorithm");
 +      RNA_def_property_update(prop, NC_SCENE, NULL);
 +
 +      prop= RNA_def_property(srna, "use_culling", PROP_BOOLEAN, PROP_NONE);
 +      RNA_def_property_boolean_sdna(prop, NULL, "flags", FREESTYLE_CULLING);
 +      RNA_def_property_ui_text(prop, "Culling", "If enabled, out-of-view edges are ignored");
 +      RNA_def_property_update(prop, NC_SCENE, NULL);
 +
 +      prop= RNA_def_property(srna, "use_suggestive_contours", PROP_BOOLEAN, PROP_NONE);
 +      RNA_def_property_boolean_sdna(prop, NULL, "flags", FREESTYLE_SUGGESTIVE_CONTOURS_FLAG);
 +      RNA_def_property_ui_text(prop, "Suggestive Contours", "Enable suggestive contours");
 +      RNA_def_property_update(prop, NC_SCENE, NULL);
 +
 +      prop= RNA_def_property(srna, "use_ridges_and_valleys", PROP_BOOLEAN, PROP_NONE);
 +      RNA_def_property_boolean_sdna(prop, NULL, "flags", FREESTYLE_RIDGES_AND_VALLEYS_FLAG);
 +      RNA_def_property_ui_text(prop, "Ridges and Valleys", "Enable ridges and valleys");
 +      RNA_def_property_update(prop, NC_SCENE, NULL);
 +
 +      prop= RNA_def_property(srna, "use_material_boundaries", PROP_BOOLEAN, PROP_NONE);
 +      RNA_def_property_boolean_sdna(prop, NULL, "flags", FREESTYLE_MATERIAL_BOUNDARIES_FLAG);
 +      RNA_def_property_ui_text(prop, "Material Boundaries", "Enable material boundaries");
 +      RNA_def_property_update(prop, NC_SCENE, NULL);
 +
 +      prop= RNA_def_property(srna, "use_smoothness", PROP_BOOLEAN, PROP_NONE);
 +      RNA_def_property_boolean_sdna(prop, NULL, "flags", FREESTYLE_FACE_SMOOTHNESS_FLAG);
 +      RNA_def_property_ui_text(prop, "Face Smoothness", "Take face smoothness into account in view map calculation");
 +      RNA_def_property_update(prop, NC_SCENE, NULL);
 +
 +      prop= RNA_def_property(srna, "use_advanced_options", PROP_BOOLEAN, PROP_NONE);
 +      RNA_def_property_boolean_sdna(prop, NULL, "flags", FREESTYLE_ADVANCED_OPTIONS_FLAG);
 +      RNA_def_property_ui_text(prop, "Advanced Edge Detection Options", "Enable advanced edge detection options (sphere radius and Kr derivative epsilon)");
 +      RNA_def_property_update(prop, NC_SCENE, NULL);
 +
 +      prop= RNA_def_property(srna, "sphere_radius", PROP_FLOAT, PROP_NONE);
 +      RNA_def_property_float_sdna(prop, NULL, "sphere_radius");
 +      RNA_def_property_range(prop, 0.0, 1000.0);
 +      RNA_def_property_ui_text(prop, "Sphere Radius", "Sphere radius for computing curvatures");
 +      RNA_def_property_update(prop, NC_SCENE, NULL);
 +
 +      prop= RNA_def_property(srna, "kr_derivative_epsilon", PROP_FLOAT, PROP_NONE);
 +      RNA_def_property_float_sdna(prop, NULL, "dkr_epsilon");
 +      RNA_def_property_range(prop, -1000.0, 1000.0);
 +      RNA_def_property_ui_text(prop, "Kr Derivative Epsilon", "Kr derivative epsilon for computing suggestive contours");
 +      RNA_def_property_update(prop, NC_SCENE, NULL);
 +
 +      prop= RNA_def_property(srna, "crease_angle", PROP_FLOAT, PROP_NONE);
 +      RNA_def_property_float_sdna(prop, NULL, "crease_angle");
 +      RNA_def_property_range(prop, 0.0, 180.0);
 +      RNA_def_property_ui_text(prop, "Crease Angle", "Angular threshold in degrees (between 0 and 180) for detecting crease edges");
 +      RNA_def_property_update(prop, NC_SCENE, NULL);
 +
 +      prop= RNA_def_property(srna, "linesets", PROP_COLLECTION, PROP_NONE);
 +      RNA_def_property_collection_sdna(prop, NULL, "linesets", NULL);
 +      RNA_def_property_struct_type(prop, "FreestyleLineSet");
 +      RNA_def_property_ui_text(prop, "Line Sets", "");
 +      rna_def_freestyle_linesets(brna, prop);
 +}
 +
  static void rna_def_scene_game_recast_data(BlenderRNA *brna)
  {
        StructRNA *srna;
@@@ -3188,23 -2766,12 +3192,23 @@@ static void rna_def_scene_game_data(Ble
  static void rna_def_scene_render_layer(BlenderRNA *brna)
  {
        StructRNA *srna;
 +      PropertyRNA *prop;
  
        srna = RNA_def_struct(brna, "SceneRenderLayer", NULL);
        RNA_def_struct_ui_text(srna, "Scene Render Layer", "Render layer");
        RNA_def_struct_ui_icon(srna, ICON_RENDERLAYERS);
  
        rna_def_render_layer_common(srna, 1);
 +
 +      /* Freestyle */
 +
 +      rna_def_freestyle_settings(brna);
 +
 +      prop= RNA_def_property(srna, "freestyle_settings", PROP_POINTER, PROP_NONE);
 +      RNA_def_property_flag(prop, PROP_NEVER_NULL);
 +      RNA_def_property_pointer_sdna(prop, NULL, "freestyleConfig");
 +      RNA_def_property_struct_type(prop, "FreestyleSettings");
 +      RNA_def_property_ui_text(prop, "Freestyle Settings", "");
  }
  
  /* curve.splines */
@@@ -3249,7 -2816,8 +3253,8 @@@ static void rna_def_render_layers(Blend
        RNA_def_function_ui_description(func, "Remove a render layer");
        RNA_def_function_flag(func, FUNC_USE_MAIN | FUNC_USE_REPORTS | FUNC_USE_SELF_ID);
        parm = RNA_def_pointer(func, "layer", "SceneRenderLayer", "", "Timeline marker to remove");
-       RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL);
+       RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL | PROP_RNAPTR);
+       RNA_def_property_clear_flag(parm, PROP_THICK_WRAP);
  }
  
  /* use for render output and image save operator,
@@@ -3787,11 -3355,6 +3792,11 @@@ static void rna_def_scene_render_data(B
                {0, NULL, 0, NULL, NULL}
        };
  
 +      static EnumPropertyItem freestyle_thickness_items[] = {
 +              {R_LINE_THICKNESS_ABSOLUTE, "ABSOLUTE", 0, "Absolute", "Specify unit line thickness in pixels"},
 +              {R_LINE_THICKNESS_RELATIVE, "RELATIVE", 0, "Relative", "Unit line thickness is scaled by the proportion of the present vertical image resolution to 480 pixels"},
 +              {0, NULL, 0, NULL, NULL}};
 +
        rna_def_scene_ffmpeg_settings(brna);
  #ifdef WITH_QUICKTIME
        rna_def_scene_quicktime_settings(brna);
        RNA_def_property_ui_text(prop, "Edge Color", "Edge color");
        RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL);
        
 +      prop= RNA_def_property(srna, "use_freestyle", PROP_BOOLEAN, PROP_NONE);
 +      RNA_def_property_boolean_sdna(prop, NULL, "mode", R_EDGE_FRS);
 +      RNA_def_property_ui_text(prop, "Edge", "Draw stylized strokes using Freestyle");
 +      RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, NULL);
 +
        /* threads */
        prop = RNA_def_property(srna, "threads", PROP_INT, PROP_NONE);
        RNA_def_property_int_sdna(prop, NULL, "threads");
        RNA_def_property_boolean_sdna(prop, NULL, "simplify_flag", R_SIMPLE_NO_TRIANGULATE);
        RNA_def_property_ui_text(prop, "Skip Quad to Triangles", "Disable non-planar quads being triangulated");
  
 +      /* Freestyle line thickness options */
 +      prop = RNA_def_property(srna, "line_thickness_mode", PROP_ENUM, PROP_NONE);
 +      RNA_def_property_enum_sdna(prop, NULL, "line_thickness_mode");
 +      RNA_def_property_enum_items(prop, freestyle_thickness_items);
 +      RNA_def_property_ui_text(prop, "Line Thickness Mode", "Line thickness mode for Freestyle line drawing");
 +
 +      prop = RNA_def_property(srna, "unit_line_thickness", PROP_FLOAT, PROP_NONE);
 +      RNA_def_property_float_sdna(prop, NULL, "unit_line_thickness");
 +      RNA_def_property_range(prop, 0.f, 10000.f);
 +      RNA_def_property_ui_text(prop, "Unit Line Thickness", "Unit line thickness in pixels");
 +
        /* Scene API */
        RNA_api_scene_render(srna);
  }
@@@ -4581,7 -4128,8 +4586,8 @@@ static void rna_def_timeline_markers(Bl
        RNA_def_function_ui_description(func, "Remove a timeline marker");
        RNA_def_function_flag(func, FUNC_USE_REPORTS);
        parm = RNA_def_pointer(func, "marker", "TimelineMarker", "", "Timeline marker to remove");
-       RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL);
+       RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL | PROP_RNAPTR);
+       RNA_def_property_clear_flag(parm, PROP_THICK_WRAP);
  
        func = RNA_def_function(srna, "clear", "rna_TimeLine_clear");
        RNA_def_function_ui_description(func, "Remove all timeline markers");
index ecb2bf71cb2130f7dd83b993c88ba6c08d642d37,962a92223eb6d98a25e8442d7cee059c7b23429d..70daba9790f4ccd73c6a96a349f10d8065356396
@@@ -958,15 -958,17 +958,17 @@@ static BGpic *rna_BackgroundImage_new(V
        return bgpic;
  }
  
- static void rna_BackgroundImage_remove(View3D *v3d, ReportList *reports, BGpic *bgpic)
+ static void rna_BackgroundImage_remove(View3D *v3d, ReportList *reports, PointerRNA *bgpic_ptr)
  {
+       BGpic *bgpic = bgpic_ptr->data;
        if (BLI_findindex(&v3d->bgpicbase, bgpic) == -1) {
                BKE_report(reports, RPT_ERROR, "Background image cannot be removed");
        }
-       else {
-               ED_view3D_background_image_remove(v3d, bgpic);
-               WM_main_add_notifier(NC_SPACE | ND_SPACE_VIEW3D, v3d);
-       }
+       ED_view3D_background_image_remove(v3d, bgpic);
+       RNA_POINTER_INVALIDATE(bgpic_ptr);
+       WM_main_add_notifier(NC_SPACE | ND_SPACE_VIEW3D, v3d);
  }
  
  static void rna_BackgroundImage_clear(View3D *v3d)
@@@ -1451,7 -1453,8 +1453,8 @@@ static void rna_def_backgroundImages(Bl
        RNA_def_function_ui_description(func, "Remove background image");
        RNA_def_function_flag(func, FUNC_USE_REPORTS);
        parm = RNA_def_pointer(func, "image", "BackgroundImage", "", "Image displayed as viewport background");
-       RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL);
+       RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL | PROP_RNAPTR);
+       RNA_def_property_clear_flag(parm, PROP_THICK_WRAP);
  
        func = RNA_def_function(srna, "clear", "rna_BackgroundImage_clear");
        RNA_def_function_ui_description(func, "Remove all background images");
@@@ -1911,7 -1914,6 +1914,7 @@@ static void rna_def_space_buttons(Blend
        static EnumPropertyItem buttons_context_items[] = {
                {BCONTEXT_SCENE, "SCENE", ICON_SCENE, "Scene", "Scene"},
                {BCONTEXT_RENDER, "RENDER", ICON_SCENE_DATA, "Render", "Render"},
 +              {BCONTEXT_RENDER_LAYER, "RENDER_LAYER", ICON_RENDERLAYERS, "Render Layers", "Render Layers"},
                {BCONTEXT_WORLD, "WORLD", ICON_WORLD, "World", "World"},
                {BCONTEXT_OBJECT, "OBJECT", ICON_OBJECT_DATA, "Object", "Object"},
                {BCONTEXT_CONSTRAINT, "CONSTRAINT", ICON_CONSTRAINT, "Constraints", "Constraints"},
index fc30c02341a7bd7c1cfabab73151543530587ffb,415d5308d85569aa9c2526b80e230e13063a7523..c49f67d49fe08f7475fc629da3570be213b80fc1
---