[Bf-blender-cvs] [2308668bac0] blender-v2.90-release: Fix T72622: Transform object origin ignores shape keys

Campbell Barton noreply at git.blender.org
Sat Jul 25 09:19:27 CEST 2020


Commit: 2308668bac049dbf0e7056f9849e67f52ddb3f9d
Author: Campbell Barton
Date:   Sat Jul 25 16:35:52 2020 +1000
Branches: blender-v2.90-release
https://developer.blender.org/rB2308668bac049dbf0e7056f9849e67f52ddb3f9d

Fix T72622: Transform object origin ignores shape keys

D8367 by @paul2t with edits.

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

M	source/blender/blenkernel/BKE_key.h
M	source/blender/blenkernel/intern/key.c
M	source/blender/editors/include/ED_object.h
M	source/blender/editors/object/object_data_transform.c

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

diff --git a/source/blender/blenkernel/BKE_key.h b/source/blender/blenkernel/BKE_key.h
index 6581891062c..b0eef02611b 100644
--- a/source/blender/blenkernel/BKE_key.h
+++ b/source/blender/blenkernel/BKE_key.h
@@ -51,6 +51,12 @@ void key_curve_normal_weights(float t, float data[4], int type);
 float *BKE_key_evaluate_object_ex(struct Object *ob, int *r_totelem, float *arr, size_t arr_size);
 float *BKE_key_evaluate_object(struct Object *ob, int *r_totelem);
 
+int BKE_keyblock_element_count_from_shape(const struct Key *key, const int shape_index);
+int BKE_keyblock_element_count(const struct Key *key);
+
+size_t BKE_keyblock_element_calc_size_from_shape(const struct Key *key, const int shape_index);
+size_t BKE_keyblock_element_calc_size(const struct Key *key);
+
 bool BKE_key_idtype_support(const short id_type);
 
 struct Key **BKE_key_from_id_p(struct ID *id);
@@ -74,6 +80,10 @@ void BKE_keyblock_convert_from_lattice(struct Lattice *lt, struct KeyBlock *kb);
 void BKE_keyblock_convert_to_lattice(struct KeyBlock *kb, struct Lattice *lt);
 
 int BKE_keyblock_curve_element_count(struct ListBase *nurb);
+void BKE_keyblock_curve_data_transform(const struct ListBase *nurb,
+                                       const float mat[4][4],
+                                       const void *src,
+                                       void *dst);
 void BKE_keyblock_update_from_curve(struct Curve *cu, struct KeyBlock *kb, struct ListBase *nurb);
 void BKE_keyblock_convert_from_curve(struct Curve *cu, struct KeyBlock *kb, struct ListBase *nurb);
 void BKE_keyblock_convert_to_curve(struct KeyBlock *kb, struct Curve *cu, struct ListBase *nurb);
@@ -104,6 +114,28 @@ bool BKE_keyblock_move(struct Object *ob, int org_index, int new_index);
 
 bool BKE_keyblock_is_basis(struct Key *key, const int index);
 
+/* -------------------------------------------------------------------- */
+/** \name Key-Block Data Access
+ * \{ */
+
+void BKE_keyblock_data_get_from_shape(const struct Key *key,
+                                      float (*arr)[3],
+                                      const int shape_index);
+void BKE_keyblock_data_get(const struct Key *key, float (*arr)[3]);
+
+void BKE_keyblock_data_set_with_mat4(struct Key *key,
+                                     const int shape_index,
+                                     const float (*vertices)[3],
+                                     const float mat[4][4]);
+void BKE_keyblock_curve_data_set_with_mat4(struct Key *key,
+                                           const struct ListBase *nurb,
+                                           const int shape_index,
+                                           const void *data,
+                                           const float mat[4][4]);
+void BKE_keyblock_data_set(struct Key *key, const int shape_index, const void *data);
+
+/** \} */
+
 #ifdef __cplusplus
 };
 #endif
diff --git a/source/blender/blenkernel/intern/key.c b/source/blender/blenkernel/intern/key.c
index 46a41df0391..a71b9cc2a1d 100644
--- a/source/blender/blenkernel/intern/key.c
+++ b/source/blender/blenkernel/intern/key.c
@@ -1547,6 +1547,134 @@ float *BKE_key_evaluate_object(Object *ob, int *r_totelem)
   return BKE_key_evaluate_object_ex(ob, r_totelem, NULL, 0);
 }
 
