Commit: cb312e3a3e149b72e8f2104885b8d1b38b4fea9b
Author: Antonio Vazquez
Date:   Wed Jul 19 12:23:34 2017 +0200
Branches: greasepencil-object
https://developer.blender.org/rBcb312e3a3e149b72e8f2104885b8d1b38b4fea9b

WIP: Initial implementation of array modifier

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

M       release/scripts/startup/bl_ui/properties_data_modifier.py
M       source/blender/blenkernel/BKE_gpencil.h
M       source/blender/blenkernel/intern/gpencil.c
M       source/blender/draw/engines/gpencil/gpencil_draw_cache_impl.c
M       source/blender/makesdna/DNA_gpencil_types.h
M       source/blender/makesdna/DNA_modifier_types.h
M       source/blender/makesrna/RNA_access.h
M       source/blender/makesrna/intern/rna_modifier.c
M       source/blender/modifiers/CMakeLists.txt
M       source/blender/modifiers/MOD_modifiertypes.h
A       source/blender/modifiers/intern/MOD_gpencilarray.c
M       source/blender/modifiers/intern/MOD_util.c

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

diff --git a/release/scripts/startup/bl_ui/properties_data_modifier.py 
b/release/scripts/startup/bl_ui/properties_data_modifier.py
index 6e56461481d..0597dc03418 100644
--- a/release/scripts/startup/bl_ui/properties_data_modifier.py
+++ b/release/scripts/startup/bl_ui/properties_data_modifier.py
@@ -1598,6 +1598,19 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel):
         row = layout.row()
         row.prop(md, "create_colors")
 
+    def GP_ARRAY(self, layout, ob, md):
+        gpd = ob.grease_pencil
+        layout.prop(md, "count")
+
+        split = layout.split()
+        col = split.column()
+        col.prop(md, "constant_offset_displace", text="")
+
+        col = split.column()
+        col.label("Layer:")
+        col.prop_search(md, "layer", gpd, "layers", text="", 
icon="GREASEPENCIL")
+        col.prop(md, "passindex", text="Pass")
+
 classes = (
     DATA_PT_modifiers,
 )
diff --git a/source/blender/blenkernel/BKE_gpencil.h 
b/source/blender/blenkernel/BKE_gpencil.h
index e3d3bb9bda2..7d74266d805 100644
--- a/source/blender/blenkernel/BKE_gpencil.h
+++ b/source/blender/blenkernel/BKE_gpencil.h
@@ -47,6 +47,7 @@ struct GpencilNoiseModifierData;
 struct GpencilSubdivModifierData;
 struct GpencilThickModifierData;
 struct GpencilTintModifierData;
+struct GpencilArrayModifierData;
 
 /* ------------ Grease-Pencil API ------------------ */
 
@@ -136,10 +137,11 @@ void BKE_gpencil_palettecolor_delete_allstrokes(struct 
PaletteColor *palcolor);
 struct BoundBox *BKE_gpencil_boundbox_get(struct Object *ob);
 
 /* modifiers */
-void ED_gpencil_stroke_modifiers(struct Object *ob, struct bGPDlayer *gpl, 
struct bGPDstroke *gps);
+void ED_gpencil_stroke_modifiers(struct Object *ob, struct bGPDlayer *gpl, 
struct bGPDframe *gpf, struct bGPDstroke *gps);
 void ED_gpencil_noise_modifier(struct GpencilNoiseModifierData *mmd, struct 
bGPDlayer *gpl, struct bGPDstroke *gps);
 void ED_gpencil_subdiv_modifier(struct GpencilSubdivModifierData *mmd, struct 
bGPDlayer *gpl, struct bGPDstroke *gps);
 void ED_gpencil_thick_modifier(struct GpencilThickModifierData *mmd, struct 
bGPDlayer *gpl, struct bGPDstroke *gps);
 void ED_gpencil_tint_modifier(struct GpencilTintModifierData *mmd, struct 
bGPDlayer *gpl, struct bGPDstroke *gps);
+void ED_gpencil_array_modifier(int id, struct GpencilArrayModifierData *mmd, 
struct bGPDlayer *gpl, struct bGPDframe *gpf, struct bGPDstroke *gps);
 
 #endif /*  __BKE_GPENCIL_H__ */
