1
1

Compare commits

...

82 Commits

Author SHA1 Message Date
Dalai Felinto
fbaf6e6fb3 Merge remote-tracking branch 'origin/blender2.8' into temp-dynamic-overrides 2018-06-26 16:07:39 +02:00
bba0ad903c Cleanup: De-duplicate overrides properties apply loop 2018-06-20 10:50:18 +02:00
2acf4ace51 Cleanup: Create ID property only once
Avoids refining ID pointer for every property which is being applied.
2018-06-20 10:29:49 +02:00
d8f5a68f63 Merge branch 'blender2.8' into temp-dynamic-overrides 2018-06-20 10:18:19 +02:00
088691254e Merge branch 'blender2.8' into temp-dynamic-overrides 2018-06-18 12:37:50 +02:00
6ee25c9d55 Fix broken multi-threaded concurrent access to same data.
Note that later we do can cache the non-data version of this path (i.e.
list of propnames), this will still save us the full RNA path parsing.

But the data side of path resolution has to be fully local, no way to
cache that since a same override can be applied to several objects!
2018-06-15 14:44:48 +02:00
Dalai Felinto
a54079eecd Update DNA comment 2018-06-15 14:11:45 +02:00
Dalai Felinto
20d5fd36a1 Depsgraph: Link scene cow with object cow
For dynamic override we need to be sure the object cow is not updated before
the scene cow.

In fact we need this to any datablock that is potentially dynamic overridable.

That said this patch makes the relationship (fix the arrows) yet it doesn't
fix the underlying problem.
2018-06-15 12:58:47 +02:00
Dalai Felinto
344c2d4674 Merge remote-tracking branch 'origin/blender2.8' into temp-dynamic-overrides 2018-06-15 12:18:36 +02:00
Dalai Felinto
c303f2a19b Use proper UI name 2018-06-12 14:26:43 +02:00
Dalai Felinto
b173b96c09 Merge remote-tracking branch 'origin/blender2.8' into temp-dynamic-overrides 2018-06-12 14:17:35 +02:00
Dalai Felinto
f30056d512 Update the UI to use bl_parent_id
Also remove the DNA/RNA settings that were added for that.
2018-06-12 11:11:13 +02:00
b06deeca25 Merge branch 'blender2.8' into temp-dynamic-overrides
Conflicts:
	source/blender/makesrna/intern/rna_access.c
2018-06-12 11:00:50 +02:00
Dalai Felinto
07bf151062 Merge remote-tracking branch 'origin/blender2.8' into temp-dynamic-overrides 2018-05-31 21:44:21 +02:00
Dalai Felinto
d341b62351 Merge remote-tracking branch 'origin/blender2.8' into temp-dynamic-overrides 2018-05-31 00:01:48 +02:00
Dalai Felinto
55d611ad5e Merge remote-tracking branch 'origin/blender2.8' into temp-dynamic-overrides 2018-05-28 21:57:02 +02:00
Dalai Felinto
dd5f69e251 Fix readfile for affected collections 2018-05-28 21:56:32 +02:00
Dalai Felinto
e20ec83765 Fixup for LinkData > AffectedCollection 2018-05-28 01:58:27 +02:00
Dalai Felinto
3e946a6f13 Tag COW when link/unlinking collections
In theory we can tag only the objects that are in the corresponding colletction
and its children.
2018-05-28 01:48:14 +02:00
Dalai Felinto
fc4c3fc35c Use affected collections to determine objects to override
Note: It is done now as a cache system, although right now
this runs for all the objects.

But the logic should be decoupable once we integrate this with
the depsgraph properly.

Note: I seem to be getting a crash on saving/writing because
AffectedCollection->collection is NULL sometimes.
2018-05-28 01:37:53 +02:00
Dalai Felinto
83e068f5df New Affected Collection struct
No point in using anonymous LinkData structs.
2018-05-28 00:42:17 +02:00
Dalai Felinto
f319e0081b Cleanup 2018-05-27 21:39:40 +02:00
Dalai Felinto
8655ed28fe Update the viewport when changing dynamic override properties 2018-05-27 19:23:46 +02:00
Dalai Felinto
c9172b65db Util function to find view layer by dynamic property 2018-05-27 19:23:20 +02:00
Dalai Felinto
dcb18ab6c9 Extra make sure view3d updates for dynamic override
Without this we do not get updates when deleting/adding override
sets and affected collections.

