[Bf-blender-cvs] [bc654dd3dde] functions: support for choosing uv layer by name

Jacques Lucke noreply at git.blender.org
Thu Sep 5 19:12:04 CEST 2019


Commit: bc654dd3ddef18cf693bde54888ee5f0a9d6944a
Author: Jacques Lucke
Date:   Thu Sep 5 16:21:32 2019 +0200
Branches: functions
https://developer.blender.org/rBbc654dd3ddef18cf693bde54888ee5f0a9d6944a

support for choosing uv layer by name

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

M	release/scripts/startup/nodes/bparticle_nodes/particle_inputs.py
M	source/blender/blenlib/BLI_math.hpp
M	source/blender/functions/types/string_type.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/release/scripts/startup/nodes/bparticle_nodes/particle_inputs.py b/release/scripts/startup/nodes/bparticle_nodes/particle_inputs.py
index 8042524c0d1..11d3d2e57ab 100644
--- a/release/scripts/startup/nodes/bparticle_nodes/particle_inputs.py
+++ b/release/scripts/startup/nodes/bparticle_nodes/particle_inputs.py
@@ -29,13 +29,27 @@ class SurfaceImageNode(bpy.types.Node, BParticlesNode):
     bl_idname = "bp_SurfaceImageNode"
     bl_label = "Surface Image"
 
+    uv_mode: EnumProperty(
+        name="UV Mode",
+        items=[
+            ('FIRST', "First", "Use first UV map", 'NONE', 0),
+            ('BY_NAME', "By Name", "Choose the UV map by name", 'NONE', 1),
+        ],
+        update=BParticlesNode.sync_tree,
+        default='FIRST',
+    )
+
     image: PointerProperty(type=bpy.types.Image)
 
     def declaration(self, builder: NodeBuilder):
+        if self.uv_mode == 'BY_NAME':
+            builder.fixed_input("uv_name", "Name", "Text")
         builder.fixed_output("color", "Color", "Color")
 
     def draw(self, layout):
-        layout.prop(self, "image", text="")
+        col = layout.column()
+        col.prop(self, "image", text="")
+        col.prop(self, "uv_mode", text="")
 
 
 class SurfaceWeightNode(bpy.types.Node, BParticlesNode):
diff --git a/source/blender/blenlib/BLI_math.hpp b/source/blender/blenlib/BLI_math.hpp
index 9139e7695f4..335d494c994 100644
--- a/source/blender/blenlib/BLI_math.hpp
+++ b/source/blender/blenlib/BLI_math.hpp
@@ -383,7 +383,7 @@ struct rgba_b {
     rgba_float_to_uchar(*this, other);
   }
 
