Blender  V3.3
texture_pointdensity.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later
2  * Copyright 2001-2002 NaN Holding BV. All rights reserved. */
3 
8 #include <math.h>
9 #include <stdio.h>
10 #include <stdlib.h>
11 
12 #include "MEM_guardedalloc.h"
13 
14 #include "BLI_blenlib.h"
15 #include "BLI_kdopbvh.h"
16 #include "BLI_math.h"
17 #include "BLI_noise.h"
18 #include "BLI_task.h"
19 #include "BLI_utildefines.h"
20 
21 #include "BLT_translation.h"
22 
23 #include "DNA_mesh_types.h"
24 #include "DNA_meshdata_types.h"
25 #include "DNA_object_types.h"
26 #include "DNA_particle_types.h"
27 #include "DNA_texture_types.h"
28 
29 #include "BKE_colorband.h"
30 #include "BKE_colortools.h"
31 #include "BKE_customdata.h"
32 #include "BKE_deform.h"
33 #include "BKE_lattice.h"
34 #include "BKE_mesh.h"
35 #include "BKE_object.h"
36 #include "BKE_particle.h"
37 #include "BKE_scene.h"
38 
39 #include "DEG_depsgraph.h"
40 #include "DEG_depsgraph_query.h"
41 
42 #include "render_types.h"
43 #include "texture_common.h"
44 
45 #include "RE_texture.h"
46 
47 static ThreadMutex sample_mutex = PTHREAD_MUTEX_INITIALIZER;
48 
50 {
51  int pd_bitflag = 0;
52 
53  if (pd->source == TEX_PD_PSYS) {
57  pd_bitflag |= POINT_DATA_VEL;
58  }
59  if ((pd->color_source == TEX_PD_COLOR_PARTAGE) ||
61  pd_bitflag |= POINT_DATA_LIFE;
62  }
63  }
64  else if (pd->source == TEX_PD_OBJECT) {
65  if (ELEM(pd->ob_color_source,
69  pd_bitflag |= POINT_DATA_COLOR;
70  }
71  }
72 
73  return pd_bitflag;
74 }
75 
77  float **r_data_velocity,
78  float **r_data_life,
79  float **r_data_color)
80 {
81  const int data_used = point_data_used(pd);
82  const int totpoint = pd->totpoints;
83  float *data = pd->point_data;
84  int offset = 0;
85 
86  if (data_used & POINT_DATA_VEL) {
87  if (r_data_velocity) {
88  *r_data_velocity = data + offset;
89  }
90  offset += 3 * totpoint;
91  }
92  else {
93  if (r_data_velocity) {
94  *r_data_velocity = NULL;
95  }
96  }
97 
98  if (data_used & POINT_DATA_LIFE) {
99  if (r_data_life) {
100  *r_data_life = data + offset;
101  }
102  offset += totpoint;
103  }
104  else {
105  if (r_data_life) {
106  *r_data_life = NULL;
107  }
108  }
109 
110  if (data_used & POINT_DATA_COLOR) {
111  if (r_data_color) {
112  *r_data_color = data + offset;
113  }
114  offset += 3 * totpoint;
115  }
116  else {
117  if (r_data_color) {
118  *r_data_color = NULL;
119  }
120  }
121 }
122 
123 /* additional data stored alongside the point density BVH,
124  * accessible by point index number to retrieve other information
125  * such as particle velocity or lifetime */
127 {
128  const int totpoints = pd->totpoints;
129  int data_used = point_data_used(pd);
130  int data_size = 0;
131 
132  if (data_used & POINT_DATA_VEL) {
133  /* store 3 channels of velocity data */
134  data_size += 3;
135  }
136  if (data_used & POINT_DATA_LIFE) {
137  /* store 1 channel of lifetime data */
138  data_size += 1;
139  }
140  if (data_used & POINT_DATA_COLOR) {
141  /* store 3 channels of RGB data */
142  data_size += 3;
143  }
144 
145  if (data_size) {
146  pd->point_data = MEM_callocN(sizeof(float) * data_size * totpoints, "particle point data");
147  }
148 }
149 
152 {
154  ParticleCacheKey *cache;
156  ParticleData *pa = NULL;
157  float cfra = BKE_scene_ctime_get(scene);
158  int i /*, Childexists*/ /* UNUSED */;
159  int total_particles;
160  int data_used;
161  float *data_vel, *data_life;
162  float partco[3];
163  const bool use_render_params = (DEG_get_mode(depsgraph) == DAG_EVAL_RENDER);
164 
165  data_used = point_data_used(pd);
166 
167  if (!psys_check_enabled(ob, psys, use_render_params)) {
168  return;
169  }
170 
171  sim.depsgraph = depsgraph;
172  sim.scene = scene;
173  sim.ob = ob;
174  sim.psys = psys;
175  sim.psmd = psys_get_modifier(ob, psys);
176 
177  /* in case ob->imat isn't up-to-date */
178  invert_m4_m4(ob->imat, ob->obmat);
179 
180  total_particles = psys->totpart + psys->totchild;
181  psys_sim_data_init(&sim);
182 
183  pd->point_tree = BLI_bvhtree_new(total_particles, 0.0, 4, 6);
184  pd->totpoints = total_particles;
185  alloc_point_data(pd);
186  point_data_pointers(pd, &data_vel, &data_life, NULL);
187 
188 #if 0 /* UNUSED */
189  if (psys->totchild > 0 && !(psys->part->draw & PART_DRAW_PARENT)) {
190  childexists = 1;
191  }
192 #endif
193 
194  for (i = 0, pa = psys->particles; i < total_particles; i++, pa++) {
195 
196  if (psys->part->type == PART_HAIR) {
197  /* hair particles */
198  if (i < psys->totpart && psys->pathcache) {
199  cache = psys->pathcache[i];
200  }
201  else if (i >= psys->totpart && psys->childcache) {
202  cache = psys->childcache[i - psys->totpart];
203  }
204  else {
205  continue;
206  }
207 
208  cache += cache->segments; /* use endpoint */
209 
210  copy_v3_v3(state.co, cache->co);
211  zero_v3(state.vel);
212  state.time = 0.0f;
213  }
214  else {
215  /* emitter particles */
216  state.time = cfra;
217 
218  if (!psys_get_particle_state(&sim, i, &state, 0)) {
219  continue;
220  }
221 
222  if (data_used & POINT_DATA_LIFE) {
223  if (i < psys->totpart) {
224  state.time = (cfra - pa->time) / pa->lifetime;
225  }
226  else {
227  ChildParticle *cpa = (psys->child + i) - psys->totpart;
228  float pa_birthtime, pa_dietime;
229 
230  state.time = psys_get_child_time(psys, cpa, cfra, &pa_birthtime, &pa_dietime);
231  }
232  }
233  }
234 
235  copy_v3_v3(partco, state.co);
236 
238  mul_m4_v3(ob->imat, partco);
239  }
240  else if (pd->psys_cache_space == TEX_PD_OBJECTLOC) {
241  sub_v3_v3(partco, ob->loc);
242  }
243  else {
244  /* TEX_PD_WORLDSPACE */
245  }
246 
247  BLI_bvhtree_insert(pd->point_tree, i, partco, 1);
248 
249  if (data_vel) {
250  data_vel[i * 3 + 0] = state.vel[0];
251  data_vel[i * 3 + 1] = state.vel[1];
252  data_vel[i * 3 + 2] = state.vel[2];
253  }
254  if (data_life) {
255  data_life[i] = state.time;
256  }
257  }
258 
260 
261  psys_sim_data_free(&sim);
262 }
263 
265  Object *UNUSED(ob),
266  Mesh *mesh,
267  float *data_color)
268 {
269  const MLoop *mloop = mesh->mloop;
270  const int totloop = mesh->totloop;
271  char layername[MAX_CUSTOMDATA_LAYER_NAME];
272  int i;
273 
274  BLI_assert(data_color);
275 
277  return;
278  }
281  const MLoopCol *mcol = CustomData_get_layer_named(&mesh->ldata, CD_PROP_BYTE_COLOR, layername);
282  if (!mcol) {
283  return;
284  }
285 
286  /* Stores the number of MLoops using the same vertex, so we can normalize colors. */
287  int *mcorners = MEM_callocN(sizeof(int) * pd->totpoints, "point density corner count");
288 
289  for (i = 0; i < totloop; i++) {
290  int v = mloop[i].v;
291 
292  if (mcorners[v] == 0) {
293  rgb_uchar_to_float(&data_color[v * 3], &mcol[i].r);
294  }
295  else {
296  float col[3];
297  rgb_uchar_to_float(col, &mcol[i].r);
298  add_v3_v3(&data_color[v * 3], col);
299  }
300 
301  ++mcorners[v];
302  }
303 
304  /* Normalize colors by averaging over mcorners.
305  * All the corners share the same vertex, ie. occupy the same point in space.
306  */
307  for (i = 0; i < pd->totpoints; i++) {
308  if (mcorners[i] > 0) {
309  mul_v3_fl(&data_color[i * 3], 1.0f / mcorners[i]);
310  }
311  }
312 
313  MEM_freeN(mcorners);
314 }
315 
317  Object *ob,
318  Mesh *mesh,
319  float *data_color)
320 {
321  const int totvert = mesh->totvert;
322  int mdef_index;
323  int i;
324 
325  BLI_assert(data_color);
326 
328  if (!mdef) {
329  return;
330  }
332  if (mdef_index < 0) {
333  mdef_index = BKE_object_defgroup_active_index_get(ob) - 1;
334  }
335  if (mdef_index < 0) {
336  return;
337  }
338 
339  const MDeformVert *dv;
340  for (i = 0, dv = mdef; i < totvert; i++, dv++, data_color += 3) {
341  MDeformWeight *dw;
342  int j;
343 
344  for (j = 0, dw = dv->dw; j < dv->totweight; j++, dw++) {
345  if (dw->def_nr == mdef_index) {
346  copy_v3_fl(data_color, dw->weight);
347  break;
348  }
349  }
350  }
351 }
352 
353 static void pointdensity_cache_vertex_normal(Mesh *mesh, float *data_color)
354 {
355  BLI_assert(data_color);
356  const float(*vert_normals)[3] = BKE_mesh_vertex_normals_ensure(mesh);
357  memcpy(data_color, vert_normals, sizeof(float[3]) * mesh->totvert);
358 }
359 
361 {
362  float *data_color;
363  int i;
364  MVert *mvert = NULL, *mv;
365  Mesh *mesh = ob->data;
366 
367 #if 0 /* UNUSED */
369  mask.fmask |= CD_MASK_MTFACE | CD_MASK_MCOL;
370  switch (pd->ob_color_source) {
372  mask.lmask |= CD_MASK_PROP_BYTE_COLOR;
373  break;
375  mask.vmask |= CD_MASK_MDEFORMVERT;
376  break;
377  }
378 #endif
379 
380  mvert = mesh->mvert; /* local object space */
381  pd->totpoints = mesh->totvert;
382  if (pd->totpoints == 0) {
383  return;
384  }
385 
386  pd->point_tree = BLI_bvhtree_new(pd->totpoints, 0.0, 4, 6);
387  alloc_point_data(pd);
388  point_data_pointers(pd, NULL, NULL, &data_color);
389 
390  for (i = 0, mv = mvert; i < pd->totpoints; i++, mv++) {
391  float co[3];
392 
393  copy_v3_v3(co, mv->co);
394 
395  switch (pd->ob_cache_space) {
396  case TEX_PD_OBJECTSPACE:
397  break;
398  case TEX_PD_OBJECTLOC:
399  mul_m4_v3(ob->obmat, co);
400  sub_v3_v3(co, ob->loc);
401  break;
402  case TEX_PD_WORLDSPACE:
403  default:
404  mul_m4_v3(ob->obmat, co);
405  break;
406  }
407 
408  BLI_bvhtree_insert(pd->point_tree, i, co, 1);
409  }
410 
411  switch (pd->ob_color_source) {
413  pointdensity_cache_vertex_color(pd, ob, mesh, data_color);
414  break;
416  pointdensity_cache_vertex_weight(pd, ob, mesh, data_color);
417  break;
420  break;
421  }
422 
424 }
425 
427 {
428  if (pd == NULL) {
429  return;
430  }
431 
432  if (pd->point_tree) {
434  pd->point_tree = NULL;
435  }
436 
437  if (pd->source == TEX_PD_PSYS) {
438  Object *ob = pd->object;
439  ParticleSystem *psys;
440 
441  if (!ob || !pd->psys) {
442  return;
443  }
444 
445  psys = BLI_findlink(&ob->particlesystem, pd->psys - 1);
446  if (!psys) {
447  return;
448  }
449 
450  pointdensity_cache_psys(depsgraph, scene, pd, ob, psys);
451  }
452  else if (pd->source == TEX_PD_OBJECT) {
453  Object *ob = pd->object;
454  if (ob && ob->type == OB_MESH) {
456  }
457  }
458 }
459 
461 {
462  if (pd == NULL) {
463  return;
464  }
465 
466  if (pd->point_tree) {
468  pd->point_tree = NULL;
469  }
470 
472  pd->totpoints = 0;
473 }
474 
475 typedef struct PointDensityRangeData {
476  float *density;
481  float *vec;
482  float *col;
483  float softness;
486  float *age;
488  float velscale;
490 
491 static float density_falloff(PointDensityRangeData *pdr, int index, float squared_dist)
492 {
493  const float dist = (pdr->squared_radius - squared_dist) / pdr->squared_radius * 0.5f;
494  float density = 0.0f;
495 
496  switch (pdr->falloff_type) {
497  case TEX_PD_FALLOFF_STD:
498  density = dist;
499  break;
501  density = 3.0f * dist * dist - 2.0f * dist * dist * dist;
502  break;
503  case TEX_PD_FALLOFF_SOFT:
504  density = pow(dist, pdr->softness);
505  break;
507  density = pdr->squared_radius;
508  break;
509  case TEX_PD_FALLOFF_ROOT:
510  density = sqrtf(dist);
511  break;
513  if (pdr->point_data_life) {
514  density = dist * MIN2(pdr->point_data_life[index], 1.0f);
515  }
516  else {
517  density = dist;
518  }
519  break;
521  if (pdr->point_data_velocity) {
522  density = dist * len_v3(&pdr->point_data_velocity[index * 3]) * pdr->velscale;
523  }
524  else {
525  density = dist;
526  }
527  break;
528  }
529 
530  if (pdr->density_curve && dist != 0.0f) {
532  density = BKE_curvemapping_evaluateF(pdr->density_curve, 0, density / dist) * dist;
533  }
534 
535  return density;
536 }
537 
538 static void accum_density(void *userdata, int index, const float co[3], float squared_dist)
539 {
540  PointDensityRangeData *pdr = (PointDensityRangeData *)userdata;
541  float density = 0.0f;
542 
543  UNUSED_VARS(co);
544 
545  if (pdr->point_data_velocity) {
546  pdr->vec[0] += pdr->point_data_velocity[index * 3 + 0]; // * density;
547  pdr->vec[1] += pdr->point_data_velocity[index * 3 + 1]; // * density;
548  pdr->vec[2] += pdr->point_data_velocity[index * 3 + 2]; // * density;
549  }
550  if (pdr->point_data_life) {
551  *pdr->age += pdr->point_data_life[index]; // * density;
552  }
553  if (pdr->point_data_color) {
554  add_v3_v3(pdr->col, &pdr->point_data_color[index * 3]); // * density;
555  }
556 
557  density = density_falloff(pdr, index, squared_dist);
558 
559  *pdr->density += density;
560 }
561 
564  float *density,
565  float *vec,
566  float *age,
567  float *col,
568  struct CurveMapping *density_curve,
569  float velscale)
570 {
571  pdr->squared_radius = pd->radius * pd->radius;
572  pdr->density = density;
573  pdr->falloff_type = pd->falloff_type;
574  pdr->vec = vec;
575  pdr->age = age;
576  pdr->col = col;
577  pdr->softness = pd->falloff_softness;
578  pdr->noise_influence = pd->noise_influence;
580  pd, &pdr->point_data_velocity, &pdr->point_data_life, &pdr->point_data_color);
581  pdr->density_curve = density_curve;
582  pdr->velscale = velscale;
583 }
584 
585 static int pointdensity(PointDensity *pd,
586  const float texvec[3],
587  TexResult *texres,
588  float r_vec[3],
589  float *r_age,
590  float r_col[3])
591 {
592  int retval = TEX_INT;
594  float density = 0.0f, age = 0.0f;
595  float vec[3] = {0.0f, 0.0f, 0.0f}, col[3] = {0.0f, 0.0f, 0.0f}, co[3];
596  float turb, noise_fac;
597  int num = 0;
598 
599  texres->tin = 0.0f;
600 
602  &pdr,
603  &density,
604  vec,
605  &age,
606  col,
608  pd->falloff_speed_scale * 0.001f);
609  noise_fac = pd->noise_fac * 0.5f; /* better default */
610 
611  copy_v3_v3(co, texvec);
612 
613  if (point_data_used(pd)) {
614  /* does a BVH lookup to find accumulated density and additional point data *
615  * stores particle velocity vector in 'vec', and particle lifetime in 'time' */
616  num = BLI_bvhtree_range_query(pd->point_tree, co, pd->radius, accum_density, &pdr);
617  if (num > 0) {
618  age /= num;
619  mul_v3_fl(vec, 1.0f / num);
620  mul_v3_fl(col, 1.0f / num);
621  }
622 
623  /* reset */
624  density = 0.0f;
625  zero_v3(vec);
626  zero_v3(col);
627  }
628 
629  if (pd->flag & TEX_PD_TURBULENCE) {
631  texvec[0] + vec[0],
632  texvec[1] + vec[1],
633  texvec[2] + vec[2],
634  pd->noise_depth,
635  0,
636  pd->noise_basis);
637 
638  turb -= 0.5f; /* re-center 0.0-1.0 range around 0 to prevent offsetting result */
639 
640  /* now we have an offset coordinate to use for the density lookup */
641  co[0] = texvec[0] + noise_fac * turb;
642  co[1] = texvec[1] + noise_fac * turb;
643  co[2] = texvec[2] + noise_fac * turb;
644  }
645 
646  /* BVH query with the potentially perturbed coordinates */
647  num = BLI_bvhtree_range_query(pd->point_tree, co, pd->radius, accum_density, &pdr);
648  if (num > 0) {
649  age /= num;
650  mul_v3_fl(vec, 1.0f / num);
651  mul_v3_fl(col, 1.0f / num);
652  }
653 
654  texres->tin = density;
655  if (r_age != NULL) {
656  *r_age = age;
657  }
658  if (r_vec != NULL) {
659  copy_v3_v3(r_vec, vec);
660  }
661  if (r_col != NULL) {
662  copy_v3_v3(r_col, col);
663  }
664 
665  return retval;
666 }
667 
668 static void pointdensity_color(
669  PointDensity *pd, TexResult *texres, float age, const float vec[3], const float col[3])
670 {
671  copy_v4_fl(texres->trgba, 1.0f);
672 
673  if (pd->source == TEX_PD_PSYS) {
674  float rgba[4];
675 
676  switch (pd->color_source) {
678  if (pd->coba) {
679  if (BKE_colorband_evaluate(pd->coba, age, rgba)) {
680  texres->talpha = true;
681  copy_v3_v3(texres->trgba, rgba);
682  texres->tin *= rgba[3];
683  texres->trgba[3] = texres->tin;
684  }
685  }
686  break;
687  case TEX_PD_COLOR_PARTSPEED: {
688  float speed = len_v3(vec) * pd->speed_scale;
689 
690  if (pd->coba) {
691  if (BKE_colorband_evaluate(pd->coba, speed, rgba)) {
692  texres->talpha = true;
693  copy_v3_v3(texres->trgba, rgba);
694  texres->tin *= rgba[3];
695  texres->trgba[3] = texres->tin;
696  }
697  }
698  break;
699  }
701  texres->talpha = true;
702  mul_v3_v3fl(texres->trgba, vec, pd->speed_scale);
703  texres->trgba[3] = texres->tin;
704  break;
706  default:
707  break;
708  }
709  }
710  else {
711  float rgba[4];
712 
713  switch (pd->ob_color_source) {
715  texres->talpha = true;
716  copy_v3_v3(texres->trgba, col);
717  texres->trgba[3] = texres->tin;
718  break;
720  texres->talpha = true;
721  if (pd->coba && BKE_colorband_evaluate(pd->coba, col[0], rgba)) {
722  copy_v3_v3(texres->trgba, rgba);
723  texres->tin *= rgba[3];
724  }
725  else {
726  copy_v3_v3(texres->trgba, col);
727  }
728  texres->trgba[3] = texres->tin;
729  break;
731  texres->talpha = true;
732  copy_v3_v3(texres->trgba, col);
733  texres->trgba[3] = texres->tin;
734  break;
736  default:
737  break;
738  }
739  }
740 }
741 
742 static void sample_dummy_point_density(int resolution, float *values)
743 {
744  memset(values, 0, sizeof(float[4]) * resolution * resolution * resolution);
745 }
746 
748  Scene *scene,
749  Object *object,
750  ParticleSystem *psys,
751  float radius,
752  float min[3],
753  float max[3])
754 {
755  const float size[3] = {radius, radius, radius};
756  const float cfra = BKE_scene_ctime_get(scene);
757  ParticleSettings *part = psys->part;
759  ParticleData *pa = NULL;
760  int i;
761  int total_particles;
762  float mat[4][4], imat[4][4];
763 
764  INIT_MINMAX(min, max);
765  if (part->type == PART_HAIR) {
766  /* TODO(sergey): Not supported currently. */
767  return;
768  }
769 
770  unit_m4(mat);
771 
772  sim.depsgraph = depsgraph;
773  sim.scene = scene;
774  sim.ob = object;
775  sim.psys = psys;
776  sim.psmd = psys_get_modifier(object, psys);
777 
778  invert_m4_m4(imat, object->obmat);
779  total_particles = psys->totpart + psys->totchild;
780  psys_sim_data_init(&sim);
781 
782  for (i = 0, pa = psys->particles; i < total_particles; i++, pa++) {
783  float co_object[3], co_min[3], co_max[3];
785  state.time = cfra;
786  if (!psys_get_particle_state(&sim, i, &state, 0)) {
787  continue;
788  }
789  mul_v3_m4v3(co_object, imat, state.co);
790  sub_v3_v3v3(co_min, co_object, size);
791  add_v3_v3v3(co_max, co_object, size);
792  minmax_v3v3_v3(min, max, co_min);
793  minmax_v3v3_v3(min, max, co_max);
794  }
795 
796  psys_sim_data_free(&sim);
797 }
798 
800 {
802 
803  /* Same matrices/resolution as dupli_render_particle_set(). */
807 }
808 
810  struct PointDensity *pd,
811  float r_min[3],
812  float r_max[3])
813 {
815  Object *object = pd->object;
816  if (object == NULL) {
817  zero_v3(r_min);
818  zero_v3(r_max);
819  return;
820  }
821  if (pd->source == TEX_PD_PSYS) {
822  ParticleSystem *psys;
823 
824  if (pd->psys == 0) {
825  zero_v3(r_min);
826  zero_v3(r_max);
827  return;
828  }
829  psys = BLI_findlink(&object->particlesystem, pd->psys - 1);
830  if (psys == NULL) {
831  zero_v3(r_min);
832  zero_v3(r_max);
833  return;
834  }
835 
836  particle_system_minmax(depsgraph, scene, object, psys, pd->radius, r_min, r_max);
837  }
838  else {
839  const float radius[3] = {pd->radius, pd->radius, pd->radius};
840  const BoundBox *bb = BKE_object_boundbox_get(object);
841 
842  if (bb != NULL) {
843  BLI_assert((bb->flag & BOUNDBOX_DIRTY) == 0);
844  copy_v3_v3(r_min, bb->vec[0]);
845  copy_v3_v3(r_max, bb->vec[6]);
846  /* Adjust texture space to include density points on the boundaries. */
847  sub_v3_v3(r_min, radius);
848  add_v3_v3(r_max, radius);
849  }
850  else {
851  zero_v3(r_min);
852  zero_v3(r_max);
853  }
854  }
855 }
856 
857 typedef struct SampleCallbackData {
860  float *min, *dim;
861  float *values;
863 
864 static void point_density_sample_func(void *__restrict data_v,
865  const int iter,
866  const TaskParallelTLS *__restrict UNUSED(tls))
867 {
869 
870  const int resolution = data->resolution;
871  const int resolution2 = resolution * resolution;
872  const float *min = data->min, *dim = data->dim;
873  PointDensity *pd = data->pd;
874  float *values = data->values;
875 
876  if (!pd || !pd->point_tree) {
877  return;
878  }
879 
880  size_t z = (size_t)iter;
881  for (size_t y = 0; y < resolution; y++) {
882  for (size_t x = 0; x < resolution; x++) {
883  size_t index = z * resolution2 + y * resolution + x;
884  float texvec[3];
885  float age, vec[3], col[3];
886  TexResult texres;
887 
888  copy_v3_v3(texvec, min);
889  texvec[0] += dim[0] * (float)x / (float)resolution;
890  texvec[1] += dim[1] * (float)y / (float)resolution;
891  texvec[2] += dim[2] * (float)z / (float)resolution;
892 
893  pointdensity(pd, texvec, &texres, vec, &age, col);
894  pointdensity_color(pd, &texres, age, vec, col);
895 
896  copy_v3_v3(&values[index * 4 + 0], texres.trgba);
897  values[index * 4 + 3] = texres.tin;
898  }
899  }
900 }
901 
903  PointDensity *pd,
904  const int resolution,
905  float *values)
906 {
907  Object *object = pd->object;
908  float min[3], max[3], dim[3];
909 
910  /* TODO(sergey): Implement some sort of assert() that point density
911  * was cached already.
912  */
913 
914  if (object == NULL) {
915  sample_dummy_point_density(resolution, values);
916  return;
917  }
918 
922  sub_v3_v3v3(dim, max, min);
923  if (dim[0] <= 0.0f || dim[1] <= 0.0f || dim[2] <= 0.0f) {
924  sample_dummy_point_density(resolution, values);
925  return;
926  }
927 
929  data.pd = pd;
930  data.resolution = resolution;
931  data.min = min;
932  data.dim = dim;
933  data.values = values;
934  TaskParallelSettings settings;
936  settings.use_threading = (resolution > 32);
937  BLI_task_parallel_range(0, resolution, &data, point_density_sample_func, &settings);
938 
939  free_pointdensity(pd);
940 }
941 
943 {
944  free_pointdensity(pd);
945 }
946 
948 {
949 }
typedef float(TangentPoint)[2]
bool BKE_colorband_evaluate(const struct ColorBand *coba, float in, float out[4])
void BKE_curvemapping_init(struct CurveMapping *cumap)
Definition: colortools.c:1235
float BKE_curvemapping_evaluateF(const struct CurveMapping *cumap, int cur, float value)
CustomData interface, see also DNA_customdata_types.h.
bool CustomData_has_layer(const struct CustomData *data, int type)
const CustomData_MeshMasks CD_MASK_BAREMESH
Definition: customdata.cc:2051
void * CustomData_get_layer_named(const struct CustomData *data, int type, const char *name)
void * CustomData_get_layer(const struct CustomData *data, int type)
void CustomData_validate_layer_name(const struct CustomData *data, int type, const char *name, char *outname)
support for deformation groups and hooks.
int BKE_object_defgroup_active_index_get(const struct Object *ob)
int BKE_id_defgroup_name_index(const struct ID *id, const char *name)
const float(* BKE_mesh_vertex_normals_ensure(const struct Mesh *mesh))[3]
General operations, lookup, etc. for blender objects.
const struct BoundBox * BKE_object_boundbox_get(struct Object *ob)
Definition: object.cc:3684
bool psys_check_enabled(struct Object *ob, struct ParticleSystem *psys, bool use_render_params)
Definition: particle.c:801
float psys_get_child_time(struct ParticleSystem *psys, struct ChildParticle *cpa, float cfra, float *birthtime, float *dietime)
Definition: particle.c:4494
void psys_sim_data_free(struct ParticleSimulationData *sim)
Definition: particle.c:726
struct ParticleSystemModifierData * psys_get_modifier(struct Object *ob, struct ParticleSystem *psys)
Definition: particle.c:2230
void psys_sim_data_init(struct ParticleSimulationData *sim)
Definition: particle.c:685
bool psys_get_particle_state(struct ParticleSimulationData *sim, int p, struct ParticleKey *state, bool always)
Definition: particle.c:4884
float BKE_scene_ctime_get(const struct Scene *scene)
#define BLI_assert(a)
Definition: BLI_assert.h:46
int BLI_bvhtree_range_query(BVHTree *tree, const float co[3], float radius, BVHTree_RangeQuery callback, void *userdata)
Definition: BLI_kdopbvh.c:2080
void BLI_bvhtree_balance(BVHTree *tree)
Definition: BLI_kdopbvh.c:937
BVHTree * BLI_bvhtree_new(int maxsize, float epsilon, char tree_type, char axis)
Definition: BLI_kdopbvh.c:854
void BLI_bvhtree_free(BVHTree *tree)
Definition: BLI_kdopbvh.c:926
void BLI_bvhtree_insert(BVHTree *tree, int index, const float co[3], int numpoints)
Definition: BLI_kdopbvh.c:979
void * BLI_findlink(const struct ListBase *listbase, int number) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
void rgb_uchar_to_float(float r_col[3], const unsigned char col_ub[3])
Definition: math_color.c:376
void unit_m4(float m[4][4])
Definition: rct.c:1090
bool invert_m4_m4(float R[4][4], const float A[4][4])
Definition: math_matrix.c:1287
void mul_m4_v3(const float M[4][4], float r[3])
Definition: math_matrix.c:729
void mul_v3_m4v3(float r[3], const float M[4][4], const float v[3])
Definition: math_matrix.c:739
void minmax_v3v3_v3(float min[3], float max[3], const float vec[3])
Definition: math_vector.c:867
MINLINE void sub_v3_v3(float r[3], const float a[3])
MINLINE void sub_v3_v3v3(float r[3], const float a[3], const float b[3])
MINLINE void mul_v3_fl(float r[3], float f)
MINLINE void copy_v3_v3(float r[3], const float a[3])
MINLINE void add_v3_v3v3(float r[3], const float a[3], const float b[3])
MINLINE void copy_v3_fl(float r[3], float f)
MINLINE void zero_v3(float r[3])
MINLINE void mul_v3_v3fl(float r[3], const float a[3], float f)
MINLINE void add_v3_v3(float r[3], const float a[3])
MINLINE void copy_v4_fl(float r[4], float f)
MINLINE float len_v3(const float a[3]) ATTR_WARN_UNUSED_RESULT
float BLI_noise_generic_turbulence(float noisesize, float x, float y, float z, int oct, bool hard, int noisebasis)
Definition: noise.c:1207
void BLI_task_parallel_range(int start, int stop, void *userdata, TaskParallelRangeFunc func, const TaskParallelSettings *settings)
Definition: task_range.cc:94
BLI_INLINE void BLI_parallel_range_settings_defaults(TaskParallelSettings *settings)
Definition: BLI_task.h:293
void BLI_mutex_lock(ThreadMutex *mutex)
Definition: threads.cc:373
void BLI_mutex_unlock(ThreadMutex *mutex)
Definition: threads.cc:378
pthread_mutex_t ThreadMutex
Definition: BLI_threads.h:82
#define INIT_MINMAX(min, max)
#define UNUSED_VARS(...)
#define UNUSED(x)
#define ELEM(...)
#define MIN2(a, b)
struct Depsgraph Depsgraph
Definition: DEG_depsgraph.h:35
@ DAG_EVAL_RENDER
Definition: DEG_depsgraph.h:46
eEvaluationMode DEG_get_mode(const Depsgraph *graph)
struct Scene * DEG_get_evaluated_scene(const struct Depsgraph *graph)
#define MAX_CUSTOMDATA_LAYER_NAME
#define CD_MASK_PROP_BYTE_COLOR
#define CD_MASK_MCOL
#define CD_MASK_MDEFORMVERT
#define CD_MASK_MTFACE
@ CD_PROP_BYTE_COLOR
@ CD_MDEFORMVERT
Object is a sort of wrapper for general info.
@ OB_MESH
@ BOUNDBOX_DIRTY
@ PART_DRAW_PARENT
@ PART_HAIR
#define TEX_PD_TURBULENCE
#define TEX_PD_FALLOFF_PARTICLE_AGE
#define TEX_PD_OBJECTSPACE
#define TEX_PD_OBJECT
#define TEX_PD_PSYS
#define TEX_INT
#define POINT_DATA_LIFE
@ TEX_PD_COLOR_VERTWEIGHT
@ TEX_PD_COLOR_VERTNOR
@ TEX_PD_COLOR_VERTCOL
@ TEX_PD_COLOR_PARTAGE
@ TEX_PD_COLOR_CONSTANT
@ TEX_PD_COLOR_PARTVEL
@ TEX_PD_COLOR_PARTSPEED
#define TEX_PD_FALLOFF_CURVE
#define TEX_PD_FALLOFF_SMOOTH
#define POINT_DATA_COLOR
#define TEX_PD_FALLOFF_PARTICLE_VEL
#define TEX_PD_FALLOFF_STD
#define TEX_PD_FALLOFF_CONSTANT
#define POINT_DATA_VEL
#define TEX_PD_WORLDSPACE
#define TEX_PD_FALLOFF_SOFT
#define TEX_PD_OBJECTLOC
#define TEX_PD_FALLOFF_ROOT
_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 z
_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 GLdouble r _GL_VOID_RET _GL_VOID GLfloat GLfloat r _GL_VOID_RET _GL_VOID GLint GLint r _GL_VOID_RET _GL_VOID GLshort GLshort r _GL_VOID_RET _GL_VOID GLdouble GLdouble r
_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 y
Read Guarded memory(de)allocation.
#define MEM_SAFE_FREE(v)
ATTR_WARN_UNUSED_RESULT const BMVert * v
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
Definition: btDbvt.cpp:52
Scene scene
const Depsgraph * depsgraph
uint col
ccl_gpu_kernel_postfix ccl_global float int int int int float bool int offset
const int state
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:27
void *(* MEM_callocN)(size_t len, const char *str)
Definition: mallocn.c:31
ccl_device_inline float3 pow(float3 v, float e)
Definition: math_float3.h:533
ccl_device_inline float4 mask(const int4 &mask, const float4 &a)
Definition: math_float4.h:513
static float turb(float x, float y, float z, int oct, int hard, int nb, float ampscale, float freqscale)
#define sqrtf(x)
Definition: metal/compat.h:243
static const pxr::TfToken rgba("rgba", pxr::TfToken::Immortal)
static const pxr::TfToken density("density", pxr::TfToken::Immortal)
#define min(a, b)
Definition: sort.c:35
float vec[8][3]
struct MDeformWeight * dw
unsigned int def_nr
unsigned int v
CustomData vdata
struct MVert * mvert
int totvert
struct MLoop * mloop
int totloop
CustomData ldata
ListBase particlesystem
float loc[3]
float imat[4][4]
float obmat[4][4]
void * data
struct Depsgraph * depsgraph
Definition: BKE_particle.h:69
struct ParticleSystemModifierData * psmd
Definition: BKE_particle.h:73
struct Scene * scene
Definition: BKE_particle.h:70
struct ParticleSystem * psys
Definition: BKE_particle.h:72
struct Object * ob
Definition: BKE_particle.h:71
ChildParticle * child
ParticleData * particles
ParticleSettings * part
struct ParticleCacheKey ** childcache
struct ParticleCacheKey ** pathcache
struct CurveMapping * density_curve
char vertex_attribute_name[64]
struct CurveMapping * falloff_curve
struct Object * object
struct ColorBand * coba
int talpha
Definition: RE_texture.h:89
float tin
Definition: RE_texture.h:86
float trgba[4]
Definition: RE_texture.h:87
static void sample_dummy_point_density(int resolution, float *values)
void RE_point_density_sample(Depsgraph *depsgraph, PointDensity *pd, const int resolution, float *values)
static void init_pointdensityrangedata(PointDensity *pd, PointDensityRangeData *pdr, float *density, float *vec, float *age, float *col, struct CurveMapping *density_curve, float velscale)
void RE_point_density_fix_linking(void)
static ThreadMutex sample_mutex
static void pointdensity_cache_object(PointDensity *pd, Object *ob)
static void accum_density(void *userdata, int index, const float co[3], float squared_dist)
struct SampleCallbackData SampleCallbackData
static void point_density_sample_func(void *__restrict data_v, const int iter, const TaskParallelTLS *__restrict UNUSED(tls))
struct PointDensityRangeData PointDensityRangeData
static void pointdensity_cache_vertex_weight(PointDensity *pd, Object *ob, Mesh *mesh, float *data_color)
void RE_point_density_minmax(struct Depsgraph *depsgraph, struct PointDensity *pd, float r_min[3], float r_max[3])
static void point_data_pointers(PointDensity *pd, float **r_data_velocity, float **r_data_life, float **r_data_color)
static void particle_system_minmax(Depsgraph *depsgraph, Scene *scene, Object *object, ParticleSystem *psys, float radius, float min[3], float max[3])
static void pointdensity_cache_vertex_color(PointDensity *pd, Object *UNUSED(ob), Mesh *mesh, float *data_color)
static int pointdensity(PointDensity *pd, const float texvec[3], TexResult *texres, float r_vec[3], float *r_age, float r_col[3])
static void pointdensity_cache_psys(Depsgraph *depsgraph, Scene *scene, PointDensity *pd, Object *ob, ParticleSystem *psys)
void RE_point_density_cache(struct Depsgraph *depsgraph, PointDensity *pd)
static void pointdensity_color(PointDensity *pd, TexResult *texres, float age, const float vec[3], const float col[3])
static float density_falloff(PointDensityRangeData *pdr, int index, float squared_dist)
static void alloc_point_data(PointDensity *pd)
static void pointdensity_cache_vertex_normal(Mesh *mesh, float *data_color)
static void cache_pointdensity(Depsgraph *depsgraph, Scene *scene, PointDensity *pd)
void RE_point_density_free(struct PointDensity *pd)
static int point_data_used(PointDensity *pd)
static void free_pointdensity(PointDensity *pd)
float max