[Bf-blender-cvs] [565510bd7fd] master: Geometry: add .attributes in the Python API for Mesh, Hair and Point Cloud

Brecht Van Lommel noreply at git.blender.org
Wed Sep 9 17:01:32 CEST 2020


Commit: 565510bd7fd87ae146cabafb27f1dfd550450f58
Author: Brecht Van Lommel
Date:   Fri Jul 3 15:30:04 2020 +0200
Branches: master
https://developer.blender.org/rB565510bd7fd87ae146cabafb27f1dfd550450f58

Geometry: add .attributes in the Python API for Mesh, Hair and Point Cloud

This puts all generic float/int/vector/color/string geometry attributes in a new
.attributes property. For meshes it provides a more general API for existing
attributes, for point clouds attributes will be used as an essential part of
particle nodes.

This patch was implemented by @lichtwerk, with further changes by me. It's
still a work in progress, but posting here to show what is going on and for
early feedback.

Ref T76659

Differential Revision: https://developer.blender.org/D8200

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

A	source/blender/blenkernel/BKE_attribute.h
M	source/blender/blenkernel/CMakeLists.txt
A	source/blender/blenkernel/intern/attribute.c
M	source/blender/blenkernel/intern/customdata.c
M	source/blender/makesdna/DNA_customdata_types.h
M	source/blender/makesdna/DNA_hair_types.h
M	source/blender/makesdna/DNA_mesh_types.h
M	source/blender/makesdna/DNA_pointcloud_types.h
M	source/blender/makesrna/RNA_access.h
M	source/blender/makesrna/intern/CMakeLists.txt
M	source/blender/makesrna/intern/makesrna.c
A	source/blender/makesrna/intern/rna_attribute.c
M	source/blender/makesrna/intern/rna_hair.c
M	source/blender/makesrna/intern/rna_internal.h
M	source/blender/makesrna/intern/rna_mesh.c
M	source/blender/makesrna/intern/rna_pointcloud.c
M	source/blender/python/bmesh/bmesh_py_types_customdata.c

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

