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