diff --git a/source/blender/blenkernel/intern/gpencil.c 
b/source/blender/blenkernel/intern/gpencil.c
index d928cc3d249..88b343ca4ed 100644
--- a/source/blender/blenkernel/intern/gpencil.c
+++ b/source/blender/blenkernel/intern/gpencil.c
@@ -1789,11 +1789,49 @@ void ED_gpencil_tint_modifier(GpencilTintModifierData 
*mmd, bGPDlayer *gpl, bGPD
        interp_v3_v3v3(gps->palcolor->fill, gps->palcolor->fill, mmd->rgb, 
mmd->factor);
 }
 
+/* array modifier */
+void ED_gpencil_array_modifier(int id, GpencilArrayModifierData *mmd, 
bGPDlayer *gpl, bGPDframe *gpf, bGPDstroke *gps)
+{
+       bGPDspoint *pt;
+       bGPDstroke *gps_dst, *old_gps;
+       float offset[3];
+
+       if (!is_stroke_affected_by_modifier(mmd->layername, mmd->passindex, 0, 
gpl, gps)) {
+               return;
+       }
+       /* if temp do not apply if was created by previous modifier to avoid 
infinite loop */
+       if (gps->flag & GP_STROKE_TEMP) {
+               if (gps->mod_idx <= id) {
+                       return;
+               }
+       }
+
+       old_gps = gps;
+       for (int e = 0; e < mmd->count; ++e) {
+               /* duplicate stroke */
+               gps_dst = MEM_dupallocN(gps);
+               gps_dst->flag |= GP_STROKE_TEMP;
+               gps_dst->points = MEM_dupallocN(gps->points);
+               gps_dst->triangles = MEM_dupallocN(gps->triangles);
+               gps_dst->mod_idx = id;
+
+               BLI_insertlinkafter(&gpf->strokes, old_gps, gps_dst);
+               old_gps = gps_dst;
+
+               mul_v3_v3fl(offset, mmd->offset, e + 1);
+               /* move points */
+               for (int i = 0; i < gps->totpoints; ++i) {
+                       pt = &gps_dst->points[i];
+                       add_v3_v3(&pt->x, offset);
+               }
+       }
+}
+
 /* apply stroke modifiers */
-void ED_gpencil_stroke_modifiers(Object *ob, bGPDlayer *gpl, bGPDstroke *gps)
+void ED_gpencil_stroke_modifiers(Object *ob, bGPDlayer *gpl, bGPDframe *gpf, 
bGPDstroke *gps)
 {
        ModifierData *md;
-
+       int id = 0;
        for (md = ob->modifiers.first; md; md = md->next) {
                if (((md->mode & eModifierMode_Realtime) && ((G.f & 
G_RENDER_OGL) == 0)) ||
                        ((md->mode & eModifierMode_Render) && (G.f & 
G_RENDER_OGL))) {
@@ -1814,9 +1852,14 @@ void ED_gpencil_stroke_modifiers(Object *ob, bGPDlayer 
*gpl, bGPDstroke *gps)
                        case eModifierType_GpencilTint:
                                
ED_gpencil_tint_modifier((GpencilTintModifierData *)md, gpl, gps);
                                break;
+                               // Tint
+                       case eModifierType_GpencilArray:
+                               ED_gpencil_array_modifier(id, 
(GpencilArrayModifierData *)md, gpl, gpf, gps);
+                               break;
                        default:
                                break;
                        }
                }
+               ++id;
        }
 }
