[Bf-blender-cvs] [bc7a4b126af] master: GPencil: Convert and Bake mesh animation to grease pencil strokes

Antonio Vazquez noreply at git.blender.org
Tue Jun 16 15:33:33 CEST 2020


Commit: bc7a4b126afb6789e301c148d8f07e38365c1545
Author: Antonio Vazquez
Date:   Tue Jun 16 15:28:46 2020 +0200
Branches: master
https://developer.blender.org/rBbc7a4b126afb6789e301c148d8f07e38365c1545

GPencil: Convert and Bake mesh animation to grease pencil strokes

This patch adds two options:

- Convert a mesh to grease pencil strokes.
- Bake the mesh animation into grease pencil strokes.

Both are related and must be included in the same patch.

Related to tasks: T77629 and T77630

Notice: The conversion is done for mesh edges and it's not considering any visibility clipping. All edges are exported, no matters if it's visible or not.

Example of Convert a Mesh to Grease Pencil strokes:

{F8606028}

This conversion was inspired by the technique used by @luamono in this tweet: https://twitter.com/luamono/status/1239983662176841730

Example of Bake Animation (the video is a little outdate, but the basic functionality is the same, only small changes in UI):

{F8606032}

Reviewed By: mendio, pepeland

Maniphest Tasks: T77629, T77630

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

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

M	release/scripts/startup/bl_operators/__init__.py
A	release/scripts/startup/bl_operators/gpencil_mesh_bake.py
M	release/scripts/startup/bl_ui/space_view3d.py
M	source/blender/blenkernel/BKE_gpencil_geom.h
M	source/blender/blenkernel/intern/gpencil_geom.c
M	source/blender/editors/gpencil/CMakeLists.txt
M	source/blender/editors/gpencil/gpencil_convert.c
M	source/blender/editors/gpencil/gpencil_intern.h
A	source/blender/editors/gpencil/gpencil_mesh.c
M	source/blender/editors/gpencil/gpencil_ops.c
M	source/blender/editors/object/object_add.c

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

diff --git a/release/scripts/startup/bl_operators/__init__.py b/release/scripts/startup/bl_operators/__init__.py
index d7df29f1769..c39a7afcff9 100644
--- a/release/scripts/startup/bl_operators/__init__.py
+++ b/release/scripts/startup/bl_operators/__init__.py
@@ -49,6 +49,7 @@ _modules = [
     "uvcalc_smart_project",
     "vertexpaint_dirt",
     "view3d",
+    "gpencil_mesh_bake",
     "wm",
 ]
 
