Blender  V3.3
MOD_explode.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later
2  * Copyright 2005 Blender Foundation. All rights reserved. */
3 
8 #include "BLI_utildefines.h"
9 
10 #include "BLI_edgehash.h"
11 #include "BLI_kdtree.h"
12 #include "BLI_math.h"
13 #include "BLI_rand.h"
14 
15 #include "BLT_translation.h"
16 
17 #include "DNA_defaults.h"
18 #include "DNA_mesh_types.h"
19 #include "DNA_meshdata_types.h"
20 #include "DNA_object_types.h"
21 #include "DNA_scene_types.h"
22 #include "DNA_screen_types.h"
23 
24 #include "BKE_context.h"
25 #include "BKE_deform.h"
26 #include "BKE_lattice.h"
27 #include "BKE_lib_id.h"
28 #include "BKE_mesh.h"
30 #include "BKE_modifier.h"
31 #include "BKE_particle.h"
32 #include "BKE_scene.h"
33 #include "BKE_screen.h"
34 
35 #include "UI_interface.h"
36 #include "UI_resources.h"
37 
38 #include "BLO_read_write.h"
39 
40 #include "RNA_access.h"
41 #include "RNA_prototypes.h"
42 
43 #include "DEG_depsgraph_query.h"
44 
45 #include "MEM_guardedalloc.h"
46 
47 #include "MOD_modifiertypes.h"
48 #include "MOD_ui_common.h"
49 
50 static void initData(ModifierData *md)
51 {
53 
55 
57 }
58 static void freeData(ModifierData *md)
59 {
61 
62  MEM_SAFE_FREE(emd->facepa);
63 }
64 static void copyData(const ModifierData *md, ModifierData *target, const int flag)
65 {
66 #if 0
67  const ExplodeModifierData *emd = (const ExplodeModifierData *)md;
68 #endif
69  ExplodeModifierData *temd = (ExplodeModifierData *)target;
70 
71  BKE_modifier_copydata_generic(md, target, flag);
72 
73  temd->facepa = NULL;
74 }
75 static bool dependsOnTime(struct Scene *UNUSED(scene), ModifierData *UNUSED(md))
76 {
77  return true;
78 }
79 static void requiredDataMask(Object *UNUSED(ob),
80  ModifierData *md,
81  CustomData_MeshMasks *r_cddata_masks)
82 {
84 
85  if (emd->vgroup) {
86  r_cddata_masks->vmask |= CD_MASK_MDEFORMVERT;
87  }
88 }
89 
91 {
92  ParticleSystem *psys = psmd->psys;
93  MFace *fa = NULL, *mface = NULL;
94  MVert *mvert = NULL;
95  ParticleData *pa;
96  KDTree_3d *tree;
97  RNG *rng;
98  float center[3], co[3];
99  int *facepa = NULL, *vertpa = NULL, totvert = 0, totface = 0, totpart = 0;
100  int i, p, v1, v2, v3, v4 = 0;
101  const bool invert_vgroup = (emd->flag & eExplodeFlag_INVERT_VGROUP) != 0;
102 
103  mvert = mesh->mvert;
104  mface = mesh->mface;
105  totvert = mesh->totvert;
106  totface = mesh->totface;
107  totpart = psmd->psys->totpart;
108 
109  rng = BLI_rng_new_srandom(psys->seed);
110 
111  if (emd->facepa) {
112  MEM_freeN(emd->facepa);
113  }
114  facepa = emd->facepa = MEM_calloc_arrayN(totface, sizeof(int), "explode_facepa");
115 
116  vertpa = MEM_calloc_arrayN(totvert, sizeof(int), "explode_vertpa");
117 
118  /* initialize all faces & verts to no particle */
119  for (i = 0; i < totface; i++) {
120  facepa[i] = totpart;
121  }
122  for (i = 0; i < totvert; i++) {
123  vertpa[i] = totpart;
124  }
125 
126  /* set protected verts */
127  if (emd->vgroup) {
129  if (dvert) {
130  const int defgrp_index = emd->vgroup - 1;
131  for (i = 0; i < totvert; i++, dvert++) {
132  float val = BLI_rng_get_float(rng);
133  val = (1.0f - emd->protect) * val + emd->protect * 0.5f;
134  const float weight = invert_vgroup ? 1.0f - BKE_defvert_find_weight(dvert, defgrp_index) :
135  BKE_defvert_find_weight(dvert, defgrp_index);
136  if (val < weight) {
137  vertpa[i] = -1;
138  }
139  }
140  }
141  }
142 
143  /* make tree of emitter locations */
144  tree = BLI_kdtree_3d_new(totpart);
145  for (p = 0, pa = psys->particles; p < totpart; p++, pa++) {
147  psys->part->from,
148  pa->num,
149  pa->num_dmcache,
150  pa->fuv,
151  pa->foffset,
152  co,
153  NULL,
154  NULL,
155  NULL,
156  NULL);
157  BLI_kdtree_3d_insert(tree, p, co);
158  }
159  BLI_kdtree_3d_balance(tree);
160 
161  /* set face-particle-indexes to nearest particle to face center */
162  for (i = 0, fa = mface; i < totface; i++, fa++) {
163  add_v3_v3v3(center, mvert[fa->v1].co, mvert[fa->v2].co);
164  add_v3_v3(center, mvert[fa->v3].co);
165  if (fa->v4) {
166  add_v3_v3(center, mvert[fa->v4].co);
167  mul_v3_fl(center, 0.25);
168  }
169  else {
170  mul_v3_fl(center, 1.0f / 3.0f);
171  }
172 
173  p = BLI_kdtree_3d_find_nearest(tree, center, NULL);
174 
175  v1 = vertpa[fa->v1];
176  v2 = vertpa[fa->v2];
177  v3 = vertpa[fa->v3];
178  if (fa->v4) {
179  v4 = vertpa[fa->v4];
180  }
181 
182  if (v1 >= 0 && v2 >= 0 && v3 >= 0 && (fa->v4 == 0 || v4 >= 0)) {
183  facepa[i] = p;
184  }
185 
186  if (v1 >= 0) {
187  vertpa[fa->v1] = p;
188  }
189  if (v2 >= 0) {
190  vertpa[fa->v2] = p;
191  }
192  if (v3 >= 0) {
193  vertpa[fa->v3] = p;
194  }
195  if (fa->v4 && v4 >= 0) {
196  vertpa[fa->v4] = p;
197  }
198  }
199 
200  if (vertpa) {
201  MEM_freeN(vertpa);
202  }
203  BLI_kdtree_3d_free(tree);
204 
205  BLI_rng_free(rng);
206 }
207 
208 static int edgecut_get(EdgeHash *edgehash, uint v1, uint v2)
209 {
210  return POINTER_AS_INT(BLI_edgehash_lookup(edgehash, v1, v2));
211 }
212 
213 static const short add_faces[24] = {
214  0, 0, 0, 2, 0, 1, 2, 2, 0, 2, 1, 2, 2, 2, 2, 3, 0, 0, 0, 1, 0, 1, 1, 2,
215 };
216 
217 static MFace *get_dface(Mesh *mesh, Mesh *split, int cur, int i, MFace *mf)
218 {
219  MFace *df = &split->mface[cur];
220  CustomData_copy_data(&mesh->fdata, &split->fdata, i, cur, 1);
221  *df = *mf;
222  return df;
223 }
224 
225 #define SET_VERTS(a, b, c, d) \
226  { \
227  v[0] = mf->v##a; \
228  uv[0] = a - 1; \
229  v[1] = mf->v##b; \
230  uv[1] = b - 1; \
231  v[2] = mf->v##c; \
232  uv[2] = c - 1; \
233  v[3] = mf->v##d; \
234  uv[3] = d - 1; \
235  } \
236  (void)0
237 
238 #define GET_ES(v1, v2) edgecut_get(eh, v1, v2)
239 #define INT_UV(uvf, c0, c1) mid_v2_v2v2(uvf, mf->uv[c0], mf->uv[c1])
240 
242  Mesh *split,
243  MFace *mf,
244  int *facepa,
245  const int *vertpa,
246  int i,
247  EdgeHash *eh,
248  int cur,
249  int v1,
250  int v2,
251  int v3,
252  int v4)
253 {
254  MFace *df1 = get_dface(mesh, split, cur, i, mf);
255  MFace *df2 = get_dface(mesh, split, cur + 1, i, mf);
256  MFace *df3 = get_dface(mesh, split, cur + 2, i, mf);
257 
258  facepa[cur] = vertpa[v1];
259  df1->v1 = v1;
260  df1->v2 = GET_ES(v1, v2);
261  df1->v3 = GET_ES(v2, v3);
262  df1->v4 = v3;
263  df1->flag |= ME_FACE_SEL;
264 
265  facepa[cur + 1] = vertpa[v2];
266  df2->v1 = GET_ES(v1, v2);
267  df2->v2 = v2;
268  df2->v3 = GET_ES(v2, v3);
269  df2->v4 = 0;
270  df2->flag &= ~ME_FACE_SEL;
271 
272  facepa[cur + 2] = vertpa[v1];
273  df3->v1 = v1;
274  df3->v2 = v3;
275  df3->v3 = v4;
276  df3->v4 = 0;
277  df3->flag &= ~ME_FACE_SEL;
278 }
279 
280 static void remap_uvs_3_6_9_12(
281  Mesh *mesh, Mesh *split, int layers_num, int i, int cur, int c0, int c1, int c2, int c3)
282 {
283  MTFace *mf, *df1, *df2, *df3;
284  int l;
285 
286  for (l = 0; l < layers_num; l++) {
287  mf = CustomData_get_layer_n(&split->fdata, CD_MTFACE, l);
288  df1 = mf + cur;
289  df2 = df1 + 1;
290  df3 = df1 + 2;
292  mf += i;
293 
294  copy_v2_v2(df1->uv[0], mf->uv[c0]);
295  INT_UV(df1->uv[1], c0, c1);
296  INT_UV(df1->uv[2], c1, c2);
297  copy_v2_v2(df1->uv[3], mf->uv[c2]);
298 
299  INT_UV(df2->uv[0], c0, c1);
300  copy_v2_v2(df2->uv[1], mf->uv[c1]);
301  INT_UV(df2->uv[2], c1, c2);
302 
303  copy_v2_v2(df3->uv[0], mf->uv[c0]);
304  copy_v2_v2(df3->uv[1], mf->uv[c2]);
305  copy_v2_v2(df3->uv[2], mf->uv[c3]);
306  }
307 }
308 
310  Mesh *split,
311  MFace *mf,
312  int *facepa,
313  const int *vertpa,
314  int i,
315  EdgeHash *eh,
316  int cur,
317  int v1,
318  int v2,
319  int v3,
320  int v4)
321 {
322  MFace *df1 = get_dface(mesh, split, cur, i, mf);
323  MFace *df2 = get_dface(mesh, split, cur + 1, i, mf);
324 
325  facepa[cur] = vertpa[v1];
326  df1->v1 = v1;
327  df1->v2 = v2;
328  df1->v3 = GET_ES(v2, v3);
329  df1->v4 = GET_ES(v1, v4);
330  df1->flag |= ME_FACE_SEL;
331 
332  facepa[cur + 1] = vertpa[v3];
333  df2->v1 = GET_ES(v1, v4);
334  df2->v2 = GET_ES(v2, v3);
335  df2->v3 = v3;
336  df2->v4 = v4;
337  df2->flag |= ME_FACE_SEL;
338 }
339 
340 static void remap_uvs_5_10(
341  Mesh *mesh, Mesh *split, int layers_num, int i, int cur, int c0, int c1, int c2, int c3)
342 {
343  MTFace *mf, *df1, *df2;
344  int l;
345 
346  for (l = 0; l < layers_num; l++) {
347  mf = CustomData_get_layer_n(&split->fdata, CD_MTFACE, l);
348  df1 = mf + cur;
349  df2 = df1 + 1;
351  mf += i;
352 
353  copy_v2_v2(df1->uv[0], mf->uv[c0]);
354  copy_v2_v2(df1->uv[1], mf->uv[c1]);
355  INT_UV(df1->uv[2], c1, c2);
356  INT_UV(df1->uv[3], c0, c3);
357 
358  INT_UV(df2->uv[0], c0, c3);
359  INT_UV(df2->uv[1], c1, c2);
360  copy_v2_v2(df2->uv[2], mf->uv[c2]);
361  copy_v2_v2(df2->uv[3], mf->uv[c3]);
362  }
363 }
364 
365 static void remap_faces_15(Mesh *mesh,
366  Mesh *split,
367  MFace *mf,
368  int *facepa,
369  const int *vertpa,
370  int i,
371  EdgeHash *eh,
372  int cur,
373  int v1,
374  int v2,
375  int v3,
376  int v4)
377 {
378  MFace *df1 = get_dface(mesh, split, cur, i, mf);
379  MFace *df2 = get_dface(mesh, split, cur + 1, i, mf);
380  MFace *df3 = get_dface(mesh, split, cur + 2, i, mf);
381  MFace *df4 = get_dface(mesh, split, cur + 3, i, mf);
382 
383  facepa[cur] = vertpa[v1];
384  df1->v1 = v1;
385  df1->v2 = GET_ES(v1, v2);
386  df1->v3 = GET_ES(v1, v3);
387  df1->v4 = GET_ES(v1, v4);
388  df1->flag |= ME_FACE_SEL;
389 
390  facepa[cur + 1] = vertpa[v2];
391  df2->v1 = GET_ES(v1, v2);
392  df2->v2 = v2;
393  df2->v3 = GET_ES(v2, v3);
394  df2->v4 = GET_ES(v1, v3);
395  df2->flag |= ME_FACE_SEL;
396 
397  facepa[cur + 2] = vertpa[v3];
398  df3->v1 = GET_ES(v1, v3);
399  df3->v2 = GET_ES(v2, v3);
400  df3->v3 = v3;
401  df3->v4 = GET_ES(v3, v4);
402  df3->flag |= ME_FACE_SEL;
403 
404  facepa[cur + 3] = vertpa[v4];
405  df4->v1 = GET_ES(v1, v4);
406  df4->v2 = GET_ES(v1, v3);
407  df4->v3 = GET_ES(v3, v4);
408  df4->v4 = v4;
409  df4->flag |= ME_FACE_SEL;
410 }
411 
412 static void remap_uvs_15(
413  Mesh *mesh, Mesh *split, int layers_num, int i, int cur, int c0, int c1, int c2, int c3)
414 {
415  MTFace *mf, *df1, *df2, *df3, *df4;
416  int l;
417 
418  for (l = 0; l < layers_num; l++) {
419  mf = CustomData_get_layer_n(&split->fdata, CD_MTFACE, l);
420  df1 = mf + cur;
421  df2 = df1 + 1;
422  df3 = df1 + 2;
423  df4 = df1 + 3;
425  mf += i;
426 
427  copy_v2_v2(df1->uv[0], mf->uv[c0]);
428  INT_UV(df1->uv[1], c0, c1);
429  INT_UV(df1->uv[2], c0, c2);
430  INT_UV(df1->uv[3], c0, c3);
431 
432  INT_UV(df2->uv[0], c0, c1);
433  copy_v2_v2(df2->uv[1], mf->uv[c1]);
434  INT_UV(df2->uv[2], c1, c2);
435  INT_UV(df2->uv[3], c0, c2);
436 
437  INT_UV(df3->uv[0], c0, c2);
438  INT_UV(df3->uv[1], c1, c2);
439  copy_v2_v2(df3->uv[2], mf->uv[c2]);
440  INT_UV(df3->uv[3], c2, c3);
441 
442  INT_UV(df4->uv[0], c0, c3);
443  INT_UV(df4->uv[1], c0, c2);
444  INT_UV(df4->uv[2], c2, c3);
445  copy_v2_v2(df4->uv[3], mf->uv[c3]);
446  }
447 }
448 
450  Mesh *split,
451  MFace *mf,
452  int *facepa,
453  const int *vertpa,
454  int i,
455  EdgeHash *eh,
456  int cur,
457  int v1,
458  int v2,
459  int v3,
460  int v4)
461 {
462  MFace *df1 = get_dface(mesh, split, cur, i, mf);
463  MFace *df2 = get_dface(mesh, split, cur + 1, i, mf);
464  MFace *df3 = get_dface(mesh, split, cur + 2, i, mf);
465 
466  facepa[cur] = vertpa[v1];
467  df1->v1 = v1;
468  df1->v2 = GET_ES(v1, v2);
469  df1->v3 = GET_ES(v2, v3);
470  df1->v4 = GET_ES(v1, v4);
471  df1->flag |= ME_FACE_SEL;
472 
473  facepa[cur + 1] = vertpa[v2];
474  df2->v1 = GET_ES(v1, v2);
475  df2->v2 = v2;
476  df2->v3 = GET_ES(v2, v3);
477  df2->v4 = 0;
478  df2->flag &= ~ME_FACE_SEL;
479 
480  facepa[cur + 2] = vertpa[v4];
481  df3->v1 = GET_ES(v1, v4);
482  df3->v2 = GET_ES(v2, v3);
483  df3->v3 = v3;
484  df3->v4 = v4;
485  df3->flag |= ME_FACE_SEL;
486 }
487 
489  Mesh *mesh, Mesh *split, int layers_num, int i, int cur, int c0, int c1, int c2, int c3)
490 {
491  MTFace *mf, *df1, *df2, *df3;
492  int l;
493 
494  for (l = 0; l < layers_num; l++) {
495  mf = CustomData_get_layer_n(&split->fdata, CD_MTFACE, l);
496  df1 = mf + cur;
497  df2 = df1 + 1;
498  df3 = df1 + 2;
500  mf += i;
501 
502  copy_v2_v2(df1->uv[0], mf->uv[c0]);
503  INT_UV(df1->uv[1], c0, c1);
504  INT_UV(df1->uv[2], c1, c2);
505  INT_UV(df1->uv[3], c0, c3);
506 
507  INT_UV(df2->uv[0], c0, c1);
508  copy_v2_v2(df2->uv[1], mf->uv[c1]);
509  INT_UV(df2->uv[2], c1, c2);
510 
511  INT_UV(df3->uv[0], c0, c3);
512  INT_UV(df3->uv[1], c1, c2);
513  copy_v2_v2(df3->uv[2], mf->uv[c2]);
514  copy_v2_v2(df3->uv[3], mf->uv[c3]);
515  }
516 }
517 
519  Mesh *split,
520  MFace *mf,
521  int *facepa,
522  const int *vertpa,
523  int i,
524  EdgeHash *eh,
525  int cur,
526  int v1,
527  int v2,
528  int v3)
529 {
530  MFace *df1 = get_dface(mesh, split, cur, i, mf);
531  MFace *df2 = get_dface(mesh, split, cur + 1, i, mf);
532 
533  facepa[cur] = vertpa[v1];
534  df1->v1 = v1;
535  df1->v2 = GET_ES(v1, v2);
536  df1->v3 = GET_ES(v1, v3);
537  df1->v4 = 0;
538  df1->flag &= ~ME_FACE_SEL;
539 
540  facepa[cur + 1] = vertpa[v2];
541  df2->v1 = GET_ES(v1, v2);
542  df2->v2 = v2;
543  df2->v3 = v3;
544  df2->v4 = GET_ES(v1, v3);
545  df2->flag |= ME_FACE_SEL;
546 }
547 
548 static void remap_uvs_19_21_22(
549  Mesh *mesh, Mesh *split, int layers_num, int i, int cur, int c0, int c1, int c2)
550 {
551  MTFace *mf, *df1, *df2;
552  int l;
553 
554  for (l = 0; l < layers_num; l++) {
555  mf = CustomData_get_layer_n(&split->fdata, CD_MTFACE, l);
556  df1 = mf + cur;
557  df2 = df1 + 1;
559  mf += i;
560 
561  copy_v2_v2(df1->uv[0], mf->uv[c0]);
562  INT_UV(df1->uv[1], c0, c1);
563  INT_UV(df1->uv[2], c0, c2);
564 
565  INT_UV(df2->uv[0], c0, c1);
566  copy_v2_v2(df2->uv[1], mf->uv[c1]);
567  copy_v2_v2(df2->uv[2], mf->uv[c2]);
568  INT_UV(df2->uv[3], c0, c2);
569  }
570 }
571 
572 static void remap_faces_23(Mesh *mesh,
573  Mesh *split,
574  MFace *mf,
575  int *facepa,
576  const int *vertpa,
577  int i,
578  EdgeHash *eh,
579  int cur,
580  int v1,
581  int v2,
582  int v3)
583 {
584  MFace *df1 = get_dface(mesh, split, cur, i, mf);
585  MFace *df2 = get_dface(mesh, split, cur + 1, i, mf);
586  MFace *df3 = get_dface(mesh, split, cur + 2, i, mf);
587 
588  facepa[cur] = vertpa[v1];
589  df1->v1 = v1;
590  df1->v2 = GET_ES(v1, v2);
591  df1->v3 = GET_ES(v2, v3);
592  df1->v4 = GET_ES(v1, v3);
593  df1->flag |= ME_FACE_SEL;
594 
595  facepa[cur + 1] = vertpa[v2];
596  df2->v1 = GET_ES(v1, v2);
597  df2->v2 = v2;
598  df2->v3 = GET_ES(v2, v3);
599  df2->v4 = 0;
600  df2->flag &= ~ME_FACE_SEL;
601 
602  facepa[cur + 2] = vertpa[v3];
603  df3->v1 = GET_ES(v1, v3);
604  df3->v2 = GET_ES(v2, v3);
605  df3->v3 = v3;
606  df3->v4 = 0;
607  df3->flag &= ~ME_FACE_SEL;
608 }
609 
610 static void remap_uvs_23(
611  Mesh *mesh, Mesh *split, int layers_num, int i, int cur, int c0, int c1, int c2)
612 {
613  MTFace *mf, *df1, *df2;
614  int l;
615 
616  for (l = 0; l < layers_num; l++) {
617  mf = CustomData_get_layer_n(&split->fdata, CD_MTFACE, l);
618  df1 = mf + cur;
619  df2 = df1 + 1;
621  mf += i;
622 
623  copy_v2_v2(df1->uv[0], mf->uv[c0]);
624  INT_UV(df1->uv[1], c0, c1);
625  INT_UV(df1->uv[2], c1, c2);
626  INT_UV(df1->uv[3], c0, c2);
627 
628  INT_UV(df2->uv[0], c0, c1);
629  copy_v2_v2(df2->uv[1], mf->uv[c1]);
630  INT_UV(df2->uv[2], c1, c2);
631 
632  INT_UV(df2->uv[0], c0, c2);
633  INT_UV(df2->uv[1], c1, c2);
634  copy_v2_v2(df2->uv[2], mf->uv[c2]);
635  }
636 }
637 
639 {
640  Mesh *split_m;
641  MFace *mf = NULL, *df1 = NULL;
642  MFace *mface = mesh->mface;
643  MVert *dupve, *mv;
644  EdgeHash *edgehash;
645  EdgeHashIterator *ehi;
646  int totvert = mesh->totvert;
647  int totface = mesh->totface;
648 
649  int *facesplit = MEM_calloc_arrayN(totface, sizeof(int), "explode_facesplit");
650  int *vertpa = MEM_calloc_arrayN(totvert, sizeof(int), "explode_vertpa2");
651  int *facepa = emd->facepa;
652  int *fs, totesplit = 0, totfsplit = 0, curdupface = 0;
653  int i, v1, v2, v3, v4, esplit, v[4] = {0, 0, 0, 0}, /* To quite gcc barking... */
654  uv[4] = {0, 0, 0, 0}; /* To quite gcc barking... */
655  int layers_num;
656  uint ed_v1, ed_v2;
657 
658  edgehash = BLI_edgehash_new(__func__);
659 
660  /* recreate vertpa from facepa calculation */
661  for (i = 0, mf = mface; i < totface; i++, mf++) {
662  vertpa[mf->v1] = facepa[i];
663  vertpa[mf->v2] = facepa[i];
664  vertpa[mf->v3] = facepa[i];
665  if (mf->v4) {
666  vertpa[mf->v4] = facepa[i];
667  }
668  }
669 
670  /* mark edges for splitting and how to split faces */
671  for (i = 0, mf = mface, fs = facesplit; i < totface; i++, mf++, fs++) {
672  v1 = vertpa[mf->v1];
673  v2 = vertpa[mf->v2];
674  v3 = vertpa[mf->v3];
675 
676  if (v1 != v2) {
677  BLI_edgehash_reinsert(edgehash, mf->v1, mf->v2, NULL);
678  (*fs) |= 1;
679  }
680 
681  if (v2 != v3) {
682  BLI_edgehash_reinsert(edgehash, mf->v2, mf->v3, NULL);
683  (*fs) |= 2;
684  }
685 
686  if (mf->v4) {
687  v4 = vertpa[mf->v4];
688 
689  if (v3 != v4) {
690  BLI_edgehash_reinsert(edgehash, mf->v3, mf->v4, NULL);
691  (*fs) |= 4;
692  }
693 
694  if (v1 != v4) {
695  BLI_edgehash_reinsert(edgehash, mf->v1, mf->v4, NULL);
696  (*fs) |= 8;
697  }
698 
699  /* mark center vertex as a fake edge split */
700  if (*fs == 15) {
701  BLI_edgehash_reinsert(edgehash, mf->v1, mf->v3, NULL);
702  }
703  }
704  else {
705  (*fs) |= 16; /* mark face as tri */
706 
707  if (v1 != v3) {
708  BLI_edgehash_reinsert(edgehash, mf->v1, mf->v3, NULL);
709  (*fs) |= 4;
710  }
711  }
712  }
713 
714  /* count splits & create indexes for new verts */
715  ehi = BLI_edgehashIterator_new(edgehash);
716  totesplit = totvert;
719  totesplit++;
720  }
722 
723  /* count new faces due to splitting */
724  for (i = 0, fs = facesplit; i < totface; i++, fs++) {
725  totfsplit += add_faces[*fs];
726  }
727 
728  split_m = BKE_mesh_new_nomain_from_template(mesh, totesplit, 0, totface + totfsplit, 0, 0);
729 
730  layers_num = CustomData_number_of_layers(&split_m->fdata, CD_MTFACE);
731 
732  /* copy new faces & verts (is it really this painful with custom data??) */
733  for (i = 0; i < totvert; i++) {
734  MVert source;
735  MVert *dest;
736  source = mesh->mvert[i];
737  dest = &split_m->mvert[i];
738 
739  CustomData_copy_data(&mesh->vdata, &split_m->vdata, i, i, 1);
740  *dest = source;
741  }
742 
743  /* override original facepa (original pointer is saved in caller function) */
744 
745  /* TODO(campbell): `(totfsplit * 2)` over allocation is used since the quads are
746  * later interpreted as tri's, for this to work right I think we probably
747  * have to stop using tessface. */
748 
749  facepa = MEM_calloc_arrayN((totface + (totfsplit * 2)), sizeof(int), "explode_facepa");
750  // memcpy(facepa, emd->facepa, totface*sizeof(int));
751  emd->facepa = facepa;
752 
753  /* create new verts */
754  ehi = BLI_edgehashIterator_new(edgehash);
756  BLI_edgehashIterator_getKey(ehi, &ed_v1, &ed_v2);
758  mv = &split_m->mvert[ed_v2];
759  dupve = &split_m->mvert[esplit];
760 
761  CustomData_copy_data(&split_m->vdata, &split_m->vdata, ed_v2, esplit, 1);
762 
763  *dupve = *mv;
764 
765  mv = &split_m->mvert[ed_v1];
766 
767  mid_v3_v3v3(dupve->co, dupve->co, mv->co);
768  }
770 
771  /* create new faces */
772  curdupface = 0; //=totface;
773  // curdupin=totesplit;
774  for (i = 0, fs = facesplit; i < totface; i++, fs++) {
775  mf = &mesh->mface[i];
776 
777  switch (*fs) {
778  case 3:
779  case 10:
780  case 11:
781  case 15:
782  SET_VERTS(1, 2, 3, 4);
783  break;
784  case 5:
785  case 6:
786  case 7:
787  SET_VERTS(2, 3, 4, 1);
788  break;
789  case 9:
790  case 13:
791  SET_VERTS(4, 1, 2, 3);
792  break;
793  case 12:
794  case 14:
795  SET_VERTS(3, 4, 1, 2);
796  break;
797  case 21:
798  case 23:
799  SET_VERTS(1, 2, 3, 4);
800  break;
801  case 19:
802  SET_VERTS(2, 3, 1, 4);
803  break;
804  case 22:
805  SET_VERTS(3, 1, 2, 4);
806  break;
807  }
808 
809  switch (*fs) {
810  case 3:
811  case 6:
812  case 9:
813  case 12:
815  mesh, split_m, mf, facepa, vertpa, i, edgehash, curdupface, v[0], v[1], v[2], v[3]);
816  if (layers_num) {
817  remap_uvs_3_6_9_12(mesh, split_m, layers_num, i, curdupface, uv[0], uv[1], uv[2], uv[3]);
818  }
819  break;
820  case 5:
821  case 10:
823  mesh, split_m, mf, facepa, vertpa, i, edgehash, curdupface, v[0], v[1], v[2], v[3]);
824  if (layers_num) {
825  remap_uvs_5_10(mesh, split_m, layers_num, i, curdupface, uv[0], uv[1], uv[2], uv[3]);
826  }
827  break;
828  case 15:
830  mesh, split_m, mf, facepa, vertpa, i, edgehash, curdupface, v[0], v[1], v[2], v[3]);
831  if (layers_num) {
832  remap_uvs_15(mesh, split_m, layers_num, i, curdupface, uv[0], uv[1], uv[2], uv[3]);
833  }
834  break;
835  case 7:
836  case 11:
837  case 13:
838  case 14:
840  mesh, split_m, mf, facepa, vertpa, i, edgehash, curdupface, v[0], v[1], v[2], v[3]);
841  if (layers_num) {
843  mesh, split_m, layers_num, i, curdupface, uv[0], uv[1], uv[2], uv[3]);
844  }
845  break;
846  case 19:
847  case 21:
848  case 22:
850  mesh, split_m, mf, facepa, vertpa, i, edgehash, curdupface, v[0], v[1], v[2]);
851  if (layers_num) {
852  remap_uvs_19_21_22(mesh, split_m, layers_num, i, curdupface, uv[0], uv[1], uv[2]);
853  }
854  break;
855  case 23:
857  mesh, split_m, mf, facepa, vertpa, i, edgehash, curdupface, v[0], v[1], v[2]);
858  if (layers_num) {
859  remap_uvs_23(mesh, split_m, layers_num, i, curdupface, uv[0], uv[1], uv[2]);
860  }
861  break;
862  case 0:
863  case 16:
864  df1 = get_dface(mesh, split_m, curdupface, i, mf);
865  facepa[curdupface] = vertpa[mf->v1];
866 
867  if (df1->v4) {
868  df1->flag |= ME_FACE_SEL;
869  }
870  else {
871  df1->flag &= ~ME_FACE_SEL;
872  }
873  break;
874  }
875 
876  curdupface += add_faces[*fs] + 1;
877  }
878 
879  for (i = 0; i < curdupface; i++) {
880  mf = &split_m->mface[i];
881  BKE_mesh_mface_index_validate(mf, &split_m->fdata, i, ((mf->flag & ME_FACE_SEL) ? 4 : 3));
882  }
883 
884  BLI_edgehash_free(edgehash, NULL);
885  MEM_freeN(facesplit);
886  MEM_freeN(vertpa);
887 
890 
891  return split_m;
892 }
895  const ModifierEvalContext *ctx,
896  Scene *scene,
897  Mesh *to_explode)
898 {
899  Mesh *explode, *mesh = to_explode;
900  MFace *mf = NULL, *mface;
901  // ParticleSettings *part=psmd->psys->part; /* UNUSED */
903  ParticleData *pa = NULL, *pars = psmd->psys->particles;
904  ParticleKey state, birth;
905  EdgeHash *vertpahash;
906  EdgeHashIterator *ehi;
907  float *vertco = NULL, imat[4][4];
908  float rot[4];
909  float ctime;
910  // float timestep;
911  const int *facepa = emd->facepa;
912  int totdup = 0, totvert = 0, totface = 0, totpart = 0, delface = 0;
913  int i, v, u;
914  uint ed_v1, ed_v2, mindex = 0;
915 
916  totface = mesh->totface;
917  totvert = mesh->totvert;
918  mface = mesh->mface;
919  totpart = psmd->psys->totpart;
920 
921  sim.depsgraph = ctx->depsgraph;
922  sim.scene = scene;
923  sim.ob = ctx->object;
924  sim.psys = psmd->psys;
925  sim.psmd = psmd;
926 
927  // timestep = psys_get_timestep(&sim);
928 
929  ctime = BKE_scene_ctime_get(scene);
930 
931  /* hash table for vertex <-> particle relations */
932  vertpahash = BLI_edgehash_new(__func__);
933 
934  for (i = 0; i < totface; i++) {
935  if (facepa[i] != totpart) {
936  pa = pars + facepa[i];
937 
938  if ((pa->alive == PARS_UNBORN && (emd->flag & eExplodeFlag_Unborn) == 0) ||
939  (pa->alive == PARS_ALIVE && (emd->flag & eExplodeFlag_Alive) == 0) ||
940  (pa->alive == PARS_DEAD && (emd->flag & eExplodeFlag_Dead) == 0)) {
941  delface++;
942  continue;
943  }
944  }
945  else {
946  pa = NULL;
947  }
948 
949  /* do mindex + totvert to ensure the vertex index to be the first
950  * with BLI_edgehashIterator_getKey */
951  if (pa == NULL || ctime < pa->time) {
952  mindex = totvert + totpart;
953  }
954  else {
955  mindex = totvert + facepa[i];
956  }
957 
958  mf = &mface[i];
959 
960  /* set face vertices to exist in particle group */
961  BLI_edgehash_reinsert(vertpahash, mf->v1, mindex, NULL);
962  BLI_edgehash_reinsert(vertpahash, mf->v2, mindex, NULL);
963  BLI_edgehash_reinsert(vertpahash, mf->v3, mindex, NULL);
964  if (mf->v4) {
965  BLI_edgehash_reinsert(vertpahash, mf->v4, mindex, NULL);
966  }
967  }
968 
969  /* make new vertex indexes & count total vertices after duplication */
970  ehi = BLI_edgehashIterator_new(vertpahash);
973  totdup++;
974  }
976 
977  /* the final duplicated vertices */
978  explode = BKE_mesh_new_nomain_from_template(mesh, totdup, 0, totface - delface, 0, 0);
979 
980  MTFace *mtface = CustomData_get_layer_named(&explode->fdata, CD_MTFACE, emd->uvname);
981 
982  /* getting back to object space */
983  invert_m4_m4(imat, ctx->object->obmat);
984 
985  psys_sim_data_init(&sim);
986 
987  /* duplicate & displace vertices */
988  ehi = BLI_edgehashIterator_new(vertpahash);
990  MVert source;
991  MVert *dest;
992 
993  /* get particle + vertex from hash */
994  BLI_edgehashIterator_getKey(ehi, &ed_v1, &ed_v2);
995  ed_v2 -= totvert;
997 
998  source = mesh->mvert[ed_v1];
999  dest = &explode->mvert[v];
1000 
1001  CustomData_copy_data(&mesh->vdata, &explode->vdata, ed_v1, v, 1);
1002 
1003  *dest = source;
1004 
1005  if (ed_v2 != totpart) {
1006  /* get particle */
1007  pa = pars + ed_v2;
1008 
1009  psys_get_birth_coords(&sim, pa, &birth, 0, 0);
1010 
1011  state.time = ctime;
1012  psys_get_particle_state(&sim, ed_v2, &state, 1);
1013 
1014  vertco = explode->mvert[v].co;
1015  mul_m4_v3(ctx->object->obmat, vertco);
1016 
1017  sub_v3_v3(vertco, birth.co);
1018 
1019  /* apply rotation, size & location */
1020  sub_qt_qtqt(rot, state.rot, birth.rot);
1021  mul_qt_v3(rot, vertco);
1022 
1023  if (emd->flag & eExplodeFlag_PaSize) {
1024  mul_v3_fl(vertco, pa->size);
1025  }
1026 
1027  add_v3_v3(vertco, state.co);
1028 
1029  mul_m4_v3(imat, vertco);
1030  }
1031  else {
1032  pa = NULL;
1033  }
1034  }
1036 
1037  /* Map new vertices to faces. */
1038  for (i = 0, u = 0; i < totface; i++) {
1039  MFace source;
1040  int orig_v4;
1041 
1042  if (facepa[i] != totpart) {
1043  pa = pars + facepa[i];
1044 
1045  if (pa->alive == PARS_UNBORN && (emd->flag & eExplodeFlag_Unborn) == 0) {
1046  continue;
1047  }
1048  if (pa->alive == PARS_ALIVE && (emd->flag & eExplodeFlag_Alive) == 0) {
1049  continue;
1050  }
1051  if (pa->alive == PARS_DEAD && (emd->flag & eExplodeFlag_Dead) == 0) {
1052  continue;
1053  }
1054  }
1055  else {
1056  pa = NULL;
1057  }
1058 
1059  source = mesh->mface[i];
1060  mf = &explode->mface[u];
1061 
1062  orig_v4 = source.v4;
1063 
1064  /* Same as above in the first loop over mesh's faces. */
1065  if (pa == NULL || ctime < pa->time) {
1066  mindex = totvert + totpart;
1067  }
1068  else {
1069  mindex = totvert + facepa[i];
1070  }
1071 
1072  source.v1 = edgecut_get(vertpahash, source.v1, mindex);
1073  source.v2 = edgecut_get(vertpahash, source.v2, mindex);
1074  source.v3 = edgecut_get(vertpahash, source.v3, mindex);
1075  if (source.v4) {
1076  source.v4 = edgecut_get(vertpahash, source.v4, mindex);
1077  }
1078 
1079  CustomData_copy_data(&mesh->fdata, &explode->fdata, i, u, 1);
1080 
1081  *mf = source;
1082 
1083  /* override uv channel for particle age */
1084  if (mtface) {
1085  float age = (pa != NULL) ? (ctime - pa->time) / pa->lifetime : 0.0f;
1086  /* Clamp to this range to avoid flipping to the other side of the coordinates. */
1087  CLAMP(age, 0.001f, 0.999f);
1088 
1089  MTFace *mtf = mtface + u;
1090 
1091  mtf->uv[0][0] = mtf->uv[1][0] = mtf->uv[2][0] = mtf->uv[3][0] = age;
1092  mtf->uv[0][1] = mtf->uv[1][1] = mtf->uv[2][1] = mtf->uv[3][1] = 0.5f;
1093  }
1094 
1095  BKE_mesh_mface_index_validate(mf, &explode->fdata, u, (orig_v4 ? 4 : 3));
1096  u++;
1097  }
1098 
1099  /* cleanup */
1100  BLI_edgehash_free(vertpahash, NULL);
1101 
1102  /* finalization */
1105 
1106  psys_sim_data_free(&sim);
1107 
1108  return explode;
1109 }
1110 
1112 {
1113  ModifierData *md;
1115 
1116  for (md = ob->modifiers.first; emd != md; md = md->next) {
1117  if (md->type == eModifierType_ParticleSystem) {
1118  psmd = (ParticleSystemModifierData *)md;
1119  }
1120  }
1121  return psmd;
1122 }
1124 {
1127 
1128  if (psmd) {
1129  ParticleSystem *psys = psmd->psys;
1130 
1131  if (psys == NULL || psys->totpart == 0) {
1132  return mesh;
1133  }
1134  if (psys->part == NULL || psys->particles == NULL) {
1135  return mesh;
1136  }
1137  if (psmd->mesh_final == NULL) {
1138  return mesh;
1139  }
1140 
1141  BKE_mesh_tessface_ensure(mesh); /* BMESH - UNTIL MODIFIER IS UPDATED FOR MPoly */
1142 
1143  /* 1. find faces to be exploded if needed */
1144  if (emd->facepa == NULL || psmd->flag & eParticleSystemFlag_Pars ||
1145  emd->flag & eExplodeFlag_CalcFaces ||
1146  MEM_allocN_len(emd->facepa) / sizeof(int) != mesh->totface) {
1147  if (psmd->flag & eParticleSystemFlag_Pars) {
1148  psmd->flag &= ~eParticleSystemFlag_Pars;
1149  }
1150  if (emd->flag & eExplodeFlag_CalcFaces) {
1151  emd->flag &= ~eExplodeFlag_CalcFaces;
1152  }
1153  createFacepa(emd, psmd, mesh);
1154  }
1155  /* 2. create new mesh */
1157  if (emd->flag & eExplodeFlag_EdgeCut) {
1158  int *facepa = emd->facepa;
1159  Mesh *split_m = cutEdges(emd, mesh);
1160  Mesh *explode = explodeMesh(emd, psmd, ctx, scene, split_m);
1161 
1162  MEM_freeN(emd->facepa);
1163  emd->facepa = facepa;
1164  BKE_id_free(NULL, split_m);
1165  return explode;
1166  }
1167 
1168  return explodeMesh(emd, psmd, ctx, scene, mesh);
1169  }
1170  return mesh;
1171 }
1172 
1173 static void panel_draw(const bContext *UNUSED(C), Panel *panel)
1174 {
1175  uiLayout *row, *col;
1176  uiLayout *layout = panel->layout;
1177  int toggles_flag = UI_ITEM_R_TOGGLE | UI_ITEM_R_FORCE_BLANK_DECORATE;
1178 
1179  PointerRNA ob_ptr;
1181 
1182  PointerRNA obj_data_ptr = RNA_pointer_get(&ob_ptr, "data");
1183  bool has_vertex_group = RNA_string_length(ptr, "vertex_group") != 0;
1184 
1185  uiLayoutSetPropSep(layout, true);
1186 
1187  uiItemPointerR(layout, ptr, "particle_uv", &obj_data_ptr, "uv_layers", NULL, ICON_NONE);
1188 
1189  row = uiLayoutRowWithHeading(layout, true, IFACE_("Show"));
1190  uiItemR(row, ptr, "show_alive", toggles_flag, NULL, ICON_NONE);
1191  uiItemR(row, ptr, "show_dead", toggles_flag, NULL, ICON_NONE);
1192  uiItemR(row, ptr, "show_unborn", toggles_flag, NULL, ICON_NONE);
1193 
1194  uiLayoutSetPropSep(layout, true);
1195 
1196  col = uiLayoutColumn(layout, false);
1197  uiItemR(col, ptr, "use_edge_cut", 0, NULL, ICON_NONE);
1198  uiItemR(col, ptr, "use_size", 0, NULL, ICON_NONE);
1199 
1200  modifier_vgroup_ui(layout, ptr, &ob_ptr, "vertex_group", "invert_vertex_group", NULL);
1201 
1202  row = uiLayoutRow(layout, false);
1203  uiLayoutSetActive(row, has_vertex_group);
1204  uiItemR(row, ptr, "protect", 0, NULL, ICON_NONE);
1205 
1206  uiItemO(layout, IFACE_("Refresh"), ICON_NONE, "OBJECT_OT_explode_refresh");
1207 
1208  modifier_panel_end(layout, ptr);
1209 }
1210 
1211 static void panelRegister(ARegionType *region_type)
1212 {
1214 }
1215 
1216 static void blendRead(BlendDataReader *UNUSED(reader), ModifierData *md)
1217 {
1219 
1220  psmd->facepa = NULL;
1221 }
1222 
1224  /* name */ N_("Explode"),
1225  /* structName */ "ExplodeModifierData",
1226  /* structSize */ sizeof(ExplodeModifierData),
1227  /* srna */ &RNA_ExplodeModifier,
1228  /* type */ eModifierTypeType_Constructive,
1229  /* flags */ eModifierTypeFlag_AcceptsMesh,
1230  /* icon */ ICON_MOD_EXPLODE,
1231  /* copyData */ copyData,
1232 
1233  /* deformVerts */ NULL,
1234  /* deformMatrices */ NULL,
1235  /* deformVertsEM */ NULL,
1236  /* deformMatricesEM */ NULL,
1237  /* modifyMesh */ modifyMesh,
1238  /* modifyGeometrySet */ NULL,
1239 
1240  /* initData */ initData,
1241  /* requiredDataMask */ requiredDataMask,
1242  /* freeData */ freeData,
1243  /* isDisabled */ NULL,
1244  /* updateDepsgraph */ NULL,
1245  /* dependsOnTime */ dependsOnTime,
1246  /* dependsOnNormals */ NULL,
1247  /* foreachIDLink */ NULL,
1248  /* foreachTexLink */ NULL,
1249  /* freeRuntimeData */ NULL,
1250  /* panelRegister */ panelRegister,
1251  /* blendWrite */ NULL,
1252  /* blendRead */ blendRead,
1253 };
int CustomData_number_of_layers(const struct CustomData *data, int type)
void * CustomData_get_layer_named(const struct CustomData *data, int type, const char *name)
void * CustomData_get_layer_n(const struct CustomData *data, int type, int n)
void * CustomData_get_layer(const struct CustomData *data, int type)
void CustomData_copy_data(const struct CustomData *source, struct CustomData *dest, int source_index, int dest_index, int count)
support for deformation groups and hooks.
float BKE_defvert_find_weight(const struct MDeformVert *dvert, int defgroup)
Definition: deform.c:704
void BKE_id_free(struct Main *bmain, void *idv)
void BKE_mesh_calc_edges_tessface(struct Mesh *mesh)
struct Mesh * BKE_mesh_new_nomain_from_template(const struct Mesh *me_src, int verts_len, int edges_len, int tessface_len, int loops_len, int polys_len)
void BKE_mesh_tessface_ensure(struct Mesh *mesh)
void BKE_mesh_convert_mfaces_to_mpolys(struct Mesh *mesh)
int BKE_mesh_mface_index_validate(struct MFace *mface, struct CustomData *mfdata, int mfindex, int nr)
@ eModifierTypeFlag_AcceptsMesh
Definition: BKE_modifier.h:66
void BKE_modifier_copydata_generic(const struct ModifierData *md, struct ModifierData *md_dst, int flag)
@ eModifierTypeType_Constructive
Definition: BKE_modifier.h:47
void psys_particle_on_emitter(struct ParticleSystemModifierData *psmd, int from, int index, int index_dmcache, float fuv[4], float foffset, float vec[3], float nor[3], float utan[3], float vtan[3], float orco[3])
Definition: particle.c:2322
void psys_sim_data_free(struct ParticleSimulationData *sim)
Definition: particle.c:726
void psys_sim_data_init(struct ParticleSimulationData *sim)
Definition: particle.c:685
void psys_get_birth_coords(struct ParticleSimulationData *sim, struct ParticleData *pa, struct ParticleKey *state, float dtime, float cfra)
bool psys_get_particle_state(struct ParticleSimulationData *sim, int p, struct ParticleKey *state, bool always)
Definition: particle.c:4884
float BKE_scene_ctime_get(const struct Scene *scene)
#define BLI_assert(a)
Definition: BLI_assert.h:46
void BLI_edgehash_free(EdgeHash *eh, EdgeHashFreeFP free_value)
Definition: edgehash.c:230
BLI_INLINE void BLI_edgehashIterator_getKey(EdgeHashIterator *ehi, unsigned int *r_v0, unsigned int *r_v1)
Definition: BLI_edgehash.h:161
bool BLI_edgehash_reinsert(EdgeHash *eh, unsigned int v0, unsigned int v1, void *val)
Definition: edgehash.c:268
EdgeHashIterator * BLI_edgehashIterator_new(EdgeHash *eh) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
Definition: edgehash.c:394
EdgeHash * BLI_edgehash_new(const char *info) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
Definition: edgehash.c:225
BLI_INLINE void BLI_edgehashIterator_step(EdgeHashIterator *ehi)
Definition: BLI_edgehash.h:153
void BLI_edgehashIterator_free(EdgeHashIterator *ehi)
Definition: edgehash.c:408
BLI_INLINE void * BLI_edgehashIterator_getValue(EdgeHashIterator *ehi)
Definition: BLI_edgehash.h:169
BLI_INLINE bool BLI_edgehashIterator_isDone(const EdgeHashIterator *ehi)
Definition: BLI_edgehash.h:157
void * BLI_edgehash_lookup(const EdgeHash *eh, unsigned int v0, unsigned int v1) ATTR_WARN_UNUSED_RESULT
Definition: edgehash.c:295
BLI_INLINE void BLI_edgehashIterator_setValue(EdgeHashIterator *ehi, void *val)
Definition: BLI_edgehash.h:177
A KD-tree for nearest neighbor search.
bool invert_m4_m4(float R[4][4], const float A[4][4])
Definition: math_matrix.c:1287
void mul_m4_v3(const float M[4][4], float r[3])
Definition: math_matrix.c:729
void sub_qt_qtqt(float q[4], const float a[4], const float b[4])
void mul_qt_v3(const float q[4], float r[3])
Definition: math_rotation.c:59
MINLINE void sub_v3_v3(float r[3], const float a[3])
MINLINE void copy_v2_v2(float r[2], const float a[2])
MINLINE void mul_v3_fl(float r[3], float f)
MINLINE void add_v3_v3v3(float r[3], const float a[3], const float b[3])
void mid_v3_v3v3(float r[3], const float a[3], const float b[3])
Definition: math_vector.c:237
MINLINE void add_v3_v3(float r[3], const float a[3])
Random number functions.
void BLI_rng_free(struct RNG *rng) ATTR_NONNULL(1)
Definition: rand.cc:58
struct RNG * BLI_rng_new_srandom(unsigned int seed)
Definition: rand.cc:46
float BLI_rng_get_float(struct RNG *rng) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
Definition: rand.cc:93
unsigned int uint
Definition: BLI_sys_types.h:67
#define POINTER_FROM_INT(i)
#define UNUSED(x)
#define POINTER_AS_INT(i)
#define MEMCMP_STRUCT_AFTER_IS_ZERO(struct_var, member)
#define MEMCPY_STRUCT_AFTER(struct_dst, struct_src, member)
#define IFACE_(msgid)
struct Scene * DEG_get_evaluated_scene(const struct Depsgraph *graph)
#define CD_MASK_MDEFORMVERT
@ CD_MTFACE
@ CD_MDEFORMVERT
#define DNA_struct_default_get(struct_name)
Definition: DNA_defaults.h:29
@ ME_FACE_SEL
@ eParticleSystemFlag_Pars
@ eModifierType_ParticleSystem
@ eModifierType_Explode
struct ExplodeModifierData ExplodeModifierData
@ eExplodeFlag_CalcFaces
@ eExplodeFlag_Alive
@ eExplodeFlag_Dead
@ eExplodeFlag_EdgeCut
@ eExplodeFlag_INVERT_VGROUP
@ eExplodeFlag_PaSize
@ eExplodeFlag_Unborn
Object is a sort of wrapper for general info.
#define PARS_DEAD
#define PARS_ALIVE
#define PARS_UNBORN
NSNotificationCenter * center
_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.
#define MEM_SAFE_FREE(v)
static bool dependsOnTime(struct Scene *UNUSED(scene), ModifierData *UNUSED(md))
Definition: MOD_explode.c:75
static MFace * get_dface(Mesh *mesh, Mesh *split, int cur, int i, MFace *mf)
Definition: MOD_explode.c:217
static void blendRead(BlendDataReader *UNUSED(reader), ModifierData *md)
Definition: MOD_explode.c:1216
static void copyData(const ModifierData *md, ModifierData *target, const int flag)
Definition: MOD_explode.c:64
static Mesh * modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mesh)
Definition: MOD_explode.c:1123
static void remap_uvs_3_6_9_12(Mesh *mesh, Mesh *split, int layers_num, int i, int cur, int c0, int c1, int c2, int c3)
Definition: MOD_explode.c:280
static void remap_uvs_5_10(Mesh *mesh, Mesh *split, int layers_num, int i, int cur, int c0, int c1, int c2, int c3)
Definition: MOD_explode.c:340
static void remap_faces_23(Mesh *mesh, Mesh *split, MFace *mf, int *facepa, const int *vertpa, int i, EdgeHash *eh, int cur, int v1, int v2, int v3)
Definition: MOD_explode.c:572
static int edgecut_get(EdgeHash *edgehash, uint v1, uint v2)
Definition: MOD_explode.c:208
static ParticleSystemModifierData * findPrecedingParticlesystem(Object *ob, ModifierData *emd)
Definition: MOD_explode.c:1111
static void createFacepa(ExplodeModifierData *emd, ParticleSystemModifierData *psmd, Mesh *mesh)
Definition: MOD_explode.c:90
static void remap_faces_3_6_9_12(Mesh *mesh, Mesh *split, MFace *mf, int *facepa, const int *vertpa, int i, EdgeHash *eh, int cur, int v1, int v2, int v3, int v4)
Definition: MOD_explode.c:241
static void remap_uvs_23(Mesh *mesh, Mesh *split, int layers_num, int i, int cur, int c0, int c1, int c2)
Definition: MOD_explode.c:610
#define SET_VERTS(a, b, c, d)
Definition: MOD_explode.c:225
static const short add_faces[24]
Definition: MOD_explode.c:213
static void remap_uvs_7_11_13_14(Mesh *mesh, Mesh *split, int layers_num, int i, int cur, int c0, int c1, int c2, int c3)
Definition: MOD_explode.c:488
static Mesh * cutEdges(ExplodeModifierData *emd, Mesh *mesh)
Definition: MOD_explode.c:638
#define GET_ES(v1, v2)
Definition: MOD_explode.c:238
ModifierTypeInfo modifierType_Explode
Definition: MOD_explode.c:1223
#define INT_UV(uvf, c0, c1)
Definition: MOD_explode.c:239
static void remap_faces_15(Mesh *mesh, Mesh *split, MFace *mf, int *facepa, const int *vertpa, int i, EdgeHash *eh, int cur, int v1, int v2, int v3, int v4)
Definition: MOD_explode.c:365
static void remap_faces_7_11_13_14(Mesh *mesh, Mesh *split, MFace *mf, int *facepa, const int *vertpa, int i, EdgeHash *eh, int cur, int v1, int v2, int v3, int v4)
Definition: MOD_explode.c:449
static void panel_draw(const bContext *UNUSED(C), Panel *panel)
Definition: MOD_explode.c:1173
static void remap_uvs_19_21_22(Mesh *mesh, Mesh *split, int layers_num, int i, int cur, int c0, int c1, int c2)
Definition: MOD_explode.c:548
static void initData(ModifierData *md)
Definition: MOD_explode.c:50
static void panelRegister(ARegionType *region_type)
Definition: MOD_explode.c:1211
static void remap_faces_5_10(Mesh *mesh, Mesh *split, MFace *mf, int *facepa, const int *vertpa, int i, EdgeHash *eh, int cur, int v1, int v2, int v3, int v4)
Definition: MOD_explode.c:309
static Mesh * explodeMesh(ExplodeModifierData *emd, ParticleSystemModifierData *psmd, const ModifierEvalContext *ctx, Scene *scene, Mesh *to_explode)
Definition: MOD_explode.c:893
static void remap_faces_19_21_22(Mesh *mesh, Mesh *split, MFace *mf, int *facepa, const int *vertpa, int i, EdgeHash *eh, int cur, int v1, int v2, int v3)
Definition: MOD_explode.c:518
static void remap_uvs_15(Mesh *mesh, Mesh *split, int layers_num, int i, int cur, int c0, int c1, int c2, int c3)
Definition: MOD_explode.c:412
static void freeData(ModifierData *md)
Definition: MOD_explode.c:58
static void requiredDataMask(Object *UNUSED(ob), ModifierData *md, CustomData_MeshMasks *r_cddata_masks)
Definition: MOD_explode.c:79
PointerRNA * modifier_panel_get_property_pointers(Panel *panel, PointerRNA *r_ob_ptr)
void modifier_panel_end(uiLayout *layout, PointerRNA *ptr)
Definition: MOD_ui_common.c:91
PanelType * modifier_panel_register(ARegionType *region_type, ModifierType type, PanelDrawFn draw)
void modifier_vgroup_ui(uiLayout *layout, PointerRNA *ptr, PointerRNA *ob_ptr, const char *vgroup_prop, const char *invert_vgroup_prop, const char *text)
Group Output data from inside of a node group A color picker Mix two input colors RGB to Convert a color s luminance to a grayscale value Generate a normal vector and a dot product Bright Control the brightness and contrast of the input color Vector Map an input vectors to used to fine tune the interpolation of the input Camera Retrieve information about the camera and how it relates to the current shading point s position CLAMP
#define C
Definition: RandGen.cpp:25
uiLayout * uiLayoutRowWithHeading(uiLayout *layout, bool align, const char *heading)
void uiLayoutSetActive(uiLayout *layout, bool active)
uiLayout * uiLayoutColumn(uiLayout *layout, bool align)
void uiLayoutSetPropSep(uiLayout *layout, bool is_sep)
uiLayout * uiLayoutRow(uiLayout *layout, bool align)
@ UI_ITEM_R_TOGGLE
@ UI_ITEM_R_FORCE_BLANK_DECORATE
void uiItemR(uiLayout *layout, struct PointerRNA *ptr, const char *propname, int flag, const char *name, int icon)
void uiItemO(uiLayout *layout, const char *name, int icon, const char *opname)
void uiItemPointerR(uiLayout *layout, struct PointerRNA *ptr, const char *propname, struct PointerRNA *searchptr, const char *searchpropname, const char *name, int icon)
ATTR_WARN_UNUSED_RESULT const BMVert * v2
ATTR_WARN_UNUSED_RESULT const BMLoop * l
ATTR_WARN_UNUSED_RESULT const BMVert * v
double time
Scene scene
SyclQueue void * dest
void * tree
#define rot(x, k)
uint col
const int state
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:27
void *(* MEM_calloc_arrayN)(size_t len, size_t size, const char *str)
Definition: mallocn.c:32
size_t(* MEM_allocN_len)(const void *vmemh)
Definition: mallocn.c:26
void split(const std::string &s, const char delim, std::vector< std::string > &tokens)
Definition: abc_util.cc:92
PointerRNA RNA_pointer_get(PointerRNA *ptr, const char *name)
Definition: rna_access.c:5167
int RNA_string_length(PointerRNA *ptr, const char *name)
Definition: rna_access.c:5144
void * first
Definition: DNA_listBase.h:31
unsigned int v2
unsigned int v1
unsigned int v4
unsigned int v3
float uv[4][2]
float co[3]
CustomData vdata
struct MVert * mvert
int totvert
int totface
CustomData fdata
struct MFace * mface
struct ModifierData * next
struct Depsgraph * depsgraph
Definition: BKE_modifier.h:140
struct Object * object
Definition: BKE_modifier.h:141
ListBase modifiers
float obmat[4][4]
struct uiLayout * layout
struct Depsgraph * depsgraph
Definition: BKE_particle.h:69
struct ParticleSystemModifierData * psmd
Definition: BKE_particle.h:73
struct Scene * scene
Definition: BKE_particle.h:70
struct ParticleSystem * psys
Definition: BKE_particle.h:72
struct Object * ob
Definition: BKE_particle.h:71
struct ParticleSystem * psys
ParticleData * particles
ParticleSettings * part
Definition: rand.cc:33
#define N_(msgid)
PointerRNA * ptr
Definition: wm_files.c:3480