diff --git a/source/blender/draw/engines/gpencil/gpencil_draw_cache_impl.c 
b/source/blender/draw/engines/gpencil/gpencil_draw_cache_impl.c
index dca090f1f73..630635592c8 100644
--- a/source/blender/draw/engines/gpencil/gpencil_draw_cache_impl.c
+++ b/source/blender/draw/engines/gpencil/gpencil_draw_cache_impl.c
@@ -564,10 +564,9 @@ static void gpencil_draw_strokes(GpencilBatchCache *cache, 
GPENCIL_e_data *e_dat
 
        DRWShadingGroup *fillgrp;
        DRWShadingGroup *strokegrp;
-       bGPDstroke *gps_mod;
        float viewmatrix[4][4];
-       bool is_edit = (bool)(gpd->flag & (GP_DATA_STROKE_EDITMODE | 
GP_DATA_STROKE_SCULPTMODE));
-       bool is_mod = false;
+       bool is_edit = (bool)((gpd->flag & (GP_DATA_STROKE_EDITMODE | 
GP_DATA_STROKE_SCULPTMODE)) || (onion));
+       ListBase tmp_colors = { NULL, NULL };
 
        /* get parent matrix and save as static data */
        ED_gpencil_parent_location(ob, gpd, gpl, viewmatrix);
@@ -612,39 +611,29 @@ static void gpencil_draw_strokes(GpencilBatchCache 
*cache, GPENCIL_e_data *e_dat
                strokegrp = stl->shgroups[id].shgrps_stroke;
 
                /* apply modifiers */
-               if ((cache->is_dirty) && (ob->modifiers.first) && (!is_edit)) {
-                       gps_mod = MEM_dupallocN(gps);
-                       gps_mod->points = MEM_dupallocN(gps->points);
-                       gps_mod->triangles = MEM_dupallocN(gps->triangles);
-                       gps_mod->palcolor = MEM_dupallocN(gps->palcolor);
-                       ED_gpencil_stroke_modifiers(ob, gpl, gps_mod);
-                       is_mod = true;
-               }
-               else {
-                       gps_mod = gps;
-                       is_mod = false;
+               if ((ob->modifiers.first) && (!is_edit)) {
+                       PaletteColor *newpalcolor = 
MEM_dupallocN(gps->palcolor);
+                       if (newpalcolor) {
+                               gps->palcolor = newpalcolor;
+                               BLI_addtail(&tmp_colors, gps->palcolor);
+                       }
+                       ED_gpencil_stroke_modifiers(ob, gpl, gpf, gps);
                }
                /* fill */
                if (fillgrp) {
-                       gpencil_add_fill_shgroup(cache, fillgrp, gpd, gpl, gpf, 
gps_mod, tintcolor, onion, custonion);
+                       gpencil_add_fill_shgroup(cache, fillgrp, gpd, gpl, gpf, 
gps, tintcolor, onion, custonion);
                }
                /* stroke */
-               gpencil_add_stroke_shgroup(cache, strokegrp, ob, gpd, gpl, gpf, 
gps_mod, opacity, tintcolor, onion, custonion);
+               gpencil_add_stroke_shgroup(cache, strokegrp, ob, gpd, gpl, gpf, 
gps, opacity, tintcolor, onion, custonion);
 
                /* edit points (only in edit mode) */
                if (!onion) {
                        gpencil_add_editpoints_shgroup(stl, cache, ts, ob, gpd, 
gpl, gpf, gps);
                }
-               /* free modifier temp data */
-               if (is_mod) {
-                       MEM_SAFE_FREE(gps_mod->triangles);
-                       MEM_SAFE_FREE(gps_mod->points);
-                       MEM_SAFE_FREE(gps_mod->palcolor);
-                       MEM_SAFE_FREE(gps_mod);
-               }
-
                ++cache->cache_idx;
        }
+       /* free modifier temp data */
+       BLI_freelistN(&tmp_colors);
 }
 
  /* draw stroke in drawing buffer */
@@ -767,6 +756,10 @@ static void gpencil_draw_onionskins(GpencilBatchCache 
*cache, GPENCIL_e_data *e_
 /* helper for populate a complete grease pencil datablock */
 void DRW_gpencil_populate_datablock(GPENCIL_e_data *e_data, void *vedata, 
Scene *scene, Object *ob, ToolSettings *ts, bGPdata *gpd)
 {
+       bGPDframe *temp_gpf = NULL;
+       bool is_edit = (bool)(gpd->flag & (GP_DATA_STROKE_EDITMODE | 
GP_DATA_STROKE_SCULPTMODE));
+       bool is_mod = false;
+
        if (G.debug_value == 668) {
                printf("DRW_gpencil_populate_datablock: %s\n", gpd->id.name);
        }
@@ -782,13 +775,28 @@ void DRW_gpencil_populate_datablock(GPENCIL_e_data 
*e_data, void *vedata, Scene
                bGPDframe *gpf = BKE_gpencil_layer_getframe(gpl, CFRA, 0);
                if (gpf == NULL)
                        continue;
+               if ((ob->modifiers.first) && (!is_edit)) {
+                       temp_gpf = BKE_gpencil_frame_duplicate(gpf);
+                       is_mod = true;
+               }
+               else {
+                       temp_gpf = gpf; 
+                       is_mod = false;
+               }
+               
                /* draw onion skins */
                if ((gpl->flag & GP_LAYER_ONIONSKIN) || (gpl->flag & 
GP_LAYER_GHOST_ALWAYS))
                {
-                       gpencil_draw_onionskins(cache, e_data, vedata, ts, ob, 
gpd, gpl, gpf);
+                       gpencil_draw_onionskins(cache, e_data, vedata, ts, ob, 
gpd, gpl, temp_gpf);
                }
                /* draw normal strokes */
-               gpencil_draw_strokes(cache, e_data, vedata, ts, ob, gpd, gpl, 
gpf, gpl->opacity, gpl->tintcolor, false, false);
+               gpencil_draw_strokes(cache, e_data, vedata, ts, ob, gpd, gpl, 
temp_gpf, gpl->opacity, gpl->tintcolor, false, false);
+               
+               /* free temp_gpf*/
+               if (is_mod) {
+                       BKE_gpencil_free_strokes(temp_gpf);
+                       MEM_SAFE_FREE(temp_gpf);
+               }
        }
        cache->is_dirty = false;
 }
diff --git a/source/blender/makesdna/DNA_gpencil_types.h 
b/source/blender/makesdna/DNA_gpencil_types.h
index e95fe848411..6b2ab7d95b7 100644
--- a/source/blender/makesdna/DNA_gpencil_types.h
+++ b/source/blender/makesdna/DNA_gpencil_types.h
@@ -180,6 +180,8 @@ typedef struct bGPDstroke {
        PaletteColor *palcolor; /* current palette color */
        /* temporary layer name only used during copy/paste to put the stroke 
in the original layer */
        char tmp_layerinfo[128];
+       int mod_idx;            /* index of modifier for temp strokes */
+       char pad2[4];
 } bGPDstroke;
 
 /* bGPDstroke->flag */
@@ -198,6 +200,8 @@ typedef enum eGPDstroke_Flag {
        GP_STROKE_RECALC_COLOR = (1 << 5),
        /* Flag used to indicate that stroke is closed and draw edge between 
last and first point */
        GP_STROKE_CYCLIC = (1 << 7),
+       /* Flag used to indicate that stroke was created by modifier and is 
temp */
+       GP_STROKE_TEMP = (1 << 8),
        /* only for use with stroke-buffer (while drawing eraser) */
        GP_STROKE_ERASER                = (1 << 15)
 } eGPDstroke_Flag;
diff --git a/source/blender/makesdna/DNA_modifier_types.h 
b/source/blender/makesdna/DNA_modifier_types.h
index 1d3a50742f9..3d0513af56f 100644
--- a/

@@ Diff output truncated at 10240 characters. @@

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
https://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to