diff --git a/release/scripts/startup/bl_operators/gpencil_mesh_bake.py b/release/scripts/startup/bl_operators/gpencil_mesh_bake.py
new file mode 100644
index 00000000000..ae75fa0e4d9
--- /dev/null
+++ b/release/scripts/startup/bl_operators/gpencil_mesh_bake.py
@@ -0,0 +1,162 @@
+# ##### BEGIN GPL LICENSE BLOCK #####
+#
+#  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.
+#
+# ##### END GPL LICENSE BLOCK #####
+
+# <pep8-80 compliant>
+
+import bpy
+from bpy.types import Operator
+from bpy.props import (
+    IntProperty,
+    FloatProperty,
+    BoolProperty,
+    EnumProperty,
+)
+
+gp_object_items = []
+
+
+def my_objlist_callback(scene, context):
+    gp_object_items.clear()
+    gp_object_items.append(('*NEW', "New Object", ""))
+    for o in context.scene.objects:
+        if o.type == 'GPENCIL':
+            gp_object_items.append((o.name, o.name, ""))
+
+    return gp_object_items
+
+
+class GPENCIL_OT_mesh_bake(Operator):
+    """Bake all mesh animation into grease pencil strokes"""
+    bl_idname = "gpencil.mesh_bake"
+    bl_label = "Bake Mesh to Grease Pencil"
+    bl_options = {'REGISTER', 'UNDO'}
+
+    frame_start: IntProperty(
+        name="Start Frame",
+        description="Start frame for baking",
+        min=0, max=300000,
+        default=1,
+    )
+    frame_end: IntProperty(
+        name="End Frame",
+        description="End frame for baking",
+        min=1, max=300000,
+        default=250,
+    )
+    step: IntProperty(
+        name="Frame Step",
+        description="Frame Step",
+        min=1, max=120,
+        default=1,
+    )
+    thickness: IntProperty(
+        name="Thickness",
+        description="Thickness of the stroke lines",
+        min=1, max=100,
+        default=1,
+    )
+    angle: FloatProperty(
+        name="Threshold Angle",
+        description="Threshold to determine ends of the strokes",
+        min=0,
+        max=+3.141592,
+        default=+1.22173,  # 70 Degress
+        subtype='ANGLE',
+    )
+    offset: FloatProperty(
+        name="Stroke Offset",
+        description="Offset strokes from fill",
+        soft_min=0.0, soft_max=100.0,
+        min=0.0, max=100.0,
+        default=0.001,
+        precision=3,
+        step=1,
+        subtype='DISTANCE',
+        unit='LENGTH',
+    )
+    seams: BoolProperty(
+        name="Only Seam Edges",
+        description="Convert only seam edges",
+        default=False,
+    )
+    faces: BoolProperty(
+        name="Export Faces",
+        description="Export faces as filled strokes",
+        default=True,
+    )
+    target: EnumProperty(
+        name="Target Object",
+        description="Grease Pencil Object",
+        items=my_objlist_callback
+        )
+    frame_target: IntProperty(
+        name="Target Frame",
+        description="Destination frame for the baked animation",
+        min=1, max=300000,
+        default=1,
+    )
+    project_type: EnumProperty(
+        name="Reproject Type",
+        description="Type of projection",
+        items=(
+            ("KEEP", "No Reproject", ""),
+            ("FRONT", "Front", "Reproject the strokes using the X-Z plane"),
+            ("SIDE", "Side", "Reproject the strokes using the Y-Z plane"),
+            ("TOP", "Top", "Reproject the strokes using the X-Y plane"),
+            ("VIEW", "View", "Reproject the strokes to current viewpoint"),
+            ("CURSOR", "Cursor", "Reproject the strokes using the orientation of 3D cursor")
+        )
+    )
+
+    @classmethod
+    def poll(self, context):
+        ob = context.active_object
+        return ((ob is not None) and
+                (ob.type in {'EMPTY', 'MESH'}) and
+                (context.mode == 'OBJECT'))
+
+    def execute(self, context):
+        bpy.ops.gpencil.bake_mesh_animation(
+            frame_start=self.frame_start,
+            frame_end=self.frame_end,
+            step=self.step,
+            angle=self.angle,
+            thickness=self.thickness,
+            seams=self.seams,
+            faces=self.faces,
+            offset=self.offset,
+            target=self.target,
+            frame_target=self.frame_target,
+            project_type=self.project_type
+        )
+
+        return {'FINISHED'}
+
+    def invoke(self, context, _event):
+        scene = context.scene
+        self.frame_start = scene.frame_start
+        self.frame_end = scene.frame_end
+        self.frame_target = scene.frame_start
+
+        wm = context.window_manager
+        return wm.invoke_props_dialog(self)
+
+
+classes = (
+    GPENCIL_OT_mesh_bake,
+)
diff --git a/release/scripts/startup/bl_ui/space_view3d.py b/release/scripts/startup/bl_ui/space_view3d.py
index c982d8e93a9..c4961125a46 100644
--- a/release/scripts/startup/bl_ui/space_view3d.py
+++ b/release/scripts/startup/bl_ui/space_view3d.py
@@ -2348,6 +2348,7 @@ class VIEW3D_MT_object_animation(Menu):
         layout.separator()
 
         layout.operator("nla.bake", text="Bake Action...")
+        layout.operator("gpencil.mesh_bake", text="Bake Mesh to Grease Pencil...")
 
 
 class VIEW3D_MT_object_rigid_body(Menu):
diff --git a/source/blender/blenkernel/BKE_gpencil_geom.h b/source/blender/blenkernel/BKE_gpencil_geom.h
index b26016aa26c..b79bbf3948f 100644
--- a/source/blender/blenkernel/BKE_gpencil_geom.h
+++ b/source/blender/blenkernel/BKE_gpencil_geom.h
@@ -98,6 +98,19 @@ bool BKE_gpencil_stroke_shrink(struct bGPDstroke *gps, const float dist);
 
 float BKE_gpencil_stroke_length(const struct bGPDstroke *gps, bool use_3d);
 
