Fix/properly implement: "make group proxy"

This was never correctly implemented. It now works as expected (ala 2.79 behaviour).
The proxy object is added to all the collections of the original empty.

Before not only this wasn't the case, but it would crash Blender.
This commit is contained in:
Dalai Felinto 2017-10-19 18:01:41 -02:00
parent 4d2416b99c
commit fc10484f7c
Notes: blender-bot 2023-02-14 06:27:47 +01:00
Referenced by issue #53108, Proxy creation error
3 changed files with 58 additions and 21 deletions

View File

@ -91,9 +91,13 @@ struct Object *BKE_object_add_only_object(
int type, const char *name)
ATTR_NONNULL(1) ATTR_RETURNS_NONNULL;
struct Object *BKE_object_add(
struct Main *bmain, struct Scene *scene, struct SceneLayer *sl,
struct Main *bmain, struct Scene *scene, struct SceneLayer *scene_layer,
int type, const char *name)
ATTR_NONNULL(1, 2, 3) ATTR_RETURNS_NONNULL;
struct Object *BKE_object_add_from(
struct Main *bmain, struct Scene *scene, struct SceneLayer *scene_layer,
int type, const char *name, struct Object *ob_src)
ATTR_NONNULL(1, 2, 3, 6) ATTR_RETURNS_NONNULL;
void *BKE_object_obdata_add_from_type(
struct Main *bmain,
int type, const char *name)

View File

@ -724,32 +724,65 @@ Object *BKE_object_add_only_object(Main *bmain, int type, const char *name)
return ob;
}
/* general add: to scene, with layer from area and default name */
/* creates minimum required data, but without vertices etc. */
Object *BKE_object_add(
Main *bmain, Scene *scene, SceneLayer *sl,
int type, const char *name)
static Object *object_add_common(Main *bmain, SceneLayer *scene_layer, int type, const char *name)
{
Object *ob;
Base *base;
LayerCollection *lc;
ob = BKE_object_add_only_object(bmain, type, name);
ob->data = BKE_object_obdata_add_from_type(bmain, type, name);
lc = BKE_layer_collection_get_active_ensure(scene, sl);
BKE_collection_object_add(scene, lc->scene_collection, ob);
base = BKE_scene_layer_base_find(sl, ob);
BKE_scene_layer_base_deselect_all(sl);
BKE_scene_layer_base_select(sl, base);
BKE_scene_layer_base_deselect_all(scene_layer);
DEG_id_tag_update_ex(bmain, &ob->id, OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME);
return ob;
}
/**
* General add: to scene, with layer from area and default name
*
* Object is added to the active SceneCollection.
* If there is no linked collection to the active SceneLayer we create a new one.
*/
/* creates minimum required data, but without vertices etc. */
Object *BKE_object_add(
Main *bmain, Scene *scene, SceneLayer *scene_layer,
int type, const char *name)
{
Object *ob;
Base *base;
LayerCollection *layer_collection;
ob = object_add_common(bmain, scene_layer, type, name);
layer_collection = BKE_layer_collection_get_active_ensure(scene, scene_layer);
BKE_collection_object_add(scene, layer_collection->scene_collection, ob);
base = BKE_scene_layer_base_find(scene_layer, ob);
BKE_scene_layer_base_select(scene_layer, base);
return ob;
}
/**
* Add a new object, using another one as a reference
*
* /param ob_src object to use to determine the collections of the new object.
*/
Object *BKE_object_add_from(
Main *bmain, Scene *scene, SceneLayer *scene_layer,
int type, const char *name, Object *ob_src)
{
Object *ob;
Base *base;
ob = object_add_common(bmain, scene_layer, type, name);
BKE_collection_object_add_from(scene, ob_src, ob);
base = BKE_scene_layer_base_find(scene_layer, ob);
BKE_scene_layer_base_select(scene_layer, base);
return ob;
}
#ifdef WITH_GAMEENGINE

View File

@ -341,7 +341,7 @@ static int make_proxy_exec(bContext *C, wmOperator *op)
Object *ob, *gob = ED_object_active_context(C);
GroupObject *go;
Scene *scene = CTX_data_scene(C);
SceneLayer *sl = CTX_data_scene_layer(C);
SceneLayer *scene_layer = CTX_data_scene_layer(C);
if (gob->dup_group != NULL) {
go = BLI_findlink(&gob->dup_group->gobject, RNA_enum_get(op->ptr, "object"));
@ -354,16 +354,16 @@ static int make_proxy_exec(bContext *C, wmOperator *op)
if (ob) {
Object *newob;
BaseLegacy *newbase, *oldbase = BASACT_NEW(sl);
Base *newbase, *oldbase = BASACT_NEW(scene_layer);
char name[MAX_ID_NAME + 4];
BLI_snprintf(name, sizeof(name), "%s_proxy", ((ID *)(gob ? gob : ob))->name + 2);
/* Add new object for the proxy */
newob = BKE_object_add(bmain, scene, sl, OB_EMPTY, name);
newob = BKE_object_add_from(bmain, scene, scene_layer, OB_EMPTY, name, gob ? gob : ob);
/* set layers OK */
newbase = BASACT_NEW(sl); /* BKE_object_add sets active... */
newbase = BASACT_NEW(scene_layer); /* BKE_object_add sets active... */
newbase->lay = oldbase->lay;
newob->lay = newbase->lay;