diff options
-rw-r--r-- | intern/cycles/blender/CMakeLists.txt | 1 | ||||
-rw-r--r-- | intern/cycles/blender/object.cpp | 73 | ||||
-rw-r--r-- | source/blender/blenkernel/BKE_duplilist.h | 8 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/object_dupli.cc | 120 | ||||
-rw-r--r-- | source/blender/draw/intern/draw_instance_data.c | 75 | ||||
-rw-r--r-- | source/blender/draw/intern/draw_resource.cc | 77 | ||||
-rw-r--r-- | source/blender/draw/intern/draw_shader_shared.h | 1 | ||||
-rw-r--r-- | source/blender/gpu/GPU_material.h | 2 | ||||
-rw-r--r-- | source/blender/gpu/intern/gpu_node_graph.c | 5 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_depsgraph.c | 8 |
10 files changed, 155 insertions, 215 deletions
diff --git a/intern/cycles/blender/CMakeLists.txt b/intern/cycles/blender/CMakeLists.txt index 666b0077a72..ceb024ba5e7 100644 --- a/intern/cycles/blender/CMakeLists.txt +++ b/intern/cycles/blender/CMakeLists.txt @@ -7,6 +7,7 @@ set(INC ../../mikktspace ../../../source/blender/makesdna ../../../source/blender/makesrna + ../../../source/blender/blenkernel ../../../source/blender/blenlib ../../../source/blender/gpu ../../../source/blender/render diff --git a/intern/cycles/blender/object.cpp b/intern/cycles/blender/object.cpp index 109408c354d..8a3c1136104 100644 --- a/intern/cycles/blender/object.cpp +++ b/intern/cycles/blender/object.cpp @@ -23,6 +23,8 @@ #include "util/log.h" #include "util/task.h" +#include "BKE_duplilist.h" + CCL_NAMESPACE_BEGIN /* Utilities */ @@ -353,79 +355,26 @@ Object *BlenderSync::sync_object(BL::Depsgraph &b_depsgraph, return object; } -/* This function mirrors drw_uniform_property_lookup in draw_instance_data.cpp */ -static bool lookup_property(BL::ID b_id, const string &name, float4 *r_value) -{ - PointerRNA ptr; - PropertyRNA *prop; - - if (!RNA_path_resolve(&b_id.ptr, name.c_str(), &ptr, &prop)) { - return false; - } - - if (prop == NULL) { - return false; - } +extern "C" DupliObject *rna_hack_DepsgraphObjectInstance_dupli_object_get(PointerRNA *ptr); - PropertyType type = RNA_property_type(prop); - int arraylen = RNA_property_array_length(&ptr, prop); - - if (arraylen == 0) { - float value; - - if (type == PROP_FLOAT) - value = RNA_property_float_get(&ptr, prop); - else if (type == PROP_INT) - value = static_cast<float>(RNA_property_int_get(&ptr, prop)); - else - return false; - - *r_value = make_float4(value, value, value, 1.0f); - return true; - } - else if (type == PROP_FLOAT && arraylen <= 4) { - *r_value = make_float4(0.0f, 0.0f, 0.0f, 1.0f); - RNA_property_float_get_array(&ptr, prop, &r_value->x); - return true; - } - - return false; -} - -/* This function mirrors drw_uniform_attribute_lookup in draw_instance_data.cpp */ static float4 lookup_instance_property(BL::DepsgraphObjectInstance &b_instance, const string &name, bool use_instancer) { - string idprop_name = string_printf("[\"%s\"]", name.c_str()); - float4 value; + ::Object *ob = (::Object *)b_instance.object().ptr.data; + ::DupliObject *dupli = nullptr; + ::Object *dupli_parent = nullptr; /* If requesting instance data, check the parent particle system and object. */ if (use_instancer && b_instance.is_instance()) { - BL::ParticleSystem b_psys = b_instance.particle_system(); - - if (b_psys) { - if (lookup_property(b_psys.settings(), idprop_name, &value) || - lookup_property(b_psys.settings(), name, &value)) { - return value; - } - } - if (lookup_property(b_instance.parent(), idprop_name, &value) || - lookup_property(b_instance.parent(), name, &value)) { - return value; - } + dupli = rna_hack_DepsgraphObjectInstance_dupli_object_get(&b_instance.ptr); + dupli_parent = (::Object *)b_instance.parent().ptr.data; } - /* Check the object and mesh. */ - BL::Object b_ob = b_instance.object(); - BL::ID b_data = b_ob.data(); - - if (lookup_property(b_ob, idprop_name, &value) || lookup_property(b_ob, name, &value) || - lookup_property(b_data, idprop_name, &value) || lookup_property(b_data, name, &value)) { - return value; - } + float4 value; + BKE_object_dupli_find_rgba_attribute(ob, dupli, dupli_parent, name.c_str(), &value.x); - return zero_float4(); + return value; } bool BlenderSync::sync_object_attributes(BL::DepsgraphObjectInstance &b_instance, Object *object) diff --git a/source/blender/blenkernel/BKE_duplilist.h b/source/blender/blenkernel/BKE_duplilist.h index cc362495a24..79f37d2edde 100644 --- a/source/blender/blenkernel/BKE_duplilist.h +++ b/source/blender/blenkernel/BKE_duplilist.h @@ -64,6 +64,14 @@ typedef struct DupliObject { unsigned int random_id; } DupliObject; +/** Look up the RGBA value of a uniform shader attribute. + * \return true if the attribute was found; if not, r_value is also set to zero. */ +bool BKE_object_dupli_find_rgba_attribute(struct Object *ob, + struct DupliObject *dupli, + struct Object *dupli_parent, + const char *name, + float r_value[4]); + #ifdef __cplusplus } #endif diff --git a/source/blender/blenkernel/intern/object_dupli.cc b/source/blender/blenkernel/intern/object_dupli.cc index 15a4a0bbb32..b4ccef56ee3 100644 --- a/source/blender/blenkernel/intern/object_dupli.cc +++ b/source/blender/blenkernel/intern/object_dupli.cc @@ -58,6 +58,9 @@ #include "BLI_hash.h" #include "NOD_geometry_nodes_log.hh" +#include "RNA_access.h" +#include "RNA_path.h" +#include "RNA_types.h" using blender::Array; using blender::float3; @@ -1711,3 +1714,120 @@ void free_object_duplilist(ListBase *lb) } /** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Uniform attribute lookup + * \{ */ + +/** Lookup an arbitrary RNA property and convert it to RGBA if possible. */ +static bool find_rna_property_rgba(PointerRNA *id_ptr, const char *name, float r_data[4]) +{ + if (id_ptr->data == nullptr) { + return false; + } + + /* First, check custom properties. */ + IDProperty *group = RNA_struct_idprops(id_ptr, false); + PropertyRNA *prop = nullptr; + + if (group && group->type == IDP_GROUP) { + prop = (PropertyRNA *)IDP_GetPropertyFromGroup(group, name); + } + + /* If not found, do full path lookup. */ + PointerRNA ptr; + + if (prop != nullptr) { + ptr = *id_ptr; + } + else if (!RNA_path_resolve(id_ptr, name, &ptr, &prop)) { + return false; + } + + if (prop == nullptr) { + return false; + } + + /* Convert the value to RGBA if possible. */ + PropertyType type = RNA_property_type(prop); + int array_len = RNA_property_array_length(&ptr, prop); + + if (array_len == 0) { + float value; + + if (type == PROP_FLOAT) { + value = RNA_property_float_get(&ptr, prop); + } + else if (type == PROP_INT) { + value = static_cast<float>(RNA_property_int_get(&ptr, prop)); + } + else if (type == PROP_BOOLEAN) { + value = RNA_property_boolean_get(&ptr, prop) ? 1.0f : 0.0f; + } + else { + return false; + } + + copy_v4_fl4(r_data, value, value, value, 1); + return true; + } + + if (type == PROP_FLOAT && array_len <= 4) { + copy_v4_fl4(r_data, 0, 0, 0, 1); + RNA_property_float_get_array(&ptr, prop, r_data); + return true; + } + + if (type == PROP_INT && array_len <= 4) { + int tmp[4] = {0, 0, 0, 1}; + RNA_property_int_get_array(&ptr, prop, tmp); + for (int i = 0; i < 4; i++) { + r_data[i] = static_cast<float>(tmp[i]); + } + return true; + } + + return false; +} + +static bool find_rna_property_rgba(ID *id, const char *name, float r_data[4]) +{ + PointerRNA ptr; + RNA_id_pointer_create(id, &ptr); + return find_rna_property_rgba(&ptr, name, r_data); +} + +bool BKE_object_dupli_find_rgba_attribute( + Object *ob, DupliObject *dupli, Object *dupli_parent, const char *name, float r_value[4]) +{ + /* Check the dupli particle system. */ + if (dupli && dupli->particle_system) { + ParticleSettings *settings = dupli->particle_system->part; + + if (find_rna_property_rgba(&settings->id, name, r_value)) { + return true; + } + } + + /* Check the dupli parent object. */ + if (dupli_parent && find_rna_property_rgba(&dupli_parent->id, name, r_value)) { + return true; + } + + /* Check the main object. */ + if (ob) { + if (find_rna_property_rgba(&ob->id, name, r_value)) { + return true; + } + + /* Check the main object data (e.g. mesh). */ + if (ob->data && find_rna_property_rgba((ID *)ob->data, name, r_value)) { + return true; + } + } + + copy_v4_fl(r_value, 0.0f); + return false; +} + +/** \} */ diff --git a/source/blender/draw/intern/draw_instance_data.c b/source/blender/draw/intern/draw_instance_data.c index 7ed5ca7c983..a56883ce304 100644 --- a/source/blender/draw/intern/draw_instance_data.c +++ b/source/blender/draw/intern/draw_instance_data.c @@ -585,87 +585,18 @@ static DRWUniformAttrBuf *drw_uniform_attrs_pool_ensure(GHash *table, return (DRWUniformAttrBuf *)*pval; } -/* This function mirrors lookup_property in cycles/blender/blender_object.cpp */ -static bool drw_uniform_property_lookup(ID *id, const char *name, float r_data[4]) -{ - PointerRNA ptr, id_ptr; - PropertyRNA *prop; - - if (!id) { - return false; - } - - RNA_id_pointer_create(id, &id_ptr); - - if (!RNA_path_resolve(&id_ptr, name, &ptr, &prop)) { - return false; - } - - if (prop == NULL) { - return false; - } - - PropertyType type = RNA_property_type(prop); - int arraylen = RNA_property_array_length(&ptr, prop); - - if (arraylen == 0) { - float value; - - if (type == PROP_FLOAT) { - value = RNA_property_float_get(&ptr, prop); - } - else if (type == PROP_INT) { - value = RNA_property_int_get(&ptr, prop); - } - else { - return false; - } - - copy_v4_fl4(r_data, value, value, value, 1); - return true; - } - - if (type == PROP_FLOAT && arraylen <= 4) { - copy_v4_fl4(r_data, 0, 0, 0, 1); - RNA_property_float_get_array(&ptr, prop, r_data); - return true; - } - - return false; -} - -/* This function mirrors lookup_instance_property in cycles/blender/blender_object.cpp */ static void drw_uniform_attribute_lookup(GPUUniformAttr *attr, Object *ob, Object *dupli_parent, DupliObject *dupli_source, float r_data[4]) { - copy_v4_fl(r_data, 0); - /* If requesting instance data, check the parent particle system and object. */ if (attr->use_dupli) { - if (dupli_source && dupli_source->particle_system) { - ParticleSettings *settings = dupli_source->particle_system->part; - if (drw_uniform_property_lookup((ID *)settings, attr->name_id_prop, r_data) || - drw_uniform_property_lookup((ID *)settings, attr->name, r_data)) { - return; - } - } - if (drw_uniform_property_lookup((ID *)dupli_parent, attr->name_id_prop, r_data) || - drw_uniform_property_lookup((ID *)dupli_parent, attr->name, r_data)) { - return; - } + BKE_object_dupli_find_rgba_attribute(ob, dupli_source, dupli_parent, attr->name, r_data); } - - /* Check the object and mesh. */ - if (ob) { - if (drw_uniform_property_lookup((ID *)ob, attr->name_id_prop, r_data) || - drw_uniform_property_lookup((ID *)ob, attr->name, r_data) || - drw_uniform_property_lookup((ID *)ob->data, attr->name_id_prop, r_data) || - drw_uniform_property_lookup((ID *)ob->data, attr->name, r_data)) { - return; - } + else { + BKE_object_dupli_find_rgba_attribute(ob, NULL, NULL, attr->name, r_data); } } diff --git a/source/blender/draw/intern/draw_resource.cc b/source/blender/draw/intern/draw_resource.cc index 689df4edb31..f57058190fb 100644 --- a/source/blender/draw/intern/draw_resource.cc +++ b/source/blender/draw/intern/draw_resource.cc @@ -19,58 +19,6 @@ * \{ */ /** - * Extract object attribute from RNA property. - * Returns true if the attribute was correctly extracted. - * This function mirrors lookup_property in cycles/blender/blender_object.cpp - */ -bool ObjectAttribute::id_property_lookup(ID *id, const char *name) -{ - PointerRNA ptr, id_ptr; - PropertyRNA *prop; - - if (id == nullptr) { - return false; - } - - RNA_id_pointer_create(id, &id_ptr); - - if (!RNA_path_resolve(&id_ptr, name, &ptr, &prop)) { - return false; - } - - if (prop == nullptr) { - return false; - } - - PropertyType type = RNA_property_type(prop); - int array_len = RNA_property_array_length(&ptr, prop); - - if (array_len == 0) { - float value; - - if (type == PROP_FLOAT) { - value = RNA_property_float_get(&ptr, prop); - } - else if (type == PROP_INT) { - value = RNA_property_int_get(&ptr, prop); - } - else { - return false; - } - - *reinterpret_cast<float4 *>(&data_x) = float4(value, value, value, 1.0f); - return true; - } - - if (type == PROP_FLOAT && array_len <= 4) { - *reinterpret_cast<float4 *>(&data_x) = float4(0.0f, 0.0f, 0.0f, 1.0f); - RNA_property_float_get_array(&ptr, prop, &data_x); - return true; - } - return false; -} - -/** * Go through all possible source of the given object uniform attribute. * Returns true if the attribute was correctly filled. * This function mirrors lookup_instance_property in cycles/blender/blender_object.cpp @@ -81,29 +29,12 @@ bool ObjectAttribute::sync(const blender::draw::ObjectRef &ref, const GPUUniform /* If requesting instance data, check the parent particle system and object. */ if (attr.use_dupli) { - if ((ref.dupli_object != nullptr) && (ref.dupli_object->particle_system != nullptr)) { - ParticleSettings *settings = ref.dupli_object->particle_system->part; - if (this->id_property_lookup((ID *)settings, attr.name_id_prop) || - this->id_property_lookup((ID *)settings, attr.name)) { - return true; - } - } - if (this->id_property_lookup((ID *)ref.dupli_parent, attr.name_id_prop) || - this->id_property_lookup((ID *)ref.dupli_parent, attr.name)) { - return true; - } + return BKE_object_dupli_find_rgba_attribute( + ref.object, ref.dupli_object, ref.dupli_parent, attr.name, &data_x); } - - /* Check the object and mesh. */ - if (ref.object != nullptr) { - if (this->id_property_lookup((ID *)ref.object, attr.name_id_prop) || - this->id_property_lookup((ID *)ref.object, attr.name) || - this->id_property_lookup((ID *)ref.object->data, attr.name_id_prop) || - this->id_property_lookup((ID *)ref.object->data, attr.name)) { - return true; - } + else { + return BKE_object_dupli_find_rgba_attribute(ref.object, nullptr, nullptr, attr.name, &data_x); } - return false; } /** \} */ diff --git a/source/blender/draw/intern/draw_shader_shared.h b/source/blender/draw/intern/draw_shader_shared.h index bedbedcf438..a572b9ee865 100644 --- a/source/blender/draw/intern/draw_shader_shared.h +++ b/source/blender/draw/intern/draw_shader_shared.h @@ -205,7 +205,6 @@ struct ObjectAttribute { #if !defined(GPU_SHADER) && defined(__cplusplus) bool sync(const blender::draw::ObjectRef &ref, const GPUUniformAttr &attr); - bool id_property_lookup(ID *id, const char *name); #endif }; #pragma pack(pop) diff --git a/source/blender/gpu/GPU_material.h b/source/blender/gpu/GPU_material.h index 1c9bdc77bac..31354585308 100644 --- a/source/blender/gpu/GPU_material.h +++ b/source/blender/gpu/GPU_material.h @@ -335,8 +335,6 @@ typedef struct GPUUniformAttr { /* Meaningful part of the attribute set key. */ char name[64]; /* MAX_CUSTOMDATA_LAYER_NAME */ - /** Escaped name with [""]. */ - char name_id_prop[64 * 2 + 4]; /** Hash of name[64] + use_dupli. */ uint32_t hash_code; bool use_dupli; diff --git a/source/blender/gpu/intern/gpu_node_graph.c b/source/blender/gpu/intern/gpu_node_graph.c index 510c16dfb02..e1ae731d49c 100644 --- a/source/blender/gpu/intern/gpu_node_graph.c +++ b/source/blender/gpu/intern/gpu_node_graph.c @@ -416,11 +416,6 @@ static GPUUniformAttr *gpu_node_graph_add_uniform_attribute(GPUNodeGraph *graph, if (attr == NULL && attrs->count < GPU_MAX_UNIFORM_ATTR) { attr = MEM_callocN(sizeof(*attr), __func__); STRNCPY(attr->name, name); - { - char attr_name_esc[sizeof(attr->name) * 2]; - BLI_str_escape(attr_name_esc, attr->name, sizeof(attr_name_esc)); - SNPRINTF(attr->name_id_prop, "[\"%s\"]", attr_name_esc); - } attr->use_dupli = use_dupli; attr->hash_code = BLI_ghashutil_strhash_p(attr->name) << 1 | (attr->use_dupli ? 0 : 1); attr->id = -1; diff --git a/source/blender/makesrna/intern/rna_depsgraph.c b/source/blender/makesrna/intern/rna_depsgraph.c index eb39492c7dc..db5b3c33c59 100644 --- a/source/blender/makesrna/intern/rna_depsgraph.c +++ b/source/blender/makesrna/intern/rna_depsgraph.c @@ -61,6 +61,14 @@ void **rna_DepsgraphIterator_instance(PointerRNA *ptr) } # endif +/* Temporary hack for Cycles until it is changed to work with the C API directly. */ +DupliObject *rna_hack_DepsgraphObjectInstance_dupli_object_get(PointerRNA *ptr) +{ + RNA_DepsgraphIterator *di = ptr->data; + DEGObjectIterData *deg_iter = (DEGObjectIterData *)di->iter.data; + return deg_iter->dupli_object_current; +} + static PointerRNA rna_DepsgraphObjectInstance_object_get(PointerRNA *ptr) { RNA_DepsgraphIterator *di = ptr->data; |