[Bf-blender-cvs] [0bfec04cd55] master: Fix T72621: Transform object origin support for grease-pencil

Sebastian Parborg noreply at git.blender.org
Tue Jul 21 12:13:08 CEST 2020


Commit: 0bfec04cd5541551fea45d0f021e2df0aca80d2f
Author: Sebastian Parborg
Date:   Tue Jul 21 12:11:56 2020 +0200
Branches: master
https://developer.blender.org/rB0bfec04cd5541551fea45d0f021e2df0aca80d2f

Fix T72621: Transform object origin support for grease-pencil

Added support for transforming only origins with greasepencil objects.

The new functions is based on BKE_gpencil_transform. That is why there is FIXME statements in there.

Reviewed By: Campbell, Antonio

Differential Revision: http://developer.blender.org/D8303

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

M	source/blender/blenkernel/BKE_gpencil_geom.h
M	source/blender/blenkernel/intern/gpencil_geom.c
M	source/blender/editors/object/object_data_transform.c

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

diff --git a/source/blender/blenkernel/BKE_gpencil_geom.h b/source/blender/blenkernel/BKE_gpencil_geom.h
index 6b0f9428f82..1b22931483c 100644
--- a/source/blender/blenkernel/BKE_gpencil_geom.h
+++ b/source/blender/blenkernel/BKE_gpencil_geom.h
@@ -78,6 +78,20 @@ void BKE_gpencil_stroke_uv_update(struct bGPDstroke *gps);
 
 void BKE_gpencil_transform(struct bGPdata *gpd, float mat[4][4]);
 
+typedef struct GPencilPointCoordinates {
+  /* This is used when doing "move only origin" in object_data_transform.c.
+   * pressure is needs to be stored here as it is tied to object scale. */
+  float co[3];
+  float pressure;
+} GPencilPointCoordinates;
+
+int BKE_gpencil_stroke_point_count(struct bGPdata *gpd);
+void BKE_gpencil_point_coords_get(struct bGPdata *gpd, GPencilPointCoordinates *elem_data);
+void BKE_gpencil_point_coords_apply(struct bGPdata *gpd, const GPencilPointCoordinates *elem_data);
+void BKE_gpencil_point_coords_apply_with_mat4(struct bGPdata *gpd,
+                                              const GPencilPointCoordinates *elem_data,
+                                              const float mat[4][4]);
+
 bool BKE_gpencil_stroke_sample(struct bGPDstroke *gps, const float dist, const bool select);
 bool BKE_gpencil_stroke_smooth(struct bGPDstroke *gps, int i, float inf);
 bool BKE_gpencil_stroke_smooth_strength(struct bGPDstroke *gps, int point_index, float influence);
diff --git a/source/blender/blenkernel/intern/gpencil_geom.c b/source/blender/blenkernel/intern/gpencil_geom.c
index 5e55d3b2bef..0b965899689 100644
--- a/source/blender/blenkernel/intern/gpencil_geom.c
+++ b/source/blender/blenkernel/intern/gpencil_geom.c
@@ -2458,4 +2458,133 @@ void BKE_gpencil_transform(bGPdata *gpd, float mat[4][4])
     }
   }
 }
+
+/* Used for "move only origins" in object_data_transform.c */
+int BKE_gpencil_stroke_point_count(bGPdata *gpd)
+{
+  int total_points = 0;
+
+  if (gpd == NULL) {
+    return 0;
+  }
+
+  LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) {
+    /* FIXME: For now, we just skip parented layers.
+     * Otherwise, we have to update each frame to find
+     * the current parent position/effects.
+     */
+    if (gpl->parent) {
+      continue;
+    }
+
+    LISTBASE_FOREACH (bGPDframe *, gpf, &gpl->frames) {
+      LISTBASE_FOREACH (bGPDstroke *, gps, &gpf->strokes) {
+        total_points += gps->totpoints;
+      }
+    }
+  }
+  return total_points;
+}
+
+/* Used for "move only origins" in object_data_transform.c */
+void BKE_gpencil_point_coords_get(bGPdata *gpd, GPencilPointCoordinates *elem_data)
+{
+  if (gpd == NULL) {
+    return;
+  }
+
+  LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) {
+    /* FIXME: For now, we just skip parented layers.
+     * Otherwise, we have to update each frame to find
+     * the current parent position/effects.
+     */
+    if (gpl->parent) {
+      continue;
+    }
+
+    LISTBASE_FOREACH (bGPDframe *, gpf, &gpl->frames) {
+      LISTBASE_FOREACH (bGPDstroke *, gps, &gpf->strokes) {
+        bGPDspoint *pt;
+        int i;
+
+        for (pt = gps->points, i = 0; i < gps->totpoints; pt++, i++) {
+          copy_v3_v3(elem_data->co, &pt->x);
+          elem_data->pressure = pt->pressure;
+          elem_data++;
+        }
+      }
+    }
+  }
+}
+
+/* Used for "move only origins" in object_data_transform.c */
+void BKE_gpencil_point_coords_apply(bGPdata *gpd, const GPencilPointCoordinates *elem_data)
+{
+  if (gpd == NULL) {
+    return;
+  }
+
+  LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) {
+    /* FIXME: For now, we just skip parented layers.
+     * Otherwise, we have to update each frame to find
+     * the current parent position/effects.
+     */
+    if (gpl->parent) {
+      continue;
+    }
+
+    LISTBASE_FOREACH (bGPDframe *, gpf, &gpl->frames) {
+      LISTBASE_FOREACH (bGPDstroke *, gps, &gpf->strokes) {
+        bGPDspoint *pt;
+        int i;
+
+        for (pt = gps->points, i = 0; i < gps->totpoints; pt++, i++) {
+          copy_v3_v3(&pt->x, elem_data->co);
+          pt->pressure = elem_data->pressure;
+          elem_data++;
+        }
+
+        /* Distortion may mean we need to re-triangulate. */
+        BKE_gpencil_stroke_geometry_update(gps);
+      }
+    }
+  }
+}
+
+/* Used for "move only origins" in object_data_transform.c */
+void BKE_gpencil_point_coords_apply_with_mat4(bGPdata *gpd,
+                                              const GPencilPointCoordinates *elem_data,
+                                              const float mat[4][4])
+{
+  if (gpd == NULL) {
+    return;
+  }
+
+  const float scalef = mat4_to_scale(mat);
+  LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) {
+    /* FIXME: For now, we just skip parented layers.
+     * Otherwise, we have to update each frame to find
+     * the current parent position/effects.
+     */
+    if (gpl->parent) {
+      continue;
+    }
+
+    LISTBASE_FOREACH (bGPDframe *, gpf, &gpl->frames) {
+      LISTBASE_FOREACH (bGPDstroke *, gps, &gpf->strokes) {
+        bGPDspoint *pt;
+        int i;
+
+        for (pt = gps->points, i = 0; i < gps->totpoints; pt++, i++) {
+          mul_v3_m4v3(&pt->x, mat, elem_data->co);
+          pt->pressure = elem_data->pressure * scalef;
+          elem_data++;
+        }
+
+        /* Distortion may mean we need to re-triangulate. */
+        BKE_gpencil_stroke_geometry_update(gps);
+      }
+    }
+  }
+}
 /** \} */
