Merge branch 'master' into free-refcount-ids
authorBastien Montagne <montagne29@wanadoo.fr>
Mon, 5 Oct 2015 10:05:00 +0000 (12:05 +0200)
committerBastien Montagne <montagne29@wanadoo.fr>
Mon, 5 Oct 2015 10:05:00 +0000 (12:05 +0200)
71 files changed:
source/blender/blenkernel/BKE_action.h
source/blender/blenkernel/BKE_armature.h
source/blender/blenkernel/BKE_brush.h
source/blender/blenkernel/BKE_camera.h
source/blender/blenkernel/BKE_curve.h
source/blender/blenkernel/BKE_font.h
source/blender/blenkernel/BKE_gpencil.h
source/blender/blenkernel/BKE_group.h
source/blender/blenkernel/BKE_image.h
source/blender/blenkernel/BKE_key.h
source/blender/blenkernel/BKE_lamp.h
source/blender/blenkernel/BKE_lattice.h
source/blender/blenkernel/BKE_linestyle.h
source/blender/blenkernel/BKE_mask.h
source/blender/blenkernel/BKE_material.h
source/blender/blenkernel/BKE_mball.h
source/blender/blenkernel/BKE_mesh.h
source/blender/blenkernel/BKE_movieclip.h
source/blender/blenkernel/BKE_node.h
source/blender/blenkernel/BKE_object.h
source/blender/blenkernel/BKE_paint.h
source/blender/blenkernel/BKE_particle.h
source/blender/blenkernel/BKE_scene.h
source/blender/blenkernel/BKE_screen.h
source/blender/blenkernel/BKE_sound.h
source/blender/blenkernel/BKE_speaker.h
source/blender/blenkernel/BKE_text.h
source/blender/blenkernel/BKE_texture.h
source/blender/blenkernel/BKE_world.h
source/blender/blenkernel/intern/action.c
source/blender/blenkernel/intern/armature.c
source/blender/blenkernel/intern/brush.c
source/blender/blenkernel/intern/camera.c
source/blender/blenkernel/intern/curve.c
source/blender/blenkernel/intern/font.c
source/blender/blenkernel/intern/gpencil.c
source/blender/blenkernel/intern/group.c
source/blender/blenkernel/intern/image.c
source/blender/blenkernel/intern/key.c
source/blender/blenkernel/intern/lamp.c
source/blender/blenkernel/intern/lattice.c
source/blender/blenkernel/intern/library.c
source/blender/blenkernel/intern/linestyle.c
source/blender/blenkernel/intern/mask.c
source/blender/blenkernel/intern/material.c
source/blender/blenkernel/intern/mball.c
source/blender/blenkernel/intern/mesh.c
source/blender/blenkernel/intern/movieclip.c
source/blender/blenkernel/intern/node.c
source/blender/blenkernel/intern/object.c
source/blender/blenkernel/intern/paint.c
source/blender/blenkernel/intern/particle.c
source/blender/blenkernel/intern/scene.c
source/blender/blenkernel/intern/screen.c
source/blender/blenkernel/intern/sequencer.c
source/blender/blenkernel/intern/sound.c
source/blender/blenkernel/intern/speaker.c
source/blender/blenkernel/intern/text.c
source/blender/blenkernel/intern/texture.c
source/blender/blenkernel/intern/world.c
source/blender/compositor/operations/COM_MaskOperation.cpp
source/blender/editors/gpencil/gpencil_undo.c
source/blender/editors/mesh/editmesh_utils.c
source/blender/editors/mesh/meshtools.c
source/blender/editors/render/render_preview.c
source/blender/editors/screen/screen_edit.c
source/blender/editors/sound/sound_ops.c
source/blender/editors/space_node/node_group.c
source/blender/makesrna/intern/rna_main_api.c
source/blender/nodes/shader/node_shader_tree.c
source/blender/render/intern/source/render_texture.c

index 3fceef5d95dd5f86264c7fbb7ac237c0f8b72439..e9adec8f3b23ffcd011c136024413ea2fc1fe980 100644 (file)
@@ -61,7 +61,7 @@ struct bAction *add_empty_action(struct Main *bmain, const char name[]);
 struct bAction *BKE_action_copy(struct bAction *src);
 
 /* Deallocate all of the Action's data, but not the Action itself */
-void BKE_action_free(struct bAction *act);
+void BKE_action_free(struct bAction *act, const bool do_id_user);
 
 // XXX is this needed?
 void BKE_action_make_local(struct bAction *act);
