[Bf-blender-cvs] [5907e16c481] greasepencil-object: GPencil: Convert Mesh to GPencil

Antonio Vazquez noreply at git.blender.org
Sun Mar 29 18:05:34 CEST 2020


Commit: 5907e16c481effa588eda1bb837a4fef6fef82bd
Author: Antonio Vazquez
Date:   Sun Mar 29 18:04:52 2020 +0200
Branches: greasepencil-object
https://developer.blender.org/rB5907e16c481effa588eda1bb837a4fef6fef82bd

GPencil: Convert Mesh to GPencil

New option to convert a mesh to a 3D grease pencil object.

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

M	source/blender/blenkernel/BKE_gpencil_geom.h
M	source/blender/blenkernel/intern/gpencil_geom.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 8c52e6d458b..25841e35b9c 100644
--- a/source/blender/blenkernel/BKE_gpencil_geom.h
+++ b/source/blender/blenkernel/BKE_gpencil_geom.h
@@ -106,6 +106,14 @@ void BKE_gpencil_convert_curve(struct Main *bmain,
                                const bool use_collections,
                                const bool only_stroke);
 
+void BKE_gpencil_convert_mesh(struct Main *bmain,
+                              struct Depsgraph *depsgraph,
+                              struct Scene *scene,
+                              struct Object *ob_gp,
+                              struct Object *ob_mesh,
+                              const bool gpencil_lines,
+                              const bool only_stroke);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/source/blender/blenkernel/intern/gpencil_geom.c b/source/blender/blenkernel/intern/gpencil_geom.c
index c4acc871752..a979d9d1c28 100644
--- a/source/blender/blenkernel/intern/gpencil_geom.c
+++ b/source/blender/blenkernel/intern/gpencil_geom.c
@@ -38,6 +38,7 @@
 #include "BLT_translation.h"
 
 #include "DNA_gpencil_types.h"
+#include "DNA_mesh_types.h"
 #include "DNA_meshdata_types.h"
 
 #include "BKE_collection.h"
@@ -1614,32 +1615,30 @@ static int gpencil_check_same_material_color(Object *ob_gp, float color[4], Mate
   return -1;
 }
 