diff --git a/source/blender/editors/object/object_data_transform.c b/source/blender/editors/object/object_data_transform.c
index 54fd1fe6671..1e030a50f38 100644
--- a/source/blender/editors/object/object_data_transform.c
+++ b/source/blender/editors/object/object_data_transform.c
@@ -33,6 +33,7 @@
 #include "DNA_anim_types.h"
 #include "DNA_armature_types.h"
 #include "DNA_collection_types.h"
+#include "DNA_gpencil_types.h"
 #include "DNA_lattice_types.h"
 #include "DNA_mesh_types.h"
 #include "DNA_meta_types.h"
@@ -46,6 +47,7 @@
 #include "BKE_armature.h"
 #include "BKE_curve.h"
 #include "BKE_editmesh.h"
+#include "BKE_gpencil_geom.h"
 #include "BKE_lattice.h"
 #include "BKE_mball.h"
 #include "BKE_mesh.h"
@@ -303,6 +305,11 @@ struct XFormObjectData_MetaBall {
   struct ElemData_MetaBall elem_array[0];
 };
 
+struct XFormObjectData_GPencil {
+  struct XFormObjectData base;
+  struct GPencilPointCoordinates elem_array[0];
+};
+
 struct XFormObjectData *ED_object_data_xform_create_ex(ID *id, bool is_edit_mode)
 {
   struct XFormObjectData *xod_base = NULL;
@@ -391,6 +398,15 @@ struct XFormObjectData *ED_object_data_xform_create_ex(ID *id, bool is_edit_mode
       xod_base = &xod->base;
       break;
     }
+    case ID_GD: {
+      bGPdata *gpd = (bGPdata *)id;
+      const int elem_array_len = BKE_gpencil_stroke_point_count(gpd);
+      struct XFormObjectData_GPencil *xod = MEM_mallocN(
+          sizeof(*xod) + (sizeof(*xod->elem_array) * elem_array_len), __func__);
+      BKE_gpencil_point_coords_get(gpd, xod->elem_array);
+      xod_base = &xod->base;
+      break;
+    }
     default: {
       break;
     }
@@ -471,6 +487,12 @@ void ED_object_data_xform_by_mat4(struct XFormObjectData *xod_base, const float
       metaball_coords_and_quats_apply_with_mat4(mb, xod->elem_array, mat);
       break;
     }
+    case ID_GD: {
+      bGPdata *gpd = (bGPdata *)xod_base->id;
+      struct XFormObjectData_GPencil *xod = (struct XFormObjectData_GPencil *)xod_base;
+      BKE_gpencil_point_coords_apply_with_mat4(gpd, xod->elem_array, mat);
+      break;
+    }
     default: {
       break;
     }
@@ -529,6 +551,12 @@ void ED_object_data_xform_restore(struct XFormObjectData *xod_base)
       metaball_coords_and_quats_apply(mb, xod->elem_array);
       break;
     }
+    case ID_GD: {
+      bGPdata *gpd = (bGPdata *)xod_base->id;
+      struct XFormObjectData_GPencil *xod = (struct XFormObjectData_GPencil *)xod_base;
+      BKE_gpencil_point_coords_apply(gpd, xod->elem_array);
+      break;
+    }
     default: {
       break;
     }
@@ -572,6 +600,12 @@ void ED_object_data_xform_tag_update(struct XFormObjectData *xod_base)
       DEG_id_tag_update(&mb->id, ID_RECALC_GEOMETRY | ID_RECALC_COPY_ON_WRITE);
       break;
     }
+    case ID_GD: {
+      /* Generic update. */
+      bGPdata *gpd = (bGPdata *)xod_base->id;
+      DEG_id_tag_update(&gpd->id, ID_RECALC_GEOMETRY | ID_RECALC_COPY_ON_WRITE);
+      break;
+    }
 
     default: {
       break;



More information about the Bf-blender-cvs mailing list