[Bf-blender-cvs] [87866245347] attribute-accessor: wip

Jacques Lucke noreply at git.blender.org
Tue Nov 17 13:55:31 CET 2020


Commit: 878662453471e043c9e8a263fbbb2f0fbcdfb4c3
Author: Jacques Lucke
Date:   Mon Nov 16 17:17:45 2020 +0100
Branches: attribute-accessor
https://developer.blender.org/rB878662453471e043c9e8a263fbbb2f0fbcdfb4c3

wip

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

A	source/blender/blenkernel/BKE_attribute_accessor.hh
M	source/blender/blenkernel/CMakeLists.txt
A	source/blender/blenkernel/intern/attribute_accessor.cc

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

diff --git a/source/blender/blenkernel/BKE_attribute_accessor.hh b/source/blender/blenkernel/BKE_attribute_accessor.hh
new file mode 100644
index 00000000000..e791800cd96
--- /dev/null
+++ b/source/blender/blenkernel/BKE_attribute_accessor.hh
@@ -0,0 +1,65 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#pragma once
+
+#include "FN_cpp_type.hh"
+
+#include "BKE_attribute.h"
+#include "BKE_geometry_set.hh"
+
+struct Mesh;
+
+namespace blender::bke {
+
+using fn::CPPType;
+
+class AttributeAccessor {
+ private:
+  const CPPType *cpp_type_;
+  int64_t size_;
+
+ public:
+  AttributeAccessor(const CPPType &cpp_type, const int64_t size)
+      : cpp_type_(&cpp_type), size_(size)
+  {
+  }
+
+  void get(const int64_t index, void *r_value) const
+  {
+    BLI_assert(index < size_);
+    this->access_single(index, r_value);
+  }
+
+  template<typename T> T get(const int64_t index) const
+  {
+    BLI_assert(index < size_);
+    T value;
+    value.~T();
+    this->access_single(index, &value);
+    return value;
+  }
+
+ protected:
+  /* r_value is expected to be uninitialized. */
+  virtual void access_single(const int64_t index, void *r_value) const = 0;
+};
+
+std::unique_ptr<AttributeAccessor> get_mesh_attribute_accessor(const MeshComponent &mesh_component,
+                                                               const AttributeDomain domain,
+                                                               const StringRef attribute_name);
+
+}  // namespace blender::bke
diff --git a/source/blender/blenkernel/CMakeLists.txt b/source/blender/blenkernel/CMakeLists.txt
index ef093174dd5..a9945aef75a 100644
--- a/source/blender/blenkernel/CMakeLists.txt
+++ b/source/blender/blenkernel/CMakeLists.txt
@@ -78,6 +78,7 @@ set(SRC
   intern/armature_deform.c
   intern/armature_update.c
   intern/attribute.c
+  intern/attribute_accessor.cc
   intern/autoexec.c
   intern/blender.c
   intern/blender_copybuffer.c
@@ -267,6 +268,7 @@ set(SRC
   BKE_appdir.h
   BKE_armature.h
   BKE_attribute.h
+  BKE_attribute_accessor.hh
   BKE_autoexec.h
   BKE_blender.h
   BKE_blender_copybuffer.h
diff --git a/source/blender/blenkernel/intern/attribute_accessor.cc b/source/blender/blenkernel/intern/attribute_accessor.cc
new file mode 100644
index 00000000000..59bb4c7c093
--- /dev/null
+++ b/source/blender/blenkernel/intern/attribute_accessor.cc
@@ -0,0 +1,255 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include <utility>
+
+#include "BKE_attribute_accessor.hh"
+#include "BKE_deform.h"
+
+#include "DNA_mesh_types.h"
+#include "DNA_meshdata_types.h"
+
+#include "BLI_color.hh"
+#include "BLI_float2.hh"
+#include "BLI_span.hh"
+
+namespace blender::bke {
+
+class VertexWeightAttributeAccessor final : public AttributeAccessor {
+ private:
+  Span<MDeformVert> dverts_;
+  int dvert_index_;
+
+ public:
+  VertexWeightAttributeAccessor(const MDeformVert *dverts,
+                                const int totvert,
+                                const int dvert_index)
+      : AttributeAccessor(CPPType::get<float>(), totvert),
+        dverts_(dverts, totvert),
+        dvert_index_(dvert_index)
+  {
+  }
+
+  void access_single(const int64_t index, void *r_value) const override
+  {
+    const MDeformVert &dvert = dverts_[index];
+    for (const MDeformWeight &weight : Span(dvert.dw, dvert.totweight)) {
+      if (weight.def_nr == dvert_index_) {
+        *(float *)r_value = weight.weight;
+        return;
+      }
+    }
+    *(float *)r_value = 0.0f;
+  }
+};
+
+template<typename T> class ArrayAttributeAccessor final : public AttributeAccessor {
+ private:
+  Span<T> data_;
+
+ public:
+  ArrayAttributeAccessor(Span<T> data)
+      : AttributeAccessor(CPPType::get<T>(), data.size()), data_(data)
+  {
+  }
+
+  void access_single(const int64_t index, void *r_value) const override
+  {
+    new (r_value) T(data_[index]);
+  }
+};
+
+template<typename StructT, typename FuncT>
+class DerivedArrayAttributeAccessor final : public AttributeAccessor {
+ private:
+  using ElemT = decltype(std::declval<FuncT>()(std::declval<StructT>()));
+
+  Span<StructT> data_;
+  FuncT function_;
+
+ public:
+  DerivedArrayAttributeAccessor(Span<StructT> data, FuncT function)
+      : AttributeAccessor(CPPType::get<ElemT>(), data.size()),
+        data_(data),
+        function_(std::move(function))
+  {
+  }
+
+  void access_single(const int64_t index, void *r_value) const override
+  {
+    const StructT &struct_value = data_[index];
+    const ElemT value = function_(struct_value);
+    new (r_value) ElemT(value);
+  }
+};
+
+template<typename T> class ConstantAttributeAccessor final : public AttributeAccessor {
+ private:
+  T value_;
+
+ public:
+  ConstantAttributeAccessor(T value, const int64_t size)
+      : AttributeAccessor(CPPType::get<T>(), size), value_(std::move(value))
+  {
+  }
+
+  void access_single(const int64_t index, void *r_value) const override
+  {
+    new (r_value) T(value_);
+  }
+};
+
+static const CPPType *cpp_type_from_custom_data_type(CustomDataType type)
+{
+  switch (type) {
+    case CD_PROP_FLOAT:
+      return &CPPType::get<float>();
+    case CD_PROP_FLOAT2:
+      return &CPPType::get<float2>();
+    case CD_PROP_FLOAT3:
+      return &CPPType::get<float3>();
+    case CD_PROP_INT32:
+      return &CPPType::get<int>();
+    case CD_PROP_COLOR:
+      return &CPPType::get<Color4f>();
+  }
+  return nullptr;
+}
+
+static std::unique_ptr<AttributeAccessor> get_attribute_layer_accessor(
+    const CustomData &custom_data, const int size, const StringRef attribute_name)
+{
+  for (const CustomDataLayer &layer : Span(custom_data.layers, custom_data.totlayer)) {
+    if (layer.name != nullptr && layer.name == attribute_name) {
+      switch (layer.type) {
+        case CD_PROP_FLOAT:
+          return std::make_unique<ArrayAttributeAccessor<float>>(
+              Span(static_cast<float *>(layer.data), size));
+        case CD_PROP_FLOAT2:
+          return std::make_unique<ArrayAttributeAccessor<float2>>(
+              Span(static_cast<float2 *>(layer.data), size));
+        case CD_PROP_FLOAT3:
+          return std::make_unique<ArrayAttributeAccessor<float3>>(
+              Span(static_cast<float3 *>(layer.data), size));
+        case CD_PROP_INT32:
+          return std::make_unique<ArrayAttributeAccessor<int>>(
+              Span(static_cast<int *>(layer.data), size));
+        case CD_PROP_COLOR:
+          return std::make_unique<ArrayAttributeAccessor<Color4f>>(
+              Span(static_cast<Color4f *>(layer.data), size));
+      }
+    }
+  }
+  return {};
+}
+
+static std::unique_ptr<AttributeAccessor> get_mesh_attribute_accessor__vertex(
+    const MeshComponent &mesh_component, const StringRef attribute_name)
+{
+  const Mesh *mesh = mesh_component.get_for_read();
+  if (mesh == nullptr) {
+    return {};
+  }
+
+  if (attribute_name == "Position") {
+    auto get_vertex_position = [](const MVert &vert) { return float3(vert.co); };
+    return std::make_unique<DerivedArrayAttributeAccessor<MVert, decltype(get_vertex_position)>>(
+        Span(mesh->mvert, mesh->totvert), get_vertex_position);
+  }
+
+  const int vertex_group_index = mesh_component.vertex_group_index(attribute_name);
+  if (vertex_group_index >= 0) {
+    return std::make_unique<VertexWeightAttributeAccessor>(
+        mesh->dvert, mesh->totvert, vertex_group_index);
+  }
+
+  return get_attribute_layer_accessor(mesh->vdata, mesh->totvert, attribute_name);
+}
+
+static std::unique_ptr<AttributeAccessor> get_mesh_attribute_accessor__edge(
+    const MeshComponent &mesh_component, const StringRef attribute_name)
+{
+  const Mesh *mesh = mesh_component.get_for_read();
+  if (mesh == nullptr) {
+    return {};
+  }
+
+  return get_attribute_layer_accessor(mesh->edata, mesh->totedge, attribute_name);
+}
+
+static std::unique_ptr<AttributeAccessor> get_mesh_attribute_accessor__corner(
+    const MeshComponent &mesh_component, const StringRef attribute_name)
+{
+  const Mesh *mesh = mesh_component.get_for_read();
+  if (mesh == nullptr) {
+    return {};
+  }
+
+  return get_attribute_layer_accessor(mesh->ldata, mesh->totloop, attribute_name);
+}
+
+static std::unique_ptr<AttributeAccessor> get_mesh_attribute_accessor__polygon(
+    const MeshComponent &mesh_component, const StringRef attribute_name)
+{
+  const Mesh *mesh = mesh_component.get_for_read();
+  if (mesh == nullptr) {
+    return {};
+  }
+
+  return get_attribute_layer_accessor(mesh->pdata, mesh->totpoly, attribute_name);
+}
+
+static std::unique_ptr<AttributeAccessor> get_mesh_attribute_accessor(
+    const MeshComponent &mesh_component, const StringRef attribute_name, AttributeDomain *r_domain)
+{
+  std::unique_ptr<AttributeAccessor> corner_level = get_mesh_attribute_accessor__corner(
+      mesh_component, attribute_name);
+  if (corner_level) {
+    *r_

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list