[Bf-blender-cvs] [a8ed7a05856] greasepencil-object: GPencil: Export mesh animation to grease pencil

Antonio Vazquez noreply at git.blender.org
Wed Apr 1 15:43:51 CEST 2020


Commit: a8ed7a058567938def26fd9939f811cc0c7f7ad4
Author: Antonio Vazquez
Date:   Wed Apr 1 11:35:21 2020 +0200
Branches: greasepencil-object
https://developer.blender.org/rBa8ed7a058567938def26fd9939f811cc0c7f7ad4

GPencil: Export mesh animation to grease pencil

This operator extract a range of frames and convert to grease pencil strokes.

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

M	source/blender/blenkernel/BKE_gpencil_geom.h
M	source/blender/blenkernel/intern/gpencil_geom.c
M	source/blender/editors/gpencil/gpencil_convert.c
M	source/blender/editors/gpencil/gpencil_intern.h
M	source/blender/editors/gpencil/gpencil_ops.c
M	source/blender/editors/object/object_add.c

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

diff --git a/source/blender/blenkernel/BKE_gpencil_geom.h b/source/blender/blenkernel/BKE_gpencil_geom.h
index c2564d60d44..5fbd2f5fdc2 100644
--- a/source/blender/blenkernel/BKE_gpencil_geom.h
+++ b/source/blender/blenkernel/BKE_gpencil_geom.h
@@ -114,6 +114,7 @@ void BKE_gpencil_convert_mesh(struct Main *bmain,
                               const float angle,
                               const int thickness,
                               const float offset,
+                              const float matrix[4][4],
                               const bool use_seams,
                               const bool use_faces);
 