-/* Helper: Add gpencil material using curve material as base. */
-static Material *gpencil_add_from_curve_material(Main *bmain,
-                                                 Object *ob_gp,
-                                                 const float cu_color[4],
-                                                 const bool gpencil_lines,
-                                                 const bool fill,
-                                                 int *r_idx)
+/* Helper: Add gpencil material using material as base. */
+static Material *gpencil_add_material(Main *bmain,
+                                      Object *ob_gp,
+                                      const float color[4],
+                                      const bool use_stroke,
+                                      const bool use_fill,
+                                      int *r_idx)
 {
-  Material *mat_gp = BKE_gpencil_object_material_new(
-      bmain, ob_gp, (fill) ? "Material" : "Unassigned", r_idx);
+  Material *mat_gp = BKE_gpencil_object_material_new(bmain, ob_gp, "Material", r_idx);
   MaterialGPencilStyle *gp_style = mat_gp->gp_style;
 
   /* Stroke color. */
-  if (gpencil_lines) {
+  if (use_stroke) {
     ARRAY_SET_ITEMS(gp_style->stroke_rgba, 0.0f, 0.0f, 0.0f, 1.0f);
     gp_style->flag |= GP_MATERIAL_STROKE_SHOW;
   }
   else {
-    linearrgb_to_srgb_v4(gp_style->stroke_rgba, cu_color);
+    linearrgb_to_srgb_v4(gp_style->stroke_rgba, color);
     gp_style->flag &= ~GP_MATERIAL_STROKE_SHOW;
   }
 
   /* Fill color. */
-  linearrgb_to_srgb_v4(gp_style->fill_rgba, cu_color);
-  /* Fill is false if the original curve hasn't material assigned, so enable it. */
-  if (fill) {
+  linearrgb_to_srgb_v4(gp_style->fill_rgba, color);
+  if (use_fill) {
     gp_style->flag |= GP_MATERIAL_FILL_SHOW;
   }
 
@@ -1771,7 +1770,7 @@ static void gpencil_convert_spline(Main *bmain,
   int r_idx = gpencil_check_same_material_color(ob_gp, color, &mat_gp);
   if ((ob_cu->totcol > 0) && (r_idx < 0)) {
     Material *mat_curve = BKE_object_material_get(ob_cu, 1);
-    mat_gp = gpencil_add_from_curve_material(bmain, ob_gp, color, gpencil_lines, fill, &r_idx);
+    mat_gp = gpencil_add_material(bmain, ob_gp, color, gpencil_lines, fill, &r_idx);
 
     if ((mat_curve) && (mat_curve->gp_style != NULL)) {
       MaterialGPencilStyle *gp_style_cur = mat_curve->gp_style;
@@ -1984,6 +1983,105 @@ void BKE_gpencil_convert_curve(Main *bmain,
   DEG_id_tag_update(&gpd->id, ID_RECALC_GEOMETRY | ID_RECALC_COPY_ON_WRITE);
 }
 
+/* Convert a mesh object to grease pencil stroke.
+ *
+ * \param bmain: Main thread pointer
+ * \param depsgraph: Original depsgraph.
+ * \param scene: Original scene.
+ * \param ob_gp: Grease pencil object to add strokes.
+ * \param ob_mesh: Mesh to convert.
+ * \param gpencil_lines: Use lines for strokes.
+ * \param use_collections: Create layers using collection names.
+ * \param only_stroke: The material must be only stroke without fill.
+ */
+void BKE_gpencil_convert_mesh(Main *bmain,
+                              Depsgraph *depsgraph,
+                              Scene *scene,
+                              Object *ob_gp,
+                              Object *ob_mesh,
+                              const bool gpencil_lines,
+                              const bool only_stroke)
+{
+  if (ELEM(NULL, ob_gp, ob_mesh) || (ob_gp->type != OB_GPENCIL) || (ob_gp->data == NULL)) {
+    return;
+  }
+  bGPdata *gpd = (bGPdata *)ob_gp->data;
+  /* Set object in 3D mode. */
+  gpd->draw_mode = GP_DRAWMODE_3D;
+
+  /* Use evaluated data to get mesh with all modifiers on top. */
+  Object *ob_eval = (Object *)DEG_get_evaluated_object(depsgraph, ob_mesh);
+  Mesh *me = (Mesh *)ob_eval->data;
+  MPoly *mp, *mpoly = me->mpoly;
+  MLoop *mloop = me->mloop;
+  int mpoly_len = me->totpoly;
+  int i;
+
+  /* Create two materials, one for stroke, one for fill */
+  int r_idx;
+  const float default_colors[3][4] = {
+      {0.0f, 0.0f, 0.0f, 1.0f}, {0.7f, 0.7f, 0.7f, 1.0f}, {0.5f, 0.5f, 0.5f, 1.0f}};
+  gpencil_add_material(bmain, ob_gp, default_colors[0], true, false, &r_idx);
+  gpencil_add_material(bmain, ob_gp, default_colors[1], false, true, &r_idx);
+
+  /* Create two layers. */
+  bGPDlayer *gpl_fill = BKE_gpencil_layer_addnew(gpd, DATA_("Fills"), true);
+  bGPDlayer *gpl_stroke = BKE_gpencil_layer_addnew(gpd, DATA_("Lines"), true);
+
+  /* Check if there is an active frame and add if needed. */
+  bGPDframe *gpf_stroke = BKE_gpencil_layer_frame_get(gpl_stroke, CFRA, GP_GETFRAME_ADD_COPY);
+  bGPDframe *gpf_fill = BKE_gpencil_layer_frame_get(gpl_fill, CFRA, GP_GETFRAME_ADD_COPY);
+
+  /* Read all polygons and create a stroke and fill for each. */
+  for (i = 0, mp = mpoly; i < mpoly_len; i++, mp++) {
+    MLoop *ml = &mloop[mp->loopstart];
+    /* Get stroke and fill color from Material Viewport color. */
+    Material *mat = me->mat != NULL ? me->mat[mp->mat_nr] : NULL;
+    float vert_color[4];
+    if (mat != NULL) {
+      copy_v3_v3(vert_color, &mat->r);
+      vert_color[3] = 1.0f;
+    }
+    else {
+      /* Use default. */
+      copy_v4_v4(vert_color, default_colors[2]);
+    }
+
+    /* Create line stroke. */
+    bGPDstroke *gps_stroke = BKE_gpencil_stroke_add(gpf_stroke, 0, mp->totloop, 10, false);
+    gps_stroke->flag |= GP_STROKE_CYCLIC;
+    bGPDstroke *gps_fill = BKE_gpencil_stroke_add(gpf_fill, 1, mp->totloop, 10, false);
+    gps_fill->flag |= GP_STROKE_CYCLIC;
+    copy_v4_v4(gps_stroke->vert_color_fill, vert_color);
+    copy_v4_v4(gps_fill->vert_color_fill, vert_color);
+
+    /* Add points to strokes. */
+    int j;
+    for (j = 0; j < mp->totloop; j++, ml++) {
+      MVert *mv = &me->mvert[ml->v];
+
+      /* Line. */
+      bGPDspoint *pt = &gps_stroke->points[j];
+      copy_v3_v3(&pt->x, mv->co);
+      pt->pressure = 1.0f;
+      pt->strength = 1.0f;
+      copy_v4_v4(pt->vert_color, vert_color);
+      /* Fill. */
+      pt = &gps_fill->points[j];
+      copy_v3_v3(&pt->x, mv->co);
+      pt->pressure = 1.0f;
+      pt->strength = 1.0f;
+      copy_v4_v4(pt->vert_color, vert_color);
+    }
+
+    BKE_gpencil_stroke_geometry_update(gps_stroke);
+    BKE_gpencil_stroke_geometry_update(gps_fill);
+  }
+
+  /* Tag for recalculation */
+  DEG_id_tag_update(&gpd->id, ID_RECALC_GEOMETRY | ID_RECALC_COPY_ON_WRITE);
+}
+
 /* Apply Transforms */
 void BKE_gpencil_transform(bGPdata *gpd, float mat[4][4])
 {
diff --git a/source/blender/editors/object/object_add.c b/source/blender/editors/object/object_add.c
index ac2958282c1..fab0641d709 100644
--- a/source/blender/editors/object/object_add.c
+++ b/source/blender/editors/object/object_add.c
@@ -2085,7 +2085,7 @@ void OBJECT_OT_duplicates_make_real(wmOperatorType *ot)
 static const EnumPropertyItem convert_target_items[] = {
     {OB_CURVE, "CURVE", ICON_OUTLINER_OB_CURVE, "Curve from Mesh/Text", ""},
     {OB_MESH, "MESH", ICON_OUTLINER_OB_MESH, "Mesh from Curve/Meta/Surf/Text", ""},
-    {OB_GPENCIL, "GPENCIL", ICON_OUTLINER_OB_GREASEPENCIL, "Grease Pencil from Curve", ""},
+    {OB_GPENCIL, "GPENCIL", ICON_OUTLINER_OB_GREASEPENCIL, "Grease Pencil from Curve/Mesh", ""},
     {0, NULL, 0, NULL, NULL},
 };
 
@@ -2331,6 +2331,23 @@ static int convert_exec(bContext *C, wmOperator *op)
         ED_rigidbody_object_remove(bmain, scene, newob);
       }
     }
+    else if (ob->type == OB_MESH && target == OB_GPENCIL) {
+      ob->flag |= OB_DONE;
+
+      /* Create a new grease pencil object and copy transformations. */
+      ushort local_view_bits = (v3d && v3d->localvd) ? v3d->local_view_uuid : 0;
+      float loc[3], size[3], rot[3][3], eul[3];
+      mat4_to_loc_rot_size(loc, rot, size, ob->obmat);
+      mat3_to_eul(eul, rot);
+
+      gpencil_ob = ED_gpencil_add_object(C, loc, local_view_bits);
+      copy_v3_v3(gpencil_ob->loc, loc);
+      copy_v3_v3(gpencil_ob->rot, eul);
+      copy_v3_v3(gpencil_ob->scale, size);
+
+      BKE_gpencil_convert_mesh(bmain, depsgraph, scene, gpencil_ob, ob, false, true);
+      gpencilConverted = true;
+    }
     else if (ob->type == OB_MESH) {
       ob->flag |= OB_DONE;
 
@@ -2574,12 +2591,12 @@ static int convert_exec(bContext *C, wmOperator *op)
       }
       FOREACH_SCENE_OBJECT_END;
     }
-    /* Remove curves converted to Grease Pencil object. */
+    /* Remove curves and meshes converted to Grease Pencil object. */
     if (gpencilConverted) {
-      FOREACH_SCENE_OBJECT_BEGIN (scene, ob_curve) {
-        if (ob_curve->type == OB_CURVE) {
-          if (ob_curve->flag & OB_DONE) {
-            ED_object_base_free_and_unlink(bmain, scene, ob_curve);
+      FOREACH_SCENE_OBJECT_BEGIN (scene, ob_delete) {
+        if ((ob_delete->type == OB_CURVE) || (ob_delete->type == OB_MESH)) {
+          if (ob_delete->flag & OB_DONE) {
+            ED_object_base_free_and_unlink(bmain, scen

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list