index e1885e46b24d6e0b771e59aebccee34a196cf0e8..80066cdc9a2bf019a30b6a15c9b7258f0a240471 100644 (file)
@@ -73,7 +73,7 @@ extern "C" {
 struct bArmature *BKE_armature_add(struct Main *bmain, const char *name);
 struct bArmature *BKE_armature_from_object(struct Object *ob);
 void BKE_armature_bonelist_free(struct ListBase *lb);
-void BKE_armature_free(struct bArmature *arm);
+void BKE_armature_free(struct bArmature *arm, const bool do_id_user);
 void BKE_armature_make_local(struct bArmature *arm);
 struct bArmature *BKE_armature_copy(struct bArmature *arm);
 
index aff3fb08df66734fb57a551cb483ece40d571f03..d2c8f97602ca994724fb50e30e4bbe2838629258 100644 (file)
@@ -44,7 +44,7 @@ struct Brush *BKE_brush_add(struct Main *bmain, const char *name, short ob_mode)
 struct Brush *BKE_brush_first_search(struct Main *bmain, short ob_mode);
 struct Brush *BKE_brush_copy(struct Brush *brush);
 void BKE_brush_make_local(struct Brush *brush);
-void BKE_brush_free(struct Brush *brush);
+void BKE_brush_free(struct Brush *brush, const bool do_id_user);
 
 void BKE_brush_sculpt_reset(struct Brush *brush);
 
index aacb7a4066bb742037eeae33eaf6496434665e3e..3dcda194cacb1e1d5e139ac5dadba94593b458a1 100644 (file)
@@ -53,7 +53,7 @@ struct GPUFXSettings;
 void *BKE_camera_add(struct Main *bmain, const char *name);
 struct Camera *BKE_camera_copy(struct Camera *cam);
 void BKE_camera_make_local(struct Camera *cam);
-void BKE_camera_free(struct Camera *ca);
+void BKE_camera_free(struct Camera *ca, const bool do_id_user);
 
 /* Camera Usage */
 
index a03dd2871467d0d617971c215bb67f9e8e4dcb4d..17836ced2baeaaa25923898f3a3aeff1b3c5459a 100644 (file)
@@ -66,8 +66,7 @@ typedef struct CurveCache {
 #define CU_DO_2DFILL(cu)  ((((cu)->flag & CU_3D) == 0) && (((cu)->flag & (CU_FRONT | CU_BACK)) != 0))
 
 /* ** Curve ** */
-void BKE_curve_unlink(struct Curve *cu);
-void BKE_curve_free(struct Curve *cu);
+void BKE_curve_free(struct Curve *cu, const bool do_id_user);
 void BKE_curve_editfont_free(struct Curve *cu);
 struct Curve *BKE_curve_add(struct Main *bmain, const char *name, int type);
 struct Curve *BKE_curve_copy(struct Curve *cu);
index 137670215cca2009f9485ab255a720e6384c3e6f..18bc22b87f09f8ef663fef200e1813ae7e393560 100644 (file)
@@ -78,7 +78,7 @@ bool BKE_vfont_is_builtin(struct VFont *vfont);
 void BKE_vfont_builtin_register(void *mem, int size);
 
 void BKE_vfont_free_data(struct VFont *vfont);
-void BKE_vfont_free(struct VFont *sc); 
+void BKE_vfont_free(struct VFont *sc, const bool do_id_user);
 struct VFont *BKE_vfont_builtin_get(void);
 struct VFont *BKE_vfont_load(struct Main *bmain, const char *name);
 
index 084c5527f211076bdb2fdb5ce37a3c64a0304242..2d287172e90c4ee1a072243d78f08f1fd02b2184 100644 (file)
@@ -42,7 +42,7 @@ struct bGPDstroke;
 bool free_gpencil_strokes(struct bGPDframe *gpf);
 void free_gpencil_frames(struct bGPDlayer *gpl);
 void free_gpencil_layers(struct ListBase *list);
-void BKE_gpencil_free(struct bGPdata *gpd);
+void BKE_gpencil_free(struct bGPdata *gpd, const bool do_id_user);
 
 void gpencil_stroke_sync_selection(struct bGPDstroke *gps);
 
index d856e90a340fc39033e410e5a7e951f2cc1d1b52..d27bdd32a586a2b3e961e872e36d60ab1440a0dd 100644 (file)
@@ -40,7 +40,7 @@ struct Main;
 struct Object;
 struct Scene;
 
-void          BKE_group_free(struct Group *group);
+void          BKE_group_free(struct Group *group, const bool do_id_user);
 void          BKE_group_unlink(struct Group *group);
 struct Group *BKE_group_add(struct Main *bmain, const char *name);
 struct Group *BKE_group_copy(struct Group *group);
index 94afc8a16eadbd652273f1e408b6c07f432b2112..baea56ac751bb6c60e6149f7241e4ae098fb27f2 100644 (file)
@@ -59,7 +59,7 @@ void    BKE_image_free_packedfiles(struct Image *image);
 void    BKE_image_free_views(struct Image *image);
 void    BKE_image_free_buffers(struct Image *image);
 /* call from library */
-void    BKE_image_free(struct Image *image);
+void    BKE_image_free(struct Image *image, const bool do_id_user);
 
 typedef void (StampCallback)(void *data, const char *propname, char *propvalue, int len);
 
index abe12282a1b976fc30f0caa0dfcb2b67db18c8ae..5354823b3d7472bd0d3deca4afb7f7c70048f86b 100644 (file)
@@ -47,7 +47,7 @@ struct WeightsArrayCache;
 extern "C" {
 #endif
 
-void        BKE_key_free(struct Key *sc);
+void        BKE_key_free(struct Key *sc, const bool do_id_user);
 void        BKE_key_free_nolib(struct Key *key);
 struct Key *BKE_key_add(struct ID *id);
 struct Key *BKE_key_copy(struct Key *key);
index fb2c4da91ea344c873d7bc48cfc4d9b6879a62b6..dce0b7c5fdcb74ef43a99949bdd6a538c0f647ad 100644 (file)
@@ -46,7 +46,7 @@ struct Lamp *BKE_lamp_add(struct Main *bmain, const char *name) ATTR_WARN_UNUSED
 struct Lamp *BKE_lamp_copy(struct Lamp *la) ATTR_WARN_UNUSED_RESULT;
 struct Lamp *localize_lamp(struct Lamp *la) ATTR_WARN_UNUSED_RESULT;
 void BKE_lamp_make_local(struct Lamp *la);
-void BKE_lamp_free(struct Lamp *la);
+void BKE_lamp_free(struct Lamp *la, const bool do_id_user);
 
 void lamp_drivers_update(struct Scene *scene, struct Lamp *la, float ctime);
 
index 677d8e342290c955d05070cc00db652bc77b8a66..adf37c6d429f43b53f7c737fb475a9ab9afa15bf 100644 (file)
@@ -47,7 +47,7 @@ struct MDeformVert;
 void BKE_lattice_resize(struct Lattice *lt, int u, int v, int w, struct Object *ltOb);
 struct Lattice *BKE_lattice_add(struct Main *bmain, const char *name);
 struct Lattice *BKE_lattice_copy(struct Lattice *lt);
-void BKE_lattice_free(struct Lattice *lt);
+void BKE_lattice_free(struct Lattice *lt, const bool do_id_user);
 void BKE_lattice_make_local(struct Lattice *lt);
 void calc_lat_fudu(int flag, int res, float *r_fu, float *r_du);
 
index e77b4f5e8fe5fb8104fee57b5e6f4ec1d32ff3fe..8d6a860cd02260484d39a0bab447eabe81285124 100644 (file)
@@ -50,7 +50,7 @@ struct ColorBand;
 struct bContext;
 
 FreestyleLineStyle *BKE_linestyle_new(struct Main *bmain, const char *name);
-void                BKE_linestyle_free(FreestyleLineStyle *linestyle);
+void                BKE_linestyle_free(FreestyleLineStyle *linestyle, const bool do_id_user);
 FreestyleLineStyle *BKE_linestyle_copy(struct Main *bmain, FreestyleLineStyle *linestyle);
 
 FreestyleLineStyle *BKE_linestyle_active_from_scene(struct Scene *scene);
index 2f85db4d5d215a165d89f65c1b8186ef19c4db8e..cc74869acfbbe25ac396d60289ae462f9def75ff 100644 (file)
@@ -123,8 +123,8 @@ struct Mask *BKE_mask_new(struct Main *bmain, const char *name);
 struct Mask *BKE_mask_copy_nolib(struct Mask *mask);
 struct Mask *BKE_mask_copy(struct Mask *mask);
 
-void BKE_mask_free_nolib(struct Mask *mask);
-void BKE_mask_free(struct Main *bmain, struct Mask *mask);
+void BKE_mask_free(struct Mask *mask, const bool do_id_user);
+void BKE_mask_unlink(struct Main *bmain, struct Mask *mask);
 
 void BKE_mask_coord_from_frame(float r_co[2], const float co[2], const float frame_size[2]);
 void BKE_mask_coord_from_movieclip(struct MovieClip *clip, struct MovieClipUser *user, float r_co[2], const float co[2]);
index a3c61f44ff2acb2cf2a69c0ad3b5b9941646a026..6804838ddf83d9f1b7e3fa71759f1922031d50b4 100644 (file)
@@ -45,8 +45,7 @@ struct Scene;
 /* materials */
 
 void init_def_material(void);
-void BKE_material_free(struct Material *sc); 
-void BKE_material_free_ex(struct Material *ma, bool do_id_user);
+void BKE_material_free(struct Material *ma, const bool do_id_user);
 void test_object_materials(struct Main *bmain, struct ID *id);
 void BKE_material_resize_object(struct Object *ob, const short totcol, bool do_id_user);
 void init_material(struct Material *ma);
index 62cd50099fd0d50a36b518ebc65dd8e9e831d2e8..02c53280551fe3d5478f7e5be144df420303cd67 100644 (file)
@@ -38,8 +38,7 @@ struct Object;
 struct Scene;
 struct MetaElem;
 
-void BKE_mball_unlink(struct MetaBall *mb);
-void BKE_mball_free(struct MetaBall *mb);
+void BKE_mball_free(struct MetaBall *mb, const bool do_id_user);
 struct MetaBall *BKE_mball_add(struct Main *bmain, const char *name);
 struct MetaBall *BKE_mball_copy(struct MetaBall *mb);
 
index a27688c1c613900fcbac0a9d8750ed21d9a175a8..805c5620d489b9a6bdeb739314ac34f0fa6b67ca 100644 (file)
@@ -80,8 +80,7 @@ int poly_get_adj_loops_from_vert(
 
 int BKE_mesh_edge_other_vert(const struct MEdge *e, int v);
 
-void BKE_mesh_unlink(struct Mesh *me);
-void BKE_mesh_free(struct Mesh *me, int unlink);
+void BKE_mesh_free(struct Mesh *me, const bool do_id_user);
 struct Mesh *BKE_mesh_add(struct Main *bmain, const char *name);
 struct Mesh *BKE_mesh_copy_ex(struct Main *bmain, struct Mesh *me);
 struct Mesh *BKE_mesh_copy(struct Mesh *me);
index 7d7675270dec0353cf6c74d661dfb16c08f0cf2a..356e8ad3657628239c8dad5effa813fe571fe7cd 100644 (file)
@@ -39,7 +39,7 @@ struct MovieClipScopes;
 struct MovieClipUser;
 struct MovieDistortion;
 
-void BKE_movieclip_free(struct MovieClip *clip);
+void BKE_movieclip_free(struct MovieClip *clip, const bool do_id_user);
 void BKE_movieclip_unlink(struct Main *bmain, struct MovieClip *clip);
 
 struct MovieClip *BKE_movieclip_file_add(struct Main *bmain, const char *name);
index b97bf203a7c625262e1b21c46e81b5203885bcd2..78a239641dd0c04f40f47906ba706b97d4331a18 100644 (file)
@@ -340,8 +340,7 @@ void ntreeSetTypes(const struct bContext *C, struct bNodeTree *ntree);
 struct bNodeTree *ntreeAddTree(struct Main *bmain, const char *name, const char *idname);
 
 /* copy/free funcs, need to manage ID users */
-void              ntreeFreeTree_ex(struct bNodeTree *ntree, const bool do_id_user);
-void              ntreeFreeTree(struct bNodeTree *ntree);
+void              ntreeFreeTree(struct bNodeTree *ntree, const bool do_id_user);
 struct bNodeTree *ntreeCopyTree_ex(struct bNodeTree *ntree, struct Main *bmain, const bool do_id_user);
 struct bNodeTree *ntreeCopyTree(struct bNodeTree *ntree);
 void              ntreeSwitchID_ex(struct bNodeTree *ntree, struct ID *sce_from, struct ID *sce_to, const bool do_id_user);
index 6c5081d1ea942498c0bd71eb43a13bb75e195a3c..6125f5c18bd51040857d5d53d86f9c4b250a85da 100644 (file)
@@ -64,8 +64,7 @@ void BKE_object_free_bulletsoftbody(struct Object *ob);
 void BKE_object_free_curve_cache(struct Object *ob);
 void BKE_object_update_base_layer(struct Scene *scene, struct Object *ob);
 
-void BKE_object_free(struct Object *ob);
-void BKE_object_free_ex(struct Object *ob, bool do_id_user);
+void BKE_object_free(struct Object *ob, const bool do_id_user);
 void BKE_object_free_derived_caches(struct Object *ob);
 void BKE_object_free_caches(struct Object *object);
 
index bf1cfb263eb2568aa90a2bced9b7e38691e00b59..a2e59e4e913a165d5464a65ad1c53d41f792e337 100644 (file)
@@ -97,7 +97,7 @@ void BKE_paint_reset_overlay_invalid(OverlayControlFlags flag);
 void BKE_paint_set_overlay_override(enum OverlayFlags flag);
 
 /* palettes */
-void                 BKE_palette_free(struct Palette *palette);
+void                 BKE_palette_free(struct Palette *palette, const bool do_id_user);
 struct Palette      *BKE_palette_add(struct Main *bmain, const char *name);
 struct PaletteColor *BKE_palette_color_add(struct Palette *palette);
 bool                 BKE_palette_is_empty(const struct Palette *palette);
@@ -106,7 +106,7 @@ void                 BKE_palette_clear(struct Palette *palette);
 
 /* paint curves */
 struct PaintCurve *BKE_paint_curve_add(struct Main *bmain, const char *name);
-void BKE_paint_curve_free(struct PaintCurve *pc);
+void BKE_paint_curve_free(struct PaintCurve *pc, const bool do_id_user);
 
 void BKE_paint_init(struct Scene *sce, PaintMode mode, const char col[3]);
 void BKE_paint_free(struct Paint *p);
index 89cfb3a2aac31eff564218cdb19e9e1977f3b91a..a71c4e533f97220e72590e55dc0ff102d91720a7 100644 (file)
@@ -297,7 +297,7 @@ void psys_check_group_weights(struct ParticleSettings *part);
 int psys_uses_gravity(struct ParticleSimulationData *sim);
 
 /* free */
-void BKE_particlesettings_free(struct ParticleSettings *part);
+void BKE_particlesettings_free(struct ParticleSettings *part, const bool do_id_user);
 void psys_free_path_cache(struct ParticleSystem *psys, struct PTCacheEdit *edit);
 void psys_free(struct Object *ob, struct ParticleSystem *psys);
 
index 027bdbbbe58aa1af21b26110aae6919fb0c62440..a18c1e7cdd2b60f7f6a04fff4d0fef749bf23c98 100644 (file)
@@ -66,7 +66,7 @@ struct Base *_setlooper_base_step(struct Scene **sce_iter, struct Base *base);
 void free_avicodecdata(struct AviCodecData *acd);
 void free_qtcodecdata(struct QuicktimeCodecData *acd);
 
-void BKE_scene_free(struct Scene *sce);
+void BKE_scene_free(struct Scene *sce, const bool do_id_user);
 struct Scene *BKE_scene_add(struct Main *bmain, const char *name);
 
 /* base functions */
index 48616418e677640c04188dc7da0744f2138e07ef..c3a0223e2a29ec6d7f6d985c270156dede2c27fb 100644 (file)
@@ -307,7 +307,7 @@ float BKE_screen_view3d_zoom_to_fac(float camzoom);
 float BKE_screen_view3d_zoom_from_fac(float zoomfac);
 
 /* screen */
-void BKE_screen_free(struct bScreen *sc); 
+void BKE_screen_free(struct bScreen *sc, const bool do_id_user);
 unsigned int BKE_screen_visible_layers(struct bScreen *screen, struct Scene *scene);
 
 #endif
index e68be701b6114528e3b7ee20674f4d638a30b91d..47123169cd1500e7fcde1a81b40671baf0f4d2b4 100644 (file)
@@ -70,15 +70,13 @@ struct bSound *BKE_sound_new_buffer(struct Main *bmain, struct bSound *source);
 struct bSound *BKE_sound_new_limiter(struct Main *bmain, struct bSound *source, float start, float end);
 #endif
 
-void BKE_sound_delete(struct Main *bmain, struct bSound *sound);
-
 void BKE_sound_cache(struct bSound *sound);
 
 void BKE_sound_delete_cache(struct bSound *sound);
 
 void BKE_sound_load(struct Main *main, struct bSound *sound);
 
-void BKE_sound_free(struct bSound *sound);
+void BKE_sound_free(struct bSound *sound, const bool do_id_user);
 
 #if defined(__AUD_C_API_H__) || defined(WITH_SYSTEM_AUDASPACE)
 AUD_Device *BKE_sound_mixdown(struct Scene *scene, AUD_DeviceSpecs specs, int start, float volume);
index 5d93b9844ab8f71223fd448bd345268a911c2518..571e6e7cb393e1741000e9fe691c6179e7a6c0d6 100644 (file)
@@ -33,6 +33,6 @@ struct Main;
 void *BKE_speaker_add(struct Main *bmain, const char *name);
 struct Speaker *BKE_speaker_copy(struct Speaker *spk);
 void BKE_speaker_make_local(struct Speaker *spk);
-void BKE_speaker_free(struct Speaker *spk);
+void BKE_speaker_free(struct Speaker *spk, const bool do_id_user);
 
 #endif
index a5a59d14c92e26bd22c488d9efb942a12a63893d..6350563adc58a704483b30f0617086d048332edf 100644 (file)
@@ -41,7 +41,7 @@ struct Main;
 struct Text;
 struct TextLine;
 
-void                   BKE_text_free           (struct Text *text);
+void                   BKE_text_free           (struct Text *text, const bool do_id_user);
 void                   txt_set_undostate       (int u);
 int                    txt_get_undostate       (void);
 struct Text    *BKE_text_add   (struct Main *bmain, const char *name);
index 95918b9ca0be6dc29ead1b773d195a8b88cff00f..504de22295a8dda0fd5c0577e139727c35149ea9 100644 (file)
@@ -67,7 +67,7 @@ struct CBData *colorband_element_add(struct ColorBand *coba, float position);
 int colorband_element_remove(struct ColorBand *coba, int index);
 void colorband_update_sort(struct ColorBand *coba);
 
-void         BKE_texture_free(struct Tex *tex);
+void         BKE_texture_free(struct Tex *tex, const bool do_id_user);
 void         BKE_texture_default(struct Tex *tex);
 struct Tex  *BKE_texture_copy(struct Tex *tex);
 struct Tex  *BKE_texture_add(struct Main *bmain, const char *name);
index 7f4ba6c615ee4f2fcbc759382d15f4c577db156f..a77a5b06817ff9e4fb58c4eed161785636751ff9 100644 (file)
@@ -36,8 +36,7 @@
 struct Main;
 struct World;
 
-void BKE_world_free(struct World *sc);
-void BKE_world_free_ex(struct World *sc, bool do_id_user);
+void BKE_world_free(struct World *sc, const bool do_id_user);
 struct World *add_world(struct Main *bmian, const char *name);
 struct World *BKE_world_copy(struct World *wrld);
 struct World *localize_world(struct World *wrld);
index b77ae45e94d7ad41e484422bf44103d58936981c..ae1604a94b51f042b2dfe3e085db9795afb9c674 100644 (file)
@@ -159,22 +159,25 @@ void BKE_action_make_local(bAction *act)
 
 /* .................................. */
 
-void BKE_action_free(bAction *act)
-{
-       /* sanity check */
-       if (act == NULL)
-               return;
-       
+/**
+ * Free (or release) any data used by this action (does not free the action itself).
+ *
+ * \param act The action to free.
+ * \param do_id_user When \a true, ID datablocks used (referenced) by this action are 'released'
+ *                   (their user count is decreased).
+ */
+void BKE_action_free(bAction *act, const bool UNUSED(do_id_user))
+{      
+       /* No animdata here. */
+
        /* Free F-Curves */
        free_fcurves(&act->curves);
        
        /* Free groups */
-       if (act->groups.first)
-               BLI_freelistN(&act->groups);
+       BLI_freelistN(&act->groups);
                
        /* Free pose-references (aka local markers) */
-       if (act->markers.first)
-               BLI_freelistN(&act->markers);
+       BLI_freelistN(&act->markers);
 }
 
 /* .................................. */
index 6afe7f1abe906d862652536e1307871b5ca95b9e..fc698f35b7110817ebffad1e378d7e65b8f515dd 100644 (file)
@@ -106,30 +106,31 @@ void BKE_armature_bonelist_free(ListBase *lb)
        BLI_freelistN(lb);
 }
 
-void BKE_armature_free(bArmature *arm)
+/**
+ * Free (or release) any data used by this armature (does not free the armature itself).
+ *
+ * \param arm The armature to free.
+ * \param do_id_user When \a true, ID datablocks used (referenced) by this armature are 'released'
+ *                   (their user count is decreased).
+ */
+void BKE_armature_free(bArmature *arm, const bool UNUSED(do_id_user))
 {
-       if (arm) {
-               BKE_armature_bonelist_free(&arm->bonebase);
+       BKE_animdata_free(&arm->id);
 
-               /* free editmode data */
-               if (arm->edbo) {
-                       BLI_freelistN(arm->edbo);
+       BKE_armature_bonelist_free(&arm->bonebase);
 
-                       MEM_freeN(arm->edbo);
-                       arm->edbo = NULL;
-               }
+       /* free editmode data */
+       if (arm->edbo) {
+               BLI_freelistN(arm->edbo);
 
-               /* free sketch */
-               if (arm->sketch) {
-                       freeSketch(arm->sketch);
-                       arm->sketch = NULL;
-               }
+               MEM_freeN(arm->edbo);
+               arm->edbo = NULL;
+       }
 
-               /* free animation data */
-               if (arm->adt) {
-                       BKE_animdata_free(&arm->id);
-                       arm->adt = NULL;
-               }
+       /* free sketch */
+       if (arm->sketch) {
+               freeSketch(arm->sketch);
+               arm->sketch = NULL;
        }
 }
 
index e0ffd83080493c33ebf933d103e34b8fcf04ee35..3c7f753e3d82736522f53832fcc94588b50fd33d 100644 (file)
@@ -197,22 +197,45 @@ Brush *BKE_brush_copy(Brush *brush)
        return brushn;
 }
 
-/* not brush itself */
-void BKE_brush_free(Brush *brush)
+/**
+ * Free (or release) any data used by this brush (does not free the brush itself).
+ *
+ * \param brush The brush to free.
+ * \param do_id_user When \a true, ID datablocks used (referenced) by this brush are 'released'
+ *                   (their user count is decreased).
+ */
+void BKE_brush_free(Brush *brush, const bool do_id_user)
 {
-       id_us_min((ID *)brush->mtex.tex);
-       id_us_min((ID *)brush->mask_mtex.tex);
-       id_us_min((ID *)brush->paint_curve);
+       if (do_id_user) {
+               if (brush->mtex.tex) {
+                       id_us_min(&brush->mtex.tex->id);
+                       brush->mtex.tex = NULL;
+               }
 
-       if (brush->icon_imbuf)
-               IMB_freeImBuf(brush->icon_imbuf);
+               if (brush->mask_mtex.tex) {
+                       id_us_min(&brush->mask_mtex.tex->id);
+                       brush->mask_mtex.tex = NULL;
+               }
 
-       BKE_previewimg_free(&(brush->preview));
+               if (brush->paint_curve) {
+                       id_us_min(&brush->paint_curve->id);
+                       brush->paint_curve = NULL;
+               }
+
+               /* No ID refcount here... */
+               brush->toggle_brush = NULL;
+               brush->clone.image = NULL;
+       }
+
+       if (brush->icon_imbuf) {
+               IMB_freeImBuf(brush->icon_imbuf);
+       }
 
        curvemapping_free(brush->curve);
 
-       if (brush->gradient)
-               MEM_freeN(brush->gradient);
+       MEM_SAFE_FREE(brush->gradient);
+
+       BKE_previewimg_free(&(brush->preview));
 }
 
 static void extern_local_brush(Brush *brush)
index 7e043df2808f747bd85f09dac5b624b6ceceeff7..eb99022d034f68d2916af05be18db77c910a5c7f 100644 (file)
@@ -144,8 +144,20 @@ void BKE_camera_make_local(Camera *cam)
        }
 }
 
-void BKE_camera_free(Camera *ca)
+/**
+ * Free (or release) any data used by this camera (does not free the camera itself).
+ *
+ * \param ca The camera to free.
+ * \param do_id_user When \a true, ID datablocks used (referenced) by this camera are 'released'
+ *                   (their user count is decreased).
+ */
+void BKE_camera_free(Camera *ca, const bool do_id_user)
 {
+       if (do_id_user) {
+               /* No ID refcount here... */
+               ca->dof_ob = NULL;
+       }
+
        BKE_animdata_free((ID *)ca);
 }
 
index 8d7d62be7e4e4d3ef50dafac53c8573e02cf6fb6..e01813e0b889823bf917a5fb96cab598d9513aa3 100644 (file)
@@ -69,35 +69,6 @@ static int cu_isectLL(const float v1[3], const float v2[3], const float v3[3], c
                       short cox, short coy,
                       float *lambda, float *mu, float vec[3]);
 
-void BKE_curve_unlink(Curve *cu)
-{
-       int a;
-
-       for (a = 0; a < cu->totcol; a++) {
-               if (cu->mat[a]) cu->mat[a]->id.us--;
-               cu->mat[a] = NULL;
-       }
-       if (cu->vfont)
-               cu->vfont->id.us--;
-       cu->vfont = NULL;
-
-       if (cu->vfontb)
-               cu->vfontb->id.us--;
-       cu->vfontb = NULL;
-
-       if (cu->vfonti)
-               cu->vfonti->id.us--;
-       cu->vfonti = NULL;
-
-       if (cu->vfontbi)
-               cu->vfontbi->id.us--;
-       cu->vfontbi = NULL;
-
-       if (cu->key)
-               cu->key->id.us--;
-       cu->key = NULL;
-}
-
 /* frees editcurve entirely */
 void BKE_curve_editfont_free(Curve *cu)
 {
@@ -139,26 +110,63 @@ void BKE_curve_editNurb_free(Curve *cu)
        }
 }
 
-/* don't free curve itself */
-void BKE_curve_free(Curve *cu)
+/**
+ * Free (or release) any data used by this curve (does not free the curve itself).
+ *
+ * \param cu The curve to free.
+ * \param do_id_user When \a true, ID datablocks used (referenced) by this curve are 'released'
+ *                   (their user count is decreased).
+ */
+void BKE_curve_free(Curve *cu, const bool do_id_user)
 {
+       if (do_id_user) {
+               int a;
+
+               for (a = 0; a < cu->totcol; a++) {
+                       if (cu->mat[a]) {
+                               id_us_min(&cu->mat[a]->id);
+                               cu->mat[a] = NULL;
+                       }
+               }
+               if (cu->vfont) {
+                       id_us_min(&cu->vfont->id);
+                       cu->vfont = NULL;
+               }
+               if (cu->vfontb) {
+                       id_us_min(&cu->vfontb->id);
+                       cu->vfontb = NULL;
+               }
+               if (cu->vfonti) {
+                       id_us_min(&cu->vfonti->id);
+                       cu->vfonti = NULL;
+               }
+               if (cu->vfontbi) {
+                       id_us_min(&cu->vfontbi->id);
+                       cu->vfontbi = NULL;
+               }
+               if (cu->key) {
+                       id_us_min(&cu->key->id);
+                       cu->key = NULL;
+               }
+
+               /* No ID refcount here... */
+               cu->bevobj = NULL;
+               cu->taperobj = NULL;
+               cu->textoncurve = NULL;
+       }
+
+       BKE_animdata_free((ID *)cu);
+
        BKE_nurbList_free(&cu->nurb);
        BKE_curve_editfont_free(cu);
 
        BKE_curve_editNurb_free(cu);
-       BKE_curve_unlink(cu);
-       BKE_animdata_free((ID *)cu);
 
-       if (cu->mat)
-               MEM_freeN(cu->mat);
-       if (cu->str)
-               MEM_freeN(cu->str);
-       if (cu->strinfo)
-               MEM_freeN(cu->strinfo);
-       if (cu->bb)
-               MEM_freeN(cu->bb);
-       if (cu->tb)
-               MEM_freeN(cu->tb);
+       MEM_SAFE_FREE(cu->mat);
+       MEM_SAFE_FREE(cu->str);
+       MEM_SAFE_FREE(cu->strinfo);
+       MEM_SAFE_FREE(cu->bb);
+       MEM_SAFE_FREE(cu->tb);
 }
 
 Curve *BKE_curve_add(Main *bmain, const char *name, int type)
index 23261b63486620cd7227994ebbb6dbc419fa50cb..800144eccb810d4051b68d5412999b3d88d0f972 100644 (file)
@@ -95,10 +95,15 @@ void BKE_vfont_free_data(struct VFont *vfont)
        }
 }
 
