Blender  V2.93
hair.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 
21 #include "MEM_guardedalloc.h"
22 
23 #include "DNA_defaults.h"
24 #include "DNA_hair_types.h"
25 #include "DNA_material_types.h"
26 #include "DNA_object_types.h"
27 
28 #include "BLI_listbase.h"
29 #include "BLI_math.h"
30 #include "BLI_rand.h"
31 #include "BLI_string.h"
32 #include "BLI_utildefines.h"
33 
34 #include "BKE_anim_data.h"
35 #include "BKE_customdata.h"
36 #include "BKE_global.h"
37 #include "BKE_hair.h"
38 #include "BKE_idtype.h"
39 #include "BKE_lib_id.h"
40 #include "BKE_lib_query.h"
41 #include "BKE_lib_remap.h"
42 #include "BKE_main.h"
43 #include "BKE_modifier.h"
44 #include "BKE_object.h"
45 
46 #include "BLT_translation.h"
47 
48 #include "DEG_depsgraph_query.h"
49 
50 #include "BLO_read_write.h"
51 
52 static const char *HAIR_ATTR_POSITION = "position";
53 static const char *HAIR_ATTR_RADIUS = "radius";
54 
55 /* Hair datablock */
56 
57 static void hair_random(Hair *hair);
58 
59 static void hair_init_data(ID *id)
60 {
61  Hair *hair = (Hair *)id;
63 
65 
66  CustomData_reset(&hair->pdata);
67  CustomData_reset(&hair->cdata);
68 
75 
76  hair_random(hair);
77 }
78 
79 static void hair_copy_data(Main *UNUSED(bmain), ID *id_dst, const ID *id_src, const int flag)
80 {
81  Hair *hair_dst = (Hair *)id_dst;
82  const Hair *hair_src = (const Hair *)id_src;
83  hair_dst->mat = MEM_dupallocN(hair_dst->mat);
84 
85  const eCDAllocType alloc_type = (flag & LIB_ID_COPY_CD_REFERENCE) ? CD_REFERENCE : CD_DUPLICATE;
86  CustomData_copy(&hair_src->pdata, &hair_dst->pdata, CD_MASK_ALL, alloc_type, hair_dst->totpoint);
87  CustomData_copy(&hair_src->cdata, &hair_dst->cdata, CD_MASK_ALL, alloc_type, hair_dst->totcurve);
89 
90  hair_dst->batch_cache = NULL;
91 }
92 
93 static void hair_free_data(ID *id)
94 {
95  Hair *hair = (Hair *)id;
96  BKE_animdata_free(&hair->id, false);
97 
99 
100  CustomData_free(&hair->pdata, hair->totpoint);
101  CustomData_free(&hair->cdata, hair->totcurve);
102 
103  MEM_SAFE_FREE(hair->mat);
104 }
105 
107 {
108  Hair *hair = (Hair *)id;
109  for (int i = 0; i < hair->totcol; i++) {
111  }
112 }
113 
114 static void hair_blend_write(BlendWriter *writer, ID *id, const void *id_address)
115 {
116  Hair *hair = (Hair *)id;
117  if (hair->id.us > 0 || BLO_write_is_undo(writer)) {
118  CustomDataLayer *players = NULL, players_buff[CD_TEMP_CHUNK_SIZE];
119  CustomDataLayer *clayers = NULL, clayers_buff[CD_TEMP_CHUNK_SIZE];
120  CustomData_blend_write_prepare(&hair->pdata, &players, players_buff, ARRAY_SIZE(players_buff));
121  CustomData_blend_write_prepare(&hair->cdata, &clayers, clayers_buff, ARRAY_SIZE(clayers_buff));
122 
123  /* Write LibData */
124  BLO_write_id_struct(writer, Hair, id_address, &hair->id);
125  BKE_id_blend_write(writer, &hair->id);
126 
127  /* Direct data */
128  CustomData_blend_write(writer, &hair->pdata, players, hair->totpoint, CD_MASK_ALL, &hair->id);
129  CustomData_blend_write(writer, &hair->cdata, clayers, hair->totcurve, CD_MASK_ALL, &hair->id);
130 
131  BLO_write_pointer_array(writer, hair->totcol, hair->mat);
132  if (hair->adt) {
133  BKE_animdata_blend_write(writer, hair->adt);
134  }
135 
136  /* Remove temporary data. */
137  if (players && players != players_buff) {
138  MEM_freeN(players);
139  }
140  if (clayers && clayers != clayers_buff) {
141  MEM_freeN(clayers);
142  }
143  }
144 }
145 
146 static void hair_blend_read_data(BlendDataReader *reader, ID *id)
147 {
148  Hair *hair = (Hair *)id;
149  BLO_read_data_address(reader, &hair->adt);
150  BKE_animdata_blend_read_data(reader, hair->adt);
151 
152  /* Geometry */
153  CustomData_blend_read(reader, &hair->pdata, hair->totpoint);
154  CustomData_blend_read(reader, &hair->cdata, hair->totcurve);
156 
157  /* Materials */
158  BLO_read_pointer_array(reader, (void **)&hair->mat);
159 }
160 
161 static void hair_blend_read_lib(BlendLibReader *reader, ID *id)
162 {
163  Hair *hair = (Hair *)id;
164  for (int a = 0; a < hair->totcol; a++) {
165  BLO_read_id_address(reader, hair->id.lib, &hair->mat[a]);
166  }
167 }
168 
169 static void hair_blend_read_expand(BlendExpander *expander, ID *id)
170 {
171  Hair *hair = (Hair *)id;
172  for (int a = 0; a < hair->totcol; a++) {
173  BLO_expand(expander, hair->mat[a]);
174  }
175 }
176 
178  .id_code = ID_HA,
179  .id_filter = FILTER_ID_HA,
180  .main_listbase_index = INDEX_ID_HA,
181  .struct_size = sizeof(Hair),
182  .name = "Hair",
183  .name_plural = "hairs",
184  .translation_context = BLT_I18NCONTEXT_ID_HAIR,
185  .flags = 0,
186 
188  .copy_data = hair_copy_data,
189  .free_data = hair_free_data,
190  .make_local = NULL,
191  .foreach_id = hair_foreach_id,
192  .foreach_cache = NULL,
193  .owner_get = NULL,
194 
195  .blend_write = hair_blend_write,
196  .blend_read_data = hair_blend_read_data,
197  .blend_read_lib = hair_blend_read_lib,
198  .blend_read_expand = hair_blend_read_expand,
199 
200  .blend_read_undo_preserve = NULL,
201 
202  .lib_override_apply_post = NULL,
203 };
204 
205 static void hair_random(Hair *hair)
206 {
207  const int numpoints = 8;
208 
209  hair->totcurve = 500;
210  hair->totpoint = hair->totcurve * numpoints;
211 
212  CustomData_realloc(&hair->pdata, hair->totpoint);
213  CustomData_realloc(&hair->cdata, hair->totcurve);
215 
216  RNG *rng = BLI_rng_new(0);
217 
218  for (int i = 0; i < hair->totcurve; i++) {
219  HairCurve *curve = &hair->curves[i];
220  curve->firstpoint = i * numpoints;
221  curve->numpoints = numpoints;
222 
223  float theta = 2.0f * M_PI * BLI_rng_get_float(rng);
224  float phi = saacosf(2.0f * BLI_rng_get_float(rng) - 1.0f);
225 
226  float no[3] = {sinf(theta) * sinf(phi), cosf(theta) * sinf(phi), cosf(phi)};
227  normalize_v3(no);
228 
229  float co[3];
230  copy_v3_v3(co, no);
231 
232  float(*curve_co)[3] = hair->co + curve->firstpoint;
233  float *curve_radius = hair->radius + curve->firstpoint;
234  for (int key = 0; key < numpoints; key++) {
235  float t = key / (float)(numpoints - 1);
236  copy_v3_v3(curve_co[key], co);
237  curve_radius[key] = 0.02f * (1.0f - t);
238 
239  float offset[3] = {2.0f * BLI_rng_get_float(rng) - 1.0f,
240  2.0f * BLI_rng_get_float(rng) - 1.0f,
241  2.0f * BLI_rng_get_float(rng) - 1.0f};
242  add_v3_v3(offset, no);
243  madd_v3_v3fl(co, offset, 1.0f / numpoints);
244  }
245  }
246 
247  BLI_rng_free(rng);
248 }
249 
250 void *BKE_hair_add(Main *bmain, const char *name)
251 {
252  Hair *hair = BKE_id_new(bmain, ID_HA, name);
253 
254  return hair;
255 }
256 
258 {
259  BLI_assert(ob->type == OB_HAIR);
260  Hair *hair = ob->data;
261 
262  if (ob->runtime.bb != NULL && (ob->runtime.bb->flag & BOUNDBOX_DIRTY) == 0) {
263  return ob->runtime.bb;
264  }
265 
266  if (ob->runtime.bb == NULL) {
267  ob->runtime.bb = MEM_callocN(sizeof(BoundBox), "hair boundbox");
268 
269  float min[3], max[3];
270  INIT_MINMAX(min, max);
271 
272  float(*hair_co)[3] = hair->co;
273  float *hair_radius = hair->radius;
274  for (int a = 0; a < hair->totpoint; a++) {
275  float *co = hair_co[a];
276  float radius = (hair_radius) ? hair_radius[a] : 0.0f;
277  const float co_min[3] = {co[0] - radius, co[1] - radius, co[2] - radius};
278  const float co_max[3] = {co[0] + radius, co[1] + radius, co[2] + radius};
279  DO_MIN(co_min, min);
280  DO_MAX(co_max, max);
281  }
282 
284  }
285 
286  return ob->runtime.bb;
287 }
288 
290 {
295 }
296 
298 {
299  return layer->type == CD_PROP_FLOAT3 && STREQ(layer->name, HAIR_ATTR_POSITION);
300 }
301 
302 /* Dependency Graph */
303 
304 Hair *BKE_hair_new_for_eval(const Hair *hair_src, int totpoint, int totcurve)
305 {
306  Hair *hair_dst = BKE_id_new_nomain(ID_HA, NULL);
307 
308  STRNCPY(hair_dst->id.name, hair_src->id.name);
309  hair_dst->mat = MEM_dupallocN(hair_src->mat);
310  hair_dst->totcol = hair_src->totcol;
311 
312  hair_dst->totpoint = totpoint;
313  hair_dst->totcurve = totcurve;
314  CustomData_copy(&hair_src->pdata, &hair_dst->pdata, CD_MASK_ALL, CD_CALLOC, totpoint);
315  CustomData_copy(&hair_src->cdata, &hair_dst->cdata, CD_MASK_ALL, CD_CALLOC, totcurve);
317 
318  return hair_dst;
319 }
320 
321 Hair *BKE_hair_copy_for_eval(Hair *hair_src, bool reference)
322 {
323  int flags = LIB_ID_COPY_LOCALIZE;
324 
325  if (reference) {
326  flags |= LIB_ID_COPY_CD_REFERENCE;
327  }
328 
329  Hair *result = (Hair *)BKE_id_copy_ex(NULL, &hair_src->id, NULL, flags);
330  return result;
331 }
332 
334  struct Scene *scene,
335  Object *object,
336  Hair *hair_input)
337 {
338  Hair *hair = hair_input;
339 
340  /* Modifier evaluation modes. */
341  const bool use_render = (DEG_get_mode(depsgraph) == DAG_EVAL_RENDER);
342  const int required_mode = use_render ? eModifierMode_Render : eModifierMode_Realtime;
343  ModifierApplyFlag apply_flag = use_render ? MOD_APPLY_RENDER : MOD_APPLY_USECACHE;
344  const ModifierEvalContext mectx = {depsgraph, object, apply_flag};
345 
346  /* Get effective list of modifiers to execute. Some effects like shape keys
347  * are added as virtual modifiers before the user created modifiers. */
348  VirtualModifierData virtualModifierData;
349  ModifierData *md = BKE_modifiers_get_virtual_modifierlist(object, &virtualModifierData);
350 
351  /* Evaluate modifiers. */
352  for (; md; md = md->next) {
353  const ModifierTypeInfo *mti = BKE_modifier_get_info(md->type);
354 
355  if (!BKE_modifier_is_enabled(scene, md, required_mode)) {
356  continue;
357  }
358 
359  if ((mti->type == eModifierTypeType_OnlyDeform) &&
361  /* Ensure we are not modifying the input. */
362  if (hair == hair_input) {
363  hair = BKE_hair_copy_for_eval(hair, true);
364  }
365 
366  /* Ensure we are not overwriting referenced data. */
370 
371  /* Created deformed coordinates array on demand. */
372  mti->deformVerts(md, &mectx, NULL, hair->co, hair->totpoint);
373  }
374  else if (mti->modifyHair) {
375  /* Ensure we are not modifying the input. */
376  if (hair == hair_input) {
377  hair = BKE_hair_copy_for_eval(hair, true);
378  }
379 
380  Hair *hair_next = mti->modifyHair(md, &mectx, hair);
381 
382  if (hair_next && hair_next != hair) {
383  /* If the modifier returned a new hair, release the old one. */
384  if (hair != hair_input) {
385  BKE_id_free(NULL, hair);
386  }
387  hair = hair_next;
388  }
389  }
390  }
391 
392  return hair;
393 }
394 
395 void BKE_hair_data_update(struct Depsgraph *depsgraph, struct Scene *scene, Object *object)
396 {
397  /* Free any evaluated data and restore original data. */
399 
400  /* Evaluate modifiers. */
401  Hair *hair = object->data;
402  Hair *hair_eval = hair_evaluate_modifiers(depsgraph, scene, object, hair);
403 
404  /* Assign evaluated object. */
405  const bool is_owned = (hair != hair_eval);
406  BKE_object_eval_assign_data(object, &hair_eval->id, is_owned);
407 }
408 
409 /* Draw Cache */
410 void (*BKE_hair_batch_cache_dirty_tag_cb)(Hair *hair, int mode) = NULL;
412 
414 {
415  if (hair->batch_cache) {
417  }
418 }
419 
421 {
422  if (hair->batch_cache) {
424  }
425 }
typedef float(TangentPoint)[2]
void BKE_animdata_free(struct ID *id, const bool do_id_user)
Definition: anim_data.c:230
void BKE_animdata_blend_read_data(struct BlendDataReader *reader, struct AnimData *adt)
Definition: anim_data.c:1574
void BKE_animdata_blend_write(struct BlendWriter *writer, struct AnimData *adt)
Definition: anim_data.c:1552
CustomData interface, see also DNA_customdata_types.h.
void CustomData_free(struct CustomData *data, int totelem)
Definition: customdata.c:2239
void CustomData_blend_read(struct BlendDataReader *reader, struct CustomData *data, int count)
Definition: customdata.c:5180
void CustomData_blend_write(struct BlendWriter *writer, struct CustomData *data, CustomDataLayer *layers, int count, CustomDataMask cddata_mask, struct ID *id)
Definition: customdata.c:5073
eCDAllocType
@ CD_REFERENCE
@ CD_CALLOC
@ CD_DUPLICATE
void * CustomData_duplicate_referenced_layer_named(struct CustomData *data, const int type, const char *name, const int totelem)
Definition: customdata.c:2807
void CustomData_blend_write_prepare(struct CustomData *data, struct CustomDataLayer **r_write_layers, struct CustomDataLayer *write_layers_buff, size_t write_layers_size)
Definition: customdata.c:4237
void * CustomData_add_layer_named(struct CustomData *data, int type, eCDAllocType alloctype, void *layer, int totelem, const char *name)
Definition: customdata.c:2637
void * CustomData_get_layer_named(const struct CustomData *data, int type, const char *name)
Definition: customdata.c:3217
void * CustomData_get_layer(const struct CustomData *data, int type)
void * CustomData_add_layer(struct CustomData *data, int type, eCDAllocType alloctype, void *layer, int totelem)
Definition: customdata.c:2620
void CustomData_copy(const struct CustomData *source, struct CustomData *dest, CustomDataMask mask, eCDAllocType alloctype, int totelem)
Definition: customdata.c:2193
void CustomData_realloc(struct CustomData *data, int totelem)
Definition: customdata.c:2180
void CustomData_reset(struct CustomData *data)
Definition: customdata.c:2233
General operations for hairs.
void * BKE_id_new_nomain(const short type, const char *name)
Definition: lib_id.c:1196
@ LIB_ID_COPY_CD_REFERENCE
Definition: BKE_lib_id.h:122
@ LIB_ID_COPY_LOCALIZE
Definition: BKE_lib_id.h:145
struct ID * BKE_id_copy_ex(struct Main *bmain, const struct ID *id, struct ID **r_newid, const int flag)
void BKE_id_free(struct Main *bmain, void *idv)
void BKE_id_blend_write(struct BlendWriter *writer, struct ID *id)
Definition: lib_id.c:2395
void * BKE_id_new(struct Main *bmain, const short type, const char *name)
Definition: lib_id.c:1177
#define BKE_LIB_FOREACHID_PROCESS(_data, _id_super, _cb_flag)
@ IDWALK_CB_USER
Definition: BKE_lib_query.h:87
const ModifierTypeInfo * BKE_modifier_get_info(ModifierType type)
bool BKE_modifier_is_enabled(const struct Scene *scene, struct ModifierData *md, int required_mode)
@ eModifierTypeFlag_AcceptsVertexCosOnly
Definition: BKE_modifier.h:114
struct ModifierData * BKE_modifiers_get_virtual_modifierlist(const struct Object *ob, struct VirtualModifierData *data)
@ eModifierTypeType_OnlyDeform
Definition: BKE_modifier.h:58
ModifierApplyFlag
Definition: BKE_modifier.h:126
@ MOD_APPLY_USECACHE
Definition: BKE_modifier.h:131
@ MOD_APPLY_RENDER
Definition: BKE_modifier.h:128
General operations, lookup, etc. for blender objects.
void BKE_boundbox_init_from_minmax(struct BoundBox *bb, const float min[3], const float max[3])
Definition: object.c:3778
void BKE_object_free_derived_caches(struct Object *ob)
Definition: object.c:1719
void BKE_object_eval_assign_data(struct Object *object, struct ID *data, bool is_owned)
Definition: object.c:1687
#define BLI_assert(a)
Definition: BLI_assert.h:58
MINLINE float saacosf(float f)
#define M_PI
Definition: BLI_math_base.h:38
MINLINE void madd_v3_v3fl(float r[3], const float a[3], float f)
MINLINE float normalize_v3(float r[3])
MINLINE void copy_v3_v3(float r[3], const float a[3])
MINLINE void add_v3_v3(float r[3], const float a[3])
Random number functions.
void BLI_rng_free(struct RNG *rng) ATTR_NONNULL(1)
Definition: rand.cc:76
struct RNG * BLI_rng_new(unsigned int seed)
Definition: rand.cc:54
float BLI_rng_get_float(struct RNG *rng) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
Definition: rand.cc:120
#define STRNCPY(dst, src)
Definition: BLI_string.h:163
#define INIT_MINMAX(min, max)
#define ARRAY_SIZE(arr)
#define UNUSED(x)
#define DO_MAX(vec, max)
#define MEMCMP_STRUCT_AFTER_IS_ZERO(struct_var, member)
#define DO_MIN(vec, min)
#define MEMCPY_STRUCT_AFTER(struct_dst, struct_src, member)
#define STREQ(a, b)
#define BLO_read_data_address(reader, ptr_p)
#define BLO_write_id_struct(writer, struct_name, id_address, id)
#define BLO_read_id_address(reader, lib, id_ptr_p)
#define BLO_expand(expander, id)
void BLO_read_pointer_array(BlendDataReader *reader, void **ptr_p)
Definition: readfile.c:5727
bool BLO_write_is_undo(BlendWriter *writer)
Definition: writefile.c:1412
void BLO_write_pointer_array(BlendWriter *writer, uint num, const void *data_ptr)
Definition: writefile.c:1388
#define BLT_I18NCONTEXT_ID_HAIR
struct Depsgraph Depsgraph
Definition: DEG_depsgraph.h:51
@ DAG_EVAL_RENDER
Definition: DEG_depsgraph.h:62
eEvaluationMode DEG_get_mode(const Depsgraph *graph)
#define FILTER_ID_HA
Definition: DNA_ID.h:736
@ INDEX_ID_HA
Definition: DNA_ID.h:830
@ ID_HA
Definition: DNA_ID_enums.h:93
#define CD_MASK_ALL
@ CD_PROP_FLOAT
@ CD_PROP_FLOAT3
@ CD_HAIRCURVE
@ CD_HAIRMAPPING
#define CD_TEMP_CHUNK_SIZE
#define DNA_struct_default_get(struct_name)
Definition: DNA_defaults.h:44
struct Hair Hair
@ eModifierMode_Render
@ eModifierMode_Realtime
Object is a sort of wrapper for general info.
@ BOUNDBOX_DIRTY
@ OB_HAIR
_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 const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_BOOL GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLushort pattern _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble u2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLdouble GLdouble v2 _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLdouble GLdouble nz _GL_VOID_RET _GL_VOID GLfloat GLfloat nz _GL_VOID_RET _GL_VOID GLint GLint nz _GL_VOID_RET _GL_VOID GLshort GLshort nz _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const GLfloat *values _GL_VOID_RET _GL_VOID GLsizei const GLushort *values _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID const GLuint const GLclampf *priorities _GL_VOID_RET _GL_VOID GLdouble y _GL_VOID_RET _GL_VOID GLfloat y _GL_VOID_RET _GL_VOID GLint y _GL_VOID_RET _GL_VOID GLshort y _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLfloat GLfloat z _GL_VOID_RET _GL_VOID GLint GLint z _GL_VOID_RET _GL_VOID GLshort GLshort z _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble w _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat w _GL_VOID_RET _GL_VOID GLint GLint GLint w _GL_VOID_RET _GL_VOID GLshort GLshort GLshort w _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble y2 _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat y2 _GL_VOID_RET _GL_VOID GLint GLint GLint y2 _GL_VOID_RET _GL_VOID GLshort GLshort GLshort y2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLuint *buffer _GL_VOID_RET _GL_VOID GLdouble t _GL_VOID_RET _GL_VOID GLfloat t _GL_VOID_RET _GL_VOID GLint t _GL_VOID_RET _GL_VOID GLshort t _GL_VOID_RET _GL_VOID GLdouble t
Read Guarded memory(de)allocation.
#define MEM_SAFE_FREE(v)
static void init_data(ModifierData *md)
Scene scene
Curve curve
const Depsgraph * depsgraph
Hair * BKE_hair_copy_for_eval(Hair *hair_src, bool reference)
Definition: hair.c:321
static void hair_random(Hair *hair)
Definition: hair.c:205
void * BKE_hair_add(Main *bmain, const char *name)
Definition: hair.c:250
static void hair_init_data(ID *id)
Definition: hair.c:59
IDTypeInfo IDType_ID_HA
Definition: hair.c:177
static const char * HAIR_ATTR_RADIUS
Definition: hair.c:53
Hair * BKE_hair_new_for_eval(const Hair *hair_src, int totpoint, int totcurve)
Definition: hair.c:304
static void hair_free_data(ID *id)
Definition: hair.c:93
void BKE_hair_update_customdata_pointers(Hair *hair)
Definition: hair.c:289
static void hair_blend_read_expand(BlendExpander *expander, ID *id)
Definition: hair.c:169
void BKE_hair_batch_cache_dirty_tag(Hair *hair, int mode)
Definition: hair.c:413
static void hair_copy_data(Main *UNUSED(bmain), ID *id_dst, const ID *id_src, const int flag)
Definition: hair.c:79
BoundBox * BKE_hair_boundbox_get(Object *ob)
Definition: hair.c:257
void(* BKE_hair_batch_cache_free_cb)(Hair *hair)
Definition: hair.c:411
static const char * HAIR_ATTR_POSITION
Definition: hair.c:52
static void hair_blend_write(BlendWriter *writer, ID *id, const void *id_address)
Definition: hair.c:114
void BKE_hair_batch_cache_free(Hair *hair)
Definition: hair.c:420
static void hair_blend_read_lib(BlendLibReader *reader, ID *id)
Definition: hair.c:161
bool BKE_hair_customdata_required(Hair *UNUSED(hair), CustomDataLayer *layer)
Definition: hair.c:297
void BKE_hair_data_update(struct Depsgraph *depsgraph, struct Scene *scene, Object *object)
Definition: hair.c:395
static void hair_foreach_id(ID *id, LibraryForeachIDData *data)
Definition: hair.c:106
static void hair_blend_read_data(BlendDataReader *reader, ID *id)
Definition: hair.c:146
void(* BKE_hair_batch_cache_dirty_tag_cb)(Hair *hair, int mode)
Definition: hair.c:410
static Hair * hair_evaluate_modifiers(struct Depsgraph *depsgraph, struct Scene *scene, Object *object, Hair *hair_input)
Definition: hair.c:333
#define sinf(x)
#define cosf(x)
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:41
void *(* MEM_dupallocN)(const void *vmemh)
Definition: mallocn.c:42
void *(* MEM_callocN)(size_t len, const char *str)
Definition: mallocn.c:45
static unsigned a[3]
Definition: RandGen.cpp:92
#define min(a, b)
Definition: sort.c:51
struct Material ** mat
struct CustomData pdata
float(* co)[3]
int totcurve
struct HairCurve * curves
float * radius
struct HairMaping * mapping
short totcol
struct AnimData * adt
int totpoint
void * batch_cache
struct CustomData cdata
short id_code
Definition: BKE_idtype.h:120
Definition: DNA_ID.h:273
struct Library * lib
Definition: DNA_ID.h:277
int us
Definition: DNA_ID.h:293
char name[66]
Definition: DNA_ID.h:283
Definition: BKE_main.h:116
struct ModifierData * next
ModifierTypeFlag flags
Definition: BKE_modifier.h:174
ModifierTypeType type
Definition: BKE_modifier.h:173
void(* deformVerts)(struct ModifierData *md, const struct ModifierEvalContext *ctx, struct Mesh *mesh, float(*vertexCos)[3], int numVerts)
Definition: BKE_modifier.h:197
struct Hair *(* modifyHair)(struct ModifierData *md, const struct ModifierEvalContext *ctx, struct Hair *hair)
Definition: BKE_modifier.h:248
struct BoundBox * bb
Object_Runtime runtime
void * data
Definition: rand.cc:48
float max