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