-void BKE_vfont_free(struct VFont *vf)
+/**
+ * Free (or release) any data used by this font (does not free the font itself).
+ *
+ * \param vf The font to free.
+ * \param do_id_user When \a true, ID datablocks used (referenced) by this font are 'released'
+ *                   (their user count is decreased).
+ */
+void BKE_vfont_free(struct VFont *vf, const bool UNUSED(do_id_user))
 {
-       if (vf == NULL) return;
-
        BKE_vfont_free_data(vf);
 
        if (vf->packedfile) {
index ee5c91923716121789da4b189d98e578a4e5e781..8779f0d5f0e342db559701c4e4cae3a49642e944 100644 (file)
@@ -112,16 +112,19 @@ void free_gpencil_layers(ListBase *list)
 }
 
 /* Free all of GPencil datablock's related data, but not the block itself */
-void BKE_gpencil_free(bGPdata *gpd)
+/**
+ * Free (or release) any data used by this grease pencil (does not free the gpencil itself).
+ *
+ * \param gpd The grease pencil to free.
+ * \param do_id_user When \a true, ID datablocks used (referenced) by this gpencil are 'released'
+ *                   (their user count is decreased).
+ */
+void BKE_gpencil_free(bGPdata *gpd, const bool UNUSED(do_id_user))
 {
+       BKE_animdata_free(&gpd->id);
+
        /* free layers */
        free_gpencil_layers(&gpd->layers);
-       
-       /* free animation data */
-       if (gpd->adt) {
-               BKE_animdata_free(&gpd->id);
-               gpd->adt = NULL;
-       }
 }
 
 /* -------- Container Creation ---------- */
index 3f68339be11bea5bfd266b60079b2dab8e22fb02..68987e21a74876bd805bccd65f48e44659e13131 100644 (file)
@@ -60,17 +60,26 @@ static void free_group_object(GroupObject *go)
        MEM_freeN(go);
 }
 
-
-void BKE_group_free(Group *group)
+/**
+ * Free (or release) any data used by this group (does not free the group itself).
+ *
+ * \param group The group to free.
+ * \param do_id_user When \a true, ID datablocks used (referenced) by this group are 'released'
+ *                   (their user count is decreased).
+ */
+/* Note: technically, groupobjects are ID users (without refcount), but for now we can ignore those. */
+void BKE_group_free(Group *group, const bool UNUSED(do_id_user))
 {
        /* don't free group itself */
        GroupObject *go;
 
-       BKE_previewimg_free(&group->preview);
+       /* No animdata here. */
 
        while ((go = BLI_pophead(&group->gobject))) {
                free_group_object(go);
        }
+
+       BKE_previewimg_free(&group->preview);
 }
 
 void BKE_group_unlink(Group *group)
@@ -132,7 +141,8 @@ void BKE_group_unlink(Group *group)
        }
        
        /* group stays in library, but no members */
-       BKE_group_free(group);
+       /* XXX This is suspicious, means we keep a dangling, empty group? Also, does not take into account fakeuser? */
+       BKE_group_free(group, false);
        group->id.us = 0;
 }
 
index 4a76c704130b978817707a7ddd5782ab69f845c8..48be188aceb69c53b204781b496a951e6f85bf46 100644 (file)
@@ -329,20 +329,22 @@ void BKE_image_free_buffers(Image *ima)
        ima->ok = IMA_OK;
 }
 
