Add option to Copy the active view layer, and add an empty view layer

Modify the view layer add operator (and underlying `BKE_view_layer_add`)
to allow for copying the current view layer, as well as adding a new one
but with all LayerCollections disabled by default (this is important for
heavy scenes where currently adding view layers can take a long time due
to enabling every collection by default).

Reviewed By: mont29

Differential Revision: https://developer.blender.org/D6862
This commit is contained in:
Chris Clyne 2020-03-26 19:33:27 +01:00 committed by Bastien Montagne
parent 839f0cfa41
commit d1972e50cb
6 changed files with 85 additions and 16 deletions

View File

@ -44,10 +44,19 @@ struct Scene;
struct View3D;
struct ViewLayer;
typedef enum eViewLayerCopyMethod {
VIEWLAYER_ADD_NEW = 0,
VIEWLAYER_ADD_EMPTY = 1,
VIEWLAYER_ADD_COPY = 2,
} eViewLayerCopyMethod;
struct ViewLayer *BKE_view_layer_default_view(const struct Scene *scene);
struct ViewLayer *BKE_view_layer_default_render(const struct Scene *scene);
struct ViewLayer *BKE_view_layer_find(const struct Scene *scene, const char *layer_name);
struct ViewLayer *BKE_view_layer_add(struct Scene *scene, const char *name);
struct ViewLayer *BKE_view_layer_add(Scene *scene,
const char *name,
ViewLayer *view_layer_source,
const int type);
/* DEPRECATED */
struct ViewLayer *BKE_view_layer_context_active_PLACEHOLDER(const struct Scene *scene);

View File

@ -178,27 +178,70 @@ static ViewLayer *view_layer_add(const char *name)
return view_layer;
}
static void layer_collection_exclude_all(LayerCollection *layer_collection)
{
LayerCollection *sub_collection = layer_collection->layer_collections.first;
for (; sub_collection != NULL; sub_collection = sub_collection->next) {
sub_collection->flag |= LAYER_COLLECTION_EXCLUDE;
layer_collection_exclude_all(sub_collection);
}
}
/**
* Add a new view layer
* by default, a view layer has the master collection
*/
ViewLayer *BKE_view_layer_add(Scene *scene, const char *name)
ViewLayer *BKE_view_layer_add(Scene *scene,
const char *name,
ViewLayer *view_layer_source,
const int type)
{
ViewLayer *view_layer = view_layer_add(name);
ViewLayer *view_layer_new;
BLI_addtail(&scene->view_layers, view_layer);
if (view_layer_source) {
name = view_layer_source->name;
}
switch (type) {
default:
case VIEWLAYER_ADD_NEW: {
view_layer_new = view_layer_add(name);
BLI_addtail(&scene->view_layers, view_layer_new);
BKE_layer_collection_sync(scene, view_layer_new);
break;
}
case VIEWLAYER_ADD_COPY: {
/* Allocate and copy view layer data */
view_layer_new = MEM_callocN(sizeof(ViewLayer), "View Layer");
BLI_addtail(&scene->view_layers, view_layer_new);
BKE_view_layer_copy_data(scene, scene, view_layer_new, view_layer_source, 0);
BLI_strncpy_utf8(view_layer_new->name, name, sizeof(view_layer_new->name));
break;
}
case VIEWLAYER_ADD_EMPTY: {
view_layer_new = view_layer_add(name);
BLI_addtail(&scene->view_layers, view_layer_new);
/* Initialise layercollections */
BKE_layer_collection_sync(scene, view_layer_new);
layer_collection_exclude_all(view_layer_new->layer_collections.first);
/* Update collections after changing visibility */
BKE_layer_collection_sync(scene, view_layer_new);
break;
}
}
/* unique name */
BLI_uniquename(&scene->view_layers,
view_layer,
view_layer_new,
DATA_("ViewLayer"),
'.',
offsetof(ViewLayer, name),
sizeof(view_layer->name));
sizeof(view_layer_new->name));
BKE_layer_collection_sync(scene, view_layer);
return view_layer;
return view_layer_new;
}
void BKE_view_layer_free(ViewLayer *view_layer)

View File

