[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