[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