+void BKE_gpencil_convert_mesh(struct Main *bmain,
+                              struct Depsgraph *depsgraph,
+                              struct Scene *scene,
+                              struct Object *ob_gp,
+                              struct Object *ob_mesh,
+                              const float angle,
+                              const int thickness,
+                              const float offset,
+                              const float matrix[4][4],
+                              const int frame_offset,
+                              const bool use_seams,
+                              const bool use_faces);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/source/blender/blenkernel/intern/gpencil_geom.c b/source/blender/blenkernel/intern/gpencil_geom.c
index d200e4e3a15..a67c36ea713 100644
--- a/source/blender/blenkernel/intern/gpencil_geom.c
+++ b/source/blender/blenkernel/intern/gpencil_geom.c
@@ -32,15 +32,22 @@
 #include "MEM_guardedalloc.h"
 
 #include "BLI_blenlib.h"
+#include "BLI_ghash.h"
 #include "BLI_math_vector.h"
 #include "BLI_polyfill_2d.h"
 
+#include "BLT_translation.h"
+
 #include "DNA_gpencil_types.h"
+#include "DNA_mesh_types.h"
 #include "DNA_meshdata_types.h"
+#include "DNA_scene_types.h"
 
 #include "BKE_deform.h"
 #include "BKE_gpencil.h"
 #include "BKE_gpencil_geom.h"
+#include "BKE_main.h"
+#include "BKE_material.h"
 #include "BKE_object.h"
 
 #include "DEG_depsgraph_query.h"
@@ -1244,7 +1251,8 @@ bool BKE_gpencil_stroke_trim(bGPDstroke *gps)
     return false;
   }
   bool intersect = false;
-  int start, end;
+  int start = 0;
+  int end = 0;
   float point[3];
   /* loop segments from start until we have an intersection */
   for (int i = 0; i < gps->totpoints - 2; i++) {
@@ -1580,6 +1588,384 @@ void BKE_gpencil_stroke_merge_distance(bGPDframe *gpf,
   BKE_gpencil_stroke_geometry_update(gps);
 }
 
+typedef struct GpEdge {
+  uint v1, v2;
+  /* Coordinates. */
+  float v1_co[3], v2_co[3];
+  /* Normals. */
+  float n1[3], n2[3];
+  /* Direction of the segment. */
+  float vec[3];
+  int flag;
+} GpEdge;
+
+static int gpencil_next_edge(
+    GpEdge *gp_edges, int totedges, GpEdge *gped_init, const float threshold, const bool reverse)
+{
+  int edge = -1;
+  float last_angle = 999999.0f;
+  for (int i = 0; i < totedges; i++) {
+    GpEdge *gped = &gp_edges[i];
+    if (gped->flag != 0) {
+      continue;
+    }
+    if (reverse) {
+      if (gped_init->v1 != gped->v2) {
+        continue;
+      }
+    }
+    else {
+      if (gped_init->v2 != gped->v1) {
+        continue;
+      }
+    }
+    /* Look for straight lines. */
+    float angle = angle_v3v3(gped->vec, gped_init->vec);
+    if ((angle < threshold) && (angle <= last_angle)) {
+      edge = i;
+      last_angle = angle;
+    }
+  }
+
+  return edge;
+}
+
+static int gpencil_walk_edge(GHash *v_table,
+                             GpEdge *gp_edges,
+                             int totedges,
+                             uint *stroke_array,
+                             int init_idx,
+                             const float angle,
+                             const bool reverse)
+{
+  GpEdge *gped_init = &gp_edges[init_idx];
+  int idx = 1;
+  int edge = 0;
+  while (edge > -1) {
+    edge = gpencil_next_edge(gp_edges, totedges, gped_init, angle, reverse);
+    if (edge > -1) {
+      GpEdge *gped = &gp_edges[edge];
+      stroke_array[idx] = edge;
+      gped->flag = 1;
+      gped_init = &gp_edges[edge];
+      idx++;
+
+      /* Avoid to follow already visited vertice. */
+      if (reverse) {
+        if (BLI_ghash_haskey(v_table, POINTER_FROM_INT(gped->v1))) {
+

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list