Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/gpencil_modifiers/intern/MOD_gpencilmultiply.c')
-rw-r--r--source/blender/gpencil_modifiers/intern/MOD_gpencilmultiply.c148
1 files changed, 62 insertions, 86 deletions
diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpencilmultiply.c b/source/blender/gpencil_modifiers/intern/MOD_gpencilmultiply.c
index 919dbf91862..16b0c4a5e38 100644
--- a/source/blender/gpencil_modifiers/intern/MOD_gpencilmultiply.c
+++ b/source/blender/gpencil_modifiers/intern/MOD_gpencilmultiply.c
@@ -66,7 +66,10 @@ static void initData(GpencilModifierData *md)
MultiplyGpencilModifierData *mmd = (MultiplyGpencilModifierData *)md;
mmd->duplications = 3;
mmd->distance = 0.1f;
- mmd->split_angle = 1.0f;
+ mmd->split_angle = DEG2RADF(1.0f);
+ mmd->fading_center = 0.5f;
+ mmd->fading_thickness = 0.5f;
+ mmd->fading_opacity = 0.5f;
}
static void copyData(const GpencilModifierData *md, GpencilModifierData *target)
@@ -74,60 +77,39 @@ static void copyData(const GpencilModifierData *md, GpencilModifierData *target)
BKE_gpencil_modifier_copyData_generic(md, target);
}
-static void splitStroke(bGPDframe *gpf, bGPDstroke *gps, float split_angle)
-{
- bGPDspoint *pt = gps->points;
- bGPDstroke *new_gps = gps;
- int i;
- volatile float angle;
-
- if (split_angle <= FLT_EPSILON) {
- return;
- }
-
- for (i = 1; i < new_gps->totpoints - 1; i++) {
- angle = angle_v3v3v3(&pt[i - 1].x, &pt[i].x, &pt[i + 1].x);
- if (angle < split_angle) {
- if (BKE_gpencil_split_stroke(gpf, new_gps, i, &new_gps)) {
- pt = new_gps->points;
- i = 0;
- continue; /* then i == 1 again */
- }
- }
- }
-}
-
static void minter_v3_v3v3v3_ref(
- float *result, float *left, float *middle, float *right, float *stroke_normal)
+ float *result, float *prev, float *curr, float *next, float *stroke_normal)
{
- float left_arm[3], right_arm[3], inter1[3], inter2[3];
+ float vec[3], inter1[3], inter2[3];
+ ARRAY_SET_ITEMS(inter1, 0.0f, 0.0f, 0.0f);
+ ARRAY_SET_ITEMS(inter2, 0.0f, 0.0f, 0.0f);
+
float minter[3];
- if (left) {
- sub_v3_v3v3(left_arm, middle, left);
- cross_v3_v3v3(inter1, stroke_normal, left_arm);
+ if (prev) {
+ sub_v3_v3v3(vec, curr, prev);
+ cross_v3_v3v3(inter1, stroke_normal, vec);
}
- if (right) {
- sub_v3_v3v3(right_arm, right, middle);
- cross_v3_v3v3(inter2, stroke_normal, right_arm);
+ if (next) {
+ sub_v3_v3v3(vec, next, curr);
+ cross_v3_v3v3(inter2, stroke_normal, vec);
}
- if (!left) {
+ if (!prev) {
normalize_v3(inter2);
copy_v3_v3(result, inter2);
return;
}
-
- if (!right) {
+ if (!next) {
normalize_v3(inter1);
copy_v3_v3(result, inter1);
return;
}
-
interp_v3_v3v3(minter, inter1, inter2, 0.5);
normalize_v3(minter);
copy_v3_v3(result, minter);
}
-static void duplicateStroke(bGPDstroke *gps,
+static void duplicateStroke(Object *ob,
+ bGPDstroke *gps,
int count,
float dist,
float offset,
@@ -138,14 +120,15 @@ static void duplicateStroke(bGPDstroke *gps,
float fading_opacity)
{
int i;
- bGPDstroke *new_gps;
+ bGPDstroke *new_gps = NULL;
float stroke_normal[3];
- float minter[3];
bGPDspoint *pt;
- float offset_factor;
float thickness_factor;
float opacity_factor;
+ /* Apply object scale to offset distance. */
+ offset *= mat4_to_scale(ob->obmat);
+
BKE_gpencil_stroke_normal(gps, stroke_normal);
if (len_v3(stroke_normal) < FLT_EPSILON) {
add_v3_fl(stroke_normal, 1);
@@ -160,6 +143,7 @@ static void duplicateStroke(bGPDstroke *gps,
pt = gps->points;
for (int j = 0; j < gps->totpoints; j++) {
+ float minter[3];
if (j == 0) {
minter_v3_v3v3v3_ref(minter, NULL, &pt[j].x, &pt[j + 1].x, stroke_normal);
}
@@ -174,11 +158,11 @@ static void duplicateStroke(bGPDstroke *gps,
sub_v3_v3v3(&t2_array[j * 3], &pt[j].x, minter);
}
- /* This ensures the original stroke is the last one to be processed. */
+ /* This ensures the original stroke is the last one
+ * to be processed, since we duplicate its data. */
for (i = count - 1; i >= 0; i--) {
if (i != 0) {
- new_gps = BKE_gpencil_stroke_duplicate(gps);
- new_gps->flag |= GP_STROKE_RECALC_GEOMETRY;
+ new_gps = BKE_gpencil_stroke_duplicate(gps, true);
BLI_addtail(results, new_gps);
}
else {
@@ -187,34 +171,26 @@ static void duplicateStroke(bGPDstroke *gps,
pt = new_gps->points;
- if (count == 1) {
- offset_factor = 0;
- }
- else {
- offset_factor = (float)i / (float)(count - 1);
- }
+ float offset_fac = (count == 1) ? 0.5f : (i / (float)(count - 1));
if (fading) {
- thickness_factor = (offset_factor > fading_center) ?
- (interpf(1 - fading_thickness, 1.0f, offset_factor - fading_center)) :
- (interpf(
- 1.0f, 1 - fading_thickness, offset_factor - fading_center + 1));
- opacity_factor = (offset_factor > fading_center) ?
- (interpf(1 - fading_opacity, 1.0f, offset_factor - fading_center)) :
- (interpf(1.0f, 1 - fading_opacity, offset_factor - fading_center + 1));
+ thickness_factor = interpf(1.0f - fading_thickness, 1.0f, fabsf(offset_fac - fading_center));
+ opacity_factor = interpf(1.0f - fading_opacity, 1.0f, fabsf(offset_fac - fading_center));
}
for (int j = 0; j < new_gps->totpoints; j++) {
- interp_v3_v3v3(&pt[j].x,
- &t1_array[j * 3],
- &t2_array[j * 3],
- interpf(1 + offset, offset, offset_factor));
+ float fac = interpf(1 + offset, offset, offset_fac);
+ interp_v3_v3v3(&pt[j].x, &t1_array[j * 3], &t2_array[j * 3], fac);
if (fading) {
pt[j].pressure = gps->points[j].pressure * thickness_factor;
pt[j].strength = gps->points[j].strength * opacity_factor;
}
}
}
+ /* Calc geometry data. */
+ if (new_gps != NULL) {
+ BKE_gpencil_stroke_geometry_update(new_gps);
+ }
MEM_freeN(t1_array);
MEM_freeN(t2_array);
}
@@ -224,11 +200,10 @@ static void bakeModifier(Main *UNUSED(bmain),
GpencilModifierData *md,
Object *ob)
{
-
bGPdata *gpd = ob->data;
- for (bGPDlayer *gpl = gpd->layers.first; gpl; gpl = gpl->next) {
- for (bGPDframe *gpf = gpl->frames.first; gpf; gpf = gpf->next) {
+ LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) {
+ LISTBASE_FOREACH (bGPDframe *, gpf, &gpl->frames) {
ListBase duplicates = {0};
MultiplyGpencilModifierData *mmd = (MultiplyGpencilModifierData *)md;
bGPDstroke *gps;
@@ -247,11 +222,9 @@ static void bakeModifier(Main *UNUSED(bmain),
mmd->flag & GP_MIRROR_INVERT_MATERIAL)) {
continue;
}
- if (mmd->flags & GP_MULTIPLY_ENABLE_ANGLE_SPLITTING) {
- splitStroke(gpf, gps, mmd->split_angle);
- }
if (mmd->duplications > 0) {
- duplicateStroke(gps,
+ duplicateStroke(ob,
+ gps,
mmd->duplications,
mmd->distance,
mmd->offset,
@@ -262,23 +235,15 @@ static void bakeModifier(Main *UNUSED(bmain),
mmd->fading_opacity);
}
}
- if (duplicates.first) {
- ((bGPDstroke *)gpf->strokes.last)->next = duplicates.first;
- ((bGPDstroke *)duplicates.first)->prev = gpf->strokes.last;
- gpf->strokes.last = duplicates.first;
+ if (!BLI_listbase_is_empty(&duplicates)) {
+ BLI_movelisttolist(&gpf->strokes, &duplicates);
}
}
}
}
/* -------------------------------- */
-
-/* Generic "generateStrokes" callback */
-static void generateStrokes(GpencilModifierData *md,
- Depsgraph *UNUSED(depsgraph),
- Object *ob,
- bGPDlayer *gpl,
- bGPDframe *gpf)
+static void generate_geometry(GpencilModifierData *md, Object *ob, bGPDlayer *gpl, bGPDframe *gpf)
{
MultiplyGpencilModifierData *mmd = (MultiplyGpencilModifierData *)md;
bGPDstroke *gps;
@@ -298,11 +263,9 @@ static void generateStrokes(GpencilModifierData *md,
mmd->flag & GP_MIRROR_INVERT_MATERIAL)) {
continue;
}
- if (mmd->flags & GP_MULTIPLY_ENABLE_ANGLE_SPLITTING) {
- splitStroke(gpf, gps, mmd->split_angle);
- }
if (mmd->duplications > 0) {
- duplicateStroke(gps,
+ duplicateStroke(ob,
+ gps,
mmd->duplications,
mmd->distance,
mmd->offset,
@@ -313,10 +276,23 @@ static void generateStrokes(GpencilModifierData *md,
mmd->fading_opacity);
}
}
- if (duplicates.first) {
- ((bGPDstroke *)gpf->strokes.last)->next = duplicates.first;
- ((bGPDstroke *)duplicates.first)->prev = gpf->strokes.last;
- gpf->strokes.last = duplicates.first;
+ if (!BLI_listbase_is_empty(&duplicates)) {
+ BLI_movelisttolist(&gpf->strokes, &duplicates);
+ }
+}
+
+/* Generic "generateStrokes" callback */
+static void generateStrokes(GpencilModifierData *md, Depsgraph *depsgraph, Object *ob)
+{
+ Scene *scene = DEG_get_evaluated_scene(depsgraph);
+ bGPdata *gpd = (bGPdata *)ob->data;
+
+ LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) {
+ bGPDframe *gpf = BKE_gpencil_frame_retime_get(depsgraph, scene, ob, gpl);
+ if (gpf == NULL) {
+ continue;
+ }
+ generate_geometry(md, ob, gpl, gpf);
}
}