+/**
+ * \param shape_index: The index to use or all (when -1).
+ */
+int BKE_keyblock_element_count_from_shape(const Key *key, const int shape_index)
+{
+  int result = 0;
+  int index = 0;
+  for (const KeyBlock *kb = key->block.first; kb; kb = kb->next, index++) {
+    if ((shape_index == -1) || (index == shape_index)) {
+      result += kb->totelem;
+    }
+  }
+  return result;
+}
+
+int BKE_keyblock_element_count(const Key *key)
+{
+  return BKE_keyblock_element_count_from_shape(key, -1);
+}
+
+/**
+ * \param shape_index: The index to use or all (when -1).
+ */
+size_t BKE_keyblock_element_calc_size_from_shape(const Key *key, const int shape_index)
+{
+  return (size_t)BKE_keyblock_element_count_from_shape(key, shape_index) * key->elemsize;
+}
+
+size_t BKE_keyblock_element_calc_size(const Key *key)
+{
+  return BKE_keyblock_element_calc_size_from_shape(key, -1);
+}
+
+/* -------------------------------------------------------------------- */
+/** \name Key-Block Data Access
+ *
+ * Utilities for getting/setting key data as a single array,
+ * use #BKE_keyblock_element_calc_size to allocate the size of the data needed.
+ * \{ */
+
+/**
+ * \param shape_index: The index to use or all (when -1).
+ */
+void BKE_keyblock_data_get_from_shape(const Key *key, float (*arr)[3], const int shape_index)
+{
+  uint8_t *elements = (uint8_t *)arr;
+  int index = 0;
+  for (const KeyBlock *kb = key->block.first; kb; kb = kb->next, index++) {
+    if ((shape_index == -1) || (index == shape_index)) {
+      const int block_elem_len = kb->totelem * key->elemsize;
+      memcpy(elements, kb->data, block_elem_len);
+      elements += block_elem_len;
+    }
+  }
+}
+
+void BKE_keyblock_data_get(const Key *key, float (*arr)[3])
+{
+  BKE_keyblock_data_get_from_shape(key, arr, -1);
+}
+
+/**
+ * Set the data to all key-blocks (or shape_index if != -1).
+ */
+void BKE_keyblock_data_set_with_mat4(Key *key,
+                                     const int shape_index,
+                                     const float (*coords)[3],
+                                     const float mat[4][4])
+{
+  if (key->elemsize != sizeof(float[3])) {
+    BLI_assert(!"Invalid elemsize");
+    return;
+  }
+
+  const float(*elements)[3] = coords;
+
+  int index = 0;
+  for (KeyBlock *kb = key->block.first; kb; kb = kb->next, index++) {
+    if ((shape_index == -1) || (index == shape_index)) {
+      const int block_elem_len = kb->totelem;
+      float(*block_data)[3] = (float(*)[3])kb->data;
+      for (int data_offset = 0; data_offset < block_elem_len; ++data_offset) {
+        const float *src_data = (const float *)(elements + data_offset);
+        float *dst_data = (float *)(block_data + data_offset);
+        mul_v3_m4v3(dst_data, mat, src_data);
+      }
+      elements += block_elem_len;
+    }
+  }
+}
+
+/**
+ * Set the data for all key-blocks (or shape_index if != -1),
+ * transforming by \a mat.
+ */
+void BKE_keyblock_curve_data_set_with_mat4(
+    Key *key, const ListBase *nurb, const int shape_index, const void *data, const float mat[4][4])
+{
+  const uint8_t *elements = data;
+
+  int index = 0;
+  for (KeyBlock *kb = key->block.first; kb; kb = kb->next, index++) {
+    if ((shape_index == -1) || (index == shape_index)) {
+      const int block_elem_size = kb->totelem * key->elemsize;
+      BKE_keyblock_curve_data_transform(nurb, mat, elements, kb->data);
+      elements += block_elem_size;
+    }
+  }
+}
+
+/**
+ * Set the data for all key-blocks (or shape_index if != -1).
+ */
+void BKE_keyblock_data_set(Key *key, const int shape_index, const void *data)
+{
+  const uint8_t *elements = data;
+  int index = 0;
+  for (KeyBlock *kb = key->block.first; kb; kb = kb->next, index++) {
+    if ((shape_index == -1) || (index == shape_index)) {
+      const int block_elem_size = kb->totelem * key->elemsize;
+      memcpy(kb->data, elements, block_elem_size);
+      elements += block_elem_size;
+    }
+  }
+}
+
+/** \} */
+
 bool BKE_key_idtype_support(const short id_type)
 {
   switch (id_type) {
@@ -1903,6 +2031,37 @@ void BKE_keyblock_update_from_curve(Curve *UNUSED(cu), KeyBlock *kb, ListBase *n
   }
 }
 
+void BKE_keyblock_curve_data_transform(const ListBase *nurb,
+                                       const float mat[4][4],
+                                       const void *src_data,
+                                       void *dst_data)
+{
+  const float *src = src_data;
+  float *dst = dst_data;
+  for (Nurb *nu = nurb->first; nu; nu = nu->next) {
+    if (nu->bezt) {
+      for (int a = nu->pntsu; a; a--) {
+        for (int i = 0; i < 3; i++) {
+          mul_v3_m4v3(&dst[i * 3], mat, &src[i * 3]);
+        }
+        dst[9] = src[9];
+        dst[10] = src[10];
+        src += KEYELEM_FLOAT_LEN_BEZTRIPLE;
+        dst += KEYELEM_FLOAT_LEN_BEZTRIPLE;
+      }
+    }
+    else {
+      for (int a = nu->pntsu * nu->pntsv; a; a--) {
+        mul_v3_m4v3(dst, mat, src);
+        dst[3] = src[3];
+        dst[4] = src[4];
+        src += KEYELEM_FLOAT_LEN_BPOINT;
+        dst += KEYELEM_FLOAT_LEN_BPOINT;
+      }
+    }
+  }
+}
+
 void BKE_keyblock_convert_from_curve(Curve *cu, KeyBlock *kb, ListBase *nurb)
 {
   int tot;
diff --git a/source/blender/editors/include/ED_object.h b/source/blender/editors/include/ED_object.h
index d8f55a0f60a..e08be5937fe 100644
--- a/source/blender/editors/include/ED_object.h
+++ b/source/blender/editors/include/ED_object.h
@@ -492,7 +492,7 @@ struct XFormObjectData *ED_object_data_xform_create_ex(struct ID *id, bool is_ed
 struct XFormObjectData *ED_object_data_xform_create(struct ID *id);
 struct XFormObjectData *ED_object_data_xform_create_from_edit_mode(ID *id);
 
-void ED_object_data_xform_destroy(struct XFormObjectData *xod);
+void ED_object_data_xform_destroy(struct XFormObjectData *xod_base);
 
 void ED_object_data_xform_by_mat4(struct XFormObjectData *xod, const float mat[4][4]);
 
diff --git a/source/blender/editors/object/object_data_transform.c b/source/blender/editors/object/object_data_transform.c
index 1e030a50f38..8ea35c7a92c 100644
--- a/source/blender/editors/object/object_data_transform.c
+++ b/source/blender/editors/object/object_data_transform.c
@@ -48,6 +48,7 @@
 #include "BKE_curve.h"
 #include "BKE_editmesh.h"
 #include "BKE_gpencil_geom.h"
+#include "BKE_key.h"
 #include "BKE_lattice.h"
 #include "BKE_mball.h"
 #include "BKE_mesh.h"
@@ -282,16 +283,22 @@ struct XFormObjectData {
 
 struct XFormObjectData_Mesh {
   struct XFormObjectData base;
+  /* Optional data for shape keys. */
+  void *key_data;
   float elem_array[0][3];
 };
 
 struct XFormObjectData_Lattice {
   struct XFormObjectData base;
+  /* Optional data for shape keys. */
+  void *key_data;
   float elem_array[0][3];
 };
 
 struct XFormObjectData_Curve {
   struct XFormObjectData base;
+  /* Optional data for shape keys. */
+  void *key_data;
   float elem_array[0][3];
 };
 
@@ -316,48 +323,98 @@ struct XFormObjectData *ED_object_data_xf

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list