[Bf-blender-cvs] [60b3fc82399] functions: better handling of attribute name collisions
Jacques Lucke
noreply at git.blender.org
Tue Dec 10 23:21:01 CET 2019
Commit: 60b3fc823998cf16387ebb4e730bea3ce239d710
Author: Jacques Lucke
Date: Tue Dec 10 22:53:32 2019 +0100
Branches: functions
https://developer.blender.org/rB60b3fc823998cf16387ebb4e730bea3ce239d710
better handling of attribute name collisions
===================================================================
M source/blender/functions/FN_attributes_ref.h
M source/blender/simulations/bparticles/emitters.cpp
M source/blender/simulations/bparticles/node_frontend.cpp
===================================================================
diff --git a/source/blender/functions/FN_attributes_ref.h b/source/blender/functions/FN_attributes_ref.h
index 89042f9bca5..9f7e5ccd785 100644
--- a/source/blender/functions/FN_attributes_ref.h
+++ b/source/blender/functions/FN_attributes_ref.h
@@ -59,6 +59,21 @@ class AttributesInfoBuilder : BLI::NonCopyable, BLI::NonMovable {
}
}
+ bool name_and_type_collide_with_existing(StringRef name, const CPPType &type) const
+ {
+ int index = m_names.index_try(name);
+ if (index == -1) {
+ return false;
+ }
+
+ const CPPType *existing_type = m_types[index];
+ if (*existing_type == type) {
+ return false;
+ }
+
+ return true;
+ }
+
uint size() const
{
return m_names.size();
@@ -121,6 +136,11 @@ class AttributesInfo : BLI::NonCopyable, BLI::NonMovable {
return this->default_of(this->index_of(name));
}
+ bool has_attribute(StringRef name, const CPPType &type) const
+ {
+ return this->try_index_of(name, type) >= 0;
+ }
+
int try_index_of(StringRef name, const CPPType &type) const
{
int index = this->try_index_of(name);
diff --git a/source/blender/simulations/bparticles/emitters.cpp b/source/blender/simulations/bparticles/emitters.cpp
index 8b906b31fe8..b076e02d9c8 100644
--- a/source/blender/simulations/bparticles/emitters.cpp
+++ b/source/blender/simulations/bparticles/emitters.cpp
@@ -409,6 +409,7 @@ void CustomEmitter::emit(EmitterInterface &interface)
for (StringRef system_name : m_systems_to_emit) {
auto new_particles = interface.particle_allocator().request(system_name, particle_count);
new_particles.fill<float>("Birth Time", interface.time_span().end());
+ const AttributesInfo &info = new_particles.info();
for (uint param_index : m_emitter_function.param_indices()) {
MFParamType param_type = m_emitter_function.param_type(param_index);
@@ -417,19 +418,23 @@ void CustomEmitter::emit(EmitterInterface &interface)
FN::GenericVectorArray &vector_array = params_builder.computed_vector_array(param_index);
FN::GenericArrayRef array = vector_array[0];
const FN::CPPType &base_type = array.type();
- if (array.size() == 0) {
- void *default_buffer = alloca(base_type.size());
- base_type.construct_default(default_buffer);
- new_particles.fill(attribute_name, base_type, default_buffer);
- }
- else {
- new_particles.set_repeated(attribute_name, array);
+ if (info.has_attribute(attribute_name, base_type)) {
+ if (array.size() == 0) {
+ void *default_buffer = alloca(base_type.size());
+ base_type.construct_default(default_buffer);
+ new_particles.fill(attribute_name, base_type, default_buffer);
+ }
+ else {
+ new_particles.set_repeated(attribute_name, array);
+ }
}
}
else if (param_type.is_single_output()) {
FN::GenericMutableArrayRef array = params_builder.computed_array(param_index);
const FN::CPPType &type = array.type();
- new_particles.fill(attribute_name, type, array[0]);
+ if (info.has_attribute(attribute_name, type)) {
+ new_particles.fill(attribute_name, type, array[0]);
+ }
}
else {
BLI_assert(false);
diff --git a/source/blender/simulations/bparticles/node_frontend.cpp b/source/blender/simulations/bparticles/node_frontend.cpp
index 8830e2847e1..0782c95b40e 100644
--- a/source/blender/simulations/bparticles/node_frontend.cpp
+++ b/source/blender/simulations/bparticles/node_frontend.cpp
@@ -230,6 +230,30 @@ class InlinedTreeData {
return fn_ptr;
}
+ bool try_add_attribute(InfluencesCollector &collector,
+ ArrayRef<std::string> system_names,
+ StringRef name,
+ const CPPType &type,
+ const void *default_value)
+ {
+ bool collides_with_existing = false;
+ for (StringRef system_name : system_names) {
+ AttributesInfoBuilder *attributes = collector.m_attributes.lookup(system_name);
+ collides_with_existing = collides_with_existing ||
+ attributes->name_and_type_collide_with_existing(name, type);
+ }
+
+ if (collides_with_existing) {
+ return false;
+ }
+
+ for (StringRef system_name : system_names) {
+ collector.m_attributes.lookup(system_name)->add(name, type, default_value);
+ }
+
+ return true;
+ }
+
private:
Vector<const XNode *> find_target_system_nodes(const XOutputSocket &xsocket)
{
@@ -348,19 +372,24 @@ class XSocketActionBuilder {
return m_inlined_tree_data.compute_all_data_inputs(m_execute_xsocket.node());
}
- template<typename T> void add_attribute_to_affected_particles(StringRef name, T default_value)
+ template<typename T>
+ bool try_add_attribute_to_affected_particles(StringRef name, T default_value)
{
- this->add_attribute_to_affected_particles(
+ return this->try_add_attribute_to_affected_particles(
name, FN::CPP_TYPE<T>(), (const void *)&default_value);
}
- void add_attribute_to_affected_particles(StringRef name,
- const CPPType &type,
- const void *default_value = nullptr)
+ bool try_add_attribute_to_affected_particles(StringRef name,
+ const CPPType &type,
+ const void *default_value = nullptr)
{
/* Add attribute to all particle systems for now. */
- m_influences_collector.m_attributes.foreach_value(
- [&](AttributesInfoBuilder *builder) { builder->add(name, type, default_value); });
+ Vector<std::string> system_names;
+ m_influences_collector.m_attributes.foreach_key(
+ [&](StringRef name) { system_names.append(name); });
+
+ return m_inlined_tree_data.try_add_attribute(
+ m_influences_collector, system_names, name, type, default_value);
}
};
@@ -471,8 +500,12 @@ static void ACTION_add_to_group(XSocketActionBuilder &builder)
return;
}
- std::string group_name = inputs->relocate_out<std::string>(0, "Group");
- builder.add_attribute_to_affected_particles<bool>(group_name, false);
+ std::string group_name = "private/group/" + inputs->relocate_out<std::string>(0, "Group");
+ bool attribute_added = builder.try_add_attribute_to_affected_particles<bool>(group_name, false);
+ if (!attribute_added) {
+ return;
+ }
+
builder.set_constructed<AddToGroupAction>(group_name);
}
@@ -506,7 +539,11 @@ static void ACTION_set_attribute(XSocketActionBuilder &builder)
std::string attribute_name = RNA_get_string_std(builder.node_rna(), "attribute_name");
const CPPType &type = builder.base_type_of(builder.xsocket().node().input(0));
- builder.add_attribute_to_affected_particles(attribute_name, type);
+ bool attribute_added = builder.try_add_attribute_to_affected_particles(attribute_name, type);
+ if (!attribute_added) {
+ return;
+ }
+
builder.set_constructed<SetAttributeAction>(attribute_name, type, *inputs_fn);
}
@@ -615,6 +652,7 @@ class XNodeInfluencesBuilder {
std::string node_identifier()
{
std::stringstream ss;
+ ss << "private/node";
for (const BKE::XParentNode *parent = m_xnode.parent(); parent; parent = parent->parent()) {
ss << "/" << parent->vnode().name();
}
@@ -645,19 +683,18 @@ class XNodeInfluencesBuilder {
}
template<typename T>
- void add_attribute(ArrayRef<std::string> system_names, StringRef name, T default_value)
+ bool try_add_attribute(ArrayRef<std::string> system_names, StringRef name, T default_value)
{
- this->add_attribute(system_names, name, (const void *)&default_value);
+ return this->try_add_attribute(system_names, name, (const void *)&default_value);
}
- void add_attribute(ArrayRef<std::string> system_names,
- StringRef name,
- const CPPType &type,
- const void *default_value = nullptr)
+ bool try_add_attribute(ArrayRef<std::string> system_names,
+ StringRef name,
+ const CPPType &type,
+ const void *default_value = nullptr)
{
- for (StringRef system_name : system_names) {
- m_influences_collector.m_attributes.lookup(system_name)->add(name, type, default_value);
- }
+ return m_inlined_tree_data.try_add_attribute(
+ m_influences_collector, system_names, name, type, default_value);
}
};
@@ -719,7 +756,7 @@ static void PARSE_custom_emitter(XNodeInfluencesBuilder &builder)
BLI_assert(false);
}
- builder.add_attribute(system_names, attribute_name, *attribute_type);
+ builder.try_add_attribute(system_names, attribute_name, *attribute_type);
}
Action &action = builder.build_action_list("Execute on Birth");
@@ -811,11 +848,15 @@ static void PARSE_age_reached_event(XNodeInfluencesBuilder &builder)
}
ArrayRef<std::string> system_names = builder.find_target_system_names(0, "Event");
- Action &action = builder.build_action_list("Execute on Event");
-
std::string is_triggered_attribute = builder.node_identifier();
- builder.add_attribute<bool>(system_names, is_triggered_attribute, false);
+ bool attribute_added = builder.try_add_attribute<bool>(
+ system_names, is_triggered_attribute, false);
+ if (!attribute_added) {
+ return;
+ }
+
+ Action &action = builder.build_action_list("Execute on Event");
Event &event = builder.construct<AgeReachedEvent>(is_triggered_attribute, inputs_fn, action);
builder.add_event(system_names, event);
}
@@ -883,10 +924,14 @@ static void PARSE_mesh_collision(XNodeInfluencesBuilder &builder)
builder.world_transition().update_float4x4(object->id.name, "obmat", object->obmat).start;
std::string last_collision_attribute = builder.node_identifier();
+ bool attribute_added = builder.try_add_attribute<int32_t>(
+ system_names, last_collision_attribute, -1);
+ if (!attribute_added) {
+ return;
+ }
Event &event = builder.construct<MeshCollisionEvent>(
last_collis
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list