-  operator rgba_f()
+  operator rgba_f() const
   {
     rgba_f result;
     rgba_uchar_to_float(result, *this);
@@ -394,6 +394,11 @@ struct rgba_b {
   {
     return &r;
   }
+
+  operator const uint8_t *() const
+  {
+    return &r;
+  }
 };
 
 /* Conversions
diff --git a/source/blender/functions/types/string_type.hpp b/source/blender/functions/types/string_type.hpp
index 4f1ceaf3168..5133e159ad3 100644
--- a/source/blender/functions/types/string_type.hpp
+++ b/source/blender/functions/types/string_type.hpp
@@ -62,6 +62,11 @@ class MyString {
     return *this;
   }
 
+  const char *data() const
+  {
+    return m_string;
+  }
+
   operator StringRefNull() const
   {
     if (m_string == nullptr) {
diff --git a/source/blender/simulations/bparticles/particle_function_builder.cpp b/source/blender/simulations/bparticles/particle_function_builder.cpp
index 890594f8cf3..e29e5fe9bdc 100644
--- a/source/blender/simulations/bparticles/particle_function_builder.cpp
+++ b/source/blender/simulations/bparticles/particle_function_builder.cpp
@@ -98,13 +98,30 @@ static ParticleFunctionInputProvider *INPUT_surface_info(VTreeDataGraph &UNUSED(
   }
 }
 
-static ParticleFunctionInputProvider *INPUT_surface_image(VTreeDataGraph &UNUSED(vtree_data_graph),
+static ParticleFunctionInputProvider *INPUT_surface_image(VTreeDataGraph &vtree_data_graph,
                                                           VirtualSocket *vsocket)
 {
+  Optional<std::string> uv_map_name;
+
   PointerRNA rna = vsocket->vnode()->rna();
   Image *image = (Image *)RNA_pointer_get(&rna, "image").data;
   BLI_assert(image != nullptr);
-  return new SurfaceImageInputProvider(image);
+
+  int uv_mode = RNA_enum_get(&rna, "uv_mode");
+  if (uv_mode == 1) {
+    FunctionGraph fgraph(vtree_data_graph.graph(),
+                         {},
+                         {vtree_data_graph.lookup_socket(vsocket->vnode()->input(0))});
+    FN::SharedFunction fn = fgraph.new_function(vsocket->vnode()->name());
+    FN::fgraph_add_TupleCallBody(fn, fgraph);
+
+    FN::TupleCallBody &body = fn->body<TupleCallBody>();
+    FN_TUPLE_CALL_ALLOC_TUPLES(body, fn_in, fn_out);
+    body.call__setup_execution_context(fn_in, fn_out);
+    uv_map_name = std::string(fn_out.relocate_out<FN::Types::MyString>(0).data());
+  }
+
+  return new SurfaceImageInputProvider(image, uv_map_name);
 }
 
 static ParticleFunctionInputProvider *INPUT_surface_weight(
diff --git a/source/blender/simulations/bparticles/particle_function_input_providers.cpp b/source/blender/simulations/bparticles/particle_function_input_providers.cpp
index cb9e09afc4e..9911225baae 100644
--- a/source/blender/simulations/bparticles/particle_function_input_providers.cpp
+++ b/source/blender/simulations/bparticles/particle_function_input_providers.cpp
@@ -78,7 +78,9 @@ Optional<ParticleFunctionInputArray> AgeInputProvider::get(InputProviderInterfac
   return ParticleFunctionInputArray(ages.as_ref(), true);
 }
 
-SurfaceImageInputProvider::SurfaceImageInputProvider(Image *image) : m_image(image)
+SurfaceImageInputProvider::SurfaceImageInputProvider(Image *image,
+                                                     Optional<std::string> uv_map_name)
+    : m_image(image), m_uv_map_name(std::move(uv_map_name))
 {
   memset(&m_image_user, 0, sizeof(ImageUser));
   m_image_user.ok = true;
@@ -110,6 +112,16 @@ Optional<ParticleFunctionInputArray> SurfaceImageInputProvider::get(
   return {};
 }
 
+static int find_uv_layer_index(Mesh *mesh, const Optional<std::string> &uv_map_name)
+{
+  if (uv_map_name.has_value()) {
+    return CustomData_get_named_layer_index(&mesh->ldata, CD_MLOOPUV, uv_map_name.value().data());
+  }
+  else {
+    return CustomData_get_active_layer(&mesh->ldata, CD_MLOOPUV);
+  }
+}
+
 Optional<ParticleFunctionInputArray> SurfaceImageInputProvider::compute_colors(
     InputProviderInterface &interface,
     MeshSurfaceContext *surface_info,
@@ -121,12 +133,14 @@ Optional<ParticleFunctionInputArray> SurfaceImageInputProvider::compute_colors(
   const MLoopTri *triangles = BKE_mesh_runtime_looptri_ensure(mesh);
   ArrayRef<float3> barycentric_coords = surface_info->barycentric_coords();
 
-  int uv_layer_index = CustomData_get_active_layer(&mesh->ldata, CD_MLOOPUV);
-  BLI_assert(uv_layer_index >= 0);
-  MLoopUV *uv_layer = (MLoopUV *)CustomData_get(&mesh->ldata, uv_layer_index, CD_MLOOPUV);
-  BLI_assert(uv_layer != nullptr);
+  int uv_layer_index = find_uv_layer_index(mesh, m_uv_map_name);
+  if (uv_layer_index < 0) {
+    return {};
+  }
+  ArrayRef<MLoopUV> uv_layer = BLI::ref_c_array(
+      (MLoopUV *)CustomData_get_layer_n(&mesh->ldata, CD_MLOOPUV, uv_layer_index), mesh->totloop);
 
-  rgba_b *pixel_buffer = (rgba_b *)m_ibuf->rect;
+  ArrayRef<rgba_b> pixel_buffer = BLI::ref_c_array((rgba_b *)m_ibuf->rect, m_ibuf->x * m_ibuf->y);
 
   uint size = interface.attributes().size();
   auto colors = BLI::temporary_allocate_array<rgba_f>(size);
diff --git a/source/blender/simulations/bparticles/particle_function_input_providers.hpp b/source/blender/simulations/bparticles/particle_function_input_providers.hpp
index 6f080cea57f..38cc65d2561 100644
--- a/source/blender/simulations/bparticles/particle_function_input_providers.hpp
+++ b/source/blender/simulations/bparticles/particle_function_input_providers.hpp
@@ -38,9 +38,10 @@ class SurfaceImageInputProvider : public ParticleFunctionInputProvider {
   Image *m_image;
   ImageUser m_image_user;
   ImBuf *m_ibuf;
+  Optional<std::string> m_uv_map_name;
 
  public:
-  SurfaceImageInputProvider(Image *image);
+  SurfaceImageInputProvider(Image *image, Optional<std::string> uv_map_name);
   ~SurfaceImageInputProvider();
 
   Optional<ParticleFunctionInputArray> get(InputProviderInterface &interface) override;



More information about the Bf-blender-cvs mailing list