-/* called by library too, do not free ima itself */
-void BKE_image_free(Image *ima)
+/**
+ * Free (or release) any data used by this image (does not free the image itself).
+ *
+ * \param ima The image to free.
+ * \param do_id_user When \a true, ID datablocks used (referenced) by this image are 'released'
+ *                   (their user count is decreased).
+ */
+void BKE_image_free(Image *ima, const bool UNUSED(do_id_user))
 {
        int a;
 
+       /* Also frees animdata. */
        BKE_image_free_buffers(ima);
 
        image_free_packedfiles(ima);
 
-       BKE_icon_id_delete(&ima->id);
-       ima->id.icon_id = 0;
-
-       BKE_previewimg_free(&ima->preview);
-
        for (a = 0; a < IMA_MAX_RENDER_SLOT; a++) {
                if (ima->renders[a]) {
                        RE_FreeRenderResult(ima->renders[a]);
@@ -351,7 +353,10 @@ void BKE_image_free(Image *ima)
        }
 
        image_free_views(ima);
-       MEM_freeN(ima->stereo3d_format);
+       MEM_SAFE_FREE(ima->stereo3d_format);
+
+       BKE_icon_id_delete(&ima->id);
+       BKE_previewimg_free(&ima->preview);
 }
 
 /* only image block itself */
index b591dc196854a05bf6b6af4ab1235177355f6bb6..e965f2a8ea7d7780e3dd85fb0bb8d245613ab6d6 100644 (file)
 #define IPO_BEZTRIPLE   100
 #define IPO_BPOINT      101
 
-void BKE_key_free(Key *key)
+
+/**
+ * Free (or release) any data used by this shapekey (does not free the key itself).
+ *
+ * \param key The shapekey to free.
+ * \param do_id_user When \a true, ID datablocks used (referenced) by this key are 'released'
+ *                   (their user count is decreased).
+ */
+void BKE_key_free(Key *key, const bool do_id_user)
 {
        KeyBlock *kb;
+
+       if (do_id_user) {
+               /* No ID refcount here... */
+               key->from = NULL;
+       }
        
        BKE_animdata_free((ID *)key);
 
index 44e35c645debc5307ac37a69cbba953d2b035a13..48498440fa9974a09533ecd2d77f668f50982346 100644 (file)
@@ -210,30 +210,48 @@ void BKE_lamp_make_local(Lamp *la)
        }
 }
 
-void BKE_lamp_free(Lamp *la)
+/**
+ * Free (or release) any data used by this lamp (does not free the lamp itself).
+ *
+ * \param la The lamp to free.
+ * \param do_id_user When \a true, ID datablocks used (referenced) by this lamp are 'released'
+ *                   (their user count is decreased).
+ */
+void BKE_lamp_free(Lamp *la, const bool do_id_user)
 {
-       MTex *mtex;
        int a;
 
-       for (a = 0; a < MAX_MTEX; a++) {
-               mtex = la->mtex[a];
-               if (mtex && mtex->tex) mtex->tex->id.us--;
-               if (mtex) MEM_freeN(mtex);
+       if (do_id_user) {
+               MTex *mtex;
+               int a;
+
+               for (a = 0; a < MAX_MTEX; a++) {
+                       mtex = la->mtex[a];
+                       if (mtex && mtex->tex) {
+                               id_us_min(&mtex->tex->id);
+                               mtex->tex = NULL;
+                       }
+               }
        }
-       
+
        BKE_animdata_free((ID *)la);
 
+       for (a = 0; a < MAX_MTEX; a++) {
+               MEM_SAFE_FREE(la->mtex[a]);
+       }
+       
        curvemapping_free(la->curfalloff);
+       la->curfalloff = NULL;
 
        /* is no lib link block, but lamp extension */
        if (la->nodetree) {
-               ntreeFreeTree(la->nodetree);
+               ntreeFreeTree(la->nodetree, do_id_user);
                MEM_freeN(la->nodetree);
+               la->nodetree = NULL;
        }
        
-       BKE_previewimg_free(&la->preview);
        BKE_icon_id_delete(&la->id);
-       la->id.icon_id = 0;
+       BKE_previewimg_free(&la->preview);
 }
 
 /* Calculate all drivers for lamps, see material_drivers_update for why this is a bad hack */
index 009e1d20328650e2d81f2741322595b76bdf3ad1..cb9b0c09f64fa8f952d9ab27f9772fedcd6ab964 100644 (file)
@@ -293,24 +293,40 @@ Lattice *BKE_lattice_copy(Lattice *lt)
        return ltn;
 }
 
-void BKE_lattice_free(Lattice *lt)
+/**
+ * Free (or release) any data used by this lattice (does not free the lattice itself).
+ *
+ * \param lt The lattice to free.
+ * \param do_id_user When \a true, ID datablocks used (referenced) by this lattice are 'released'
+ *                   (their user count is decreased).
+ */
+void BKE_lattice_free(Lattice *lt, const bool do_id_user)
 {
-       if (lt->def) MEM_freeN(lt->def);
-       if (lt->dvert) BKE_defvert_array_free(lt->dvert, lt->pntsu * lt->pntsv * lt->pntsw);
+       if (do_id_user) {
+               if (lt->key) {
+                       id_us_min(&lt->key->id);
+                       lt->key = NULL;
+               }
+       }
+
+       BKE_animdata_free(&lt->id);
+
+       MEM_SAFE_FREE(lt->def);
+       if (lt->dvert) {
+               BKE_defvert_array_free(lt->dvert, lt->pntsu * lt->pntsv * lt->pntsw);
+               lt->dvert = NULL;
+       }
        if (lt->editlatt) {
                Lattice *editlt = lt->editlatt->latt;
 
-               if (editlt->def) MEM_freeN(editlt->def);
-               if (editlt->dvert) BKE_defvert_array_free(editlt->dvert, lt->pntsu * lt->pntsv * lt->pntsw);
+               if (editlt->def)
+                       MEM_freeN(editlt->def);
+               if (editlt->dvert)
+                       BKE_defvert_array_free(editlt->dvert, lt->pntsu * lt->pntsv * lt->pntsw);
 
                MEM_freeN(editlt);
                MEM_freeN(lt->editlatt);
-       }
-       
-       /* free animation data */
-       if (lt->adt) {
-               BKE_animdata_free(&lt->id);
-               lt->adt = NULL;
+               lt->editlatt = NULL;
        }
 }
 
index 9fb0cb42dfc008152b84be43fa41f1b832f77bca..2d2f9c1aa497ee4e911d0ba8c3bebb2799b28ca0 100644 (file)
@@ -864,7 +864,7 @@ void *BKE_libblock_copy(ID *id)
        return BKE_libblock_copy_ex(G.main, id);
 }
 
-static void BKE_library_free(Library *lib)
+static void BKE_library_free(Library *lib, const bool UNUSED(do_id_user))
 {
        if (lib->packedfile)
                freePackedFile(lib->packedfile);
@@ -925,7 +925,10 @@ void BKE_libblock_free_data(Main *bmain, ID *id)
        BKE_animdata_main_cb(bmain, animdata_dtar_clear_cb, (void *)id);
 }
 
-/* used in headerbuttons.c image.c mesh.c screen.c sound.c and library.c */
+/**
+ * used in headerbuttons.c image.c mesh.c screen.c sound.c and library.c
+ *
+ * \param do_id_user if \a true, try to release other ID's 'references' hold by \a idv. */
 void BKE_libblock_free_ex(Main *bmain, void *idv, bool do_id_user)
 {
        ID *id = idv;
@@ -940,107 +943,107 @@ void BKE_libblock_free_ex(Main *bmain, void *idv, bool do_id_user)
 
        switch (type) {    /* GetShort from util.h */
                case ID_SCE:
-                       BKE_scene_free((Scene *)id);
+                       BKE_scene_free((Scene *)id, do_id_user);
                        break;
                case ID_LI:
-                       BKE_library_free((Library *)id);
+                       BKE_library_free((Library *)id, do_id_user);
                        break;
                case ID_OB:
-                       BKE_object_free_ex((Object *)id, do_id_user);
+                       BKE_object_free((Object *)id, do_id_user);
                        break;
                case ID_ME:
-                       BKE_mesh_free((Mesh *)id, 1);
+                       BKE_mesh_free((Mesh *)id, do_id_user);
                        break;
                case ID_CU:
-                       BKE_curve_free((Curve *)id);
+                       BKE_curve_free((Curve *)id, do_id_user);
                        break;
                case ID_MB:
-                       BKE_mball_free((MetaBall *)id);
+                       BKE_mball_free((MetaBall *)id, do_id_user);
                        break;
                case ID_MA:
-                       BKE_material_free((Material *)id);
+                       BKE_material_free((Material *)id, do_id_user);
                        break;
                case ID_TE:
-                       BKE_texture_free((Tex *)id);
+                       BKE_texture_free((Tex *)id, do_id_user);
                        break;
                case ID_IM:
-                       BKE_image_free((Image *)id);
+                       BKE_image_free((Image *)id, do_id_user);
                        break;
                case ID_LT:
-                       BKE_lattice_free((Lattice *)id);
+                       BKE_lattice_free((Lattice *)id, do_id_user);
                        break;
                case ID_LA:
-                       BKE_lamp_free((Lamp *)id);
+                       BKE_lamp_free((Lamp *)id, do_id_user);
                        break;
                case ID_CA:
-                       BKE_camera_free((Camera *) id);
+                       BKE_camera_free((Camera *) id, do_id_user);
                        break;
-               case ID_IP:
+               case ID_IP:  /* Deprecated. */
                        BKE_ipo_free((Ipo *)id);
                        break;
                case ID_KE:
-                       BKE_key_free((Key *)id);
+                       BKE_key_free((Key *)id, do_id_user);
                        break;
                case ID_WO:
-                       BKE_world_free((World *)id);
+                       BKE_world_free((World *)id, do_id_user);
                        break;
                case ID_SCR:
-                       BKE_screen_free((bScreen *)id);
+                       BKE_screen_free((bScreen *)id, do_id_user);
                        break;
                case ID_VF:
-                       BKE_vfont_free((VFont *)id);
+                       BKE_vfont_free((VFont *)id, do_id_user);
                        break;
                case ID_TXT:
-                       BKE_text_free((Text *)id);
+                       BKE_text_free((Text *)id, do_id_user);
                        break;
                case ID_SCRIPT:
                        /* deprecated */
                        break;
                case ID_SPK:
-                       BKE_speaker_free((Speaker *)id);
+                       BKE_speaker_free((Speaker *)id, do_id_user);
                        break;
                case ID_SO:
-                       BKE_sound_free((bSound *)id);
+                       BKE_sound_free((bSound *)id, do_id_user);
                        break;
                case ID_GR:
-                       BKE_group_free((Group *)id);
+                       BKE_group_free((Group *)id, do_id_user);
                        break;
                case ID_AR:
-                       BKE_armature_free((bArmature *)id);
+                       BKE_armature_free((bArmature *)id, do_id_user);
                        break;
                case ID_AC:
-                       BKE_action_free((bAction *)id);
+                       BKE_action_free((bAction *)id, do_id_user);
                        break;
                case ID_NT:
-                       ntreeFreeTree_ex((bNodeTree *)id, do_id_user);
+                       ntreeFreeTree((bNodeTree *)id, do_id_user);
                        break;
                case ID_BR:
-                       BKE_brush_free((Brush *)id);
+                       BKE_brush_free((Brush *)id, do_id_user);
                        break;
                case ID_PA:
-                       BKE_particlesettings_free((ParticleSettings *)id);
+                       BKE_particlesettings_free((ParticleSettings *)id, do_id_user);
                        break;
                case ID_WM:
                        if (free_windowmanager_cb)
                                free_windowmanager_cb(NULL, (wmWindowManager *)id);
                        break;
                case ID_GD:
-                       BKE_gpencil_free((bGPdata *)id);
+                       BKE_gpencil_free((bGPdata *)id, do_id_user);
                        break;
                case ID_MC:
-                       BKE_movieclip_free((MovieClip *)id);
+                       BKE_movieclip_free((MovieClip *)id, do_id_user);
                        break;
                case ID_MSK:
-                       BKE_mask_free(bmain, (Mask *)id);
+                       BKE_mask_free((Mask *)id, do_id_user);
                        break;
                case ID_LS:
-                       BKE_linestyle_free((FreestyleLineStyle *)id);
+                       BKE_linestyle_free((FreestyleLineStyle *)id, do_id_user);
                        break;
                case ID_PAL:
-                       BKE_palette_free((Palette *)id);
+                       BKE_palette_free((Palette *)id, do_id_user);
                        break;
                case ID_PC:
-                       BKE_paint_curve_free((PaintCurve *)id);
+                       BKE_paint_curve_free((PaintCurve *)id, do_id_user);
                        break;
        }
 
index ac2c4e35dce1d1763846df71c1b7b52e34e9bfd5..0875321a779a9b89bcc8f99053099078ee4024c4 100644 (file)
@@ -123,24 +123,43 @@ FreestyleLineStyle *BKE_linestyle_new(struct Main *bmain, const char *name)
        return linestyle;
 }
 