diff --git a/source/blender/blenkernel/intern/gpencil_geom.c b/source/blender/blenkernel/intern/gpencil_geom.c
index 2598b8895aa..37ffbc28d54 100644
--- a/source/blender/blenkernel/intern/gpencil_geom.c
+++ b/source/blender/blenkernel/intern/gpencil_geom.c
@@ -2074,6 +2074,7 @@ static void gpencil_generate_edgeloops(Object *ob,
                                        const float angle,
                                        const int thickness,
                                        const float offset,
+                                       const float matrix[4][4],
                                        const bool use_seams)
 {
   Mesh *me = (Mesh *)ob->data;
@@ -2166,12 +2167,16 @@ static void gpencil_generate_edgeloops(Object *ob,
     bGPDspoint *pt = &gps_stroke->points[0];
     mul_v3_v3fl(fpt, gped->n1, offset);
     add_v3_v3v3(&pt->x, gped->v1_co, fpt);
+    mul_m4_v3(matrix, &pt->x);
+
     pt->pressure = 1.0f;
     pt->strength = 1.0f;
 
     pt = &gps_stroke->points[1];
     mul_v3_v3fl(fpt, gped->n2, offset);
     add_v3_v3v3(&pt->x, gped->v2_co, fpt);
+    mul_m4_v3(matrix, &pt->x);
+
     pt->pressure = 1.0f;
     pt->strength = 1.0f;
 
@@ -2183,6 +2188,8 @@ static void gpencil_generate_edgeloops(Object *ob,
       bGPDspoint *pt = &gps_stroke->points[i + 1];
       mul_v3_v3fl(fpt, gped->n2, offset);
       add_v3_v3v3(&pt->x, gped->v2_co, fpt);
+      mul_m4_v3(matrix, &pt->x);
+
       pt->pressure = 1.0f;
       pt->strength = 1.0f;
     }
@@ -2206,8 +2213,10 @@ static void gpencil_generate_edgeloops(Object *ob,
  * \param ob_mesh: Mesh to convert.
  * \param angle: Limit angle to consider a edgeloop ends.
  * \param thickness: Thickness of the strokes.
+ * \param offset: Offset along the normals.
+ * \param matrix: Transformation matrix.
  * \param use_seams: Only export seam edges.
- * \param use_seams: Export faces as filled strokes.
+ * \param use_faces: Export faces as filled strokes.
  */
 void BKE_gpencil_convert_mesh(Main *bmain,
                               Depsgraph *depsgraph,
@@ -2217,6 +2226,7 @@ void BKE_gpencil_convert_mesh(Main *bmain,
                               const float angle,
                               const int thickness,
                               const float offset,
+                              const float matrix[4][4],
                               const bool use_seams,
                               const bool use_faces)
 {
@@ -2275,7 +2285,7 @@ void BKE_gpencil_convert_mesh(Main *bmain,
       if (gpl_fill == NULL) {
         gpl_fill = BKE_gpencil_layer_addnew(gpd, DATA_("Fills"), true);
       }
-      bGPDframe *gpf_fill = BKE_gpencil_layer_frame_get(gpl_fill, CFRA, GP_GETFRAME_ADD_COPY);
+      bGPDframe *gpf_fill = BKE_gpencil_layer_frame_get(gpl_fill, CFRA, GP_GETFRAME_ADD_NEW);
       for (i = 0, mp = mpoly; i < mpoly_len; i++, mp++) {
         MLoop *ml = &mloop[mp->loopstart];
         /* Create fill stroke. */
@@ -2290,6 +2300,7 @@ void BKE_gpencil_convert_mesh(Main *bmain,
 
           bGPDspoint *pt = &gps_fill->points[j];
           copy_v3_v3(&pt->x, mv->co);
+          mul_m4_v3(matrix, &pt->x);
           pt->pressure = 1.0f;
           pt->strength = 1.0f;
         }
@@ -2304,8 +2315,8 @@ void BKE_gpencil_convert_mesh(Main *bmain,
   if (gpl_stroke == NULL) {
     gpl_stroke = BKE_gpencil_layer_addnew(gpd, DATA_("Lines"), true);
   }
-  bGPDframe *gpf_stroke = BKE_gpencil_layer_frame_get(gpl_stroke, CFRA, GP_GETFRAME_ADD_COPY);
-  gpencil_generate_edgeloops(ob_eval, gpf_stroke, angle, thickness, offset, use_seams);
+  bGPDframe *gpf_stroke = BKE_gpencil_layer_frame_get(gpl_stroke, CFRA, GP_GETFRAME_ADD_NEW);
+  gpencil_generate_edgeloops(ob_eval, gpf_stroke, angle, thickness, offset, matrix, use_seams);
 
   /* Tag for recalculation */
   DEG_id_tag_update(&gpd->id, ID_RECALC_GEOMETRY | ID_RECALC_COPY_ON_WRITE);
diff --git a/source/blender/editors/gpencil/gpencil_convert.c b/source/blender/editors/gpencil/gpencil_convert.c
index b7a19d913c2..df542142127 100644
--- a/source/blender/editors/gpencil/gpencil_convert.c
+++ b/source/blender/editors/gpencil/gpencil_convert.c
@@ -54,8 +54,10 @@
 #include "BKE_fcurve.h"
 #include "BKE_global.h"
 #include "BKE_gpencil.h"
+#include "BKE_gpencil_geom.h"
 #include "BKE_layer.h"
 #include "BKE_main.h"
+#include "BKE_material.h"
 #include "BKE_object.h"
 #include "BKE_report.h"
 #include "BKE_scene.h"
@@ -1855,3 +1857,166 @@ void GPENCIL_OT_image_to_grease_pencil(wmOperatorType *ot)
                          "Create an inverted image for masking using alpha channel");
   RNA_def_property_flag(prop, PROP_SKIP_SAVE);
 }
+
+/* Extract mesh animation to Grease Pencil. */
+static bool gp_extract_mesh_animation_poll(bContext *C)
+{
+  if (CTX_data_mode_enum(C) != CTX_MODE_OBJECT) {
+    return false;
+  }
+
+  /* Only if the current view is 3D View. */
+  ScrArea *sa = CTX_wm_area(C);
+  return (sa && sa->spacetype);
+}
+
+static int gp_extract_mesh_animation_exec(bContext *C, wmOperator *op)
+{
+  Main *bmain = CTX_data_main(C);
+  Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
+  Scene *scene = CTX_data_scene(C);
+  View3D *v3d = CTX_wm_view3d(C);
+  Object *ob = CTX_data_active_object(C);
+
+  /* Cannot check this in poll because the active object changes. */
+  if ((ob == NULL) || (ob->type != OB_MESH)) {
+    BKE_report(op->reports, RPT_ERROR, "No Mesh object selected");
+    return OPERATOR_CANCELLED;
+  }
+
+  /* Set cursor to indicate working. */
+  WM_cursor_wait(1);
+
+  Object *ob_eval = (Object *)DEG_get_evaluated_object(depsgraph, ob);
+
+  /* Grab all relevant settings. */
+  const int step = RNA_int_get(op->ptr, "step");
+
+  const int start_frame = (scene->r.sfra > RNA_int_get(op->ptr, "start_frame")) ?
+                              scene->r.sfra :
+                              RNA_int_get(op->ptr, "start_frame");
+
+  const int end_frame = (scene->r.efra < RNA_int_get(op->ptr, "end_frame")) ?
+                            scene->r.efra :
+                            RNA_int_get(op->ptr, "end_frame");
+
+  const float angle = RNA_float_get(op->ptr, "angle");
+  const int thickness = RNA_int_get(op->ptr, "thickness");
+  const bool use_seams = RNA_boolean_get(op->ptr, "seams");
+  const bool use_faces = RNA_boolean_get(op->ptr, "faces");
+  const float offset = RNA_float_get(op->ptr, "offset");
+
+  /* Create a new grease pencil object in origin. */
+  ushort local_view_bits = (v3d && v3d->localvd) ? v3d->local_view_uuid : 0;
+  float loc[3] = {0.0f, 0.0f, 0.0f};
+  Object *ob_gpencil = ED_gpencil_add_object(C, loc, local_view_bits);
+
+  /* Loop all frame range. */
+  int oldframe = (int)DEG_get_ctime(depsgraph);
+  int key = -1;
+  for (int i = start_frame; i < end_frame + 1; i++) {
+    key++;
+    /* Jump if not step limit but include last frame always. */
+    if ((key % step != 0) && (i != end_frame)) {
+      continue;
+    }
+
+    /* Move scene to new frame. */
+    CFRA = i;
+    BKE_scene_graph_update_for_newframe(depsgraph, bmain);
+
+    /* Generate strokes. */
+    BKE_gpencil_convert_mesh(bmain,
+                             depsgraph,
+                             scene,
+                             ob_gpencil,
+                             ob,
+                             angle,
+                             thickness,
+                             offset,
+                             ob_eval->obmat,
+                             use_seams,
+                             use_faces);
+  }
+
+  /* Return scene frame state and DB to original state. */
+  CFRA = oldframe;
+  BKE_scene_graph_update_for_newframe(depsgraph, bmain);
+
+  /* Remove unused materials. */
+  int actcol = ob_gpencil->actcol;
+  for (int slot = 1; slot <= ob_gpencil->totcol; slot++) {
+    while (slot <= ob_gpencil->totcol && !BKE_object_material_slot_used(ob_gpencil->data, slot)) {
+      ob_gpencil->actcol = slot;
+      BKE_object_material_slot_remove(CTX_data_main(C), ob_gpencil);
+
+      if (actcol >= slot) {
+        actcol--;
+      }
+    }
+  }
+  ob_gpencil->actcol = actcol;
+
+  /* notifiers */
+  DEG_id_tag_update(&scene->id, ID_RECALC_SELECT);
+  WM_event_add_notifier(C, NC_OBJECT | NA_ADDED, NULL);
+  WM_event_add_notifier(C, NC_SCENE | ND_OB_ACTIVE, scene);
+
+  /* Reset cursor. */
+  WM_cursor_wait(0);
+
+  /* done */
+  return OPERATOR_FINISHED;
+}
+
+void GPENCIL_OT_extract_mesh_animation(wmOperatorType *ot)
+{
+  PropertyRNA *prop;
+
+  /* identifiers */
+  ot->name = "Extract Mesh Animation to Grease Pencil";
+  ot->idname = "GPENCIL_OT_extract_mesh_animation";
+  ot->description = "Convert all animation of mesh in Grease Pencil strokes";
+
+  /* callbacks */
+  ot->exec = gp_extract_mesh_animation_exec;
+  ot->poll = gp_extract_mesh_animation_poll;
+
+  /* flags */
+  ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+
+  /* properties */
+  ot->prop = RNA_def_int(
+      ot->srna, "start_frame", 1, 1, 100000, "Start Frame", "The start frame", 1, 100000);
+
+  prop = RNA_def_int(
+      ot->srna, "end_frame", 250, 1, 100000, "End Frame", "The end frame", 1, 100000);
+  RNA_def_property_update_runtime(prop, gp_convert_set_end_frame);
+
+  prop = RNA_def_int(ot->srna, "step", 1, 1, 100, "Step", "Step between generated frames", 1, 100);
+
+  prop = RNA_def_float_rotation(ot->srna,
+                                "angle",
+                                0,
+                                NULL,
+                                DEG2RADF(0.0f),
+                                DEG2RADF(180.0f),
+                                "Threshold Angle",
+                                "Th

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list