[Bf-blender-cvs] [b245562d0ec] functions: better error handling when expected action context is not given

Jacques Lucke noreply at git.blender.org
Tue Sep 3 16:23:09 CEST 2019


Commit: b245562d0ec32f41f7c4fb1fb5252bdae93daf52
Author: Jacques Lucke
Date:   Tue Sep 3 12:34:45 2019 +0200
Branches: functions
https://developer.blender.org/rBb245562d0ec32f41f7c4fb1fb5252bdae93daf52

better error handling when expected action context is not given

===================================================================

M	source/blender/simulations/bparticles/particle_function.cpp
M	source/blender/simulations/bparticles/particle_function.hpp
M	source/blender/simulations/bparticles/particle_function_builder.cpp
M	source/blender/simulations/bparticles/particle_function_input_providers.cpp
M	source/blender/simulations/bparticles/particle_function_input_providers.hpp

===================================================================

diff --git a/source/blender/simulations/bparticles/particle_function.cpp b/source/blender/simulations/bparticles/particle_function.cpp
index 7ff4148b74c..89d059c8049 100644
--- a/source/blender/simulations/bparticles/particle_function.cpp
+++ b/source/blender/simulations/bparticles/particle_function.cpp
@@ -153,13 +153,26 @@ void ParticleFunction::init_with_deps(ParticleFunctionResult *result,
   for (uint i = 0; i < m_fn_with_deps->input_amount(); i++) {
     auto *provider = m_input_providers[i];
     InputProviderInterface interface(pindices, attributes, particle_times, action_context);
-    auto array = provider->get(interface);
-    BLI_assert(array.buffer != nullptr);
-    BLI_assert(array.stride > 0);
-
-    input_buffers.append(array.buffer);
-    input_sizes.append(array.stride);
-    if (array.is_newly_allocated) {
+    auto optional_array = provider->get(interface);
+    if (optional_array.has_value()) {
+      ParticleFunctionInputArray array = optional_array.extract();
+      BLI_assert(array.buffer != nullptr);
+      BLI_assert(array.stride > 0);
+
+      input_buffers.append(array.buffer);
+      input_sizes.append(array.stride);
+      if (array.is_newly_allocated) {
+        inputs_to_free.append(i);
+      }
+    }
+    else {
+      uint element_size = m_fn_with_deps->input_type(i)->extension<CPPTypeInfo>().size();
+      void *default_buffer = BLI_temporary_allocate(element_size * attributes.size());
+      for (uint pindex : pindices) {
+        memset(POINTER_OFFSET(default_buffer, pindex * element_size), 0, element_size);
+      }
+      input_buffers.append(default_buffer);
+      input_sizes.append(element_size);
       inputs_to_free.append(i);
     }
   }
diff --git a/source/blender/simulations/bparticles/particle_function.hpp b/source/blender/simulations/bparticles/particle_function.hpp
index fa51f6d1cc3..ab03b425e4f 100644
--- a/source/blender/simulations/bparticles/particle_function.hpp
+++ b/source/blender/simulations/bparticles/particle_function.hpp
@@ -192,7 +192,7 @@ class ParticleFunctionInputProvider {
  public:
   virtual ~ParticleFunctionInputProvider();
 
-  virtual ParticleFunctionInputArray get(InputProviderInterface &interface) = 0;
+  virtual Optional<ParticleFunctionInputArray> get(InputProviderInterface &interface) = 0;
 };
 
 class ParticleFunction {
diff --git a/source/blender/simulations/bparticles/particle_function_builder.cpp b/source/blender/simulations/bparticles/particle_function_builder.cpp
index 75930efaaf2..b35c943332e 100644
--- a/source/blender/simulations/bparticles/particle_function_builder.cpp
+++ b/source/blender/simulations/bparticles/particle_function_builder.cpp
@@ -49,7 +49,25 @@ static SetVector<VirtualSocket *> find_particle_dependencies(
   return combined_dependencies;
 }
 
-static ParticleFunctionInputProvider *create_input_provider(VirtualSocket *vsocket)
+static AttributeType attribute_type_from_socket_type(FN::Type *type)
+{
+  if (type == FN::Types::TYPE_float3) {
+    return AttributeType::Float3;
+  }
+  else if (type == FN::Types::TYPE_float) {
+    return AttributeType::Float;
+  }
+  else if (type == FN::Types::TYPE_int32) {
+    return AttributeType::Integer;
+  }
+  else {
+    BLI_assert(false);
+  }
+}
+
+static ParticleFunctionInputProvider *create_input_provider(VirtualSocket *vsocket,
+                                                            SharedDataGraph &data_graph,
+                                                            DataSocket socket)
 {
   VirtualNode *vnode = vsocket->vnode();
   if (STREQ(vnode->idname(), "bp_ParticleInfoNode")) {
@@ -57,7 +75,8 @@ static ParticleFunctionInputProvider *create_input_provider(VirtualSocket *vsock
       return new AgeInputProvider();
     }
     else {
-      return new AttributeInputProvider(vsocket->name());
+      return new AttributeInputProvider(
+          attribute_type_from_socket_type(data_graph->type_of_socket(socket)), vsocket->name());
     }
   }
   else if (STREQ(vnode->idname(), "bp_CollisionInfoNode")) {
@@ -92,7 +111,8 @@ static SharedFunction create_function__with_deps(
   fn_builder.add_outputs(data_graph.graph(), sockets_to_compute);
 
   for (uint i = 0; i < input_amount; i++) {
-    r_input_providers[i] = create_input_provider(input_vsockets[i]);
+    r_input_providers[i] = create_input_provider(
+        input_vsockets[i], data_graph.graph(), input_sockets[i]);
   }
 
   SharedFunction fn = fn_builder.build(function_name);
diff --git a/source/blender/simulations/bparticles/particle_function_input_providers.cpp b/source/blender/simulations/bparticles/particle_function_input_providers.cpp
index 6e06b8e9de2..d7c73d50629 100644
--- a/source/blender/simulations/bparticles/particle_function_input_providers.cpp
+++ b/source/blender/simulations/bparticles/particle_function_input_providers.cpp
@@ -10,25 +10,34 @@
 
 namespace BParticles {
 
-ParticleFunctionInputArray AttributeInputProvider::get(InputProviderInterface &interface)
+Optional<ParticleFunctionInputArray> AttributeInputProvider::get(InputProviderInterface &interface)
 {
   AttributesRef attributes = interface.attributes();
-  uint attribute_index = attributes.attribute_index(m_name);
-  uint size = attributes.attribute_size(attribute_index);
-  void *buffer = attributes.get_ptr(attribute_index);
-  return {buffer, size, false};
+  uint element_size = size_of_attribute_type(m_type);
+  int attribute_index = attributes.info().attribute_index_try(m_name, m_type);
+
+  if (attribute_index == -1) {
+    return {};
+  }
+  else {
+    void *buffer = attributes.get_ptr(attribute_index);
+    return ParticleFunctionInputArray(buffer, element_size, false);
+  }
 }
 
-ParticleFunctionInputArray CollisionNormalInputProvider::get(InputProviderInterface &interface)
+Optional<ParticleFunctionInputArray> CollisionNormalInputProvider::get(
+    InputProviderInterface &interface)
 {
   ActionContext *action_context = interface.action_context();
-  BLI_assert(action_context != nullptr);
   auto *surface_info = dynamic_cast<MeshSurfaceActionContext *>(action_context);
-  BLI_assert(surface_info != nullptr);
-  return {surface_info->world_normals(), false};
+  if (surface_info == nullptr) {
+    return {};
+  }
+
+  return ParticleFunctionInputArray(surface_info->world_normals(), false);
 }
 
-ParticleFunctionInputArray AgeInputProvider::get(InputProviderInterface &interface)
+Optional<ParticleFunctionInputArray> AgeInputProvider::get(InputProviderInterface &interface)
 {
   auto birth_times = interface.attributes().get<float>("Birth Time");
   float *ages_buffer = (float *)BLI_temporary_allocate(sizeof(float) * birth_times.size());
@@ -51,7 +60,7 @@ ParticleFunctionInputArray AgeInputProvider::get(InputProviderInterface &interfa
   else {
     BLI_assert(false);
   }
-  return {ArrayRef<float>(ages), true};
+  return ParticleFunctionInputArray(ArrayRef<float>(ages), true);
 }
 
 SurfaceImageInputProvider::SurfaceImageInputProvider(Image *image) : m_image(image)
@@ -67,12 +76,14 @@ SurfaceImageInputProvider::~SurfaceImageInputProvider()
   BKE_image_release_ibuf(m_image, m_ibuf, NULL);
 }
 
-ParticleFunctionInputArray SurfaceImageInputProvider::get(InputProviderInterface &interface)
+Optional<ParticleFunctionInputArray> SurfaceImageInputProvider::get(
+    InputProviderInterface &interface)
 {
   ActionContext *action_context = interface.action_context();
-  BLI_assert(action_context != nullptr);
   auto *surface_info = dynamic_cast<MeshSurfaceActionContext *>(action_context);
-  BLI_assert(surface_info != nullptr);
+  if (surface_info == nullptr) {
+    return {};
+  }
 
   const Object *object = surface_info->object();
   Mesh *mesh = (Mesh *)object->data;
@@ -120,7 +131,7 @@ ParticleFunctionInputArray SurfaceImageInputProvider::get(InputProviderInterface
     uint y = uv.y * (m_ibuf->y - 1);
     colors[pindex] = pixel_buffer[y * m_ibuf->x + x];
   }
-  return {ArrayRef<rgba_f>(colors), true};
+  return ParticleFunctionInputArray(ArrayRef<rgba_f>(colors), true);
 }
 
 }  // namespace BParticles
diff --git a/source/blender/simulations/bparticles/particle_function_input_providers.hpp b/source/blender/simulations/bparticles/particle_function_input_providers.hpp
index 5d407b745c2..fe3e87f83b5 100644
--- a/source/blender/simulations/bparticles/particle_function_input_providers.hpp
+++ b/source/blender/simulations/bparticles/particle_function_input_providers.hpp
@@ -9,22 +9,23 @@ namespace BParticles {
 
 class AttributeInputProvider : public ParticleFunctionInputProvider {
  private:
+  AttributeType m_type;
   std::string m_name;
 
  public:
-  AttributeInputProvider(StringRef name) : m_name(name)
+  AttributeInputProvider(AttributeType type, StringRef name) : m_type(type), m_name(name)
   {
   }
 
-  ParticleFunctionInputArray get(InputProviderInterface &interface) override;
+  Optional<ParticleFunctionInputArray> get(InputProviderInterface &interface) override;
 };
 
 class CollisionNormalInputProvider : public ParticleFunctionInputProvider {
-  ParticleFunctionInputArray get(InputProviderInterface &interface) override;
+  Optional<ParticleFunctionInputArray> get(InputProviderInterface &interface) override;
 };
 
 class AgeInputProvider : public ParticleFunctionInputProvider {
-  ParticleFunctionInputArray get(InputProviderInterface &interface) override;
+  Optional<ParticleFunctionInputArray> get(InputProviderInterface &interface) override;
 };
 
 class SurfaceImageInputProvider : public ParticleFunctionInputProvider {
@@ -37,7 +38,7 @@ class SurfaceImageInputProvider : public ParticleFunctionInputProvider {
   SurfaceImageInputProvider(Image *image);
   ~SurfaceImageInputProvider();
 
-  ParticleFunctionInputArray get(InputProviderInterface &interface) override;
+  Optional<ParticleFunctionInputArray> get(InputProviderInterface &interface) override;
 };
 
 }  // namespace BParticles



More information about the Bf-blender-cvs mailing list