-void BKE_linestyle_free(FreestyleLineStyle *linestyle)
+/**
+ * Free (or release) any data used by this linestyle (does not free the linestyle itself).
+ *
+ * \param linestyle The linestyle to free.
+ * \param do_id_user When \a true, ID datablocks used (referenced) by this linestyle are 'released'
+ *                   (their user count is decreased).
+ */
+void BKE_linestyle_free(FreestyleLineStyle *linestyle, const bool do_id_user)
 {
        LineStyleModifier *m;
-
-       MTex *mtex;
        int a;
 
+       if (do_id_user) {
+               MTex *mtex;
+
+               for (a = 0; a < MAX_MTEX; a++) {
+                       mtex = linestyle->mtex[a];
+                       if (mtex && mtex->tex) {
+                               id_us_min(&mtex->tex->id);
+                               mtex->tex = NULL;
+                       }
+               }
+       }
+
+       BKE_animdata_free(&linestyle->id);
+
        for (a = 0; a < MAX_MTEX; a++) {
-               mtex = linestyle->mtex[a];
-               if (mtex && mtex->tex) mtex->tex->id.us--;
-               if (mtex) MEM_freeN(mtex);
+               MEM_SAFE_FREE(linestyle->mtex[a]);
        }
+
+       /* is no lib link block, but linestyle extension */
        if (linestyle->nodetree) {
-               ntreeFreeTree(linestyle->nodetree);
+               ntreeFreeTree(linestyle->nodetree, true);  /* XXX Or do_id_user? */
                MEM_freeN(linestyle->nodetree);
+               linestyle->nodetree = NULL;
        }
 
-       BKE_animdata_free(&linestyle->id);
        while ((m = (LineStyleModifier *)linestyle->color_modifiers.first))
                BKE_linestyle_color_modifier_remove(linestyle, m);
        while ((m = (LineStyleModifier *)linestyle->alpha_modifiers.first))
@@ -158,7 +177,7 @@ FreestyleLineStyle *BKE_linestyle_copy(struct Main *bmain, FreestyleLineStyle *l
        int a;
 
        new_linestyle = BKE_linestyle_new(bmain, linestyle->id.name + 2);
-       BKE_linestyle_free(new_linestyle);
+       BKE_linestyle_free(new_linestyle, true);
 
        for (a = 0; a < MAX_MTEX; a++) {
                if (linestyle->mtex[a]) {
index 141597e859c41710a7369d724ba22da37745bd1b..62a2b73a971042fd02b9c78fbbc164fe024560b8 100644 (file)
@@ -1016,13 +1016,22 @@ void BKE_mask_layer_free_list(ListBase *masklayers)
        }
 }
 
-/** free for temp copy, but don't manage unlinking from other pointers */
-void BKE_mask_free_nolib(Mask *mask)
+/**
+ * Free (or release) any data used by this mask (does not free the mask itself).
+ *
+ * \param mask The mask to free.
+ * \param do_id_user When \a true, ID datablocks used (referenced) by this mask are 'released'
+ *                   (their user count is decreased).
+ */
+void BKE_mask_free(Mask *mask, const bool UNUSED(do_id_user))
 {
+       BKE_animdata_free((ID *)mask);
+
+       /* free mask data */
        BKE_mask_layer_free_list(&mask->masklayers);
 }
 
-void BKE_mask_free(Main *bmain, Mask *mask)
+void BKE_mask_unlink(Main *bmain, Mask *mask)
 {
        bScreen *scr;
        ScrArea *area;
@@ -1073,9 +1082,6 @@ void BKE_mask_free(Main *bmain, Mask *mask)
        FOREACH_NODETREE(bmain, ntree, id) {
                BKE_node_tree_unlink_id((ID *)mask, ntree);
        } FOREACH_NODETREE_END
-
-       /* free mask data */
-       BKE_mask_layer_free_list(&mask->masklayers);
 }
 
 void BKE_mask_coord_from_frame(float r_co[2], const float co[2], const float frame_size[2])
index 3e7e98b4a1d03fa4822fdd1adcc7489ff514b28c..300485c2c0ae034a4ddc149ae8eb7fb2b23aa9f7 100644 (file)
@@ -81,45 +81,54 @@ void init_def_material(void)
        init_material(&defmaterial);
 }
 
-/* not material itself */
-void BKE_material_free(Material *ma)
-{
-       BKE_material_free_ex(ma, true);
-}
-
-/* not material itself */
-void BKE_material_free_ex(Material *ma, bool do_id_user)
+/**
+ * Free (or release) any data used by this material (does not free the material itself).
+ *
+ * \param ma The material to free.
+ * \param do_id_user When \a true, ID datablocks used (referenced) by this material are 'released'
+ *                   (their user count is decreased).
+ */
+void BKE_material_free(Material *ma, const bool do_id_user)
 {
-       MTex *mtex;
        int a;
+
+       if (do_id_user)  {
+               MTex *mtex;
+
+               for (a = 0; a < MAX_MTEX; a++) {
+                       mtex = ma->mtex[a];
+                       if (mtex && mtex->tex) {
+                               id_us_min(&mtex->tex->id);
+                               mtex->tex = NULL;
+                       }
+               }
+
+               /* No ID refcount here... */
+               ma->group = NULL;
+       }
+
+       BKE_animdata_free((ID *)ma);
        
        for (a = 0; a < MAX_MTEX; a++) {
-               mtex = ma->mtex[a];
-               if (do_id_user && mtex && mtex->tex) mtex->tex->id.us--;
-               if (mtex) MEM_freeN(mtex);
+               MEM_SAFE_FREE(ma->mtex[a]);
        }
        
-       if (ma->ramp_col) MEM_freeN(ma->ramp_col);
-       if (ma->ramp_spec) MEM_freeN(ma->ramp_spec);
-       
-       BKE_animdata_free((ID *)ma);
-       
-       if (ma->preview)
-               BKE_previewimg_free(&ma->preview);
-       BKE_icon_id_delete((struct ID *)ma);
-       ma->id.icon_id = 0;
+       MEM_SAFE_FREE(ma->ramp_col);
+       MEM_SAFE_FREE(ma->ramp_spec);
        
        /* is no lib link block, but material extension */
        if (ma->nodetree) {
-               ntreeFreeTree_ex(ma->nodetree, do_id_user);
+               ntreeFreeTree(ma->nodetree, do_id_user);
                MEM_freeN(ma->nodetree);
+               ma->nodetree = NULL;
        }
 
-       if (ma->texpaintslot)
-               MEM_freeN(ma->texpaintslot);
+       MEM_SAFE_FREE(ma->texpaintslot);
+
+       GPU_material_free(&ma->gpumaterial);
 
-       if (ma->gpumaterial.first)
-               GPU_material_free(&ma->gpumaterial);
+       BKE_icon_id_delete((ID *)ma);
+       BKE_previewimg_free(&ma->preview);
 }
 
 void init_material(Material *ma)
@@ -1757,7 +1766,7 @@ void free_matcopybuf(void)
        matcopybuf.ramp_spec = NULL;
 
        if (matcopybuf.nodetree) {
-               ntreeFreeTree_ex(matcopybuf.nodetree, false);
+               ntreeFreeTree(matcopybuf.nodetree, false);
                MEM_freeN(matcopybuf.nodetree);
                matcopybuf.nodetree = NULL;
        }
@@ -1807,7 +1816,7 @@ void paste_matcopybuf(Material *ma)
        }
 
        if (ma->nodetree) {
-               ntreeFreeTree(ma->nodetree);
+               ntreeFreeTree(ma->nodetree, true);  /* XXX Or do_id_user? */
                MEM_freeN(ma->nodetree);
        }
 
index c09cd1aabdcf51a85c41228276efe44bba2a6261..89c6a7d00b9d51c910bcf70d722c1fa95db4620d 100644 (file)
 
 /* Functions */
 
-void BKE_mball_unlink(MetaBall *mb)
+/**
+ * Free (or release) any data used by this mball (does not free the mball itself).
+ *
+ * \param mb The mball to free.
+ * \param do_id_user When \a true, ID datablocks used (referenced) by this mball are 'released'
+ *                   (their user count is decreased).
+ */
+void BKE_mball_free(MetaBall *mb, const bool do_id_user)
 {
-       int a;
+       if (do_id_user) {
+               int a;
        
-       for (a = 0; a < mb->totcol; a++) {
-               if (mb->mat[a]) mb->mat[a]->id.us--;
-               mb->mat[a] = NULL;
+               for (a = 0; a < mb->totcol; a++) {
+                       if (mb->mat[a]) {
+                               id_us_min(&mb->mat[a]->id);
+                               mb->mat[a] = NULL;
+                       }
+               }
        }
-}
+       
+       BKE_animdata_free((ID *)mb);
 
+       MEM_SAFE_FREE(mb->mat);
 
-/* do not free mball itself */
-void BKE_mball_free(MetaBall *mb)
-{
-       BKE_mball_unlink(mb);
-       
-       if (mb->adt) {
-               BKE_animdata_free((ID *)mb);
-               mb->adt = NULL;
-       }
-       if (mb->mat) MEM_freeN(mb->mat);
        BLI_freelistN(&mb->elems);
-       if (mb->disp.first) BKE_displist_free(&mb->disp);
+       BKE_displist_free(&mb->disp);
 }
 
 MetaBall *BKE_mball_add(Main *bmain, const char *name)
index 8c89a7249759a358353ff1cdcf11f105abb0ef07..e2991c8868bf707390aab51f5daca9dd7b70a80e 100644 (file)
@@ -430,32 +430,38 @@ bool BKE_mesh_has_custom_loop_normals(Mesh *me)
  * we need a more generic method, like the expand() functions in
  * readfile.c */
 
-void BKE_mesh_unlink(Mesh *me)
+
+/**
+ * Free (or release) any data used by this mesh (does not free the mesh itself).
+ *
+ * \param me The mesh to free.
+ * \param do_id_user When \a true, ID datablocks used (referenced) by this mesh are 'released'
+ *                   (their user count is decreased).
+ */
+void BKE_mesh_free(Mesh *me, const bool do_id_user)
 {
-       int a;
+       if (do_id_user) {
+               int a;
        
-       if (me == NULL) return;
-
-       if (me->mat) {
-               for (a = 0; a < me->totcol; a++) {
-                       if (me->mat[a]) me->mat[a]->id.us--;
-                       me->mat[a] = NULL;
+               if (me->mat) {
+                       for (a = 0; a < me->totcol; a++) {
+                               if (me->mat[a]) {
+                                       id_us_min(&me->mat[a]->id);
+                                       me->mat[a] = NULL;
+                               }
+                       }
                }
-       }
 
-       if (me->key) {
-               me->key->id.us--;
-       }
-       me->key = NULL;
+               if (me->key) {
+                       id_us_min(&me->key->id);
+                       me->key = NULL;
+               }
        
-       if (me->texcomesh) me->texcomesh = NULL;
-}
+               /* No ID refcount here... */
+               me->texcomesh = NULL;
+       }
 
-/* do not free mesh itself */
-void BKE_mesh_free(Mesh *me, int unlink)
-{
-       if (unlink)
-               BKE_mesh_unlink(me);
+       BKE_animdata_free(&me->id);
 
        CustomData_free(&me->vdata, me->totvert);
        CustomData_free(&me->edata, me->totedge);
@@ -463,16 +469,10 @@ void BKE_mesh_free(Mesh *me, int unlink)
        CustomData_free(&me->ldata, me->totloop);
        CustomData_free(&me->pdata, me->totpoly);
 
-       if (me->adt) {
-               BKE_animdata_free(&me->id);
-               me->adt = NULL;
-       }
-       
-       if (me->mat) MEM_freeN(me->mat);
-       
-       if (me->bb) MEM_freeN(me->bb);
-       if (me->mselect) MEM_freeN(me->mselect);
-       if (me->edit_btmesh) MEM_freeN(me->edit_btmesh);
+       MEM_SAFE_FREE(me->mat);
+       MEM_SAFE_FREE(me->bb);
+       MEM_SAFE_FREE(me->mselect);
+       MEM_SAFE_FREE(me->edit_btmesh);
 }
 
 static void mesh_tessface_clear_intern(Mesh *mesh, int free_customdata)
index 7a8c4ad456418067b8400fd64b4c514936cc88e7..335ea9346b7982d65364f0973d824bff0b19c74f 100644 (file)
@@ -44,6 +44,7 @@
 #include "MEM_guardedalloc.h"
 
 #include "DNA_constraint_types.h"
+#include "DNA_gpencil_types.h"
 #include "DNA_screen_types.h"
 #include "DNA_space_types.h"
 #include "DNA_movieclip_types.h"
@@ -1402,8 +1403,23 @@ void BKE_movieclip_build_proxy_frame_for_ibuf(MovieClip *clip, ImBuf *ibuf, stru
        }
 }
 
-void BKE_movieclip_free(MovieClip *clip)
+/**
+ * Free (or release) any data used by this lamp (does not free the lamp itself).
+ *
+ * \param la The lamp to free.
+ * \param do_id_user When \a true, ID datablocks used (referenced) by this lamp are 'released'
+ *                   (their user count is decreased).
+ */
+void BKE_movieclip_free(MovieClip *clip, const bool do_id_user)
 {
+       if (do_id_user) {
+               if (clip->gpd) {
+                       id_us_min(&clip->gpd->id);
+                       clip->gpd = NULL;
+               }
+       }
+
+       /* Also frees animdata. */
        free_buffers(clip);
 
        BKE_tracking_free(&clip->tracking);
index c656931d18b0779d46c61406602f76d5f78f4c2d..b256e11c538ec5d7eeb7c4fda3595179c3649644 100644 (file)
@@ -38,6 +38,7 @@
 
 #include "DNA_action_types.h"
 #include "DNA_anim_types.h"
+#include "DNA_gpencil_types.h"
 #include "DNA_lamp_types.h"
 #include "DNA_material_types.h"
 #include "DNA_node_types.h"
@@ -1775,21 +1776,35 @@ static void free_localized_node_groups(bNodeTree *ntree)
        for (node = ntree->nodes.first; node; node = node->next) {
                if (node->type == NODE_GROUP && node->id) {
                        bNodeTree *ngroup = (bNodeTree *)node->id;
-                       ntreeFreeTree_ex(ngroup, false);
+                       ntreeFreeTree(ngroup, false);
                        MEM_freeN(ngroup);
                }
        }
 }
 
-/* do not free ntree itself here, BKE_libblock_free calls this function too */
-void ntreeFreeTree_ex(bNodeTree *ntree, const bool do_id_user)
+/**
+ * Free (or release) any data used by this nodetree (does not free the nodetree itself).
+ *
+ * \param ntree The nodetree to free.
+ * \param do_id_user When \a true, ID datablocks used (referenced) by this nodetree are 'released'
+ *                   (their user count is decreased).
+ */
+void ntreeFreeTree(bNodeTree *ntree, const bool do_id_user)
 {
        bNodeTree *tntree;
        bNode *node, *next;
        bNodeSocket *sock, *nextsock;
-       
-       if (ntree == NULL) return;
-       
+
+       if (do_id_user) {
+               if (ntree->gpd) {
+                       id_us_min(&ntree->gpd->id);
+                       ntree->gpd = NULL;
+               }
+               /* XXX See comment below about id used by nodes... */
+       }
+
+       BKE_animdata_free((ID *)ntree);
+
        /* XXX hack! node trees should not store execution graphs at all.
         * This should be removed when old tree types no longer require it.
         * Currently the execution data for texture nodes remains in the tree
@@ -1813,10 +1828,6 @@ void ntreeFreeTree_ex(bNodeTree *ntree, const bool do_id_user)
        /* unregister associated RNA types */
        ntreeInterfaceTypeFree(ntree);
        
-       BKE_animdata_free((ID *)ntree);
-       
-       id_us_min((ID *)ntree->gpd);
-
        BLI_freelistN(&ntree->links);   /* do first, then unlink_node goes fast */
        
        for (node = ntree->nodes.first; node; node = next) {
@@ -1867,11 +1878,6 @@ void ntreeFreeTree_ex(bNodeTree *ntree, const bool do_id_user)
                BKE_libblock_free_data(G.main, &ntree->id);
        }
 }
-/* same as ntreeFreeTree_ex but always manage users */
-void ntreeFreeTree(bNodeTree *ntree)
-{
-       ntreeFreeTree_ex(ntree, true);
-}
 
 void ntreeFreeCache(bNodeTree *ntree)
 {
@@ -2145,7 +2151,7 @@ void ntreeLocalMerge(bNodeTree *localtree, bNodeTree *ntree)
                if (ntree->typeinfo->local_merge)
                        ntree->typeinfo->local_merge(localtree, ntree);
                
-               ntreeFreeTree_ex(localtree, false);
+               ntreeFreeTree(localtree, false);
                MEM_freeN(localtree);
        }
 }