We should probably replace this by manually publishin RNA updates though.
2018-05-27 19:22:27 +02:00
Dalai Felinto
f7301293b9 Make sure viewport updates on dynamic override and override set changes 2018-05-27 19:21:18 +02:00
Dalai Felinto
7265f6c25c Depsgraph: Tag depsgraph id based on id type 2018-05-27 19:20:32 +02:00
Dalai Felinto
8fb93aebe7 BKE_idtype_to_main_data
Function to map ID_Type to bmain-> listbases.
2018-05-27 18:33:08 +02:00
bab887fbfe Fix 'broken' Multiply operation for Dynamic Overrides.
No reason to store operands of Multiply op in a separate property! Let's
keep things simple ;)
2018-05-27 18:23:14 +02:00
e7e792f0f4 Fix broken RNA override apply in Dynamic case.
Was accessing some pointers it should not access in Dynamic case.
Typical stupid mistakes that happen when you code without being able to
test your changes... ;)

Also made code a bit clear by using a global bool is_dynamic_override,
instead of using crappy NULL-pointer check.
2018-05-27 16:34:14 +02:00
Dalai Felinto
a5ca6d752e Hacky code just to try RNA_struct_dynamic_override_apply
It is crashing now, I tried either adding a scene setting (EEVEE AO), or
object settings (ob.color).

This also shows a few problems:
* We can't simply tag Scene to update when changing an override set, we need
  the tagging to flush down to the scene objects.

* For scene settings we may want to do at this moment in COW evaluation, however
  for objects the implementation is a bit more tricky. Because we need to change
  the data owned by the object as well. For example, the material.

