GPencil: Add skip option to envelope modifier
This patch adds an option to only use every n-th segment of the envelope result. This can be used to reduce the complexity of the result. Differential Revision: http://developer.blender.org/D14503
This commit is contained in:
parent
1a09024eac
commit
f8c21937d2
|
@ -332,18 +332,17 @@ static void add_stroke(Object *ob,
|
|||
bGPDstroke *gps,
|
||||
const int point_index,
|
||||
const int connection_index,
|
||||
const int size,
|
||||
const int size2,
|
||||
const int size1,
|
||||
const int mat_nr,
|
||||
const float thickness,
|
||||
const float strength,
|
||||
ListBase *results)
|
||||
{
|
||||
const int size = size1 + size2;
|
||||
bGPdata *gpd = ob->data;
|
||||
bGPDstroke *gps_dst = BKE_gpencil_stroke_new(mat_nr, size, gps->thickness);
|
||||
|
||||
const int size1 = size == 4 ? 2 : 1;
|
||||
const int size2 = size - size1;
|
||||
|
||||
memcpy(&gps_dst->points[0], &gps->points[connection_index], size1 * sizeof(bGPDspoint));
|
||||
memcpy(&gps_dst->points[size1], &gps->points[point_index], size2 * sizeof(bGPDspoint));
|
||||
|
||||
|
@ -369,35 +368,36 @@ static void add_stroke_cyclic(Object *ob,
|
|||
bGPDstroke *gps,
|
||||
const int point_index,
|
||||
const int connection_index,
|
||||
const int size,
|
||||
const int mat_nr,
|
||||
const float thickness,
|
||||
const float strength,
|
||||
ListBase *results)
|
||||
{
|
||||
bGPdata *gpd = ob->data;
|
||||
bGPDstroke *gps_dst = BKE_gpencil_stroke_new(mat_nr, 4, gps->thickness);
|
||||
bGPDstroke *gps_dst = BKE_gpencil_stroke_new(mat_nr, size * 2, gps->thickness);
|
||||
if (gps->dvert != NULL) {
|
||||
gps_dst->dvert = MEM_malloc_arrayN(size * 2, sizeof(MDeformVert), __func__);
|
||||
}
|
||||
|
||||
int connection_index2 = (connection_index + 1) % gps->totpoints;
|
||||
int point_index2 = (point_index + 1) % gps->totpoints;
|
||||
for (int i = 0; i < size; i++) {
|
||||
int a = (connection_index + i) % gps->totpoints;
|
||||
int b = (point_index + i) % gps->totpoints;
|
||||
|
||||
gps_dst->points[0] = gps->points[connection_index];
|
||||
gps_dst->points[1] = gps->points[connection_index2];
|
||||
gps_dst->points[2] = gps->points[point_index];
|
||||
gps_dst->points[3] = gps->points[point_index2];
|
||||
for (int i = 0; i < 4; i++) {
|
||||
gps_dst->points[i] = gps->points[a];
|
||||
gps_dst->points[size + i] = gps->points[b];
|
||||
|
||||
if (gps->dvert != NULL) {
|
||||
BKE_defvert_array_copy(&gps_dst->dvert[i], &gps->dvert[a], 1);
|
||||
BKE_defvert_array_copy(&gps_dst->dvert[size + i], &gps->dvert[b], 1);
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < size * 2; i++) {
|
||||
gps_dst->points[i].pressure *= thickness;
|
||||
gps_dst->points[i].strength *= strength;
|
||||
memset(&gps_dst->points[i].runtime, 0, sizeof(bGPDspoint_Runtime));
|
||||
}
|
||||
|
||||
if (gps->dvert != NULL) {
|
||||
gps_dst->dvert = MEM_malloc_arrayN(4, sizeof(MDeformVert), __func__);
|
||||
BKE_defvert_array_copy(&gps_dst->dvert[0], &gps->dvert[connection_index], 1);
|
||||
BKE_defvert_array_copy(&gps_dst->dvert[1], &gps->dvert[connection_index2], 1);
|
||||
BKE_defvert_array_copy(&gps_dst->dvert[2], &gps->dvert[point_index], 1);
|
||||
BKE_defvert_array_copy(&gps_dst->dvert[3], &gps->dvert[point_index2], 1);
|
||||
}
|
||||
|
||||
BLI_addtail(results, gps_dst);
|
||||
|
||||
/* Calc geometry data. */
|
||||
|
@ -459,31 +459,41 @@ static void generate_geometry(GpencilModifierData *md, Object *ob, bGPDlayer *gp
|
|||
|
||||
const int mat_nr = mmd->mat_nr < 0 ? gps->mat_nr : min_ii(mmd->mat_nr, ob->totcol - 1);
|
||||
if (mmd->mode == GP_ENVELOPE_FILLS) {
|
||||
const int skip = min_ii(mmd->skip, min_ii(mmd->spread / 2, gps->totpoints - 2));
|
||||
if (gps->flag & GP_STROKE_CYCLIC) {
|
||||
for (int i = 0; i < gps->totpoints; i++) {
|
||||
const int connection_index = (i + mmd->spread) % gps->totpoints;
|
||||
add_stroke_cyclic(
|
||||
ob, gps, i, connection_index, mat_nr, mmd->thickness, mmd->strength, &duplicates);
|
||||
const int connection_index = (i + mmd->spread - skip) % gps->totpoints;
|
||||
add_stroke_cyclic(ob,
|
||||
gps,
|
||||
i,
|
||||
connection_index,
|
||||
2 + skip,
|
||||
mat_nr,
|
||||
mmd->thickness,
|
||||
mmd->strength,
|
||||
&duplicates);
|
||||
i += mmd->skip;
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (int i = 1; i < gps->totpoints - 1 && i < mmd->spread + 1; i++) {
|
||||
add_stroke(ob, gps, i, 0, 3, mat_nr, mmd->thickness, mmd->strength, &duplicates);
|
||||
}
|
||||
for (int i = 0; i < gps->totpoints - 1; i++) {
|
||||
const int connection_index = min_ii(i + mmd->spread, gps->totpoints - 1);
|
||||
const int size = i == gps->totpoints - 2 ? 2 :
|
||||
connection_index < gps->totpoints - 1 ? 4 :
|
||||
3;
|
||||
for (int i = -mmd->spread + skip; i < gps->totpoints - 1; i++) {
|
||||
const int point_index = max_ii(0, i);
|
||||
const int connection_index = min_ii(i + mmd->spread + 1, gps->totpoints - 1);
|
||||
const int size1 = min_ii(2 + skip,
|
||||
min_ii(point_index + 1, gps->totpoints - point_index));
|
||||
const int size2 = min_ii(
|
||||
2 + skip, min_ii(connection_index + 1, gps->totpoints - connection_index));
|
||||
add_stroke(ob,
|
||||
gps,
|
||||
i,
|
||||
connection_index,
|
||||
size,
|
||||
point_index,
|
||||
connection_index + 1 - size2,
|
||||
size1,
|
||||
size2,
|
||||
mat_nr,
|
||||
mmd->thickness,
|
||||
mmd->strength,
|
||||
&duplicates);
|
||||
i += mmd->skip;
|
||||
}
|
||||
}
|
||||
BLI_remlink(&gpf->strokes, gps);
|
||||
|
@ -496,6 +506,7 @@ static void generate_geometry(GpencilModifierData *md, Object *ob, bGPDlayer *gp
|
|||
const int connection_index = (i + 1 + mmd->spread) % gps->totpoints;
|
||||
add_stroke_simple(
|
||||
ob, gps, i, connection_index, mat_nr, mmd->thickness, mmd->strength, &duplicates);
|
||||
i += mmd->skip;
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
@ -509,6 +520,7 @@ static void generate_geometry(GpencilModifierData *md, Object *ob, bGPDlayer *gp
|
|||
mmd->thickness,
|
||||
mmd->strength,
|
||||
&duplicates);
|
||||
i += mmd->skip;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -585,6 +597,7 @@ static void panel_draw(const bContext *UNUSED(C), Panel *panel)
|
|||
if (mode != GP_ENVELOPE_DEFORM) {
|
||||
uiItemR(layout, ptr, "strength", 0, NULL, ICON_NONE);
|
||||
uiItemR(layout, ptr, "mat_nr", 0, NULL, ICON_NONE);
|
||||
uiItemR(layout, ptr, "skip", 0, NULL, ICON_NONE);
|
||||
}
|
||||
|
||||
gpencil_modifier_panel_end(layout, ptr);
|
||||
|
|
|
@ -373,6 +373,7 @@
|
|||
.mat_nr = -1, \
|
||||
.thickness = 1.0f, \
|
||||
.strength = 1.0f, \
|
||||
.skip = 0, \
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1168,10 +1168,14 @@ typedef struct EnvelopeGpencilModifierData {
|
|||
float thickness;
|
||||
/** Strength multiplier for the new strokes. */
|
||||
float strength;
|
||||
/** Number of points to skip over. */
|
||||
int skip;
|
||||
/** Custom index for passes. */
|
||||
int layer_pass;
|
||||
/* Length of the envelope effect. */
|
||||
int spread;
|
||||
|
||||
char _pad[4];
|
||||
} EnvelopeGpencilModifierData;
|
||||
|
||||
typedef enum eEnvelopeGpencil_Flag {
|
||||
|
|
|
@ -4126,6 +4126,13 @@ static void rna_def_modifier_gpencilenvelope(BlenderRNA *brna)
|
|||
RNA_def_property_ui_text(prop, "Strength", "Multiplier for the strength of the new strokes");
|
||||
RNA_def_property_update(prop, 0, "rna_GpencilModifier_update");
|
||||
|
||||
prop = RNA_def_property(srna, "skip", PROP_INT, PROP_NONE);
|
||||
RNA_def_property_int_sdna(prop, NULL, "skip");
|
||||
RNA_def_property_range(prop, 0, INT_MAX);
|
||||
RNA_def_property_ui_text(
|
||||
prop, "Skip Segments", "The number of generated segments to skip to reduce complexity");
|
||||
RNA_def_property_update(prop, 0, "rna_GpencilModifier_update");
|
||||
|
||||
prop = RNA_def_property(srna, "invert_layers", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_ENVELOPE_INVERT_LAYER);
|
||||
RNA_def_property_ui_text(prop, "Inverse Layers", "Inverse filter");
|
||||
|
|
Loading…
Reference in New Issue