index 0c9239e3ddf3711385707be2f3bbe700a9313959..36dc954a724682b2df08fd6cf9b987340d0e71b5 100644 (file)
@@ -40,6 +40,7 @@
 #include "DNA_armature_types.h"
 #include "DNA_camera_types.h"
 #include "DNA_constraint_types.h"
+#include "DNA_gpencil_types.h"
 #include "DNA_group_types.h"
 #include "DNA_key_types.h"
 #include "DNA_lamp_types.h"
@@ -379,55 +380,62 @@ void BKE_object_free_caches(Object *object)
        }
 }
 
-/* do not free object itself */
-void BKE_object_free_ex(Object *ob, bool do_id_user)
+/**
+ * Free (or release) any data used by this object (does not free the object itself).
+ *
+ * \param ob The object to free.
+ * \param do_id_user When \a true, ID datablocks used (referenced) by this object are 'released'
+ *                   (their user count is decreased).
+ */
+void BKE_object_free(Object *ob, const bool do_id_user)
 {
-       int a;
-       
-       BKE_object_free_derived_caches(ob);
-       
-       /* disconnect specific data, but not for lib data (might be indirect data, can get relinked) */
-       if (ob->data) {
-               ID *id = ob->data;
-               id->us--;
-               if (id->us == 0 && id->lib == NULL) {
-                       switch (ob->type) {
-                               case OB_MESH:
-                                       BKE_mesh_unlink((Mesh *)id);
-                                       break;
-                               case OB_CURVE:
-                                       BKE_curve_unlink((Curve *)id);
-                                       break;
-                               case OB_MBALL:
-                                       BKE_mball_unlink((MetaBall *)id);
-                                       break;
+       if (do_id_user) {
+               /* Note: This totally ignores indirectly-'linked' datablocks (through constraints, modifiers...).
+                *       That’s fine for now (none of them actually refcount IDs), remap project will rework this deeply anyway. */
+               int a;
+
+               if (ob->data) {
+                       id_us_min((ID *)ob->data);
+                       ob->data = NULL;
+               }
+
+               if (ob->mat) {
+                       for (a = 0; a < ob->totcol; a++) {
+                               if (ob->mat[a]) {
+                                       id_us_min(&ob->mat[a]->id);
+                                       ob->mat[a] = NULL;
+                               }
                        }
                }
-               ob->data = NULL;
-       }
 
-       if (ob->mat) {
-               for (a = 0; a < ob->totcol; a++) {
-                       if (ob->mat[a]) ob->mat[a]->id.us--;
+               if (ob->poselib) {
+                       id_us_min(&ob->poselib->id);
+                       ob->poselib = NULL;
+               }
+               if (ob->gpd) {
+                       id_us_min(&ob->gpd->id);
+                       ob->gpd = NULL;
                }
-               MEM_freeN(ob->mat);
        }
-       if (ob->matbits) MEM_freeN(ob->matbits);
-       ob->mat = NULL;
-       ob->matbits = NULL;
-       if (ob->iuser) MEM_freeN(ob->iuser);
-       ob->iuser = NULL;
-       if (ob->bb) MEM_freeN(ob->bb); 
-       ob->bb = NULL;
-       if (ob->adt) BKE_animdata_free((ID *)ob);
-       if (ob->poselib) ob->poselib->id.us--;
-       if (ob->gpd) ((ID *)ob->gpd)->us--;
-       if (ob->defbase.first)
-               BLI_freelistN(&ob->defbase);
-       if (ob->pose)
+
+       BKE_animdata_free((ID *)ob);
+
+       BKE_object_free_derived_caches(ob);
+
+       MEM_SAFE_FREE(ob->mat);
+       MEM_SAFE_FREE(ob->matbits);
+       MEM_SAFE_FREE(ob->iuser);
+       MEM_SAFE_FREE(ob->bb);
+
+       BLI_freelistN(&ob->defbase);
+       if (ob->pose) {
                BKE_pose_free_ex(ob->pose, do_id_user);
-       if (ob->mpath)
+               ob->pose = NULL;
+       }
+       if (ob->mpath) {
                animviz_free_motionpath(ob->mpath);
+               ob->mpath = NULL;
+       }
        BKE_bproperty_free_list(&ob->prop);
        BKE_object_free_modifiers(ob);
        
@@ -441,13 +449,19 @@ void BKE_object_free_ex(Object *ob, bool do_id_user)
        BKE_rigidbody_free_object(ob);
        BKE_rigidbody_free_constraint(ob);
 
-       if (ob->soft) sbFree(ob->soft);
-       if (ob->bsoft) bsbFree(ob->bsoft);
-       if (ob->gpulamp.first) GPU_lamp_free(ob);
+       if (ob->soft) {
+               sbFree(ob->soft);
+               ob->soft = NULL;
+       }
+       if (ob->bsoft) {
+               bsbFree(ob->bsoft);
+               ob->bsoft = NULL;
+       }
+       GPU_lamp_free(ob);
 
        BKE_sculptsession_free(ob);
 
-       if (ob->pc_ids.first) BLI_freelistN(&ob->pc_ids);
+       BLI_freelistN(&ob->pc_ids);
 
        BLI_freelistN(&ob->lodlevels);
 
@@ -457,16 +471,12 @@ void BKE_object_free_ex(Object *ob, bool do_id_user)
                if (ob->curve_cache->path)
                        free_path(ob->curve_cache->path);
                MEM_freeN(ob->curve_cache);
+               ob->curve_cache = NULL;
        }
 
        BKE_previewimg_free(&ob->preview);
 }
 
-void BKE_object_free(Object *ob)
-{
-       BKE_object_free_ex(ob, true);
-}
-
 static void unlink_object__unlinkModifierLinks(void *userData, Object *ob, Object **obpoin)
 {
        Object *unlinkOb = userData;
@@ -478,6 +488,9 @@ static void unlink_object__unlinkModifierLinks(void *userData, Object *ob, Objec
        }
 }
 
+/* XXX Horrific! This pretty much re-does BKE_library_foreach_ID_link() and
+ *     BKE_library_callback_free_editor_id_reference_set() & co...
+ * TODO This is to be replaced by/merged in more generic 'id-remap' process being worked on in same-named branch... */
 void BKE_object_unlink(Object *ob)
 {
        Main *bmain = G.main;
index 06844b09a9b22d1ee69bb962983c57be722893c3..90c07280a61b0fbc1868dcac179666919836a507 100644 (file)
@@ -298,13 +298,17 @@ void BKE_paint_brush_set(Paint *p, Brush *br)
        }
 }
 
-void BKE_paint_curve_free(PaintCurve *pc)
+/**
+ * Free (or release) any data used by this paint curve (does not free the pcurve itself).
+ *
+ * \param pc The paint curve to free.
+ * \param do_id_user When \a true, ID datablocks used (referenced) by this paint curve are 'released'
+ *                   (their user count is decreased).
+ */
+void BKE_paint_curve_free(PaintCurve *pc, const bool UNUSED(do_id_user))
 {
-       if (pc->points) {
-               MEM_freeN(pc->points);
-               pc->points = NULL;
-               pc->tot_points = 0;
-       }
+       MEM_SAFE_FREE(pc->points);
+       pc->tot_points = 0;
 }
 
 PaintCurve *BKE_paint_curve_add(Main *bmain, const char *name)
@@ -378,7 +382,14 @@ Palette *BKE_palette_add(Main *bmain, const char *name)
        return palette;
 }
 
-void BKE_palette_free(Palette *palette)
+/**
+ * Free (or release) any data used by this palette (does not free the palette itself).
+ *
+ * \param palette The palette to free.
+ * \param do_id_user When \a true, ID datablocks used (referenced) by this palette are 'released'
+ *                   (their user count is decreased).
+ */
+void BKE_palette_free(Palette *palette, const bool UNUSED(do_id_user))
 {
        BLI_freelistN(&palette->colors);
 }
index 9aacba8d02ec2322f1b776b1d914964a811080fc..90c9a71f4ee5e2108d84550555fbc0f1edb9384c 100644 (file)
@@ -371,12 +371,40 @@ static void fluid_free_settings(SPHFluidSettings *fluid)
                MEM_freeN(fluid); 
 }
 
