Blender  V3.3
MOD_gpenciltint.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later
2  * Copyright 2017 Blender Foundation. */
3 
8 #include <stdio.h>
9 
10 #include "BLI_utildefines.h"
11 
12 #include "BLI_listbase.h"
13 #include "BLI_math_vector.h"
14 
15 #include "BLT_translation.h"
16 
17 #include "DNA_defaults.h"
19 #include "DNA_gpencil_types.h"
20 #include "DNA_material_types.h"
21 #include "DNA_meshdata_types.h"
22 #include "DNA_modifier_types.h"
23 #include "DNA_object_types.h"
24 #include "DNA_scene_types.h"
25 #include "DNA_screen_types.h"
26 
27 #include "BKE_colorband.h"
28 #include "BKE_colortools.h"
29 #include "BKE_context.h"
30 #include "BKE_deform.h"
31 #include "BKE_gpencil_modifier.h"
32 #include "BKE_lib_query.h"
33 #include "BKE_main.h"
34 #include "BKE_material.h"
35 #include "BKE_modifier.h"
36 #include "BKE_scene.h"
37 #include "BKE_screen.h"
38 
39 #include "MEM_guardedalloc.h"
40 
41 #include "UI_interface.h"
42 #include "UI_resources.h"
43 
44 #include "RNA_access.h"
45 
47 #include "MOD_gpencil_ui_common.h"
48 #include "MOD_gpencil_util.h"
49 
50 #include "DEG_depsgraph.h"
51 #include "DEG_depsgraph_build.h"
52 
53 static void initData(GpencilModifierData *md)
54 {
56 
57  BLI_assert(MEMCMP_STRUCT_AFTER_IS_ZERO(gpmd, modifier));
58 
60 
61  /* Add default color ramp. */
62  gpmd->colorband = BKE_colorband_add(false);
63  if (gpmd->colorband) {
64  BKE_colorband_init(gpmd->colorband, true);
65  CBData *ramp = gpmd->colorband->data;
66  ramp[0].r = ramp[0].g = ramp[0].b = ramp[0].a = 1.0f;
67  ramp[0].pos = 0.0f;
68  ramp[1].r = ramp[1].g = ramp[1].b = 0.0f;
69  ramp[1].a = 1.0f;
70  ramp[1].pos = 1.0f;
71 
72  gpmd->colorband->tot = 2;
73  }
74 
75  gpmd->curve_intensity = BKE_curvemapping_add(1, 0.0f, 0.0f, 1.0f, 1.0f);
77 }
78 
79 static void copyData(const GpencilModifierData *md, GpencilModifierData *target)
80 {
83 
84  MEM_SAFE_FREE(tgmd->colorband);
85 
86  if (tgmd->curve_intensity != NULL) {
88  tgmd->curve_intensity = NULL;
89  }
90 
92 
93  if (gmd->colorband) {
94  tgmd->colorband = MEM_dupallocN(gmd->colorband);
95  }
96 
98 }
99 
100 /* deform stroke */
103  Object *ob,
104  bGPDlayer *gpl,
105  bGPDframe *UNUSED(gpf),
106  bGPDstroke *gps)
107 {
109  if ((mmd->type == GP_TINT_GRADIENT) && (!mmd->object)) {
110  return;
111  }
112 
113  const int def_nr = BKE_object_defgroup_name_index(ob, mmd->vgname);
114  const bool use_curve = (mmd->flag & GP_TINT_CUSTOM_CURVE) != 0 && mmd->curve_intensity;
115  bool is_inverted = ((mmd->flag & GP_TINT_WEIGHT_FACTOR) == 0) &&
116  ((mmd->flag & GP_TINT_INVERT_VGROUP) != 0);
117 
119  mmd->layername,
120  mmd->material,
121  mmd->pass_index,
122  mmd->layer_pass,
123  1,
124  gpl,
125  gps,
126  mmd->flag & GP_TINT_INVERT_LAYER,
127  mmd->flag & GP_TINT_INVERT_PASS,
129  mmd->flag & GP_TINT_INVERT_MATERIAL)) {
130  return;
131  }
133  const bool is_gradient = (mmd->type == GP_TINT_GRADIENT);
134 
135  /* If factor > 1.0, affect the strength of the stroke. */
136  if (mmd->factor > 1.0f) {
137  for (int i = 0; i < gps->totpoints; i++) {
138  bGPDspoint *pt = &gps->points[i];
139  pt->strength += mmd->factor - 1.0f;
140  CLAMP(pt->strength, 0.0f, 1.0f);
141  }
142  }
143 
144  float coba_res[4];
145  float matrix[4][4];
146  if (is_gradient) {
147  mul_m4_m4m4(matrix, mmd->object->imat, ob->obmat);
148  }
149 
150  /* loop points and apply color. */
151  bool fill_done = false;
152  for (int i = 0; i < gps->totpoints; i++) {
153  bGPDspoint *pt = &gps->points[i];
154  MDeformVert *dvert = gps->dvert != NULL ? &gps->dvert[i] : NULL;
155 
156  if (!fill_done) {
157  /* Apply to fill. */
158  if (mmd->mode != GPPAINT_MODE_STROKE) {
159  float fill_factor = mmd->factor;
160 
161  /* Use weighted factor. */
162  if (mmd->flag & GP_TINT_WEIGHT_FACTOR) {
163  /* Use first point for weight. */
164  MDeformVert *dvert_fill = (gps->dvert != NULL) ? &gps->dvert[0] : NULL;
165  float weight = get_modifier_point_weight(dvert_fill, is_inverted, def_nr);
166  if (weight >= 0.0f) {
167  fill_factor = ((mmd->flag & GP_TINT_INVERT_VGROUP) ? 1.0f - weight : weight);
168  }
169  }
170 
171  /* If not using Vertex Color, use the material color. */
172  if ((gp_style != NULL) && (gps->vert_color_fill[3] == 0.0f) &&
173  (gp_style->fill_rgba[3] > 0.0f)) {
174  copy_v4_v4(gps->vert_color_fill, gp_style->fill_rgba);
175  gps->vert_color_fill[3] = 1.0f;
176  }
177 
178  if (is_gradient) {
179  float center[3];
181  mul_v3_fl(center, 0.5f);
182  float pt_loc[3];
183  mul_v3_m4v3(pt_loc, matrix, &pt->x);
184  float dist = len_v3(pt_loc);
185  float mix_factor = clamp_f(dist / mmd->radius, 0.0f, 1.0f);
186 
187  BKE_colorband_evaluate(mmd->colorband, mix_factor, coba_res);
188  interp_v3_v3v3(gps->vert_color_fill, gps->vert_color_fill, coba_res, mmd->factor);
189  gps->vert_color_fill[3] = clamp_f(fill_factor, 0.0f, 1.0f);
190  }
191  else {
193  gps->vert_color_fill,
194  mmd->rgb,
195  clamp_f(fill_factor, 0.0f, 1.0f));
196  }
197  /* If no stroke, cancel loop. */
198  if (mmd->mode != GPPAINT_MODE_BOTH) {
199  break;
200  }
201  }
202 
203  fill_done = true;
204  }
205 
206  /* Verify vertex group. */
207  if (mmd->mode != GPPAINT_MODE_FILL) {
208  float weight = get_modifier_point_weight(dvert, is_inverted, def_nr);
209  if (weight < 0.0f) {
210  continue;
211  }
212 
213  float factor = mmd->factor;
214 
215  /* Custom curve to modulate value. */
216  if (use_curve) {
217  float value = (float)i / (gps->totpoints - 1);
218  weight *= BKE_curvemapping_evaluateF(mmd->curve_intensity, 0, value);
219  }
220 
221  /* If not using Vertex Color, use the material color. */
222  if ((gp_style != NULL) && (pt->vert_color[3] == 0.0f) && (gp_style->stroke_rgba[3] > 0.0f)) {
223  copy_v4_v4(pt->vert_color, gp_style->stroke_rgba);
224  pt->vert_color[3] = 1.0f;
225  }
226 
227  /* Apply weight directly. */
228  if (mmd->flag & GP_TINT_WEIGHT_FACTOR) {
229  factor = ((mmd->flag & GP_TINT_INVERT_VGROUP) ? 1.0f - weight : weight);
230  weight = 1.0f;
231  }
232 
233  if (is_gradient) {
234  /* Calc world position of point. */
235  float pt_loc[3];
236  mul_v3_m4v3(pt_loc, matrix, &pt->x);
237  float dist = len_v3(pt_loc);
238 
239  /* Calc the factor using the distance and get mix color. */
240  float mix_factor = clamp_f(dist / mmd->radius, 0.0f, 1.0f);
241  BKE_colorband_evaluate(mmd->colorband, mix_factor, coba_res);
242 
244  pt->vert_color,
245  coba_res,
246  clamp_f(factor, 0.0f, 1.0f) * weight * coba_res[3]);
247  }
248  else {
250  pt->vert_color, pt->vert_color, mmd->rgb, clamp_f(factor * weight, 0.0, 1.0f));
251  }
252  }
253  }
254 }
255 
256 /* FIXME: Ideally we be doing this on a copy of the main depsgraph
257  * (i.e. one where we don't have to worry about restoring state)
258  */
259 static void bakeModifier(Main *UNUSED(bmain),
262  Object *ob)
263 {
265 
266  if ((mmd->type == GP_TINT_GRADIENT) && (mmd->object == NULL)) {
267  return;
268  }
269 
271 }
272 
274 {
276  MEM_SAFE_FREE(mmd->colorband);
277  if (mmd->curve_intensity) {
279  }
280 }
281 
282 static bool isDisabled(GpencilModifierData *md, int UNUSED(userRenderParams))
283 {
285  if (mmd->type == GP_TINT_UNIFORM) {
286  return false;
287  }
288 
289  return !mmd->object;
290 }
291 
294  const int UNUSED(mode))
295 {
297  if (lmd->object != NULL) {
298  DEG_add_object_relation(ctx->node, lmd->object, DEG_OB_COMP_GEOMETRY, "Vertexcolor Modifier");
299  DEG_add_object_relation(ctx->node, lmd->object, DEG_OB_COMP_TRANSFORM, "Vertexcolor Modifier");
300  }
301  DEG_add_object_relation(ctx->node, ctx->object, DEG_OB_COMP_TRANSFORM, "Vertexcolor Modifier");
302 }
303 
304 static void foreachIDLink(GpencilModifierData *md, Object *ob, IDWalkFunc walk, void *userData)
305 {
307 
308  walk(userData, ob, (ID **)&mmd->material, IDWALK_CB_USER);
309  walk(userData, ob, (ID **)&mmd->object, IDWALK_CB_NOP);
310 }
311 
312 static void panel_draw(const bContext *UNUSED(C), Panel *panel)
313 {
314  uiLayout *col;
315  uiLayout *layout = panel->layout;
316 
318 
319  int tint_type = RNA_enum_get(ptr, "tint_type");
320 
321  uiLayoutSetPropSep(layout, true);
322 
323  uiItemR(layout, ptr, "vertex_mode", 0, NULL, ICON_NONE);
324 
325  const bool is_weighted = !RNA_boolean_get(ptr, "use_weight_factor");
326  uiLayout *row = uiLayoutRow(layout, true);
327  uiLayoutSetActive(row, is_weighted);
328  uiItemR(row, ptr, "factor", 0, NULL, ICON_NONE);
329  uiLayout *sub = uiLayoutRow(row, true);
330  uiLayoutSetActive(sub, true);
331  uiItemR(row, ptr, "use_weight_factor", 0, "", ICON_MOD_VERTEX_WEIGHT);
332 
333  uiItemR(layout, ptr, "tint_type", UI_ITEM_R_EXPAND, NULL, ICON_NONE);
334 
335  if (tint_type == GP_TINT_UNIFORM) {
336  uiItemR(layout, ptr, "color", 0, NULL, ICON_NONE);
337  }
338  else {
339  col = uiLayoutColumn(layout, false);
340  uiLayoutSetPropSep(col, false);
341  uiTemplateColorRamp(col, ptr, "colors", true);
342  uiItemS(layout);
343  uiItemR(layout, ptr, "object", 0, NULL, ICON_NONE);
344  uiItemR(layout, ptr, "radius", 0, NULL, ICON_NONE);
345  }
346 
348 }
349 
350 static void mask_panel_draw(const bContext *UNUSED(C), Panel *panel)
351 {
352  gpencil_modifier_masking_panel_draw(panel, true, true);
353 }
354 
355 static void panelRegister(ARegionType *region_type)
356 {
358  region_type, eGpencilModifierType_Tint, panel_draw);
360  region_type, "mask", "Influence", NULL, mask_panel_draw, panel_type);
362  "curve",
363  "",
366  mask_panel_type);
367 }
368 
370  /* name */ N_("Tint"),
371  /* structName */ "TintGpencilModifierData",
372  /* structSize */ sizeof(TintGpencilModifierData),
375 
376  /* copyData */ copyData,
377 
378  /* deformStroke */ deformStroke,
379  /* generateStrokes */ NULL,
380  /* bakeModifier */ bakeModifier,
381  /* remapTime */ NULL,
382 
383  /* initData */ initData,
384  /* freeData */ freeData,
385  /* isDisabled */ isDisabled,
386  /* updateDepsgraph */ updateDepsgraph,
387  /* dependsOnTime */ NULL,
388  /* foreachIDLink */ foreachIDLink,
389  /* foreachTexLink */ NULL,
390  /* panelRegister */ panelRegister,
391 };
typedef float(TangentPoint)[2]
struct ColorBand * BKE_colorband_add(bool rangetype)
Definition: colorband.c:296
void BKE_colorband_init(struct ColorBand *coba, bool rangetype)
Definition: colorband.c:22
bool BKE_colorband_evaluate(const struct ColorBand *coba, float in, float out[4])
void BKE_curvemapping_init(struct CurveMapping *cumap)
Definition: colortools.c:1235
struct CurveMapping * BKE_curvemapping_copy(const struct CurveMapping *cumap)
float BKE_curvemapping_evaluateF(const struct CurveMapping *cumap, int cur, float value)
void BKE_curvemapping_free(struct CurveMapping *cumap)
Definition: colortools.c:103
struct CurveMapping * BKE_curvemapping_add(int tot, float minx, float miny, float maxx, float maxy)
Definition: colortools.c:72
support for deformation groups and hooks.
int BKE_object_defgroup_name_index(const struct Object *ob, const char *name)
void BKE_gpencil_modifier_copydata_generic(const struct GpencilModifierData *md_src, struct GpencilModifierData *md_dst)
@ eGpencilModifierTypeFlag_SupportsEditmode
@ eGpencilModifierTypeType_Gpencil
@ IDWALK_CB_USER
Definition: BKE_lib_query.h:73
@ IDWALK_CB_NOP
Definition: BKE_lib_query.h:33
General operations, lookup, etc. for materials.
struct MaterialGPencilStyle * BKE_gpencil_material_settings(struct Object *ob, short act)
Definition: material.c:805
void(* IDWalkFunc)(void *userData, struct Object *ob, struct ID **idpoin, int cb_flag)
Definition: BKE_modifier.h:107
#define BLI_assert(a)
Definition: BLI_assert.h:46
MINLINE float clamp_f(float value, float min, float max)
void mul_m4_m4m4(float R[4][4], const float A[4][4], const float B[4][4])
Definition: math_matrix.c:259
void mul_v3_m4v3(float r[3], const float M[4][4], const float v[3])
Definition: math_matrix.c:739
MINLINE void copy_v4_v4(float r[4], const float a[4])
MINLINE void mul_v3_fl(float r[3], float f)
void interp_v3_v3v3(float r[3], const float a[3], const float b[3], float t)
Definition: math_vector.c:29
MINLINE void add_v3_v3v3(float r[3], const float a[3], const float b[3])
MINLINE float len_v3(const float a[3]) ATTR_WARN_UNUSED_RESULT
#define UNUSED(x)
#define MEMCMP_STRUCT_AFTER_IS_ZERO(struct_var, member)
#define MEMCPY_STRUCT_AFTER(struct_dst, struct_src, member)
struct Depsgraph Depsgraph
Definition: DEG_depsgraph.h:35
void DEG_add_object_relation(struct DepsNodeHandle *node_handle, struct Object *object, eDepsObjectComponentType component, const char *description)
@ DEG_OB_COMP_GEOMETRY
@ DEG_OB_COMP_TRANSFORM
@ GPPAINT_MODE_STROKE
@ GPPAINT_MODE_FILL
@ GPPAINT_MODE_BOTH
#define DNA_struct_default_get(struct_name)
Definition: DNA_defaults.h:29
struct TintGpencilModifierData TintGpencilModifierData
@ GP_TINT_INVERT_LAYERPASS
@ GP_TINT_INVERT_MATERIAL
@ eGpencilModifierType_Tint
Object is a sort of wrapper for general info.
NSNotificationCenter * center
Read Guarded memory(de)allocation.
#define MEM_SAFE_FREE(v)
PointerRNA * gpencil_modifier_panel_get_property_pointers(Panel *panel, PointerRNA *r_ob_ptr)
void gpencil_modifier_masking_panel_draw(Panel *panel, bool use_material, bool use_vertex)
void gpencil_modifier_panel_end(uiLayout *layout, PointerRNA *ptr)
PanelType * gpencil_modifier_subpanel_register(ARegionType *region_type, const char *name, const char *label, PanelDrawFn draw_header, PanelDrawFn draw, PanelType *parent)
PanelType * gpencil_modifier_panel_register(ARegionType *region_type, GpencilModifierType type, PanelDrawFn draw)
void gpencil_modifier_curve_header_draw(const bContext *UNUSED(C), Panel *panel)
void gpencil_modifier_curve_panel_draw(const bContext *UNUSED(C), Panel *panel)
float get_modifier_point_weight(MDeformVert *dvert, bool inverse, int def_nr)
void generic_bake_deform_stroke(Depsgraph *depsgraph, GpencilModifierData *md, Object *ob, const bool retime, gpBakeCb bake_cb)
bool is_stroke_affected_by_modifier(Object *ob, char *mlayername, Material *material, const int mpassindex, const int gpl_passindex, const int minpoints, bGPDlayer *gpl, bGPDstroke *gps, const bool inv1, const bool inv2, const bool inv3, const bool inv4)
static void deformStroke(GpencilModifierData *md, Depsgraph *UNUSED(depsgraph), Object *ob, bGPDlayer *gpl, bGPDframe *UNUSED(gpf), bGPDstroke *gps)
static bool isDisabled(GpencilModifierData *md, int UNUSED(userRenderParams))
static void freeData(GpencilModifierData *md)
static void updateDepsgraph(GpencilModifierData *md, const ModifierUpdateDepsgraphContext *ctx, const int UNUSED(mode))
static void mask_panel_draw(const bContext *UNUSED(C), Panel *panel)
static void foreachIDLink(GpencilModifierData *md, Object *ob, IDWalkFunc walk, void *userData)
static void bakeModifier(Main *UNUSED(bmain), Depsgraph *depsgraph, GpencilModifierData *md, Object *ob)
static void copyData(const GpencilModifierData *md, GpencilModifierData *target)
GpencilModifierTypeInfo modifierType_Gpencil_Tint
static void panel_draw(const bContext *UNUSED(C), Panel *panel)
static void panelRegister(ARegionType *region_type)
static void initData(GpencilModifierData *md)
Group Output data from inside of a node group A color picker Mix two input colors RGB to Convert a color s luminance to a grayscale value Generate a normal vector and a dot product Bright Control the brightness and contrast of the input color Vector Map an input vectors to used to fine tune the interpolation of the input Camera Retrieve information about the camera and how it relates to the current shading point s position CLAMP
#define C
Definition: RandGen.cpp:25
void uiLayoutSetActive(uiLayout *layout, bool active)
uiLayout * uiLayoutColumn(uiLayout *layout, bool align)
void uiLayoutSetPropSep(uiLayout *layout, bool is_sep)
void uiItemS(uiLayout *layout)
uiLayout * uiLayoutRow(uiLayout *layout, bool align)
@ UI_ITEM_R_EXPAND
void uiItemR(uiLayout *layout, struct PointerRNA *ptr, const char *propname, int flag, const char *name, int icon)
void uiTemplateColorRamp(uiLayout *layout, struct PointerRNA *ptr, const char *propname, bool expand)
const Depsgraph * depsgraph
uint col
void *(* MEM_dupallocN)(const void *vmemh)
Definition: mallocn.c:28
bool RNA_boolean_get(PointerRNA *ptr, const char *name)
Definition: rna_access.c:4863
int RNA_enum_get(PointerRNA *ptr, const char *name)
Definition: rna_access.c:5004
CBData data[32]
Definition: DNA_ID.h:368
Definition: BKE_main.h:121
struct DepsNodeHandle * node
Definition: BKE_modifier.h:134
float imat[4][4]
float obmat[4][4]
struct uiLayout * layout
struct CurveMapping * curve_intensity
float vert_color[4]
bGPDspoint * points
float vert_color_fill[4]
float boundbox_max[3]
float boundbox_min[3]
struct MDeformVert * dvert
#define N_(msgid)
PointerRNA * ptr
Definition: wm_files.c:3480