[Bf-blender-cvs] [2b1056183c8] greasepencil-object: WIP: More work on modifiers
Antonio Vazquez
noreply at git.blender.org
Fri Jul 21 09:29:35 CEST 2017
Commit: 2b1056183c8b38379ae3ebd6f9fdf974cfd6d38c
Author: Antonio Vazquez
Date: Fri Jul 21 09:29:04 2017 +0200
Branches: greasepencil-object
https://developer.blender.org/rB2b1056183c8b38379ae3ebd6f9fdf974cfd6d38c
WIP: More work on modifiers
Reorganize the system to create new strokes in 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/intern/rna_modifier.c
M source/blender/modifiers/intern/MOD_gpencilarray.c
===================================================================
diff --git a/release/scripts/startup/bl_ui/properties_data_modifier.py b/release/scripts/startup/bl_ui/properties_data_modifier.py
index 3a048768a3c..071269967f0 100644
--- a/release/scripts/startup/bl_ui/properties_data_modifier.py
+++ b/release/scripts/startup/bl_ui/properties_data_modifier.py
@@ -1636,10 +1636,18 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel):
col = split.column()
col.label("Rotation:")
col.prop(md, "rotation", text="")
+ col.separator()
+ row = col.row(align=True)
+ row.prop(md, "random_rot", text="", icon="TIME", toggle=True)
+ row.prop(md, "rot_factor", text="")
col = split.column()
col.label("Scale:")
col.prop(md, "scale", text="")
+ col.separator()
+ row = col.row(align=True)
+ row.prop(md, "random_scale", text="", icon="TIME", toggle=True)
+ row.prop(md, "scale_factor", text="")
classes = (
DATA_PT_modifiers,
diff --git a/source/blender/blenkernel/BKE_gpencil.h b/source/blender/blenkernel/BKE_gpencil.h
index 9b81649c858..f26ea602791 100644
--- a/source/blender/blenkernel/BKE_gpencil.h
+++ b/source/blender/blenkernel/BKE_gpencil.h
@@ -49,9 +49,6 @@ struct GpencilThickModifierData;
struct GpencilTintModifierData;
struct GpencilArrayModifierData;
-#define GP_MOD_DUPLI_ON 1
-#define GP_MOD_DUPLI_OFF 0
-
/* ------------ Grease-Pencil API ------------------ */
void BKE_gpencil_free_stroke(struct bGPDstroke *gps);
@@ -142,12 +139,16 @@ 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 bGPDframe *gpf, struct bGPDstroke *gps, int duplimode);
+void ED_gpencil_reset_modifiers(struct Object *ob);
+bool ED_gpencil_has_geometry_modifiers(struct Object *ob);
+void ED_gpencil_stroke_modifiers(struct Object *ob, struct bGPDlayer *gpl, struct bGPDframe *gpf, struct bGPDstroke *gps);
+void ED_gpencil_geometry_modifiers(struct Object *ob, struct bGPDlayer *gpl, struct bGPDframe *gpf);
+void ED_gpencil_fill_random_array(float *ar, int count);
void ED_gpencil_stroke_normal(const struct bGPDstroke *gps, float r_normal[3]);
void ED_gpencil_noise_modifier(int id, struct GpencilNoiseModifierData *mmd, struct bGPDlayer *gpl, struct bGPDstroke *gps);
void ED_gpencil_subdiv_modifier(int id, struct GpencilSubdivModifierData *mmd, struct bGPDlayer *gpl, struct bGPDstroke *gps);
void ED_gpencil_thick_modifier(int id, struct GpencilThickModifierData *mmd, struct bGPDlayer *gpl, struct bGPDstroke *gps);
void ED_gpencil_tint_modifier(int id, 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);
+void ED_gpencil_array_modifier(int id, struct GpencilArrayModifierData *mmd, struct bGPDlayer *gpl, struct bGPDframe *gpf);
#endif /* __BKE_GPENCIL_H__ */
diff --git a/source/blender/blenkernel/intern/gpencil.c b/source/blender/blenkernel/intern/gpencil.c
index 6a335aeef43..591910ab33e 100644
--- a/source/blender/blenkernel/intern/gpencil.c
+++ b/source/blender/blenkernel/intern/gpencil.c
@@ -60,8 +60,11 @@
#include "BKE_main.h"
#include "BKE_object.h"
-#define GP_MOD_DUPLI_ON 1
-#define GP_MOD_DUPLI_OFF 0
+ /* used to save gpencil objects */
+typedef struct tGPencilStrokeCache {
+ struct bGPDstroke *gps;
+ int idx;
+} tGPencilStrokeCache;
/* Draw Engine */
void(*BKE_gpencil_batch_cache_dirty_cb)(bGPdata *gpd) = NULL;
@@ -1599,6 +1602,13 @@ BoundBox *BKE_gpencil_boundbox_get(Object *ob)
}
/******************** Modifiers **********************************/
+void ED_gpencil_fill_random_array(float *ar, int count)
+{
+ for (int i = 0; i < count; ++i) {
+ ar[i] = BLI_frand();
+ }
+}
+
/* verify if valid layer and pass index */
static bool is_stroke_affected_by_modifier(char *mlayername, int mpassindex, int minpoints,
bGPDlayer *gpl, bGPDstroke *gps, int inv1, int inv2)
@@ -1882,91 +1892,182 @@ void ED_gpencil_tint_modifier(int UNUSED(id), GpencilTintModifierData *mmd, bGPD
interp_v3_v3v3(gps->palcolor->fill, gps->palcolor->fill, mmd->rgb, mmd->factor);
}
+/* helper function to sort strokes using qsort */
+static int gpencil_stroke_cache_compare(const void *a1, const void *a2)
+{
+ const tGPencilStrokeCache *ps1 = a1, *ps2 = a2;
+
+ if (ps1->idx < ps2->idx) return -1;
+ else if (ps1->idx > ps2->idx) return 1;
+
+ return 0;
+}
+
/* array modifier */
-void ED_gpencil_array_modifier(int id, GpencilArrayModifierData *mmd, bGPDlayer *gpl, bGPDframe *gpf, bGPDstroke *gps)
+void ED_gpencil_array_modifier(int id, GpencilArrayModifierData *mmd, bGPDlayer *gpl, bGPDframe *gpf)
{
bGPDspoint *pt;
- bGPDstroke *gps_dst, *old_gps;
- float offset[3], zerov3[3];
+ bGPDstroke *gps_dst;
+ struct tGPencilStrokeCache *stroke_cache, *p = NULL;
+ float offset[3], zerov3[3], rot[3], scale[3];
float mat[4][4];
+ float factor;
+ int ri;
zero_v3(zerov3);
-
- if (!is_stroke_affected_by_modifier(mmd->layername, mmd->passindex, 3, gpl, gps,
- (int)mmd->flag & GP_ARRAY_INVERSE_LAYER, (int)mmd->flag & GP_ARRAY_INVERSE_PASS)) {
+ /* create cache for sorting */
+ int totstrokes = BLI_listbase_count(&gpf->strokes);
+ int cachesize = totstrokes * mmd->count;
+ p = MEM_callocN(sizeof(struct tGPencilStrokeCache) * cachesize, "tGPencilStrokeCache");
+ if (p) {
+ stroke_cache = p;
+ }
+ else {
return;
}
- /* if temp do not apply if modifier is before current */
- if (gps->flag & GP_STROKE_TEMP) {
- if (gps->mod_idx <= id) {
- return;
+ int stroke = 0;
+ int idx = 0;
+ for (bGPDstroke *gps = gpf->strokes.first; gps; gps = gps->next) {
+ ++stroke;
+ if (!is_stroke_affected_by_modifier(mmd->layername, mmd->passindex, 3, gpl, gps,
+ (int)mmd->flag & GP_ARRAY_INVERSE_LAYER, (int)mmd->flag & GP_ARRAY_INVERSE_PASS)) {
+ continue;
+ }
+
+ for (int e = 0; e < mmd->count; ++e) {
+ /* duplicate stroke */
+ gps_dst = MEM_dupallocN(gps);
+ if (id > -1) {
+ gps_dst->palcolor = MEM_dupallocN(gps->palcolor);
+ }
+ gps_dst->points = MEM_dupallocN(gps->points);
+ gps_dst->triangles = MEM_dupallocN(gps->triangles);
+
+ /* add to array for sorting later */
+ stroke_cache[idx].gps = gps_dst;
+ stroke_cache[idx].idx = (e * 100000) + stroke;
+
+ mul_v3_v3fl(offset, mmd->offset, e + 1);
+ ri = mmd->rnd[0];
+ /* rotation */
+ if (mmd->flag & GP_ARRAY_RANDOM_ROT) {
+ factor = mmd->rnd_rot * mmd->rnd[ri];
+ mul_v3_v3fl(rot, mmd->rot, factor);
+ add_v3_v3(rot, mmd->rot);
+ }
+ else {
+ copy_v3_v3(rot, mmd->rot);
+ }
+ /* scale */
+ if (mmd->flag & GP_ARRAY_RANDOM_SIZE) {
+ factor = mmd->rnd_size * mmd->rnd[ri];
+ mul_v3_v3fl(scale, mmd->scale, factor);
+ add_v3_v3(scale, mmd->scale);
+ }
+ else {
+ copy_v3_v3(scale, mmd->scale);
+ }
+ /* move random index */
+ ++mmd->rnd[0];
+ if (mmd->rnd[0] > 19) {
+ mmd->rnd[0] = 1;
+ }
+
+ loc_eul_size_to_mat4(mat, zerov3, rot, scale);
+
+ /* move points */
+ for (int i = 0; i < gps->totpoints; ++i) {
+ pt = &gps_dst->points[i];
+ mul_m4_v3(mat, &pt->x);
+ add_v3_v3(&pt->x, offset);
+ }
+ ++idx;
}
}
+ /* sort by idx */
+ qsort(stroke_cache, idx, sizeof(tGPencilStrokeCache), gpencil_stroke_cache_compare);
+
+ /* add to listbase */
+ for (int i = 0; i < idx; ++i)
+ {
+ BLI_addtail(&gpf->strokes, stroke_cache[i].gps);
+ }
- old_gps = gps;
+ /* free memory */
+ MEM_SAFE_FREE(stroke_cache);
+}
- for (int e = 0; e < mmd->count; ++e) {
- /* duplicate stroke */
- gps_dst = MEM_dupallocN(gps);
- if (id > -1) {
- gps_dst->palcolor = MEM_dupallocN(gps->palcolor);
+/* reset modifiers */
+void ED_gpencil_reset_modifiers(Object *ob)
+{
+ ModifierData *md;
+ GpencilArrayModifierData *arr;
+
+ for (md = ob->modifiers.first; md; md = md->next) {
+ switch (md->type) {
+ case eModifierType_GpencilArray:
+ arr = (GpencilArrayModifierData *) md;
+ arr->rnd[0] = 1;
+ break;
}
- gps_dst->points = MEM_dupallocN(gps->points);
- gps_dst->triangles = MEM_dupallocN(gps->triangles);
- gps_dst->flag |= GP_STROKE_TEMP;
- 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);
- loc_eul_size_to_mat4(mat, zerov3, mmd->rot, mmd->scale);
-
- /* move points */
- for (int i = 0; i < gps->totpoints; ++i) {
- pt = &gps_dst->points[i];
- mul_m4_v3(mat, &pt->x);
- add_v3_v3(&pt->x, offset);
+ }
+}
+
+/* verify if exist geometry modifiers */
+bool ED_gpencil_has_geometry_modifiers(Object *ob)
+{
+ ModifierData *md;
+ for (md = ob->modifiers.first; md; md = md->next) {
+ if (md->type == eModifierType_GpencilArray) {
+ return true;
}
}
+ return false;
}
/* apply stroke modifiers */
-void ED_gpencil_stroke_modifiers(Object *ob, bGPDlayer *gpl, bGPDframe *gpf, bGPDstroke *gps, int duplimode)
+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))) {
- switch (duplimode) {
- case GP_MOD_DUPLI_OFF:
- switch (md->type) {
- // Noise Modifier
- case eModifierType_GpencilNoise:
- ED_gpencil_noise_modifier(id, (GpencilNoiseModifierData *)md, gpl, gps);
- break;
- // Subdiv Modifier
- case eModifierType_GpencilSubdiv:
- ED_gpencil_subdiv_modifier(id, (GpencilSubdivModifierData *)md, gpl, gps);
- break;
- // Thickness
- case eModifierType_GpencilThick:
- ED_gpencil_thick_modifier(id, (GpencilThickModifierData *)md, gpl, gps);
- break;
- // Tint
- case eModifierType_GpencilTint:
- ED_gpencil_tint_modifier(id, (GpencilTintModifierData *)md, gpl, gps);
- break;
- }
+ switch (md->type) {
+ // Noise Modifier
+ case eModifierType_GpencilNoise:
+ ED_gpencil_noise_modifier(id, (GpencilNoiseModifierData *)md
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list