-void BKE_particlesettings_free(ParticleSettings *part)
+/**
+ * Free (or release) any data used by this particle settings (does not free the partsett itself).
+ *
+ * \param part The particle settings to free.
+ * \param do_id_user When \a true, ID datablocks used (referenced) by this partsett are 'released'
+ *                   (their user count is decreased).
+ */
+void BKE_particlesettings_free(ParticleSettings *part, const bool do_id_user)
 {
-       MTex *mtex;
        int a;
+
+       if (do_id_user) {
+               MTex *mtex;
+
+               for (a = 0; a < MAX_MTEX; a++) {
+                       mtex = part->mtex[a];
+                       if (mtex && mtex->tex) {
+                               id_us_min(&mtex->tex->id);
+                               mtex->tex = NULL;
+                       }
+               }
+
+               /* No ID refcount here... */
+               part->dup_group = NULL;
+               part->dup_ob = NULL;
+               part->bb_ob = NULL;
+       }
+
        BKE_animdata_free(&part->id);
        
+       for (a = 0; a < MAX_MTEX; a++) {
+               MEM_SAFE_FREE(part->mtex[a]);
+       }
+
        if (part->clumpcurve)
                curvemapping_free(part->clumpcurve);
        if (part->roughcurve)
@@ -385,19 +413,13 @@ void BKE_particlesettings_free(ParticleSettings *part)
        free_partdeflect(part->pd);
        free_partdeflect(part->pd2);
 
-       if (part->effector_weights)
-               MEM_freeN(part->effector_weights);
+       MEM_SAFE_FREE(part->effector_weights);
 
        BLI_freelistN(&part->dupliweights);
 
        boid_free_settings(part->boids);
        fluid_free_settings(part->fluid);
 
-       for (a = 0; a < MAX_MTEX; a++) {
-               mtex = part->mtex[a];
-               if (mtex && mtex->tex) mtex->tex->id.us--;
-               if (mtex) MEM_freeN(mtex);
-       }
 }
 
 void free_hair(Object *UNUSED(ob), ParticleSystem *psys, int dynamics)
index 1ccc213006ad74b4dc106badbce7f72a21392f6c..8f0437109a5c35ee0150c33ed1f04df52cb236de 100644 (file)
@@ -360,41 +360,73 @@ void BKE_scene_groups_relink(Scene *sce)
                BKE_rigidbody_world_groups_relink(sce->rigidbody_world);
 }
 
-/* do not free scene itself */
-void BKE_scene_free(Scene *sce)
+/**
+ * Free (or release) any data used by this scene (does not free the scene itself).
+ *
+ * \param sce The scene to free.
+ * \param do_id_user When \a true, ID datablocks used (referenced) by this scene are 'released'
+ *                   (their user count is decreased).
+ */
+void BKE_scene_free(Scene *sce, const bool do_id_user)
 {
-       Base *base;
        SceneRenderLayer *srl;
 
-       /* check all sequences */
-       BKE_sequencer_clear_scene_in_allseqs(G.main, sce);
+       if (do_id_user) {
+               Base *base;
 
-       base = sce->base.first;
-       while (base) {
-               base->object->id.us--;
-               base = base->next;
-       }
-       /* do not free objects! */
-       
-       if (sce->gpd) {
-#if 0   /* removed since this can be invalid memory when freeing everything */
-               /* since the grease pencil data is freed before the scene.
-                * since grease pencil data is not (yet?), shared between objects
-                * its probably safe not to do this, some save and reload will free this. */
-               sce->gpd->id.us--;
+               for (base = sce->base.first; base; base = base->next) {
+                       id_us_min(&base->object->id);
+                       base->object = NULL;
+               }
+               /* do not free objects! */
+
+               if (sce->world) {
+                       id_us_min(&sce->world->id);
+                       sce->world = NULL;
+               }
+
+               BLI_assert(sce->obedit == NULL);
+
+               if (sce->gpd) {
+                       /* XXX TODO Fix This! */
+#if 0     /* removed since this can be invalid memory when freeing everything */
+                       /* since the grease pencil data is freed before the scene.
+                        * since grease pencil data is not (yet?), shared between objects
+                        * its probably safe not to do this, some save and reload will free this. */
+                       id_us_min(&sce->gpd->id);
 #endif
-               sce->gpd = NULL;
+                       sce->gpd = NULL;
+               }
+
+               /* No ID refcount here... */
+               sce->camera = NULL;
+               sce->set = NULL;
+               sce->clip = NULL;
        }
 
+       BKE_animdata_free((ID *)sce);
+
+       /* check all sequences */
+       BKE_sequencer_clear_scene_in_allseqs(G.main, sce);
+
+       sce->basact = NULL;
        BLI_freelistN(&sce->base);
        BKE_sequencer_editing_free(sce);
 
-       BKE_animdata_free((ID *)sce);
        BKE_keyingsets_free(&sce->keyingsets);
-       
-       if (sce->rigidbody_world)
+
+       /* is no lib link block, but scene extension */
+       if (sce->nodetree) {
+               ntreeFreeTree(sce->nodetree, do_id_user);
+               MEM_freeN(sce->nodetree);
+               sce->nodetree = NULL;
+       }
+
+       if (sce->rigidbody_world) {
                BKE_rigidbody_free_world(sce->rigidbody_world);
-       
+               sce->rigidbody_world = NULL;
+       }
+
        if (sce->r.avicodecdata) {
                free_avicodecdata(sce->r.avicodecdata);
                MEM_freeN(sce->r.avicodecdata);
@@ -447,15 +479,8 @@ void BKE_scene_free(Scene *sce)
        if (sce->depsgraph)
                DEG_graph_free(sce->depsgraph);
        
-       if (sce->nodetree) {
-               ntreeFreeTree(sce->nodetree);
-               MEM_freeN(sce->nodetree);
-       }
-
-       if (sce->stats)
-               MEM_freeN(sce->stats);
-       if (sce->fps_info)
-               MEM_freeN(sce->fps_info);
+       MEM_SAFE_FREE(sce->stats);
+       MEM_SAFE_FREE(sce->fps_info);
 
        BKE_sound_destroy_scene(sce);
 
index 7401ef28f62808afcc3d70bda624304be61daf63..4dd67f5ecff2bd6fcd0b97372e66dcb23687cf2d 100644 (file)
@@ -357,11 +357,19 @@ void BKE_screen_area_free(ScrArea *sa)
        BLI_freelistN(&sa->actionzones);
 }
 
-/* don't free screen itself */
-void BKE_screen_free(bScreen *sc)
+/**
+ * Free (or release) any data used by this screen (does not free the screen itself).
+ *
+ * \param sc The screen to free.
+ * \param do_id_user When \a true, ID datablocks used (referenced) by this screen are 'released'
+ *                   (their user count is decreased).
+ */
+void BKE_screen_free(bScreen *sc, const bool UNUSED(do_id_user))
 {
        ScrArea *sa, *san;
        ARegion *ar;
+
+       /* No animdata here. */
        
        for (ar = sc->regionbase.first; ar; ar = ar->next)
                BKE_area_region_free(NULL, ar);
index 4847306f6beb269749e3dac5003f675336c834dc..896688565da4b94b2971dc6afd58f815bbd812b4 100644 (file)
@@ -3031,7 +3031,7 @@ static ImBuf *seq_render_mask(const SeqRenderData *context, Mask *mask, float nr
 
                BKE_maskrasterize_handle_init(mr_handle, mask_temp, context->rectx, context->recty, true, true, true);
 
-               BKE_mask_free_nolib(mask_temp);
+               BKE_mask_free(mask_temp, false);
                MEM_freeN(mask_temp);
 
                BKE_maskrasterize_buffer(mr_handle, context->rectx, context->recty, maskbuf);
@@ -5021,7 +5021,7 @@ Sequence *BKE_sequencer_add_sound_strip(bContext *C, ListBase *seqbasep, SeqLoad
        info = AUD_getInfo(sound->playback_handle);
 
        if (info.specs.channels == AUD_CHANNELS_INVALID) {
-               BKE_sound_delete(bmain, sound);
+               BKE_libblock_free(bmain, sound);
 #if 0
                if (op)
                        BKE_report(op->reports, RPT_ERROR, "Unsupported audio format");
index 0b89931aa75e49e4a033ee80f926a388d2fabd04..180c82f5c0008a7fae39c54a874316a1f26d05f1 100644 (file)
@@ -99,8 +99,17 @@ bSound *BKE_sound_new_file(struct Main *bmain, const char *filename)
        return sound;
 }
 
-void BKE_sound_free(bSound *sound)
+/**
+ * Free (or release) any data used by this sound (does not free the sound itself).
+ *
+ * \param sound The sound to free.
+ * \param do_id_user When \a true, ID datablocks used (referenced) by this sound are 'released'
+ *                   (their user count is decreased).
+ */
+void BKE_sound_free(bSound *sound, const bool UNUSED(do_id_user))
 {
+       /* No animdata here. */
+
        if (sound->packedfile) {
                freePackedFile(sound->packedfile);
                sound->packedfile = NULL;
@@ -124,8 +133,7 @@ void BKE_sound_free(bSound *sound)
                BLI_spin_end(sound->spinlock);
                MEM_freeN(sound->spinlock);
                sound->spinlock = NULL;
-       }
-       
+       }       
 #endif  /* WITH_AUDASPACE */
 }
 
@@ -291,15 +299,6 @@ bSound *BKE_sound_new_limiter(struct Main *bmain, bSound *source, float start, f
 }
 #endif
 
-void BKE_sound_delete(struct Main *bmain, bSound *sound)
-{
-       if (sound) {
-               BKE_sound_free(sound);
-
-               BKE_libblock_free(bmain, sound);
-       }
-}
-
 void BKE_sound_cache(bSound *sound)
 {
        sound->flags |= SOUND_FLAGS_CACHING;
index 7a800555144294300828dfadbd457e7d4484fec8..96a6dc35a1afdefaf265c558b4d79869a6708490 100644 (file)
@@ -125,10 +125,21 @@ void BKE_speaker_make_local(Speaker *spk)
        }
 }
 
-void BKE_speaker_free(Speaker *spk)
+/**
+ * Free (or release) any data used by this speaker (does not free the speaker itself).
+ *
+ * \param spk The speaker to free.
+ * \param do_id_user When \a true, ID datablocks used (referenced) by this speaker are 'released'
+ *                   (their user count is decreased).
+ */
+void BKE_speaker_free(Speaker *spk, const bool do_id_user)
 {
-       if (spk->sound)
-               spk->sound->id.us--;
+       if (do_id_user) {
+               if (spk->sound) {
+                       id_us_min(&spk->sound->id);
+                       spk->sound = NULL;
+               }
+       }
 
        BKE_animdata_free((ID *)spk);
 }
index 77d6043d6f35015c064a60c528262621e71d36bf..d5d2e169aa3eb366cea84e3269829d213fae3be4 100644 (file)
@@ -152,10 +152,19 @@ static void init_undo_text(Text *text)
        text->undo_buf = MEM_mallocN(text->undo_len, "undo buf");
 }
 
-void BKE_text_free(Text *text)
+/**
+ * Free (or release) any data used by this text (does not free the text itself).
+ *
+ * \param text The text to free.
+ * \param do_id_user When \a true, ID datablocks used (referenced) by this text are 'released'
+ *                   (their user count is decreased).
+ */
+void BKE_text_free(Text *text, const bool UNUSED(do_id_user))
 {
        TextLine *tmp;
 
+       /* No animdata here. */
+
        for (tmp = text->lines.first; tmp; tmp = tmp->next) {
                MEM_freeN(tmp->line);
                if (tmp->format)
@@ -164,10 +173,10 @@ void BKE_text_free(Text *text)
        
        BLI_freelistN(&text->lines);
 
-       if (text->name) MEM_freeN(text->name);
-       MEM_freeN(text->undo_buf);
+       MEM_SAFE_FREE(text->name);
+       MEM_SAFE_FREE(text->undo_buf);
 #ifdef WITH_PYTHON
-       if (text->compiled) BPY_text_free_code(text);
+       BPY_text_free_code(text);
 #endif
 }
 
index 88a412d5e95d8f40bb4588f1bc2b64eeafc5c8ec..ef1863e555be7f89637e7c0b126277beea565a0b 100644 (file)
@@ -557,23 +557,51 @@ int colorband_element_remove(struct ColorBand *coba, int index)
 
 /* ******************* TEX ************************ */
 
-void BKE_texture_free(Tex *tex)
+/**
+ * Free (or release) any data used by this texture (does not free the texure itself).
+ *
+ * \param te The texure to free.
+ * \param do_id_user When \a true, ID datablocks used (referenced) by this texture are 'released'
+ *                   (their user count is decreased).
+ */
+void BKE_texture_free(Tex *tex, const bool do_id_user)
 {
-       if (tex->coba) MEM_freeN(tex->coba);
-       if (tex->env) BKE_texture_envmap_free(tex->env);
-       if (tex->pd) BKE_texture_pointdensity_free(tex->pd);
-       if (tex->vd) BKE_texture_voxeldata_free(tex->vd);
-       if (tex->ot) BKE_texture_ocean_free(tex->ot);
-       BKE_animdata_free((struct ID *)tex);
-       
-       BKE_previewimg_free(&tex->preview);
-       BKE_icon_id_delete((struct ID *)tex);
-       tex->id.icon_id = 0;
-       
+       if (do_id_user) {
+               if (tex->ima) {
+                       id_us_min(&tex->ima->id);
+                       tex->ima = NULL;
+               }
+       }
+
+       BKE_animdata_free((ID *)tex);
+
+       /* is no lib link block, but texture extension */
        if (tex->nodetree) {
-               ntreeFreeTree(tex->nodetree);
+               ntreeFreeTree(tex->nodetree, do_id_user);
                MEM_freeN(tex->nodetree);
+               tex->nodetree = NULL;
        }
+
+       MEM_SAFE_FREE(tex->coba);
+       if (tex->env) {
+               BKE_texture_envmap_free(tex->env);
+               tex->env = NULL;
+       }
+       if (tex->pd) {
+               BKE_texture_pointdensity_free(tex->pd);
+               tex->pd = NULL;
+       }
+       if (tex->vd) {
+               BKE_texture_voxeldata_free(tex->vd);
+               tex->vd = NULL;
+       }
+       if (tex->ot) {
+               BKE_texture_ocean_free(tex->ot);
+               tex->ot = NULL;
+       }
+       
+       BKE_icon_id_delete((ID *)tex);
+       BKE_previewimg_free(&tex->preview);
 }
 
 /* ------------------------------------------------------------------------- */
index e4736b1f54c5fe1bc09a43502fff943df12ba142..95fa0679a99ee6e38f3a8e7eb74ca479bacf1705 100644 (file)
 
 #include "GPU_material.h"
 
-void BKE_world_free_ex(World *wrld, bool do_id_user)
+/**
+ * Free (or release) any data used by this world (does not free the world itself).
+ *
+ * \param wrld The world to free.
+ * \param do_id_user When \a true, ID datablocks used (referenced) by this world are 'released'
+ *                   (their user count is decreased).
+ */
+void BKE_world_free(World *wrld, const bool do_id_user)
 {
-       MTex *mtex;
        int a;
-       
-       for (a = 0; a < MAX_MTEX; a++) {
-               mtex = wrld->mtex[a];
-               if (do_id_user && mtex && mtex->tex) mtex->tex->id.us--;
-               if (mtex) MEM_freeN(mtex);
+
+       if (do_id_user) {
+               MTex *mtex;
+
+               for (a = 0; a < MAX_MTEX; a++) {
+                       mtex = wrld->mtex[a];
+                       if (mtex && mtex->tex) {
+                               id_us_min(&mtex->tex->id);
+                               mtex->tex = NULL;
+                       }
+               }
        }
-       BKE_previewimg_free(&wrld->preview);
 
        BKE_animdata_free((ID *)wrld);
 
+       for (a = 0; a < MAX_MTEX; a++) {
+               MEM_SAFE_FREE(wrld->mtex[a]);
+       }
+
        /* is no lib link block, but world extension */
        if (wrld->nodetree) {
-               ntreeFreeTree_ex(wrld->nodetree, do_id_user);
+               ntreeFreeTree(wrld->nodetree, do_id_user);
                MEM_freeN(wrld->nodetree);
+               wrld->nodetree = NULL;
        }
 
-       if (wrld->gpumaterial.first)
-               GPU_material_free(&wrld->gpumaterial);
+       GPU_material_free(&wrld->gpumaterial);
        
        BKE_icon_id_delete((struct ID *)wrld);
-       wrld->id.icon_id = 0;
-}
-
-void BKE_world_free(World *wrld)
-{
-       BKE_world_free_ex(wrld, true);
+       BKE_previewimg_free(&wrld->preview);
 }
 
 World *add_world(Main *bmain, const char *name)
index 220b4e908a613cf6bfae17a70087e055345a53fe..5202134833e17a7d80a12fdce57aaca1a3aac6cd 100644 (file)
@@ -94,7 +94,7 @@ void MaskOperation::initExecution()
                                frame_iter += frame_step;
                        }
 
-                       BKE_mask_free_nolib(mask_temp);
+                       BKE_mask_free(mask_temp, false);
                        MEM_freeN(mask_temp);
                }
        }
index 34e640a4b7baf1ea81c66c6dbedd3ac4cfc3cd66..eaa0cd5563c0e76a283769b0eef2249e6de6b567 100644 (file)
@@ -140,7 +140,7 @@ void gpencil_undo_push(bGPdata *gpd)
                         */
                        undo_node->gpd->adt = NULL;
                        
-                       BKE_gpencil_free(undo_node->gpd);
+                       BKE_gpencil_free(undo_node->gpd, false);
                        MEM_freeN(undo_node->gpd);
                        
                        BLI_freelinkN(&undo_nodes, undo_node);
@@ -168,7 +168,7 @@ void gpencil_undo_finish(void)
                 */
                undo_node->gpd->adt = NULL;
                
-               BKE_gpencil_free(undo_node->gpd);
+               BKE_gpencil_free(undo_node->gpd, false);
                MEM_freeN(undo_node->gpd);
                
                undo_node = undo_node->next;
index c101b416169a12a15b1d07e9aa81f1b65b937a60..736fef58a096fe343e593d5a2ca34153db4e5937 100644 (file)
@@ -591,7 +591,7 @@ static void free_undo(void *me_v)
 {
        Mesh *me = me_v;
        if (me->key) {
-               BKE_key_free(me->key);
+               BKE_key_free(me->key, false);
                MEM_freeN(me->key);
        }
 
index 2491685161c0e2f6fd29fe935fa63b784990e54f..9525e88bd6ffc4815def814436413c240438b3fa 100644 (file)
@@ -552,7 +552,7 @@ int join_mesh_exec(bContext *C, wmOperator *op)
                }
 #endif
                
-               BKE_key_free(nkey);
+               BKE_key_free(nkey, true);
                BLI_remlink(&bmain->key, nkey);
                MEM_freeN(nkey);
        }
