diff options
Diffstat (limited to 'source/blender/blenkernel/intern')
31 files changed, 418 insertions, 734 deletions
diff --git a/source/blender/blenkernel/intern/action.c b/source/blender/blenkernel/intern/action.c index ae1604a94b5..b77ae45e94d 100644 --- a/source/blender/blenkernel/intern/action.c +++ b/source/blender/blenkernel/intern/action.c @@ -159,25 +159,22 @@ void BKE_action_make_local(bAction *act) /* .................................. */ -/** - * 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. */ - +void BKE_action_free(bAction *act) +{ + /* sanity check */ + if (act == NULL) + return; + /* Free F-Curves */ free_fcurves(&act->curves); /* Free groups */ - BLI_freelistN(&act->groups); + if (act->groups.first) + BLI_freelistN(&act->groups); /* Free pose-references (aka local markers) */ - BLI_freelistN(&act->markers); + if (act->markers.first) + BLI_freelistN(&act->markers); } /* .................................. */ diff --git a/source/blender/blenkernel/intern/armature.c b/source/blender/blenkernel/intern/armature.c index fc698f35b71..6afe7f1abe9 100644 --- a/source/blender/blenkernel/intern/armature.c +++ b/source/blender/blenkernel/intern/armature.c @@ -106,31 +106,30 @@ void BKE_armature_bonelist_free(ListBase *lb) BLI_freelistN(lb); } -/** - * 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)) +void BKE_armature_free(bArmature *arm) { - BKE_animdata_free(&arm->id); + if (arm) { + BKE_armature_bonelist_free(&arm->bonebase); - BKE_armature_bonelist_free(&arm->bonebase); + /* free editmode data */ + if (arm->edbo) { + BLI_freelistN(arm->edbo); - /* free editmode data */ - if (arm->edbo) { - BLI_freelistN(arm->edbo); + MEM_freeN(arm->edbo); + arm->edbo = NULL; + } - MEM_freeN(arm->edbo); - arm->edbo = NULL; - } + /* free sketch */ + if (arm->sketch) { + freeSketch(arm->sketch); + arm->sketch = NULL; + } - /* free sketch */ - if (arm->sketch) { - freeSketch(arm->sketch); - arm->sketch = NULL; + /* free animation data */ + if (arm->adt) { + BKE_animdata_free(&arm->id); + arm->adt = NULL; + } } } diff --git a/source/blender/blenkernel/intern/brush.c b/source/blender/blenkernel/intern/brush.c index 3c7f753e3d8..e0ffd830804 100644 --- a/source/blender/blenkernel/intern/brush.c +++ b/source/blender/blenkernel/intern/brush.c @@ -197,45 +197,22 @@ Brush *BKE_brush_copy(Brush *brush) return brushn; } -/** - * 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) +/* not brush itself */ +void BKE_brush_free(Brush *brush) { - if (do_id_user) { - if (brush->mtex.tex) { - id_us_min(&brush->mtex.tex->id); - brush->mtex.tex = NULL; - } + id_us_min((ID *)brush->mtex.tex); + id_us_min((ID *)brush->mask_mtex.tex); + id_us_min((ID *)brush->paint_curve); - if (brush->mask_mtex.tex) { - id_us_min(&brush->mask_mtex.tex->id); - brush->mask_mtex.tex = NULL; - } - - 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) { + if (brush->icon_imbuf) IMB_freeImBuf(brush->icon_imbuf); - } - curvemapping_free(brush->curve); + BKE_previewimg_free(&(brush->preview)); - MEM_SAFE_FREE(brush->gradient); + curvemapping_free(brush->curve); - BKE_previewimg_free(&(brush->preview)); + if (brush->gradient) + MEM_freeN(brush->gradient); } static void extern_local_brush(Brush *brush) diff --git a/source/blender/blenkernel/intern/camera.c b/source/blender/blenkernel/intern/camera.c index eb99022d034..7e043df2808 100644 --- a/source/blender/blenkernel/intern/camera.c +++ b/source/blender/blenkernel/intern/camera.c @@ -144,20 +144,8 @@ void BKE_camera_make_local(Camera *cam) } } -/** - * 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) +void BKE_camera_free(Camera *ca) { - if (do_id_user) { - /* No ID refcount here... */ - ca->dof_ob = NULL; - } - BKE_animdata_free((ID *)ca); } diff --git a/source/blender/blenkernel/intern/curve.c b/source/blender/blenkernel/intern/curve.c index e01813e0b88..8d7d62be7e4 100644 --- a/source/blender/blenkernel/intern/curve.c +++ b/source/blender/blenkernel/intern/curve.c @@ -69,6 +69,35 @@ 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) { @@ -110,63 +139,26 @@ void BKE_curve_editNurb_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) +/* don't free curve itself */ +void BKE_curve_free(Curve *cu) { - 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); - 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); + 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); } Curve *BKE_curve_add(Main *bmain, const char *name, int type) diff --git a/source/blender/blenkernel/intern/font.c b/source/blender/blenkernel/intern/font.c index a8339b567dc..e3ebb7f908c 100644 --- a/source/blender/blenkernel/intern/font.c +++ b/source/blender/blenkernel/intern/font.c @@ -95,15 +95,10 @@ void BKE_vfont_free_data(struct VFont *vfont) } } -/** - * 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)) +void BKE_vfont_free(struct VFont *vf) { + if (vf == NULL) return; + BKE_vfont_free_data(vf); if (vf->packedfile) { diff --git a/source/blender/blenkernel/intern/gpencil.c b/source/blender/blenkernel/intern/gpencil.c index 8779f0d5f0e..ee5c9192371 100644 --- a/source/blender/blenkernel/intern/gpencil.c +++ b/source/blender/blenkernel/intern/gpencil.c @@ -112,19 +112,16 @@ void free_gpencil_layers(ListBase *list) } /* Free all of GPencil datablock's related data, but not the block itself */ -/** - * 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)) +void BKE_gpencil_free(bGPdata *gpd) { - 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 ---------- */ diff --git a/source/blender/blenkernel/intern/group.c b/source/blender/blenkernel/intern/group.c index 68987e21a74..3f68339be11 100644 --- a/source/blender/blenkernel/intern/group.c +++ b/source/blender/blenkernel/intern/group.c @@ -60,26 +60,17 @@ static void free_group_object(GroupObject *go) MEM_freeN(go); } -/** - * 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)) + +void BKE_group_free(Group *group) { /* don't free group itself */ GroupObject *go; - /* No animdata here. */ + BKE_previewimg_free(&group->preview); while ((go = BLI_pophead(&group->gobject))) { free_group_object(go); } - - BKE_previewimg_free(&group->preview); } void BKE_group_unlink(Group *group) @@ -141,8 +132,7 @@ void BKE_group_unlink(Group *group) } /* group stays in library, but no members */ - /* XXX This is suspicious, means we keep a dangling, empty group? Also, does not take into account fakeuser? */ - BKE_group_free(group, false); + BKE_group_free(group); group->id.us = 0; } diff --git a/source/blender/blenkernel/intern/image.c b/source/blender/blenkernel/intern/image.c index 4563b18a822..1b329815493 100644 --- a/source/blender/blenkernel/intern/image.c +++ b/source/blender/blenkernel/intern/image.c @@ -329,22 +329,20 @@ void BKE_image_free_buffers(Image *ima) ima->ok = IMA_OK; } -/** - * 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)) +/* called by library too, do not free ima itself */ +void BKE_image_free(Image *ima) { 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]); @@ -353,10 +351,7 @@ void BKE_image_free(Image *ima, const bool UNUSED(do_id_user)) } image_free_views(ima); - MEM_SAFE_FREE(ima->stereo3d_format); - - BKE_icon_id_delete(&ima->id); - BKE_previewimg_free(&ima->preview); + MEM_freeN(ima->stereo3d_format); } /* only image block itself */ diff --git a/source/blender/blenkernel/intern/key.c b/source/blender/blenkernel/intern/key.c index b1e12588962..362f41335d2 100644 --- a/source/blender/blenkernel/intern/key.c +++ b/source/blender/blenkernel/intern/key.c @@ -74,22 +74,9 @@ #define IPO_BEZTRIPLE 100 #define IPO_BPOINT 101 - -/** - * 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) +void BKE_key_free(Key *key) { KeyBlock *kb; - - if (do_id_user) { - /* No ID refcount here... */ - key->from = NULL; - } BKE_animdata_free((ID *)key); diff --git a/source/blender/blenkernel/intern/lamp.c b/source/blender/blenkernel/intern/lamp.c index 48498440fa9..44e35c645de 100644 --- a/source/blender/blenkernel/intern/lamp.c +++ b/source/blender/blenkernel/intern/lamp.c @@ -210,48 +210,30 @@ void BKE_lamp_make_local(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) +void BKE_lamp_free(Lamp *la) { + MTex *mtex; int a; - 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]); + mtex = la->mtex[a]; + if (mtex && mtex->tex) mtex->tex->id.us--; + if (mtex) MEM_freeN(mtex); } + BKE_animdata_free((ID *)la); + curvemapping_free(la->curfalloff); - la->curfalloff = NULL; /* is no lib link block, but lamp extension */ if (la->nodetree) { - ntreeFreeTree(la->nodetree, do_id_user); + ntreeFreeTree(la->nodetree); MEM_freeN(la->nodetree); - la->nodetree = NULL; } - BKE_icon_id_delete(&la->id); BKE_previewimg_free(&la->preview); + BKE_icon_id_delete(&la->id); + la->id.icon_id = 0; } /* Calculate all drivers for lamps, see material_drivers_update for why this is a bad hack */ diff --git a/source/blender/blenkernel/intern/lattice.c b/source/blender/blenkernel/intern/lattice.c index cb9b0c09f64..009e1d20328 100644 --- a/source/blender/blenkernel/intern/lattice.c +++ b/source/blender/blenkernel/intern/lattice.c @@ -293,40 +293,24 @@ Lattice *BKE_lattice_copy(Lattice *lt) return ltn; } -/** - * 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) +void BKE_lattice_free(Lattice *lt) { - if (do_id_user) { - if (lt->key) { - id_us_min(<->key->id); - lt->key = NULL; - } - } - - BKE_animdata_free(<->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->def) MEM_freeN(lt->def); + if (lt->dvert) BKE_defvert_array_free(lt->dvert, lt->pntsu * lt->pntsv * lt->pntsw); 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); - lt->editlatt = NULL; + } + + /* free animation data */ + if (lt->adt) { + BKE_animdata_free(<->id); + lt->adt = NULL; } } diff --git a/source/blender/blenkernel/intern/library.c b/source/blender/blenkernel/intern/library.c index b24eb6510d2..d6b2a3cea29 100644 --- a/source/blender/blenkernel/intern/library.c +++ b/source/blender/blenkernel/intern/library.c @@ -890,7 +890,7 @@ void BKE_libblock_relink(ID *id) BKE_library_foreach_ID_link(id, id_relink_looper, NULL, 0); } -static void library_free(Library *lib, const bool UNUSED(do_id_user)) +static void BKE_library_free(Library *lib) { if (lib->packedfile) freePackedFile(lib->packedfile); @@ -951,10 +951,7 @@ 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 - * - * \param do_id_user if \a true, try to release other ID's 'references' hold by \a idv. */ +/* used in headerbuttons.c image.c mesh.c screen.c sound.c and library.c */ void BKE_libblock_free_ex(Main *bmain, void *idv, bool do_id_user) { ID *id = idv; @@ -969,107 +966,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, do_id_user); + BKE_scene_free((Scene *)id); break; case ID_LI: - library_free((Library *)id, do_id_user); + BKE_library_free((Library *)id); break; case ID_OB: - BKE_object_free((Object *)id, do_id_user); + BKE_object_free_ex((Object *)id, do_id_user); break; case ID_ME: - BKE_mesh_free((Mesh *)id, do_id_user); + BKE_mesh_free((Mesh *)id, 1); break; case ID_CU: - BKE_curve_free((Curve *)id, do_id_user); + BKE_curve_free((Curve *)id); break; case ID_MB: - BKE_mball_free((MetaBall *)id, do_id_user); + BKE_mball_free((MetaBall *)id); break; case ID_MA: - BKE_material_free((Material *)id, do_id_user); + BKE_material_free((Material *)id); break; case ID_TE: - BKE_texture_free((Tex *)id, do_id_user); + BKE_texture_free((Tex *)id); break; case ID_IM: - BKE_image_free((Image *)id, do_id_user); + BKE_image_free((Image *)id); break; case ID_LT: - BKE_lattice_free((Lattice *)id, do_id_user); + BKE_lattice_free((Lattice *)id); break; case ID_LA: - BKE_lamp_free((Lamp *)id, do_id_user); + BKE_lamp_free((Lamp *)id); break; case ID_CA: - BKE_camera_free((Camera *) id, do_id_user); + BKE_camera_free((Camera *) id); break; - case ID_IP: /* Deprecated. */ + case ID_IP: BKE_ipo_free((Ipo *)id); break; case ID_KE: - BKE_key_free((Key *)id, do_id_user); + BKE_key_free((Key *)id); break; case ID_WO: - BKE_world_free((World *)id, do_id_user); + BKE_world_free((World *)id); break; case ID_SCR: - BKE_screen_free((bScreen *)id, do_id_user); + BKE_screen_free((bScreen *)id); break; case ID_VF: - BKE_vfont_free((VFont *)id, do_id_user); + BKE_vfont_free((VFont *)id); break; case ID_TXT: - BKE_text_free((Text *)id, do_id_user); + BKE_text_free((Text *)id); break; case ID_SCRIPT: /* deprecated */ break; case ID_SPK: - BKE_speaker_free((Speaker *)id, do_id_user); + BKE_speaker_free((Speaker *)id); break; case ID_SO: - BKE_sound_free((bSound *)id, do_id_user); + BKE_sound_free((bSound *)id); break; case ID_GR: - BKE_group_free((Group *)id, do_id_user); + BKE_group_free((Group *)id); break; case ID_AR: - BKE_armature_free((bArmature *)id, do_id_user); + BKE_armature_free((bArmature *)id); break; case ID_AC: - BKE_action_free((bAction *)id, do_id_user); + BKE_action_free((bAction *)id); break; case ID_NT: - ntreeFreeTree((bNodeTree *)id, do_id_user); + ntreeFreeTree_ex((bNodeTree *)id, do_id_user); break; case ID_BR: - BKE_brush_free((Brush *)id, do_id_user); + BKE_brush_free((Brush *)id); break; case ID_PA: - BKE_particlesettings_free((ParticleSettings *)id, do_id_user); + BKE_particlesettings_free((ParticleSettings *)id); break; case ID_WM: if (free_windowmanager_cb) free_windowmanager_cb(NULL, (wmWindowManager *)id); break; case ID_GD: - BKE_gpencil_free((bGPdata *)id, do_id_user); + BKE_gpencil_free((bGPdata *)id); break; case ID_MC: - BKE_movieclip_free((MovieClip *)id, do_id_user); + BKE_movieclip_free((MovieClip *)id); break; case ID_MSK: - BKE_mask_free((Mask *)id, do_id_user); + BKE_mask_free(bmain, (Mask *)id); break; case ID_LS: - BKE_linestyle_free((FreestyleLineStyle *)id, do_id_user); + BKE_linestyle_free((FreestyleLineStyle *)id); break; case ID_PAL: - BKE_palette_free((Palette *)id, do_id_user); + BKE_palette_free((Palette *)id); break; case ID_PC: - BKE_paint_curve_free((PaintCurve *)id, do_id_user); + BKE_paint_curve_free((PaintCurve *)id); break; } diff --git a/source/blender/blenkernel/intern/linestyle.c b/source/blender/blenkernel/intern/linestyle.c index 0875321a779..ac2c4e35dce 100644 --- a/source/blender/blenkernel/intern/linestyle.c +++ b/source/blender/blenkernel/intern/linestyle.c @@ -123,43 +123,24 @@ FreestyleLineStyle *BKE_linestyle_new(struct Main *bmain, const char *name) return 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) +void BKE_linestyle_free(FreestyleLineStyle *linestyle) { LineStyleModifier *m; - 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); + MTex *mtex; + int a; for (a = 0; a < MAX_MTEX; a++) { - MEM_SAFE_FREE(linestyle->mtex[a]); + mtex = linestyle->mtex[a]; + if (mtex && mtex->tex) mtex->tex->id.us--; + if (mtex) MEM_freeN(mtex); } - - /* is no lib link block, but linestyle extension */ if (linestyle->nodetree) { - ntreeFreeTree(linestyle->nodetree, true); /* XXX Or do_id_user? */ + ntreeFreeTree(linestyle->nodetree); 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)) @@ -177,7 +158,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, true); + BKE_linestyle_free(new_linestyle); for (a = 0; a < MAX_MTEX; a++) { if (linestyle->mtex[a]) { diff --git a/source/blender/blenkernel/intern/mask.c b/source/blender/blenkernel/intern/mask.c index 62a2b73a971..141597e859c 100644 --- a/source/blender/blenkernel/intern/mask.c +++ b/source/blender/blenkernel/intern/mask.c @@ -1016,22 +1016,13 @@ void BKE_mask_layer_free_list(ListBase *masklayers) } } -/** - * 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)) +/** free for temp copy, but don't manage unlinking from other pointers */ +void BKE_mask_free_nolib(Mask *mask) { - BKE_animdata_free((ID *)mask); - - /* free mask data */ BKE_mask_layer_free_list(&mask->masklayers); } -void BKE_mask_unlink(Main *bmain, Mask *mask) +void BKE_mask_free(Main *bmain, Mask *mask) { bScreen *scr; ScrArea *area; @@ -1082,6 +1073,9 @@ void BKE_mask_unlink(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]) diff --git a/source/blender/blenkernel/intern/material.c b/source/blender/blenkernel/intern/material.c index 300485c2c0a..3e7e98b4a1d 100644 --- a/source/blender/blenkernel/intern/material.c +++ b/source/blender/blenkernel/intern/material.c @@ -81,54 +81,45 @@ void init_def_material(void) init_material(&defmaterial); } -/** - * 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) +/* not material itself */ +void BKE_material_free(Material *ma) { - 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_material_free_ex(ma, true); +} - BKE_animdata_free((ID *)ma); +/* not material itself */ +void BKE_material_free_ex(Material *ma, bool do_id_user) +{ + MTex *mtex; + int a; for (a = 0; a < MAX_MTEX; a++) { - MEM_SAFE_FREE(ma->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->ramp_col); - MEM_SAFE_FREE(ma->ramp_spec); + 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; /* is no lib link block, but material extension */ if (ma->nodetree) { - ntreeFreeTree(ma->nodetree, do_id_user); + ntreeFreeTree_ex(ma->nodetree, do_id_user); MEM_freeN(ma->nodetree); - ma->nodetree = NULL; } - MEM_SAFE_FREE(ma->texpaintslot); - - GPU_material_free(&ma->gpumaterial); + if (ma->texpaintslot) + MEM_freeN(ma->texpaintslot); - BKE_icon_id_delete((ID *)ma); - BKE_previewimg_free(&ma->preview); + if (ma->gpumaterial.first) + GPU_material_free(&ma->gpumaterial); } void init_material(Material *ma) @@ -1766,7 +1757,7 @@ void free_matcopybuf(void) matcopybuf.ramp_spec = NULL; if (matcopybuf.nodetree) { - ntreeFreeTree(matcopybuf.nodetree, false); + ntreeFreeTree_ex(matcopybuf.nodetree, false); MEM_freeN(matcopybuf.nodetree); matcopybuf.nodetree = NULL; } @@ -1816,7 +1807,7 @@ void paste_matcopybuf(Material *ma) } if (ma->nodetree) { - ntreeFreeTree(ma->nodetree, true); /* XXX Or do_id_user? */ + ntreeFreeTree(ma->nodetree); MEM_freeN(ma->nodetree); } diff --git a/source/blender/blenkernel/intern/mball.c b/source/blender/blenkernel/intern/mball.c index 89c6a7d00b9..c09cd1aabdc 100644 --- a/source/blender/blenkernel/intern/mball.c +++ b/source/blender/blenkernel/intern/mball.c @@ -66,32 +66,29 @@ /* Functions */ -/** - * 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) +void BKE_mball_unlink(MetaBall *mb) { - if (do_id_user) { - int a; + int a; - for (a = 0; a < mb->totcol; a++) { - if (mb->mat[a]) { - id_us_min(&mb->mat[a]->id); - mb->mat[a] = NULL; - } - } + for (a = 0; a < mb->totcol; a++) { + if (mb->mat[a]) mb->mat[a]->id.us--; + 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); - BKE_displist_free(&mb->disp); + if (mb->disp.first) BKE_displist_free(&mb->disp); } MetaBall *BKE_mball_add(Main *bmain, const char *name) diff --git a/source/blender/blenkernel/intern/mesh.c b/source/blender/blenkernel/intern/mesh.c index 327025c3e9a..b948ed56c56 100644 --- a/source/blender/blenkernel/intern/mesh.c +++ b/source/blender/blenkernel/intern/mesh.c @@ -430,38 +430,32 @@ bool BKE_mesh_has_custom_loop_normals(Mesh *me) * we need a more generic method, like the expand() functions in * readfile.c */ - -/** - * 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) +void BKE_mesh_unlink(Mesh *me) { - if (do_id_user) { - int a; + int a; - 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 == NULL) return; - if (me->key) { - id_us_min(&me->key->id); - me->key = NULL; + if (me->mat) { + for (a = 0; a < me->totcol; a++) { + if (me->mat[a]) me->mat[a]->id.us--; + me->mat[a] = NULL; } - - /* No ID refcount here... */ - me->texcomesh = NULL; } - BKE_animdata_free(&me->id); + if (me->key) { + me->key->id.us--; + } + me->key = NULL; + + if (me->texcomesh) me->texcomesh = NULL; +} + +/* do not free mesh itself */ +void BKE_mesh_free(Mesh *me, int unlink) +{ + if (unlink) + BKE_mesh_unlink(me); CustomData_free(&me->vdata, me->totvert); CustomData_free(&me->edata, me->totedge); @@ -469,10 +463,16 @@ void BKE_mesh_free(Mesh *me, const bool do_id_user) CustomData_free(&me->ldata, me->totloop); CustomData_free(&me->pdata, me->totpoly); - MEM_SAFE_FREE(me->mat); - MEM_SAFE_FREE(me->bb); - MEM_SAFE_FREE(me->mselect); - MEM_SAFE_FREE(me->edit_btmesh); + 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); } static void mesh_tessface_clear_intern(Mesh *mesh, int free_customdata) diff --git a/source/blender/blenkernel/intern/movieclip.c b/source/blender/blenkernel/intern/movieclip.c index 70d36155ad5..432ae32f02b 100644 --- a/source/blender/blenkernel/intern/movieclip.c +++ b/source/blender/blenkernel/intern/movieclip.c @@ -44,7 +44,6 @@ #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" @@ -1414,23 +1413,8 @@ void BKE_movieclip_build_proxy_frame_for_ibuf(MovieClip *clip, ImBuf *ibuf, stru } } -/** - * 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) +void BKE_movieclip_free(MovieClip *clip) { - 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); diff --git a/source/blender/blenkernel/intern/node.c b/source/blender/blenkernel/intern/node.c index b256e11c538..c656931d18b 100644 --- a/source/blender/blenkernel/intern/node.c +++ b/source/blender/blenkernel/intern/node.c @@ -38,7 +38,6 @@ #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" @@ -1776,35 +1775,21 @@ 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(ngroup, false); + ntreeFreeTree_ex(ngroup, false); MEM_freeN(ngroup); } } } -/** - * 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) +/* do not free ntree itself here, BKE_libblock_free calls this function too */ +void ntreeFreeTree_ex(bNodeTree *ntree, const bool do_id_user) { bNodeTree *tntree; bNode *node, *next; bNodeSocket *sock, *nextsock; - - 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); - + + if (ntree == NULL) return; + /* 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 @@ -1828,6 +1813,10 @@ void ntreeFreeTree(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) { @@ -1878,6 +1867,11 @@ void ntreeFreeTree(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) { @@ -2151,7 +2145,7 @@ void ntreeLocalMerge(bNodeTree *localtree, bNodeTree *ntree) if (ntree->typeinfo->local_merge) ntree->typeinfo->local_merge(localtree, ntree); - ntreeFreeTree(localtree, false); + ntreeFreeTree_ex(localtree, false); MEM_freeN(localtree); } } diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c index 4ef30c06fe5..e5f826f670d 100644 --- a/source/blender/blenkernel/intern/object.c +++ b/source/blender/blenkernel/intern/object.c @@ -40,7 +40,6 @@ #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" @@ -380,63 +379,55 @@ void BKE_object_free_caches(Object *object) } } -/** - * 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) +/* do not free object itself */ +void BKE_object_free_ex(Object *ob, bool do_id_user) { - /* Needs valid obdata pointer... */ + int a; + BKE_object_free_derived_caches(ob); - - 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; - } + + /* 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; } } + ob->data = NULL; + } - if (ob->poselib) { - id_us_min(&ob->poselib->id); - ob->poselib = NULL; - } - if (ob->gpd) { - id_us_min(&ob->gpd->id); - ob->gpd = NULL; + if (ob->mat) { + for (a = 0; a < ob->totcol; a++) { + if (ob->mat[a]) ob->mat[a]->id.us--; } + MEM_freeN(ob->mat); } - - BKE_animdata_free((ID *)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) { + 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_pose_free_ex(ob->pose, do_id_user); - ob->pose = NULL; - } - if (ob->mpath) { + if (ob->mpath) animviz_free_motionpath(ob->mpath); - ob->mpath = NULL; - } BKE_bproperty_free_list(&ob->prop); BKE_object_free_modifiers(ob); @@ -450,19 +441,13 @@ void BKE_object_free(Object *ob, const bool do_id_user) BKE_rigidbody_free_object(ob); BKE_rigidbody_free_constraint(ob); - if (ob->soft) { - sbFree(ob->soft); - ob->soft = NULL; - } - if (ob->bsoft) { - bsbFree(ob->bsoft); - ob->bsoft = NULL; - } - GPU_lamp_free(ob); + if (ob->soft) sbFree(ob->soft); + if (ob->bsoft) bsbFree(ob->bsoft); + if (ob->gpulamp.first) GPU_lamp_free(ob); BKE_sculptsession_free(ob); - BLI_freelistN(&ob->pc_ids); + if (ob->pc_ids.first) BLI_freelistN(&ob->pc_ids); BLI_freelistN(&ob->lodlevels); @@ -472,12 +457,16 @@ void BKE_object_free(Object *ob, const 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, int UNUSED(cd_flag)) { Object *unlinkOb = userData; @@ -489,9 +478,6 @@ 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; diff --git a/source/blender/blenkernel/intern/paint.c b/source/blender/blenkernel/intern/paint.c index 90c07280a61..06844b09a9b 100644 --- a/source/blender/blenkernel/intern/paint.c +++ b/source/blender/blenkernel/intern/paint.c @@ -298,17 +298,13 @@ void BKE_paint_brush_set(Paint *p, Brush *br) } } -/** - * 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)) +void BKE_paint_curve_free(PaintCurve *pc) { - MEM_SAFE_FREE(pc->points); - pc->tot_points = 0; + if (pc->points) { + MEM_freeN(pc->points); + pc->points = NULL; + pc->tot_points = 0; + } } PaintCurve *BKE_paint_curve_add(Main *bmain, const char *name) @@ -382,14 +378,7 @@ Palette *BKE_palette_add(Main *bmain, const char *name) return 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)) +void BKE_palette_free(Palette *palette) { BLI_freelistN(&palette->colors); } diff --git a/source/blender/blenkernel/intern/particle.c b/source/blender/blenkernel/intern/particle.c index 90c9a71f4ee..9aacba8d02e 100644 --- a/source/blender/blenkernel/intern/particle.c +++ b/source/blender/blenkernel/intern/particle.c @@ -371,40 +371,12 @@ static void fluid_free_settings(SPHFluidSettings *fluid) MEM_freeN(fluid); } -/** - * 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) +void BKE_particlesettings_free(ParticleSettings *part) { + 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) @@ -413,13 +385,19 @@ void BKE_particlesettings_free(ParticleSettings *part, const bool do_id_user) free_partdeflect(part->pd); free_partdeflect(part->pd2); - MEM_SAFE_FREE(part->effector_weights); + if (part->effector_weights) + MEM_freeN(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) diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c index 8f0437109a5..1ccc213006a 100644 --- a/source/blender/blenkernel/intern/scene.c +++ b/source/blender/blenkernel/intern/scene.c @@ -360,73 +360,41 @@ void BKE_scene_groups_relink(Scene *sce) BKE_rigidbody_world_groups_relink(sce->rigidbody_world); } -/** - * 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) +/* do not free scene itself */ +void BKE_scene_free(Scene *sce) { + Base *base; SceneRenderLayer *srl; - if (do_id_user) { - Base *base; - - 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); + /* check all sequences */ + BKE_sequencer_clear_scene_in_allseqs(G.main, sce); - 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); + 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--; #endif - sce->gpd = NULL; - } - - /* No ID refcount here... */ - sce->camera = NULL; - sce->set = NULL; - sce->clip = NULL; + sce->gpd = 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); - - /* 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) { + + 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); @@ -479,8 +447,15 @@ void BKE_scene_free(Scene *sce, const bool do_id_user) if (sce->depsgraph) DEG_graph_free(sce->depsgraph); - MEM_SAFE_FREE(sce->stats); - MEM_SAFE_FREE(sce->fps_info); + 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); BKE_sound_destroy_scene(sce); diff --git a/source/blender/blenkernel/intern/screen.c b/source/blender/blenkernel/intern/screen.c index 4dd67f5ecff..7401ef28f62 100644 --- a/source/blender/blenkernel/intern/screen.c +++ b/source/blender/blenkernel/intern/screen.c @@ -357,19 +357,11 @@ void BKE_screen_area_free(ScrArea *sa) BLI_freelistN(&sa->actionzones); } -/** - * 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)) +/* don't free screen itself */ +void BKE_screen_free(bScreen *sc) { ScrArea *sa, *san; ARegion *ar; - - /* No animdata here. */ for (ar = sc->regionbase.first; ar; ar = ar->next) BKE_area_region_free(NULL, ar); diff --git a/source/blender/blenkernel/intern/sequencer.c b/source/blender/blenkernel/intern/sequencer.c index fe197fb4122..fc8fa616d20 100644 --- a/source/blender/blenkernel/intern/sequencer.c +++ b/source/blender/blenkernel/intern/sequencer.c @@ -3036,7 +3036,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(mask_temp, false); + BKE_mask_free_nolib(mask_temp); MEM_freeN(mask_temp); BKE_maskrasterize_buffer(mr_handle, context->rectx, context->recty, maskbuf); @@ -5026,7 +5026,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_libblock_free(bmain, sound); + BKE_sound_delete(bmain, sound); #if 0 if (op) BKE_report(op->reports, RPT_ERROR, "Unsupported audio format"); diff --git a/source/blender/blenkernel/intern/sound.c b/source/blender/blenkernel/intern/sound.c index 53d6d8b5d10..7e7cc8745fd 100644 --- a/source/blender/blenkernel/intern/sound.c +++ b/source/blender/blenkernel/intern/sound.c @@ -123,17 +123,8 @@ bSound *BKE_sound_new_file_exists(struct Main *bmain, const char *filepath) return BKE_sound_new_file_exists_ex(bmain, filepath, NULL); } -/** - * 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)) +void BKE_sound_free(bSound *sound) { - /* No animdata here. */ - if (sound->packedfile) { freePackedFile(sound->packedfile); sound->packedfile = NULL; @@ -157,7 +148,8 @@ void BKE_sound_free(bSound *sound, const bool UNUSED(do_id_user)) BLI_spin_end(sound->spinlock); MEM_freeN(sound->spinlock); sound->spinlock = NULL; - } + } + #endif /* WITH_AUDASPACE */ } @@ -323,6 +315,15 @@ 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; diff --git a/source/blender/blenkernel/intern/speaker.c b/source/blender/blenkernel/intern/speaker.c index 96a6dc35a1a..7a800555144 100644 --- a/source/blender/blenkernel/intern/speaker.c +++ b/source/blender/blenkernel/intern/speaker.c @@ -125,21 +125,10 @@ void BKE_speaker_make_local(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) +void BKE_speaker_free(Speaker *spk) { - if (do_id_user) { - if (spk->sound) { - id_us_min(&spk->sound->id); - spk->sound = NULL; - } - } + if (spk->sound) + spk->sound->id.us--; BKE_animdata_free((ID *)spk); } diff --git a/source/blender/blenkernel/intern/text.c b/source/blender/blenkernel/intern/text.c index d5d2e169aa3..77d6043d6f3 100644 --- a/source/blender/blenkernel/intern/text.c +++ b/source/blender/blenkernel/intern/text.c @@ -152,19 +152,10 @@ static void init_undo_text(Text *text) text->undo_buf = MEM_mallocN(text->undo_len, "undo buf"); } -/** - * 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)) +void BKE_text_free(Text *text) { TextLine *tmp; - /* No animdata here. */ - for (tmp = text->lines.first; tmp; tmp = tmp->next) { MEM_freeN(tmp->line); if (tmp->format) @@ -173,10 +164,10 @@ void BKE_text_free(Text *text, const bool UNUSED(do_id_user)) BLI_freelistN(&text->lines); - MEM_SAFE_FREE(text->name); - MEM_SAFE_FREE(text->undo_buf); + if (text->name) MEM_freeN(text->name); + MEM_freeN(text->undo_buf); #ifdef WITH_PYTHON - BPY_text_free_code(text); + if (text->compiled) BPY_text_free_code(text); #endif } diff --git a/source/blender/blenkernel/intern/texture.c b/source/blender/blenkernel/intern/texture.c index ef1863e555b..88a412d5e95 100644 --- a/source/blender/blenkernel/intern/texture.c +++ b/source/blender/blenkernel/intern/texture.c @@ -557,51 +557,23 @@ int colorband_element_remove(struct ColorBand *coba, int index) /* ******************* 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) +void BKE_texture_free(Tex *tex) { - 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->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 (tex->nodetree) { - ntreeFreeTree(tex->nodetree, do_id_user); + ntreeFreeTree(tex->nodetree); 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); } /* ------------------------------------------------------------------------- */ diff --git a/source/blender/blenkernel/intern/world.c b/source/blender/blenkernel/intern/world.c index 95fa0679a99..e4736b1f54c 100644 --- a/source/blender/blenkernel/intern/world.c +++ b/source/blender/blenkernel/intern/world.c @@ -51,46 +51,36 @@ #include "GPU_material.h" -/** - * 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) +void BKE_world_free_ex(World *wrld, bool do_id_user) { + MTex *mtex; int a; - - 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; - } - } + + 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); } + 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(wrld->nodetree, do_id_user); + ntreeFreeTree_ex(wrld->nodetree, do_id_user); MEM_freeN(wrld->nodetree); - wrld->nodetree = NULL; } - GPU_material_free(&wrld->gpumaterial); + if (wrld->gpumaterial.first) + GPU_material_free(&wrld->gpumaterial); BKE_icon_id_delete((struct ID *)wrld); - BKE_previewimg_free(&wrld->preview); + wrld->id.icon_id = 0; +} + +void BKE_world_free(World *wrld) +{ + BKE_world_free_ex(wrld, true); } World *add_world(Main *bmain, const char *name) |