9#define DNA_DEPRECATED_ALLOW
41#include "RNA_prototypes.hh"
90 MFace *fa =
nullptr, *mface =
nullptr;
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;
116 for (
i = 0;
i < totface;
i++) {
119 for (
i = 0;
i < totvert;
i++) {
125 const MDeformVert *dvert = mesh->deform_verts().data();
127 const int defgrp_index = emd->
vgroup - 1;
128 for (
i = 0;
i < totvert;
i++, dvert++) {
141 tree = BLI_kdtree_3d_new(totpart);
142 for (p = 0, pa = psys->
particles; p < totpart; p++, pa++) {
154 BLI_kdtree_3d_insert(
tree, p, co);
156 BLI_kdtree_3d_balance(
tree);
159 for (
i = 0, fa = mface;
i < totface;
i++, fa++) {
170 p = BLI_kdtree_3d_find_nearest(
tree, center,
nullptr);
179 if (v1 >= 0 &&
v2 >= 0 && v3 >= 0 && (fa->
v4 == 0 || v4 >= 0)) {
192 if (fa->
v4 && v4 >= 0) {
200 BLI_kdtree_3d_free(
tree);
207 return edgehash.
lookup({int(v1), int(
v2)});
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,
218 MFace *df = &mfaces[cur];
224#define SET_VERTS(a, b, c, d) \
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])
257 facepa[cur] = vertpa[v1];
262 df1->
flag |= ME_FACE_SEL;
264 facepa[cur + 1] = vertpa[
v2];
269 df2->
flag &= ~ME_FACE_SEL;
271 facepa[cur + 2] = vertpa[v1];
276 df3->
flag &= ~ME_FACE_SEL;
280 Mesh *mesh,
Mesh *
split,
int layers_num,
int i,
int cur,
int c0,
int c1,
int c2,
int c3)
282 MTFace *mf, *df1, *df2, *df3;
285 for (
l = 0;
l < layers_num;
l++) {
291 mf =
static_cast<MTFace *
>(
326 facepa[cur] = vertpa[v1];
331 df1->
flag |= ME_FACE_SEL;
333 facepa[cur + 1] = vertpa[v3];
338 df2->
flag |= ME_FACE_SEL;
342 Mesh *mesh,
Mesh *
split,
int layers_num,
int i,
int cur,
int c0,
int c1,
int c2,
int c3)
347 for (
l = 0;
l < layers_num;
l++) {
352 mf =
static_cast<MTFace *
>(
386 facepa[cur] = vertpa[v1];
391 df1->
flag |= ME_FACE_SEL;
393 facepa[cur + 1] = vertpa[
v2];
398 df2->
flag |= ME_FACE_SEL;
400 facepa[cur + 2] = vertpa[v3];
405 df3->
flag |= ME_FACE_SEL;
407 facepa[cur + 3] = vertpa[v4];
412 df4->
flag |= ME_FACE_SEL;
416 Mesh *mesh,
Mesh *
split,
int layers_num,
int i,
int cur,
int c0,
int c1,
int c2,
int c3)
418 MTFace *mf, *df1, *df2, *df3, *df4;
421 for (
l = 0;
l < layers_num;
l++) {
428 mf =
static_cast<MTFace *
>(
471 facepa[cur] = vertpa[v1];
476 df1->
flag |= ME_FACE_SEL;
478 facepa[cur + 1] = vertpa[
v2];
483 df2->
flag &= ~ME_FACE_SEL;
485 facepa[cur + 2] = vertpa[v4];
490 df3->
flag |= ME_FACE_SEL;
494 Mesh *mesh,
Mesh *
split,
int layers_num,
int i,
int cur,
int c0,
int c1,
int c2,
int c3)
496 MTFace *mf, *df1, *df2, *df3;
499 for (
l = 0;
l < layers_num;
l++) {
505 mf =
static_cast<MTFace *
>(
540 facepa[cur] = vertpa[v1];
545 df1->
flag &= ~ME_FACE_SEL;
547 facepa[cur + 1] = vertpa[
v2];
552 df2->
flag |= ME_FACE_SEL;
556 Mesh *mesh,
Mesh *
split,
int layers_num,
int i,
int cur,
int c0,
int c1,
int c2)
561 for (
l = 0;
l < layers_num;
l++) {
566 mf =
static_cast<MTFace *
>(
597 facepa[cur] = vertpa[v1];
602 df1->
flag |= ME_FACE_SEL;
604 facepa[cur + 1] = vertpa[
v2];
609 df2->
flag &= ~ME_FACE_SEL;
611 facepa[cur + 2] = vertpa[v3];
616 df3->
flag &= ~ME_FACE_SEL;
620 Mesh *mesh,
Mesh *
split,
int layers_num,
int i,
int cur,
int c0,
int c1,
int c2)
625 for (
l = 0;
l < layers_num;
l++) {
630 mf =
static_cast<MTFace *
>(
652 MFace *mf =
nullptr, *df1 =
nullptr;
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},
664 uv[4] = {0, 0, 0, 0};
667 int totesplit = totvert;
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];
676 vertpa[mf->
v4] = facepa[
i];
681 for (
i = 0, mf = mface, fs = facesplit;
i < totface;
i++, mf++, fs++) {
727 for (
i = 0, fs = facesplit;
i < totface;
i++, fs++) {
739 for (
i = 0;
i < totvert;
i++) {
754 for (
const auto [edge, esplit] : edgehash.
items()) {
755 const int ed_v1 = edge.v_low;
756 const int ed_v2 = edge.v_high;
761 dupve = split_m_positions[esplit];
764 mid_v3_v3v3(dupve, dupve, split_m_positions[ed_v1]);
770 for (
i = 0, fs = facesplit;
i < totface;
i++, fs++) {
811 mesh, split_m, mf, facepa, vertpa,
i, edgehash, curdupface,
v[0],
v[1],
v[2],
v[3]);
819 mesh, split_m, mf, facepa, vertpa,
i, edgehash, curdupface,
v[0],
v[1],
v[2],
v[3]);
821 remap_uvs_5_10(mesh, split_m, layers_num,
i, curdupface, uv[0], uv[1], uv[2], uv[3]);
826 mesh, split_m, mf, facepa, vertpa,
i, edgehash, curdupface,
v[0],
v[1],
v[2],
v[3]);
828 remap_uvs_15(mesh, split_m, layers_num,
i, curdupface, uv[0], uv[1], uv[2], uv[3]);
836 mesh, split_m, mf, facepa, vertpa,
i, edgehash, curdupface,
v[0],
v[1],
v[2],
v[3]);
839 mesh, split_m, layers_num,
i, curdupface, uv[0], uv[1], uv[2], uv[3]);
846 mesh, split_m, mf, facepa, vertpa,
i, edgehash, curdupface,
v[0],
v[1],
v[2]);
853 mesh, split_m, mf, facepa, vertpa,
i, edgehash, curdupface,
v[0],
v[1],
v[2]);
855 remap_uvs_23(mesh, split_m, layers_num,
i, curdupface, uv[0], uv[1], uv[2]);
860 df1 =
get_dface(mesh, split_m, curdupface,
i, mf);
861 facepa[curdupface] = vertpa[mf->
v1];
864 df1->flag |= ME_FACE_SEL;
867 df1->flag &= ~ME_FACE_SEL;
877 for (
i = 0;
i < curdupface;
i++) {
878 mf = &split_mface[
i];
898 Mesh *explode, *mesh = to_explode;
899 MFace *mf =
nullptr, *mface;
904 float *vertco =
nullptr, imat[4][4];
908 const int *facepa = emd->
facepa;
909 int totdup = 0, totvert = 0, totface = 0, totpart = 0, delface = 0;
915 mface =
static_cast<MFace *
>(
932 for (
i = 0;
i < totface;
i++) {
933 if (facepa[
i] != totpart) {
934 pa = pars + facepa[
i];
949 if (pa ==
nullptr || ctime < pa->time) {
950 mindex = totvert + totpart;
953 mindex = totvert + facepa[
i];
982 for (
const auto [edge,
v] : vertpahash.
items()) {
983 int ed_v1 = edge.v_low;
984 int ed_v2 = edge.v_high;
987 copy_v3_v3(explode_positions[
v], positions[ed_v1]);
991 copy_v3_v3(explode_positions[
v], positions[ed_v1]);
993 if (ed_v2 != totpart) {
1002 vertco = explode_positions[
v];
1027 for (
i = 0, u = 0;
i < totface;
i++) {
1031 if (facepa[
i] != totpart) {
1032 pa = pars + facepa[
i];
1049 mf = &explode_mface[u];
1051 orig_v4 = source.
v4;
1054 if (pa ==
nullptr || ctime < pa->time) {
1055 mindex = totvert + totpart;
1058 mindex = totvert + facepa[
i];
1074 float age = (pa !=
nullptr) ? (ctime - pa->
time) / pa->
lifetime : 0.0f;
1076 CLAMP(age, 0.001f, 0.999f);
1078 MTFace *mtf = mtface + u;
1080 mtf->
uv[0][0] = mtf->
uv[1][0] = mtf->
uv[2][0] = mtf->
uv[3][0] = age;
1081 mtf->
uv[0][1] = mtf->
uv[1][1] = mtf->
uv[2][1] = mtf->
uv[3][1] = 0.5f;
1118 if (psys ==
nullptr || psys->
totpart == 0) {
1146 int *facepa = emd->
facepa;
1176 ptr,
"particle_uv", &obj_data_ptr,
"uv_layers", std::nullopt, ICON_GROUP_UVS);
1178 row = &layout->
row(
true,
IFACE_(
"Show"));
1179 row->
prop(
ptr,
"show_alive", toggles_flag, std::nullopt, ICON_NONE);
1180 row->
prop(
ptr,
"show_dead", toggles_flag, std::nullopt, ICON_NONE);
1181 row->
prop(
ptr,
"show_unborn", toggles_flag, std::nullopt, ICON_NONE);
1191 row = &layout->
row(
false);
1195 layout->
op(
"OBJECT_OT_explode_refresh",
IFACE_(
"Refresh"), ICON_NONE);
1215 "ExplodeModifierData",
1217 &RNA_ExplodeModifier,
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)
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])
void psys_sim_data_free(struct ParticleSimulationData *sim)
void psys_sim_data_init(struct ParticleSimulationData *sim)
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)
float BKE_scene_ctime_get(const Scene *scene)
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])
void BLI_rng_free(struct RNG *rng) ATTR_NONNULL(1)
struct RNG * BLI_rng_new_srandom(unsigned int seed)
float BLI_rng_get_float(struct RNG *rng) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
#define MEMCMP_STRUCT_AFTER_IS_ZERO(struct_var, member)
#define MEMCPY_STRUCT_AFTER(struct_dst, struct_src, member)
Scene * DEG_get_evaluated_scene(const Depsgraph *graph)
#define CD_MASK_MDEFORMVERT
#define DNA_struct_default_get(struct_name)
@ eParticleSystemFlag_Pars
@ eModifierType_ParticleSystem
@ eExplodeFlag_INVERT_VGROUP
Object is a sort of wrapper for general info.
static void split(const char *text, const char *seps, char ***str, int *count)
Read Guarded memory(de)allocation.
static void init_data(ModifierData *md)
static void panel_register(ARegionType *region_type)
static void required_data_mask(ModifierData *, CustomData_MeshMasks *r_cddata_masks)
static void blend_read(BlendDataReader *, ModifierData *md)
static void panel_draw(const bContext *, Panel *panel)
static void copy_data(const ModifierData *md, ModifierData *target, const int flag)
static Mesh * modify_mesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mesh)
static void free_data(ModifierData *md)
static bool depends_on_time(Scene *, ModifierData *)
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)
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_vgroup_ui(uiLayout *layout, PointerRNA *ptr, PointerRNA *ob_ptr, const StringRefNull vgroup_prop, const std::optional< StringRefNull > invert_vgroup_prop, const std::optional< StringRefNull > text)
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_error_message_draw(uiLayout *layout, PointerRNA *ptr)
@ 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
Value & lookup_or_add_cb(const Key &key, const CreateValueF &create_value)
ItemIterator items() const &
void * MEM_calloc_arrayN(size_t len, size_t size, const char *str)
size_t(* MEM_allocN_len)(const void *vmemh)
void MEM_freeN(void *vmemh)
PointerRNA RNA_pointer_get(PointerRNA *ptr, const char *name)
int RNA_string_length(PointerRNA *ptr, const char *name)
struct ModifierData * next
struct Depsgraph * depsgraph
struct ParticleSystemModifierData * psmd
struct ParticleSystem * psys
struct ParticleSystem * psys
uiLayout & column(bool align)
void prop_search(PointerRNA *ptr, PropertyRNA *prop, PointerRNA *searchptr, PropertyRNA *searchprop, PropertyRNA *item_searchpropname, std::optional< blender::StringRefNull > name, int icon, bool results_are_suggestions)
void active_set(bool active)
uiLayout & row(bool align)
PointerRNA op(wmOperatorType *ot, std::optional< blender::StringRef > name, int icon, blender::wm::OpCallContext context, eUI_Item_Flag flag)
void use_property_split_set(bool value)
void prop(PointerRNA *ptr, PropertyRNA *prop, int index, int value, eUI_Item_Flag flag, std::optional< blender::StringRef > name_opt, int icon, std::optional< blender::StringRef > placeholder=std::nullopt)