index 6dfd2b31d3043113c333963ac21e2bbbe9178e09..575faa5703367f858e7f8316cf960f09e19098a2 100644 (file)
@@ -828,7 +828,7 @@ static void shader_preview_free(void *customdata)
                /* get rid of copied material */
                BLI_remlink(&pr_main->mat, sp->matcopy);
                
-               BKE_material_free_ex(sp->matcopy, false);
+               BKE_material_free(sp->matcopy, false);
 
                properties = IDP_GetProperties((ID *)sp->matcopy, false);
                if (properties) {
@@ -844,7 +844,7 @@ static void shader_preview_free(void *customdata)
                
                /* get rid of copied texture */
                BLI_remlink(&pr_main->tex, sp->texcopy);
-               BKE_texture_free(sp->texcopy);
+               BKE_texture_free(sp->texcopy, false);
                
                properties = IDP_GetProperties((ID *)sp->texcopy, false);
                if (properties) {
@@ -860,7 +860,7 @@ static void shader_preview_free(void *customdata)
                
                /* get rid of copied world */
                BLI_remlink(&pr_main->world, sp->worldcopy);
-               BKE_world_free_ex(sp->worldcopy, true); /* [#32865] - we need to unlink the texture copies, unlike for materials */
+               BKE_world_free(sp->worldcopy, true); /* [#32865] - we need to unlink the texture copies, unlike for materials */
                
                properties = IDP_GetProperties((ID *)sp->worldcopy, false);
                if (properties) {
@@ -876,7 +876,7 @@ static void shader_preview_free(void *customdata)
                
                /* get rid of copied lamp */
                BLI_remlink(&pr_main->lamp, sp->lampcopy);
-               BKE_lamp_free(sp->lampcopy);
+               BKE_lamp_free(sp->lampcopy, true);
                
                properties = IDP_GetProperties((ID *)sp->lampcopy, false);
                if (properties) {
index 1a1cc8894e631aad7fb7a345a1f8b0a808379646..f368f786a464ed786b736106cfb582c5227aca44 100644 (file)
@@ -494,7 +494,7 @@ static void screen_copy(bScreen *to, bScreen *from)
        ScrArea *sa, *saf;
        
        /* free contents of 'to', is from blenkernel screen.c */
-       BKE_screen_free(to);
+       BKE_screen_free(to, false);
        
        BLI_duplicatelist(&to->vertbase, &from->vertbase);
        BLI_duplicatelist(&to->edgebase, &from->edgebase);
@@ -1903,7 +1903,7 @@ ScrArea *ED_screen_state_toggle(bContext *C, wmWindow *win, ScrArea *sa, const s
 
                ED_screen_set(C, sc);
 
-               BKE_screen_free(oldscreen);
+               BKE_screen_free(oldscreen, false);
                BKE_libblock_free(CTX_data_main(C), oldscreen);
 
                /* After we've restored back to SCREENNORMAL, we have to wait with
index f8d84cc0276c1ac4fd9800642202b951fa509db2..d34f57577be50de65c92fb9de584fb8cbc36bb6f 100644 (file)
@@ -116,7 +116,7 @@ static int sound_open_exec(bContext *C, wmOperator *op)
        info = AUD_getInfo(sound->playback_handle);
 
        if (info.specs.channels == AUD_CHANNELS_INVALID) {
-               BKE_sound_delete(bmain, sound);
+               BKE_libblock_free(bmain, sound);
                if (op->customdata) MEM_freeN(op->customdata);
                BKE_report(op->reports, RPT_ERROR, "Unsupported audio format");
                return OPERATOR_CANCELLED;
index b57f95db4e6af11930e82be624a5609b350a5b0a..cdbdf48f1ba25ba00a27e7c9ea66012444559725 100644 (file)
@@ -623,7 +623,7 @@ static bool node_group_make_test_selected(bNodeTree *ntree, bNode *gnode, const
        }
        
        /* free local pseudo node tree again */
-       ntreeFreeTree(ngroup);
+       ntreeFreeTree(ngroup, true);
        MEM_freeN(ngroup);
        if (!ok)
                return false;
index b38f4fa67b6eab9d9ba47b704dc2de7396ece124..fcac879523eb147e11b2d346c449e3cda5f6bba7 100644 (file)
@@ -709,7 +709,7 @@ static Mask *rna_Main_mask_new(Main *bmain, const char *name)
 static void rna_Main_masks_remove(Main *bmain, PointerRNA *mask_ptr)
 {
        Mask *mask = mask_ptr->data;
-       BKE_mask_free(bmain, mask);
+       BKE_mask_unlink(bmain, mask);
        BKE_libblock_free(bmain, mask);
        RNA_POINTER_INVALIDATE(mask_ptr);
 }
@@ -718,7 +718,6 @@ static void rna_Main_grease_pencil_remove(Main *bmain, ReportList *reports, Poin
 {
        bGPdata *gpd = gpd_ptr->data;
        if (ID_REAL_USERS(gpd) <= 0) {
-               BKE_gpencil_free(gpd);
                BKE_libblock_free(bmain, gpd);
                RNA_POINTER_INVALIDATE(gpd_ptr);
        }
index c4ec55c8d06f543f0a54a64e36acac0f9f469349..c3dbe2b5fe383e6af7f223acd6804f0e9729c327 100644 (file)
@@ -209,7 +209,7 @@ void ntreeGPUMaterialNodes(bNodeTree *ntree, GPUMaterial *mat, short compatibili
        ntreeExecGPUNodes(exec, mat, 1, compatibility);
        ntreeShaderEndExecTree(exec);
 
-       ntreeFreeTree_ex(localtree, false);
+       ntreeFreeTree(localtree, false);
        MEM_freeN(localtree);
 }
 
index b282ec0593e12e4ab9f95f1e0762e6e683112056..2f3f69a7245fa3cf044dabab2af3d0211e22f443 100644 (file)
@@ -3655,7 +3655,8 @@ void RE_free_sample_material(Material *mat)
                        MTex *mtex= mat->mtex[tex_nr];
        
                        if (mtex->tex) {
-                               BKE_texture_free(mtex->tex);
+                               /* don't update user counts as we are freeing a duplicate */
+                               BKE_texture_free(mtex->tex, false);
                                MEM_freeN(mtex->tex);
                                mtex->tex = NULL;
                        }
@@ -3663,7 +3664,7 @@ void RE_free_sample_material(Material *mat)
        }
 
        /* don't update user counts as we are freeing a duplicate */
-       BKE_material_free_ex(mat, false);
+       BKE_material_free(mat, false);
        MEM_freeN(mat);
 }