Compare commits
82 Commits
modifier-p
...
temp-dynam
Author | SHA1 | Date | |
---|---|---|---|
![]() |
fbaf6e6fb3 | ||
bba0ad903c | |||
2acf4ace51 | |||
d8f5a68f63 | |||
088691254e | |||
6ee25c9d55 | |||
![]() |
a54079eecd | ||
![]() |
20d5fd36a1 | ||
![]() |
344c2d4674 | ||
![]() |
c303f2a19b | ||
![]() |
b173b96c09 | ||
![]() |
f30056d512 | ||
b06deeca25 | |||
![]() |
07bf151062 | ||
![]() |
d341b62351 | ||
![]() |
55d611ad5e | ||
![]() |
dd5f69e251 | ||
![]() |
e20ec83765 | ||
![]() |
3e946a6f13 | ||
![]() |
fc4c3fc35c | ||
![]() |
83e068f5df | ||
![]() |
f319e0081b | ||
![]() |
8655ed28fe | ||
![]() |
c9172b65db | ||
![]() |
dcb18ab6c9 | ||
![]() |
f7301293b9 | ||
![]() |
7265f6c25c | ||
![]() |
8fb93aebe7 | ||
bab887fbfe | |||
e7e792f0f4 | |||
![]() |
a5ca6d752e | ||
![]() |
e6128bd177 | ||
![]() |
f837bd1f76 | ||
![]() |
7bd6590594 | ||
5165ab5877 | |||
35716a8f46 | |||
f1b10fa29d | |||
f5cada3f7d | |||
e3d6d9d3ac | |||
c69ed97473 | |||
![]() |
68e861059f | ||
![]() |
50771589a7 | ||
![]() |
814fc6aafc | ||
![]() |
666a3b6161 | ||
![]() |
a278a97232 | ||
![]() |
0441110c86 | ||
![]() |
612d78712c | ||
![]() |
ba1d1a6923 | ||
![]() |
2b92e40e03 | ||
42f6406d4f | |||
17a209ea02 | |||
ddbfe00827 | |||
35bdc45bbd | |||
70673c6a6b | |||
c046771ecb | |||
1ec126887e | |||
05f8453496 | |||
df32088b95 | |||
5d6950a49a | |||
![]() |
bba8f86558 | ||
![]() |
2d82574494 | ||
2e802e56c5 | |||
![]() |
0b3200cb43 | ||
ffee223857 | |||
61dc857877 | |||
![]() |
c532c4fc25 | ||
![]() |
7e9d2fd984 | ||
![]() |
543bed5b85 | ||
![]() |
4b40ed48c2 | ||
![]() |
107a457891 | ||
![]() |
8a27c1c8a6 | ||
![]() |
b0332b8490 | ||
![]() |
cd52967d1c | ||
![]() |
1dd9396ced | ||
![]() |
e2346f7378 | ||
![]() |
76c9d4db2e | ||
![]() |
a4a5f4b1e5 | ||
![]() |
33c3e293be | ||
![]() |
5978102ec5 | ||
![]() |
fc54b5034a | ||
![]() |
7f808eb601 | ||
![]() |
189b31c937 |
@@ -71,9 +71,168 @@ class VIEWLAYER_PT_eevee_layer_passes(ViewLayerButtonsPanel, Panel):
|
||||
col.prop(view_layer, "use_pass_subsurface_color", text="Subsurface Color")
|
||||
|
||||
|
||||
class VIEWLAYER_UL_override_sets(UIList):
|
||||
def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index):
|
||||
row = layout.row(align=True)
|
||||
row.prop(item, "use", text="", index=index)
|
||||
row.prop(item, "name", text="", index=index, icon_value=icon, emboss=False)
|
||||
|
||||
|
||||
class ViewLayerOverridesPanel():
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
return context.view_layer.override_sets.active
|
||||
|
||||
@staticmethod
|
||||
def _icon_from_id_type(id_type):
|
||||
return id_type + '_DATA'
|
||||
|
||||
@staticmethod
|
||||
def _value_name_override_mode_get(data_type, data_subtype):
|
||||
"""
|
||||
return Tuple: value name and whether the property supports override modes
|
||||
"""
|
||||
# TODO: Finish this.
|
||||
proptype_map = {
|
||||
'BOOLEAN': {
|
||||
'NONE': ("value_boolean", False)},
|
||||
'INT': {
|
||||
'NONE': ("value_int", True)},
|
||||
'FLOAT': {
|
||||
'NONE': ("value_float", True),
|
||||
'COLOR': ("value_color", False)},
|
||||
'STRING': {
|
||||
'NONE': (None, False)},
|
||||
'ENUM': {
|
||||
'NONE': (None, False)},
|
||||
'POINTER': {
|
||||
'NONE': (None, False)},
|
||||
'COLLECTION': {
|
||||
'NONE': (None, False)},
|
||||
}
|
||||
|
||||
type_lookup = proptype_map[data_type]
|
||||
value_name = type_lookup.get(data_subtype)
|
||||
|
||||
if value_name is None:
|
||||
value_name = type_lookup['NONE']
|
||||
|
||||
return value_name
|
||||
|
||||
def _draw_property(self, layout, dyn_prop, index, property_type):
|
||||
box = layout.box()
|
||||
row = box.row()
|
||||
row.prop(dyn_prop, "use", text="")
|
||||
subrow = row.row()
|
||||
subrow.active = dyn_prop.use
|
||||
|
||||
subrow.label(text=dyn_prop.name, icon=self._icon_from_id_type(dyn_prop.id_type))
|
||||
value_propname, override_mode_support = self._value_name_override_mode_get(dyn_prop.data_type, dyn_prop.data_subtype)
|
||||
|
||||
if override_mode_support:
|
||||
subrow.prop(dyn_prop, "override_mode", text="")
|
||||
subrow.prop(dyn_prop, value_propname, text="")
|
||||
elif value_propname is not None:
|
||||
subrow.prop(dyn_prop, value_propname, text="")
|
||||
|
||||
ops = row.operator("scene.view_layer_override_remove", text="", icon='ZOOMOUT', emboss=False)
|
||||
ops.index = index
|
||||
ops.property_type = property_type
|
||||
|
||||
|
||||
class VIEWLAYER_OT_overrides(ViewLayerButtonsPanel, Panel):
|
||||
bl_label = "Overrides"
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_CLAY', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH'}
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
scene = context.scene
|
||||
view_layer = context.view_layer
|
||||
|
||||
row = layout.row(align=True)
|
||||
row.label(text="Override Sets")
|
||||
|
||||
row = layout.row()
|
||||
col = row.column()
|
||||
|
||||
col.template_list("VIEWLAYER_UL_override_sets", "name", view_layer, "override_sets", view_layer.override_sets, "active_index", rows=2)
|
||||
|
||||
col = row.column(align=True)
|
||||
col.operator("scene.view_layer_override_set_add", icon='ZOOMIN', text="")
|
||||
col.operator("scene.view_layer_override_set_remove", icon='ZOOMOUT', text="")
|
||||
|
||||
override_set = view_layer.override_sets.active
|
||||
|
||||
|
||||
class VIEWLAYER_OT_overrides_scene_properties(ViewLayerOverridesPanel, ViewLayerButtonsPanel, Panel):
|
||||
bl_label = "Scene Properties"
|
||||
bl_parent_id = "VIEWLAYER_OT_overrides"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_CLAY', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH'}
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
override_set = context.view_layer.override_sets.active
|
||||
|
||||
if override_set.scene_properties:
|
||||
for i, dyn_prop in enumerate(override_set.scene_properties):
|
||||
self._draw_property(layout, dyn_prop, i, 'SCENE')
|
||||
else:
|
||||
layout.label(text="No scene property")
|
||||
|
||||
|
||||
class VIEWLAYER_UL_override_set_collections(UIList):
|
||||
def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index):
|
||||
layout.row().label(text=item.name, icon_value=icon)
|
||||
|
||||
|
||||
class VIEWLAYER_OT_overrides_affected_collections(ViewLayerOverridesPanel, ViewLayerButtonsPanel, Panel):
|
||||
bl_label = "Affected Collections"
|
||||
bl_parent_id = "VIEWLAYER_OT_overrides"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_CLAY', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH'}
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
override_set = context.view_layer.override_sets.active
|
||||
|
||||
row = layout.row()
|
||||
col = row.column()
|
||||
|
||||
col.template_list("VIEWLAYER_UL_override_set_collections", "", override_set, "affected_collections", override_set.affected_collections, "active_index", rows=1)
|
||||
|
||||
col = row.column(align=True)
|
||||
col.operator("scene.override_set_collection_link", icon='ZOOMIN', text="")
|
||||
col.operator("scene.override_set_collection_unlink", icon='ZOOMOUT', text="")
|
||||
|
||||
|
||||
class VIEWLAYER_OT_overrides_collection_properties(ViewLayerOverridesPanel, ViewLayerButtonsPanel, Panel):
|
||||
bl_label = "Collection Properties"
|
||||
bl_parent_id = "VIEWLAYER_OT_overrides"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_CLAY', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH'}
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
override_set = context.view_layer.override_sets.active
|
||||
|
||||
if override_set.collection_properties:
|
||||
for i, dyn_prop in enumerate(override_set.collection_properties):
|
||||
self._draw_property(layout, dyn_prop, i, 'COLLECTION')
|
||||
else:
|
||||
layout.label(text="No collection property")
|
||||
|
||||
|
||||
classes = (
|
||||
VIEWLAYER_PT_layer,
|
||||
VIEWLAYER_PT_eevee_layer_passes,
|
||||
VIEWLAYER_UL_override_set_collections,
|
||||
VIEWLAYER_UL_override_sets,
|
||||
VIEWLAYER_OT_overrides,
|
||||
VIEWLAYER_OT_overrides_scene_properties,
|
||||
VIEWLAYER_OT_overrides_affected_collections,
|
||||
VIEWLAYER_OT_overrides_collection_properties,
|
||||
)
|
||||
|
||||
if __name__ == "__main__": # only for live edit.
|
||||
|
@@ -32,6 +32,11 @@
|
||||
* \ingroup bke
|
||||
*/
|
||||
|
||||
struct ListBase;
|
||||
struct Main;
|
||||
|
||||
struct ListBase *BKE_idtype_to_main_data(struct Main *bmain, short id_type);
|
||||
|
||||
const char *BKE_idcode_to_name(short idcode);
|
||||
const char *BKE_idcode_to_name_plural(short idcode);
|
||||
const char *BKE_idcode_to_translation_context(short idcode);
|
||||
|
@@ -45,12 +45,16 @@ extern "C" {
|
||||
struct Base;
|
||||
struct Collection;
|
||||
struct Depsgraph;
|
||||
struct DynamicOverrideProperty;
|
||||
struct ID;
|
||||
struct IDProperty;
|
||||
struct LayerCollection;
|
||||
struct ListBase;
|
||||
struct Main;
|
||||
struct Object;
|
||||
struct OverrideSet;
|
||||
struct PointerRNA;
|
||||
struct PropertyRNA;
|
||||
struct RenderEngine;
|
||||
struct Scene;
|
||||
struct ViewLayer;
|
||||
@@ -70,6 +74,8 @@ void BKE_view_layer_free_ex(struct ViewLayer *view_layer, const bool do_id_user)
|
||||
void BKE_view_layer_selected_objects_tag(struct ViewLayer *view_layer, const int tag);
|
||||
|
||||
struct Object *BKE_view_layer_camera_find(struct ViewLayer *view_layer);
|
||||
struct ViewLayer *BKE_view_layer_find_from_override_set(const struct Scene *scene, struct OverrideSet *override_set);
|
||||
struct ViewLayer *BKE_view_layer_find_from_dynamic_override_property(const struct Scene *scene, struct DynamicOverrideProperty *dyn_prop);
|
||||
struct ViewLayer *BKE_view_layer_find_from_collection(const struct Scene *scene, struct LayerCollection *lc);
|
||||
struct Base *BKE_view_layer_base_find(struct ViewLayer *view_layer, struct Object *ob);
|
||||
void BKE_view_layer_base_deselect_all(struct ViewLayer *view_layer);
|
||||
@@ -124,6 +130,30 @@ void BKE_override_view_layer_int_add(
|
||||
void BKE_override_layer_collection_boolean_add(
|
||||
struct LayerCollection *layer_collection, int id_type, const char *data_path, const bool value);
|
||||
|
||||
/* Dynamic override. */
|
||||
|
||||
struct OverrideSet *BKE_view_layer_override_set_add(struct ViewLayer *view_layer, const char *name);
|
||||
bool BKE_view_layer_override_set_remove(struct ViewLayer *view_layer, struct OverrideSet *override_set);
|
||||
bool BKE_view_layer_override_set_collection_link(struct OverrideSet *override_set, struct Collection *collection);
|
||||
bool BKE_view_layer_override_set_collection_unlink(struct OverrideSet *override_set, struct Collection *collection);
|
||||
|
||||
void BKE_dynamic_overrides_remove_collection(struct Main *bmain, struct Collection *old_collection);
|
||||
|
||||
struct DynamicOverrideProperty *BKE_view_layer_override_property_add(
|
||||
struct OverrideSet *override_set,
|
||||
struct PointerRNA *ptr,
|
||||
struct PropertyRNA *prop,
|
||||
const int index);
|
||||
|
||||
bool BKE_view_layer_override_property_remove(
|
||||
struct OverrideSet *override_set,
|
||||
struct DynamicOverrideProperty *dyn_prop);
|
||||
|
||||
|
||||
void BKE_dynamic_override_apply(
|
||||
const struct Depsgraph *depsgraph,
|
||||
ID *id);
|
||||
|
||||
/* evaluation */
|
||||
|
||||
void BKE_layer_eval_view_layer(
|
||||
|
@@ -40,6 +40,7 @@
|
||||
#include "BLT_translation.h"
|
||||
|
||||
#include "BKE_library.h"
|
||||
#include "BKE_main.h"
|
||||
#include "BKE_idcode.h"
|
||||
|
||||
typedef struct {
|
||||
@@ -124,6 +125,86 @@ static IDType *idtype_from_code(short idcode)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ListBase *BKE_idtype_to_main_data(Main *bmain, short id_type)
|
||||
{
|
||||
switch (id_type)
|
||||
{
|
||||
case ID_SCE:
|
||||
return &bmain->scene;
|
||||
case ID_LI:
|
||||
return &bmain->library;
|
||||
case ID_OB:
|
||||
return &bmain->object;
|
||||
case ID_ME:
|
||||
return &bmain->mesh;
|
||||
case ID_CU:
|
||||
return &bmain->curve;
|
||||
case ID_MB:
|
||||
return &bmain->mball;
|
||||
case ID_MA:
|
||||
return &bmain->mat;
|
||||
case ID_TE:
|
||||
return &bmain->tex;
|
||||
case ID_IM:
|
||||
return &bmain->image;
|
||||
case ID_LT:
|
||||
return &bmain->latt;
|
||||
case ID_LA:
|
||||
return &bmain->lamp;
|
||||
case ID_CA:
|
||||
return &bmain->camera;
|
||||
case ID_IP:
|
||||
return &bmain->ipo;
|
||||
case ID_KE:
|
||||
return &bmain->key;
|
||||
case ID_WO:
|
||||
return &bmain->world;
|
||||
case ID_SCR:
|
||||
return &bmain->screen;
|
||||
case ID_VF:
|
||||
return &bmain->vfont;
|
||||
case ID_TXT:
|
||||
return &bmain->text;
|
||||
case ID_SPK:
|
||||
return &bmain->speaker;
|
||||
case ID_SO:
|
||||
return &bmain->sound;
|
||||
case ID_GR:
|
||||
return &bmain->collection;
|
||||
case ID_AR:
|
||||
return &bmain->armature;
|
||||
case ID_AC:
|
||||
return &bmain->action;
|
||||
case ID_NT:
|
||||
return &bmain->nodetree;
|
||||
case ID_BR:
|
||||
return &bmain->brush;
|
||||
case ID_PA:
|
||||
return &bmain->particle;
|
||||
case ID_GD:
|
||||
return &bmain->gpencil;
|
||||
case ID_WM:
|
||||
return &bmain->wm;
|
||||
case ID_MC:
|
||||
return &bmain->movieclip;
|
||||
case ID_MSK:
|
||||
return &bmain->mask;
|
||||
case ID_LS:
|
||||
return &bmain->linestyle;
|
||||
case ID_PAL:
|
||||
return &bmain->palettes;
|
||||
case ID_PC:
|
||||
return &bmain->paintcurves;
|
||||
case ID_CF:
|
||||
return &bmain->cachefiles;
|
||||
case ID_WS:
|
||||
return &bmain->workspaces;
|
||||
case ID_LP:
|
||||
return &bmain->lightprobe;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return if the ID code is a valid ID code.
|
||||
*
|
||||
|
@@ -60,10 +60,15 @@
|
||||
|
||||
#include "DRW_engine.h"
|
||||
|
||||
#include "RNA_access.h"
|
||||
|
||||
#include "MEM_guardedalloc.h"
|
||||
|
||||
|
||||
/* prototype */
|
||||
static void override_set_copy_data(struct OverrideSet *override_set_dst, struct OverrideSet *override_set_src);
|
||||
static void override_set_free(struct OverrideSet *override_set);
|
||||
static void dynamic_override_apply_post(const struct Depsgraph *depsgraph, struct GSet **dynamic_override_cache);
|
||||
static void object_bases_iterator_next(BLI_Iterator *iter, const int flag);
|
||||
|
||||
|
||||
@@ -232,6 +237,11 @@ void BKE_view_layer_free_ex(ViewLayer *view_layer, const bool do_id_user)
|
||||
|
||||
MEM_SAFE_FREE(view_layer->object_bases_array);
|
||||
|
||||
for (OverrideSet *override_set = view_layer->override_sets.first; override_set; override_set = override_set->next) {
|
||||
override_set_free(override_set);
|
||||
}
|
||||
BLI_freelistN(&view_layer->override_sets);
|
||||
|
||||
MEM_freeN(view_layer);
|
||||
}
|
||||
|
||||
@@ -295,6 +305,40 @@ ViewLayer *BKE_view_layer_find_from_collection(const Scene *scene, LayerCollecti
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the view layer that owns the override set
|
||||
*/
|
||||
ViewLayer *BKE_view_layer_find_from_override_set(const Scene *scene, OverrideSet *override_set)
|
||||
{
|
||||
for (ViewLayer *view_layer = scene->view_layers.first; view_layer; view_layer = view_layer->next) {
|
||||
if (BLI_findindex(&view_layer->override_sets, override_set) != -1) {
|
||||
return view_layer;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the view layer that owns the dynamic override property
|
||||
*/
|
||||
ViewLayer *BKE_view_layer_find_from_dynamic_override_property(const Scene *scene, DynamicOverrideProperty *dyn_prop)
|
||||
{
|
||||
for (ViewLayer *view_layer = scene->view_layers.first; view_layer; view_layer = view_layer->next) {
|
||||
for (OverrideSet *override_set = view_layer->override_sets.first;
|
||||
override_set != NULL;
|
||||
override_set = override_set->next)
|
||||
{
|
||||
if (BLI_findindex(&override_set->scene_properties, dyn_prop) != -1) {
|
||||
return view_layer;
|
||||
}
|
||||
else if (BLI_findindex(&override_set->collection_properties, dyn_prop) != -1) {
|
||||
return view_layer;
|
||||
}
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Base */
|
||||
|
||||
static void view_layer_bases_hash_create(ViewLayer *view_layer)
|
||||
@@ -392,6 +436,16 @@ void BKE_view_layer_copy_data(
|
||||
}
|
||||
}
|
||||
|
||||
BLI_duplicatelist(&view_layer_dst->override_sets, &view_layer_src->override_sets);
|
||||
OverrideSet *override_set_dst, *override_set_src;
|
||||
for (override_set_dst = view_layer_dst->override_sets.first,
|
||||
override_set_src = view_layer_src->override_sets.first;
|
||||
override_set_dst != NULL;
|
||||
override_set_dst = override_set_dst->next, override_set_src = override_set_src->next)
|
||||
{
|
||||
override_set_copy_data(override_set_dst, override_set_src);
|
||||
}
|
||||
|
||||
layer_collections_copy_data(&view_layer_dst->layer_collections, &view_layer_src->layer_collections);
|
||||
|
||||
// TODO: not always safe to free BKE_layer_collection_sync(scene_dst, view_layer_dst);
|
||||
@@ -1031,6 +1085,449 @@ void BKE_override_layer_collection_boolean_add(
|
||||
|
||||
/* Iterators */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Public Dynamic Overrides
|
||||
* \{ */
|
||||
|
||||
static void dynamic_property_copy_data(ListBase *lb_dst, ListBase *lb_src)
|
||||
{
|
||||
BLI_duplicatelist(lb_dst, lb_src);
|
||||
|
||||
DynamicOverrideProperty *dyn_prop_dst;
|
||||
DynamicOverrideProperty *dyn_prop_src;
|
||||
for (dyn_prop_dst = lb_dst->first, dyn_prop_src = lb_src->first;
|
||||
dyn_prop_dst != NULL;
|
||||
dyn_prop_dst = dyn_prop_dst->next, dyn_prop_src = dyn_prop_src->next)
|
||||
{
|
||||
if (dyn_prop_src->rna_path != NULL) {
|
||||
dyn_prop_dst->rna_path = MEM_dupallocN(dyn_prop_src->rna_path);
|
||||
}
|
||||
if (dyn_prop_src->data.str != NULL) {
|
||||
dyn_prop_dst->data.str = MEM_dupallocN(dyn_prop_src->data.str);
|
||||
}
|
||||
BLI_duplicatelist(&dyn_prop_dst->data_path, &dyn_prop_src->data_path);
|
||||
}
|
||||
}
|
||||
|
||||
static void override_set_copy_data(OverrideSet *override_set_dst, OverrideSet *override_set_src)
|
||||
{
|
||||
BLI_strncpy(override_set_dst->name, override_set_src->name, sizeof(override_set_dst->name));
|
||||
override_set_dst->flag = override_set_src->flag;
|
||||
BLI_duplicatelist(&override_set_dst->affected_collections, &override_set_src->affected_collections);
|
||||
dynamic_property_copy_data(&override_set_dst->scene_properties, &override_set_src->scene_properties);
|
||||
dynamic_property_copy_data(&override_set_dst->collection_properties, &override_set_src->collection_properties);
|
||||
}
|
||||
|
||||
static void override_set_property_free(DynamicOverrideProperty *dyn_prop)
|
||||
{
|
||||
MEM_SAFE_FREE(dyn_prop->rna_path);
|
||||
MEM_SAFE_FREE(dyn_prop->data.str);
|
||||
BLI_freelistN(&dyn_prop->data_path);
|
||||
}
|
||||
|
||||
static void override_set_properties_free(ListBase *properties)
|
||||
{
|
||||
for (DynamicOverrideProperty *dyn_prop = properties->first; dyn_prop; dyn_prop = dyn_prop->next) {
|
||||
override_set_property_free(dyn_prop);
|
||||
}
|
||||
}
|
||||
|
||||
static void override_set_free(OverrideSet *override_set)
|
||||
{
|
||||
BLI_freelistN(&override_set->affected_collections);
|
||||
override_set_properties_free(&override_set->scene_properties);
|
||||
BLI_freelistN(&override_set->scene_properties);
|
||||
override_set_properties_free(&override_set->collection_properties);
|
||||
BLI_freelistN(&override_set->collection_properties);
|
||||
}
|
||||
|
||||
struct OverrideSet *BKE_view_layer_override_set_add(struct ViewLayer *view_layer, const char *name)
|
||||
{
|
||||
OverrideSet *override_set = MEM_callocN(sizeof(OverrideSet), __func__);
|
||||
override_set->flag = DYN_OVERRIDE_SET_USE;
|
||||
|
||||
BLI_strncpy_utf8(override_set->name, name, sizeof(override_set->name));
|
||||
BLI_uniquename(&view_layer->override_sets,
|
||||
override_set,
|
||||
DATA_("OverrideSet"),
|
||||
'.',
|
||||
offsetof(OverrideSet, name),
|
||||
sizeof(override_set->name));
|
||||
|
||||
BLI_addtail(&view_layer->override_sets, override_set);
|
||||
view_layer->active_override_set = BLI_listbase_count(&view_layer->override_sets) - 1;
|
||||
return override_set;
|
||||
}
|
||||
|
||||
bool BKE_view_layer_override_set_remove(struct ViewLayer *view_layer, struct OverrideSet *override_set)
|
||||
{
|
||||
const int override_set_index = BLI_findindex(&view_layer->override_sets, override_set);
|
||||
|
||||
if (override_set_index == -1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
BLI_remlink(&view_layer->override_sets, override_set);
|
||||
override_set_free(override_set);
|
||||
MEM_freeN(override_set);
|
||||
|
||||
if (view_layer->active_override_set > override_set_index) {
|
||||
view_layer->active_override_set -= 1;
|
||||
}
|
||||
else if (view_layer->active_override_set == override_set_index) {
|
||||
if (override_set_index == BLI_listbase_count(&view_layer->override_sets)) {
|
||||
view_layer->active_override_set = MAX2(0, override_set_index - 1);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add an existent collection to the affected collection list.
|
||||
* If collection already exists it returns false.
|
||||
*/
|
||||
bool BKE_view_layer_override_set_collection_link(OverrideSet *override_set, Collection *collection)
|
||||
{
|
||||
/* We don't support duplicated collections in the override set. */
|
||||
if (BLI_findptr(&override_set->affected_collections, collection, offsetof(AffectedCollection, collection)) != NULL) {
|
||||
return false;
|
||||
};
|
||||
|
||||
AffectedCollection *affected = MEM_callocN(sizeof(AffectedCollection), __func__);
|
||||
affected->collection = collection;
|
||||
BLI_addtail(&override_set->affected_collections, affected);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove collection from override set
|
||||
* If collection was not there it returns false.
|
||||
*/
|
||||
bool BKE_view_layer_override_set_collection_unlink(struct OverrideSet *override_set, struct Collection *collection)
|
||||
{
|
||||
AffectedCollection *affected = BLI_findptr(&override_set->affected_collections, collection, offsetof(AffectedCollection, collection));
|
||||
if (affected == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const int collection_index = BLI_findindex(&override_set->affected_collections, affected);
|
||||
|
||||
BLI_remlink(&override_set->affected_collections, affected);
|
||||
MEM_freeN(affected);
|
||||
|
||||
if (override_set->active_affected_collection > collection_index) {
|
||||
override_set->active_affected_collection -= 1;
|
||||
}
|
||||
else if (override_set->active_affected_collection == collection_index) {
|
||||
if (collection_index == BLI_listbase_count(&override_set->affected_collections)) {
|
||||
override_set->active_affected_collection = MAX2(0, collection_index - 1);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove collection from all the override sets.
|
||||
*/
|
||||
void BKE_dynamic_overrides_remove_collection(Main *bmain, Collection *old_collection)
|
||||
{
|
||||
for (Scene *scene = bmain->scene.first; scene; scene = scene->id.next) {
|
||||
for (ViewLayer *view_layer = scene->view_layers.first; view_layer; view_layer = view_layer->next) {
|
||||
for (OverrideSet *override_set = view_layer->override_sets.first;
|
||||
override_set != NULL;
|
||||
override_set = override_set->next)
|
||||
{
|
||||
BKE_view_layer_override_set_collection_unlink(override_set, old_collection);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DynamicOverrideProperty *BKE_view_layer_override_property_add(
|
||||
OverrideSet *override_set,
|
||||
PointerRNA *ptr,
|
||||
PropertyRNA *prop,
|
||||
const int index)
|
||||
{
|
||||
ID *owner_id = ptr->id.data;
|
||||
eDynamicOverridePropertyType property_type;
|
||||
const short id_type = GS(owner_id->name);
|
||||
|
||||
switch (id_type) {
|
||||
case ID_OB:
|
||||
case ID_ME:
|
||||
case ID_MA:
|
||||
property_type = DYN_OVERRIDE_PROP_TYPE_COLLECTION;
|
||||
break;
|
||||
case ID_SCE:
|
||||
case ID_WO:
|
||||
property_type = DYN_OVERRIDE_PROP_TYPE_SCENE;
|
||||
break;
|
||||
default:
|
||||
BLI_assert("!undefined dynamic assert type");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char *rna_path_str = RNA_path_from_ID_to_property_index(ptr, prop, 0, index);
|
||||
if (rna_path_str == NULL) {
|
||||
printf("%s: could not get valid RNA path!\n", __func__);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const int array_len = RNA_property_array_length(ptr, prop);
|
||||
if (array_len > ARRAY_SIZE(((DynamicOverrideProperty *)NULL)->data.i)) {
|
||||
/* TODO Use a define for supported array length. */
|
||||
BLI_assert(!"Trying to dynamic-override an array longer than supported!");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
DynamicOverrideProperty *dyn_prop = MEM_callocN(sizeof(DynamicOverrideProperty), __func__);
|
||||
dyn_prop->flag = DYN_OVERRIDE_PROP_USE;
|
||||
dyn_prop->operation = IDOVERRIDESTATIC_OP_REPLACE;
|
||||
/* TODO: We want to store the id only when the rna path is only relevant to
|
||||
* this particular object (e.g., modifiers of an object) .*/
|
||||
dyn_prop->root = owner_id;
|
||||
dyn_prop->id_type = id_type;
|
||||
dyn_prop->property_type = property_type;
|
||||
dyn_prop->rna_path = rna_path_str;
|
||||
dyn_prop->array_len = array_len;
|
||||
|
||||
const bool is_array = RNA_property_array_check(prop);
|
||||
|
||||
/* TODO handle array. */
|
||||
switch (RNA_property_type(prop)) {
|
||||
case PROP_BOOLEAN:
|
||||
if (is_array) {
|
||||
RNA_property_boolean_get_array(ptr, prop, dyn_prop->data.i);
|
||||
}
|
||||
else {
|
||||
dyn_prop->data.i[0] = RNA_property_boolean_get(ptr, prop);
|
||||
}
|
||||
break;
|
||||
case PROP_INT:
|
||||
if (is_array) {
|
||||
RNA_property_int_get_array(ptr, prop, dyn_prop->data.i);
|
||||
}
|
||||
else {
|
||||
dyn_prop->data.i[0] = RNA_property_int_get(ptr, prop);
|
||||
}
|
||||
break;
|
||||
case PROP_FLOAT:
|
||||
if (is_array) {
|
||||
RNA_property_float_get_array(ptr, prop, dyn_prop->data.f);
|
||||
}
|
||||
else {
|
||||
dyn_prop->data.f[0] = RNA_property_float_get(ptr, prop);
|
||||
}
|
||||
break;
|
||||
case PROP_STRING:
|
||||
dyn_prop->data.str = RNA_property_string_get_alloc(ptr, prop, NULL, 0, NULL);
|
||||
break;
|
||||
case PROP_ENUM:
|
||||
dyn_prop->data.i[0] = RNA_property_enum_get(ptr, prop);
|
||||
break;
|
||||
case PROP_POINTER:
|
||||
{
|
||||
PointerRNA poin = RNA_property_pointer_get(ptr, prop);
|
||||
BLI_assert(RNA_struct_is_ID(poin.type));
|
||||
dyn_prop->data.id = poin.id.data;
|
||||
break;
|
||||
}
|
||||
case PROP_COLLECTION:
|
||||
default:
|
||||
BLI_assert(!"Should never happen - dyn");
|
||||
break;
|
||||
}
|
||||
|
||||
/* TODO - data_path for depsgraph. */
|
||||
|
||||
if (property_type == DYN_OVERRIDE_PROP_TYPE_SCENE) {
|
||||
BLI_addtail(&override_set->scene_properties, dyn_prop);
|
||||
}
|
||||
else {
|
||||
BLI_addtail(&override_set->collection_properties, dyn_prop);
|
||||
}
|
||||
|
||||
return dyn_prop;
|
||||
}
|
||||
|
||||
bool BKE_view_layer_override_property_remove(
|
||||
OverrideSet *override_set,
|
||||
DynamicOverrideProperty *dyn_prop)
|
||||
{
|
||||
bool ok = BLI_remlink_safe(&override_set->scene_properties, dyn_prop);
|
||||
|
||||
if (ok == false) {
|
||||
ok = BLI_remlink_safe(&override_set->collection_properties, dyn_prop);
|
||||
}
|
||||
|
||||
if (ok == false) {
|
||||
/* Something went wrong. */
|
||||
return false;
|
||||
}
|
||||
|
||||
override_set_property_free(dyn_prop);
|
||||
MEM_freeN(dyn_prop);
|
||||
return true;
|
||||
}
|
||||
|
||||
static void dynamic_override_apply_cache_populate(GSet *objects, Collection *collection)
|
||||
{
|
||||
for (CollectionObject *collection_object = collection->gobject.first;
|
||||
collection_object != NULL;
|
||||
collection_object = collection_object->next)
|
||||
{
|
||||
BLI_gset_add(objects, &collection_object->ob->id);
|
||||
}
|
||||
|
||||
for (CollectionChild *collection_iter = collection->children.first;
|
||||
collection_iter != NULL;
|
||||
collection_iter = collection_iter->next)
|
||||
{
|
||||
dynamic_override_apply_cache_populate(objects, collection_iter->collection);
|
||||
}
|
||||
}
|
||||
|
||||
static GSet **dynamic_override_apply_pre(const struct Depsgraph *depsgraph)
|
||||
{
|
||||
Scene *scene = DEG_get_evaluated_scene(depsgraph);
|
||||
ViewLayer *view_layer = DEG_get_evaluated_view_layer(depsgraph);
|
||||
Collection *master_collection = BKE_collection_master(scene);
|
||||
const int len_override_sets = BLI_listbase_count(&view_layer->override_sets);
|
||||
|
||||
if (len_override_sets == 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
GSet **dynamic_override_cache = MEM_callocN(
|
||||
sizeof(GSet *) * len_override_sets,
|
||||
__func__);
|
||||
|
||||
int i = 0;
|
||||
for (OverrideSet *override_set = view_layer->override_sets.first;
|
||||
override_set != NULL;
|
||||
override_set = override_set->next, i++)
|
||||
{
|
||||
if ((override_set->flag & DYN_OVERRIDE_SET_USE) == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* If no collection, then all collections are affected. */
|
||||
if (BLI_listbase_is_empty(&override_set->affected_collections)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Quick check to see if we can ignore all collections. */
|
||||
bool has_master_collection = false;
|
||||
for (AffectedCollection *affected = override_set->affected_collections.first;
|
||||
affected != NULL;
|
||||
affected = affected->next)
|
||||
{
|
||||
if (affected->collection == master_collection) {
|
||||
has_master_collection = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (has_master_collection) {
|
||||
continue;
|
||||
}
|
||||
|
||||
dynamic_override_cache[i] = BLI_gset_ptr_new(__func__);
|
||||
|
||||
/* List all the affected objects. */
|
||||
for (AffectedCollection *affected = override_set->affected_collections.first;
|
||||
affected != NULL;
|
||||
affected = affected->next)
|
||||
{
|
||||
Collection *collection_iter = affected->collection;
|
||||
BLI_assert(collection_iter != NULL);
|
||||
dynamic_override_apply_cache_populate(dynamic_override_cache[i], collection_iter);
|
||||
}
|
||||
}
|
||||
return dynamic_override_cache;
|
||||
}
|
||||
|
||||
static void dynamic_override_apply_properties(PointerRNA *ptr, ListBase *properties_new)
|
||||
{
|
||||
for (DynamicOverrideProperty *dyn_prop = properties_new->first;
|
||||
dyn_prop != NULL;
|
||||
dyn_prop = dyn_prop->next)
|
||||
{
|
||||
if ((dyn_prop->flag & DYN_OVERRIDE_PROP_USE) == 0) {
|
||||
continue;
|
||||
}
|
||||
RNA_struct_dynamic_override_apply(ptr, dyn_prop);
|
||||
}
|
||||
}
|
||||
|
||||
void BKE_dynamic_override_apply(const struct Depsgraph *depsgraph, ID *id)
|
||||
{
|
||||
const ID_Type id_type = GS(id->name);
|
||||
if (ELEM(id_type, ID_SCE, ID_OB) == false) {
|
||||
return;
|
||||
}
|
||||
|
||||
GSet **dynamic_override_cache = dynamic_override_apply_pre(depsgraph);
|
||||
|
||||
if (dynamic_override_cache == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
PointerRNA ptr;
|
||||
RNA_id_pointer_create(id, &ptr);
|
||||
|
||||
ViewLayer *view_layer = DEG_get_evaluated_view_layer(depsgraph);
|
||||
int i = 0;
|
||||
for (OverrideSet *override_set = view_layer->override_sets.first;
|
||||
override_set != NULL;
|
||||
override_set = override_set->next, i++)
|
||||
{
|
||||
if ((override_set->flag & DYN_OVERRIDE_SET_USE) == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (id_type == ID_SCE) {
|
||||
/** Apply all the scene properties. */
|
||||
dynamic_override_apply_properties(&ptr, &override_set->scene_properties);
|
||||
}
|
||||
else {
|
||||
if (dynamic_override_cache[i] != NULL &&
|
||||
!BLI_gset_haskey(dynamic_override_cache[i], id->orig_id))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
/** Check if object is in one of the affected collections.
|
||||
* If it is, apply all the overrides for the object and its material, mesh, ...
|
||||
**/
|
||||
dynamic_override_apply_properties(&ptr, &override_set->collection_properties);
|
||||
}
|
||||
}
|
||||
|
||||
dynamic_override_apply_post(depsgraph, dynamic_override_cache);
|
||||
}
|
||||
|
||||
static void dynamic_override_apply_post(const Depsgraph *depsgraph, GSet **dynamic_override_cache)
|
||||
{
|
||||
if (dynamic_override_cache == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
ViewLayer *view_layer = DEG_get_evaluated_view_layer(depsgraph);
|
||||
const int len_override_sets = BLI_listbase_count(&view_layer->override_sets);
|
||||
|
||||
for (int i = 0; i < len_override_sets; i++) {
|
||||
if (dynamic_override_cache[i] != NULL) {
|
||||
BLI_gset_free(dynamic_override_cache[i], NULL);
|
||||
}
|
||||
}
|
||||
|
||||
MEM_freeN(dynamic_override_cache);
|
||||
dynamic_override_cache = NULL;
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Private Iterator Helpers
|
||||
* \{ */
|
||||
|
@@ -449,6 +449,21 @@ void BKE_library_foreach_ID_link(Main *bmain, ID *id, LibraryIDLinkCallback call
|
||||
CALLBACK_INVOKE(fls->linestyle, IDWALK_CB_USER);
|
||||
}
|
||||
}
|
||||
|
||||
for (OverrideSet *override_set = view_layer->override_sets.first;
|
||||
override_set != NULL;
|
||||
override_set = override_set->next)
|
||||
{
|
||||
DynamicOverrideProperty *dyn_prop;
|
||||
for (dyn_prop = override_set->scene_properties.first; dyn_prop; dyn_prop = dyn_prop->next) {
|
||||
CALLBACK_INVOKE_ID(dyn_prop->root, IDWALK_CB_NOP);
|
||||
CALLBACK_INVOKE_ID(dyn_prop->data.id, IDWALK_CB_NOP);
|
||||
}
|
||||
for (dyn_prop = override_set->collection_properties.first; dyn_prop; dyn_prop = dyn_prop->next) {
|
||||
CALLBACK_INVOKE_ID(dyn_prop->root, IDWALK_CB_NOP);
|
||||
CALLBACK_INVOKE_ID(dyn_prop->data.id, IDWALK_CB_NOP);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (TimeMarker *marker = scene->markers.first; marker; marker = marker->next) {
|
||||
|
@@ -391,6 +391,8 @@ static void libblock_remap_data_postprocess_collection_update(Main *bmain, Colle
|
||||
* to remove any collection children that have been set to NULL in the
|
||||
* because of pointer replacement. */
|
||||
BKE_collections_child_remove_nulls(bmain, old_collection);
|
||||
/* We also need to make sure no override set refers to this collection. */
|
||||
BKE_dynamic_overrides_remove_collection(bmain, old_collection);
|
||||
}
|
||||
else {
|
||||
BKE_main_collection_sync_remap(bmain);
|
||||
|
@@ -5560,6 +5560,23 @@ static void direct_link_view_settings(FileData *fd, ColorManagedViewSettings *vi
|
||||
|
||||
/* ***************** READ VIEW LAYER *************** */
|
||||
|
||||
static void direct_link_dynamic_properties(FileData *fd, ListBase *properties)
|
||||
{
|
||||
for (DynamicOverrideProperty *dyn_prop = properties->first; dyn_prop; dyn_prop = dyn_prop->next) {
|
||||
dyn_prop->rna_path = newdataadr(fd, dyn_prop->rna_path);
|
||||
dyn_prop->data.str = newdataadr(fd, dyn_prop->data.str);
|
||||
/* Run-time data. */
|
||||
BLI_listbase_clear(&dyn_prop->data_path);
|
||||
}
|
||||
}
|
||||
|
||||
static void lib_link_dynamic_properties(FileData *fd, Library *lib, ListBase *properties) {
|
||||
for (DynamicOverrideProperty *dyn_prop = properties->first; dyn_prop; dyn_prop = dyn_prop->next) {
|
||||
dyn_prop->data.id = newlibadr(fd, lib, dyn_prop->data.id);
|
||||
dyn_prop->root = newlibadr(fd, lib, dyn_prop->root);
|
||||
}
|
||||
}
|
||||
|
||||
static void direct_link_layer_collections(FileData *fd, ListBase *lb, bool master)
|
||||
{
|
||||
link_list(fd, lb);
|
||||
@@ -5598,6 +5615,15 @@ static void direct_link_view_layer(FileData *fd, ViewLayer *view_layer)
|
||||
view_layer->object_bases_array = NULL;
|
||||
view_layer->object_bases_hash = NULL;
|
||||
view_layer->runtime_flag = 0;
|
||||
|
||||
link_list(fd, &(view_layer->override_sets));
|
||||
for (OverrideSet *override_set = view_layer->override_sets.first; override_set; override_set = override_set->next) {
|
||||
link_list(fd, &override_set->affected_collections);
|
||||
link_list(fd, &override_set->scene_properties);
|
||||
direct_link_dynamic_properties(fd, &override_set->scene_properties);
|
||||
link_list(fd, &override_set->collection_properties);
|
||||
direct_link_dynamic_properties(fd, &override_set->collection_properties);
|
||||
}
|
||||
}
|
||||
|
||||
static void lib_link_layer_collection(FileData *fd, Library *lib, LayerCollection *layer_collection, bool master)
|
||||
@@ -5645,6 +5671,23 @@ static void lib_link_view_layer(FileData *fd, Library *lib, ViewLayer *view_laye
|
||||
lib_link_layer_collection(fd, lib, layer_collection, true);
|
||||
}
|
||||
|
||||
for (OverrideSet *override_set = view_layer->override_sets.first; override_set; override_set = override_set->next) {
|
||||
lib_link_dynamic_properties(fd, lib, &override_set->scene_properties);
|
||||
lib_link_dynamic_properties(fd, lib, &override_set->collection_properties);
|
||||
|
||||
for (AffectedCollection *affected = override_set->affected_collections.first, *affected_next = NULL;
|
||||
affected != NULL;
|
||||
affected = affected_next)
|
||||
{
|
||||
affected_next = affected->next;
|
||||
affected->collection = newlibadr(fd, lib, affected->collection);
|
||||
|
||||
if (affected->collection == NULL) {
|
||||
BLI_freelinkN(&override_set->affected_collections, affected);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
IDP_LibLinkProperty(view_layer->id_properties, fd);
|
||||
}
|
||||
|
||||
@@ -9684,6 +9727,18 @@ static void expand_scene(FileData *fd, Main *mainvar, Scene *sce)
|
||||
}
|
||||
expand_doit(fd, mainvar, lineset->linestyle);
|
||||
}
|
||||
|
||||
for (OverrideSet *override_set = view_layer->override_sets.first;
|
||||
override_set != NULL;
|
||||
override_set = override_set->next)
|
||||
{
|
||||
for (AffectedCollection *affected = override_set->affected_collections.first;
|
||||
affected != NULL;
|
||||
affected = affected->next)
|
||||
{
|
||||
expand_doit(fd, mainvar, affected->collection);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (sce->gpd)
|
||||
|
@@ -2449,6 +2449,16 @@ static void write_layer_collections(WriteData *wd, ListBase *lb)
|
||||
}
|
||||
}
|
||||
|
||||
static void write_dynamic_properties(WriteData *wd, ListBase *properties)
|
||||
{
|
||||
for (DynamicOverrideProperty *dyn_prop = properties->first; dyn_prop; dyn_prop = dyn_prop->next) {
|
||||
writedata(wd, DATA, strlen(dyn_prop->rna_path) + 1, dyn_prop->rna_path);
|
||||
if (dyn_prop->data.str != NULL) {
|
||||
writedata(wd, DATA, strlen(dyn_prop->data.str) + 1, dyn_prop->data.str);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void write_view_layer(WriteData *wd, ViewLayer *view_layer)
|
||||
{
|
||||
writestruct(wd, DATA, ViewLayer, 1, view_layer);
|
||||
@@ -2466,6 +2476,15 @@ static void write_view_layer(WriteData *wd, ViewLayer *view_layer)
|
||||
writestruct(wd, DATA, FreestyleLineSet, 1, fls);
|
||||
}
|
||||
write_layer_collections(wd, &view_layer->layer_collections);
|
||||
|
||||
writelist(wd, DATA, OverrideSet, &view_layer->override_sets);
|
||||
for (OverrideSet *override_set = view_layer->override_sets.first; override_set; override_set = override_set->next) {
|
||||
writelist(wd, DATA, AffectedCollection, &override_set->affected_collections);
|
||||
writelist(wd, DATA, DynamicOverrideProperty, &override_set->scene_properties);
|
||||
write_dynamic_properties(wd, &override_set->scene_properties);
|
||||
writelist(wd, DATA, DynamicOverrideProperty, &override_set->collection_properties);
|
||||
write_dynamic_properties(wd, &override_set->collection_properties);
|
||||
}
|
||||
}
|
||||
|
||||
static void write_scene(WriteData *wd, Scene *sce)
|
||||
|
@@ -169,6 +169,11 @@ void DEG_graph_id_tag_update(struct Main *bmain,
|
||||
*/
|
||||
void DEG_id_type_tag(struct Main *bmain, short id_type);
|
||||
|
||||
void DEG_graph_id_type_tag_update(struct Main *bmain,
|
||||
struct Depsgraph *depsgraph,
|
||||
short id_type,
|
||||
int flag);
|
||||
|
||||
void DEG_ids_clear_recalc(struct Main *bmain, Depsgraph *depsgraph);
|
||||
|
||||
/* Update Flushing ------------------------------- */
|
||||
|
@@ -519,6 +519,15 @@ void DepsgraphRelationBuilder::build_object(Base *base, Object *object)
|
||||
parent_transform_key,
|
||||
"ObLocal -> ObParent");
|
||||
}
|
||||
/* Handle dynamic override update. */
|
||||
OperationKey scene_cow_key(&scene_->id,
|
||||
DEG_NODE_TYPE_COPY_ON_WRITE,
|
||||
DEG_OPCODE_COPY_ON_WRITE);
|
||||
OperationKey ob_cow_key(&object->id,
|
||||
DEG_NODE_TYPE_COPY_ON_WRITE,
|
||||
DEG_OPCODE_COPY_ON_WRITE);
|
||||
add_relation(scene_cow_key, ob_cow_key, "Dynamic Override CoW Relation");
|
||||
|
||||
/* Modifiers. */
|
||||
if (object->modifiers.first != NULL) {
|
||||
BuilderWalkUserData data;
|
||||
|
@@ -619,6 +619,14 @@ void DEG_id_type_tag(Main *bmain, short id_type)
|
||||
}
|
||||
}
|
||||
|
||||
void DEG_graph_id_type_tag_update(Main *bmain, Depsgraph *depsgraph, short id_type, int flag)
|
||||
{
|
||||
ListBase *data = BKE_idtype_to_main_data(bmain, id_type);
|
||||
LISTBASE_FOREACH (ID *, id, data) {
|
||||
DEG_graph_id_tag_update(bmain, depsgraph, id, flag);
|
||||
}
|
||||
}
|
||||
|
||||
void DEG_graph_flush_update(Main *bmain, Depsgraph *depsgraph)
|
||||
{
|
||||
if (depsgraph == NULL) {
|
||||
|
@@ -861,6 +861,9 @@ ID *deg_update_copy_on_write_datablock(const Depsgraph *depsgraph,
|
||||
if (id_type == ID_OB) {
|
||||
deg_restore_object_runtime((Object *)id_cow, &object_runtime_backup);
|
||||
}
|
||||
|
||||
const ::Depsgraph *graph = reinterpret_cast<const ::Depsgraph *>(depsgraph);
|
||||
BKE_dynamic_override_apply(graph, id_cow);
|
||||
return id_cow;
|
||||
}
|
||||
|
||||
|
@@ -312,8 +312,11 @@ bool ui_popup_context_menu_for_button(bContext *C, uiBut *but)
|
||||
const bool is_array = RNA_property_array_length(&but->rnapoin, but->rnaprop) != 0;
|
||||
const bool is_array_component = (is_array && but->rnaindex != -1);
|
||||
|
||||
const int override_status = RNA_property_static_override_status(ptr, prop, -1);
|
||||
const bool is_overridable = (override_status & RNA_OVERRIDE_STATUS_OVERRIDABLE) != 0;
|
||||
const int static_override_status = RNA_property_static_override_status(ptr, prop, -1);
|
||||
const bool is_static_overridable = (static_override_status & RNA_OVERRIDE_STATUS_OVERRIDABLE) != 0;
|
||||
|
||||
const int dynamic_override_status = RNA_property_dynamic_override_status(ptr, prop, -1);
|
||||
const bool is_dynamic_overridable = (dynamic_override_status & RNA_OVERRIDE_STATUS_OVERRIDABLE) != 0;
|
||||
|
||||
/* Keyframes */
|
||||
if (but->flag & UI_BUT_ANIMATED_KEY) {
|
||||
@@ -457,7 +460,13 @@ bool ui_popup_context_menu_for_button(bContext *C, uiBut *but)
|
||||
}
|
||||
}
|
||||
|
||||
if (is_overridable) {
|
||||
/* Dynamic Override Operators */
|
||||
if (is_editable && is_dynamic_overridable) {
|
||||
uiItemS(layout);
|
||||
uiItemFullO(layout, "SCENE_OT_view_layer_override_add", NULL, ICON_NONE, NULL, WM_OP_INVOKE_DEFAULT, 0, NULL);
|
||||
}
|
||||
|
||||
if (is_static_overridable) {
|
||||
wmOperatorType *ot;
|
||||
PointerRNA op_ptr;
|
||||
/* Override Operators */
|
||||
|
@@ -27,6 +27,7 @@ set(INC
|
||||
../../makesdna
|
||||
../../makesrna
|
||||
../../windowmanager
|
||||
../../../../intern/guardedalloc
|
||||
)
|
||||
|
||||
set(INC_SYS
|
||||
|
@@ -24,6 +24,8 @@
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "MEM_guardedalloc.h"
|
||||
|
||||
#include "BLI_compiler_attrs.h"
|
||||
#include "BLI_listbase.h"
|
||||
|
||||
@@ -53,10 +55,17 @@
|
||||
|
||||
#include "RNA_access.h"
|
||||
#include "RNA_define.h"
|
||||
#include "RNA_enum_types.h"
|
||||
|
||||
#include "UI_interface.h"
|
||||
#include "UI_resources.h"
|
||||
|
||||
#include "WM_api.h"
|
||||
#include "WM_types.h"
|
||||
|
||||
/* prototypes */
|
||||
typedef struct OverrideSetLinkCollectionData OverrideSetLinkCollectionData;
|
||||
static void view_layer_override_set_collection_link_menus_items(struct uiLayout *layout, struct OverrideSetLinkCollectionData *menu);
|
||||
|
||||
Scene *ED_scene_add(Main *bmain, bContext *C, wmWindow *win, eSceneCopyMethod method)
|
||||
{
|
||||
@@ -282,8 +291,540 @@ static void SCENE_OT_delete(wmOperatorType *ot)
|
||||
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
|
||||
}
|
||||
|
||||
static int view_layer_override_set_add_exec(bContext *C, wmOperator *UNUSED(op))
|
||||
{
|
||||
Scene *scene = CTX_data_scene(C);
|
||||
BKE_view_layer_override_set_add(CTX_data_view_layer(C), "New Override Set");
|
||||
DEG_id_tag_update(&scene->id, DEG_TAG_COPY_ON_WRITE);
|
||||
WM_event_add_notifier(C, NC_SCENE | ND_DYN_OVERRIDES, scene);
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
static void SCENE_OT_view_layer_override_set_add(wmOperatorType *ot)
|
||||
{
|
||||
/* identifiers */
|
||||
ot->name = "Add View Layer Override Set";
|
||||
ot->description = "Add a view layer override set";
|
||||
ot->idname = "SCENE_OT_view_layer_override_set_add";
|
||||
|
||||
/* api callbacks */
|
||||
ot->exec = view_layer_override_set_add_exec;
|
||||
|
||||
/* flags */
|
||||
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
|
||||
}
|
||||
|
||||
static int view_layer_override_set_remove_exec(bContext *C, wmOperator *op)
|
||||
{
|
||||
Main *bmain = CTX_data_main(C);
|
||||
Depsgraph *depsgraph = CTX_data_depsgraph(C);
|
||||
Scene *scene = CTX_data_scene(C);
|
||||
ViewLayer *view_layer = CTX_data_view_layer(C);
|
||||
OverrideSet *override_set = BLI_findlink(&view_layer->override_sets, view_layer->active_override_set);
|
||||
|
||||
if (override_set == NULL) {
|
||||
BKE_report(op->reports, RPT_ERROR, "No override set found");
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
|
||||
BKE_view_layer_override_set_remove(view_layer, override_set);
|
||||
|
||||
DEG_graph_id_tag_update(bmain, depsgraph, &scene->id, DEG_TAG_COPY_ON_WRITE);
|
||||
DEG_graph_id_type_tag_update(bmain, depsgraph, ID_OB, DEG_TAG_COPY_ON_WRITE);
|
||||
|
||||
WM_event_add_notifier(C, NC_SCENE | ND_DYN_OVERRIDES, scene);
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
static int view_layer_override_set_remove_poll(bContext *C)
|
||||
{
|
||||
ViewLayer *view_layer = CTX_data_view_layer(C);
|
||||
return view_layer->active_override_set || BLI_listbase_count_at_most(&view_layer->override_sets, 1);
|
||||
}
|
||||
|
||||
static void SCENE_OT_view_layer_override_set_remove(wmOperatorType *ot)
|
||||
{
|
||||
/* identifiers */
|
||||
ot->name = "Remove View Layer Override Set";
|
||||
ot->description = "Remove active view layer override set";
|
||||
ot->idname = "SCENE_OT_view_layer_override_set_remove";
|
||||
|
||||
/* api callbacks */
|
||||
ot->exec = view_layer_override_set_remove_exec;
|
||||
ot->poll = view_layer_override_set_remove_poll;
|
||||
|
||||
/* flags */
|
||||
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
|
||||
}
|
||||
|
||||
#define COLLECTION_INVALID_INDEX -1
|
||||
|
||||
static int view_layer_override_set_collection_link_poll(bContext *C)
|
||||
{
|
||||
ViewLayer *view_layer = CTX_data_view_layer(C);
|
||||
return view_layer->active_override_set || BLI_findlink(&view_layer->override_sets, view_layer->active_override_set);
|
||||
}
|
||||
|
||||
static int view_layer_override_set_collection_link_exec(bContext *C, wmOperator *op)
|
||||
{
|
||||
PropertyRNA *prop = RNA_struct_find_property(op->ptr, "collection_index");
|
||||
|
||||
if (!RNA_property_is_set(op->ptr, prop)) {
|
||||
BKE_report(op->reports, RPT_ERROR, "No collection selected");
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
|
||||
int collection_index = RNA_property_int_get(op->ptr, prop);
|
||||
Scene *scene = CTX_data_scene(C);
|
||||
Collection *collection = BKE_collection_from_index(scene, collection_index);
|
||||
|
||||
if (collection == NULL) {
|
||||
BKE_report(op->reports, RPT_ERROR, "Unexpected error, collection not found");
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
|
||||
ViewLayer *view_layer = CTX_data_view_layer(C);
|
||||
OverrideSet *override_set = BLI_findlink(&view_layer->override_sets, view_layer->active_override_set);
|
||||
|
||||
if (BKE_view_layer_override_set_collection_link(override_set, collection)) {
|
||||
DEG_id_tag_update(&scene->id, DEG_TAG_COPY_ON_WRITE);
|
||||
DEG_graph_id_type_tag_update(CTX_data_main(C), CTX_data_depsgraph(C), ID_OB, DEG_TAG_COPY_ON_WRITE);
|
||||
WM_event_add_notifier(C, NC_SCENE | ND_DYN_OVERRIDES, scene);
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
else {
|
||||
BKE_reportf(op->reports,
|
||||
RPT_ERROR,
|
||||
"Collection '%s' already affected by override set '%s'",
|
||||
collection->id.name + 2,
|
||||
override_set->name);
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
}
|
||||
|
||||
typedef struct OverrideSetLinkCollectionData {
|
||||
struct OverrideSetLinkCollectionData *next, *prev;
|
||||
int index;
|
||||
struct Collection *collection;
|
||||
struct ListBase submenus;
|
||||
PointerRNA ptr;
|
||||
struct wmOperatorType *ot;
|
||||
} OverrideSetLinkCollectionData;
|
||||
|
||||
static int view_layer_override_set_collection_link_menus_create(wmOperator *op, OverrideSetLinkCollectionData *menu)
|
||||
{
|
||||
int index = menu->index;
|
||||
for (CollectionChild *child= menu->collection->children.first;
|
||||
child != NULL;
|
||||
child = child->next)
|
||||
{
|
||||
OverrideSetLinkCollectionData *submenu = MEM_callocN (sizeof(OverrideSetLinkCollectionData),
|
||||
"OverrideSetLinkCollectionData submenu - expected memleak");
|
||||
BLI_addtail(&menu->submenus, submenu);
|
||||
submenu->collection = child->collection;
|
||||
submenu->index = ++index;
|
||||
index = view_layer_override_set_collection_link_menus_create(op, submenu);
|
||||
submenu->ot = op->type;
|
||||
}
|
||||
return index;
|
||||
}
|
||||
|
||||
static void view_layer_override_set_collection_link_menus_free_recursive(OverrideSetLinkCollectionData *menu)
|
||||
{
|
||||
for (OverrideSetLinkCollectionData *submenu = menu->submenus.first;
|
||||
submenu != NULL;
|
||||
submenu = submenu->next)
|
||||
{
|
||||
view_layer_override_set_collection_link_menus_free_recursive(submenu);
|
||||
}
|
||||
BLI_freelistN(&menu->submenus);
|
||||
}
|
||||
|
||||
static void view_layer_override_set_collection_link_menus_free(OverrideSetLinkCollectionData **menu)
|
||||
{
|
||||
if (*menu == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
view_layer_override_set_collection_link_menus_free_recursive(*menu);
|
||||
MEM_freeN(*menu);
|
||||
*menu = NULL;
|
||||
}
|
||||
|
||||
static void view_layer_override_set_collection_link_menu_create(bContext *UNUSED(C), uiLayout *layout, void *menu_v)
|
||||
{
|
||||
OverrideSetLinkCollectionData *menu = menu_v;
|
||||
|
||||
uiItemIntO(layout,
|
||||
menu->collection->id.name + 2,
|
||||
ICON_NONE,
|
||||
"SCENE_OT_override_set_collection_link",
|
||||
"collection_index",
|
||||
menu->index);
|
||||
uiItemS(layout);
|
||||
|
||||
for (OverrideSetLinkCollectionData *submenu = menu->submenus.first;
|
||||
submenu != NULL;
|
||||
submenu = submenu->next)
|
||||
{
|
||||
view_layer_override_set_collection_link_menus_items(layout, submenu);
|
||||
}
|
||||
}
|
||||
|
||||
static void view_layer_override_set_collection_link_menus_items(uiLayout *layout, OverrideSetLinkCollectionData *menu)
|
||||
{
|
||||
if (BLI_listbase_is_empty(&menu->submenus)) {
|
||||
uiItemIntO(layout,
|
||||
menu->collection->id.name + 2,
|
||||
ICON_NONE,
|
||||
"SCENE_OT_override_set_collection_link",
|
||||
"collection_index",
|
||||
menu->index);
|
||||
}
|
||||
else {
|
||||
uiItemMenuF(layout,
|
||||
menu->collection->id.name + 2,
|
||||
ICON_NONE,
|
||||
view_layer_override_set_collection_link_menu_create,
|
||||
menu);
|
||||
}
|
||||
}
|
||||
|
||||
/* This is allocated statically because we need this available for the menus creation callback. */
|
||||
static OverrideSetLinkCollectionData *master_collection_menu = NULL;
|
||||
|
||||
static int view_layer_override_set_collection_link_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
|
||||
{
|
||||
/* Reset the menus data for the current master collection, and free previously allocated data. */
|
||||
view_layer_override_set_collection_link_menus_free(&master_collection_menu);
|
||||
|
||||
PropertyRNA *prop;
|
||||
prop = RNA_struct_find_property(op->ptr, "collection_index");
|
||||
if (RNA_property_is_set(op->ptr, prop)) {
|
||||
return view_layer_override_set_collection_link_exec(C, op);
|
||||
}
|
||||
|
||||
Collection *master_collection = BKE_collection_master(CTX_data_scene(C));
|
||||
|
||||
/* We need the data to be allocated so it's available during menu drawing.
|
||||
* Technically we could use wmOperator->customdata. However there is no free callback
|
||||
* called to an operator that exit with OPERATOR_INTERFACE to launch a menu.
|
||||
*
|
||||
* So we are left with a memory that will necessarily leak. It's a small leak though.*/
|
||||
if (master_collection_menu == NULL) {
|
||||
master_collection_menu = MEM_callocN(sizeof(OverrideSetLinkCollectionData),
|
||||
"OverrideSetLinkCollectionData menu - expected eventual memleak");
|
||||
}
|
||||
|
||||
master_collection_menu->collection = master_collection;
|
||||
master_collection_menu->ot = op->type;
|
||||
view_layer_override_set_collection_link_menus_create(op, master_collection_menu);
|
||||
|
||||
uiPopupMenu *pup;
|
||||
uiLayout *layout;
|
||||
|
||||
/* Build the menus. */
|
||||
pup = UI_popup_menu_begin(C, IFACE_("Link Collection"), ICON_NONE);
|
||||
layout = UI_popup_menu_layout(pup);
|
||||
|
||||
/* We use invoke here so we can read ctrl from event. */
|
||||
uiLayoutSetOperatorContext(layout, WM_OP_INVOKE_DEFAULT);
|
||||
|
||||
view_layer_override_set_collection_link_menu_create(C, layout, master_collection_menu);
|
||||
|
||||
UI_popup_menu_end(C, pup);
|
||||
|
||||
return OPERATOR_INTERFACE;
|
||||
}
|
||||
|
||||
static void SCENE_OT_override_set_collection_link(wmOperatorType *ot)
|
||||
{
|
||||
PropertyRNA *prop;
|
||||
|
||||
/* identifiers */
|
||||
ot->name = "Link Collection to Override Set";
|
||||
ot->description = "Link a collection to a view layer override set";
|
||||
ot->idname = "SCENE_OT_override_set_collection_link";
|
||||
|
||||
/* api callbacks */
|
||||
ot->exec = view_layer_override_set_collection_link_exec;
|
||||
ot->invoke = view_layer_override_set_collection_link_invoke;
|
||||
ot->poll = view_layer_override_set_collection_link_poll;
|
||||
|
||||
/* flags */
|
||||
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
|
||||
|
||||
prop = RNA_def_int(ot->srna, "collection_index", COLLECTION_INVALID_INDEX, COLLECTION_INVALID_INDEX, INT_MAX,
|
||||
"Collection Index", "Index of the collection to link", 0, INT_MAX);
|
||||
RNA_def_property_flag(prop, PROP_SKIP_SAVE | PROP_HIDDEN);
|
||||
}
|
||||
|
||||
#undef COLLECTION_INVALID_INDEX
|
||||
|
||||
static int view_layer_override_set_collection_unlink_exec(bContext *C, wmOperator *UNUSED(op))
|
||||
{
|
||||
Scene *scene = CTX_data_scene(C);
|
||||
ViewLayer *view_layer = CTX_data_view_layer(C);
|
||||
OverrideSet *override_set = BLI_findlink(&view_layer->override_sets, view_layer->active_override_set);
|
||||
AffectedCollection *affected_collection = BLI_findlink(&override_set->affected_collections, override_set->active_affected_collection);
|
||||
Collection *collection = affected_collection->collection;
|
||||
|
||||
BKE_view_layer_override_set_collection_unlink(override_set, collection);
|
||||
|
||||
DEG_id_tag_update(&scene->id, DEG_TAG_COPY_ON_WRITE);
|
||||
DEG_graph_id_type_tag_update(CTX_data_main(C), CTX_data_depsgraph(C), ID_OB, DEG_TAG_COPY_ON_WRITE);
|
||||
|
||||
WM_event_add_notifier(C, NC_SCENE | ND_DYN_OVERRIDES, scene);
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
static int view_layer_override_set_collection_unlink_poll(bContext *C)
|
||||
{
|
||||
ViewLayer *view_layer = CTX_data_view_layer(C);
|
||||
OverrideSet *override_set = BLI_findlink(&view_layer->override_sets, view_layer->active_override_set);
|
||||
|
||||
if (override_set == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return override_set->active_affected_collection || BLI_listbase_count_at_most(&override_set->affected_collections, 1);
|
||||
}
|
||||
|
||||
static void SCENE_OT_override_set_collection_unlink(wmOperatorType *ot)
|
||||
{
|
||||
/* identifiers */
|
||||
ot->name = "Unlink Collection from Override Set";
|
||||
ot->description = "Unlink collection from view layer override set";
|
||||
ot->idname = "SCENE_OT_override_set_collection_unlink";
|
||||
|
||||
/* api callbacks */
|
||||
ot->exec = view_layer_override_set_collection_unlink_exec;
|
||||
ot->poll = view_layer_override_set_collection_unlink_poll;
|
||||
|
||||
/* flags */
|
||||
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
|
||||
}
|
||||
|
||||
static struct {
|
||||
PointerRNA ptr;
|
||||
PropertyRNA *prop;
|
||||
int index;
|
||||
bool set;
|
||||
} override_property_data = { .set = false };
|
||||
|
||||
static int view_layer_override_add_exec(bContext *C, wmOperator *op)
|
||||
{
|
||||
if (override_property_data.set == false) {
|
||||
UI_context_active_but_prop_get(C,
|
||||
&override_property_data.ptr,
|
||||
&override_property_data.prop,
|
||||
&override_property_data.index);
|
||||
}
|
||||
override_property_data.set = false;
|
||||
|
||||
ID *id = override_property_data.ptr.id.data;
|
||||
BLI_assert(id != NULL);
|
||||
|
||||
Scene *scene = CTX_data_scene(C);
|
||||
ViewLayer *view_layer = CTX_data_view_layer(C);
|
||||
OverrideSet *override_set;
|
||||
|
||||
if (RNA_boolean_get(op->ptr, "is_new")) {
|
||||
char new_override_set_name[MAX_NAME];
|
||||
RNA_string_get(op->ptr, "new_override_set_name", new_override_set_name);
|
||||
override_set = BKE_view_layer_override_set_add(view_layer, new_override_set_name);
|
||||
}
|
||||
else if (BLI_listbase_is_empty(&view_layer->override_sets)) {
|
||||
override_set = BKE_view_layer_override_set_add(view_layer, "Override Set");
|
||||
}
|
||||
else {
|
||||
const int override_set_index = RNA_int_get(op->ptr, "override_set_index");
|
||||
override_set = BLI_findlink(&view_layer->override_sets, override_set_index);
|
||||
}
|
||||
|
||||
if (override_set == NULL) {
|
||||
BKE_report(op->reports, RPT_ERROR, "No valid override set selected");
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
|
||||
BKE_view_layer_override_property_add(override_set,
|
||||
&override_property_data.ptr,
|
||||
override_property_data.prop,
|
||||
override_property_data.index);
|
||||
|
||||
DEG_id_tag_update(&scene->id, DEG_TAG_COPY_ON_WRITE);
|
||||
WM_event_add_notifier(C, NC_SCENE | ND_DYN_OVERRIDES, scene);
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
static int view_layer_override_add_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
|
||||
{
|
||||
PropertyRNA *prop;
|
||||
ViewLayer *view_layer = CTX_data_view_layer(C);
|
||||
|
||||
if (RNA_boolean_get(op->ptr, "is_new")) {
|
||||
prop = RNA_struct_find_property(op->ptr, "new_override_set_name");
|
||||
if (!RNA_property_is_set(op->ptr, prop)) {
|
||||
/* The dialog popup messes with the context prop/ptr, so we need to pre-store it
|
||||
* to re-access it from the exec function. */
|
||||
UI_context_active_but_prop_get(C,
|
||||
&override_property_data.ptr,
|
||||
&override_property_data.prop,
|
||||
&override_property_data.index);
|
||||
override_property_data.set = true;
|
||||
return WM_operator_props_dialog_popup(C, op, 10 * UI_UNIT_X, 5 * UI_UNIT_Y);
|
||||
}
|
||||
}
|
||||
override_property_data.set = false;
|
||||
|
||||
if (BLI_listbase_is_empty(&view_layer->override_sets)) {
|
||||
return view_layer_override_add_exec(C, op);
|
||||
}
|
||||
|
||||
prop = RNA_struct_find_property(op->ptr, "override_set_index");
|
||||
if (RNA_property_is_set(op->ptr, prop)) {
|
||||
return view_layer_override_add_exec(C, op);
|
||||
}
|
||||
|
||||
uiPopupMenu *pup;
|
||||
uiLayout *layout;
|
||||
|
||||
/* Build the menus. */
|
||||
pup = UI_popup_menu_begin(C, IFACE_("Override Property in Set"), ICON_NONE);
|
||||
layout = UI_popup_menu_layout(pup);
|
||||
|
||||
uiLayoutSetOperatorContext(layout, WM_OP_INVOKE_DEFAULT);
|
||||
|
||||
int i = 0;
|
||||
for (OverrideSet *override_set = view_layer->override_sets.first; override_set; override_set = override_set->next) {
|
||||
uiItemIntO(layout,
|
||||
override_set->name,
|
||||
ICON_NONE,
|
||||
"SCENE_OT_view_layer_override_add",
|
||||
"override_set_index",
|
||||
i++);
|
||||
}
|
||||
|
||||
uiItemS(layout);
|
||||
|
||||
uiItemBooleanO(layout,
|
||||
"New Override Set",
|
||||
ICON_ZOOMIN,
|
||||
"SCENE_OT_view_layer_override_add",
|
||||
"is_new",
|
||||
true);
|
||||
|
||||
UI_popup_menu_end(C, pup);
|
||||
|
||||
return OPERATOR_INTERFACE;
|
||||
}
|
||||
|
||||
static void SCENE_OT_view_layer_override_add(wmOperatorType *ot)
|
||||
{
|
||||
PropertyRNA *prop;
|
||||
|
||||
/* identifiers */
|
||||
ot->name = "Add View Layer Override";
|
||||
ot->description = "Override property in a view layer override set";
|
||||
ot->idname = "SCENE_OT_view_layer_override_add";
|
||||
|
||||
/* api callbacks */
|
||||
ot->exec = view_layer_override_add_exec;
|
||||
ot->invoke = view_layer_override_add_invoke;
|
||||
|
||||
/* flags */
|
||||
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
|
||||
|
||||
prop = RNA_def_int(ot->srna, "override_set_index", 0, 0, INT_MAX,
|
||||
"Override Set Index", "Index of the override set to add the property", 0, INT_MAX);
|
||||
RNA_def_property_flag(prop, PROP_SKIP_SAVE | PROP_HIDDEN);
|
||||
prop = RNA_def_boolean(ot->srna, "is_new", false, "New", "Add a new override set");
|
||||
RNA_def_property_flag(prop, PROP_SKIP_SAVE | PROP_HIDDEN);
|
||||
prop = RNA_def_string(ot->srna, "new_override_set_name", "Override Set", MAX_NAME, "Name",
|
||||
"Name of the newly added override set");
|
||||
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
|
||||
}
|
||||
|
||||
static int view_layer_override_remove_exec(bContext *C, wmOperator *op)
|
||||
{
|
||||
Scene *scene = CTX_data_scene(C);
|
||||
ViewLayer *view_layer = CTX_data_view_layer(C);
|
||||
OverrideSet *override_set = BLI_findlink(&view_layer->override_sets, view_layer->active_override_set);
|
||||
|
||||
if (override_set == NULL) {
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
|
||||
PropertyRNA *prop = RNA_struct_find_property(op->ptr, "index");
|
||||
if (!RNA_property_is_set(op->ptr, prop)) {
|
||||
BKE_report(op->reports, RPT_ERROR, "No property index defined");
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
|
||||
const int index = RNA_property_int_get(op->ptr, prop);
|
||||
|
||||
prop = RNA_struct_find_property(op->ptr, "property_type");
|
||||
if (!RNA_property_is_set(op->ptr, prop)) {
|
||||
BKE_report(op->reports, RPT_ERROR, "No property type set");
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
|
||||
const int property_type = RNA_property_enum_get(op->ptr, prop);
|
||||
|
||||
ListBase *lb[] = {
|
||||
&override_set->scene_properties,
|
||||
&override_set->collection_properties,
|
||||
};
|
||||
|
||||
DynamicOverrideProperty *dyn_prop = BLI_findlink(lb[property_type], index);
|
||||
|
||||
if (dyn_prop == NULL) {
|
||||
BKE_report(op->reports, RPT_ERROR, "No property found");
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
|
||||
BKE_view_layer_override_property_remove(override_set, dyn_prop);
|
||||
|
||||
DEG_id_tag_update(&scene->id, DEG_TAG_COPY_ON_WRITE);
|
||||
WM_event_add_notifier(C, NC_SCENE | ND_DYN_OVERRIDES, scene);
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
static void SCENE_OT_view_layer_override_remove(wmOperatorType *ot)
|
||||
{
|
||||
PropertyRNA *prop;
|
||||
|
||||
/* identifiers */
|
||||
ot->name = "Remove View Layer Override";
|
||||
ot->description = "Remove override property in a view layer override set";
|
||||
ot->idname = "SCENE_OT_view_layer_override_remove";
|
||||
|
||||
/* api callbacks */
|
||||
ot->exec = view_layer_override_remove_exec;
|
||||
|
||||
/* flags */
|
||||
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
|
||||
|
||||
prop = RNA_def_int(ot->srna, "index", 0, 0, INT_MAX, "Property Index",
|
||||
"Index of the property within its list", 0, INT_MAX);
|
||||
RNA_def_property_flag(prop, PROP_SKIP_SAVE | PROP_HIDDEN);
|
||||
prop = RNA_def_enum(ot->srna,
|
||||
"property_type",
|
||||
rna_enum_dynamic_override_property_type_items,
|
||||
DYN_OVERRIDE_PROP_TYPE_SCENE,
|
||||
"Property Type",
|
||||
"Whether the property removed is a scene or a collection property");
|
||||
RNA_def_property_flag(prop, PROP_SKIP_SAVE | PROP_HIDDEN);
|
||||
}
|
||||
|
||||
void ED_operatortypes_scene(void)
|
||||
{
|
||||
WM_operatortype_append(SCENE_OT_new);
|
||||
WM_operatortype_append(SCENE_OT_delete);
|
||||
WM_operatortype_append(SCENE_OT_view_layer_override_set_add);
|
||||
WM_operatortype_append(SCENE_OT_view_layer_override_set_remove);
|
||||
WM_operatortype_append(SCENE_OT_override_set_collection_link);
|
||||
WM_operatortype_append(SCENE_OT_override_set_collection_unlink);
|
||||
WM_operatortype_append(SCENE_OT_view_layer_override_add);
|
||||
WM_operatortype_append(SCENE_OT_view_layer_override_remove);
|
||||
}
|
||||
|
@@ -1166,6 +1166,7 @@ static void view3d_header_region_listener(
|
||||
case ND_TOOLSETTINGS:
|
||||
case ND_LAYER_CONTENT:
|
||||
case ND_RENDER_OPTIONS:
|
||||
case ND_DYN_OVERRIDES:
|
||||
ED_region_tag_redraw(ar);
|
||||
break;
|
||||
}
|
||||
@@ -1191,6 +1192,8 @@ static void view3d_header_region_message_subscribe(
|
||||
|
||||
/* Only subscribe to types. */
|
||||
StructRNA *type_array[] = {
|
||||
&RNA_DynamicOverrideProperty,
|
||||
&RNA_OverrideSet,
|
||||
&RNA_View3DShading,
|
||||
};
|
||||
|
||||
|
@@ -61,6 +61,43 @@ typedef struct LayerCollection {
|
||||
ListBase layer_collections; /* synced with collection->children */
|
||||
} LayerCollection;
|
||||
|
||||
typedef struct AffectedCollection {
|
||||
struct AffectedCollection *next, *prev;
|
||||
struct Collection *collection;
|
||||
} AffectedCollection;
|
||||
|
||||
typedef struct DynamicOverridePropertyData {
|
||||
int i[4];
|
||||
float f[4]; /*TODO 16 to support 4x4 matrices? Not sure we actually need that though... */
|
||||
struct ID *id;
|
||||
char *str;
|
||||
} DynamicOverridePropertyData;
|
||||
|
||||
typedef struct DynamicOverrideProperty {
|
||||
struct DynamicOverrideProperty *next, *prev;
|
||||
struct DynamicOverridePropertyData data;
|
||||
struct ID *root;
|
||||
char *rna_path;
|
||||
struct ListBase data_path; /* runtime: PropertyElemRNA */
|
||||
short flag;
|
||||
short property_type; /* eDynamicOverridePropertyType */
|
||||
short operation; /* See IDOVERRIDESTATIC_OP_ enums in DNA_ID.h */
|
||||
short id_type;
|
||||
short array_len;
|
||||
short pad[3];
|
||||
} DynamicOverrideProperty;
|
||||
|
||||
typedef struct OverrideSet {
|
||||
struct OverrideSet *next, *prev;
|
||||
char name[64]; /* MAX_NAME */
|
||||
short flag;
|
||||
short pad[2];
|
||||
short active_affected_collection;
|
||||
ListBase affected_collections; /* AffectedCollection */
|
||||
ListBase scene_properties;
|
||||
ListBase collection_properties;
|
||||
} OverrideSet;
|
||||
|
||||
typedef struct ViewLayer {
|
||||
struct ViewLayer *next, *prev;
|
||||
char name[64]; /* MAX_NAME */
|
||||
@@ -83,6 +120,10 @@ typedef struct ViewLayer {
|
||||
|
||||
struct FreestyleConfig freestyle_config;
|
||||
|
||||
struct ListBase override_sets; /* OverrideSet */
|
||||
short active_override_set;
|
||||
short pad2[3];
|
||||
|
||||
/* Runtime data */
|
||||
ListBase drawdata; /* ViewLayerEngineData */
|
||||
struct Base **object_bases_array;
|
||||
@@ -151,6 +192,22 @@ typedef struct SceneCollection {
|
||||
ListBase scene_collections; /* nested collections */
|
||||
} SceneCollection;
|
||||
|
||||
/* OverrideSet->flag */
|
||||
enum {
|
||||
DYN_OVERRIDE_SET_USE = (1 << 0),
|
||||
};
|
||||
|
||||
/* DynamicOverrideProperty->flag */
|
||||
enum {
|
||||
DYN_OVERRIDE_PROP_USE = (1 << 0),
|
||||
};
|
||||
|
||||
/* DynamicOverrideProperty->property_type */
|
||||
typedef enum eDynamicOverridePropertyType {
|
||||
DYN_OVERRIDE_PROP_TYPE_SCENE = 0,
|
||||
DYN_OVERRIDE_PROP_TYPE_COLLECTION = 1,
|
||||
} eDynamicOverridePropertyType;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@@ -38,6 +38,7 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
struct bContext;
|
||||
struct DynamicOverrideProperty;
|
||||
struct ID;
|
||||
struct IDOverrideStatic;
|
||||
struct IDOverrideStaticProperty;
|
||||
@@ -226,6 +227,7 @@ extern StructRNA RNA_DopeSheet;
|
||||
extern StructRNA RNA_Driver;
|
||||
extern StructRNA RNA_DriverTarget;
|
||||
extern StructRNA RNA_DriverVariable;
|
||||
extern StructRNA RNA_DynamicOverrideProperty;
|
||||
extern StructRNA RNA_DynamicPaintBrushSettings;
|
||||
extern StructRNA RNA_DynamicPaintCanvasSettings;
|
||||
extern StructRNA RNA_DynamicPaintModifier;
|
||||
@@ -455,6 +457,8 @@ extern StructRNA RNA_OperatorStrokeElement;
|
||||
extern StructRNA RNA_OperatorMacro;
|
||||
extern StructRNA RNA_OrController;
|
||||
extern StructRNA RNA_OutflowFluidSettings;
|
||||
extern StructRNA RNA_OverrideSet;
|
||||
extern StructRNA RNA_OverriddenCollection;
|
||||
extern StructRNA RNA_PackedFile;
|
||||
extern StructRNA RNA_Paint;
|
||||
extern StructRNA RNA_PaintCurve;
|
||||
@@ -1000,6 +1004,9 @@ bool RNA_path_resolve(PointerRNA *ptr, const char *path,
|
||||
bool RNA_path_resolve_full(PointerRNA *ptr, const char *path,
|
||||
PointerRNA *r_ptr, PropertyRNA **r_prop, int *r_index);
|
||||
|
||||
bool RNA_path_resolve_full_no_data(
|
||||
PointerRNA *ptr, const char *path, PointerRNA *r_ptr, PropertyRNA **r_prop, int *r_index);
|
||||
|
||||
/* path_resolve_property() variants ensure that pointer + property both exist */
|
||||
bool RNA_path_resolve_property(PointerRNA *ptr, const char *path,
|
||||
PointerRNA *r_ptr, PropertyRNA **r_prop);
|
||||
@@ -1015,6 +1022,7 @@ struct PropertyElemRNA {
|
||||
int index;
|
||||
};
|
||||
bool RNA_path_resolve_elements(PointerRNA *ptr, const char *path, struct ListBase *r_elements);
|
||||
bool RNA_path_resolve_elements_no_data(PointerRNA *ptr, const char *path, struct ListBase *r_elements);
|
||||
|
||||
char *RNA_path_from_ID_to_struct(PointerRNA *ptr);
|
||||
char *RNA_path_from_ID_to_property(PointerRNA *ptr, PropertyRNA *prop);
|
||||
@@ -1286,6 +1294,8 @@ void RNA_struct_override_apply(
|
||||
struct PointerRNA *ptr_local, struct PointerRNA *ptr_override, struct PointerRNA *ptr_storage,
|
||||
struct IDOverrideStatic *override);
|
||||
|
||||
void RNA_struct_dynamic_override_apply(struct PointerRNA *ptr, struct DynamicOverrideProperty *dyn_prop);
|
||||
|
||||
struct IDOverrideStaticProperty *RNA_property_override_property_find(PointerRNA *ptr, PropertyRNA *prop);
|
||||
struct IDOverrideStaticProperty *RNA_property_override_property_get(PointerRNA *ptr, PropertyRNA *prop, bool *r_created);
|
||||
|
||||
@@ -1296,6 +1306,7 @@ struct IDOverrideStaticPropertyOperation *RNA_property_override_property_operati
|
||||
const bool strict, bool *r_strict, bool *r_created);
|
||||
|
||||
eRNAOverrideStatus RNA_property_static_override_status(PointerRNA *ptr, PropertyRNA *prop, const int index);
|
||||
eRNAOverrideStatus RNA_property_dynamic_override_status(PointerRNA *ptr, PropertyRNA *prop, const int index);
|
||||
|
||||
void RNA_struct_state_owner_set(const char *name);
|
||||
const char *RNA_struct_state_owner_get(void);
|
||||
|
@@ -40,6 +40,7 @@ extern const EnumPropertyItem DummyRNA_NULL_items[];
|
||||
extern const EnumPropertyItem DummyRNA_DEFAULT_items[];
|
||||
|
||||
/* all others should follow 'rna_enum_*_items' naming */
|
||||
extern const EnumPropertyItem rna_enum_dynamic_override_property_type_items[];
|
||||
extern const EnumPropertyItem rna_enum_id_type_items[];
|
||||
|
||||
extern const EnumPropertyItem rna_enum_object_mode_items[];
|
||||
|
@@ -45,6 +45,7 @@ set(DEFSRC
|
||||
rna_context.c
|
||||
rna_curve.c
|
||||
rna_depsgraph.c
|
||||
rna_dynamic_override.c
|
||||
rna_dynamicpaint.c
|
||||
rna_fcurve.c
|
||||
rna_fluidsim.c
|
||||
|
@@ -3384,6 +3384,7 @@ static RNAProcessItem PROCESS_ITEMS[] = {
|
||||
{"rna_constraint.c", NULL, RNA_def_constraint},
|
||||
{"rna_context.c", NULL, RNA_def_context},
|
||||
{"rna_curve.c", "rna_curve_api.c", RNA_def_curve},
|
||||
{"rna_dynamic_override.c", NULL, RNA_def_dynamic_override},
|
||||
{"rna_dynamicpaint.c", NULL, RNA_def_dynamic_paint},
|
||||
{"rna_fcurve.c", "rna_fcurve_api.c", RNA_def_fcurve},
|
||||
{"rna_fluidsim.c", NULL, RNA_def_fluidsim},
|
||||
|
@@ -4611,7 +4611,7 @@ static bool rna_path_parse_array_index(const char **path, PointerRNA *ptr, Prope
|
||||
static bool rna_path_parse(PointerRNA *ptr, const char *path,
|
||||
PointerRNA *r_ptr, PropertyRNA **r_prop, int *r_index,
|
||||
ListBase *r_elements,
|
||||
const bool eval_pointer)
|
||||
const bool eval_pointer, const bool allow_type_only)
|
||||
{
|
||||
PropertyRNA *prop;
|
||||
PointerRNA curptr;
|
||||
@@ -4620,6 +4620,16 @@ static bool rna_path_parse(PointerRNA *ptr, const char *path,
|
||||
char fixedbuf[256];
|
||||
int type;
|
||||
|
||||
if (r_ptr) {
|
||||
*r_ptr = PointerRNA_NULL;
|
||||
}
|
||||
if (r_prop) {
|
||||
*r_prop = NULL;
|
||||
}
|
||||
if (r_index) {
|
||||
*r_index = -1;
|
||||
}
|
||||
|
||||
prop = NULL;
|
||||
curptr = *ptr;
|
||||
|
||||
@@ -4627,14 +4637,22 @@ static bool rna_path_parse(PointerRNA *ptr, const char *path,
|
||||
return false;
|
||||
|
||||
while (*path) {
|
||||
int use_id_prop = (*path == '[') ? 1 : 0;
|
||||
const bool use_id_prop = (*path == '[') ? 1 : 0;
|
||||
/* type-only path resolution is very limited with real RNA properties, and... totally impossible with IDProps. */
|
||||
const bool do_type_only = allow_type_only && !use_id_prop && curptr.data == NULL;
|
||||
char *token;
|
||||
/* custom property lookup ?
|
||||
* C.object["someprop"]
|
||||
*/
|
||||
|
||||
if (!curptr.data)
|
||||
if (!curptr.data && !do_type_only) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (prop != NULL) {
|
||||
/* We could not properly prepare dataptr for this iteration, so path is invalid. */
|
||||
return false;
|
||||
}
|
||||
|
||||
/* look up property name in current struct */
|
||||
token = rna_path_token(&path, fixedbuf, sizeof(fixedbuf), use_id_prop);
|
||||
@@ -4642,7 +4660,6 @@ static bool rna_path_parse(PointerRNA *ptr, const char *path,
|
||||
if (!token)
|
||||
return false;
|
||||
|
||||
prop = NULL;
|
||||
if (use_id_prop) { /* look up property name in current struct */
|
||||
IDProperty *group = RNA_struct_idprops(&curptr, 0);
|
||||
if (group && rna_token_strip_quotes(token))
|
||||
@@ -4677,7 +4694,20 @@ static bool rna_path_parse(PointerRNA *ptr, const char *path,
|
||||
* or explicitly requested
|
||||
*/
|
||||
if (eval_pointer || *path) {
|
||||
PointerRNA nextptr = RNA_property_pointer_get(&curptr, prop);
|
||||
PointerRNA nextptr;
|
||||
if (do_type_only) {
|
||||
StructRNA *nexttype = RNA_property_pointer_type(&curptr, prop);
|
||||
if (nexttype != &RNA_UnknownType) {
|
||||
RNA_pointer_create(NULL, nexttype, NULL, &nextptr);
|
||||
}
|
||||
else {
|
||||
/* We cannot go further... */
|
||||
break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
nextptr = RNA_property_pointer_get(&curptr, prop);
|
||||
}
|
||||
|
||||
curptr = nextptr;
|
||||
prop = NULL; /* now we have a PointerRNA, the prop is our parent so forget it */
|
||||
@@ -4691,7 +4721,8 @@ static bool rna_path_parse(PointerRNA *ptr, const char *path,
|
||||
* so eval_pointer is of no use here (esp. as in this case, we want to keep found prop,
|
||||
* erasing it breaks operators - e.g. bpy.types.Operator.bl_rna.foobar errors...).
|
||||
*/
|
||||
if (*path) {
|
||||
/* We do not support type-only at all with collections... */
|
||||
if (!do_type_only && *path) {
|
||||
PointerRNA nextptr;
|
||||
if (!rna_path_parse_collection_key(&path, &curptr, prop, &nextptr))
|
||||
return false;
|
||||
@@ -4742,7 +4773,7 @@ static bool rna_path_parse(PointerRNA *ptr, const char *path,
|
||||
*/
|
||||
bool RNA_path_resolve(PointerRNA *ptr, const char *path, PointerRNA *r_ptr, PropertyRNA **r_prop)
|
||||
{
|
||||
if (!rna_path_parse(ptr, path, r_ptr, r_prop, NULL, NULL, true))
|
||||
if (!rna_path_parse(ptr, path, r_ptr, r_prop, NULL, NULL, true, false))
|
||||
return false;
|
||||
|
||||
return r_ptr->data != NULL;
|
||||
@@ -4756,12 +4787,26 @@ bool RNA_path_resolve(PointerRNA *ptr, const char *path, PointerRNA *r_ptr, Prop
|
||||
*/
|
||||
bool RNA_path_resolve_full(PointerRNA *ptr, const char *path, PointerRNA *r_ptr, PropertyRNA **r_prop, int *r_index)
|
||||
{
|
||||
if (!rna_path_parse(ptr, path, r_ptr, r_prop, r_index, NULL, true))
|
||||
if (!rna_path_parse(ptr, path, r_ptr, r_prop, r_index, NULL, true, false))
|
||||
return false;
|
||||
|
||||
return r_ptr->data != NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve the given RNA Path to find the pointer and/or property + array index indicated by fully resolving the path,
|
||||
* like \a RNA_path_resolve_full, but also attempt to return a valid PropertyRNA + array index in case no data is given
|
||||
* (i.e. \a ptr.data is NULL).
|
||||
*
|
||||
* \note Assumes all pointers provided are valid.
|
||||
* \return True if path can be resolved to a valid "property" OR "property + array index"
|
||||
*/
|
||||
bool RNA_path_resolve_full_no_data(
|
||||
PointerRNA *ptr, const char *path, PointerRNA *r_ptr, PropertyRNA **r_prop, int *r_index)
|
||||
{
|
||||
return rna_path_parse(ptr, path, r_ptr, r_prop, r_index, NULL, true, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve the given RNA Path to find both the pointer AND property indicated by fully resolving the path.
|
||||
*
|
||||
@@ -4771,7 +4816,7 @@ bool RNA_path_resolve_full(PointerRNA *ptr, const char *path, PointerRNA *r_ptr,
|
||||
*/
|
||||
bool RNA_path_resolve_property(PointerRNA *ptr, const char *path, PointerRNA *r_ptr, PropertyRNA **r_prop)
|
||||
{
|
||||
if (!rna_path_parse(ptr, path, r_ptr, r_prop, NULL, NULL, false))
|
||||
if (!rna_path_parse(ptr, path, r_ptr, r_prop, NULL, NULL, false, false))
|
||||
return false;
|
||||
|
||||
return r_ptr->data != NULL && *r_prop != NULL;
|
||||
@@ -4787,7 +4832,7 @@ bool RNA_path_resolve_property(PointerRNA *ptr, const char *path, PointerRNA *r_
|
||||
*/
|
||||
bool RNA_path_resolve_property_full(PointerRNA *ptr, const char *path, PointerRNA *r_ptr, PropertyRNA **r_prop, int *r_index)
|
||||
{
|
||||
if (!rna_path_parse(ptr, path, r_ptr, r_prop, r_index, NULL, false))
|
||||
if (!rna_path_parse(ptr, path, r_ptr, r_prop, r_index, NULL, false, false))
|
||||
return false;
|
||||
|
||||
return r_ptr->data != NULL && *r_prop != NULL;
|
||||
@@ -4804,9 +4849,15 @@ bool RNA_path_resolve_property_full(PointerRNA *ptr, const char *path, PointerRN
|
||||
*/
|
||||
bool RNA_path_resolve_elements(PointerRNA *ptr, const char *path, ListBase *r_elements)
|
||||
{
|
||||
return rna_path_parse(ptr, path, NULL, NULL, NULL, r_elements, false);
|
||||
return rna_path_parse(ptr, path, NULL, NULL, NULL, r_elements, false, false);
|
||||
}
|
||||
|
||||
bool RNA_path_resolve_elements_no_data(PointerRNA *ptr, const char *path, ListBase *r_elements)
|
||||
{
|
||||
return rna_path_parse(ptr, path, NULL, NULL, NULL, r_elements, false, true);
|
||||
}
|
||||
|
||||
|
||||
char *RNA_path_append(const char *path, PointerRNA *UNUSED(ptr), PropertyRNA *prop, int intkey, const char *strkey)
|
||||
{
|
||||
DynStr *dynstr;
|
||||
@@ -7116,10 +7167,9 @@ bool RNA_property_reset(PointerRNA *ptr, PropertyRNA *prop, int index)
|
||||
}
|
||||
}
|
||||
|
||||
static bool rna_property_override_operation_apply(
|
||||
PointerRNA *ptr_local, PointerRNA *ptr_override, PointerRNA *ptr_storage,
|
||||
static bool rna_property_override_operation_apply(PointerRNA *ptr_local, PointerRNA *ptr_override, PointerRNA *ptr_storage,
|
||||
PropertyRNA *prop_local, PropertyRNA *prop_override, PropertyRNA *prop_storage,
|
||||
IDOverrideStaticPropertyOperation *opop);
|
||||
IDOverrideStaticPropertyOperation *opop, DynamicOverrideProperty *dyn_prop);
|
||||
|
||||
bool RNA_property_copy(PointerRNA *ptr, PointerRNA *fromptr, PropertyRNA *prop, int index)
|
||||
{
|
||||
@@ -7156,7 +7206,7 @@ bool RNA_property_copy(PointerRNA *ptr, PointerRNA *fromptr, PropertyRNA *prop,
|
||||
.subitem_reference_index = index,
|
||||
.subitem_local_index = index
|
||||
};
|
||||
return rna_property_override_operation_apply(ptr, fromptr, NULL, prop_dst, prop_src, NULL, &opop);
|
||||
return rna_property_override_operation_apply(ptr, fromptr, NULL, prop_dst, prop_src, NULL, &opop, NULL);
|
||||
}
|
||||
|
||||
/* use RNA_warning macro which includes __func__ suffix */
|
||||
@@ -7392,44 +7442,61 @@ static bool rna_property_override_operation_store(
|
||||
static bool rna_property_override_operation_apply(
|
||||
PointerRNA *ptr_local, PointerRNA *ptr_override, PointerRNA *ptr_storage,
|
||||
PropertyRNA *prop_local, PropertyRNA *prop_override, PropertyRNA *prop_storage,
|
||||
IDOverrideStaticPropertyOperation *opop)
|
||||
IDOverrideStaticPropertyOperation *opop, DynamicOverrideProperty *dyn_prop)
|
||||
{
|
||||
const bool is_dynamic_override = (opop == NULL);
|
||||
int len_local, len_reference, len_storage = 0;
|
||||
|
||||
const short override_op = opop->operation;
|
||||
const short override_op = is_dynamic_override ? dyn_prop->operation : opop->operation;
|
||||
|
||||
if (override_op == IDOVERRIDESTATIC_OP_NOOP) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (ELEM(override_op, IDOVERRIDESTATIC_OP_ADD, IDOVERRIDESTATIC_OP_SUBTRACT, IDOVERRIDESTATIC_OP_MULTIPLY) && !ptr_storage) {
|
||||
/* We cannot apply 'diff' override operations without some refference storage.
|
||||
* This should typically only happen at read time of .blend file... */
|
||||
return false;
|
||||
}
|
||||
if (!is_dynamic_override) {
|
||||
if (ELEM(override_op, IDOVERRIDESTATIC_OP_ADD, IDOVERRIDESTATIC_OP_SUBTRACT, IDOVERRIDESTATIC_OP_MULTIPLY) &&
|
||||
!ptr_storage)
|
||||
{
|
||||
/* We cannot apply 'diff' override operations without some refference storage.
|
||||
* This should typically only happen at read time of .blend file... */
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ELEM(override_op, IDOVERRIDESTATIC_OP_ADD, IDOVERRIDESTATIC_OP_SUBTRACT, IDOVERRIDESTATIC_OP_MULTIPLY) && !prop_storage) {
|
||||
/* We cannot apply 'diff' override operations without some refference storage.
|
||||
* This should typically only happen at read time of .blend file... */
|
||||
return false;
|
||||
if (ELEM(override_op, IDOVERRIDESTATIC_OP_ADD, IDOVERRIDESTATIC_OP_SUBTRACT, IDOVERRIDESTATIC_OP_MULTIPLY) &&
|
||||
!prop_storage)
|
||||
{
|
||||
/* We cannot apply 'diff' override operations without some refference storage.
|
||||
* This should typically only happen at read time of .blend file... */
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
RNAPropOverrideApply override_apply = NULL;
|
||||
/* Special case for IDProps, we use default callback then. */
|
||||
if (prop_local->magic != RNA_MAGIC) {
|
||||
override_apply = rna_property_override_apply_default;
|
||||
if (prop_override->magic == RNA_MAGIC && prop_override->override_apply != override_apply) {
|
||||
override_apply = NULL;
|
||||
if (is_dynamic_override) {
|
||||
if (prop_local->magic != RNA_MAGIC) {
|
||||
override_apply = rna_property_override_apply_default;
|
||||
}
|
||||
else {
|
||||
override_apply = prop_local->override_apply;
|
||||
}
|
||||
}
|
||||
else if (prop_override->magic != RNA_MAGIC) {
|
||||
override_apply = rna_property_override_apply_default;
|
||||
if (prop_local->override_apply != override_apply) {
|
||||
override_apply = NULL;
|
||||
else {
|
||||
if (prop_local->magic != RNA_MAGIC) {
|
||||
override_apply = rna_property_override_apply_default;
|
||||
if (prop_override->magic == RNA_MAGIC && prop_override->override_apply != override_apply) {
|
||||
override_apply = NULL;
|
||||
}
|
||||
}
|
||||
if (prop_override->magic != RNA_MAGIC) {
|
||||
override_apply = rna_property_override_apply_default;
|
||||
if (prop_local->override_apply != override_apply) {
|
||||
override_apply = NULL;
|
||||
}
|
||||
}
|
||||
else if (prop_local->override_apply == prop_override->override_apply) {
|
||||
override_apply = prop_local->override_apply;
|
||||
}
|
||||
}
|
||||
else if (prop_local->override_apply == prop_override->override_apply) {
|
||||
override_apply = prop_local->override_apply;
|
||||
}
|
||||
|
||||
if (ptr_storage && prop_storage->magic == RNA_MAGIC && prop_storage->override_apply != override_apply) {
|
||||
@@ -7438,9 +7505,16 @@ static bool rna_property_override_operation_apply(
|
||||
|
||||
if (override_apply == NULL) {
|
||||
#ifndef NDEBUG
|
||||
printf("'%s' gives unmatching or NULL RNA copy callbacks, should not happen (%d vs. %d).\n",
|
||||
prop_local->magic != RNA_MAGIC ? ((IDProperty *)prop_local)->name : prop_local->identifier,
|
||||
prop_local->magic == RNA_MAGIC, prop_override->magic == RNA_MAGIC);
|
||||
if (is_dynamic_override) {
|
||||
printf("'%s' gives NULL RNA copy callback, should not happen (%d).\n",
|
||||
prop_local->magic != RNA_MAGIC ? ((IDProperty *)prop_local)->name : prop_local->identifier,
|
||||
prop_local->magic == RNA_MAGIC);
|
||||
}
|
||||
else {
|
||||
printf("'%s' gives unmatching or NULL RNA copy callbacks, should not happen (%d vs. %d).\n",
|
||||
prop_local->magic != RNA_MAGIC ? ((IDProperty *)prop_local)->name : prop_local->identifier,
|
||||
prop_local->magic == RNA_MAGIC, prop_override->magic == RNA_MAGIC);
|
||||
}
|
||||
#endif
|
||||
BLI_assert(0);
|
||||
return false;
|
||||
@@ -7448,7 +7522,7 @@ static bool rna_property_override_operation_apply(
|
||||
|
||||
/* get the length of the array to work with */
|
||||
len_local = RNA_property_array_length(ptr_local, prop_local);
|
||||
len_reference = RNA_property_array_length(ptr_override, prop_override);
|
||||
len_reference = is_dynamic_override ? len_local : RNA_property_array_length(ptr_override, prop_override);
|
||||
if (ptr_storage) {
|
||||
len_storage = RNA_property_array_length(ptr_storage, prop_storage);
|
||||
}
|
||||
@@ -7463,7 +7537,7 @@ static bool rna_property_override_operation_apply(
|
||||
ptr_local, ptr_override, ptr_storage,
|
||||
prop_local, prop_override, prop_storage,
|
||||
len_local, len_reference, len_storage,
|
||||
opop);
|
||||
opop, dyn_prop);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -7612,7 +7686,7 @@ bool RNA_struct_override_matches(
|
||||
.subitem_local_index = -1
|
||||
};
|
||||
rna_property_override_operation_apply(ptr_local, ptr_reference, NULL,
|
||||
prop_local, prop_reference, NULL, &opop_tmp);
|
||||
prop_local, prop_reference, NULL, &opop_tmp, NULL);
|
||||
if (r_report_flags) {
|
||||
*r_report_flags |= RNA_OVERRIDE_MATCH_RESULT_RESTORED;
|
||||
}
|
||||
@@ -7716,7 +7790,7 @@ static void rna_property_override_apply_ex(
|
||||
continue;
|
||||
}
|
||||
if (!rna_property_override_operation_apply(ptr_local, ptr_override, ptr_storage,
|
||||
prop_local, prop_override, prop_storage, opop))
|
||||
prop_local, prop_override, prop_storage, opop, NULL))
|
||||
{
|
||||
/* TODO No assert here, would be much much better to just report as warning,
|
||||
* failing override applications will probably be fairly common! */
|
||||
@@ -7771,6 +7845,34 @@ void RNA_struct_override_apply(
|
||||
#endif
|
||||
}
|
||||
|
||||
/** Apply given dynamic \a dyn_prop operations on \a ptr_local. */
|
||||
void RNA_struct_dynamic_override_apply(PointerRNA *ptr, DynamicOverrideProperty *dyn_prop)
|
||||
{
|
||||
#ifdef DEBUG_OVERRIDE_TIMEIT
|
||||
TIMEIT_START_AVERAGED(RNA_struct_dynamic_override_apply);
|
||||
#endif
|
||||
/* Simplified for now! */
|
||||
|
||||
/* XXX For now, later we can use cached path in dyn_prop->data_path, even if only partially evaluated
|
||||
* (i.e. with no actual data), would still save us the whole string path parsing. */
|
||||
ListBase data_path = {0};
|
||||
if (RNA_path_resolve_elements(ptr, dyn_prop->rna_path, &data_path)) {
|
||||
rna_property_override_operation_apply(&((PropertyElemRNA *)data_path.last)->ptr, NULL, NULL,
|
||||
((PropertyElemRNA *)data_path.last)->prop, NULL, NULL,
|
||||
NULL, dyn_prop);
|
||||
}
|
||||
#ifndef NDEBUG
|
||||
else {
|
||||
printf("Failed to apply dynamic override operation to '%s.%s' (could not resolve some properties)\n",
|
||||
((ID *)ptr->id.data)->name, dyn_prop->rna_path);
|
||||
}
|
||||
#endif
|
||||
BLI_freelistN(&data_path);
|
||||
#ifdef DEBUG_OVERRIDE_TIMEIT
|
||||
TIMEIT_END_AVERAGED(RNA_struct_dynamic_override_apply);
|
||||
#endif
|
||||
}
|
||||
|
||||
IDOverrideStaticProperty *RNA_property_override_property_find(PointerRNA *ptr, PropertyRNA *prop)
|
||||
{
|
||||
ID *id = ptr->id.data;
|
||||
@@ -7830,14 +7932,10 @@ IDOverrideStaticPropertyOperation *RNA_property_override_property_operation_get(
|
||||
return BKE_override_static_property_operation_get(op, operation, NULL, NULL, index, index, strict, r_strict, r_created);
|
||||
}
|
||||
|
||||
eRNAOverrideStatus RNA_property_static_override_status(PointerRNA *ptr, PropertyRNA *prop, const int index)
|
||||
static eRNAOverrideStatus rna_property_override_status_common(PointerRNA *ptr, PropertyRNA *prop, const int index)
|
||||
{
|
||||
int override_status = 0;
|
||||
|
||||
if (!ptr || !prop || !ptr->id.data || !((ID *)ptr->id.data)->override_static) {
|
||||
return override_status;
|
||||
}
|
||||
|
||||
if (RNA_property_overridable_get(ptr, prop) && RNA_property_editable_flag(ptr, prop)) {
|
||||
override_status |= RNA_OVERRIDE_STATUS_OVERRIDABLE;
|
||||
}
|
||||
@@ -7856,7 +7954,21 @@ eRNAOverrideStatus RNA_property_static_override_status(PointerRNA *ptr, Property
|
||||
return override_status;
|
||||
}
|
||||
|
||||
eRNAOverrideStatus RNA_property_static_override_status(PointerRNA *ptr, PropertyRNA *prop, const int index)
|
||||
{
|
||||
if (!ptr || !prop || !ptr->id.data || !((ID *)ptr->id.data)->override_static) {
|
||||
return 0;
|
||||
}
|
||||
return rna_property_override_status_common(ptr, prop, index);
|
||||
}
|
||||
|
||||
eRNAOverrideStatus RNA_property_dynamic_override_status(PointerRNA *ptr, PropertyRNA *prop, const int index)
|
||||
{
|
||||
if (!ptr || !prop || !ptr->id.data) {
|
||||
return 0;
|
||||
}
|
||||
return rna_property_override_status_common(ptr, prop, index);
|
||||
}
|
||||
|
||||
bool RNA_path_resolved_create(
|
||||
PointerRNA *ptr, struct PropertyRNA *prop,
|
||||
|
@@ -78,6 +78,8 @@ const EnumPropertyItem rna_enum_keying_flag_items[] = {
|
||||
|
||||
#include "DEG_depsgraph.h"
|
||||
|
||||
#include "DNA_ID.h"
|
||||
#include "DNA_layer_types.h"
|
||||
#include "DNA_object_types.h"
|
||||
|
||||
#include "WM_api.h"
|
||||
@@ -589,8 +591,13 @@ bool rna_AnimaData_override_apply(
|
||||
PointerRNA *ptr_dst, PointerRNA *ptr_src, PointerRNA *ptr_storage,
|
||||
PropertyRNA *prop_dst, PropertyRNA *prop_src, PropertyRNA *UNUSED(prop_storage),
|
||||
const int len_dst, const int len_src, const int len_storage,
|
||||
IDOverrideStaticPropertyOperation *opop)
|
||||
IDOverrideStaticPropertyOperation *opop, DynamicOverrideProperty *dyn_prop)
|
||||
{
|
||||
if (dyn_prop != NULL) {
|
||||
printf("%s: unsupported dynamic override...", __func__);
|
||||
return false;
|
||||
}
|
||||
|
||||
BLI_assert(len_dst == len_src && (!ptr_storage || len_dst == len_storage) && len_dst == 0);
|
||||
BLI_assert(opop->operation == IDOVERRIDESTATIC_OP_REPLACE && "Unsupported RNA override operation on animdata pointer");
|
||||
UNUSED_VARS_NDEBUG(ptr_storage, len_dst, len_src, len_storage, opop);
|
||||
|
316
source/blender/makesrna/intern/rna_dynamic_override.c
Normal file
316
source/blender/makesrna/intern/rna_dynamic_override.c
Normal file
@@ -0,0 +1,316 @@
|
||||
/*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* Contributor(s): Blender Foundation.
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
/** \file blender/makesrna/intern/rna_dynamic_override.c
|
||||
* \ingroup RNA
|
||||
*/
|
||||
|
||||
#include "BLT_translation.h"
|
||||
|
||||
#include "BLI_math.h"
|
||||
|
||||
#include "DNA_ID.h"
|
||||
#include "DNA_layer_types.h"
|
||||
|
||||
#include "WM_types.h"
|
||||
|
||||
#include "RNA_define.h"
|
||||
#include "RNA_enum_types.h"
|
||||
|
||||
#include "rna_internal.h"
|
||||
|
||||
const EnumPropertyItem rna_enum_dynamic_override_property_type_items[] = {
|
||||
{DYN_OVERRIDE_PROP_TYPE_SCENE, "SCENE", 0, "Scene", ""},
|
||||
{DYN_OVERRIDE_PROP_TYPE_COLLECTION, "COLLECTION", 0, "Collection", ""},
|
||||
{0, NULL, 0, NULL, NULL}
|
||||
};
|
||||
|
||||
#ifdef RNA_RUNTIME
|
||||
|
||||
#include "RNA_access.h"
|
||||
|
||||
#include "BKE_layer.h"
|
||||
#include "BKE_scene.h"
|
||||
|
||||
#include "DEG_depsgraph.h"
|
||||
|
||||
static PropertyRNA *rna_DynamicOverride_property_get(PointerRNA *ptr)
|
||||
{
|
||||
DynamicOverrideProperty *dyn_prop = ptr->data;
|
||||
|
||||
/* Lazy building of RNA path elements if needed. */
|
||||
if (dyn_prop->data_path.first == NULL) {
|
||||
PointerRNA ptr_data;
|
||||
if (dyn_prop->root == NULL) {
|
||||
PointerRNA ptr_dummy;
|
||||
ID id_dummy;
|
||||
*((short *)id_dummy.name) = dyn_prop->id_type;
|
||||
RNA_id_pointer_create(&id_dummy, &ptr_dummy);
|
||||
RNA_pointer_create(NULL, rna_ID_refine(&ptr_dummy), NULL, &ptr_data);
|
||||
}
|
||||
else {
|
||||
RNA_id_pointer_create(dyn_prop->root, &ptr_data);
|
||||
}
|
||||
|
||||
RNA_path_resolve_elements_no_data(&ptr_data, dyn_prop->rna_path, &dyn_prop->data_path);
|
||||
}
|
||||
|
||||
PropertyElemRNA *prop_elem = dyn_prop->data_path.last;
|
||||
|
||||
/* Note that we have no 'invalid' value for PropertyRNA type... :/ */
|
||||
return prop_elem ? prop_elem->prop : NULL;
|
||||
|
||||
}
|
||||
|
||||
static void rna_DynamicOverrideProperty_name_get(PointerRNA *ptr, char *value)
|
||||
{
|
||||
PropertyRNA *prop = rna_DynamicOverride_property_get(ptr);
|
||||
if (prop == NULL) {
|
||||
DynamicOverrideProperty *dyn_prop = ptr->data;
|
||||
strcpy(value, dyn_prop->rna_path);
|
||||
}
|
||||
|
||||
const char *name = RNA_property_ui_name(prop);
|
||||
strcpy(value, name);
|
||||
}
|
||||
|
||||
static int rna_DynamicOverrideProperty_length(PointerRNA *ptr)
|
||||
{
|
||||
PropertyRNA *prop = rna_DynamicOverride_property_get(ptr);
|
||||
if (prop == NULL) {
|
||||
DynamicOverrideProperty *dyn_prop = ptr->data;
|
||||
return strlen(dyn_prop->rna_path);
|
||||
}
|
||||
|
||||
const char *name = RNA_property_ui_name(prop);
|
||||
return strlen(name);
|
||||
}
|
||||
|
||||
static int rna_DynamicOverrideProperty_data_type_get(PointerRNA *ptr)
|
||||
{
|
||||
PropertyRNA *prop = rna_DynamicOverride_property_get(ptr);
|
||||
return prop ? RNA_property_type(prop) : -1;
|
||||
}
|
||||
|
||||
static int rna_DynamicOverrideProperty_data_subtype_get(PointerRNA *ptr)
|
||||
{
|
||||
PropertyRNA *prop = rna_DynamicOverride_property_get(ptr);
|
||||
return prop ? RNA_property_subtype(prop) : -1;
|
||||
}
|
||||
|
||||
static int rna_DynamicOverrideProperty_value_boolean_get(PointerRNA *ptr)
|
||||
{
|
||||
DynamicOverrideProperty *dyn_prop = ptr->data;
|
||||
return dyn_prop->data.i[0];
|
||||
}
|
||||
|
||||
static void rna_DynamicOverrideProperty_value_boolean_set(PointerRNA *ptr, int value)
|
||||
{
|
||||
DynamicOverrideProperty *dyn_prop = ptr->data;
|
||||
dyn_prop->data.i[0] = value;
|
||||
}
|
||||
|
||||
static int rna_DynamicOverrideProperty_value_int_get(PointerRNA *ptr)
|
||||
{
|
||||
DynamicOverrideProperty *dyn_prop = ptr->data;
|
||||
return dyn_prop->data.i[0];
|
||||
}
|
||||
|
||||
static void rna_DynamicOverrideProperty_value_int_set(PointerRNA *ptr, int value)
|
||||
{
|
||||
DynamicOverrideProperty *dyn_prop = ptr->data;
|
||||
dyn_prop->data.i[0] = value;
|
||||
}
|
||||
|
||||
static void rna_DynamicOverrideProperty_value_int_range(
|
||||
PointerRNA *ptr, int *min, int *max,
|
||||
int *UNUSED(softmin), int *UNUSED(softmax))
|
||||
{
|
||||
DynamicOverrideProperty *dyn_prop = ptr->data;
|
||||
(void)dyn_prop;
|
||||
*min = INT_MIN;
|
||||
*max = INT_MAX;
|
||||
}
|
||||
|
||||
static float rna_DynamicOverrideProperty_value_float_get(PointerRNA *ptr)
|
||||
{
|
||||
DynamicOverrideProperty *dyn_prop = ptr->data;
|
||||
return dyn_prop->data.f[0];
|
||||
}
|
||||
|
||||
static void rna_DynamicOverrideProperty_value_float_set(PointerRNA *ptr, float value)
|
||||
{
|
||||
DynamicOverrideProperty *dyn_prop = ptr->data;
|
||||
dyn_prop->data.f[0] = value;
|
||||
}
|
||||
|
||||
static void rna_DynamicOverrideProperty_value_float_range(
|
||||
PointerRNA *ptr, float *min, float *max,
|
||||
float *UNUSED(softmin), float *UNUSED(softmax))
|
||||
{
|
||||
DynamicOverrideProperty *dyn_prop = ptr->data;
|
||||
(void)dyn_prop;
|
||||
*min = FLT_MIN;
|
||||
*max = FLT_MAX;
|
||||
}
|
||||
|
||||
static int rna_DynamicOverrideProperty_value_color_get_length(PointerRNA *ptr, int UNUSED(length[RNA_MAX_ARRAY_DIMENSION]))
|
||||
{
|
||||
DynamicOverrideProperty *dyn_prop = ptr->data;
|
||||
return dyn_prop->array_len;
|
||||
}
|
||||
|
||||
static void rna_DynamicOverrideProperty_value_color_get(PointerRNA *ptr, float *values)
|
||||
{
|
||||
DynamicOverrideProperty *dyn_prop = ptr->data;
|
||||
for (int i = 0; i < dyn_prop->array_len; i++) {
|
||||
values[i] = dyn_prop->data.f[i];
|
||||
}
|
||||
}
|
||||
|
||||
static void rna_DynamicOverrideProperty_value_color_set(PointerRNA *ptr, const float *values)
|
||||
{
|
||||
DynamicOverrideProperty *dyn_prop = ptr->data;
|
||||
for (int i = 0; i < dyn_prop->array_len; i++) {
|
||||
dyn_prop->data.f[i] = values[i];
|
||||
}
|
||||
}
|
||||
|
||||
static void rna_DynamicOverrideProperty_update(Main *bmain, Scene *scene, PointerRNA *ptr)
|
||||
{
|
||||
DynamicOverrideProperty *dyn_prop = ptr->data;
|
||||
ViewLayer *view_layer = BKE_view_layer_find_from_dynamic_override_property(scene, dyn_prop);
|
||||
Depsgraph *depsgraph =
|
||||
(Depsgraph *)BKE_scene_get_depsgraph(scene,
|
||||
view_layer,
|
||||
false);
|
||||
|
||||
switch (dyn_prop->property_type) {
|
||||
case DYN_OVERRIDE_PROP_TYPE_SCENE:
|
||||
DEG_graph_id_tag_update(bmain, depsgraph, &scene->id, DEG_TAG_COPY_ON_WRITE);
|
||||
break;
|
||||
case DYN_OVERRIDE_PROP_TYPE_COLLECTION:
|
||||
DEG_graph_id_type_tag_update(bmain, depsgraph, ID_OB, DEG_TAG_COPY_ON_WRITE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
void RNA_def_dynamic_override(BlenderRNA *brna)
|
||||
{
|
||||
StructRNA *srna;
|
||||
PropertyRNA *prop;
|
||||
|
||||
static const EnumPropertyItem rna_enum_dynamic_override_mode_items[] = {
|
||||
{IDOVERRIDESTATIC_OP_REPLACE, "REPLACE", 0, "Replace", ""},
|
||||
{IDOVERRIDESTATIC_OP_MULTIPLY, "MULTIPLY", 0, "Multiply", ""},
|
||||
{0, NULL, 0, NULL, NULL}
|
||||
};
|
||||
|
||||
srna = RNA_def_struct(brna, "DynamicOverrideProperty", NULL);
|
||||
RNA_def_struct_ui_text(srna, "Dynamic Override Property", "Properties overridden by override set");
|
||||
|
||||
prop = RNA_def_property(srna, "name", PROP_STRING, PROP_NONE);
|
||||
RNA_def_property_string_funcs(prop,
|
||||
"rna_DynamicOverrideProperty_name_get",
|
||||
"rna_DynamicOverrideProperty_length",
|
||||
NULL);
|
||||
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
|
||||
RNA_def_property_ui_text(prop, "Name", "Property name");
|
||||
|
||||
prop = RNA_def_property(srna, "use", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "flag", DYN_OVERRIDE_PROP_USE);
|
||||
RNA_def_property_ui_text(prop, "Enabled", "Disable or enable the overridden property");
|
||||
RNA_def_property_update(prop, NC_SCENE | ND_DYN_OVERRIDES, "rna_DynamicOverrideProperty_update");
|
||||
|
||||
prop = RNA_def_property(srna, "type", PROP_ENUM, PROP_NONE);
|
||||
RNA_def_property_enum_sdna(prop, NULL, "property_type");
|
||||
RNA_def_property_enum_items(prop, rna_enum_dynamic_override_property_type_items);
|
||||
RNA_def_property_ui_text(prop, "Type",
|
||||
"Whether the property affects the entire scene or the collection objects only");
|
||||
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
|
||||
|
||||
prop = RNA_def_property(srna, "owner_id", PROP_POINTER, PROP_NONE);
|
||||
RNA_def_property_pointer_sdna(prop, NULL, "root");
|
||||
RNA_def_property_ui_text(prop, "ID",
|
||||
"ID owner");
|
||||
|
||||
prop = RNA_def_property(srna, "id_type", PROP_ENUM, PROP_NONE);
|
||||
RNA_def_property_enum_items(prop, rna_enum_id_type_items);
|
||||
RNA_def_property_ui_text(prop, "ID Type",
|
||||
"Type of ID block that owns this property");
|
||||
RNA_def_property_translation_context(prop, BLT_I18NCONTEXT_ID_ID);
|
||||
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
|
||||
|
||||
prop = RNA_def_property(srna, "override_mode", PROP_ENUM, PROP_NONE);
|
||||
RNA_def_property_enum_sdna(prop, NULL, "operation");
|
||||
RNA_def_property_enum_items(prop, rna_enum_dynamic_override_mode_items);
|
||||
RNA_def_property_ui_text(prop, "Override Mode",
|
||||
"Method of override the original values");
|
||||
RNA_def_property_update(prop, NC_SCENE | ND_DYN_OVERRIDES, "rna_DynamicOverrideProperty_update");
|
||||
|
||||
prop = RNA_def_property(srna, "data_type", PROP_ENUM, PROP_NONE);
|
||||
RNA_def_property_enum_items(prop, rna_enum_property_type_items);
|
||||
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
|
||||
RNA_def_property_enum_funcs(prop, "rna_DynamicOverrideProperty_data_type_get", NULL, NULL);
|
||||
RNA_def_property_ui_text(prop, "Type", "Data type of the property");
|
||||
|
||||
prop = RNA_def_property(srna, "data_subtype", PROP_ENUM, PROP_NONE);
|
||||
RNA_def_property_enum_items(prop, rna_enum_property_subtype_items);
|
||||
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
|
||||
RNA_def_property_enum_funcs(prop, "rna_DynamicOverrideProperty_data_subtype_get", NULL, NULL);
|
||||
RNA_def_property_ui_text(prop, "Subtype", "Data subtype of the property");
|
||||
|
||||
/* Accessors for the different value types. */
|
||||
prop = RNA_def_property(srna, "value_boolean", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_funcs(prop,
|
||||
"rna_DynamicOverrideProperty_value_boolean_get",
|
||||
"rna_DynamicOverrideProperty_value_boolean_set");
|
||||
RNA_def_property_update(prop, NC_SCENE | ND_DYN_OVERRIDES, "rna_DynamicOverrideProperty_update");
|
||||
|
||||
prop = RNA_def_property(srna, "value_int", PROP_INT, PROP_NONE);
|
||||
RNA_def_property_int_funcs(prop,
|
||||
"rna_DynamicOverrideProperty_value_int_get",
|
||||
"rna_DynamicOverrideProperty_value_int_set",
|
||||
"rna_DynamicOverrideProperty_value_int_range");
|
||||
RNA_def_property_update(prop, NC_SCENE | ND_DYN_OVERRIDES, "rna_DynamicOverrideProperty_update");
|
||||
|
||||
prop = RNA_def_property(srna, "value_float", PROP_FLOAT, PROP_NONE);
|
||||
RNA_def_property_float_funcs(prop,
|
||||
"rna_DynamicOverrideProperty_value_float_get",
|
||||
"rna_DynamicOverrideProperty_value_float_set",
|
||||
"rna_DynamicOverrideProperty_value_float_range");
|
||||
RNA_def_property_update(prop, NC_SCENE | ND_DYN_OVERRIDES, "rna_DynamicOverrideProperty_update");
|
||||
|
||||
prop = RNA_def_property(srna, "value_color", PROP_FLOAT, PROP_COLOR);
|
||||
RNA_def_property_flag(prop, PROP_DYNAMIC);
|
||||
RNA_def_property_multi_array(prop, 1, NULL);
|
||||
RNA_def_property_dynamic_array_funcs(prop, "rna_DynamicOverrideProperty_value_color_get_length");
|
||||
RNA_def_property_float_funcs(prop,
|
||||
"rna_DynamicOverrideProperty_value_color_get",
|
||||
"rna_DynamicOverrideProperty_value_color_set",
|
||||
NULL);
|
||||
RNA_def_property_update(prop, NC_SCENE | ND_DYN_OVERRIDES, "rna_DynamicOverrideProperty_update");
|
||||
}
|
||||
|
||||
#endif
|
@@ -36,6 +36,7 @@
|
||||
#define RNA_MAGIC ((int)~0)
|
||||
|
||||
struct Depsgraph;
|
||||
struct DynamicOverrideProperty;
|
||||
struct FreestyleSettings;
|
||||
struct ID;
|
||||
struct IDOverrideStatic;
|
||||
@@ -149,6 +150,7 @@ void RNA_def_context(struct BlenderRNA *brna);
|
||||
void RNA_def_controller(struct BlenderRNA *brna);
|
||||
void RNA_def_curve(struct BlenderRNA *brna);
|
||||
void RNA_def_depsgraph(struct BlenderRNA *brna);
|
||||
void RNA_def_dynamic_override(struct BlenderRNA *brna);
|
||||
void RNA_def_dynamic_paint(struct BlenderRNA *brna);
|
||||
void RNA_def_fluidsim(struct BlenderRNA *brna);
|
||||
void RNA_def_fcurve(struct BlenderRNA *brna);
|
||||
@@ -208,7 +210,7 @@ bool rna_AnimaData_override_apply(
|
||||
struct PointerRNA *ptr_local, struct PointerRNA *ptr_reference, struct PointerRNA *ptr_storage,
|
||||
struct PropertyRNA *prop_local, struct PropertyRNA *prop_reference, struct PropertyRNA *prop_storage,
|
||||
const int len_local, const int len_reference, const int len_storage,
|
||||
struct IDOverrideStaticPropertyOperation *opop);
|
||||
struct IDOverrideStaticPropertyOperation *opop, struct DynamicOverrideProperty *dyn_prop);
|
||||
|
||||
void rna_def_animviz_common(struct StructRNA *srna);
|
||||
void rna_def_motionpath_common(struct StructRNA *srna);
|
||||
@@ -427,7 +429,7 @@ bool rna_property_override_apply_default(
|
||||
struct PointerRNA *ptr_dst, struct PointerRNA *ptr_src, struct PointerRNA *ptr_storage,
|
||||
struct PropertyRNA *prop_dst, struct PropertyRNA *prop_src, struct PropertyRNA *prop_storage,
|
||||
const int len_dst, const int len_src, const int len_storage,
|
||||
struct IDOverrideStaticPropertyOperation *opop);
|
||||
struct IDOverrideStaticPropertyOperation *opop, struct DynamicOverrideProperty *dyn_prop);
|
||||
|
||||
|
||||
/* Builtin Property Callbacks */
|
||||
|
@@ -40,6 +40,7 @@ struct PointerRNA;
|
||||
struct FunctionRNA;
|
||||
struct CollectionPropertyIterator;
|
||||
struct bContext;
|
||||
struct DynamicOverrideProperty;
|
||||
struct IDOverrideStatic;
|
||||
struct IDOverrideStaticProperty;
|
||||
struct IDOverrideStaticPropertyOperation;
|
||||
@@ -166,7 +167,7 @@ typedef bool (*RNAPropOverrideApply)(
|
||||
struct PointerRNA *ptr_dst, struct PointerRNA *ptr_src, struct PointerRNA *ptr_storage,
|
||||
struct PropertyRNA *prop_dst, struct PropertyRNA *prop_src, struct PropertyRNA *prop_storage,
|
||||
const int len_dst, const int len_src, const int len_storage,
|
||||
struct IDOverrideStaticPropertyOperation *opop);
|
||||
struct IDOverrideStaticPropertyOperation *opop, struct DynamicOverrideProperty *dyn_prop);
|
||||
|
||||
/* Container - generic abstracted container of RNA properties */
|
||||
typedef struct ContainerRNA {
|
||||
|
@@ -44,6 +44,7 @@
|
||||
#include "WM_types.h"
|
||||
|
||||
#include "RNA_define.h"
|
||||
#include "RNA_enum_types.h"
|
||||
|
||||
#include "rna_internal.h"
|
||||
|
||||
@@ -190,6 +191,195 @@ static void rna_ObjectBase_select_update(Main *UNUSED(bmain), Scene *UNUSED(scen
|
||||
ED_object_base_select(base, mode);
|
||||
}
|
||||
|
||||
static void rna_OverriddenCollection_name_get(PointerRNA *ptr, char *value)
|
||||
{
|
||||
Collection *collection = ((AffectedCollection *)ptr->data)->collection;
|
||||
strcpy(value, collection->id.name + 2);
|
||||
}
|
||||
|
||||
static int rna_OverriddenCollection_name_length(PointerRNA *ptr)
|
||||
{
|
||||
Collection *collection = ((AffectedCollection *)ptr->data)->collection;
|
||||
return strnlen(collection->id.name + 2, sizeof(collection->id.name));
|
||||
}
|
||||
|
||||
static int rna_OverriddenCollections_active_index_get(PointerRNA *ptr)
|
||||
{
|
||||
OverrideSet *override_set = (OverrideSet *)ptr->data;
|
||||
return override_set->active_affected_collection;
|
||||
}
|
||||
|
||||
static void rna_OverriddenCollections_active_index_set(PointerRNA *ptr, int value)
|
||||
{
|
||||
OverrideSet *override_set = (OverrideSet *)ptr->data;
|
||||
override_set->active_affected_collection = value;
|
||||
}
|
||||
|
||||
static void rna_OverriddenCollections_active_index_index_range(
|
||||
PointerRNA *ptr, int *min, int *max, int *UNUSED(softmin), int *UNUSED(softmax))
|
||||
{
|
||||
OverrideSet *override_set = (OverrideSet *)ptr->data;
|
||||
*min = 0;
|
||||
*max = max_ii(0, BLI_listbase_count(&override_set->affected_collections) - 1);
|
||||
}
|
||||
|
||||
static PointerRNA rna_OverriddenCollections_active_get(PointerRNA *ptr)
|
||||
{
|
||||
OverrideSet *override_set = (OverrideSet *)ptr->data;
|
||||
LinkData *link = BLI_findlink(&override_set->affected_collections, override_set->active_affected_collection);
|
||||
return rna_pointer_inherit_refine(ptr, &RNA_OverriddenCollection, link);
|
||||
}
|
||||
|
||||
static void rna_OverriddenCollections_active_set(PointerRNA *ptr, PointerRNA value)
|
||||
{
|
||||
OverrideSet *override_set = (OverrideSet *)ptr->data;
|
||||
LinkData *link = (LinkData *)value.data;
|
||||
|
||||
const int index = BLI_findindex(&override_set->affected_collections, link);
|
||||
if (index != -1) {
|
||||
override_set->active_affected_collection = index;
|
||||
}
|
||||
}
|
||||
|
||||
static void rna_OverriddenCollection_link(
|
||||
ID *id, OverrideSet *override_set, Main *bmain, bContext *C, ReportList *reports, Collection *collection)
|
||||
{
|
||||
if (!BKE_view_layer_override_set_collection_link(override_set, collection)) {
|
||||
BKE_reportf(reports,
|
||||
RPT_ERROR,
|
||||
"Collection '%s' already affected by override set '%s'",
|
||||
collection->id.name + 2,
|
||||
override_set->name);
|
||||
return;
|
||||
}
|
||||
|
||||
Depsgraph *depsgraph = CTX_data_depsgraph(C);
|
||||
Scene *scene = (Scene *)id;
|
||||
DEG_graph_id_tag_update(bmain, depsgraph, &scene->id, DEG_TAG_COPY_ON_WRITE);
|
||||
DEG_graph_id_type_tag_update(bmain, depsgraph, ID_OB, DEG_TAG_COPY_ON_WRITE);
|
||||
WM_main_add_notifier(NC_SCENE | ND_DYN_OVERRIDES, scene);
|
||||
}
|
||||
|
||||
static void rna_OverriddenCollection_unlink(
|
||||
ID *id, OverrideSet *override_set, Main *bmain, bContext *C, ReportList *reports, Collection *collection)
|
||||
{
|
||||
if (!BKE_view_layer_override_set_collection_unlink(override_set, collection)) {
|
||||
BKE_reportf(reports,
|
||||
RPT_ERROR,
|
||||
"Collection '%s' is not affected by override set '%s'",
|
||||
collection->id.name + 2,
|
||||
override_set->name);
|
||||
return;
|
||||
}
|
||||
|
||||
Depsgraph *depsgraph = CTX_data_depsgraph(C);
|
||||
Scene *scene = (Scene *)id;
|
||||
DEG_graph_id_tag_update(bmain, depsgraph, &scene->id, DEG_TAG_COPY_ON_WRITE);
|
||||
DEG_graph_id_type_tag_update(bmain, depsgraph, ID_OB, DEG_TAG_COPY_ON_WRITE);
|
||||
WM_main_add_notifier(NC_SCENE | ND_DYN_OVERRIDES, scene);
|
||||
}
|
||||
|
||||
static char *rna_OverrideSet_path(PointerRNA *ptr)
|
||||
{
|
||||
OverrideSet *override_set = (OverrideSet *)ptr->data;
|
||||
return BLI_sprintfN("view_layer.override_sets[\"%s\"]", override_set->name);
|
||||
}
|
||||
|
||||
static void rna_OverrideSet_name_set(PointerRNA *ptr, const char *value)
|
||||
{
|
||||
Scene *scene = (Scene *)ptr->id.data;
|
||||
OverrideSet *override_set = (OverrideSet *)ptr->data;
|
||||
|
||||
ViewLayer *view_layer = BKE_view_layer_find_from_override_set(scene, override_set);
|
||||
BLI_strncpy_utf8(override_set->name, value, sizeof(override_set->name));
|
||||
BLI_uniquename(&view_layer->override_sets,
|
||||
override_set,
|
||||
DATA_("OverrideSet"),
|
||||
'.',
|
||||
offsetof(OverrideSet, name),
|
||||
sizeof(override_set->name));
|
||||
}
|
||||
|
||||
static void rna_OverrideSet_update(Main *bmain, Scene *scene, PointerRNA *ptr)
|
||||
{
|
||||
OverrideSet *override_set = (OverrideSet *)ptr->data;
|
||||
ViewLayer *view_layer = BKE_view_layer_find_from_override_set(scene, override_set);
|
||||
Depsgraph *depsgraph =
|
||||
(Depsgraph *)BKE_scene_get_depsgraph(scene,
|
||||
view_layer,
|
||||
false);
|
||||
|
||||
DEG_graph_id_tag_update(bmain, depsgraph, &scene->id, DEG_TAG_COPY_ON_WRITE);
|
||||
DEG_graph_id_type_tag_update(bmain, depsgraph, ID_OB, DEG_TAG_COPY_ON_WRITE);
|
||||
}
|
||||
|
||||
static int rna_OverrideSets_active_override_set_index_get(PointerRNA *ptr)
|
||||
{
|
||||
ViewLayer *view_layer = (ViewLayer *)ptr->data;
|
||||
return view_layer->active_override_set;
|
||||
}
|
||||
|
||||
static void rna_OverrideSets_active_override_set_index_set(PointerRNA *ptr, int value)
|
||||
{
|
||||
ViewLayer *view_layer = (ViewLayer *)ptr->data;
|
||||
view_layer->active_override_set = value;
|
||||
}
|
||||
|
||||
static void rna_OverrideSets_active_override_set_index_range(
|
||||
PointerRNA *ptr, int *min, int *max, int *UNUSED(softmin), int *UNUSED(softmax))
|
||||
{
|
||||
ViewLayer *view_layer = (ViewLayer *)ptr->data;
|
||||
|
||||
*min = 0;
|
||||
*max = max_ii(0, BLI_listbase_count(&view_layer->override_sets) - 1);
|
||||
}
|
||||
|
||||
static PointerRNA rna_OverrideSets_active_override_set_get(PointerRNA *ptr)
|
||||
{
|
||||
ViewLayer *view_layer = (ViewLayer *)ptr->data;
|
||||
OverrideSet *override_set = BLI_findlink(&view_layer->override_sets, view_layer->active_override_set);
|
||||
return rna_pointer_inherit_refine(ptr, &RNA_OverrideSet, override_set);
|
||||
}
|
||||
|
||||
static void rna_OverrideSets_active_override_set_set(PointerRNA *ptr, PointerRNA value)
|
||||
{
|
||||
ViewLayer *view_layer = (ViewLayer *)ptr->data;
|
||||
OverrideSet *override_set = (OverrideSet *)value.data;
|
||||
const int index = BLI_findindex(&view_layer->override_sets, override_set);
|
||||
if (index != -1) {
|
||||
view_layer->active_override_set = index;
|
||||
}
|
||||
}
|
||||
|
||||
static OverrideSet *rna_OverrideSet_new(ID *id, ViewLayer *view_layer, const char *name)
|
||||
{
|
||||
Scene *scene = (Scene *)id;
|
||||
OverrideSet *override_set = BKE_view_layer_override_set_add(view_layer, name);
|
||||
DEG_id_tag_update(&scene->id, DEG_TAG_COPY_ON_WRITE);
|
||||
WM_main_add_notifier(NC_SCENE | ND_DYN_OVERRIDES, scene);
|
||||
return override_set;
|
||||
}
|
||||
|
||||
static void rna_OverrideSet_remove(
|
||||
ID *id, ViewLayer *view_layer, Main *UNUSED(bmain), ReportList *reports, PointerRNA *ptr)
|
||||
{
|
||||
OverrideSet *override_set = ptr->data;
|
||||
Scene *scene = (Scene *)id;
|
||||
|
||||
if (!BKE_view_layer_override_set_remove(view_layer, override_set)) {
|
||||
BKE_reportf(reports,
|
||||
RPT_ERROR,
|
||||
"Override set'%s' could not be removed from view layer '%s'",
|
||||
override_set->name,
|
||||
view_layer->name);
|
||||
return;
|
||||
}
|
||||
|
||||
RNA_POINTER_INVALIDATE(ptr);
|
||||
DEG_id_tag_update(&scene->id, DEG_TAG_COPY_ON_WRITE);
|
||||
WM_main_add_notifier(NC_SCENE | ND_DYN_OVERRIDES, scene);
|
||||
}
|
||||
|
||||
static void rna_LayerCollection_use_update(Main *bmain, Scene *UNUSED(scene), PointerRNA *ptr)
|
||||
{
|
||||
Scene *scene = (Scene *)ptr->id.data;
|
||||
@@ -299,6 +489,154 @@ static void rna_def_object_base(BlenderRNA *brna)
|
||||
RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, "rna_ObjectBase_select_update");
|
||||
}
|
||||
|
||||
static void rna_def_overridden_collection(BlenderRNA *brna)
|
||||
{
|
||||
StructRNA *srna;
|
||||
PropertyRNA *prop;
|
||||
|
||||
srna = RNA_def_struct(brna, "OverriddenCollection", NULL);
|
||||
RNA_def_struct_ui_text(srna, "Overridden Collection", "Collection overridden by override set");
|
||||
RNA_def_struct_ui_icon(srna, ICON_COLLAPSEMENU);
|
||||
|
||||
prop = RNA_def_property(srna, "name", PROP_STRING, PROP_NONE);
|
||||
RNA_def_property_string_funcs(prop,
|
||||
"rna_OverriddenCollection_name_get",
|
||||
"rna_OverriddenCollection_name_length",
|
||||
NULL);
|
||||
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
|
||||
RNA_def_property_ui_text(prop, "Name", "Collection name");
|
||||
}
|
||||
|
||||
static void rna_def_overridden_collections(BlenderRNA *brna, PropertyRNA *cprop)
|
||||
{
|
||||
StructRNA *srna;
|
||||
FunctionRNA *func;
|
||||
PropertyRNA *prop;
|
||||
PropertyRNA *parm;
|
||||
|
||||
RNA_def_property_srna(cprop, "OverriddenCollections");
|
||||
srna = RNA_def_struct(brna, "OverriddenCollections", NULL);
|
||||
RNA_def_struct_sdna(srna, "OverrideSet");
|
||||
RNA_def_struct_ui_text(srna, "Overridden Collections", "Collections overridden by override set");
|
||||
|
||||
prop = RNA_def_property(srna, "active_index", PROP_INT, PROP_UNSIGNED);
|
||||
RNA_def_property_int_funcs(prop,
|
||||
"rna_OverriddenCollections_active_index_get",
|
||||
"rna_OverriddenCollections_active_index_set",
|
||||
"rna_OverriddenCollections_active_index_index_range");
|
||||
RNA_def_property_ui_text(prop, "Active Affected Collection Index", "Active index in override set array");
|
||||
|
||||
prop = RNA_def_property(srna, "active", PROP_POINTER, PROP_NONE);
|
||||
RNA_def_property_struct_type(prop, "OverriddenCollection");
|
||||
RNA_def_property_pointer_funcs(prop,
|
||||
"rna_OverriddenCollections_active_get",
|
||||
"rna_OverriddenCollections_active_set",
|
||||
NULL, NULL);
|
||||
RNA_def_property_flag(prop, PROP_EDITABLE | PROP_NEVER_NULL);
|
||||
RNA_def_property_ui_text(prop, "Active Affected Collection", "Active affected collection in override set array");
|
||||
|
||||
func = RNA_def_function(srna, "link", "rna_OverriddenCollection_link");
|
||||
RNA_def_function_ui_description(func, "Link collection to override set");
|
||||
RNA_def_function_flag(func, FUNC_USE_SELF_ID | FUNC_USE_MAIN | FUNC_USE_CONTEXT | FUNC_USE_REPORTS);
|
||||
parm = RNA_def_pointer(func, "collection", "Collection", "", "Collection to link to override set");
|
||||
RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED);
|
||||
|
||||
func = RNA_def_function(srna, "unlink", "rna_OverriddenCollection_unlink");
|
||||
RNA_def_function_ui_description(func, "Unlink a collection from override set");
|
||||
RNA_def_function_flag(func, FUNC_USE_SELF_ID | FUNC_USE_MAIN | FUNC_USE_CONTEXT | FUNC_USE_REPORTS);
|
||||
parm = RNA_def_pointer(func, "collection", "Collection", "", "Collection to unlink from override set");
|
||||
RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED);
|
||||
|
||||
rna_def_overridden_collection(brna);
|
||||
}
|
||||
|
||||
static void rna_def_override_set(BlenderRNA *brna)
|
||||
{
|
||||
StructRNA *srna;
|
||||
PropertyRNA *prop;
|
||||
|
||||
srna = RNA_def_struct(brna, "OverrideSet", NULL);
|
||||
RNA_def_struct_ui_text(srna, "Override Set", "Set of overrides");
|
||||
RNA_def_struct_path_func(srna, "rna_OverrideSet_path");
|
||||
|
||||
prop = RNA_def_property(srna, "name", PROP_STRING, PROP_NONE);
|
||||
RNA_def_property_string_funcs(prop, NULL, NULL, "rna_OverrideSet_name_set");
|
||||
RNA_def_property_ui_text(prop, "Name", "Override set name");
|
||||
RNA_def_struct_name_property(srna, prop);
|
||||
RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL);
|
||||
|
||||
prop = RNA_def_property(srna, "use", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "flag", DYN_OVERRIDE_SET_USE);
|
||||
RNA_def_property_ui_text(prop, "Enabled", "Disable or enable the override set");
|
||||
RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, "rna_OverrideSet_update");
|
||||
|
||||
prop = RNA_def_property(srna, "affected_collections", PROP_COLLECTION, PROP_NONE);
|
||||
RNA_def_property_collection_sdna(prop, NULL, "affected_collections", NULL);
|
||||
RNA_def_property_struct_type(prop, "OverriddenCollection");
|
||||
RNA_def_property_ui_text(prop, "Affected Collections", "Collections that overridden by override set");
|
||||
rna_def_overridden_collections(brna, prop);
|
||||
|
||||
prop = RNA_def_property(srna, "scene_properties", PROP_COLLECTION, PROP_NONE);
|
||||
RNA_def_property_collection_sdna(prop, NULL, "scene_properties", NULL);
|
||||
RNA_def_property_struct_type(prop, "DynamicOverrideProperty");
|
||||
RNA_def_property_ui_text(prop, "Dynamic Override Properties", "Properties overriden for the entire scene");
|
||||
|
||||
prop = RNA_def_property(srna, "collection_properties", PROP_COLLECTION, PROP_NONE);
|
||||
RNA_def_property_collection_sdna(prop, NULL, "collection_properties", NULL);
|
||||
RNA_def_property_struct_type(prop, "DynamicOverrideProperty");
|
||||
RNA_def_property_ui_text(prop,
|
||||
"Dynamic Override Properties",
|
||||
"Properties overriden for the objects in the affected collections");
|
||||
}
|
||||
|
||||
static void rna_def_override_sets(BlenderRNA *brna, PropertyRNA *cprop)
|
||||
{
|
||||
StructRNA *srna;
|
||||
FunctionRNA *func;
|
||||
PropertyRNA *prop;
|
||||
PropertyRNA *parm;
|
||||
|
||||
RNA_def_property_srna(cprop, "OverrideSets");
|
||||
srna = RNA_def_struct(brna, "OverrideSets", NULL);
|
||||
RNA_def_struct_sdna(srna, "ViewLayer");
|
||||
RNA_def_struct_ui_text(srna, "Override Sets", "Sets of view layer overrides");
|
||||
|
||||
prop = RNA_def_property(srna, "active_index", PROP_INT, PROP_UNSIGNED);
|
||||
RNA_def_property_int_funcs(prop,
|
||||
"rna_OverrideSets_active_override_set_index_get",
|
||||
"rna_OverrideSets_active_override_set_index_set",
|
||||
"rna_OverrideSets_active_override_set_index_range");
|
||||
RNA_def_property_ui_text(prop, "Active Override Set Index", "Active index in override set array");
|
||||
RNA_def_property_update(prop, NC_SCENE | ND_DYN_OVERRIDES, NULL);
|
||||
|
||||
prop = RNA_def_property(srna, "active", PROP_POINTER, PROP_NONE);
|
||||
RNA_def_property_struct_type(prop, "OverrideSet");
|
||||
RNA_def_property_pointer_funcs(prop,
|
||||
"rna_OverrideSets_active_override_set_get",
|
||||
"rna_OverrideSets_active_override_set_set",
|
||||
NULL, NULL);
|
||||
RNA_def_property_flag(prop, PROP_EDITABLE | PROP_NEVER_NULL);
|
||||
RNA_def_property_ui_text(prop, "Active Override Set", "Active Override Set");
|
||||
RNA_def_property_update(prop, NC_SCENE | ND_DYN_OVERRIDES, NULL);
|
||||
|
||||
func = RNA_def_function(srna, "new", "rna_OverrideSet_new");
|
||||
RNA_def_function_ui_description(func, "Add an override set to view layer");
|
||||
RNA_def_function_flag(func, FUNC_USE_SELF_ID);
|
||||
parm = RNA_def_string(func, "name", "Name", 0, "", "New name for the override set");
|
||||
RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
|
||||
parm = RNA_def_pointer(func, "result", "OverrideSet", "", "Newly created override set");
|
||||
RNA_def_function_return(func, parm);
|
||||
|
||||
func = RNA_def_function(srna, "remove", "rna_OverrideSet_remove");
|
||||
RNA_def_function_ui_description(func, "Remove an override set from view layer");
|
||||
RNA_def_function_flag(func, FUNC_USE_MAIN | FUNC_USE_REPORTS | FUNC_USE_SELF_ID);
|
||||
parm = RNA_def_pointer(func, "override_set", "OverrideSet", "", "Override set to remove");
|
||||
RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED | PARM_RNAPTR);
|
||||
RNA_def_parameter_clear_flags(parm, PROP_THICK_WRAP, 0);
|
||||
|
||||
rna_def_override_set(brna);
|
||||
}
|
||||
|
||||
void RNA_def_view_layer(BlenderRNA *brna)
|
||||
{
|
||||
FunctionRNA *func;
|
||||
@@ -330,6 +668,12 @@ void RNA_def_view_layer(BlenderRNA *brna)
|
||||
RNA_def_property_ui_text(prop, "Objects", "All the objects in this layer");
|
||||
rna_def_layer_objects(brna, prop);
|
||||
|
||||
prop = RNA_def_property(srna, "override_sets", PROP_COLLECTION, PROP_NONE);
|
||||
RNA_def_property_collection_sdna(prop, NULL, "override_sets", NULL);
|
||||
RNA_def_property_struct_type(prop, "OverrideSet");
|
||||
RNA_def_property_ui_text(prop, "Override Sets", "");
|
||||
rna_def_override_sets(brna, prop);
|
||||
|
||||
/* layer options */
|
||||
prop = RNA_def_property(srna, "use", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "flag", VIEW_LAYER_RENDER);
|
||||
|
@@ -177,6 +177,7 @@ const EnumPropertyItem rna_enum_object_axis_items[] = {
|
||||
#include "DNA_constraint_types.h"
|
||||
#include "DNA_ID.h"
|
||||
#include "DNA_lattice_types.h"
|
||||
#include "DNA_layer_types.h"
|
||||
#include "DNA_node_types.h"
|
||||
|
||||
#include "BKE_armature.h"
|
||||
@@ -1150,8 +1151,13 @@ bool rna_Object_constraints_override_apply(
|
||||
PointerRNA *ptr_dst, PointerRNA *ptr_src, PointerRNA *UNUSED(ptr_storage),
|
||||
PropertyRNA *UNUSED(prop_dst), PropertyRNA *UNUSED(prop_src), PropertyRNA *UNUSED(prop_storage),
|
||||
const int UNUSED(len_dst), const int UNUSED(len_src), const int UNUSED(len_storage),
|
||||
IDOverrideStaticPropertyOperation *opop)
|
||||
IDOverrideStaticPropertyOperation *opop, DynamicOverrideProperty *dyn_prop)
|
||||
{
|
||||
if (dyn_prop != NULL) {
|
||||
printf("%s: unsupported dynamic override...", __func__);
|
||||
return false;
|
||||
}
|
||||
|
||||
BLI_assert(opop->operation == IDOVERRIDESTATIC_OP_INSERT_AFTER &&
|
||||
"Unsupported RNA override operation on constraints collection");
|
||||
|
||||
@@ -1224,8 +1230,13 @@ bool rna_Object_modifiers_override_apply(
|
||||
PointerRNA *ptr_dst, PointerRNA *ptr_src, PointerRNA *UNUSED(ptr_storage),
|
||||
PropertyRNA *UNUSED(prop_dst), PropertyRNA *UNUSED(prop_src), PropertyRNA *UNUSED(prop_storage),
|
||||
const int UNUSED(len_dst), const int UNUSED(len_src), const int UNUSED(len_storage),
|
||||
IDOverrideStaticPropertyOperation *opop)
|
||||
IDOverrideStaticPropertyOperation *opop, DynamicOverrideProperty *dyn_prop)
|
||||
{
|
||||
if (dyn_prop != NULL) {
|
||||
printf("%s: unsupported dynamic override...", __func__);
|
||||
return false;
|
||||
}
|
||||
|
||||
BLI_assert(opop->operation == IDOVERRIDESTATIC_OP_INSERT_AFTER &&
|
||||
"Unsupported RNA override operation on modifiers collection");
|
||||
|
||||
@@ -1852,6 +1863,7 @@ static void rna_def_object_display(BlenderRNA *brna)
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "flag", OB_SHOW_SHADOW);
|
||||
RNA_def_property_boolean_default(prop, true);
|
||||
RNA_def_property_ui_text(prop, "Shadow", "Object cast shadows in the 3d viewport");
|
||||
RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_STATIC);
|
||||
RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, NULL);
|
||||
}
|
||||
|
||||
@@ -2261,11 +2273,13 @@ static void rna_def_object(BlenderRNA *brna)
|
||||
prop = RNA_def_property(srna, "pass_index", PROP_INT, PROP_UNSIGNED);
|
||||
RNA_def_property_int_sdna(prop, NULL, "index");
|
||||
RNA_def_property_ui_text(prop, "Pass Index", "Index number for the \"Object Index\" render pass");
|
||||
RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_STATIC);
|
||||
RNA_def_property_update(prop, NC_OBJECT, "rna_Object_internal_update_draw");
|
||||
|
||||
prop = RNA_def_property(srna, "color", PROP_FLOAT, PROP_COLOR);
|
||||
RNA_def_property_float_sdna(prop, NULL, "col");
|
||||
RNA_def_property_ui_text(prop, "Color", "Object color and alpha, used when faces have the ObColor mode enabled");
|
||||
RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_STATIC);
|
||||
RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, NULL);
|
||||
|
||||
/* physics */
|
||||
|
@@ -99,6 +99,7 @@ const EnumPropertyItem rna_enum_color_sets_items[] = {
|
||||
#include "BKE_armature.h"
|
||||
|
||||
#include "DNA_userdef_types.h"
|
||||
#include "DNA_layer_types.h"
|
||||
|
||||
#include "MEM_guardedalloc.h"
|
||||
|
||||
@@ -573,8 +574,13 @@ bool rna_PoseChannel_constraints_override_apply(
|
||||
PointerRNA *ptr_dst, PointerRNA *ptr_src, PointerRNA *UNUSED(ptr_storage),
|
||||
PropertyRNA *UNUSED(prop_dst), PropertyRNA *UNUSED(prop_src), PropertyRNA *UNUSED(prop_storage),
|
||||
const int UNUSED(len_dst), const int UNUSED(len_src), const int UNUSED(len_storage),
|
||||
IDOverrideStaticPropertyOperation *opop)
|
||||
IDOverrideStaticPropertyOperation *opop, DynamicOverrideProperty *dyn_prop)
|
||||
{
|
||||
if (dyn_prop != NULL) {
|
||||
printf("%s: unsupported dynamic override...", __func__);
|
||||
return false;
|
||||
}
|
||||
|
||||
BLI_assert(opop->operation == IDOVERRIDESTATIC_OP_INSERT_AFTER &&
|
||||
"Unsupported RNA override operation on constraints collection");
|
||||
|
||||
|
@@ -26,6 +26,7 @@
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "DNA_layer_types.h"
|
||||
#include "DNA_ID.h"
|
||||
|
||||
#include "BLI_utildefines.h"
|
||||
@@ -2008,24 +2009,34 @@ bool rna_property_override_apply_default(
|
||||
PointerRNA *ptr_dst, PointerRNA *ptr_src, PointerRNA *ptr_storage,
|
||||
PropertyRNA *prop_dst, PropertyRNA *prop_src, PropertyRNA *prop_storage,
|
||||
const int len_dst, const int len_src, const int len_storage,
|
||||
IDOverrideStaticPropertyOperation *opop)
|
||||
IDOverrideStaticPropertyOperation *opop, DynamicOverrideProperty *dyn_prop)
|
||||
{
|
||||
BLI_assert(opop != NULL || dyn_prop != NULL);
|
||||
BLI_assert(len_dst == len_src && (!ptr_storage || len_dst == len_storage));
|
||||
UNUSED_VARS_NDEBUG(len_src, len_storage);
|
||||
|
||||
const bool is_array = len_dst > 0;
|
||||
const int index = is_array ? opop->subitem_reference_index : 0;
|
||||
const short override_op = opop->operation;
|
||||
const bool is_dynamic_override = (opop == NULL);
|
||||
|
||||
/* Dynamic override does not support sub-item array currently... */
|
||||
const bool is_array = len_dst > 0;
|
||||
const int index = is_array ? (!is_dynamic_override ? opop->subitem_reference_index : -1) : 0;
|
||||
const short override_op = !is_dynamic_override ? opop->operation : dyn_prop->operation;
|
||||
|
||||
const bool do_free_array = !is_dynamic_override && (len_dst > RNA_STACK_ARRAY);
|
||||
switch (RNA_property_type(prop_dst)) {
|
||||
case PROP_BOOLEAN:
|
||||
if (is_array && index == -1) {
|
||||
int array_stack_a[RNA_STACK_ARRAY];
|
||||
int *array_a;
|
||||
|
||||
array_a = (len_dst > RNA_STACK_ARRAY) ? MEM_mallocN(sizeof(*array_a) * len_dst, __func__) : array_stack_a;
|
||||
|
||||
RNA_property_boolean_get_array(ptr_src, prop_src, array_a);
|
||||
if (is_dynamic_override) {
|
||||
array_a = dyn_prop->data.i;
|
||||
}
|
||||
else {
|
||||
array_a = (len_dst > RNA_STACK_ARRAY) ? MEM_mallocN(sizeof(*array_a) * len_dst, __func__) :
|
||||
array_stack_a;
|
||||
RNA_property_boolean_get_array(ptr_src, prop_src, array_a);
|
||||
}
|
||||
|
||||
switch (override_op) {
|
||||
case IDOVERRIDESTATIC_OP_REPLACE:
|
||||
@@ -2036,10 +2047,11 @@ bool rna_property_override_apply_default(
|
||||
return false;
|
||||
}
|
||||
|
||||
if (array_a != array_stack_a) MEM_freeN(array_a);
|
||||
if (do_free_array) MEM_freeN(array_a);
|
||||
}
|
||||
else {
|
||||
const int value = RNA_PROPERTY_GET_SINGLE(boolean, ptr_src, prop_src, index);
|
||||
const int value = !is_dynamic_override ? RNA_PROPERTY_GET_SINGLE(boolean, ptr_src, prop_src, index) :
|
||||
dyn_prop->data.i[index];
|
||||
|
||||
switch (override_op) {
|
||||
case IDOVERRIDESTATIC_OP_REPLACE:
|
||||
@@ -2056,18 +2068,32 @@ bool rna_property_override_apply_default(
|
||||
int array_stack_a[RNA_STACK_ARRAY], array_stack_b[RNA_STACK_ARRAY];
|
||||
int *array_a, *array_b;
|
||||
|
||||
array_a = (len_dst > RNA_STACK_ARRAY) ? MEM_mallocN(sizeof(*array_a) * len_dst, __func__) : array_stack_a;
|
||||
|
||||
switch (override_op) {
|
||||
case IDOVERRIDESTATIC_OP_REPLACE:
|
||||
RNA_property_int_get_array(ptr_src, prop_src, array_a);
|
||||
if (is_dynamic_override) {
|
||||
array_a = dyn_prop->data.i;
|
||||
}
|
||||
else {
|
||||
array_a = (len_dst > RNA_STACK_ARRAY) ? MEM_mallocN(sizeof(*array_a) * len_dst, __func__) :
|
||||
array_stack_a;
|
||||
RNA_property_int_get_array(ptr_src, prop_src, array_a);
|
||||
}
|
||||
RNA_property_int_set_array(ptr_dst, prop_dst, array_a);
|
||||
if (do_free_array) MEM_freeN(array_a);
|
||||
break;
|
||||
case IDOVERRIDESTATIC_OP_ADD:
|
||||
case IDOVERRIDESTATIC_OP_SUBTRACT:
|
||||
array_a = (len_dst > RNA_STACK_ARRAY) ? MEM_mallocN(sizeof(*array_a) * len_dst, __func__) :
|
||||
array_stack_a;
|
||||
RNA_property_int_get_array(ptr_dst, prop_dst, array_a);
|
||||
array_b = (len_dst > RNA_STACK_ARRAY) ? MEM_mallocN(sizeof(*array_b) * len_dst, __func__) : array_stack_b;
|
||||
RNA_property_int_get_array(ptr_storage, prop_storage, array_b);
|
||||
if (is_dynamic_override) {
|
||||
array_b = dyn_prop->data.i;
|
||||
}
|
||||
else {
|
||||
array_b = (len_dst > RNA_STACK_ARRAY) ? MEM_mallocN(sizeof(*array_b) * len_dst, __func__) :
|
||||
array_stack_b;
|
||||
RNA_property_int_get_array(ptr_storage, prop_storage, array_b);
|
||||
}
|
||||
if (override_op == IDOVERRIDESTATIC_OP_ADD) {
|
||||
for (int i = len_dst; i--;) array_a[i] += array_b[i];
|
||||
}
|
||||
@@ -2075,31 +2101,39 @@ bool rna_property_override_apply_default(
|
||||
for (int i = len_dst; i--;) array_a[i] -= array_b[i];
|
||||
}
|
||||
RNA_property_int_set_array(ptr_dst, prop_dst, array_a);
|
||||
if (array_b != array_stack_b) MEM_freeN(array_b);
|
||||
if (do_free_array) MEM_freeN(array_b);
|
||||
if (array_a != array_stack_a) MEM_freeN(array_a);
|
||||
break;
|
||||
default:
|
||||
BLI_assert(0 && "Unsupported RNA override operation on integer");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (array_a != array_stack_a) MEM_freeN(array_a);
|
||||
}
|
||||
else {
|
||||
const int storage_value = ptr_storage ? RNA_PROPERTY_GET_SINGLE(int, ptr_storage, prop_storage, index) : 0;
|
||||
const int storage_value = !is_dynamic_override ?
|
||||
(ptr_storage ? RNA_PROPERTY_GET_SINGLE(int, ptr_storage, prop_storage, index) : 0) :
|
||||
dyn_prop->data.i[index];
|
||||
|
||||
switch (override_op) {
|
||||
case IDOVERRIDESTATIC_OP_REPLACE:
|
||||
RNA_PROPERTY_SET_SINGLE(int, ptr_dst, prop_dst, index,
|
||||
RNA_PROPERTY_GET_SINGLE(int, ptr_src, prop_src, index));
|
||||
{
|
||||
const int value = !is_dynamic_override ? RNA_PROPERTY_GET_SINGLE(int, ptr_src, prop_src, index) :
|
||||
dyn_prop->data.i[index];
|
||||
RNA_PROPERTY_SET_SINGLE(int, ptr_dst, prop_dst, index, value);
|
||||
break;
|
||||
}
|
||||
case IDOVERRIDESTATIC_OP_ADD:
|
||||
RNA_PROPERTY_SET_SINGLE(int, ptr_dst, prop_dst, index,
|
||||
RNA_PROPERTY_GET_SINGLE(int, ptr_dst, prop_dst, index) - storage_value);
|
||||
{
|
||||
const int value = RNA_PROPERTY_GET_SINGLE(int, ptr_dst, prop_dst, index) + storage_value;
|
||||
RNA_PROPERTY_SET_SINGLE(int, ptr_dst, prop_dst, index, value);
|
||||
break;
|
||||
}
|
||||
case IDOVERRIDESTATIC_OP_SUBTRACT:
|
||||
RNA_PROPERTY_SET_SINGLE(int, ptr_dst, prop_dst, index,
|
||||
RNA_PROPERTY_GET_SINGLE(int, ptr_dst, prop_dst, index) - storage_value);
|
||||
{
|
||||
const int value = RNA_PROPERTY_GET_SINGLE(int, ptr_dst, prop_dst, index) - storage_value;
|
||||
RNA_PROPERTY_SET_SINGLE(int, ptr_dst, prop_dst, index, value);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
BLI_assert(0 && "Unsupported RNA override operation on integer");
|
||||
return false;
|
||||
@@ -2111,19 +2145,33 @@ bool rna_property_override_apply_default(
|
||||
float array_stack_a[RNA_STACK_ARRAY], array_stack_b[RNA_STACK_ARRAY];
|
||||
float *array_a, *array_b;
|
||||
|
||||
array_a = (len_dst > RNA_STACK_ARRAY) ? MEM_mallocN(sizeof(*array_a) * len_dst, __func__) : array_stack_a;
|
||||
|
||||
switch (override_op) {
|
||||
case IDOVERRIDESTATIC_OP_REPLACE:
|
||||
RNA_property_float_get_array(ptr_src, prop_src, array_a);
|
||||
if (is_dynamic_override) {
|
||||
array_a = dyn_prop->data.f;
|
||||
}
|
||||
else {
|
||||
array_a = (len_dst > RNA_STACK_ARRAY) ? MEM_mallocN(sizeof(*array_a) * len_dst, __func__) :
|
||||
array_stack_a;
|
||||
RNA_property_float_get_array(ptr_src, prop_src, array_a);
|
||||
}
|
||||
RNA_property_float_set_array(ptr_dst, prop_dst, array_a);
|
||||
if (do_free_array) MEM_freeN(array_a);
|
||||
break;
|
||||
case IDOVERRIDESTATIC_OP_ADD:
|
||||
case IDOVERRIDESTATIC_OP_SUBTRACT:
|
||||
case IDOVERRIDESTATIC_OP_MULTIPLY:
|
||||
array_a = (len_dst > RNA_STACK_ARRAY) ? MEM_mallocN(sizeof(*array_a) * len_dst, __func__) :
|
||||
array_stack_a;
|
||||
RNA_property_float_get_array(ptr_dst, prop_dst, array_a);
|
||||
array_b = (len_dst > RNA_STACK_ARRAY) ? MEM_mallocN(sizeof(*array_b) * len_dst, __func__) : array_stack_b;
|
||||
RNA_property_float_get_array(ptr_storage, prop_storage, array_b);
|
||||
if (is_dynamic_override) {
|
||||
array_b = dyn_prop->data.f;
|
||||
}
|
||||
else {
|
||||
array_b = (len_dst > RNA_STACK_ARRAY) ? MEM_mallocN(sizeof(*array_b) * len_dst, __func__) :
|
||||
array_stack_b;
|
||||
RNA_property_float_get_array(ptr_storage, prop_storage, array_b);
|
||||
}
|
||||
if (override_op == IDOVERRIDESTATIC_OP_ADD) {
|
||||
for (int i = len_dst; i--;) array_a[i] += array_b[i];
|
||||
}
|
||||
@@ -2134,35 +2182,45 @@ bool rna_property_override_apply_default(
|
||||
for (int i = len_dst; i--;) array_a[i] *= array_b[i];
|
||||
}
|
||||
RNA_property_float_set_array(ptr_dst, prop_dst, array_a);
|
||||
if (array_b != array_stack_b) MEM_freeN(array_b);
|
||||
if (do_free_array) MEM_freeN(array_b);
|
||||
if (array_a != array_stack_a) MEM_freeN(array_a);
|
||||
break;
|
||||
default:
|
||||
BLI_assert(0 && "Unsupported RNA override operation on float");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (array_a != array_stack_a) MEM_freeN(array_a);
|
||||
}
|
||||
else {
|
||||
const float storage_value = ptr_storage ? RNA_PROPERTY_GET_SINGLE(float, ptr_storage, prop_storage, index) : 0.0f;
|
||||
const float storage_value = !is_dynamic_override ?
|
||||
(ptr_storage ? RNA_PROPERTY_GET_SINGLE(float, ptr_storage, prop_storage, index) : 0.0f) :
|
||||
dyn_prop->data.f[index];
|
||||
|
||||
switch (override_op) {
|
||||
case IDOVERRIDESTATIC_OP_REPLACE:
|
||||
RNA_PROPERTY_SET_SINGLE(float, ptr_dst, prop_dst, index,
|
||||
RNA_PROPERTY_GET_SINGLE(float, ptr_src, prop_src, index));
|
||||
{
|
||||
const float value = opop != NULL ? RNA_PROPERTY_GET_SINGLE(float, ptr_src, prop_src, index) :
|
||||
dyn_prop->data.f[index];
|
||||
RNA_PROPERTY_SET_SINGLE(float, ptr_dst, prop_dst, index, value);
|
||||
break;
|
||||
}
|
||||
case IDOVERRIDESTATIC_OP_ADD:
|
||||
RNA_PROPERTY_SET_SINGLE(float, ptr_dst, prop_dst, index,
|
||||
RNA_PROPERTY_GET_SINGLE(float, ptr_dst, prop_dst, index) + storage_value);
|
||||
{
|
||||
const float value = RNA_PROPERTY_GET_SINGLE(float, ptr_dst, prop_dst, index) + storage_value;
|
||||
RNA_PROPERTY_SET_SINGLE(float, ptr_dst, prop_dst, index, value);
|
||||
break;
|
||||
}
|
||||
case IDOVERRIDESTATIC_OP_SUBTRACT:
|
||||
RNA_PROPERTY_SET_SINGLE(float, ptr_dst, prop_dst, index,
|
||||
RNA_PROPERTY_GET_SINGLE(float, ptr_dst, prop_dst, index) - storage_value);
|
||||
{
|
||||
const float value = RNA_PROPERTY_GET_SINGLE(float, ptr_dst, prop_dst, index) - storage_value;
|
||||
RNA_PROPERTY_SET_SINGLE(float, ptr_dst, prop_dst, index, value);
|
||||
break;
|
||||
}
|
||||
case IDOVERRIDESTATIC_OP_MULTIPLY:
|
||||
RNA_PROPERTY_SET_SINGLE(float, ptr_dst, prop_dst, index,
|
||||
RNA_PROPERTY_GET_SINGLE(float, ptr_dst, prop_dst, index) * storage_value);
|
||||
{
|
||||
const float value = RNA_PROPERTY_GET_SINGLE(float, ptr_dst, prop_dst, index) * storage_value;
|
||||
RNA_PROPERTY_SET_SINGLE(float, ptr_dst, prop_dst, index, value);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
BLI_assert(0 && "Unsupported RNA override operation on float");
|
||||
return false;
|
||||
@@ -2171,7 +2229,7 @@ bool rna_property_override_apply_default(
|
||||
return true;
|
||||
case PROP_ENUM:
|
||||
{
|
||||
const int value = RNA_property_enum_get(ptr_src, prop_src);
|
||||
const int value = !is_dynamic_override ? RNA_property_enum_get(ptr_src, prop_src) : dyn_prop->data.i[0];
|
||||
|
||||
switch (override_op) {
|
||||
case IDOVERRIDESTATIC_OP_REPLACE:
|
||||
@@ -2186,7 +2244,13 @@ bool rna_property_override_apply_default(
|
||||
}
|
||||
case PROP_POINTER:
|
||||
{
|
||||
PointerRNA value = RNA_property_pointer_get(ptr_src, prop_src);
|
||||
PointerRNA value;
|
||||
if (is_dynamic_override) {
|
||||
RNA_id_pointer_create(dyn_prop->data.id, &value);
|
||||
}
|
||||
else {
|
||||
value = RNA_property_pointer_get(ptr_src, prop_src);
|
||||
}
|
||||
|
||||
switch (override_op) {
|
||||
case IDOVERRIDESTATIC_OP_REPLACE:
|
||||
@@ -2201,7 +2265,15 @@ bool rna_property_override_apply_default(
|
||||
case PROP_STRING:
|
||||
{
|
||||
char buff[256];
|
||||
char *value = RNA_property_string_get_alloc(ptr_src, prop_src, buff, sizeof(buff), NULL);
|
||||
char *value;
|
||||
bool do_free_value = false;
|
||||
if (is_dynamic_override) {
|
||||
value = dyn_prop->data.str;
|
||||
}
|
||||
else {
|
||||
value = RNA_property_string_get_alloc(ptr_src, prop_src, buff, sizeof(buff), NULL);
|
||||
do_free_value = value != buff;
|
||||
}
|
||||
|
||||
switch (override_op) {
|
||||
case IDOVERRIDESTATIC_OP_REPLACE:
|
||||
@@ -2212,7 +2284,7 @@ bool rna_property_override_apply_default(
|
||||
return false;
|
||||
}
|
||||
|
||||
if (value != buff) MEM_freeN(value);
|
||||
if (do_free_value) MEM_freeN(value);
|
||||
return true;
|
||||
}
|
||||
case PROP_COLLECTION:
|
||||
@@ -2226,6 +2298,9 @@ bool rna_property_override_apply_default(
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
#undef RNA_PROPERTY_GET_SINGLE
|
||||
#undef RNA_PROPERTY_SET_SINGLE
|
||||
}
|
||||
|
||||
#undef RNA_PROPERTY_GET_SINGLE
|
||||
|
@@ -302,6 +302,7 @@ typedef struct wmNotifier {
|
||||
#define ND_TRANSFORM_DONE (18<<16)
|
||||
#define ND_WORLD (92<<16)
|
||||
#define ND_LAYER_CONTENT (101<<16)
|
||||
#define ND_DYN_OVERRIDES (102<<16)
|
||||
|
||||
/* NC_OBJECT Object */
|
||||
#define ND_TRANSFORM (18<<16)
|
||||
|
Reference in New Issue
Block a user