diff --git a/source/blender/blenkernel/BKE_attribute.h b/source/blender/blenkernel/BKE_attribute.h
new file mode 100644
index 00000000000..9eba13ef7c4
--- /dev/null
+++ b/source/blender/blenkernel/BKE_attribute.h
@@ -0,0 +1,82 @@
+/*
+ * 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.
+ *
+ * The Original Code is Copyright (C) 2006 Blender Foundation.
+ * All rights reserved.
+ */
+
+/** \file
+ * \ingroup bke
+ * \brief Generic geometry attributes built on CustomData.
+ */
+
+#pragma once
+
+#include "BLI_sys_types.h"
+
+#include "BKE_customdata.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct CustomData;
+struct CustomDataLayer;
+struct ID;
+struct PointerRNA;
+struct ReportList;
+
+/* Attribute.domain */
+typedef enum AttributeDomain {
+  ATTR_DOMAIN_VERTEX = 0,  /* Mesh Vertex */
+  ATTR_DOMAIN_EDGE = 1,    /* Mesh Edge */
+  ATTR_DOMAIN_CORNER = 2,  /* Mesh Corner */
+  ATTR_DOMAIN_POLYGON = 3, /* Mesh Polygon */
+
+  ATTR_DOMAIN_POINT = 4, /* Hair or PointCloud Point */
+  ATTR_DOMAIN_CURVE = 5, /* Hair Curve */
+
+  ATTR_DOMAIN_NUM
+} AttributeDomain;
+
+/* Attributes */
+
+struct CustomDataLayer *BKE_id_attribute_new(struct ID *id,
+                                             const char *name,
+                                             const int type,
+                                             const AttributeDomain domain,
+                                             struct ReportList *reports);
+void BKE_id_attribute_remove(struct ID *id,
+                             struct CustomDataLayer *layer,
+                             struct ReportList *reports);
+
+AttributeDomain BKE_id_attribute_domain(struct ID *id, struct CustomDataLayer *layer);
+int BKE_id_attribute_data_length(struct ID *id, struct CustomDataLayer *layer);
+bool BKE_id_attribute_rename(struct ID *id,
+                             struct CustomDataLayer *layer,
+                             const char *new_name,
+                             struct ReportList *reports);
+
+int BKE_id_attributes_length(struct ID *id, const CustomDataMask mask);
+
+struct CustomDataLayer *BKE_id_attributes_active_get(struct ID *id);
+void BKE_id_attributes_active_set(struct ID *id, struct CustomDataLayer *layer);
+int *BKE_id_attributes_active_index_p(struct ID *id);
+
+CustomData *BKE_id_attributes_iterator_next_domain(struct ID *id, struct CustomDataLayer *layers);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/source/blender/blenkernel/CMakeLists.txt b/source/blender/blenkernel/CMakeLists.txt
index bf3077b7743..cf43d0fe845 100644
--- a/source/blender/blenkernel/CMakeLists.txt
+++ b/source/blender/blenkernel/CMakeLists.txt
@@ -77,6 +77,7 @@ set(SRC
   intern/armature.c
   intern/armature_deform.c
   intern/armature_update.c
+  intern/attribute.c
   intern/autoexec.c
   intern/blender.c
   intern/blender_copybuffer.c
@@ -267,6 +268,7 @@ set(SRC
   BKE_animsys.h
   BKE_appdir.h
   BKE_armature.h
+  BKE_attribute.h
   BKE_autoexec.h
   BKE_blender.h
   BKE_blender_copybuffer.h
diff --git a/source/blender/blenkernel/intern/attribute.c b/source/blender/blenkernel/intern/attribute.c
new file mode 100644
index 00000000000..49c255fc065
--- /dev/null
+++ b/source/blender/blenkernel/intern/attribute.c
@@ -0,0 +1,291 @@
+/*
+ * 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.
+ *
+ * The Original Code is Copyright (C) 2006 Blender Foundation.
+ * All rights reserved.
+ *
+ * Implementation of generic geometry attributes management. This is built
+ * on top of CustomData, which manages individual domains.
+ */
+
+/** \file
+ * \ingroup bke
+ */
+
+#include <string.h>
+
+#include "MEM_guardedalloc.h"
+
+#include "DNA_ID.h"
+#include "DNA_customdata_types.h"
+#include "DNA_hair_types.h"
+#include "DNA_mesh_types.h"
+#include "DNA_meshdata_types.h"
+#include "DNA_pointcloud_types.h"
+
+#include "BLI_string_utf8.h"
+
+#include "BKE_attribute.h"
+#include "BKE_customdata.h"
+#include "BKE_report.h"
+
+#include "RNA_access.h"
+
+typedef struct DomainInfo {
+  CustomData *customdata;
+  int length;
+} DomainInfo;
+
+static void get_domains(ID *id, DomainInfo info[ATTR_DOMAIN_NUM])
+{
+  memset(info, 0, sizeof(DomainInfo) * ATTR_DOMAIN_NUM);
+
+  switch (GS(id->name)) {
+    case ID_PT: {
+      PointCloud *pointcloud = (PointCloud *)id;
+      info[ATTR_DOMAIN_POINT].customdata = &pointcloud->pdata;
+      info[ATTR_DOMAIN_POINT].length = pointcloud->totpoint;
+      break;
+    }
+    case ID_ME: {
+      Mesh *mesh = (Mesh *)id;
+      info[ATTR_DOMAIN_VERTEX].customdata = &mesh->vdata;
+      info[ATTR_DOMAIN_VERTEX].length = mesh->totvert;
+      info[ATTR_DOMAIN_EDGE].customdata = &mesh->edata;
+      info[ATTR_DOMAIN_EDGE].length = mesh->totedge;
+      info[ATTR_DOMAIN_CORNER].customdata = &mesh->ldata;
+      info[ATTR_DOMAIN_CORNER].length = mesh->totloop;
+      info[ATTR_DOMAIN_POLYGON].customdata = &mesh->pdata;
+      info[ATTR_DOMAIN_POLYGON].length = mesh->totpoly;
+      break;
+    }
+    case ID_HA: {
+      Hair *hair = (Hair *)id;
+      info[ATTR_DOMAIN_POINT].customdata = &hair->pdata;
+      info[ATTR_DOMAIN_POINT].length = hair->totpoint;
+      info[ATTR_DOMAIN_CURVE].customdata = &hair->cdata;
+      info[ATTR_DOMAIN_CURVE].length = hair->totcurve;
+      break;
+    }
+    default:
+      break;
+  }
+}
+
+static CustomData *attribute_customdata_find(ID *id, CustomDataLayer *layer)
+{
+  DomainInfo info[ATTR_DOMAIN_NUM];
+  get_domains(id, info);
+
+  for (AttributeDomain domain = 0; domain < ATTR_DOMAIN_NUM; domain++) {
+    CustomData *customdata = info[domain].customdata;
+    if (customdata && ARRAY_HAS_ITEM(layer, customdata->layers, customdata->totlayer)) {
+      return customdata;
+    }
+  }
+
+  return NULL;
+}
+
+bool BKE_id_attribute_rename(ID *id,
+                             CustomDataLayer *layer,
+                             const char *new_name,
+                             ReportList *reports)
+{
+  CustomData *customdata = attribute_customdata_find(id, layer);
+  if (customdata == NULL) {
+    BKE_report(reports, RPT_ERROR, "Attribute is not part of this geometry");
+    return false;
+  }
+
+  BLI_strncpy_utf8(layer->name, new_name, sizeof(layer->name));
+  CustomData_set_layer_unique_name(customdata, layer - customdata->layers);
+  return true;
+}
+
+CustomDataLayer *BKE_id_attribute_new(
+    ID *id, const char *name, const int type, const AttributeDomain domain, ReportList *reports)
+{
+  DomainInfo info[ATTR_DOMAIN_NUM];
+  get_domains(id, info);
+
+  CustomData *customdata = info[domain].customdata;
+  if (customdata == NULL) {
+    BKE_report(reports, RPT_ERROR, "Attribute domain not supported by this geometry type");
+    return NULL;
+  }
+
+  CustomData_add_layer_named(customdata, type, CD_DEFAULT, NULL, info[domain].length, name);
+  const int index = CustomData_get_named_layer_index(customdata, type, name);
+  return (index == -1) ? NULL : &(customdata->layers[index]);
+}
+
+void BKE_id_attribute_remove(ID *id, CustomDataLayer *layer, ReportList *reports)
+{
+  CustomData *customdata = attribute_customdata_find(id, layer);
+  const int index = (customdata) ?
+                        CustomData_get_named_layer_index(customdata, layer->type, layer->name) :
+                        -1;
+
+  if (index == -1) {
+    BKE_report(reports, RPT_ERROR, "Attribute is not part of this geometry");
+    return;
+  }
+
+  const int length = BKE_id_attribute_data_length(id, layer);
+  CustomData_free_layer(customdata, layer->type, length, index);
+}
+
+int BKE_id_attributes_length(ID *id, const CustomDataMask mask)
+{
+  DomainInfo info[ATTR_DOMAIN_NUM];
+  get_domains(id, info);
+
+  int length = 0;
+
+  for (AttributeDomain domain = 0; domain < ATTR_DOMAIN_NUM; domain++) {
+    CustomData *customdata = info[domain].customdata;
+    if (customdata) {
+      length += CustomData_number_of_layers_typemask(customdata, mask);
+    }
+  }
+
+  return length;
+}
+
+AttributeDomain BKE_id_attribute_domain(ID *id, CustomDataLayer *layer)
+{
+  DomainInfo info[ATTR_DOMAIN_NUM];
+  get_domains(id, info);
+
+  for (AttributeDomain domain = 0; domain < ATTR_DOMAIN_NUM; domain++) {
+    CustomData *customdata = info[domain].customdata;
+    if (customdata && ARRAY_HAS_ITEM(layer, customdata->layers, customdata->totlayer)) {
+      return domain;
+    }
+  }
+
+  BLI_assert(!"Custom data layer not found in geometry");
+  return ATTR_DOMAIN_NUM;
+}
+
+int BKE_id_attribute_data_length(ID *id, CustomDataLayer *layer)
+{
+  DomainInfo info[ATTR_DOMAIN_NUM];
+  get_domains(id, info);
+
+  for (AttributeDomain domain = 0; domain < ATTR_DOMAIN_NUM; domain++) {
+    CustomData *customdata = info[domain].customdata;
+    if (customdata && ARRAY_HAS_ITEM(layer, customdata->layers, customdata->totlayer)) {
+      return info[domain].length;
+    }
+  }
+
+  BLI_assert(!"Custom data layer not found in geometry");
+  return 0;
+}
+
+CustomDa

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list