[Bf-blender-cvs] [a7b3047cefc] master: Datablock ID Properties
Alexander Romanov
noreply at git.blender.org
Thu Apr 13 11:36:03 CEST 2017
Commit: a7b3047cefcbfae4d8b13e15026497fd5ae92730
Author: Alexander Romanov
Date: Thu Apr 13 12:30:03 2017 +0300
Branches: master
https://developer.blender.org/rBa7b3047cefcbfae4d8b13e15026497fd5ae92730
Datablock ID Properties
The absence of datablock properties "will certainly be resolved soon as the need for them is becoming obvious" said the [[http://wiki.blender.org/index.php/Dev:Ref/Release_Notes/2.67/Python_Nodes|Python Nodes release notes]]. So this patch allows Python scripts to create ID Properties which reference datablocks.
This functionality is implemented for `PointerProperty` and now such properties can be created with Python.
In addition to the standard update callback, `PointerProperty` can have a `poll` callback (standard RNA) which is useful for search menus. For details see the test included in this patch.
Original author: @artfunkel
Alexander (Blend4Web Team)
Reviewers: brecht, artfunkel, mont29, campbellbarton
Reviewed By: mont29, campbellbarton
Subscribers: jta, sergey, campbellbarton, wisaac, poseidon4o, mont29, homyachetser, Evgeny_Rodygin, AlexKowel, yurikovelenov, fjuhec, sharlybg, cardboard, duarteframos, blueprintrandom, a.romanov, BYOB, disnel, aditiapratama, bliblubli, dfelinto, lukastoenne
Maniphest Tasks: T37754
Differential Revision: https://developer.blender.org/D113
===================================================================
M source/blender/blenkernel/BKE_idprop.h
M source/blender/blenkernel/BKE_library.h
M source/blender/blenkernel/BKE_library_query.h
M source/blender/blenkernel/intern/idprop.c
M source/blender/blenkernel/intern/library_query.c
M source/blender/blenkernel/intern/library_remap.c
M source/blender/blenkernel/intern/node.c
M source/blender/blenloader/intern/readfile.c
M source/blender/editors/object/object_relations.c
M source/blender/makesdna/DNA_ID.h
M source/blender/makesrna/RNA_access.h
M source/blender/makesrna/RNA_define.h
M source/blender/makesrna/RNA_types.h
M source/blender/makesrna/intern/rna_ID.c
M source/blender/makesrna/intern/rna_access.c
M source/blender/makesrna/intern/rna_define.c
M source/blender/makesrna/intern/rna_internal.h
M source/blender/makesrna/intern/rna_internal_types.h
M source/blender/makesrna/intern/rna_ui.c
M source/blender/makesrna/intern/rna_userdef.c
M source/blender/makesrna/intern/rna_wm.c
M source/blender/python/generic/idprop_py_api.c
M source/blender/python/intern/bpy_props.c
M source/blender/python/intern/bpy_props.h
M source/blender/python/intern/bpy_rna.c
M source/blender/python/intern/bpy_rna.h
M source/blender/windowmanager/intern/wm.c
M tests/python/CMakeLists.txt
A tests/python/bl_pyapi_idprop_datablock.py
===================================================================
diff --git a/source/blender/blenkernel/BKE_idprop.h b/source/blender/blenkernel/BKE_idprop.h
index 5b10d7ebc06..ab8728faedb 100644
--- a/source/blender/blenkernel/BKE_idprop.h
+++ b/source/blender/blenkernel/BKE_idprop.h
@@ -60,8 +60,6 @@ typedef union IDPropertyTemplate {
IDProperty *IDP_NewIDPArray(const char *name) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
IDProperty *IDP_CopyIDPArray(const IDProperty *array) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
-void IDP_FreeIDPArray(IDProperty *prop);
-
/* shallow copies item */
void IDP_SetIndexArray(struct IDProperty *prop, int index, struct IDProperty *item) ATTR_NONNULL();
struct IDProperty *IDP_GetIndexArray(struct IDProperty *prop, int index) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
@@ -81,8 +79,8 @@ void IDP_ConcatString(struct IDProperty *str1, struct IDProperty *append) ATTR_N
void IDP_FreeString(struct IDProperty *prop) ATTR_NONNULL();
/*-------- ID Type -------*/
-void IDP_LinkID(struct IDProperty *prop, ID *id);
-void IDP_UnlinkID(struct IDProperty *prop);
+
+typedef void(*IDPWalkFunc)(void *userData, IDProperty *idp);
/*-------- Group Functions -------*/
@@ -112,11 +110,12 @@ bool IDP_EqualsProperties(struct IDProperty *prop1, struct IDProperty *prop2) AT
struct IDProperty *IDP_New(const char type, const IDPropertyTemplate *val, const char *name) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
+void IDP_FreeProperty_ex(struct IDProperty *prop, const bool do_id_user);
void IDP_FreeProperty(struct IDProperty *prop);
void IDP_ClearProperty(IDProperty *prop);
-void IDP_UnlinkProperty(struct IDProperty *prop);
+void IDP_RelinkProperty(struct IDProperty *prop);
#define IDP_Int(prop) ((prop)->data.val)
#define IDP_Array(prop) ((prop)->data.pointer)
@@ -134,11 +133,15 @@ void IDP_UnlinkProperty(struct IDProperty *prop);
# define IDP_IDPArray(prop) _Generic((prop), \
IDProperty *: ((IDProperty *) (prop)->data.pointer), \
const IDProperty *: ((const IDProperty *) (prop)->data.pointer))
+# define IDP_Id(prop) _Generic((prop), \
+ IDProperty *: ((ID *) (prop)->data.pointer), \
+ const IDProperty *: ((const ID *) (prop)->data.pointer))
#else
# define IDP_Float(prop) (*(float *)&(prop)->data.val)
# define IDP_Double(prop) (*(double *)&(prop)->data.val)
# define IDP_String(prop) ((char *) (prop)->data.pointer)
# define IDP_IDPArray(prop) ((IDProperty *) (prop)->data.pointer)
+# define IDP_Id(prop) ((ID *) (prop)->data.pointer)
#endif
#ifndef NDEBUG
diff --git a/source/blender/blenkernel/BKE_library.h b/source/blender/blenkernel/BKE_library.h
index 72ae2cf4efa..6649cfbb585 100644
--- a/source/blender/blenkernel/BKE_library.h
+++ b/source/blender/blenkernel/BKE_library.h
@@ -66,7 +66,7 @@ struct ID *BKE_libblock_find_name(const short type, const char *name) ATTR_WARN_
void BKE_libblock_free(struct Main *bmain, void *idv) ATTR_NONNULL();
void BKE_libblock_free_ex(struct Main *bmain, void *idv, const bool do_id_user, const bool do_ui_user) ATTR_NONNULL();
void BKE_libblock_free_us(struct Main *bmain, void *idv) ATTR_NONNULL();
-void BKE_libblock_free_data(struct Main *bmain, struct ID *id) ATTR_NONNULL();
+void BKE_libblock_free_data(struct Main *bmain, struct ID *id, const bool do_id_user) ATTR_NONNULL();
void BKE_libblock_delete(struct Main *bmain, void *idv) ATTR_NONNULL();
void BKE_id_lib_local_paths(struct Main *bmain, struct Library *lib, struct ID *id);
diff --git a/source/blender/blenkernel/BKE_library_query.h b/source/blender/blenkernel/BKE_library_query.h
index 1258e2fa72e..68bf9f43fe1 100644
--- a/source/blender/blenkernel/BKE_library_query.h
+++ b/source/blender/blenkernel/BKE_library_query.h
@@ -87,7 +87,7 @@ void BKE_library_update_ID_link_user(struct ID *id_dst, struct ID *id_src, const
int BKE_library_ID_use_ID(struct ID *id_user, struct ID *id_used);
-bool BKE_library_idtype_can_use_idtype(const short id_type_owner, const short id_type_used);
+bool BKE_library_id_can_use_idtype(struct ID *id_owner, const short id_type_used);
bool BKE_library_ID_is_locally_used(struct Main *bmain, void *idv);
bool BKE_library_ID_is_indirectly_used(struct Main *bmain, void *idv);
diff --git a/source/blender/blenkernel/intern/idprop.c b/source/blender/blenkernel/intern/idprop.c
index 5e4e8eb34ad..074a9a12fe0 100644
--- a/source/blender/blenkernel/intern/idprop.c
+++ b/source/blender/blenkernel/intern/idprop.c
@@ -117,14 +117,14 @@ IDProperty *IDP_CopyIDPArray(const IDProperty *array)
return narray;
}
-void IDP_FreeIDPArray(IDProperty *prop)
+static void IDP_FreeIDPArray(IDProperty *prop, const bool do_id_user)
{
int i;
BLI_assert(prop->type == IDP_IDPARRAY);
for (i = 0; i < prop->len; i++)
- IDP_FreeProperty(GETPROP(prop, i));
+ IDP_FreeProperty_ex(GETPROP(prop, i), do_id_user);
if (prop->data.pointer)
MEM_freeN(prop->data.pointer);
@@ -437,22 +437,24 @@ void IDP_FreeString(IDProperty *prop)
/* -------------------------------------------------------------------- */
-/* ID Type (not in use yet) */
+/* ID Type */
-/** \name IDProperty ID API (unused)
+/** \name IDProperty ID API
* \{ */
-void IDP_LinkID(IDProperty *prop, ID *id)
-{
- if (prop->data.pointer)
- id_us_min(((ID *)prop->data.pointer));
- prop->data.pointer = id;
- id_us_plus(id);
-}
-void IDP_UnlinkID(IDProperty *prop)
+static IDProperty *IDP_CopyID(const IDProperty *prop)
{
- id_us_min(((ID *)prop->data.pointer));
+ IDProperty *newp;
+
+ BLI_assert(prop->type == IDP_ID);
+ newp = idp_generic_copy(prop);
+
+ newp->data.pointer = prop->data.pointer;
+ id_us_plus(IDP_Id(newp));
+
+ return newp;
}
+
/** \} */
@@ -710,13 +712,13 @@ IDProperty *IDP_GetPropertyTypeFromGroup(IDProperty *prop, const char *name, con
* This is because all ID Property freeing functions free only direct data (not the ID Property
* struct itself), but for Groups the child properties *are* considered
* direct data. */
-static void IDP_FreeGroup(IDProperty *prop)
+static void IDP_FreeGroup(IDProperty *prop, const bool do_id_user)
{
IDProperty *loop;
BLI_assert(prop->type == IDP_GROUP);
for (loop = prop->data.group.first; loop; loop = loop->next) {
- IDP_FreeProperty(loop);
+ IDP_FreeProperty_ex(loop, do_id_user);
}
BLI_freelistN(&prop->data.group);
}
@@ -733,12 +735,51 @@ IDProperty *IDP_CopyProperty(const IDProperty *prop)
switch (prop->type) {
case IDP_GROUP: return IDP_CopyGroup(prop);
case IDP_STRING: return IDP_CopyString(prop);
+ case IDP_ID: return IDP_CopyID(prop);
case IDP_ARRAY: return IDP_CopyArray(prop);
case IDP_IDPARRAY: return IDP_CopyIDPArray(prop);
default: return idp_generic_copy(prop);
}
}
+/* Updates ID pointers after an object has been copied */
+/* TODO Nuke this once its only user has been correctly converted to use generic ID management from BKE_library! */
+void IDP_RelinkProperty(struct IDProperty *prop)
+{
+ if (!prop)
+ return;
+
+ switch (prop->type) {
+ case IDP_GROUP:
+ {
+ for (IDProperty *loop = prop->data.group.first; loop; loop = loop->next) {
+ IDP_RelinkProperty(loop);
+ }
+ break;
+ }
+ case IDP_IDPARRAY:
+ {
+ IDProperty *idp_array = IDP_Array(prop);
+ for (int i = 0; i < prop->len; i++) {
+ IDP_RelinkProperty(&idp_array[i]);
+ }
+ break;
+ }
+ case IDP_ID:
+ {
+ ID *id = IDP_Id(prop);
+ if (id && id->newid) {
+ id_us_min(IDP_Id(prop));
+ prop->data.pointer = id->newid;
+ id_us_plus(IDP_Id(prop));
+ }
+ break;
+ }
+ default:
+ break; /* Nothing to do for other IDProp types. */
+ }
+}
+
/**
* Get the Group property that contains the id properties for ID id. Set create_if_needed
* to create the Group property and attach it to id if it doesn't exist; otherwise
@@ -835,6 +876,8 @@ bool IDP_EqualsProperties_ex(IDProperty *prop1, IDProperty *prop2, const bool is
return false;
return true;
}
+ case IDP_ID:
+ return (IDP_Id(prop1) == IDP_Id(prop2));
default:
/* should never get here */
BLI_assert(0);
@@ -910,6 +953,7 @@ IDProperty *IDP_New(const char type, const IDPropertyTemplate *val, const char *
prop->len = prop->totallen = val->array.len;
break;
}
+ printf("%s: bad array type.\n",__func__);
return NULL;
}
case IDP_STRING:
@@ -956,6 +1000,14 @@ IDProperty *IDP_New(const char type, const IDPropertyTemplate *val, const char *
/* heh I think all needed values are set properly by calloc anyway :) */
break;
}
+ case IDP_ID:
+ {
+ prop = MEM_callocN(sizeof(IDProperty), "IDProperty datablock");
+ prop->data.pointer = (void *)val->id;
+ prop->type = IDP_ID;
+ id_us_plus(IDP_Id(prop));
+ break;
+ }
default:
{
prop = MEM_callocN(sizeof(IDProperty), "IDProperty array");
@@ -970,11 +1022,10 @@ IDProperty *IDP_New(const char type, const IDPropertyTemplate *val, const char *
}
/**
- * \note this will free all child properties of list arrays and groups!
- * Also, note that this does NOT unlink anything! Plus it doesn't free
- * the actual struct IDProperty struct either.
+ * \note This will free allocated data, all child properties of arrays and groups, and unlink IDs!
+ * But it does not free the actual IDProperty struct itself.
*/
-void IDP_FreeProperty(IDProperty *prop)
+void IDP_FreeProperty_ex(IDProperty *prop, const bool do_id_user)
{
switch (prop->type) {
case IDP_ARRAY:
@@ -984,14 +1035,24 @@ void IDP_FreeProperty(IDProperty *prop)
IDP_FreeString(prop);
break;
case IDP_GROUP:
- IDP_FreeGroup(prop);
+ IDP_FreeGroup(prop, do_id_user);
break;
case IDP_IDPARRAY:
- IDP_FreeIDPArray(prop);
+ IDP_FreeIDPArray(prop, do_id_user);
+ break;
+ case IDP_ID:
+ if (do_id_user) {
+ id_us_min(IDP_Id(prop));
+ }
break;
}
}
+void IDP_FreeProperty(IDProperty *prop)
+{
+ IDP_FreeProperty_ex(prop, true);
+}
+
void IDP_ClearProperty(IDProperty *prop)
{
IDP_FreeProperty(prop);
@@ -999,18 +1060,4 @@ void IDP_ClearProperty(IDProperty *prop)
prop->len = prop->totallen = 0;
}
-/**
- * Unlinks any struct IDProperty<->ID linkage that might be going on.
- *
- * \note currently unused
- */
-void IDP_UnlinkProperty(IDProperty *prop)
-{
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list