Blender  V3.3
particle_distribute.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later
2  * Copyright 2007 by Janne Karhu. All rights reserved. */
3 
8 #include <string.h>
9 
10 #include "MEM_guardedalloc.h"
11 
12 #include "BLI_jitter_2d.h"
13 #include "BLI_kdtree.h"
14 #include "BLI_math.h"
15 #include "BLI_math_geom.h"
16 #include "BLI_rand.h"
17 #include "BLI_sort.h"
18 #include "BLI_task.h"
19 #include "BLI_utildefines.h"
20 
21 #include "DNA_mesh_types.h"
22 #include "DNA_meshdata_types.h"
23 #include "DNA_modifier_types.h"
24 #include "DNA_particle_types.h"
25 #include "DNA_scene_types.h"
26 
27 #include "BKE_customdata.h"
28 #include "BKE_global.h"
29 #include "BKE_lib_id.h"
30 #include "BKE_mesh.h"
32 #include "BKE_object.h"
33 #include "BKE_particle.h"
34 
35 #include "DEG_depsgraph_query.h"
36 
37 static void alloc_child_particles(ParticleSystem *psys, int tot)
38 {
39  if (psys->child) {
40  /* only re-allocate if we have to */
41  if (psys->part->childtype && psys->totchild == tot) {
42  memset(psys->child, 0, tot * sizeof(ChildParticle));
43  return;
44  }
45 
46  MEM_freeN(psys->child);
47  psys->child = NULL;
48  psys->totchild = 0;
49  }
50 
51  if (psys->part->childtype) {
52  psys->totchild = tot;
53  if (psys->totchild) {
54  psys->child = MEM_callocN(psys->totchild * sizeof(ChildParticle), "child_particles");
55  }
56  }
57 }
58 
60  Object *ob,
61  Mesh *final_mesh,
62  Mesh *deform_mesh,
63  ParticleSystem *psys,
64  const bool use_render_params)
65 {
66  ChildParticle *cpa = NULL;
67  int i, p;
68  const int child_num = psys_get_child_number(scene, psys, use_render_params);
69  const int totpart = psys_get_tot_child(scene, psys, use_render_params);
70  RNG *rng = BLI_rng_new_srandom(31415926 + psys->seed + psys->child_seed);
71 
72  alloc_child_particles(psys, totpart);
73 
74  cpa = psys->child;
75  for (i = 0; i < child_num; i++) {
76  for (p = 0; p < psys->totpart; p++, cpa++) {
77  float length = 2.0;
78  cpa->parent = p;
79 
80  /* create even spherical distribution inside unit sphere */
81  while (length >= 1.0f) {
82  cpa->fuv[0] = 2.0f * BLI_rng_get_float(rng) - 1.0f;
83  cpa->fuv[1] = 2.0f * BLI_rng_get_float(rng) - 1.0f;
84  cpa->fuv[2] = 2.0f * BLI_rng_get_float(rng) - 1.0f;
85  length = len_v3(cpa->fuv);
86  }
87 
88  cpa->num = -1;
89  }
90  }
91  /* dmcache must be updated for parent particles if children from faces is used */
92  psys_calc_dmcache(ob, final_mesh, deform_mesh, psys);
93 
94  BLI_rng_free(rng);
95 }
97 {
98  ParticleData *pa = NULL;
99  float min[3], max[3], delta[3], d;
100  MVert *mv, *mvert = mesh->mvert;
101  int totvert = mesh->totvert, from = psys->part->from;
102  int i, j, k, p, res = psys->part->grid_res, size[3], axis;
103 
104  /* find bounding box of dm */
105  if (totvert > 0) {
106  mv = mvert;
107  copy_v3_v3(min, mv->co);
108  copy_v3_v3(max, mv->co);
109  mv++;
110  for (i = 1; i < totvert; i++, mv++) {
111  minmax_v3v3_v3(min, max, mv->co);
112  }
113  }
114  else {
115  zero_v3(min);
116  zero_v3(max);
117  }
118 
119  sub_v3_v3v3(delta, max, min);
120 
121  /* determine major axis */
122  axis = axis_dominant_v3_single(delta);
123 
124  d = delta[axis] / (float)res;
125 
126  size[axis] = res;
127  size[(axis + 1) % 3] = (int)ceil(delta[(axis + 1) % 3] / d);
128  size[(axis + 2) % 3] = (int)ceil(delta[(axis + 2) % 3] / d);
129 
130  /* float errors grrr. */
131  size[(axis + 1) % 3] = MIN2(size[(axis + 1) % 3], res);
132  size[(axis + 2) % 3] = MIN2(size[(axis + 2) % 3], res);
133 
134  size[0] = MAX2(size[0], 1);
135  size[1] = MAX2(size[1], 1);
136  size[2] = MAX2(size[2], 1);
137 
138  /* no full offset for flat/thin objects */
139  min[0] += d < delta[0] ? d / 2.0f : delta[0] / 2.0f;
140  min[1] += d < delta[1] ? d / 2.0f : delta[1] / 2.0f;
141  min[2] += d < delta[2] ? d / 2.0f : delta[2] / 2.0f;
142 
143  for (i = 0, p = 0, pa = psys->particles; i < res; i++) {
144  for (j = 0; j < res; j++) {
145  for (k = 0; k < res; k++, p++, pa++) {
146  pa->fuv[0] = min[0] + (float)i * d;
147  pa->fuv[1] = min[1] + (float)j * d;
148  pa->fuv[2] = min[2] + (float)k * d;
149  pa->flag |= PARS_UNEXIST;
150  pa->hair_index = 0; /* abused in volume calculation */
151  }
152  }
153  }
154 
155  /* enable particles near verts/edges/faces/inside surface */
156  if (from == PART_FROM_VERT) {
157  float vec[3];
158 
159  pa = psys->particles;
160 
161  min[0] -= d / 2.0f;
162  min[1] -= d / 2.0f;
163  min[2] -= d / 2.0f;
164 
165  for (i = 0, mv = mvert; i < totvert; i++, mv++) {
166  sub_v3_v3v3(vec, mv->co, min);
167  vec[0] /= delta[0];
168  vec[1] /= delta[1];
169  vec[2] /= delta[2];
170  pa[((int)(vec[0] * (size[0] - 1)) * res + (int)(vec[1] * (size[1] - 1))) * res +
171  (int)(vec[2] * (size[2] - 1))]
172  .flag &= ~PARS_UNEXIST;
173  }
174  }
176  float co1[3], co2[3];
177 
178  MFace *mface = NULL, *mface_array;
179  float v1[3], v2[3], v3[3], v4[4], lambda;
180  int a, a1, a2, a0mul, a1mul, a2mul, totface;
181  int amax = from == PART_FROM_FACE ? 3 : 1;
182 
183  totface = mesh->totface;
184  mface = mface_array = mesh->mface;
185 
186  for (a = 0; a < amax; a++) {
187  if (a == 0) {
188  a0mul = res * res;
189  a1mul = res;
190  a2mul = 1;
191  }
192  else if (a == 1) {
193  a0mul = res;
194  a1mul = 1;
195  a2mul = res * res;
196  }
197  else {
198  a0mul = 1;
199  a1mul = res * res;
200  a2mul = res;
201  }
202 
203  for (a1 = 0; a1 < size[(a + 1) % 3]; a1++) {
204  for (a2 = 0; a2 < size[(a + 2) % 3]; a2++) {
205  mface = mface_array;
206 
207  pa = psys->particles + a1 * a1mul + a2 * a2mul;
208  copy_v3_v3(co1, pa->fuv);
209  co1[a] -= d < delta[a] ? d / 2.0f : delta[a] / 2.0f;
210  copy_v3_v3(co2, co1);
211  co2[a] += delta[a] + 0.001f * d;
212  co1[a] -= 0.001f * d;
213 
214  struct IsectRayPrecalc isect_precalc;
215  float ray_direction[3];
216  sub_v3_v3v3(ray_direction, co2, co1);
217  isect_ray_tri_watertight_v3_precalc(&isect_precalc, ray_direction);
218 
219  /* lets intersect the faces */
220  for (i = 0; i < totface; i++, mface++) {
221  ParticleData *pa1 = NULL, *pa2 = NULL;
222 
223  copy_v3_v3(v1, mvert[mface->v1].co);
224  copy_v3_v3(v2, mvert[mface->v2].co);
225  copy_v3_v3(v3, mvert[mface->v3].co);
226 
227  bool intersects_tri = isect_ray_tri_watertight_v3(
228  co1, &isect_precalc, v1, v2, v3, &lambda, NULL);
229  if (intersects_tri) {
230  pa1 = (pa + (int)(lambda * size[a]) * a0mul);
231  }
232 
233  if (mface->v4 && (!intersects_tri || from == PART_FROM_VOLUME)) {
234  copy_v3_v3(v4, mvert[mface->v4].co);
235 
236  if (isect_ray_tri_watertight_v3(co1, &isect_precalc, v1, v3, v4, &lambda, NULL)) {
237  pa2 = (pa + (int)(lambda * size[a]) * a0mul);
238  }
239  }
240 
241  if (pa1) {
242  if (from == PART_FROM_FACE) {
243  pa1->flag &= ~PARS_UNEXIST;
244  }
245  else { /* store number of intersections */
246  pa1->hair_index++;
247  }
248  }
249 
250  if (pa2 && pa2 != pa1) {
251  if (from == PART_FROM_FACE) {
252  pa2->flag &= ~PARS_UNEXIST;
253  }
254  else { /* store number of intersections */
255  pa2->hair_index++;
256  }
257  }
258  }
259 
260  if (from == PART_FROM_VOLUME) {
261  int in = pa->hair_index % 2;
262  if (in) {
263  pa->hair_index++;
264  }
265  for (i = 0; i < size[0]; i++) {
266  if (in || (pa + i * a0mul)->hair_index % 2) {
267  (pa + i * a0mul)->flag &= ~PARS_UNEXIST;
268  }
269  /* odd intersections == in->out / out->in */
270  /* even intersections -> in stays same */
271  in = (in + (pa + i * a0mul)->hair_index) % 2;
272  }
273  }
274  }
275  }
276  }
277  }
278 
279  if (psys->part->flag & PART_GRID_HEXAGONAL) {
280  for (i = 0, p = 0, pa = psys->particles; i < res; i++) {
281  for (j = 0; j < res; j++) {
282  for (k = 0; k < res; k++, p++, pa++) {
283  if (j % 2) {
284  pa->fuv[0] += d / 2.0f;
285  }
286 
287  if (k % 2) {
288  pa->fuv[0] += d / 2.0f;
289  pa->fuv[1] += d / 2.0f;
290  }
291  }
292  }
293  }
294  }
295 
296  if (psys->part->flag & PART_GRID_INVERT) {
297  for (i = 0; i < size[0]; i++) {
298  for (j = 0; j < size[1]; j++) {
299  pa = psys->particles + res * (i * res + j);
300  for (k = 0; k < size[2]; k++, pa++) {
301  pa->flag ^= PARS_UNEXIST;
302  }
303  }
304  }
305  }
306 
307  if (psys->part->grid_rand > 0.0f) {
308  float rfac = d * psys->part->grid_rand;
309  for (p = 0, pa = psys->particles; p < psys->totpart; p++, pa++) {
310  if (pa->flag & PARS_UNEXIST) {
311  continue;
312  }
313 
314  pa->fuv[0] += rfac * (psys_frand(psys, p + 31) - 0.5f);
315  pa->fuv[1] += rfac * (psys_frand(psys, p + 32) - 0.5f);
316  pa->fuv[2] += rfac * (psys_frand(psys, p + 33) - 0.5f);
317  }
318  }
319 }
320 
321 /* modified copy from rayshade.c */
322 static void hammersley_create(float *out, int n, int seed, float amount)
323 {
324  RNG *rng;
325 
326  double ofs[2], t;
327 
328  rng = BLI_rng_new(31415926 + n + seed);
329  ofs[0] = BLI_rng_get_double(rng) + (double)amount;
330  ofs[1] = BLI_rng_get_double(rng) + (double)amount;
331  BLI_rng_free(rng);
332 
333  for (int k = 0; k < n; k++) {
334  BLI_hammersley_1d(k, &t);
335 
336  out[2 * k + 0] = fmod((double)k / (double)n + ofs[0], 1.0);
337  out[2 * k + 1] = fmod(t + ofs[1], 1.0);
338  }
339 }
340 
341 /* almost exact copy of BLI_jitter_init */
342 static void init_mv_jit(float *jit, int num, int seed2, float amount)
343 {
344  RNG *rng;
345  float *jit2, x, rad1, rad2, rad3;
346  int i, num2;
347 
348  if (num == 0) {
349  return;
350  }
351 
352  rad1 = (float)(1.0f / sqrtf((float)num));
353  rad2 = (float)(1.0f / ((float)num));
354  rad3 = (float)sqrtf((float)num) / ((float)num);
355 
356  rng = BLI_rng_new(31415926 + num + seed2);
357  x = 0;
358  num2 = 2 * num;
359  for (i = 0; i < num2; i += 2) {
360 
361  jit[i] = x + amount * rad1 * (0.5f - BLI_rng_get_float(rng));
362  jit[i + 1] = i / (2.0f * num) + amount * rad1 * (0.5f - BLI_rng_get_float(rng));
363 
364  jit[i] -= (float)floor(jit[i]);
365  jit[i + 1] -= (float)floor(jit[i + 1]);
366 
367  x += rad3;
368  x -= (float)floor(x);
369  }
370 
371  jit2 = MEM_mallocN(12 + sizeof(float[2]) * num, "initjit");
372 
373  for (i = 0; i < 4; i++) {
374  BLI_jitterate1((float(*)[2])jit, (float(*)[2])jit2, num, rad1);
375  BLI_jitterate1((float(*)[2])jit, (float(*)[2])jit2, num, rad1);
376  BLI_jitterate2((float(*)[2])jit, (float(*)[2])jit2, num, rad2);
377  }
378  MEM_freeN(jit2);
379  BLI_rng_free(rng);
380 }
381 
382 static void psys_uv_to_w(float u, float v, int quad, float *w)
383 {
384  float vert[4][3], co[3];
385 
386  if (!quad) {
387  if (u + v > 1.0f) {
388  v = 1.0f - v;
389  }
390  else {
391  u = 1.0f - u;
392  }
393  }
394 
395  vert[0][0] = 0.0f;
396  vert[0][1] = 0.0f;
397  vert[0][2] = 0.0f;
398  vert[1][0] = 1.0f;
399  vert[1][1] = 0.0f;
400  vert[1][2] = 0.0f;
401  vert[2][0] = 1.0f;
402  vert[2][1] = 1.0f;
403  vert[2][2] = 0.0f;
404 
405  co[0] = u;
406  co[1] = v;
407  co[2] = 0.0f;
408 
409  if (quad) {
410  vert[3][0] = 0.0f;
411  vert[3][1] = 1.0f;
412  vert[3][2] = 0.0f;
413  interp_weights_poly_v3(w, vert, 4, co);
414  }
415  else {
416  interp_weights_poly_v3(w, vert, 3, co);
417  w[3] = 0.0f;
418  }
419 }
420 
421 /* Find the index in "sum" array before "value" is crossed. */
422 static int distribute_binary_search(const float *sum, int n, float value)
423 {
424  int mid, low = 0, high = n - 1;
425 
426  if (high == low) {
427  return low;
428  }
429 
430  if (sum[low] >= value) {
431  return low;
432  }
433 
434  if (sum[high - 1] < value) {
435  return high;
436  }
437 
438  while (low < high) {
439  mid = (low + high) / 2;
440 
441  if ((sum[mid] >= value) && (sum[mid - 1] < value)) {
442  return mid;
443  }
444 
445  if (sum[mid] > value) {
446  high = mid - 1;
447  }
448  else {
449  low = mid + 1;
450  }
451  }
452 
453  return low;
454 }
455 
456 /* the max number if calls to rng_* funcs within psys_thread_distribute_particle
457  * be sure to keep up to date if this changes */
458 #define PSYS_RND_DIST_SKIP 3
459 
460 /* NOTE: this function must be thread safe, for `from == PART_FROM_CHILD`. */
461 #define ONLY_WORKING_WITH_PA_VERTS 0
463 {
464  ParticleThreadContext *ctx = thread->ctx;
465  MFace *mface;
466 
467  mface = ctx->mesh->mface;
468 
469  int rng_skip_tot = PSYS_RND_DIST_SKIP; /* count how many rng_* calls won't need skipping */
470 
471  /* TODO_PARTICLE - use original index */
472  pa->num = ctx->index[p];
473 
474  zero_v4(pa->fuv);
475 
476  if (pa->num != DMCACHE_NOTFOUND && pa->num < ctx->mesh->totvert) {
477 
478  /* This finds the first face to contain the emitting vertex,
479  * this is not ideal, but is mostly fine as UV seams generally
480  * map to equal-colored parts of a texture */
481  for (int i = 0; i < ctx->mesh->totface; i++, mface++) {
482  if (ELEM(pa->num, mface->v1, mface->v2, mface->v3, mface->v4)) {
483  unsigned int *vert = &mface->v1;
484 
485  for (int j = 0; j < 4; j++, vert++) {
486  if (*vert == pa->num) {
487  pa->fuv[j] = 1.0f;
488  break;
489  }
490  }
491 
492  break;
493  }
494  }
495  }
496 
497 #if ONLY_WORKING_WITH_PA_VERTS
498  if (ctx->tree) {
499  KDTreeNearest_3d ptn[3];
500  int w, maxw;
501 
503  ctx->mesh, from, pa->num, pa->num_dmcache, pa->fuv, pa->foffset, co1, 0, 0, 0, orco1, 0);
504  BKE_mesh_orco_verts_transform(ob->data, &orco1, 1, 1);
505  maxw = BLI_kdtree_3d_find_nearest_n(ctx->tree, orco1, ptn, 3);
506 
507  for (w = 0; w < maxw; w++) {
508  pa->verts[w] = ptn->num;
509  }
510  }
511 #endif
512 
513  BLI_assert(rng_skip_tot >= 0); /* should never be below zero */
514  if (rng_skip_tot > 0) {
515  BLI_rng_skip(thread->rng, rng_skip_tot);
516  }
517 }
518 
520 {
521  ParticleThreadContext *ctx = thread->ctx;
522  Mesh *mesh = ctx->mesh;
523  float randu, randv;
524  int distr = ctx->distr;
525  int i;
526  int rng_skip_tot = PSYS_RND_DIST_SKIP; /* count how many rng_* calls won't need skipping */
527 
528  MFace *mface;
529 
530  pa->num = i = ctx->index[p];
531  mface = &mesh->mface[i];
532 
533  switch (distr) {
534  case PART_DISTR_JIT:
535  if (ctx->jitlevel == 1) {
536  if (mface->v4) {
537  psys_uv_to_w(0.5f, 0.5f, mface->v4, pa->fuv);
538  }
539  else {
540  psys_uv_to_w(1.0f / 3.0f, 1.0f / 3.0f, mface->v4, pa->fuv);
541  }
542  }
543  else {
544  float offset = fmod(ctx->jitoff[i] + (float)p, (float)ctx->jitlevel);
545  if (!isnan(offset)) {
546  psys_uv_to_w(
547  ctx->jit[2 * (int)offset], ctx->jit[2 * (int)offset + 1], mface->v4, pa->fuv);
548  }
549  }
550  break;
551  case PART_DISTR_RAND:
552  randu = BLI_rng_get_float(thread->rng);
553  randv = BLI_rng_get_float(thread->rng);
554  rng_skip_tot -= 2;
555 
556  psys_uv_to_w(randu, randv, mface->v4, pa->fuv);
557  break;
558  }
559  pa->foffset = 0.0f;
560 
561  BLI_assert(rng_skip_tot >= 0); /* should never be below zero */
562  if (rng_skip_tot > 0) {
563  BLI_rng_skip(thread->rng, rng_skip_tot);
564  }
565 }
566 
568 {
569  ParticleThreadContext *ctx = thread->ctx;
570  Mesh *mesh = ctx->mesh;
571  float *v1, *v2, *v3, *v4, nor[3], co[3];
572  float cur_d, min_d, randu, randv;
573  int distr = ctx->distr;
574  int i, intersect, tot;
575  int rng_skip_tot = PSYS_RND_DIST_SKIP; /* count how many rng_* calls won't need skipping */
576 
577  MFace *mface;
578  MVert *mvert = mesh->mvert;
579 
580  pa->num = i = ctx->index[p];
581  mface = &mesh->mface[i];
582 
583  switch (distr) {
584  case PART_DISTR_JIT:
585  if (ctx->jitlevel == 1) {
586  if (mface->v4) {
587  psys_uv_to_w(0.5f, 0.5f, mface->v4, pa->fuv);
588  }
589  else {
590  psys_uv_to_w(1.0f / 3.0f, 1.0f / 3.0f, mface->v4, pa->fuv);
591  }
592  }
593  else {
594  float offset = fmod(ctx->jitoff[i] + (float)p, (float)ctx->jitlevel);
595  if (!isnan(offset)) {
596  psys_uv_to_w(
597  ctx->jit[2 * (int)offset], ctx->jit[2 * (int)offset + 1], mface->v4, pa->fuv);
598  }
599  }
600  break;
601  case PART_DISTR_RAND:
602  randu = BLI_rng_get_float(thread->rng);
603  randv = BLI_rng_get_float(thread->rng);
604  rng_skip_tot -= 2;
605 
606  psys_uv_to_w(randu, randv, mface->v4, pa->fuv);
607  break;
608  }
609  pa->foffset = 0.0f;
610 
611  /* experimental */
612  tot = mesh->totface;
613 
615  mesh, mvert, BKE_mesh_vertex_normals_ensure(mesh), mface, 0, 0, pa->fuv, co, nor, 0, 0, 0);
616 
617  normalize_v3(nor);
618  negate_v3(nor);
619 
620  min_d = FLT_MAX;
621  intersect = 0;
622 
623  for (i = 0, mface = mesh->mface; i < tot; i++, mface++) {
624  if (i == pa->num) {
625  continue;
626  }
627 
628  v1 = mvert[mface->v1].co;
629  v2 = mvert[mface->v2].co;
630  v3 = mvert[mface->v3].co;
631 
632  if (isect_ray_tri_v3(co, nor, v2, v3, v1, &cur_d, NULL)) {
633  if (cur_d < min_d) {
634  min_d = cur_d;
635  pa->foffset = cur_d * 0.5f; /* to the middle of volume */
636  intersect = 1;
637  }
638  }
639  if (mface->v4) {
640  v4 = mvert[mface->v4].co;
641 
642  if (isect_ray_tri_v3(co, nor, v4, v1, v3, &cur_d, NULL)) {
643  if (cur_d < min_d) {
644  min_d = cur_d;
645  pa->foffset = cur_d * 0.5f; /* to the middle of volume */
646  intersect = 1;
647  }
648  }
649  }
650  }
651  if (intersect == 0) {
652  pa->foffset = 0.0;
653  }
654  else {
655  switch (distr) {
656  case PART_DISTR_JIT:
657  pa->foffset *= ctx->jit[p % (2 * ctx->jitlevel)];
658  break;
659  case PART_DISTR_RAND:
660  pa->foffset *= BLI_rng_get_float(thread->rng);
661  rng_skip_tot--;
662  break;
663  }
664  }
665 
666  BLI_assert(rng_skip_tot >= 0); /* should never be below zero */
667  if (rng_skip_tot > 0) {
668  BLI_rng_skip(thread->rng, rng_skip_tot);
669  }
670 }
671 
673 {
674  ParticleThreadContext *ctx = thread->ctx;
675  Object *ob = ctx->sim.ob;
676  Mesh *mesh = ctx->mesh;
677  float orco1[3], co1[3], nor1[3];
678  float randu, randv;
679  int cfrom = ctx->cfrom;
680  int i;
681  int rng_skip_tot = PSYS_RND_DIST_SKIP; /* count how many rng_* calls won't need skipping */
682 
683  MFace *mf;
684 
685  if (ctx->index[p] < 0) {
686  cpa->num = 0;
687  cpa->fuv[0] = cpa->fuv[1] = cpa->fuv[2] = cpa->fuv[3] = 0.0f;
688  cpa->pa[0] = cpa->pa[1] = cpa->pa[2] = cpa->pa[3] = 0;
689  return;
690  }
691 
692  mf = &mesh->mface[ctx->index[p]];
693 
694  randu = BLI_rng_get_float(thread->rng);
695  randv = BLI_rng_get_float(thread->rng);
696  rng_skip_tot -= 2;
697 
698  psys_uv_to_w(randu, randv, mf->v4, cpa->fuv);
699 
700  cpa->num = ctx->index[p];
701 
702  if (ctx->tree) {
703  KDTreeNearest_3d ptn[10];
704  int w, maxw; //, do_seams;
705  float maxd /*, mind,dd */, totw = 0.0f;
706  int parent[10];
707  float pweight[10];
708 
710  cfrom,
711  cpa->num,
713  cpa->fuv,
714  cpa->foffset,
715  co1,
716  nor1,
717  NULL,
718  NULL,
719  orco1);
720  BKE_mesh_orco_verts_transform(ob->data, &orco1, 1, 1);
721  maxw = BLI_kdtree_3d_find_nearest_n(ctx->tree, orco1, ptn, 3);
722 
723  maxd = ptn[maxw - 1].dist;
724  /* mind=ptn[0].dist; */ /* UNUSED */
725 
726  /* the weights here could be done better */
727  for (w = 0; w < maxw; w++) {
728  parent[w] = ptn[w].index;
729  pweight[w] = (float)pow(2.0, (double)(-6.0f * ptn[w].dist / maxd));
730  }
731  for (; w < 10; w++) {
732  parent[w] = -1;
733  pweight[w] = 0.0f;
734  }
735 
736  for (w = 0, i = 0; w < maxw && i < 4; w++) {
737  if (parent[w] >= 0) {
738  cpa->pa[i] = parent[w];
739  cpa->w[i] = pweight[w];
740  totw += pweight[w];
741  i++;
742  }
743  }
744  for (; i < 4; i++) {
745  cpa->pa[i] = -1;
746  cpa->w[i] = 0.0f;
747  }
748 
749  if (totw > 0.0f) {
750  for (w = 0; w < 4; w++) {
751  cpa->w[w] /= totw;
752  }
753  }
754 
755  cpa->parent = cpa->pa[0];
756  }
757 
758  if (rng_skip_tot > 0) { /* should never be below zero */
759  BLI_rng_skip(thread->rng, rng_skip_tot);
760  }
761 }
762 
763 static void exec_distribute_parent(TaskPool *__restrict UNUSED(pool), void *taskdata)
764 {
765  ParticleTask *task = taskdata;
766  ParticleSystem *psys = task->ctx->sim.psys;
767  ParticleData *pa;
768  int p;
769 
770  BLI_rng_skip(task->rng, PSYS_RND_DIST_SKIP * task->begin);
771 
772  pa = psys->particles + task->begin;
773  switch (psys->part->from) {
774  case PART_FROM_FACE:
775  for (p = task->begin; p < task->end; p++, pa++) {
777  }
778  break;
779  case PART_FROM_VOLUME:
780  for (p = task->begin; p < task->end; p++, pa++) {
782  }
783  break;
784  case PART_FROM_VERT:
785  for (p = task->begin; p < task->end; p++, pa++) {
787  }
788  break;
789  }
790 }
791 
792 static void exec_distribute_child(TaskPool *__restrict UNUSED(pool), void *taskdata)
793 {
794  ParticleTask *task = taskdata;
795  ParticleSystem *psys = task->ctx->sim.psys;
796  ChildParticle *cpa;
797  int p;
798 
799  /* RNG skipping at the beginning */
800  cpa = psys->child;
801  for (p = 0; p < task->begin; p++, cpa++) {
803  }
804 
805  for (; p < task->end; p++, cpa++) {
807  }
808 }
809 
810 static int distribute_compare_orig_index(const void *p1, const void *p2, void *user_data)
811 {
812  const int *orig_index = (const int *)user_data;
813  int index1 = orig_index[*(const int *)p1];
814  int index2 = orig_index[*(const int *)p2];
815 
816  if (index1 < index2) {
817  return -1;
818  }
819  if (index1 == index2) {
820  /* this pointer comparison appears to make qsort stable for glibc,
821  * and apparently on solaris too, makes the renders reproducible */
822  if (p1 < p2) {
823  return -1;
824  }
825  if (p1 == p2) {
826  return 0;
827  }
828 
829  return 1;
830  }
831 
832  return 1;
833 }
834 
836 {
837  Scene *scene = sim->scene;
838  ParticleSystem *psys = sim->psys;
839  const bool use_render_params = (DEG_get_mode(sim->depsgraph) == DAG_EVAL_RENDER);
840 
841  if (from == PART_FROM_CHILD) {
842  ChildParticle *cpa;
843  int p, totchild = psys_get_tot_child(scene, psys, use_render_params);
844 
845  if (psys->child && totchild) {
846  for (p = 0, cpa = psys->child; p < totchild; p++, cpa++) {
847  cpa->fuv[0] = cpa->fuv[1] = cpa->fuv[2] = cpa->fuv[3] = 0.0;
848  cpa->foffset = 0.0f;
849  cpa->parent = 0;
850  cpa->pa[0] = cpa->pa[1] = cpa->pa[2] = cpa->pa[3] = 0;
851  cpa->num = -1;
852  }
853  }
854  }
855  else {
856  PARTICLE_P;
858  {
859  pa->fuv[0] = pa->fuv[1] = pa->fuv[2] = pa->fuv[3] = 0.0;
860  pa->foffset = 0.0f;
861  pa->num = -1;
862  }
863  }
864 }
865 
866 /* Creates a distribution of coordinates on a Mesh */
869  int from)
870 {
871  Scene *scene = sim->scene;
872  Mesh *final_mesh = sim->psmd->mesh_final;
873  Object *ob = sim->ob;
874  ParticleSystem *psys = sim->psys;
875  ParticleData *pa = 0, *tpars = 0;
876  ParticleSettings *part;
877  ParticleSeam *seams = 0;
878  KDTree_3d *tree = 0;
879  Mesh *mesh = NULL;
880  float *jit = NULL;
881  int i, p = 0;
882  int cfrom = 0;
883  int totelem = 0, totpart, *particle_element = 0, children = 0, totseam = 0;
884  int jitlevel = 1, distr;
885  float *element_weight = NULL, *jitter_offset = NULL, *vweight = NULL;
886  float cur, maxweight = 0.0, tweight, totweight, inv_totweight, co[3], nor[3], orco[3];
887  RNG *rng = NULL;
888 
889  if (ELEM(NULL, ob, psys, psys->part)) {
890  return 0;
891  }
892 
893  part = psys->part;
894  totpart = psys->totpart;
895  if (totpart == 0) {
896  return 0;
897  }
898 
899  if (!final_mesh->runtime.deformed_only &&
900  !CustomData_get_layer(&final_mesh->fdata, CD_ORIGINDEX)) {
901  printf(
902  "Can't create particles with the current modifier stack, disable destructive modifiers\n");
903  // XXX error("Can't paint with the current modifier stack, disable destructive modifiers");
904  return 0;
905  }
906 
907  /* XXX This distribution code is totally broken in case from == PART_FROM_CHILD,
908  * it's always using finaldm even if use_modifier_stack is unset...
909  * But making things consistent here break all existing edited
910  * hair systems, so better wait for complete rewrite. */
911 
912  psys_thread_context_init(ctx, sim);
913 
914  const bool use_render_params = (DEG_get_mode(sim->depsgraph) == DAG_EVAL_RENDER);
915 
916  /* First handle special cases */
917  if (from == PART_FROM_CHILD) {
918  /* Simple children */
919  if (part->childtype != PART_CHILD_FACES) {
921  scene, ob, final_mesh, sim->psmd->mesh_original, psys, use_render_params);
922  return 0;
923  }
924  }
925  else {
926  /* Grid distribution */
927  if (part->distr == PART_DISTR_GRID && from != PART_FROM_VERT) {
928  if (psys->part->use_modifier_stack) {
929  mesh = final_mesh;
930  }
931  else {
933  }
935 
936  distribute_grid(mesh, psys);
937 
938  if (mesh != final_mesh) {
940  }
941 
942  return 0;
943  }
944  }
945 
946  /* After this #BKE_mesh_orco_verts_transform can be used safely from multiple threads. */
947  BKE_mesh_texspace_ensure(final_mesh);
948 
949  /* Create trees and original coordinates if needed */
950  if (from == PART_FROM_CHILD) {
951  distr = PART_DISTR_RAND;
952  rng = BLI_rng_new_srandom(31415926 + psys->seed + psys->child_seed);
953  mesh = final_mesh;
954 
955  /* BMESH ONLY */
957 
958  children = 1;
959 
960  tree = BLI_kdtree_3d_new(totpart);
961 
962  for (p = 0, pa = psys->particles; p < totpart; p++, pa++) {
964  mesh, part->from, pa->num, pa->num_dmcache, pa->fuv, pa->foffset, co, nor, 0, 0, orco);
965  BKE_mesh_orco_verts_transform(ob->data, &orco, 1, 1);
966  BLI_kdtree_3d_insert(tree, p, orco);
967  }
968 
969  BLI_kdtree_3d_balance(tree);
970 
971  totpart = psys_get_tot_child(scene, psys, use_render_params);
972  cfrom = from = PART_FROM_FACE;
973  }
974  else {
975  distr = part->distr;
976 
977  rng = BLI_rng_new_srandom(31415926 + psys->seed);
978 
979  if (psys->part->use_modifier_stack) {
980  mesh = final_mesh;
981  }
982  else {
984  }
985 
987 
988  /* we need orco for consistent distributions */
990 
991  if (from == PART_FROM_VERT) {
992  MVert *mv = mesh->mvert;
993  const float(*orcodata)[3] = CustomData_get_layer(&mesh->vdata, CD_ORCO);
994  int totvert = mesh->totvert;
995 
996  tree = BLI_kdtree_3d_new(totvert);
997 
998  for (p = 0; p < totvert; p++) {
999  if (orcodata) {
1000  copy_v3_v3(co, orcodata[p]);
1001  BKE_mesh_orco_verts_transform(ob->data, &co, 1, 1);
1002  }
1003  else {
1004  copy_v3_v3(co, mv[p].co);
1005  }
1006  BLI_kdtree_3d_insert(tree, p, co);
1007  }
1008 
1009  BLI_kdtree_3d_balance(tree);
1010  }
1011  }
1012 
1013  /* Get total number of emission elements and allocate needed arrays */
1014  totelem = (from == PART_FROM_VERT) ? mesh->totvert : mesh->totface;
1015 
1016  if (totelem == 0) {
1017  distribute_invalid(sim, children ? PART_FROM_CHILD : 0);
1018 
1019  if (G.debug & G_DEBUG) {
1020  fprintf(stderr, "Particle distribution error: Nothing to emit from!\n");
1021  }
1022 
1023  if (mesh != final_mesh) {
1024  BKE_id_free(NULL, mesh);
1025  }
1026 
1027  BLI_kdtree_3d_free(tree);
1028  BLI_rng_free(rng);
1029 
1030  return 0;
1031  }
1032 
1033  element_weight = MEM_callocN(sizeof(float) * totelem, "particle_distribution_weights");
1034  particle_element = MEM_callocN(sizeof(int) * totpart, "particle_distribution_indexes");
1035  jitter_offset = MEM_callocN(sizeof(float) * totelem, "particle_distribution_jitoff");
1036 
1037  /* Calculate weights from face areas */
1038  if ((part->flag & PART_EDISTR || children) && from != PART_FROM_VERT) {
1039  MVert *v1, *v2, *v3, *v4;
1040  float totarea = 0.0f, co1[3], co2[3], co3[3], co4[3];
1041  const float(*orcodata)[3];
1042 
1043  orcodata = CustomData_get_layer(&mesh->vdata, CD_ORCO);
1044 
1045  for (i = 0; i < totelem; i++) {
1046  MFace *mf = &mesh->mface[i];
1047 
1048  if (orcodata) {
1049  /* Transform orcos from normalized 0..1 to object space. */
1050  copy_v3_v3(co1, orcodata[mf->v1]);
1051  copy_v3_v3(co2, orcodata[mf->v2]);
1052  copy_v3_v3(co3, orcodata[mf->v3]);
1053  BKE_mesh_orco_verts_transform(ob->data, &co1, 1, 1);
1054  BKE_mesh_orco_verts_transform(ob->data, &co2, 1, 1);
1055  BKE_mesh_orco_verts_transform(ob->data, &co3, 1, 1);
1056  if (mf->v4) {
1057  copy_v3_v3(co4, orcodata[mf->v4]);
1058  BKE_mesh_orco_verts_transform(ob->data, &co4, 1, 1);
1059  }
1060  }
1061  else {
1062  v1 = &mesh->mvert[mf->v1];
1063  v2 = &mesh->mvert[mf->v2];
1064  v3 = &mesh->mvert[mf->v3];
1065  copy_v3_v3(co1, v1->co);
1066  copy_v3_v3(co2, v2->co);
1067  copy_v3_v3(co3, v3->co);
1068  if (mf->v4) {
1069  v4 = &mesh->mvert[mf->v4];
1070  copy_v3_v3(co4, v4->co);
1071  }
1072  }
1073 
1074  cur = mf->v4 ? area_quad_v3(co1, co2, co3, co4) : area_tri_v3(co1, co2, co3);
1075 
1076  if (cur > maxweight) {
1077  maxweight = cur;
1078  }
1079 
1080  element_weight[i] = cur;
1081  totarea += cur;
1082  }
1083 
1084  for (i = 0; i < totelem; i++) {
1085  element_weight[i] /= totarea;
1086  }
1087 
1088  maxweight /= totarea;
1089  }
1090  else {
1091  float min = 1.0f / (float)(MIN2(totelem, totpart));
1092  for (i = 0; i < totelem; i++) {
1093  element_weight[i] = min;
1094  }
1095  maxweight = min;
1096  }
1097 
1098  /* Calculate weights from vgroup */
1099  vweight = psys_cache_vgroup(mesh, psys, PSYS_VG_DENSITY);
1100 
1101  if (vweight) {
1102  if (from == PART_FROM_VERT) {
1103  for (i = 0; i < totelem; i++) {
1104  element_weight[i] *= vweight[i];
1105  }
1106  }
1107  else { /* PART_FROM_FACE / PART_FROM_VOLUME */
1108  for (i = 0; i < totelem; i++) {
1109  MFace *mf = &mesh->mface[i];
1110  tweight = vweight[mf->v1] + vweight[mf->v2] + vweight[mf->v3];
1111 
1112  if (mf->v4) {
1113  tweight += vweight[mf->v4];
1114  tweight /= 4.0f;
1115  }
1116  else {
1117  tweight /= 3.0f;
1118  }
1119 
1120  element_weight[i] *= tweight;
1121  }
1122  }
1123  MEM_freeN(vweight);
1124  }
1125 
1126  /* Calculate total weight of all elements */
1127  int totmapped = 0;
1128  totweight = 0.0f;
1129  for (i = 0; i < totelem; i++) {
1130  if (element_weight[i] > 0.0f) {
1131  totmapped++;
1132  totweight += element_weight[i];
1133  }
1134  }
1135 
1136  if (totmapped == 0) {
1137  /* We are not allowed to distribute particles anywhere... */
1138  if (mesh != final_mesh) {
1139  BKE_id_free(NULL, mesh);
1140  }
1141  BLI_kdtree_3d_free(tree);
1142  BLI_rng_free(rng);
1143  MEM_freeN(element_weight);
1144  MEM_freeN(particle_element);
1145  MEM_freeN(jitter_offset);
1146  return 0;
1147  }
1148 
1149  inv_totweight = 1.0f / totweight;
1150 
1151  /* Calculate cumulative weights.
1152  * We remove all null-weighted elements from element_sum, and create a new mapping
1153  * 'activ'_elem_index -> orig_elem_index.
1154  * This simplifies greatly the filtering of zero-weighted items - and can be much more efficient
1155  * especially in random case (reducing a lot the size of binary-searched array)...
1156  */
1157  float *element_sum = MEM_mallocN(sizeof(*element_sum) * totmapped, __func__);
1158  int *element_map = MEM_mallocN(sizeof(*element_map) * totmapped, __func__);
1159  int i_mapped = 0;
1160 
1161  for (i = 0; i < totelem && element_weight[i] == 0.0f; i++) {
1162  /* pass */
1163  }
1164  element_sum[i_mapped] = element_weight[i] * inv_totweight;
1165  element_map[i_mapped] = i;
1166  i_mapped++;
1167  for (i++; i < totelem; i++) {
1168  if (element_weight[i] > 0.0f) {
1169  element_sum[i_mapped] = element_sum[i_mapped - 1] + element_weight[i] * inv_totweight;
1170  /* Skip elements which weight is so small that it does not affect the sum. */
1171  if (element_sum[i_mapped] > element_sum[i_mapped - 1]) {
1172  element_map[i_mapped] = i;
1173  i_mapped++;
1174  }
1175  }
1176  }
1177  totmapped = i_mapped;
1178 
1179  /* Finally assign elements to particles */
1180  if (part->flag & PART_TRAND) {
1181  for (p = 0; p < totpart; p++) {
1182  /* In theory element_sum[totmapped - 1] should be 1.0,
1183  * but due to float errors this is not necessarily always true, so scale pos accordingly. */
1184  const float pos = BLI_rng_get_float(rng) * element_sum[totmapped - 1];
1185  const int eidx = distribute_binary_search(element_sum, totmapped, pos);
1186  particle_element[p] = element_map[eidx];
1187  BLI_assert(pos <= element_sum[eidx]);
1188  BLI_assert(eidx ? (pos > element_sum[eidx - 1]) : (pos >= 0.0f));
1189  jitter_offset[particle_element[p]] = pos;
1190  }
1191  }
1192  else {
1193  double step, pos;
1194 
1195  step = (totpart < 2) ? 0.5 : 1.0 / (double)totpart;
1196  /* This is to address tricky issues with vertex-emitting when user tries
1197  * (and expects) exact 1-1 vert/part distribution (see T47983 and its two example files).
1198  * It allows us to consider pos as 'midpoint between v and v+1'
1199  * (or 'p and p+1', depending whether we have more vertices than particles or not),
1200  * and avoid stumbling over float impression in element_sum.
1201  * NOTE: moved face and volume distribution to this as well (instead of starting at zero),
1202  * for the same reasons, see T52682. */
1203  pos = (totpart < totmapped) ? 0.5 / (double)totmapped :
1204  step * 0.5; /* We choose the smaller step. */
1205 
1206  for (i = 0, p = 0; p < totpart; p++, pos += step) {
1207  for (; (i < totmapped - 1) && (pos > (double)element_sum[i]); i++) {
1208  /* pass */
1209  }
1210 
1211  particle_element[p] = element_map[i];
1212 
1213  jitter_offset[particle_element[p]] = pos;
1214  }
1215  }
1216 
1217  MEM_freeN(element_sum);
1218  MEM_freeN(element_map);
1219 
1220  /* For hair, sort by #CD_ORIGINDEX (allows optimization's in rendering),
1221  * however with virtual parents the children need to be in random order. */
1222  if (part->type == PART_HAIR && !(part->childtype == PART_CHILD_FACES && part->parents != 0.0f)) {
1223  const int *orig_index = NULL;
1224 
1225  if (from == PART_FROM_VERT) {
1226  if (mesh->totvert) {
1227  orig_index = CustomData_get_layer(&mesh->vdata, CD_ORIGINDEX);
1228  }
1229  }
1230  else {
1231  if (mesh->totface) {
1232  orig_index = CustomData_get_layer(&mesh->fdata, CD_ORIGINDEX);
1233  }
1234  }
1235 
1236  if (orig_index) {
1237  BLI_qsort_r(particle_element,
1238  totpart,
1239  sizeof(int),
1241  (void *)orig_index);
1242  }
1243  }
1244 
1245  /* Create jittering if needed */
1247  jitlevel = part->userjit;
1248 
1249  if (jitlevel == 0) {
1250  jitlevel = totpart / totelem;
1251  if (part->flag & PART_EDISTR) {
1252  jitlevel *= 2; /* looks better in general, not very scientific */
1253  }
1254  if (jitlevel < 3) {
1255  jitlevel = 3;
1256  }
1257  }
1258 
1259  jit = MEM_callocN((2 + jitlevel * 2) * sizeof(float), "jit");
1260 
1261  /* for small amounts of particles we use regular jitter since it looks
1262  * a bit better, for larger amounts we switch to hammersley sequence
1263  * because it is much faster */
1264  if (jitlevel < 25) {
1265  init_mv_jit(jit, jitlevel, psys->seed, part->jitfac);
1266  }
1267  else {
1268  hammersley_create(jit, jitlevel + 1, psys->seed, part->jitfac);
1269  }
1271  jit, sizeof(float[2]), jitlevel, psys->seed); /* for custom jit or even distribution */
1272  }
1273 
1274  /* Setup things for threaded distribution */
1275  ctx->tree = tree;
1276  ctx->seams = seams;
1277  ctx->totseam = totseam;
1278  ctx->sim.psys = psys;
1279  ctx->index = particle_element;
1280  ctx->jit = jit;
1281  ctx->jitlevel = jitlevel;
1282  ctx->jitoff = jitter_offset;
1283  ctx->weight = element_weight;
1284  ctx->maxweight = maxweight;
1285  ctx->cfrom = cfrom;
1286  ctx->distr = distr;
1287  ctx->mesh = mesh;
1288  ctx->tpars = tpars;
1289 
1290  if (children) {
1291  alloc_child_particles(psys, totpart);
1292  }
1293 
1294  BLI_rng_free(rng);
1295 
1296  return 1;
1297 }
1298 
1300 {
1301  /* init random number generator */
1302  int seed = 31415926 + sim->psys->seed;
1303 
1304  task->rng = BLI_rng_new(seed);
1305 }
1306 
1308 {
1311  ParticleTask *tasks;
1312  Mesh *final_mesh = sim->psmd->mesh_final;
1313  int i, totpart, numtasks;
1314 
1315  /* create a task pool for distribution tasks */
1316  if (!psys_thread_context_init_distribute(&ctx, sim, from)) {
1317  return;
1318  }
1319 
1321 
1322  totpart = (from == PART_FROM_CHILD ? sim->psys->totchild : sim->psys->totpart);
1323  psys_tasks_create(&ctx, 0, totpart, &tasks, &numtasks);
1324  for (i = 0; i < numtasks; i++) {
1325  ParticleTask *task = &tasks[i];
1326 
1328  if (from == PART_FROM_CHILD) {
1330  }
1331  else {
1333  }
1334  }
1336 
1338 
1339  psys_calc_dmcache(sim->ob, final_mesh, sim->psmd->mesh_original, sim->psys);
1340 
1341  if (ctx.mesh != final_mesh) {
1342  BKE_id_free(NULL, ctx.mesh);
1343  }
1344 
1345  psys_tasks_free(tasks, numtasks);
1346 
1348 }
1349 
1350 /* ready for future use, to emit particles without geometry */
1352 {
1353  distribute_invalid(sim, 0);
1354 
1355  fprintf(stderr, "Shape emission not yet possible!\n");
1356 }
1357 
1359 {
1360  PARTICLE_PSMD;
1361  int distr_error = 0;
1362 
1363  if (psmd) {
1364  if (psmd->mesh_final) {
1366  }
1367  else {
1368  distr_error = 1;
1369  }
1370  }
1371  else {
1373  }
1374 
1375  if (distr_error) {
1376  distribute_invalid(sim, from);
1377 
1378  fprintf(stderr, "Particle distribution error!\n");
1379  }
1380 }
typedef float(TangentPoint)[2]
CustomData interface, see also DNA_customdata_types.h.
void * CustomData_get_layer(const struct CustomData *data, int type)
@ G_DEBUG
Definition: BKE_global.h:174
@ LIB_ID_COPY_LOCALIZE
Definition: BKE_lib_id.h:187
struct ID * BKE_id_copy_ex(struct Main *bmain, const struct ID *id, struct ID **r_newid, int flag)
void BKE_id_free(struct Main *bmain, void *idv)
void BKE_mesh_orco_ensure(struct Object *ob, struct Mesh *mesh)
Definition: mesh.cc:1353
const float(* BKE_mesh_vertex_normals_ensure(const struct Mesh *mesh))[3]
void BKE_mesh_orco_verts_transform(struct Mesh *me, float(*orco)[3], int totvert, int invert)
Definition: mesh.cc:1331
void BKE_mesh_texspace_ensure(struct Mesh *me)
Definition: mesh.cc:1268
void BKE_mesh_tessface_ensure(struct Mesh *mesh)
General operations, lookup, etc. for blender objects.
int psys_get_child_number(struct Scene *scene, struct ParticleSystem *psys, bool use_render_params)
void psys_thread_context_init(struct ParticleThreadContext *ctx, struct ParticleSimulationData *sim)
void psys_calc_dmcache(struct Object *ob, struct Mesh *mesh_final, struct Mesh *mesh_original, struct ParticleSystem *psys)
#define DMCACHE_NOTFOUND
Definition: BKE_particle.h:672
float * psys_cache_vgroup(struct Mesh *mesh, struct ParticleSystem *psys, int vgroup)
Definition: particle.c:2652
void psys_tasks_free(struct ParticleTask *tasks, int numtasks)
void psys_tasks_create(struct ParticleThreadContext *ctx, int startpart, int endpart, struct ParticleTask **r_tasks, int *r_numtasks)
void psys_thread_context_free(struct ParticleThreadContext *ctx)
int psys_get_tot_child(struct Scene *scene, struct ParticleSystem *psys, bool use_render_params)
void psys_particle_on_dm(struct Mesh *mesh_final, int from, int index, int index_dmcache, const float fw[4], float foffset, float vec[3], float nor[3], float utan[3], float vtan[3], float orco[3])
Definition: particle.c:2101
#define LOOP_PARTICLES
Definition: BKE_particle.h:51
#define DMCACHE_ISCHILD
Definition: BKE_particle.h:673
#define PARTICLE_PSMD
Definition: BKE_particle.h:64
void psys_interpolate_face(struct Mesh *mesh, struct MVert *mvert, const float(*vert_normals)[3], struct MFace *mface, struct MTFace *tface, const float(*orcodata)[3], float w[4], float vec[3], float nor[3], float utan[3], float vtan[3], float orco[3])
Definition: particle.c:1689
#define PARTICLE_P
Definition: BKE_particle.h:48
BLI_INLINE float psys_frand(ParticleSystem *psys, unsigned int seed)
Definition: BKE_particle.h:248
#define BLI_assert(a)
Definition: BLI_assert.h:46
void BLI_jitterate1(float(*jit1)[2], float(*jit2)[2], int num, float radius1)
Definition: jitter_2d.c:18
void BLI_jitterate2(float(*jit1)[2], float(*jit2)[2], int num, float radius2)
Definition: jitter_2d.c:76
A KD-tree for nearest neighbor search.
void isect_ray_tri_watertight_v3_precalc(struct IsectRayPrecalc *isect_precalc, const float ray_direction[3])
Definition: math_geom.c:1784
bool isect_ray_tri_v3(const float ray_origin[3], const float ray_direction[3], const float v0[3], const float v1[3], const float v2[3], float *r_lambda, float r_uv[2])
Definition: math_geom.c:1662
MINLINE int axis_dominant_v3_single(const float vec[3])
bool isect_ray_tri_watertight_v3(const float ray_origin[3], const struct IsectRayPrecalc *isect_precalc, const float v0[3], const float v1[3], const float v2[3], float *r_dist, float r_uv[2])
Definition: math_geom.c:1811
float area_tri_v3(const float v1[3], const float v2[3], const float v3[3])
Definition: math_geom.c:92
float area_quad_v3(const float v1[3], const float v2[3], const float v3[3], const float v4[3])
Definition: math_geom.c:77
void interp_weights_poly_v3(float w[], float v[][3], int n, const float co[3])
void minmax_v3v3_v3(float min[3], float max[3], const float vec[3])
Definition: math_vector.c:867
MINLINE float normalize_v3(float r[3])
MINLINE void sub_v3_v3v3(float r[3], const float a[3], const float b[3])
MINLINE void copy_v3_v3(float r[3], const float a[3])
MINLINE void negate_v3(float r[3])
MINLINE void zero_v4(float r[4])
MINLINE void zero_v3(float r[3])
MINLINE float len_v3(const float a[3]) ATTR_WARN_UNUSED_RESULT
Random number functions.
void BLI_rng_free(struct RNG *rng) ATTR_NONNULL(1)
Definition: rand.cc:58
void BLI_hammersley_1d(unsigned int n, double *r)
Definition: rand.cc:353
struct RNG * BLI_rng_new(unsigned int seed)
Definition: rand.cc:39
double BLI_rng_get_double(struct RNG *rng) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
Definition: rand.cc:88
void void void BLI_rng_skip(struct RNG *rng, int n) ATTR_NONNULL(1)
Definition: rand.cc:162
struct RNG * BLI_rng_new_srandom(unsigned int seed)
Definition: rand.cc:46
float BLI_rng_get_float(struct RNG *rng) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
Definition: rand.cc:93
void BLI_array_randomize(void *data, unsigned int elem_size, unsigned int elem_num, unsigned int seed)
Definition: rand.cc:188
void BLI_qsort_r(void *a, size_t n, size_t es, BLI_sort_cmp_t cmp, void *thunk)
Definition: sort.c:79
@ TASK_PRIORITY_HIGH
Definition: BLI_task.h:57
void BLI_task_pool_work_and_wait(TaskPool *pool)
Definition: task_pool.cc:480
TaskPool * BLI_task_pool_create(void *userdata, eTaskPriority priority)
Definition: task_pool.cc:390
void BLI_task_pool_free(TaskPool *pool)
Definition: task_pool.cc:440
void BLI_task_pool_push(TaskPool *pool, TaskRunFunction run, void *taskdata, bool free_taskdata, TaskFreeFunction freedata)
Definition: task_pool.cc:459
#define UNUSED(x)
#define MAX2(a, b)
#define ELEM(...)
#define MIN2(a, b)
typedef double(DMatrix)[4][4]
@ DAG_EVAL_RENDER
Definition: DEG_depsgraph.h:46
eEvaluationMode DEG_get_mode(const Depsgraph *graph)
@ CD_ORIGINDEX
#define PART_FROM_VOLUME
#define PART_FROM_FACE
#define PART_FROM_VERT
#define PART_EDISTR
#define PART_FROM_CHILD
#define PARS_UNEXIST
#define PART_GRID_HEXAGONAL
#define PART_GRID_INVERT
#define PART_DISTR_JIT
#define PART_CHILD_FACES
@ PART_HAIR
#define PART_DISTR_RAND
#define PART_DISTR_GRID
#define PSYS_VG_DENSITY
#define PART_TRAND
_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
_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 v1
Read Guarded memory(de)allocation.
__forceinline ssef low(const avxf &a)
Definition: avxf.h:264
__forceinline ssef high(const avxf &a)
Definition: avxf.h:268
ATTR_WARN_UNUSED_RESULT const BMVert * v2
ATTR_WARN_UNUSED_RESULT const BMVert * v
__forceinline BoundBox intersect(const BoundBox &a, const BoundBox &b)
Definition: boundbox.h:179
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
Definition: btDbvt.cpp:52
SIMD_FORCE_INLINE const btScalar & w() const
Return the w value.
Definition: btQuadWord.h:119
static T sum(const btAlignedObjectArray< T > &items)
static unsigned long seed
Definition: btSoftBody.h:39
Definition: thread.h:34
StackEntry * from
Scene scene
void * user_data
TaskPool * task_pool
void * tree
uint pos
uint nor
GPUBatch * quad
#define jit
ccl_gpu_kernel_postfix ccl_global float int int int int float bool int offset
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:27
void *(* MEM_callocN)(size_t len, const char *str)
Definition: mallocn.c:31
void *(* MEM_mallocN)(size_t len, const char *str)
Definition: mallocn.c:33
ccl_device_inline float3 ceil(const float3 &a)
Definition: math_float3.h:363
ccl_device_inline float3 pow(float3 v, float e)
Definition: math_float3.h:533
#define G(x, y, z)
#define sqrtf(x)
Definition: metal/compat.h:243
static unsigned a[3]
Definition: RandGen.cpp:78
struct blender::compositor::@179::@181 task
T length(const vec_base< T, Size > &a)
T floor(const T &a)
bool isnan(double i)
Definition: numeric.h:451
static const pxr::TfToken out("out", pxr::TfToken::Immortal)
static void init_mv_jit(float *jit, int num, int seed2, float amount)
static void distribute_children_exec(ParticleTask *thread, ChildParticle *cpa, int p)
#define PSYS_RND_DIST_SKIP
static void psys_task_init_distribute(ParticleTask *task, ParticleSimulationData *sim)
static void distribute_simple_children(Scene *scene, Object *ob, Mesh *final_mesh, Mesh *deform_mesh, ParticleSystem *psys, const bool use_render_params)
static void distribute_from_verts_exec(ParticleTask *thread, ParticleData *pa, int p)
static void distribute_invalid(ParticleSimulationData *sim, int from)
static void exec_distribute_parent(TaskPool *__restrict UNUSED(pool), void *taskdata)
static void distribute_from_volume_exec(ParticleTask *thread, ParticleData *pa, int p)
static void distribute_particles_on_dm(ParticleSimulationData *sim, int from)
static void distribute_from_faces_exec(ParticleTask *thread, ParticleData *pa, int p)
static void distribute_grid(Mesh *mesh, ParticleSystem *psys)
static void exec_distribute_child(TaskPool *__restrict UNUSED(pool), void *taskdata)
static void distribute_particles_on_shape(ParticleSimulationData *sim, int UNUSED(from))
void distribute_particles(ParticleSimulationData *sim, int from)
static int distribute_binary_search(const float *sum, int n, float value)
static void psys_uv_to_w(float u, float v, int quad, float *w)
static int psys_thread_context_init_distribute(ParticleThreadContext *ctx, ParticleSimulationData *sim, int from)
static void hammersley_create(float *out, int n, int seed, float amount)
static void alloc_child_particles(ParticleSystem *psys, int tot)
static int distribute_compare_orig_index(const void *p1, const void *p2, void *user_data)
#define min(a, b)
Definition: sort.c:35
float co[3]
Definition: bmesh_class.h:87
unsigned int v2
unsigned int v1
unsigned int v4
unsigned int v3
float co[3]
CustomData vdata
struct MVert * mvert
int totvert
int totface
Mesh_Runtime runtime
CustomData fdata
struct MFace * mface
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 ParticleData * tpars
Definition: BKE_particle.h:146
struct Mesh * mesh
Definition: BKE_particle.h:131
struct ParticleSeam * seams
Definition: BKE_particle.h:137
struct ParticleSimulationData sim
Definition: BKE_particle.h:130
struct KDTree_3d * tree
Definition: BKE_particle.h:135
Definition: rand.cc:33
float max