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