@ -211,7 +211,7 @@ static void scene_init_data(ID *id)
/* Master Collection */
scene->master_collection = BKE_collection_master_add();
BKE_view_layer_add(scene, "View Layer");
BKE_view_layer_add(scene, "View Layer", NULL, VIEWLAYER_ADD_NEW);
}
static void scene_copy_data(Main *bmain, ID *id_dst, const ID *id_src, const int flag)

View File

@ -462,7 +462,7 @@ static void do_version_layers_to_collections(Main *bmain, Scene *scene)
const bool need_default_renderlayer = scene->r.layers.first == NULL;
for (SceneRenderLayer *srl = scene->r.layers.first; srl; srl = srl->next) {
ViewLayer *view_layer = BKE_view_layer_add(scene, srl->name);
ViewLayer *view_layer = BKE_view_layer_add(scene, srl->name, NULL, VIEWLAYER_ADD_NEW);
if (srl->layflag & SCE_LAY_DISABLE) {
view_layer->flag &= ~VIEW_LAYER_RENDER;
@ -528,7 +528,7 @@ static void do_version_layers_to_collections(Main *bmain, Scene *scene)
/* If render layers included overrides, or there are no render layers,
* we also create a vanilla viewport layer. */
if (have_override || need_default_renderlayer) {
ViewLayer *view_layer = BKE_view_layer_add(scene, "Viewport");
ViewLayer *view_layer = BKE_view_layer_add(scene, "Viewport", NULL, VIEWLAYER_ADD_NEW);
/* If we ported all the original render layers,
* we don't need to make the viewport layer renderable. */

View File

@ -814,14 +814,16 @@ void WORLD_OT_new(wmOperatorType *ot)
/********************** render layer operators *********************/
static int view_layer_add_exec(bContext *C, wmOperator *UNUSED(op))
static int view_layer_add_exec(bContext *C, wmOperator *op)
{
wmWindow *win = CTX_wm_window(C);
Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = BKE_view_layer_add(scene, NULL);
ViewLayer *view_layer_current = WM_window_get_active_view_layer(win);
ViewLayer *view_layer_new = BKE_view_layer_add(
scene, view_layer_current->name, view_layer_current, RNA_enum_get(op->ptr, "type"));
if (win) {
WM_window_set_active_view_layer(win, view_layer);
WM_window_set_active_view_layer(win, view_layer_new);
}
DEG_id_tag_update(&scene->id, 0);
@ -833,6 +835,17 @@ static int view_layer_add_exec(bContext *C, wmOperator *UNUSED(op))
void SCENE_OT_view_layer_add(wmOperatorType *ot)
{
static EnumPropertyItem type_items[] = {
{VIEWLAYER_ADD_NEW, "NEW", 0, "New", "Add a new view layer"},
{VIEWLAYER_ADD_COPY, "COPY", 0, "Copy Settings", "Copy settings of current view layer"},
{VIEWLAYER_ADD_EMPTY,
"EMPTY",
0,
"Blank",
"Add a new view layer with all collections disabled"},
{0, NULL, 0, NULL, NULL},
};
/* identifiers */
ot->name = "Add View Layer";
ot->idname = "SCENE_OT_view_layer_add";
@ -840,9 +853,13 @@ void SCENE_OT_view_layer_add(wmOperatorType *ot)
/* api callbacks */
ot->exec = view_layer_add_exec;
ot->invoke = WM_menu_invoke;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
/* properties */
ot->prop = RNA_def_enum(ot->srna, "type", type_items, 0, "Type", "");
}
static bool view_layer_remove_poll(bContext *C)

View File

@ -2340,7 +2340,7 @@ static void rna_Stereo3dFormat_update(Main *bmain, Scene *UNUSED(scene), Pointer
static ViewLayer *rna_ViewLayer_new(ID *id, Scene *UNUSED(sce), Main *bmain, const char *name)
{
Scene *scene = (Scene *)id;
ViewLayer *view_layer = BKE_view_layer_add(scene, name);
ViewLayer *view_layer = BKE_view_layer_add(scene, name, NULL, VIEWLAYER_ADD_NEW);
DEG_id_tag_update(&scene->id, 0);
DEG_relations_tag_update(bmain);