* In this case it is almost as if we want a cow-cow ID (the OVERRIDEN id should be
  shared by all the objects that are being overridden.

* Also the affected collections thing is to be handled somehow.
2018-05-25 20:59:04 +02:00
Dalai Felinto
e6128bd177 Tag depsgraph COW for update when changing dynamic overrides 2018-05-25 20:40:09 +02:00
Dalai Felinto
f837bd1f76 Merge remote-tracking branch 'origin/blender2.8' into temp-dynamic-overrides 2018-05-25 19:52:10 +02:00
Dalai Felinto
7bd6590594 Merge remote-tracking branch 'origin/blender2.8' into temp-dynamic-overrides
Big merge, this addresses all the conflicts due to the Group > Collection change.
2018-05-25 18:03:45 +02:00
5165ab5877 Dynamic override: add RNA callback to apply an override.
Theoritical code for now, since we still miss the depsgraph part to hook
it up to actual evaluation.
2018-05-17 18:11:52 +02:00
35716a8f46 Merge branch 'blender2.8' into temp-dynamic-overrides
Conflicts:
	source/blender/makesrna/intern/rna_rna.c
2018-05-17 17:14:48 +02:00
f1b10fa29d Initial step to support dynoverride eval in RNA code.
Using as much as possible static override code. Againm ideally we'll
merge back both into a fully single system after everything is working.

Also found a way to reduce a bit verbosity of code here...
2018-05-17 16:43:26 +02:00
f5cada3f7d Dynamic Override: Add support for arrays of bools and ints, check array size! 2018-05-17 14:16:47 +02:00
e3d6d9d3ac Dynamic Override: Share a tiny bit more code betzeen dynamic and static overrides.
Renamed dynamic's override_mode to 'operation' (same as with static) and
made it use same enum values.

Note that ultimately/ideally both would only use one data structure,
this should be manageable and will simplify RNA apply code (which is to
be shared by both), but that kind of cleanup/refactor we can do once we
have a working system, just before merging into blender2.8.
2018-05-17 12:56:32 +02:00
c69ed97473 Merge branch 'blender2.8' into temp-dynamic-overrides 2018-05-17 11:38:08 +02:00
Dalai Felinto
68e861059f Merge remote-tracking branch 'origin/blender2.8' into temp-dynamic-overrides 2018-05-16 23:21:45 +02:00
Dalai Felinto
50771589a7 Fix building
It was broken since rB666a3b6161af, shame on me.
2018-05-16 23:20:40 +02:00
Dalai Felinto
814fc6aafc Merge remote-tracking branch 'origin/blender2.8' into temp-dynamic-overrides 2018-05-16 15:26:27 +02:00
Dalai Felinto
666a3b6161 Fix warning + cleanup 2018-05-16 15:26:21 +02:00
Dalai Felinto
a278a97232 Dynamic length for color arrays 2018-05-16 00:43:24 +02:00
Dalai Felinto
0441110c86 Split dynamic override into its own rna file 2018-05-16 00:29:06 +02:00
Dalai Felinto
612d78712c Merge remote-tracking branch 'origin/blender2.8' into temp-dynamic-overrides 2018-05-15 23:50:02 +02:00
Dalai Felinto
ba1d1a6923 Hard-coded support for arrays, color works 2018-05-14 22:21:34 +02:00
Dalai Felinto
2b92e40e03 UI: Show override mode only for compatible properties 2018-05-14 11:59:40 +02:00
42f6406d4f Dynamic overrides: Add support to retrieve type of property from rna path.
Also added proper value accessor for booleans, so now
Object.display.show_shadows shall work nicely.
2018-05-13 19:14:05 +02:00
17a209ea02 Fix 'add new dynamic override' func, could store NULL rna path string.
Do not generate the dynamic override data in case a valid RNA path
cannot be built.
2018-05-13 19:14:05 +02:00
ddbfe00827 New no-data RNA path sover: add another helper func.
That one is more helpful, allows to directly build the runtime list of
RNA items.
2018-05-13 19:14:05 +02:00
35bdc45bbd Fix missing path callback for new Object.display struct. 2018-05-13 19:14:05 +02:00
70673c6a6b Fix issue w/ recent tool name use
Use the context space type, not the workspace.
Broke setting tools for the first time.
2018-05-13 19:14:05 +02:00
c046771ecb Icons: updated transform icons 2018-05-13 19:14:05 +02:00
1ec126887e UI: fix popovers not properly working with scroll arrows for long menus. 2018-05-13 19:14:05 +02:00
05f8453496 Build deps: avoid ffmpeg external crystalhd library dependency. 2018-05-13 19:14:05 +02:00
df32088b95 Fix typo in previous commit. 2018-05-13 19:14:05 +02:00
5d6950a49a Icons: fix z-sorting
Was depth sorting per mesh.
2018-05-13 19:14:05 +02:00
Julian Eisel
bba8f86558 Fix/workaround crash when appending workspace in edit mode
Linking/appending in edit mode currently isn't supported. For workspaces it
should probably be, but we can look into supporting this later.

For now gray out buttons in "Add Workspace" menu while in edit mode.
2018-05-13 19:14:05 +02:00
Julian Eisel
2d82574494 Fix invisible scroll-bars after file read
Own mistake from 51efeb6834.
2018-05-13 19:14:05 +02:00
2e802e56c5 Icons: optionally use material color
The RGB node is used if it exists,
this is multiplied by the vertex color.
2018-05-13 19:14:05 +02:00
Nick Milios
0b3200cb43 Fix build error with Visual Studio / Windows.
Differential Revision: https://developer.blender.org/D3363
2018-05-13 19:14:05 +02:00
ffee223857 Attempt to make limited resolution of RNA paths possible without any data.
Note that while code is essentially the same with or without a valid
PointerRNA, 'public' API is clearly separated. Existing code should
hence exhibit no change in behaviour.

Also, no-data case is essentially not tested yet.
2018-05-13 17:06:13 +02:00
61dc857877 Merge branch 'blender2.8' into temp-dynamic-overrides 2018-05-13 15:45:01 +02:00
Dalai Felinto
c532c4fc25 Expose root ID* to rna
Note: We should only store root when relevante (e.g., modifiers).
And remove this dyn property when root is deleted in these cases.
2018-05-11 16:07:21 +02:00
Dalai Felinto
7e9d2fd984 ID Type needs to be stored 2018-05-11 16:06:40 +02:00
Dalai Felinto
543bed5b85 Merge remote-tracking branch 'origin/blender2.8' into temp-dynamic-overrides 2018-05-11 10:32:00 +02:00
Dalai Felinto
4b40ed48c2 Implement copy_data for dynamic properties 2018-05-11 10:25:28 +02:00
Dalai Felinto
107a457891 Add multiplication factor
Also tagged a few TODOs in the UI.
2018-05-10 14:00:56 +02:00
Dalai Felinto
8a27c1c8a6 Merge remote-tracking branch 'origin/blender2.8' into temp-dynamic-overrides 2018-05-10 13:34:34 +02:00
Dalai Felinto
b0332b8490 Finish the operator to add overrides
You now can create a new override set, or pick an existent one.
2018-05-10 13:07:28 +02:00
Dalai Felinto
cd52967d1c Set new override set as the active one 2018-05-10 11:44:30 +02:00
Dalai Felinto
1dd9396ced Handle library query for dynamic overrides 2018-05-10 10:45:14 +02:00
Dalai Felinto
e2346f7378 Dynamic Override Property: Mode
ID props won't have these options showing in the UI, but there is no need
to have them stored in the DNA since we need to know the prop type to know
which rna prop to show in the UI.

Also more UI changes.
2018-05-10 00:56:40 +02:00
Dalai Felinto
76c9d4db2e Dynamic Override Property: Remove Operator 2018-05-10 00:20:46 +02:00
Dalai Felinto
a4a5f4b1e5 Merge remote-tracking branch 'origin/blender2.8' into temp-dynamic-overrides 2018-05-09 18:55:38 +02:00
Dalai Felinto
33c3e293be Dynamic Override Properties
TODO:
 * Final UI
 * Operator to delete them.
 * Depsgraph.
 * Copy properties (copy data).
 * Handle arrays (e.g., ob.color).
 * Data path.
 * Create default override set or let user pick existent one.
 * Get name from data path (rna).
 * Get icon.
 * Set different override_modes based on property type.

Done together with Bastien Montagne.
2018-05-09 18:55:03 +02:00
Dalai Felinto
5978102ec5 Merge remote-tracking branch 'origin/blender2.8' into temp-dynamic-overrides 2018-05-09 16:18:24 +02:00
Dalai Felinto
fc54b5034a Merge remote-tracking branch 'origin/blender2.8' into temp-dynamic-overrides 2018-05-09 15:58:38 +02:00
Dalai Felinto
7f808eb601 No need to store the name of the Dynamic Properties 2018-05-09 09:51:47 +02:00
Dalai Felinto
189b31c937 View Layer overrides
TODO:
* Properties (all)

Notes:
* UI settings, stored per scene so it does not change based on view layer
* Link collection menu can leak memory (like Move to Collection).

The design for this task is: T54792
2018-05-08 20:10:21 +02:00
32 changed files with 2495 additions and 104 deletions

View File

@@ -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.

View File

@@ -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);

View File

@@ -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(

View File

@@ -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.
*

View File

@@ -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
* \{ */

View File

@@ -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) {

View File

@@ -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);

View File

@@ -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)

View File

@@ -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)

View File

@@ -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 ------------------------------- */

View File

@@ -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;

View File

@@ -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) {

View File

@@ -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;
}

View File

@@ -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 */

View File

@@ -27,6 +27,7 @@ set(INC
../../makesdna
../../makesrna
../../windowmanager
../../../../intern/guardedalloc
)
set(INC_SYS

View File

@@ -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);
}

View File

@@ -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,
};

View File

@@ -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

View File

@@ -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);

View File

@@ -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[];

View File

@@ -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

View File

@@ -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},

View File

@@ -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,

View File

@@ -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);

View 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

View File

@@ -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 */

View File

@@ -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 {

View File

@@ -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);

View File

@@ -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 */

View File

@@ -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");

View File

@@ -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

View File

@@ -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)