[Bf-blender-cvs] [a05408220df] greasepencil-object: GPencil: New operator to generate Grease Pencil from images
Antonio Vazquez
noreply at git.blender.org
Sun Dec 8 13:17:06 CET 2019
Commit: a05408220dfd143e70cf20b0584910c130246d35
Author: Antonio Vazquez
Date: Sun Dec 8 13:16:58 2019 +0100
Branches: greasepencil-object
https://developer.blender.org/rBa05408220dfd143e70cf20b0584910c130246d35
GPencil: New operator to generate Grease Pencil from images
This takes a image and generate a new grease pencil object and each pixel is a vertex point. THe image is generated by lines.
As an option, an inverted mask can be generated
===================================================================
M release/scripts/startup/bl_ui/space_image.py
M source/blender/blenkernel/BKE_gpencil.h
M source/blender/blenkernel/intern/gpencil.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
===================================================================
diff --git a/release/scripts/startup/bl_ui/space_image.py b/release/scripts/startup/bl_ui/space_image.py
index d4aab89ba3f..0677e2e4b62 100644
--- a/release/scripts/startup/bl_ui/space_image.py
+++ b/release/scripts/startup/bl_ui/space_image.py
@@ -254,6 +254,7 @@ class IMAGE_MT_image(Menu):
if ima:
layout.separator()
layout.operator("palette.extract_from_image", text="Extract Palette")
+ layout.operator("gpencil.image_to_grease_pencil", text="Generate Grease Pencil")
class IMAGE_MT_image_invert(Menu):
diff --git a/source/blender/blenkernel/BKE_gpencil.h b/source/blender/blenkernel/BKE_gpencil.h
index 8050c027de0..8dc19ed32e5 100644
--- a/source/blender/blenkernel/BKE_gpencil.h
+++ b/source/blender/blenkernel/BKE_gpencil.h
@@ -34,6 +34,7 @@ struct Main;
struct Material;
struct Object;
struct Scene;
+struct SpaceImage;
struct ToolSettings;
struct bDeformGroup;
struct bGPDframe;
@@ -296,6 +297,11 @@ void BKE_gpencil_convert_curve(struct Main *bmain,
void BKE_gpencil_palette_ensure(struct Main *bmain, struct Scene *scene);
+bool BKE_gpencil_from_image(struct SpaceImage *sima,
+ struct bGPDframe *gpf,
+ const float size,
+ const bool mask);
+
extern void (*BKE_gpencil_batch_cache_dirty_tag_cb)(struct bGPdata *gpd);
extern void (*BKE_gpencil_batch_cache_free_cb)(struct bGPdata *gpd);
diff --git a/source/blender/blenkernel/intern/gpencil.c b/source/blender/blenkernel/intern/gpencil.c
index 80ae8308934..69a4fca1485 100644
--- a/source/blender/blenkernel/intern/gpencil.c
+++ b/source/blender/blenkernel/intern/gpencil.c
@@ -39,12 +39,15 @@
#include "BLT_translation.h"
+#include "IMB_imbuf_types.h"
+
#include "DNA_anim_types.h"
#include "DNA_meshdata_types.h"
#include "DNA_material_types.h"
#include "DNA_gpencil_types.h"
#include "DNA_userdef_types.h"
#include "DNA_scene_types.h"
+#include "DNA_space_types.h"
#include "DNA_object_types.h"
#include "BKE_action.h"
@@ -55,6 +58,7 @@
#include "BKE_deform.h"
#include "BKE_gpencil.h"
#include "BKE_icons.h"
+#include "BKE_image.h"
#include "BKE_library.h"
#include "BKE_main.h"
#include "BKE_material.h"
@@ -3560,3 +3564,82 @@ void BKE_gpencil_palette_ensure(Main *bmain, Scene *scene)
}
}
}
+
+static void BKE_gpencil_get_pixel(const ImBuf *ibuf, const int idx, float r_col[4])
+{
+ if (ibuf->rect_float) {
+ const float *frgba = &ibuf->rect_float[idx * 4];
+ copy_v4_v4(r_col, frgba);
+ }
+ else if (ibuf->rect) {
+ unsigned char *cp = (unsigned char *)(ibuf->rect + idx);
+ r_col[0] = (float)cp[0] / 255.0f;
+ r_col[1] = (float)cp[1] / 255.0f;
+ r_col[2] = (float)cp[2] / 255.0f;
+ r_col[3] = (float)cp[3] / 255.0f;
+ }
+ else {
+ zero_v4(r_col);
+ }
+}
+
+bool BKE_gpencil_from_image(SpaceImage *sima, bGPDframe *gpf, const float size, const bool mask)
+{
+ Image *image = sima->image;
+ bool done = false;
+
+ if (image == NULL) {
+ return false;
+ }
+
+ ImageUser iuser = sima->iuser;
+ void *lock;
+ ImBuf *ibuf;
+
+ ibuf = BKE_image_acquire_ibuf(image, &iuser, &lock);
+
+ if (ibuf->rect) {
+ int img_x = ibuf->x;
+ int img_y = ibuf->y;
+
+ // space = 0.005 pixels = image.pixels
+ float color[4];
+ bGPDspoint *pt;
+ for (int row = 0; row < img_y; row++) {
+ /* Create new stroke */
+ bGPDstroke *gps = BKE_gpencil_add_stroke(gpf, 0, img_x, size * 1000);
+ done = true;
+ for (int col = 0; col < img_x; col++) {
+ int pix = ((row * img_x) + col);
+ BKE_gpencil_get_pixel(ibuf, pix, color);
+ pt = &gps->points[col];
+ pt->pressure = 1.2f; /* expand the point to avoid gaps. */
+ pt->x = col * size;
+ pt->z = row * size;
+ if (!mask) {
+ copy_v3_v3(pt->mix_color, color);
+ pt->mix_color[3] = 1.0f;
+ pt->strength = color[3];
+ }
+ else {
+ zero_v3(pt->mix_color);
+ pt->mix_color[3] = 1.0f;
+ pt->strength = 1.0f - color[3];
+ }
+
+ /* Selet Alpha points. */
+ if (pt->strength < 0.03f) {
+ gps->flag |= GP_STROKE_SELECT;
+ pt->flag |= GP_SPOINT_SELECT;
+ }
+ }
+ /* Dissolve any selected point. */
+ BKE_gpencil_dissolve_points(gpf, gps, GP_SPOINT_SELECT);
+ }
+ }
+
+ /* Free memory. */
+ BKE_image_release_ibuf(image, ibuf, lock);
+
+ return done;
+}
diff --git a/source/blender/editors/gpencil/gpencil_convert.c b/source/blender/editors/gpencil/gpencil_convert.c
index 4a91a90c075..11317491227 100644
--- a/source/blender/editors/gpencil/gpencil_convert.c
+++ b/source/blender/editors/gpencil/gpencil_convert.c
@@ -1749,4 +1749,87 @@ void GPENCIL_OT_convert(wmOperatorType *ot)
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
}
-/* ************************************************ */
+/* Generate Grease Pencil from Image. */
+static bool image_to_gpencil_poll(bContext *C)
+{
+ SpaceLink *sl = CTX_wm_space_data(C);
+ if (sl->spacetype == SPACE_IMAGE) {
+ return true;
+ }
+
+ return false;
+}
+
+static int image_to_gpencil_exec(bContext *C, wmOperator *op)
+{
+ const float size = RNA_float_get(op->ptr, "size");
+ const bool is_mask = RNA_boolean_get(op->ptr, "mask");
+
+ Main *bmain = CTX_data_main(C);
+ Scene *scene = CTX_data_scene(C);
+ SpaceImage *sima = CTX_wm_space_image(C);
+ bool done = false;
+
+ if (sima->image == NULL) {
+ return OPERATOR_CANCELLED;
+ }
+
+ /* Create Object. */
+ const float *cur = scene->cursor.location;
+ ushort local_view_bits = 0;
+ Object *ob = ED_gpencil_add_object(C, cur, local_view_bits);
+ DEG_relations_tag_update(bmain); /* added object */
+
+ /* Create material slot. */
+ Material *ma = BKE_gpencil_object_material_new(bmain, ob, "Image Material", NULL);
+ MaterialGPencilStyle *gp_style = ma->gp_style;
+ gp_style->mode = GP_STYLE_MODE_BOX;
+
+ /* Add layer and frame. */
+ bGPdata *gpd = (bGPdata *)ob->data;
+ bGPDlayer *gpl = BKE_gpencil_layer_addnew(gpd, "Image Layer", true);
+ bGPDframe *gpf = BKE_gpencil_frame_addnew(gpl, CFRA);
+ done = BKE_gpencil_from_image(sima, gpf, size, is_mask);
+
+ if (done) {
+ BKE_reportf(op->reports, RPT_INFO, "Object created");
+ }
+
+ return OPERATOR_FINISHED;
+}
+
+void GPENCIL_OT_image_to_grease_pencil(wmOperatorType *ot)
+{
+ PropertyRNA *prop;
+
+ /* identifiers */
+ ot->name = "Generate Grease Pencil Object using image as source";
+ ot->idname = "GPENCIL_OT_image_to_grease_pencil";
+ ot->description = "Generate a Grease Pencil Object using Image as source";
+
+ /* api callbacks */
+ ot->exec = image_to_gpencil_exec;
+ ot->poll = image_to_gpencil_poll;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+
+ /* properties */
+ ot->prop = RNA_def_float(ot->srna,
+ "size",
+ 0.005f,
+ 0.0001f,
+ 10.0f,
+ "Point Size",
+ "Size used for graese pencil points",
+ 0.001f,
+ 1.0f);
+ RNA_def_property_flag(ot->prop, PROP_SKIP_SAVE);
+
+ prop = RNA_def_boolean(ot->srna,
+ "mask",
+ false,
+ "Generate Mask",
+ "Create an inverted image for masking using alpha channel");
+ RNA_def_property_flag(prop, PROP_SKIP_SAVE);
+}
diff --git a/source/blender/editors/gpencil/gpencil_intern.h b/source/blender/editors/gpencil/gpencil_intern.h
index 9c1e0a30709..ee0cbdf7c93 100644
--- a/source/blender/editors/gpencil/gpencil_intern.h
+++ b/source/blender/editors/gpencil/gpencil_intern.h
@@ -465,6 +465,7 @@ void GPENCIL_OT_frame_clean_fill(struct wmOperatorType *ot);
void GPENCIL_OT_frame_clean_loose(struct wmOperatorType *ot);
void GPENCIL_OT_convert(struct wmOperatorType *ot);
+void GPENCIL_OT_image_to_grease_pencil(struct wmOperatorType *ot);
enum {
GP_STROKE_JOIN = -1,
diff --git a/source/blender/editors/gpencil/gpencil_ops.c b/source/blender/editors/gpencil/gpencil_ops.c
index 0efead2f9fe..dc4927c252f 100644
--- a/source/blender/editors/gpencil/gpencil_ops.c
+++ b/source/blender/editors/gpencil/gpencil_ops.c
@@ -595,6 +595,8 @@ void ED_operatortypes_gpencil(void)
WM_operatortype_append(GPENCIL_OT_convert);
+ WM_operatortype_append(GPENCIL_OT_image_to_grease_pencil);
+
WM_operatortype_append(GPENCIL_OT_stroke_arrange);
WM_operatortype_append(GPENCIL_OT_stroke_change_color);
WM_operatortype_append(GPENCIL_OT_stroke_lock_color);
More information about the Bf-blender-cvs
mailing list