Blender  V2.93
shader_fx.c
Go to the documentation of this file.
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  *
16  * The Original Code is Copyright (C) 2018, Blender Foundation
17  * This is a new part of Blender
18  */
19 
24 #include <stdio.h>
25 
26 #include "MEM_guardedalloc.h"
27 
28 #include "BLI_blenlib.h"
29 #include "BLI_math_vector.h"
30 #include "BLI_string_utils.h"
31 #include "BLI_utildefines.h"
32 
33 #include "BLT_translation.h"
34 
35 #include "DNA_gpencil_types.h"
36 #include "DNA_meshdata_types.h"
37 #include "DNA_object_types.h"
38 #include "DNA_scene_types.h"
39 #include "DNA_screen_types.h"
40 #include "DNA_shader_fx_types.h"
41 
42 #include "BKE_gpencil.h"
43 #include "BKE_lib_id.h"
44 #include "BKE_lib_query.h"
45 #include "BKE_object.h"
46 #include "BKE_shader_fx.h"
47 
48 #include "DEG_depsgraph.h"
49 #include "DEG_depsgraph_query.h"
50 
51 #include "FX_shader_types.h"
52 
53 #include "BLO_read_write.h"
54 
56 
57 /* *************************************************** */
58 /* Methods - Evaluation Loops, etc. */
59 
60 /* check if exist grease pencil effects */
62 {
63  ShaderFxData *fx;
64  for (fx = ob->shader_fx.first; fx; fx = fx->next) {
66  if (fxi->type == eShaderFxType_GpencilType) {
67  return true;
68  }
69  }
70  return false;
71 }
72 
74 {
75  /* Initialize shaders */
76  shaderfx_type_init(shader_fx_types); /* FX_shader_util.c */
77 }
78 
80 {
83 
84  /* note, this name must be made unique later */
85  BLI_strncpy(fx->name, DATA_(fxi->name), sizeof(fx->name));
86 
87  fx->type = type;
90  fx->ui_expand_flag = 1; /* Expand only the parent panel by default. */
91 
94  }
95 
96  if (fxi->initData) {
97  fxi->initData(fx);
98  }
99 
100  return fx;
101 }
102 
103 static void shaderfx_free_data_id_us_cb(void *UNUSED(userData),
104  Object *UNUSED(ob),
105  ID **idpoin,
106  int cb_flag)
107 {
108  ID *id = *idpoin;
109  if (id != NULL && (cb_flag & IDWALK_CB_USER) != 0) {
110  id_us_min(id);
111  }
112 }
113 
114 void BKE_shaderfx_free_ex(ShaderFxData *fx, const int flag)
115 {
116  const ShaderFxTypeInfo *fxi = BKE_shaderfx_get_info(fx->type);
117 
118  if ((flag & LIB_ID_CREATE_NO_USER_REFCOUNT) == 0) {
119  if (fxi->foreachIDLink) {
121  }
122  }
123 
124  if (fxi->freeData) {
125  fxi->freeData(fx);
126  }
127  if (fx->error) {
128  MEM_freeN(fx->error);
129  }
130 
131  MEM_freeN(fx);
132 }
133 
135 {
136  BKE_shaderfx_free_ex(fx, 0);
137 }
138 
139 /* check unique name */
141 {
142  if (shaders && fx) {
143  const ShaderFxTypeInfo *fxi = BKE_shaderfx_get_info(fx->type);
144  return BLI_uniquename(
145  shaders, fx, DATA_(fxi->name), '.', offsetof(ShaderFxData, name), sizeof(fx->name));
146  }
147  return false;
148 }
149 
151 {
152  const ShaderFxTypeInfo *fxi = BKE_shaderfx_get_info(fx->type);
153 
154  return fxi->dependsOnTime && fxi->dependsOnTime(fx);
155 }
156 
158 {
159  /* type unsigned, no need to check < 0 */
160  if (type < NUM_SHADER_FX_TYPES && type > 0 && shader_fx_types[type]->name[0] != '\0') {
161  return shader_fx_types[type];
162  }
163 
164  return NULL;
165 }
166 
174 {
176 
177  strcpy(r_idname, SHADERFX_TYPE_PANEL_PREFIX);
178  strcat(r_idname, fxi->name);
179 }
180 
182 {
184 }
185 
187 {
188  const ShaderFxTypeInfo *fxi = BKE_shaderfx_get_info(fx_src->type);
189 
190  /* fx_dst may have already be fully initialized with some extra allocated data,
191  * we need to free it now to avoid memleak. */
192  if (fxi->freeData) {
193  fxi->freeData(fx_dst);
194  }
195 
196  const size_t data_size = sizeof(ShaderFxData);
197  const char *fx_src_data = ((const char *)fx_src) + data_size;
198  char *fx_dst_data = ((char *)fx_dst) + data_size;
199  BLI_assert(data_size <= (size_t)fxi->struct_size);
200  memcpy(fx_dst_data, fx_src_data, (size_t)fxi->struct_size - data_size);
201 }
202 
203 static void shaderfx_copy_data_id_us_cb(void *UNUSED(userData),
204  Object *UNUSED(ob),
205  ID **idpoin,
206  int cb_flag)
207 {
208  ID *id = *idpoin;
209  if (id != NULL && (cb_flag & IDWALK_CB_USER) != 0) {
210  id_us_plus(id);
211  }
212 }
213 
214 void BKE_shaderfx_copydata_ex(ShaderFxData *fx, ShaderFxData *target, const int flag)
215 {
216  const ShaderFxTypeInfo *fxi = BKE_shaderfx_get_info(fx->type);
217 
218  target->mode = fx->mode;
219  target->flag = fx->flag;
220  target->ui_expand_flag = fx->ui_expand_flag;
221 
222  if (fxi->copyData) {
223  fxi->copyData(fx, target);
224  }
225 
226  if ((flag & LIB_ID_CREATE_NO_USER_REFCOUNT) == 0) {
227  if (fxi->foreachIDLink) {
229  }
230  }
231 }
232 
234 {
235  BKE_shaderfx_copydata_ex(fx, target, 0);
236 }
237 
238 void BKE_shaderfx_copy(ListBase *dst, const ListBase *src)
239 {
240  ShaderFxData *fx;
241  ShaderFxData *srcfx;
242 
243  BLI_listbase_clear(dst);
244  BLI_duplicatelist(dst, src);
245 
246  for (srcfx = src->first, fx = dst->first; srcfx && fx; srcfx = srcfx->next, fx = fx->next) {
247  BKE_shaderfx_copydata(srcfx, fx);
248  }
249 }
250 
252 {
253  ShaderFxData *fx = ob->shader_fx.first;
254 
255  for (; fx; fx = fx->next) {
256  if (fx->type == type) {
257  break;
258  }
259  }
260 
261  return fx;
262 }
263 
265 {
266  ShaderFxData *fx = ob->shader_fx.first;
267 
268  for (; fx; fx = fx->next) {
269  const ShaderFxTypeInfo *fxi = BKE_shaderfx_get_info(fx->type);
270 
271  if (fxi->foreachIDLink) {
272  fxi->foreachIDLink(fx, ob, walk, userData);
273  }
274  }
275 }
276 
278 {
279  return BLI_findstring(&(ob->shader_fx), name, offsetof(ShaderFxData, name));
280 }
281 
283 {
284  if (fxbase == NULL) {
285  return;
286  }
287 
288  LISTBASE_FOREACH (ShaderFxData *, fx, fxbase) {
289  const ShaderFxTypeInfo *fxi = BKE_shaderfx_get_info(fx->type);
290  if (fxi == NULL) {
291  return;
292  }
293 
294  BLO_write_struct_by_name(writer, fxi->struct_name, fx);
295  }
296 }
297 
299 {
300  BLO_read_list(reader, lb);
301 
302  LISTBASE_FOREACH (ShaderFxData *, fx, lb) {
303  fx->error = NULL;
304 
305  /* if shader disappear, or for upward compatibility */
306  if (NULL == BKE_shaderfx_get_info(fx->type)) {
307  fx->type = eShaderFxType_None;
308  }
309  }
310 }
311 
313 {
315 
316  /* If linking from a library, clear 'local' library override flag. */
317  if (ob->id.lib != NULL) {
318  LISTBASE_FOREACH (ShaderFxData *, fx, &ob->shader_fx) {
320  }
321  }
322 }
void id_us_min(struct ID *id)
Definition: lib_id.c:297
@ LIB_ID_CREATE_NO_USER_REFCOUNT
Definition: BKE_lib_id.h:92
void id_us_plus(struct ID *id)
Definition: lib_id.c:288
@ IDWALK_CB_USER
Definition: BKE_lib_query.h:87
General operations, lookup, etc. for blender objects.
void BKE_object_modifiers_lib_link_common(void *userData, struct Object *ob, struct ID **idpoin, int cb_flag)
Definition: object.c:5706
@ eShaderFxType_GpencilType
Definition: BKE_shader_fx.h:49
void(* ShaderFxIDWalkFunc)(void *userData, struct Object *ob, struct ID **idpoin, int cb_flag)
Definition: BKE_shader_fx.h:67
@ eShaderFxTypeFlag_EnableInEditmode
Definition: BKE_shader_fx.h:58
#define SHADERFX_TYPE_PANEL_PREFIX
#define BLI_assert(a)
Definition: BLI_assert.h:58
#define LISTBASE_FOREACH(type, var, list)
Definition: BLI_listbase.h:172
void void void void void BLI_duplicatelist(struct ListBase *dst, const struct ListBase *src) ATTR_NONNULL(1
BLI_INLINE void BLI_listbase_clear(struct ListBase *lb)
Definition: BLI_listbase.h:128
void * BLI_findstring(const struct ListBase *listbase, const char *id, const int offset) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
char * BLI_strncpy(char *__restrict dst, const char *__restrict src, const size_t maxncpy) ATTR_NONNULL()
Definition: string.c:108
bool BLI_uniquename(struct ListBase *list, void *vlink, const char *defname, char delim, int name_offset, size_t len)
Definition: string_utils.c:381
#define UNUSED(x)
void BLO_write_struct_by_name(BlendWriter *writer, const char *struct_name, const void *data_ptr)
Definition: writefile.c:1291
void BLO_read_list(BlendDataReader *reader, struct ListBase *list)
Definition: readfile.c:5654
#define DATA_(msgid)
Object is a sort of wrapper for general info.
@ UI_PANEL_DATA_EXPAND_ROOT
@ eShaderFxFlag_OverrideLibrary_Local
@ eShaderFxMode_Realtime
@ eShaderFxMode_Editmode
@ eShaderFxMode_Render
struct ShaderFxData ShaderFxData
ShaderFxType
@ eShaderFxType_None
@ NUM_SHADER_FX_TYPES
void shaderfx_type_init(ShaderFxTypeInfo *types[])
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum type
Read Guarded memory(de)allocation.
IMAGE_Shaders shaders
Definition: image_shader.c:44
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:41
void *(* MEM_callocN)(size_t len, const char *str)
Definition: mallocn.c:45
void BKE_shaderfx_copydata(ShaderFxData *fx, ShaderFxData *target)
Definition: shader_fx.c:233
void BKE_shaderfx_copydata_generic(const ShaderFxData *fx_src, ShaderFxData *fx_dst)
Definition: shader_fx.c:186
void BKE_shaderfx_init(void)
Definition: shader_fx.c:73
void BKE_shaderfx_foreach_ID_link(Object *ob, ShaderFxIDWalkFunc walk, void *userData)
Definition: shader_fx.c:264
void BKE_shaderfxType_panel_id(ShaderFxType type, char *r_idname)
Definition: shader_fx.c:173
bool BKE_shaderfx_has_gpencil(Object *ob)
Definition: shader_fx.c:61
void BKE_shaderfx_blend_write(BlendWriter *writer, ListBase *fxbase)
Definition: shader_fx.c:282
ShaderFxData * BKE_shaderfx_findby_name(Object *ob, const char *name)
Definition: shader_fx.c:277
const ShaderFxTypeInfo * BKE_shaderfx_get_info(ShaderFxType type)
Definition: shader_fx.c:157
void BKE_shaderfx_panel_expand(ShaderFxData *fx)
Definition: shader_fx.c:181
void BKE_shaderfx_blend_read_data(BlendDataReader *reader, ListBase *lb)
Definition: shader_fx.c:298
static void shaderfx_copy_data_id_us_cb(void *UNUSED(userData), Object *UNUSED(ob), ID **idpoin, int cb_flag)
Definition: shader_fx.c:203
void BKE_shaderfx_copy(ListBase *dst, const ListBase *src)
Definition: shader_fx.c:238
bool BKE_shaderfx_unique_name(ListBase *shaders, ShaderFxData *fx)
Definition: shader_fx.c:140
static void shaderfx_free_data_id_us_cb(void *UNUSED(userData), Object *UNUSED(ob), ID **idpoin, int cb_flag)
Definition: shader_fx.c:103
void BKE_shaderfx_free_ex(ShaderFxData *fx, const int flag)
Definition: shader_fx.c:114
void BKE_shaderfx_blend_read_lib(BlendLibReader *reader, Object *ob)
Definition: shader_fx.c:312
bool BKE_shaderfx_depends_ontime(ShaderFxData *fx)
Definition: shader_fx.c:150
static ShaderFxTypeInfo * shader_fx_types[NUM_SHADER_FX_TYPES]
Definition: shader_fx.c:55
ShaderFxData * BKE_shaderfx_findby_type(Object *ob, ShaderFxType type)
Definition: shader_fx.c:251
ShaderFxData * BKE_shaderfx_new(int type)
Definition: shader_fx.c:79
void BKE_shaderfx_copydata_ex(ShaderFxData *fx, ShaderFxData *target, const int flag)
Definition: shader_fx.c:214
void BKE_shaderfx_free(ShaderFxData *fx)
Definition: shader_fx.c:134
Definition: DNA_ID.h:273
struct Library * lib
Definition: DNA_ID.h:277
void * first
Definition: DNA_listBase.h:47
ListBase shader_fx
struct ShaderFxData * next
void(* freeData)(struct ShaderFxData *fx)
ShaderFxTypeFlag flags
Definition: BKE_shader_fx.h:89
void(* copyData)(const struct ShaderFxData *fx, struct ShaderFxData *target)
Definition: BKE_shader_fx.h:94
ShaderFxTypeType type
Definition: BKE_shader_fx.h:88
void(* foreachIDLink)(struct ShaderFxData *fx, struct Object *ob, ShaderFxIDWalkFunc walk, void *userData)
bool(* dependsOnTime)(struct ShaderFxData *fx)
char struct_name[32]
Definition: BKE_shader_fx.h:83
void(* initData)(struct ShaderFxData *fx)