Refactor: Remove `BKE_XXX_localize()`, in favor of using regular ID copying code.
Besides the NodeTree case (which remains unchanged), the localize code is only used in one place (to generate previews of shading data-blocks). This commit introduces a new `LIB_ID_CREATE_LOCAL` option for ID creation/copying, which essentially implements the behavior of the removed `BKE_XXX_localize()` functions into regular mainstream ID copy code. When this option is set: - new ID is tagged with `LIB_TAG_LOCALIZED`; - Some ID copying callbacks have specific behaviors, mainly the root nodetree of shading IDs gets duplicated with specialized `ntreeLocalize()` function. Note that I would not consider getting rid of `ntreeLocalize` for now, this function is recursive, which should ideally never happen within ID management copying code (this introduces all kind of complications). No behavioral change expected from this commit.
This commit is contained in:
parent
94f91827f8
commit
874cf52c10
|
@ -99,6 +99,12 @@ enum {
|
|||
/** Do not tag new ID for update in depsgraph. */
|
||||
LIB_ID_CREATE_NO_DEG_TAG = 1 << 8,
|
||||
|
||||
/** Very similar to #LIB_ID_CREATE_NO_MAIN, and should never be used with it (typically combined
|
||||
* with #LIB_ID_CREATE_LOCALIZE or #LIB_ID_COPY_LOCALIZE in fact).
|
||||
* It ensures that IDs created with it will get the #LIB_TAG_LOCALIZED tag, and uses some
|
||||
* specific code in some copy cases (mostly for node trees). */
|
||||
LIB_ID_CREATE_LOCAL = 1 << 9,
|
||||
|
||||
/* *** Specific options to some ID types or usages. *** */
|
||||
/* *** May be ignored by unrelated ID copying functions. *** */
|
||||
/** Object only, needed by make_local code. */
|
||||
|
|
|
@ -36,7 +36,6 @@ struct Main;
|
|||
|
||||
struct Light *BKE_light_add(struct Main *bmain, const char *name) ATTR_WARN_UNUSED_RESULT;
|
||||
struct Light *BKE_light_copy(struct Main *bmain, const struct Light *la) ATTR_WARN_UNUSED_RESULT;
|
||||
struct Light *BKE_light_localize(struct Light *la) ATTR_WARN_UNUSED_RESULT;
|
||||
|
||||
void BKE_light_eval(struct Depsgraph *depsgraph, struct Light *la);
|
||||
|
||||
|
|
|
@ -54,7 +54,6 @@ void BKE_object_material_remap_calc(struct Object *ob_dst,
|
|||
struct Material *BKE_material_add(struct Main *bmain, const char *name);
|
||||
struct Material *BKE_gpencil_material_add(struct Main *bmain, const char *name);
|
||||
struct Material *BKE_material_copy(struct Main *bmain, const struct Material *ma);
|
||||
struct Material *BKE_material_localize(struct Material *ma);
|
||||
void BKE_gpencil_material_attr_init(struct Material *ma);
|
||||
|
||||
/* UNUSED */
|
||||
|
|
|
@ -47,7 +47,6 @@ void BKE_texture_mtex_foreach_id(struct LibraryForeachIDData *data, struct MTex
|
|||
void BKE_texture_default(struct Tex *tex);
|
||||
struct Tex *BKE_texture_copy(struct Main *bmain, const struct Tex *tex);
|
||||
struct Tex *BKE_texture_add(struct Main *bmain, const char *name);
|
||||
struct Tex *BKE_texture_localize(struct Tex *tex);
|
||||
void BKE_texture_type_set(struct Tex *tex, int type);
|
||||
|
||||
void BKE_texture_mtex_default(struct MTex *mtex);
|
||||
|
|
|
@ -31,7 +31,6 @@ struct Main;
|
|||
struct World;
|
||||
|
||||
struct World *BKE_world_add(struct Main *bmain, const char *name);
|
||||
struct World *BKE_world_localize(struct World *wrld);
|
||||
void BKE_world_eval(struct Depsgraph *depsgraph, struct World *world);
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
@ -1035,6 +1035,8 @@ void *BKE_libblock_alloc_notest(short type)
|
|||
void *BKE_libblock_alloc(Main *bmain, short type, const char *name, const int flag)
|
||||
{
|
||||
BLI_assert((flag & LIB_ID_CREATE_NO_ALLOCATE) == 0);
|
||||
BLI_assert((flag & LIB_ID_CREATE_NO_MAIN) != 0 || bmain != NULL);
|
||||
BLI_assert((flag & LIB_ID_CREATE_NO_MAIN) != 0 || (flag & LIB_ID_CREATE_LOCAL) == 0);
|
||||
|
||||
ID *id = BKE_libblock_alloc_notest(type);
|
||||
|
||||
|
@ -1045,6 +1047,9 @@ void *BKE_libblock_alloc(Main *bmain, short type, const char *name, const int fl
|
|||
if ((flag & LIB_ID_CREATE_NO_USER_REFCOUNT) != 0) {
|
||||
id->tag |= LIB_TAG_NO_USER_REFCOUNT;
|
||||
}
|
||||
if (flag & LIB_ID_CREATE_LOCAL) {
|
||||
id->tag |= LIB_TAG_LOCALIZED;
|
||||
}
|
||||
|
||||
id->icon_id = 0;
|
||||
*((short *)id->name) = type;
|
||||
|
@ -1180,6 +1185,7 @@ void BKE_libblock_copy_ex(Main *bmain, const ID *id, ID **r_newid, const int ori
|
|||
|
||||
BLI_assert((flag & LIB_ID_CREATE_NO_MAIN) != 0 || bmain != NULL);
|
||||
BLI_assert((flag & LIB_ID_CREATE_NO_MAIN) != 0 || (flag & LIB_ID_CREATE_NO_ALLOCATE) == 0);
|
||||
BLI_assert((flag & LIB_ID_CREATE_NO_MAIN) != 0 || (flag & LIB_ID_CREATE_LOCAL) == 0);
|
||||
if (!is_private_id_data) {
|
||||
/* When we are handling private ID data, we might still want to manage usercounts, even
|
||||
* though that ID data-block is actually outside of Main... */
|
||||
|
|
|
@ -81,13 +81,21 @@ static void light_copy_data(Main *bmain, ID *id_dst, const ID *id_src, const int
|
|||
{
|
||||
Light *la_dst = (Light *)id_dst;
|
||||
const Light *la_src = (const Light *)id_src;
|
||||
|
||||
const bool is_localized = (flag & LIB_ID_CREATE_LOCAL) != 0;
|
||||
/* We always need allocation of our private ID data. */
|
||||
const int flag_private_id_data = flag & ~LIB_ID_CREATE_NO_ALLOCATE;
|
||||
|
||||
la_dst->curfalloff = BKE_curvemapping_copy(la_src->curfalloff);
|
||||
|
||||
if (la_src->nodetree) {
|
||||
BKE_id_copy_ex(bmain, (ID *)la_src->nodetree, (ID **)&la_dst->nodetree, flag_private_id_data);
|
||||
if (is_localized) {
|
||||
la_dst->nodetree = ntreeLocalize(la_src->nodetree);
|
||||
}
|
||||
else {
|
||||
BKE_id_copy_ex(
|
||||
bmain, (ID *)la_src->nodetree, (ID **)&la_dst->nodetree, flag_private_id_data);
|
||||
}
|
||||
}
|
||||
|
||||
if ((flag & LIB_ID_COPY_NO_PREVIEW) == 0) {
|
||||
|
@ -219,33 +227,6 @@ Light *BKE_light_copy(Main *bmain, const Light *la)
|
|||
return la_copy;
|
||||
}
|
||||
|
||||
Light *BKE_light_localize(Light *la)
|
||||
{
|
||||
/* TODO(bastien): Replace with something like:
|
||||
*
|
||||
* Light *la_copy;
|
||||
* BKE_id_copy_ex(bmain, &la->id, (ID **)&la_copy,
|
||||
* LIB_ID_COPY_NO_MAIN | LIB_ID_COPY_NO_PREVIEW | LIB_ID_COPY_NO_USER_REFCOUNT,
|
||||
* false);
|
||||
* return la_copy;
|
||||
*
|
||||
* NOTE: Only possible once nested node trees are fully converted to that too. */
|
||||
|
||||
Light *lan = BKE_libblock_copy_for_localize(&la->id);
|
||||
|
||||
lan->curfalloff = BKE_curvemapping_copy(la->curfalloff);
|
||||
|
||||
if (la->nodetree) {
|
||||
lan->nodetree = ntreeLocalize(la->nodetree);
|
||||
}
|
||||
|
||||
lan->preview = NULL;
|
||||
|
||||
lan->id.tag |= LIB_TAG_LOCALIZED;
|
||||
|
||||
return lan;
|
||||
}
|
||||
|
||||
void BKE_light_eval(struct Depsgraph *depsgraph, Light *la)
|
||||
{
|
||||
DEG_debug_print_eval(depsgraph, __func__, la->id.name, la);
|
||||
|
|
|
@ -100,12 +100,20 @@ static void material_copy_data(Main *bmain, ID *id_dst, const ID *id_src, const
|
|||
Material *material_dst = (Material *)id_dst;
|
||||
const Material *material_src = (const Material *)id_src;
|
||||
|
||||
const bool is_localized = (flag & LIB_ID_CREATE_LOCAL) != 0;
|
||||
/* We always need allocation of our private ID data. */
|
||||
const int flag_private_id_data = flag & ~LIB_ID_CREATE_NO_ALLOCATE;
|
||||
|
||||
if (material_src->nodetree) {
|
||||
BKE_id_copy_ex(
|
||||
bmain, (ID *)material_src->nodetree, (ID **)&material_dst->nodetree, flag_private_id_data);
|
||||
if (material_src->nodetree != NULL) {
|
||||
if (is_localized) {
|
||||
material_dst->nodetree = ntreeLocalize(material_src->nodetree);
|
||||
}
|
||||
else {
|
||||
BKE_id_copy_ex(bmain,
|
||||
(ID *)material_src->nodetree,
|
||||
(ID **)&material_dst->nodetree,
|
||||
flag_private_id_data);
|
||||
}
|
||||
}
|
||||
|
||||
if ((flag & LIB_ID_COPY_NO_PREVIEW) == 0) {
|
||||
|
@ -116,7 +124,8 @@ static void material_copy_data(Main *bmain, ID *id_dst, const ID *id_src, const
|
|||
}
|
||||
|
||||
if (material_src->texpaintslot != NULL) {
|
||||
material_dst->texpaintslot = MEM_dupallocN(material_src->texpaintslot);
|
||||
/* TODO: Think we can also skip copying this data in the more generic `NO_MAIN` case? */
|
||||
material_dst->texpaintslot = is_localized ? NULL : MEM_dupallocN(material_src->texpaintslot);
|
||||
}
|
||||
|
||||
if (material_src->gp_style != NULL) {
|
||||
|
@ -315,41 +324,6 @@ Material *BKE_material_copy(Main *bmain, const Material *ma)
|
|||
return ma_copy;
|
||||
}
|
||||
|
||||
/* XXX (see above) material copy without adding to main dbase */
|
||||
Material *BKE_material_localize(Material *ma)
|
||||
{
|
||||
/* TODO(bastien): Replace with something like:
|
||||
*
|
||||
* Material *ma_copy;
|
||||
* BKE_id_copy_ex(bmain, &ma->id, (ID **)&ma_copy,
|
||||
* LIB_ID_COPY_NO_MAIN | LIB_ID_COPY_NO_PREVIEW | LIB_ID_COPY_NO_USER_REFCOUNT,
|
||||
* false);
|
||||
* return ma_copy;
|
||||
*
|
||||
* NOTE: Only possible once nested node trees are fully converted to that too. */
|
||||
|
||||
Material *man = BKE_libblock_copy_for_localize(&ma->id);
|
||||
|
||||
man->texpaintslot = NULL;
|
||||
man->preview = NULL;
|
||||
|
||||
if (ma->nodetree != NULL) {
|
||||
man->nodetree = ntreeLocalize(ma->nodetree);
|
||||
}
|
||||
|
||||
if (ma->gp_style != NULL) {
|
||||
man->gp_style = MEM_dupallocN(ma->gp_style);
|
||||
}
|
||||
|
||||
BLI_listbase_clear(&man->gpumaterial);
|
||||
|
||||
/* TODO Duplicate Engine Settings and set runtime to NULL */
|
||||
|
||||
man->id.tag |= LIB_TAG_LOCALIZED;
|
||||
|
||||
return man;
|
||||
}
|
||||
|
||||
Material ***BKE_object_material_array_p(Object *ob)
|
||||
{
|
||||
if (ob->type == OB_MESH) {
|
||||
|
|
|
@ -87,6 +87,7 @@ static void texture_copy_data(Main *bmain, ID *id_dst, const ID *id_src, const i
|
|||
Tex *texture_dst = (Tex *)id_dst;
|
||||
const Tex *texture_src = (const Tex *)id_src;
|
||||
|
||||
const bool is_localized = (flag & LIB_ID_CREATE_LOCAL) != 0;
|
||||
/* We always need allocation of our private ID data. */
|
||||
const int flag_private_id_data = flag & ~LIB_ID_CREATE_NO_ALLOCATE;
|
||||
|
||||
|
@ -101,8 +102,14 @@ static void texture_copy_data(Main *bmain, ID *id_dst, const ID *id_src, const i
|
|||
if (texture_src->nodetree->execdata) {
|
||||
ntreeTexEndExecTree(texture_src->nodetree->execdata);
|
||||
}
|
||||
BKE_id_copy_ex(
|
||||
bmain, (ID *)texture_src->nodetree, (ID **)&texture_dst->nodetree, flag_private_id_data);
|
||||
|
||||
if (is_localized) {
|
||||
texture_dst->nodetree = ntreeLocalize(texture_src->nodetree);
|
||||
}
|
||||
else {
|
||||
BKE_id_copy_ex(
|
||||
bmain, (ID *)texture_src->nodetree, (ID **)&texture_dst->nodetree, flag_private_id_data);
|
||||
}
|
||||
}
|
||||
|
||||
if ((flag & LIB_ID_COPY_NO_PREVIEW) == 0) {
|
||||
|
@ -455,40 +462,6 @@ Tex *BKE_texture_copy(Main *bmain, const Tex *tex)
|
|||
return tex_copy;
|
||||
}
|
||||
|
||||
/* texture copy without adding to main dbase */
|
||||
Tex *BKE_texture_localize(Tex *tex)
|
||||
{
|
||||
/* TODO(bastien): Replace with something like:
|
||||
*
|
||||
* Tex *tex_copy;
|
||||
* BKE_id_copy_ex(bmain, &tex->id, (ID **)&tex_copy,
|
||||
* LIB_ID_COPY_NO_MAIN | LIB_ID_COPY_NO_PREVIEW | LIB_ID_COPY_NO_USER_REFCOUNT,
|
||||
* false);
|
||||
* return tex_copy;
|
||||
*
|
||||
* NOTE: Only possible once nested node trees are fully converted to that too. */
|
||||
|
||||
Tex *texn;
|
||||
|
||||
texn = BKE_libblock_copy_for_localize(&tex->id);
|
||||
|
||||
/* image texture: texture_free_data also doesn't decrease */
|
||||
|
||||
if (texn->coba) {
|
||||
texn->coba = MEM_dupallocN(texn->coba);
|
||||
}
|
||||
|
||||
texn->preview = NULL;
|
||||
|
||||
if (tex->nodetree) {
|
||||
texn->nodetree = ntreeLocalize(tex->nodetree);
|
||||
}
|
||||
|
||||
texn->id.tag |= LIB_TAG_LOCALIZED;
|
||||
|
||||
return texn;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
Tex *give_current_linestyle_texture(FreestyleLineStyle *linestyle)
|
||||
|
|
|
@ -99,12 +99,19 @@ static void world_copy_data(Main *bmain, ID *id_dst, const ID *id_src, const int
|
|||
{
|
||||
World *wrld_dst = (World *)id_dst;
|
||||
const World *wrld_src = (const World *)id_src;
|
||||
|
||||
const bool is_localized = (flag & LIB_ID_CREATE_LOCAL) != 0;
|
||||
/* We always need allocation of our private ID data. */
|
||||
const int flag_private_id_data = flag & ~LIB_ID_CREATE_NO_ALLOCATE;
|
||||
|
||||
if (wrld_src->nodetree) {
|
||||
BKE_id_copy_ex(
|
||||
bmain, (ID *)wrld_src->nodetree, (ID **)&wrld_dst->nodetree, flag_private_id_data);
|
||||
if (is_localized) {
|
||||
wrld_dst->nodetree = ntreeLocalize(wrld_src->nodetree);
|
||||
}
|
||||
else {
|
||||
BKE_id_copy_ex(
|
||||
bmain, (ID *)wrld_src->nodetree, (ID **)&wrld_dst->nodetree, flag_private_id_data);
|
||||
}
|
||||
}
|
||||
|
||||
BLI_listbase_clear(&wrld_dst->gpumaterial);
|
||||
|
@ -210,36 +217,6 @@ World *BKE_world_add(Main *bmain, const char *name)
|
|||
return wrld;
|
||||
}
|
||||
|
||||
World *BKE_world_localize(World *wrld)
|
||||
{
|
||||
/* TODO(bastien): Replace with something like:
|
||||
*
|
||||
* World *wrld_copy;
|
||||
* BKE_id_copy_ex(bmain, &wrld->id, (ID **)&wrld_copy,
|
||||
* LIB_ID_COPY_NO_MAIN | LIB_ID_COPY_NO_PREVIEW | LIB_ID_COPY_NO_USER_REFCOUNT,
|
||||
* false);
|
||||
* return wrld_copy;
|
||||
*
|
||||
* NOTE: Only possible once nested node trees are fully converted to that too. */
|
||||
|
||||
World *wrldn;
|
||||
|
||||
wrldn = BKE_libblock_copy_for_localize(&wrld->id);
|
||||
|
||||
if (wrld->nodetree) {
|
||||
wrldn->nodetree = ntreeLocalize(wrld->nodetree);
|
||||
}
|
||||
|
||||
wrldn->preview = NULL;
|
||||
|
||||
BLI_listbase_clear(&wrldn->gpumaterial);
|
||||
BLI_listbase_clear((ListBase *)&wrldn->drawdata);
|
||||
|
||||
wrldn->id.tag |= LIB_TAG_LOCALIZED;
|
||||
|
||||
return wrldn;
|
||||
}
|
||||
|
||||
void BKE_world_eval(struct Depsgraph *depsgraph, World *world)
|
||||
{
|
||||
DEG_debug_print_eval(depsgraph, __func__, world->id.name, world);
|
||||
|
|
|
@ -325,7 +325,13 @@ static World *preview_get_localized_world(ShaderPreview *sp, World *world)
|
|||
if (sp->worldcopy != NULL) {
|
||||
return sp->worldcopy;
|
||||
}
|
||||
sp->worldcopy = BKE_world_localize(world);
|
||||
|
||||
ID *id_copy;
|
||||
BKE_id_copy_ex(NULL,
|
||||
&world->id,
|
||||
&id_copy,
|
||||
LIB_ID_CREATE_LOCAL | LIB_ID_COPY_LOCALIZE | LIB_ID_COPY_NO_ANIMDATA);
|
||||
sp->worldcopy = (World *)id_copy;
|
||||
BLI_addtail(&sp->pr_main->worlds, sp->worldcopy);
|
||||
return sp->worldcopy;
|
||||
}
|
||||
|
@ -339,13 +345,16 @@ static ID *duplicate_ids(ID *id)
|
|||
|
||||
switch (GS(id->name)) {
|
||||
case ID_MA:
|
||||
return (ID *)BKE_material_localize((Material *)id);
|
||||
case ID_TE:
|
||||
return (ID *)BKE_texture_localize((Tex *)id);
|
||||
case ID_LA:
|
||||
return (ID *)BKE_light_localize((Light *)id);
|
||||
case ID_WO:
|
||||
return (ID *)BKE_world_localize((World *)id);
|
||||
case ID_WO: {
|
||||
ID *id_copy;
|
||||
BKE_id_copy_ex(NULL,
|
||||
id,
|
||||
&id_copy,
|
||||
LIB_ID_CREATE_LOCAL | LIB_ID_COPY_LOCALIZE | LIB_ID_COPY_NO_ANIMDATA);
|
||||
return id_copy;
|
||||
}
|
||||
case ID_IM:
|
||||
case ID_BR:
|
||||
case ID_SCR:
|
||||
|
|
Loading…
Reference in New Issue