Changeset View
Changeset View
Standalone View
Standalone View
source/blender/modifiers/intern/MOD_explode.c
| Show All 38 Lines | |||||
| #include "DNA_mesh_types.h" | #include "DNA_mesh_types.h" | ||||
| #include "BLI_utildefines.h" | #include "BLI_utildefines.h" | ||||
| #include "BLI_kdtree.h" | #include "BLI_kdtree.h" | ||||
| #include "BLI_rand.h" | #include "BLI_rand.h" | ||||
| #include "BLI_math.h" | #include "BLI_math.h" | ||||
| #include "BLI_edgehash.h" | #include "BLI_edgehash.h" | ||||
| #include "BKE_cdderivedmesh.h" | |||||
| #include "BKE_deform.h" | #include "BKE_deform.h" | ||||
| #include "BKE_lattice.h" | #include "BKE_lattice.h" | ||||
| #include "BKE_library.h" | |||||
| #include "BKE_mesh.h" | #include "BKE_mesh.h" | ||||
| #include "BKE_modifier.h" | #include "BKE_modifier.h" | ||||
| #include "BKE_particle.h" | #include "BKE_particle.h" | ||||
| #include "BKE_scene.h" | #include "BKE_scene.h" | ||||
| #include "DEG_depsgraph_query.h" | #include "DEG_depsgraph_query.h" | ||||
| #include "MEM_guardedalloc.h" | #include "MEM_guardedalloc.h" | ||||
| #include "MOD_modifiertypes.h" | #include "MOD_modifiertypes.h" | ||||
| static void initData(ModifierData *md) | static void initData(ModifierData *md) | ||||
brecht: Can you rename this to `BKE_mesh_calc_edges_tessface()` and move it to `mesh_validate.c`? | |||||
| { | { | ||||
| ExplodeModifierData *emd = (ExplodeModifierData *) md; | ExplodeModifierData *emd = (ExplodeModifierData *) md; | ||||
| emd->facepa = NULL; | emd->facepa = NULL; | ||||
| emd->flag |= eExplodeFlag_Unborn + eExplodeFlag_Alive + eExplodeFlag_Dead; | emd->flag |= eExplodeFlag_Unborn + eExplodeFlag_Alive + eExplodeFlag_Dead; | ||||
| } | } | ||||
| static void freeData(ModifierData *md) | static void freeData(ModifierData *md) | ||||
| { | { | ||||
| Show All 25 Lines | if (emd->vgroup) | ||||
| dataMask |= CD_MASK_MDEFORMVERT; | dataMask |= CD_MASK_MDEFORMVERT; | ||||
| return dataMask; | return dataMask; | ||||
| } | } | ||||
| static void createFacepa( | static void createFacepa( | ||||
| ExplodeModifierData *emd, | ExplodeModifierData *emd, | ||||
| ParticleSystemModifierData *psmd, | ParticleSystemModifierData *psmd, | ||||
| DerivedMesh *dm) | Mesh *mesh) | ||||
| { | { | ||||
| ParticleSystem *psys = psmd->psys; | ParticleSystem *psys = psmd->psys; | ||||
| MFace *fa = NULL, *mface = NULL; | MFace *fa = NULL, *mface = NULL; | ||||
| MVert *mvert = NULL; | MVert *mvert = NULL; | ||||
| ParticleData *pa; | ParticleData *pa; | ||||
| KDTree *tree; | KDTree *tree; | ||||
| RNG *rng; | RNG *rng; | ||||
| float center[3], co[3]; | float center[3], co[3]; | ||||
| int *facepa = NULL, *vertpa = NULL, totvert = 0, totface = 0, totpart = 0; | int *facepa = NULL, *vertpa = NULL, totvert = 0, totface = 0, totpart = 0; | ||||
| int i, p, v1, v2, v3, v4 = 0; | int i, p, v1, v2, v3, v4 = 0; | ||||
| mvert = dm->getVertArray(dm); | mvert = mesh->mvert; | ||||
| mface = dm->getTessFaceArray(dm); | mface = mesh->mface; | ||||
| totface = dm->getNumTessFaces(dm); | totvert = mesh->totvert; | ||||
| totvert = dm->getNumVerts(dm); | totface = mesh->totface; | ||||
| totpart = psmd->psys->totpart; | totpart = psmd->psys->totpart; | ||||
| rng = BLI_rng_new_srandom(psys->seed); | rng = BLI_rng_new_srandom(psys->seed); | ||||
| if (emd->facepa) | if (emd->facepa) { | ||||
| MEM_freeN(emd->facepa); | MEM_freeN(emd->facepa); | ||||
| } | |||||
| facepa = emd->facepa = MEM_calloc_arrayN(totface, sizeof(int), "explode_facepa"); | facepa = emd->facepa = MEM_calloc_arrayN(totface, sizeof(int), "explode_facepa"); | ||||
| vertpa = MEM_calloc_arrayN(totvert, sizeof(int), "explode_vertpa"); | vertpa = MEM_calloc_arrayN(totvert, sizeof(int), "explode_vertpa"); | ||||
| /* initialize all faces & verts to no particle */ | /* initialize all faces & verts to no particle */ | ||||
| for (i = 0; i < totface; i++) | for (i = 0; i < totface; i++) { | ||||
| facepa[i] = totpart; | facepa[i] = totpart; | ||||
| } | |||||
| for (i = 0; i < totvert; i++) | for (i = 0; i < totvert; i++) { | ||||
| vertpa[i] = totpart; | vertpa[i] = totpart; | ||||
| } | |||||
| /* set protected verts */ | /* set protected verts */ | ||||
| if (emd->vgroup) { | if (emd->vgroup) { | ||||
| MDeformVert *dvert = dm->getVertDataArray(dm, CD_MDEFORMVERT); | MDeformVert *dvert = CustomData_get_layer(&mesh->vdata, CD_MDEFORMVERT); | ||||
| if (dvert) { | if (dvert) { | ||||
| const int defgrp_index = emd->vgroup - 1; | const int defgrp_index = emd->vgroup - 1; | ||||
| for (i = 0; i < totvert; i++, dvert++) { | for (i = 0; i < totvert; i++, dvert++) { | ||||
| float val = BLI_rng_get_float(rng); | float val = BLI_rng_get_float(rng); | ||||
| val = (1.0f - emd->protect) * val + emd->protect * 0.5f; | val = (1.0f - emd->protect) * val + emd->protect * 0.5f; | ||||
| if (val < defvert_find_weight(dvert, defgrp_index)) | if (val < defvert_find_weight(dvert, defgrp_index)) | ||||
| vertpa[i] = -1; | vertpa[i] = -1; | ||||
| } | } | ||||
| Show All 11 Lines | static void createFacepa( | ||||
| /* set face-particle-indexes to nearest particle to face center */ | /* set face-particle-indexes to nearest particle to face center */ | ||||
| for (i = 0, fa = mface; i < totface; i++, fa++) { | for (i = 0, fa = mface; i < totface; i++, fa++) { | ||||
| add_v3_v3v3(center, mvert[fa->v1].co, mvert[fa->v2].co); | add_v3_v3v3(center, mvert[fa->v1].co, mvert[fa->v2].co); | ||||
| add_v3_v3(center, mvert[fa->v3].co); | add_v3_v3(center, mvert[fa->v3].co); | ||||
| if (fa->v4) { | if (fa->v4) { | ||||
| add_v3_v3(center, mvert[fa->v4].co); | add_v3_v3(center, mvert[fa->v4].co); | ||||
| mul_v3_fl(center, 0.25); | mul_v3_fl(center, 0.25); | ||||
| } | } | ||||
| else | else { | ||||
| mul_v3_fl(center, 1.0f / 3.0f); | mul_v3_fl(center, 1.0f / 3.0f); | ||||
| } | |||||
| p = BLI_kdtree_find_nearest(tree, center, NULL); | p = BLI_kdtree_find_nearest(tree, center, NULL); | ||||
| v1 = vertpa[fa->v1]; | v1 = vertpa[fa->v1]; | ||||
| v2 = vertpa[fa->v2]; | v2 = vertpa[fa->v2]; | ||||
| v3 = vertpa[fa->v3]; | v3 = vertpa[fa->v3]; | ||||
| if (fa->v4) | if (fa->v4) { | ||||
| v4 = vertpa[fa->v4]; | v4 = vertpa[fa->v4]; | ||||
| } | |||||
| if (v1 >= 0 && v2 >= 0 && v3 >= 0 && (fa->v4 == 0 || v4 >= 0)) | if (v1 >= 0 && v2 >= 0 && v3 >= 0 && (fa->v4 == 0 || v4 >= 0)) { | ||||
| facepa[i] = p; | facepa[i] = p; | ||||
| } | |||||
| if (v1 >= 0) vertpa[fa->v1] = p; | if (v1 >= 0) { | ||||
| if (v2 >= 0) vertpa[fa->v2] = p; | vertpa[fa->v1] = p; | ||||
| if (v3 >= 0) vertpa[fa->v3] = p; | } | ||||
| if (fa->v4 && v4 >= 0) vertpa[fa->v4] = p; | if (v2 >= 0) { | ||||
| vertpa[fa->v2] = p; | |||||
| } | |||||
| if (v3 >= 0) { | |||||
| vertpa[fa->v3] = p; | |||||
| } | |||||
| if (fa->v4 && v4 >= 0) { | |||||
| vertpa[fa->v4] = p; | |||||
| } | |||||
| } | } | ||||
| if (vertpa) MEM_freeN(vertpa); | if (vertpa) { | ||||
| MEM_freeN(vertpa); | |||||
| } | |||||
| BLI_kdtree_free(tree); | BLI_kdtree_free(tree); | ||||
| BLI_rng_free(rng); | BLI_rng_free(rng); | ||||
| } | } | ||||
| static int edgecut_get(EdgeHash *edgehash, unsigned int v1, unsigned int v2) | static int edgecut_get(EdgeHash *edgehash, unsigned int v1, unsigned int v2) | ||||
| { | { | ||||
| return POINTER_AS_INT(BLI_edgehash_lookup(edgehash, v1, v2)); | return POINTER_AS_INT(BLI_edgehash_lookup(edgehash, v1, v2)); | ||||
| } | } | ||||
| static const short add_faces[24] = { | static const short add_faces[24] = { | ||||
| 0, | 0, | ||||
| 0, 0, 2, 0, 1, 2, 2, 0, 2, 1, | 0, 0, 2, 0, 1, 2, 2, 0, 2, 1, | ||||
| 2, 2, 2, 2, 3, 0, 0, 0, 1, 0, | 2, 2, 2, 2, 3, 0, 0, 0, 1, 0, | ||||
| 1, 1, 2 | 1, 1, 2 | ||||
| }; | }; | ||||
| static MFace *get_dface(DerivedMesh *dm, DerivedMesh *split, int cur, int i, MFace *mf) | static MFace *get_dface(Mesh *mesh, Mesh *split, int cur, int i, MFace *mf) | ||||
| { | { | ||||
| MFace *df = CDDM_get_tessface(split, cur); | MFace *df = &split->mface[cur]; | ||||
| DM_copy_tessface_data(dm, split, i, cur, 1); | CustomData_copy_data(&mesh->fdata, &split->fdata, i, cur, 1); | ||||
| *df = *mf; | *df = *mf; | ||||
| return df; | return df; | ||||
| } | } | ||||
| #define SET_VERTS(a, b, c, d) \ | #define SET_VERTS(a, b, c, d) \ | ||||
| { \ | { \ | ||||
| v[0] = mf->v##a; uv[0] = a - 1; \ | v[0] = mf->v##a; uv[0] = a - 1; \ | ||||
| v[1] = mf->v##b; uv[1] = b - 1; \ | v[1] = mf->v##b; uv[1] = b - 1; \ | ||||
| v[2] = mf->v##c; uv[2] = c - 1; \ | v[2] = mf->v##c; uv[2] = c - 1; \ | ||||
| v[3] = mf->v##d; uv[3] = d - 1; \ | v[3] = mf->v##d; uv[3] = d - 1; \ | ||||
| } (void)0 | } (void)0 | ||||
| #define GET_ES(v1, v2) edgecut_get(eh, v1, v2) | #define GET_ES(v1, v2) edgecut_get(eh, v1, v2) | ||||
| #define INT_UV(uvf, c0, c1) mid_v2_v2v2(uvf, mf->uv[c0], mf->uv[c1]) | #define INT_UV(uvf, c0, c1) mid_v2_v2v2(uvf, mf->uv[c0], mf->uv[c1]) | ||||
| static void remap_faces_3_6_9_12(DerivedMesh *dm, DerivedMesh *split, MFace *mf, int *facepa, int *vertpa, int i, EdgeHash *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, int *vertpa, int i, EdgeHash *eh, int cur, int v1, int v2, int v3, int v4) | ||||
| { | { | ||||
| MFace *df1 = get_dface(dm, split, cur, i, mf); | MFace *df1 = get_dface(mesh, split, cur, i, mf); | ||||
| MFace *df2 = get_dface(dm, split, cur + 1, i, mf); | MFace *df2 = get_dface(mesh, split, cur + 1, i, mf); | ||||
| MFace *df3 = get_dface(dm, split, cur + 2, i, mf); | MFace *df3 = get_dface(mesh, split, cur + 2, i, mf); | ||||
| facepa[cur] = vertpa[v1]; | facepa[cur] = vertpa[v1]; | ||||
| df1->v1 = v1; | df1->v1 = v1; | ||||
| df1->v2 = GET_ES(v1, v2); | df1->v2 = GET_ES(v1, v2); | ||||
| df1->v3 = GET_ES(v2, v3); | df1->v3 = GET_ES(v2, v3); | ||||
| df1->v4 = v3; | df1->v4 = v3; | ||||
| df1->flag |= ME_FACE_SEL; | df1->flag |= ME_FACE_SEL; | ||||
| facepa[cur + 1] = vertpa[v2]; | facepa[cur + 1] = vertpa[v2]; | ||||
| df2->v1 = GET_ES(v1, v2); | df2->v1 = GET_ES(v1, v2); | ||||
| df2->v2 = v2; | df2->v2 = v2; | ||||
| df2->v3 = GET_ES(v2, v3); | df2->v3 = GET_ES(v2, v3); | ||||
| df2->v4 = 0; | df2->v4 = 0; | ||||
| df2->flag &= ~ME_FACE_SEL; | df2->flag &= ~ME_FACE_SEL; | ||||
| facepa[cur + 2] = vertpa[v1]; | facepa[cur + 2] = vertpa[v1]; | ||||
| df3->v1 = v1; | df3->v1 = v1; | ||||
| df3->v2 = v3; | df3->v2 = v3; | ||||
| df3->v3 = v4; | df3->v3 = v4; | ||||
| df3->v4 = 0; | df3->v4 = 0; | ||||
| df3->flag &= ~ME_FACE_SEL; | df3->flag &= ~ME_FACE_SEL; | ||||
| } | } | ||||
| static void remap_uvs_3_6_9_12(DerivedMesh *dm, DerivedMesh *split, int numlayer, int i, int cur, int c0, int c1, int c2, int c3) | static void remap_uvs_3_6_9_12(Mesh *mesh, Mesh *split, int numlayer, int i, int cur, int c0, int c1, int c2, int c3) | ||||
| { | { | ||||
| MTFace *mf, *df1, *df2, *df3; | MTFace *mf, *df1, *df2, *df3; | ||||
| int l; | int l; | ||||
| for (l = 0; l < numlayer; l++) { | for (l = 0; l < numlayer; l++) { | ||||
| mf = CustomData_get_layer_n(&split->faceData, CD_MTFACE, l); | mf = CustomData_get_layer_n(&split->fdata, CD_MTFACE, l); | ||||
| df1 = mf + cur; | df1 = mf + cur; | ||||
| df2 = df1 + 1; | df2 = df1 + 1; | ||||
| df3 = df1 + 2; | df3 = df1 + 2; | ||||
| mf = CustomData_get_layer_n(&dm->faceData, CD_MTFACE, l); | mf = CustomData_get_layer_n(&mesh->fdata, CD_MTFACE, l); | ||||
| mf += i; | mf += i; | ||||
| copy_v2_v2(df1->uv[0], mf->uv[c0]); | copy_v2_v2(df1->uv[0], mf->uv[c0]); | ||||
| INT_UV(df1->uv[1], c0, c1); | INT_UV(df1->uv[1], c0, c1); | ||||
| INT_UV(df1->uv[2], c1, c2); | INT_UV(df1->uv[2], c1, c2); | ||||
| copy_v2_v2(df1->uv[3], mf->uv[c2]); | copy_v2_v2(df1->uv[3], mf->uv[c2]); | ||||
| INT_UV(df2->uv[0], c0, c1); | INT_UV(df2->uv[0], c0, c1); | ||||
| copy_v2_v2(df2->uv[1], mf->uv[c1]); | copy_v2_v2(df2->uv[1], mf->uv[c1]); | ||||
| INT_UV(df2->uv[2], c1, c2); | INT_UV(df2->uv[2], c1, c2); | ||||
| copy_v2_v2(df3->uv[0], mf->uv[c0]); | copy_v2_v2(df3->uv[0], mf->uv[c0]); | ||||
| copy_v2_v2(df3->uv[1], mf->uv[c2]); | copy_v2_v2(df3->uv[1], mf->uv[c2]); | ||||
| copy_v2_v2(df3->uv[2], mf->uv[c3]); | copy_v2_v2(df3->uv[2], mf->uv[c3]); | ||||
| } | } | ||||
| } | } | ||||
| static void remap_faces_5_10(DerivedMesh *dm, DerivedMesh *split, MFace *mf, int *facepa, int *vertpa, int i, EdgeHash *eh, int cur, int v1, int v2, int v3, int v4) | static void remap_faces_5_10(Mesh *mesh, Mesh *split, MFace *mf, int *facepa, int *vertpa, int i, EdgeHash *eh, int cur, int v1, int v2, int v3, int v4) | ||||
| { | { | ||||
| MFace *df1 = get_dface(dm, split, cur, i, mf); | MFace *df1 = get_dface(mesh, split, cur, i, mf); | ||||
| MFace *df2 = get_dface(dm, split, cur + 1, i, mf); | MFace *df2 = get_dface(mesh, split, cur + 1, i, mf); | ||||
| facepa[cur] = vertpa[v1]; | facepa[cur] = vertpa[v1]; | ||||
| df1->v1 = v1; | df1->v1 = v1; | ||||
| df1->v2 = v2; | df1->v2 = v2; | ||||
| df1->v3 = GET_ES(v2, v3); | df1->v3 = GET_ES(v2, v3); | ||||
| df1->v4 = GET_ES(v1, v4); | df1->v4 = GET_ES(v1, v4); | ||||
| df1->flag |= ME_FACE_SEL; | df1->flag |= ME_FACE_SEL; | ||||
| facepa[cur + 1] = vertpa[v3]; | facepa[cur + 1] = vertpa[v3]; | ||||
| df2->v1 = GET_ES(v1, v4); | df2->v1 = GET_ES(v1, v4); | ||||
| df2->v2 = GET_ES(v2, v3); | df2->v2 = GET_ES(v2, v3); | ||||
| df2->v3 = v3; | df2->v3 = v3; | ||||
| df2->v4 = v4; | df2->v4 = v4; | ||||
| df2->flag |= ME_FACE_SEL; | df2->flag |= ME_FACE_SEL; | ||||
| } | } | ||||
| static void remap_uvs_5_10(DerivedMesh *dm, DerivedMesh *split, int numlayer, int i, int cur, int c0, int c1, int c2, int c3) | static void remap_uvs_5_10(Mesh *mesh, Mesh *split, int numlayer, int i, int cur, int c0, int c1, int c2, int c3) | ||||
| { | { | ||||
| MTFace *mf, *df1, *df2; | MTFace *mf, *df1, *df2; | ||||
| int l; | int l; | ||||
| for (l = 0; l < numlayer; l++) { | for (l = 0; l < numlayer; l++) { | ||||
| mf = CustomData_get_layer_n(&split->faceData, CD_MTFACE, l); | mf = CustomData_get_layer_n(&split->fdata, CD_MTFACE, l); | ||||
| df1 = mf + cur; | df1 = mf + cur; | ||||
| df2 = df1 + 1; | df2 = df1 + 1; | ||||
| mf = CustomData_get_layer_n(&dm->faceData, CD_MTFACE, l); | mf = CustomData_get_layer_n(&mesh->fdata, CD_MTFACE, l); | ||||
| mf += i; | mf += i; | ||||
| copy_v2_v2(df1->uv[0], mf->uv[c0]); | copy_v2_v2(df1->uv[0], mf->uv[c0]); | ||||
| copy_v2_v2(df1->uv[1], mf->uv[c1]); | copy_v2_v2(df1->uv[1], mf->uv[c1]); | ||||
| INT_UV(df1->uv[2], c1, c2); | INT_UV(df1->uv[2], c1, c2); | ||||
| INT_UV(df1->uv[3], c0, c3); | INT_UV(df1->uv[3], c0, c3); | ||||
| INT_UV(df2->uv[0], c0, c3); | INT_UV(df2->uv[0], c0, c3); | ||||
| INT_UV(df2->uv[1], c1, c2); | INT_UV(df2->uv[1], c1, c2); | ||||
| copy_v2_v2(df2->uv[2], mf->uv[c2]); | copy_v2_v2(df2->uv[2], mf->uv[c2]); | ||||
| copy_v2_v2(df2->uv[3], mf->uv[c3]); | copy_v2_v2(df2->uv[3], mf->uv[c3]); | ||||
| } | } | ||||
| } | } | ||||
| static void remap_faces_15(DerivedMesh *dm, DerivedMesh *split, MFace *mf, int *facepa, int *vertpa, int i, EdgeHash *eh, int cur, int v1, int v2, int v3, int v4) | static void remap_faces_15(Mesh *mesh, Mesh *split, MFace *mf, int *facepa, int *vertpa, int i, EdgeHash *eh, int cur, int v1, int v2, int v3, int v4) | ||||
| { | { | ||||
| MFace *df1 = get_dface(dm, split, cur, i, mf); | MFace *df1 = get_dface(mesh, split, cur, i, mf); | ||||
| MFace *df2 = get_dface(dm, split, cur + 1, i, mf); | MFace *df2 = get_dface(mesh, split, cur + 1, i, mf); | ||||
| MFace *df3 = get_dface(dm, split, cur + 2, i, mf); | MFace *df3 = get_dface(mesh, split, cur + 2, i, mf); | ||||
| MFace *df4 = get_dface(dm, split, cur + 3, i, mf); | MFace *df4 = get_dface(mesh, split, cur + 3, i, mf); | ||||
| facepa[cur] = vertpa[v1]; | facepa[cur] = vertpa[v1]; | ||||
| df1->v1 = v1; | df1->v1 = v1; | ||||
| df1->v2 = GET_ES(v1, v2); | df1->v2 = GET_ES(v1, v2); | ||||
| df1->v3 = GET_ES(v1, v3); | df1->v3 = GET_ES(v1, v3); | ||||
| df1->v4 = GET_ES(v1, v4); | df1->v4 = GET_ES(v1, v4); | ||||
| df1->flag |= ME_FACE_SEL; | df1->flag |= ME_FACE_SEL; | ||||
| Show All 14 Lines | static void remap_faces_15(Mesh *mesh, Mesh *split, MFace *mf, int *facepa, int *vertpa, int i, EdgeHash *eh, int cur, int v1, int v2, int v3, int v4) | ||||
| facepa[cur + 3] = vertpa[v4]; | facepa[cur + 3] = vertpa[v4]; | ||||
| df4->v1 = GET_ES(v1, v4); | df4->v1 = GET_ES(v1, v4); | ||||
| df4->v2 = GET_ES(v1, v3); | df4->v2 = GET_ES(v1, v3); | ||||
| df4->v3 = GET_ES(v3, v4); | df4->v3 = GET_ES(v3, v4); | ||||
| df4->v4 = v4; | df4->v4 = v4; | ||||
| df4->flag |= ME_FACE_SEL; | df4->flag |= ME_FACE_SEL; | ||||
| } | } | ||||
| static void remap_uvs_15(DerivedMesh *dm, DerivedMesh *split, int numlayer, int i, int cur, int c0, int c1, int c2, int c3) | static void remap_uvs_15(Mesh *mesh, Mesh *split, int numlayer, int i, int cur, int c0, int c1, int c2, int c3) | ||||
| { | { | ||||
| MTFace *mf, *df1, *df2, *df3, *df4; | MTFace *mf, *df1, *df2, *df3, *df4; | ||||
| int l; | int l; | ||||
| for (l = 0; l < numlayer; l++) { | for (l = 0; l < numlayer; l++) { | ||||
| mf = CustomData_get_layer_n(&split->faceData, CD_MTFACE, l); | mf = CustomData_get_layer_n(&split->fdata, CD_MTFACE, l); | ||||
| df1 = mf + cur; | df1 = mf + cur; | ||||
| df2 = df1 + 1; | df2 = df1 + 1; | ||||
| df3 = df1 + 2; | df3 = df1 + 2; | ||||
| df4 = df1 + 3; | df4 = df1 + 3; | ||||
| mf = CustomData_get_layer_n(&dm->faceData, CD_MTFACE, l); | mf = CustomData_get_layer_n(&mesh->fdata, CD_MTFACE, l); | ||||
| mf += i; | mf += i; | ||||
| copy_v2_v2(df1->uv[0], mf->uv[c0]); | copy_v2_v2(df1->uv[0], mf->uv[c0]); | ||||
| INT_UV(df1->uv[1], c0, c1); | INT_UV(df1->uv[1], c0, c1); | ||||
| INT_UV(df1->uv[2], c0, c2); | INT_UV(df1->uv[2], c0, c2); | ||||
| INT_UV(df1->uv[3], c0, c3); | INT_UV(df1->uv[3], c0, c3); | ||||
| INT_UV(df2->uv[0], c0, c1); | INT_UV(df2->uv[0], c0, c1); | ||||
| copy_v2_v2(df2->uv[1], mf->uv[c1]); | copy_v2_v2(df2->uv[1], mf->uv[c1]); | ||||
| INT_UV(df2->uv[2], c1, c2); | INT_UV(df2->uv[2], c1, c2); | ||||
| INT_UV(df2->uv[3], c0, c2); | INT_UV(df2->uv[3], c0, c2); | ||||
| INT_UV(df3->uv[0], c0, c2); | INT_UV(df3->uv[0], c0, c2); | ||||
| INT_UV(df3->uv[1], c1, c2); | INT_UV(df3->uv[1], c1, c2); | ||||
| copy_v2_v2(df3->uv[2], mf->uv[c2]); | copy_v2_v2(df3->uv[2], mf->uv[c2]); | ||||
| INT_UV(df3->uv[3], c2, c3); | INT_UV(df3->uv[3], c2, c3); | ||||
| INT_UV(df4->uv[0], c0, c3); | INT_UV(df4->uv[0], c0, c3); | ||||
| INT_UV(df4->uv[1], c0, c2); | INT_UV(df4->uv[1], c0, c2); | ||||
| INT_UV(df4->uv[2], c2, c3); | INT_UV(df4->uv[2], c2, c3); | ||||
| copy_v2_v2(df4->uv[3], mf->uv[c3]); | copy_v2_v2(df4->uv[3], mf->uv[c3]); | ||||
| } | } | ||||
| } | } | ||||
| static void remap_faces_7_11_13_14(DerivedMesh *dm, DerivedMesh *split, MFace *mf, int *facepa, int *vertpa, int i, EdgeHash *eh, int cur, int v1, int v2, int v3, int v4) | static void remap_faces_7_11_13_14(Mesh *mesh, Mesh *split, MFace *mf, int *facepa, int *vertpa, int i, EdgeHash *eh, int cur, int v1, int v2, int v3, int v4) | ||||
| { | { | ||||
| MFace *df1 = get_dface(dm, split, cur, i, mf); | MFace *df1 = get_dface(mesh, split, cur, i, mf); | ||||
| MFace *df2 = get_dface(dm, split, cur + 1, i, mf); | MFace *df2 = get_dface(mesh, split, cur + 1, i, mf); | ||||
| MFace *df3 = get_dface(dm, split, cur + 2, i, mf); | MFace *df3 = get_dface(mesh, split, cur + 2, i, mf); | ||||
| facepa[cur] = vertpa[v1]; | facepa[cur] = vertpa[v1]; | ||||
| df1->v1 = v1; | df1->v1 = v1; | ||||
| df1->v2 = GET_ES(v1, v2); | df1->v2 = GET_ES(v1, v2); | ||||
| df1->v3 = GET_ES(v2, v3); | df1->v3 = GET_ES(v2, v3); | ||||
| df1->v4 = GET_ES(v1, v4); | df1->v4 = GET_ES(v1, v4); | ||||
| df1->flag |= ME_FACE_SEL; | df1->flag |= ME_FACE_SEL; | ||||
| facepa[cur + 1] = vertpa[v2]; | facepa[cur + 1] = vertpa[v2]; | ||||
| df2->v1 = GET_ES(v1, v2); | df2->v1 = GET_ES(v1, v2); | ||||
| df2->v2 = v2; | df2->v2 = v2; | ||||
| df2->v3 = GET_ES(v2, v3); | df2->v3 = GET_ES(v2, v3); | ||||
| df2->v4 = 0; | df2->v4 = 0; | ||||
| df2->flag &= ~ME_FACE_SEL; | df2->flag &= ~ME_FACE_SEL; | ||||
| facepa[cur + 2] = vertpa[v4]; | facepa[cur + 2] = vertpa[v4]; | ||||
| df3->v1 = GET_ES(v1, v4); | df3->v1 = GET_ES(v1, v4); | ||||
| df3->v2 = GET_ES(v2, v3); | df3->v2 = GET_ES(v2, v3); | ||||
| df3->v3 = v3; | df3->v3 = v3; | ||||
| df3->v4 = v4; | df3->v4 = v4; | ||||
| df3->flag |= ME_FACE_SEL; | df3->flag |= ME_FACE_SEL; | ||||
| } | } | ||||
| static void remap_uvs_7_11_13_14(DerivedMesh *dm, DerivedMesh *split, int numlayer, int i, int cur, int c0, int c1, int c2, int c3) | static void remap_uvs_7_11_13_14(Mesh *mesh, Mesh *split, int numlayer, int i, int cur, int c0, int c1, int c2, int c3) | ||||
| { | { | ||||
| MTFace *mf, *df1, *df2, *df3; | MTFace *mf, *df1, *df2, *df3; | ||||
| int l; | int l; | ||||
| for (l = 0; l < numlayer; l++) { | for (l = 0; l < numlayer; l++) { | ||||
| mf = CustomData_get_layer_n(&split->faceData, CD_MTFACE, l); | mf = CustomData_get_layer_n(&split->fdata, CD_MTFACE, l); | ||||
| df1 = mf + cur; | df1 = mf + cur; | ||||
| df2 = df1 + 1; | df2 = df1 + 1; | ||||
| df3 = df1 + 2; | df3 = df1 + 2; | ||||
| mf = CustomData_get_layer_n(&dm->faceData, CD_MTFACE, l); | mf = CustomData_get_layer_n(&mesh->fdata, CD_MTFACE, l); | ||||
| mf += i; | mf += i; | ||||
| copy_v2_v2(df1->uv[0], mf->uv[c0]); | copy_v2_v2(df1->uv[0], mf->uv[c0]); | ||||
| INT_UV(df1->uv[1], c0, c1); | INT_UV(df1->uv[1], c0, c1); | ||||
| INT_UV(df1->uv[2], c1, c2); | INT_UV(df1->uv[2], c1, c2); | ||||
| INT_UV(df1->uv[3], c0, c3); | INT_UV(df1->uv[3], c0, c3); | ||||
| INT_UV(df2->uv[0], c0, c1); | INT_UV(df2->uv[0], c0, c1); | ||||
| copy_v2_v2(df2->uv[1], mf->uv[c1]); | copy_v2_v2(df2->uv[1], mf->uv[c1]); | ||||
| INT_UV(df2->uv[2], c1, c2); | INT_UV(df2->uv[2], c1, c2); | ||||
| INT_UV(df3->uv[0], c0, c3); | INT_UV(df3->uv[0], c0, c3); | ||||
| INT_UV(df3->uv[1], c1, c2); | INT_UV(df3->uv[1], c1, c2); | ||||
| copy_v2_v2(df3->uv[2], mf->uv[c2]); | copy_v2_v2(df3->uv[2], mf->uv[c2]); | ||||
| copy_v2_v2(df3->uv[3], mf->uv[c3]); | copy_v2_v2(df3->uv[3], mf->uv[c3]); | ||||
| } | } | ||||
| } | } | ||||
| static void remap_faces_19_21_22(DerivedMesh *dm, DerivedMesh *split, MFace *mf, int *facepa, int *vertpa, int i, EdgeHash *eh, int cur, int v1, int v2, int v3) | static void remap_faces_19_21_22(Mesh *mesh, Mesh *split, MFace *mf, int *facepa, int *vertpa, int i, EdgeHash *eh, int cur, int v1, int v2, int v3) | ||||
| { | { | ||||
| MFace *df1 = get_dface(dm, split, cur, i, mf); | MFace *df1 = get_dface(mesh, split, cur, i, mf); | ||||
| MFace *df2 = get_dface(dm, split, cur + 1, i, mf); | MFace *df2 = get_dface(mesh, split, cur + 1, i, mf); | ||||
| facepa[cur] = vertpa[v1]; | facepa[cur] = vertpa[v1]; | ||||
| df1->v1 = v1; | df1->v1 = v1; | ||||
| df1->v2 = GET_ES(v1, v2); | df1->v2 = GET_ES(v1, v2); | ||||
| df1->v3 = GET_ES(v1, v3); | df1->v3 = GET_ES(v1, v3); | ||||
| df1->v4 = 0; | df1->v4 = 0; | ||||
| df1->flag &= ~ME_FACE_SEL; | df1->flag &= ~ME_FACE_SEL; | ||||
| facepa[cur + 1] = vertpa[v2]; | facepa[cur + 1] = vertpa[v2]; | ||||
| df2->v1 = GET_ES(v1, v2); | df2->v1 = GET_ES(v1, v2); | ||||
| df2->v2 = v2; | df2->v2 = v2; | ||||
| df2->v3 = v3; | df2->v3 = v3; | ||||
| df2->v4 = GET_ES(v1, v3); | df2->v4 = GET_ES(v1, v3); | ||||
| df2->flag |= ME_FACE_SEL; | df2->flag |= ME_FACE_SEL; | ||||
| } | } | ||||
| static void remap_uvs_19_21_22(DerivedMesh *dm, DerivedMesh *split, int numlayer, int i, int cur, int c0, int c1, int c2) | static void remap_uvs_19_21_22(Mesh *mesh, Mesh *split, int numlayer, int i, int cur, int c0, int c1, int c2) | ||||
| { | { | ||||
| MTFace *mf, *df1, *df2; | MTFace *mf, *df1, *df2; | ||||
| int l; | int l; | ||||
| for (l = 0; l < numlayer; l++) { | for (l = 0; l < numlayer; l++) { | ||||
| mf = CustomData_get_layer_n(&split->faceData, CD_MTFACE, l); | mf = CustomData_get_layer_n(&split->fdata, CD_MTFACE, l); | ||||
| df1 = mf + cur; | df1 = mf + cur; | ||||
| df2 = df1 + 1; | df2 = df1 + 1; | ||||
| mf = CustomData_get_layer_n(&dm->faceData, CD_MTFACE, l); | mf = CustomData_get_layer_n(&mesh->fdata, CD_MTFACE, l); | ||||
| mf += i; | mf += i; | ||||
| copy_v2_v2(df1->uv[0], mf->uv[c0]); | copy_v2_v2(df1->uv[0], mf->uv[c0]); | ||||
| INT_UV(df1->uv[1], c0, c1); | INT_UV(df1->uv[1], c0, c1); | ||||
| INT_UV(df1->uv[2], c0, c2); | INT_UV(df1->uv[2], c0, c2); | ||||
| INT_UV(df2->uv[0], c0, c1); | INT_UV(df2->uv[0], c0, c1); | ||||
| copy_v2_v2(df2->uv[1], mf->uv[c1]); | copy_v2_v2(df2->uv[1], mf->uv[c1]); | ||||
| copy_v2_v2(df2->uv[2], mf->uv[c2]); | copy_v2_v2(df2->uv[2], mf->uv[c2]); | ||||
| INT_UV(df2->uv[3], c0, c2); | INT_UV(df2->uv[3], c0, c2); | ||||
| } | } | ||||
| } | } | ||||
| static void remap_faces_23(DerivedMesh *dm, DerivedMesh *split, MFace *mf, int *facepa, int *vertpa, int i, EdgeHash *eh, int cur, int v1, int v2, int v3) | static void remap_faces_23(Mesh *mesh, Mesh *split, MFace *mf, int *facepa, int *vertpa, int i, EdgeHash *eh, int cur, int v1, int v2, int v3) | ||||
| { | { | ||||
| MFace *df1 = get_dface(dm, split, cur, i, mf); | MFace *df1 = get_dface(mesh, split, cur, i, mf); | ||||
| MFace *df2 = get_dface(dm, split, cur + 1, i, mf); | MFace *df2 = get_dface(mesh, split, cur + 1, i, mf); | ||||
| MFace *df3 = get_dface(dm, split, cur + 2, i, mf); | MFace *df3 = get_dface(mesh, split, cur + 2, i, mf); | ||||
| facepa[cur] = vertpa[v1]; | facepa[cur] = vertpa[v1]; | ||||
| df1->v1 = v1; | df1->v1 = v1; | ||||
| df1->v2 = GET_ES(v1, v2); | df1->v2 = GET_ES(v1, v2); | ||||
| df1->v3 = GET_ES(v2, v3); | df1->v3 = GET_ES(v2, v3); | ||||
| df1->v4 = GET_ES(v1, v3); | df1->v4 = GET_ES(v1, v3); | ||||
| df1->flag |= ME_FACE_SEL; | df1->flag |= ME_FACE_SEL; | ||||
| facepa[cur + 1] = vertpa[v2]; | facepa[cur + 1] = vertpa[v2]; | ||||
| df2->v1 = GET_ES(v1, v2); | df2->v1 = GET_ES(v1, v2); | ||||
| df2->v2 = v2; | df2->v2 = v2; | ||||
| df2->v3 = GET_ES(v2, v3); | df2->v3 = GET_ES(v2, v3); | ||||
| df2->v4 = 0; | df2->v4 = 0; | ||||
| df2->flag &= ~ME_FACE_SEL; | df2->flag &= ~ME_FACE_SEL; | ||||
| facepa[cur + 2] = vertpa[v3]; | facepa[cur + 2] = vertpa[v3]; | ||||
| df3->v1 = GET_ES(v1, v3); | df3->v1 = GET_ES(v1, v3); | ||||
| df3->v2 = GET_ES(v2, v3); | df3->v2 = GET_ES(v2, v3); | ||||
| df3->v3 = v3; | df3->v3 = v3; | ||||
| df3->v4 = 0; | df3->v4 = 0; | ||||
| df3->flag &= ~ME_FACE_SEL; | df3->flag &= ~ME_FACE_SEL; | ||||
| } | } | ||||
| static void remap_uvs_23(DerivedMesh *dm, DerivedMesh *split, int numlayer, int i, int cur, int c0, int c1, int c2) | static void remap_uvs_23(Mesh *mesh, Mesh *split, int numlayer, int i, int cur, int c0, int c1, int c2) | ||||
| { | { | ||||
| MTFace *mf, *df1, *df2; | MTFace *mf, *df1, *df2; | ||||
| int l; | int l; | ||||
| for (l = 0; l < numlayer; l++) { | for (l = 0; l < numlayer; l++) { | ||||
| mf = CustomData_get_layer_n(&split->faceData, CD_MTFACE, l); | mf = CustomData_get_layer_n(&split->fdata, CD_MTFACE, l); | ||||
| df1 = mf + cur; | df1 = mf + cur; | ||||
| df2 = df1 + 1; | df2 = df1 + 1; | ||||
| mf = CustomData_get_layer_n(&dm->faceData, CD_MTFACE, l); | mf = CustomData_get_layer_n(&mesh->fdata, CD_MTFACE, l); | ||||
| mf += i; | mf += i; | ||||
| copy_v2_v2(df1->uv[0], mf->uv[c0]); | copy_v2_v2(df1->uv[0], mf->uv[c0]); | ||||
| INT_UV(df1->uv[1], c0, c1); | INT_UV(df1->uv[1], c0, c1); | ||||
| INT_UV(df1->uv[2], c1, c2); | INT_UV(df1->uv[2], c1, c2); | ||||
| INT_UV(df1->uv[3], c0, c2); | INT_UV(df1->uv[3], c0, c2); | ||||
| INT_UV(df2->uv[0], c0, c1); | INT_UV(df2->uv[0], c0, c1); | ||||
| copy_v2_v2(df2->uv[1], mf->uv[c1]); | copy_v2_v2(df2->uv[1], mf->uv[c1]); | ||||
| INT_UV(df2->uv[2], c1, c2); | INT_UV(df2->uv[2], c1, c2); | ||||
| INT_UV(df2->uv[0], c0, c2); | INT_UV(df2->uv[0], c0, c2); | ||||
| INT_UV(df2->uv[1], c1, c2); | INT_UV(df2->uv[1], c1, c2); | ||||
| copy_v2_v2(df2->uv[2], mf->uv[c2]); | copy_v2_v2(df2->uv[2], mf->uv[c2]); | ||||
| } | } | ||||
| } | } | ||||
| static DerivedMesh *cutEdges(ExplodeModifierData *emd, DerivedMesh *dm) | static Mesh *cutEdges(ExplodeModifierData *emd, Mesh *mesh) | ||||
| { | { | ||||
| DerivedMesh *splitdm; | Mesh *split_m; | ||||
| MFace *mf = NULL, *df1 = NULL; | MFace *mf = NULL, *df1 = NULL; | ||||
| MFace *mface = dm->getTessFaceArray(dm); | MFace *mface = mesh->mface; | ||||
| MVert *dupve, *mv; | MVert *dupve, *mv; | ||||
| EdgeHash *edgehash; | EdgeHash *edgehash; | ||||
| EdgeHashIterator *ehi; | EdgeHashIterator *ehi; | ||||
| int totvert = dm->getNumVerts(dm); | int totvert = mesh->totvert; | ||||
| int totface = dm->getNumTessFaces(dm); | int totface = mesh->totface; | ||||
| int *facesplit = MEM_calloc_arrayN(totface, sizeof(int), "explode_facesplit"); | int *facesplit = MEM_calloc_arrayN(totface, sizeof(int), "explode_facesplit"); | ||||
| int *vertpa = MEM_calloc_arrayN(totvert, sizeof(int), "explode_vertpa2"); | int *vertpa = MEM_calloc_arrayN(totvert, sizeof(int), "explode_vertpa2"); | ||||
| int *facepa = emd->facepa; | int *facepa = emd->facepa; | ||||
| int *fs, totesplit = 0, totfsplit = 0, curdupface = 0; | int *fs, totesplit = 0, totfsplit = 0, curdupface = 0; | ||||
| int i, v1, v2, v3, v4, esplit, | int i, v1, v2, v3, v4, esplit, | ||||
| v[4] = {0, 0, 0, 0}, /* To quite gcc barking... */ | v[4] = {0, 0, 0, 0}, /* To quite gcc barking... */ | ||||
| uv[4] = {0, 0, 0, 0}; /* To quite gcc barking... */ | uv[4] = {0, 0, 0, 0}; /* To quite gcc barking... */ | ||||
| int numlayer; | int numlayer; | ||||
| unsigned int ed_v1, ed_v2; | unsigned int ed_v1, ed_v2; | ||||
| edgehash = BLI_edgehash_new(__func__); | edgehash = BLI_edgehash_new(__func__); | ||||
| /* recreate vertpa from facepa calculation */ | /* recreate vertpa from facepa calculation */ | ||||
| for (i = 0, mf = mface; i < totface; i++, mf++) { | for (i = 0, mf = mface; i < totface; i++, mf++) { | ||||
| vertpa[mf->v1] = facepa[i]; | vertpa[mf->v1] = facepa[i]; | ||||
| vertpa[mf->v2] = facepa[i]; | vertpa[mf->v2] = facepa[i]; | ||||
| vertpa[mf->v3] = facepa[i]; | vertpa[mf->v3] = facepa[i]; | ||||
| if (mf->v4) | if (mf->v4) { | ||||
| vertpa[mf->v4] = facepa[i]; | vertpa[mf->v4] = facepa[i]; | ||||
| } | } | ||||
| } | |||||
| /* mark edges for splitting and how to split faces */ | /* mark edges for splitting and how to split faces */ | ||||
| for (i = 0, mf = mface, fs = facesplit; i < totface; i++, mf++, fs++) { | for (i = 0, mf = mface, fs = facesplit; i < totface; i++, mf++, fs++) { | ||||
| v1 = vertpa[mf->v1]; | v1 = vertpa[mf->v1]; | ||||
| v2 = vertpa[mf->v2]; | v2 = vertpa[mf->v2]; | ||||
| v3 = vertpa[mf->v3]; | v3 = vertpa[mf->v3]; | ||||
| if (v1 != v2) { | if (v1 != v2) { | ||||
| Show All 15 Lines | if (mf->v4) { | ||||
| } | } | ||||
| if (v1 != v4) { | if (v1 != v4) { | ||||
| BLI_edgehash_reinsert(edgehash, mf->v1, mf->v4, NULL); | BLI_edgehash_reinsert(edgehash, mf->v1, mf->v4, NULL); | ||||
| (*fs) |= 8; | (*fs) |= 8; | ||||
| } | } | ||||
| /* mark center vertex as a fake edge split */ | /* mark center vertex as a fake edge split */ | ||||
| if (*fs == 15) | if (*fs == 15) { | ||||
| BLI_edgehash_reinsert(edgehash, mf->v1, mf->v3, NULL); | BLI_edgehash_reinsert(edgehash, mf->v1, mf->v3, NULL); | ||||
| } | } | ||||
| } | |||||
| else { | else { | ||||
| (*fs) |= 16; /* mark face as tri */ | (*fs) |= 16; /* mark face as tri */ | ||||
| if (v1 != v3) { | if (v1 != v3) { | ||||
| BLI_edgehash_reinsert(edgehash, mf->v1, mf->v3, NULL); | BLI_edgehash_reinsert(edgehash, mf->v1, mf->v3, NULL); | ||||
| (*fs) |= 4; | (*fs) |= 4; | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| /* count splits & create indexes for new verts */ | /* count splits & create indexes for new verts */ | ||||
| ehi = BLI_edgehashIterator_new(edgehash); | ehi = BLI_edgehashIterator_new(edgehash); | ||||
| totesplit = totvert; | totesplit = totvert; | ||||
| for (; !BLI_edgehashIterator_isDone(ehi); BLI_edgehashIterator_step(ehi)) { | for (; !BLI_edgehashIterator_isDone(ehi); BLI_edgehashIterator_step(ehi)) { | ||||
| BLI_edgehashIterator_setValue(ehi, POINTER_FROM_INT(totesplit)); | BLI_edgehashIterator_setValue(ehi, POINTER_FROM_INT(totesplit)); | ||||
| totesplit++; | totesplit++; | ||||
| } | } | ||||
| BLI_edgehashIterator_free(ehi); | BLI_edgehashIterator_free(ehi); | ||||
| /* count new faces due to splitting */ | /* count new faces due to splitting */ | ||||
| for (i = 0, fs = facesplit; i < totface; i++, fs++) | for (i = 0, fs = facesplit; i < totface; i++, fs++) | ||||
| totfsplit += add_faces[*fs]; | totfsplit += add_faces[*fs]; | ||||
| splitdm = CDDM_from_template_ex( | split_m = BKE_mesh_new_nomain_from_template( | ||||
| dm, totesplit, 0, totface + totfsplit, 0, 0, | mesh, totesplit, 0, totface + totfsplit, 0, 0); | ||||
| CD_MASK_DERIVEDMESH | CD_MASK_FACECORNERS); | |||||
| numlayer = CustomData_number_of_layers(&splitdm->faceData, CD_MTFACE); | numlayer = CustomData_number_of_layers(&split_m->fdata, CD_MTFACE); | ||||
| /* copy new faces & verts (is it really this painful with custom data??) */ | /* copy new faces & verts (is it really this painful with custom data??) */ | ||||
| for (i = 0; i < totvert; i++) { | for (i = 0; i < totvert; i++) { | ||||
| MVert source; | MVert source; | ||||
| MVert *dest; | MVert *dest; | ||||
| dm->getVert(dm, i, &source); | source = mesh->mvert[i]; | ||||
| dest = CDDM_get_vert(splitdm, i); | dest = &split_m->mvert[i]; | ||||
| DM_copy_vert_data(dm, splitdm, i, i, 1); | CustomData_copy_data(&mesh->vdata, &split_m->vdata, i, i, 1); | ||||
| *dest = source; | *dest = source; | ||||
| } | } | ||||
| /* override original facepa (original pointer is saved in caller function) */ | /* override original facepa (original pointer is saved in caller function) */ | ||||
| /* BMESH_TODO, (totfsplit * 2) over allocation is used since the quads are | /* BMESH_TODO, (totfsplit * 2) over allocation is used since the quads are | ||||
| * later interpreted as tri's, for this to work right I think we probably | * later interpreted as tri's, for this to work right I think we probably | ||||
| * have to stop using tessface - campbell */ | * have to stop using tessface - campbell */ | ||||
| facepa = MEM_calloc_arrayN((totface + (totfsplit * 2)), sizeof(int), "explode_facepa"); | facepa = MEM_calloc_arrayN((totface + (totfsplit * 2)), sizeof(int), "explode_facepa"); | ||||
| //memcpy(facepa, emd->facepa, totface*sizeof(int)); | //memcpy(facepa, emd->facepa, totface*sizeof(int)); | ||||
| emd->facepa = facepa; | emd->facepa = facepa; | ||||
| /* create new verts */ | /* create new verts */ | ||||
| ehi = BLI_edgehashIterator_new(edgehash); | ehi = BLI_edgehashIterator_new(edgehash); | ||||
| for (; !BLI_edgehashIterator_isDone(ehi); BLI_edgehashIterator_step(ehi)) { | for (; !BLI_edgehashIterator_isDone(ehi); BLI_edgehashIterator_step(ehi)) { | ||||
| BLI_edgehashIterator_getKey(ehi, &ed_v1, &ed_v2); | BLI_edgehashIterator_getKey(ehi, &ed_v1, &ed_v2); | ||||
| esplit = POINTER_AS_INT(BLI_edgehashIterator_getValue(ehi)); | esplit = POINTER_AS_INT(BLI_edgehashIterator_getValue(ehi)); | ||||
| mv = CDDM_get_vert(splitdm, ed_v2); | mv = &split_m->mvert[ed_v2]; | ||||
| dupve = CDDM_get_vert(splitdm, esplit); | dupve = &split_m->mvert[esplit]; | ||||
| DM_copy_vert_data(splitdm, splitdm, ed_v2, esplit, 1); | CustomData_copy_data(&split_m->vdata, &split_m->vdata, ed_v2, esplit, 1); | ||||
| *dupve = *mv; | *dupve = *mv; | ||||
| mv = CDDM_get_vert(splitdm, ed_v1); | mv = &split_m->mvert[ed_v1]; | ||||
| mid_v3_v3v3(dupve->co, dupve->co, mv->co); | mid_v3_v3v3(dupve->co, dupve->co, mv->co); | ||||
| } | } | ||||
| BLI_edgehashIterator_free(ehi); | BLI_edgehashIterator_free(ehi); | ||||
| /* create new faces */ | /* create new faces */ | ||||
| curdupface = 0; //=totface; | curdupface = 0; //=totface; | ||||
| //curdupin=totesplit; | //curdupin=totesplit; | ||||
| for (i = 0, fs = facesplit; i < totface; i++, fs++) { | for (i = 0, fs = facesplit; i < totface; i++, fs++) { | ||||
| mf = dm->getTessFaceData(dm, i, CD_MFACE); | mf = &mesh->mface[i]; | ||||
| switch (*fs) { | switch (*fs) { | ||||
| case 3: | case 3: | ||||
| case 10: | case 10: | ||||
| case 11: | case 11: | ||||
| case 15: | case 15: | ||||
| SET_VERTS(1, 2, 3, 4); | SET_VERTS(1, 2, 3, 4); | ||||
| break; | break; | ||||
| case 5: | case 5: | ||||
Not Done Inline ActionsRather than this hack, you can change BKE_mesh_new_nomain_from_template_ex: - const bool do_tessface = ((me_src->totface != 0) && (me_src->totpoly == 0)); /* only do tessface if we have no polys */ + /* Only do tessface if we are creating tessfaces or copying from mesh with only tessfaces. */ + const bool do_tessface = (tessface_len || + (me_src->totface != 0) && (me_src->totpoly == 0)); brecht: Rather than this hack, you can change `BKE_mesh_new_nomain_from_template_ex`:
```
- const bool… | |||||
| case 6: | case 6: | ||||
| case 7: | case 7: | ||||
| SET_VERTS(2, 3, 4, 1); | SET_VERTS(2, 3, 4, 1); | ||||
| break; | break; | ||||
| case 9: | case 9: | ||||
| case 13: | case 13: | ||||
| SET_VERTS(4, 1, 2, 3); | SET_VERTS(4, 1, 2, 3); | ||||
| break; | break; | ||||
| Show All 13 Lines | switch (*fs) { | ||||
| break; | break; | ||||
| } | } | ||||
| switch (*fs) { | switch (*fs) { | ||||
| case 3: | case 3: | ||||
| case 6: | case 6: | ||||
| case 9: | case 9: | ||||
| case 12: | case 12: | ||||
| remap_faces_3_6_9_12(dm, splitdm, mf, facepa, vertpa, i, edgehash, curdupface, v[0], v[1], v[2], v[3]); | remap_faces_3_6_9_12(mesh, split_m, mf, facepa, vertpa, i, edgehash, curdupface, v[0], v[1], v[2], v[3]); | ||||
| if (numlayer) | if (numlayer) { | ||||
| remap_uvs_3_6_9_12(dm, splitdm, numlayer, i, curdupface, uv[0], uv[1], uv[2], uv[3]); | remap_uvs_3_6_9_12(mesh, split_m, numlayer, i, curdupface, uv[0], uv[1], uv[2], uv[3]); | ||||
| } | |||||
| break; | break; | ||||
| case 5: | case 5: | ||||
| case 10: | case 10: | ||||
| remap_faces_5_10(dm, splitdm, mf, facepa, vertpa, i, edgehash, curdupface, v[0], v[1], v[2], v[3]); | remap_faces_5_10(mesh, split_m, mf, facepa, vertpa, i, edgehash, curdupface, v[0], v[1], v[2], v[3]); | ||||
| if (numlayer) | if (numlayer) { | ||||
| remap_uvs_5_10(dm, splitdm, numlayer, i, curdupface, uv[0], uv[1], uv[2], uv[3]); | remap_uvs_5_10(mesh, split_m, numlayer, i, curdupface, uv[0], uv[1], uv[2], uv[3]); | ||||
| } | |||||
| break; | break; | ||||
| case 15: | case 15: | ||||
| remap_faces_15(dm, splitdm, mf, facepa, vertpa, i, edgehash, curdupface, v[0], v[1], v[2], v[3]); | remap_faces_15(mesh, split_m, mf, facepa, vertpa, i, edgehash, curdupface, v[0], v[1], v[2], v[3]); | ||||
| if (numlayer) | if (numlayer) { | ||||
| remap_uvs_15(dm, splitdm, numlayer, i, curdupface, uv[0], uv[1], uv[2], uv[3]); | remap_uvs_15(mesh, split_m, numlayer, i, curdupface, uv[0], uv[1], uv[2], uv[3]); | ||||
| } | |||||
| break; | break; | ||||
| case 7: | case 7: | ||||
| case 11: | case 11: | ||||
| case 13: | case 13: | ||||
| case 14: | case 14: | ||||
| remap_faces_7_11_13_14(dm, splitdm, mf, facepa, vertpa, i, edgehash, curdupface, v[0], v[1], v[2], v[3]); | remap_faces_7_11_13_14(mesh, split_m, mf, facepa, vertpa, i, edgehash, curdupface, v[0], v[1], v[2], v[3]); | ||||
| if (numlayer) | if (numlayer) { | ||||
| remap_uvs_7_11_13_14(dm, splitdm, numlayer, i, curdupface, uv[0], uv[1], uv[2], uv[3]); | remap_uvs_7_11_13_14(mesh, split_m, numlayer, i, curdupface, uv[0], uv[1], uv[2], uv[3]); | ||||
| } | |||||
| break; | break; | ||||
| case 19: | case 19: | ||||
| case 21: | case 21: | ||||
| case 22: | case 22: | ||||
| remap_faces_19_21_22(dm, splitdm, mf, facepa, vertpa, i, edgehash, curdupface, v[0], v[1], v[2]); | remap_faces_19_21_22(mesh, split_m, mf, facepa, vertpa, i, edgehash, curdupface, v[0], v[1], v[2]); | ||||
| if (numlayer) | if (numlayer) { | ||||
| remap_uvs_19_21_22(dm, splitdm, numlayer, i, curdupface, uv[0], uv[1], uv[2]); | remap_uvs_19_21_22(mesh, split_m, numlayer, i, curdupface, uv[0], uv[1], uv[2]); | ||||
| } | |||||
| break; | break; | ||||
| case 23: | case 23: | ||||
| remap_faces_23(dm, splitdm, mf, facepa, vertpa, i, edgehash, curdupface, v[0], v[1], v[2]); | remap_faces_23(mesh, split_m, mf, facepa, vertpa, i, edgehash, curdupface, v[0], v[1], v[2]); | ||||
| if (numlayer) | if (numlayer) { | ||||
| remap_uvs_23(dm, splitdm, numlayer, i, curdupface, uv[0], uv[1], uv[2]); | remap_uvs_23(mesh, split_m, numlayer, i, curdupface, uv[0], uv[1], uv[2]); | ||||
| } | |||||
| break; | break; | ||||
| case 0: | case 0: | ||||
| case 16: | case 16: | ||||
| df1 = get_dface(dm, splitdm, curdupface, i, mf); | df1 = get_dface(mesh, split_m, curdupface, i, mf); | ||||
| facepa[curdupface] = vertpa[mf->v1]; | facepa[curdupface] = vertpa[mf->v1]; | ||||
| if (df1->v4) | if (df1->v4) { | ||||
| df1->flag |= ME_FACE_SEL; | df1->flag |= ME_FACE_SEL; | ||||
| else | } | ||||
| else { | |||||
| df1->flag &= ~ME_FACE_SEL; | df1->flag &= ~ME_FACE_SEL; | ||||
| } | |||||
| break; | break; | ||||
| } | } | ||||
| curdupface += add_faces[*fs] + 1; | curdupface += add_faces[*fs] + 1; | ||||
| } | } | ||||
| for (i = 0; i < curdupface; i++) { | for (i = 0; i < curdupface; i++) { | ||||
| mf = CDDM_get_tessface(splitdm, i); | mf = &split_m->mface[i]; | ||||
| test_index_face(mf, &splitdm->faceData, i, ((mf->flag & ME_FACE_SEL) ? 4 : 3)); | test_index_face(mf, &split_m->fdata, i, ((mf->flag & ME_FACE_SEL) ? 4 : 3)); | ||||
| } | } | ||||
| BLI_edgehash_free(edgehash, NULL); | BLI_edgehash_free(edgehash, NULL); | ||||
| MEM_freeN(facesplit); | MEM_freeN(facesplit); | ||||
| MEM_freeN(vertpa); | MEM_freeN(vertpa); | ||||
| CDDM_calc_edges_tessface(splitdm); | BKE_mesh_calc_edges_tessface(split_m); | ||||
| CDDM_tessfaces_to_faces(splitdm); /*builds ngon faces from tess (mface) faces*/ | BKE_mesh_convert_mfaces_to_mpolys(split_m); | ||||
| return splitdm; | return split_m; | ||||
| } | } | ||||
| static DerivedMesh *explodeMesh( | static Mesh *explodeMesh( | ||||
| ExplodeModifierData *emd, | ExplodeModifierData *emd, | ||||
| ParticleSystemModifierData *psmd, const ModifierEvalContext *ctx, Scene *scene, | ParticleSystemModifierData *psmd, const ModifierEvalContext *ctx, Scene *scene, | ||||
| DerivedMesh *to_explode) | Mesh *to_explode) | ||||
| { | { | ||||
| DerivedMesh *explode, *dm = to_explode; | Mesh *explode, *mesh = to_explode; | ||||
| MFace *mf = NULL, *mface; | MFace *mf = NULL, *mface; | ||||
| /* ParticleSettings *part=psmd->psys->part; */ /* UNUSED */ | /* ParticleSettings *part=psmd->psys->part; */ /* UNUSED */ | ||||
| ParticleSimulationData sim = {NULL}; | ParticleSimulationData sim = {NULL}; | ||||
| ParticleData *pa = NULL, *pars = psmd->psys->particles; | ParticleData *pa = NULL, *pars = psmd->psys->particles; | ||||
| ParticleKey state, birth; | ParticleKey state, birth; | ||||
| EdgeHash *vertpahash; | EdgeHash *vertpahash; | ||||
| EdgeHashIterator *ehi; | EdgeHashIterator *ehi; | ||||
| float *vertco = NULL, imat[4][4]; | float *vertco = NULL, imat[4][4]; | ||||
| float rot[4]; | float rot[4]; | ||||
| float cfra; | float cfra; | ||||
| /* float timestep; */ | /* float timestep; */ | ||||
| const int *facepa = emd->facepa; | const int *facepa = emd->facepa; | ||||
| int totdup = 0, totvert = 0, totface = 0, totpart = 0, delface = 0; | int totdup = 0, totvert = 0, totface = 0, totpart = 0, delface = 0; | ||||
| int i, v, u; | int i, v, u; | ||||
| unsigned int ed_v1, ed_v2, mindex = 0; | unsigned int ed_v1, ed_v2, mindex = 0; | ||||
| MTFace *mtface = NULL, *mtf; | MTFace *mtface = NULL, *mtf; | ||||
| totface = dm->getNumTessFaces(dm); | totface = mesh->totface; | ||||
| totvert = dm->getNumVerts(dm); | totvert = mesh->totvert; | ||||
| mface = dm->getTessFaceArray(dm); | mface = mesh->mface; | ||||
| totpart = psmd->psys->totpart; | totpart = psmd->psys->totpart; | ||||
| sim.depsgraph = ctx->depsgraph; | sim.depsgraph = ctx->depsgraph; | ||||
| sim.scene = scene; | sim.scene = scene; | ||||
| sim.ob = ctx->object; | sim.ob = ctx->object; | ||||
| sim.psys = psmd->psys; | sim.psys = psmd->psys; | ||||
| sim.psmd = psmd; | sim.psmd = psmd; | ||||
| Show All 14 Lines | if (facepa[i] != totpart) { | ||||
| { | { | ||||
| delface++; | delface++; | ||||
| continue; | continue; | ||||
| } | } | ||||
| } | } | ||||
| /* do mindex + totvert to ensure the vertex index to be the first | /* do mindex + totvert to ensure the vertex index to be the first | ||||
| * with BLI_edgehashIterator_getKey */ | * with BLI_edgehashIterator_getKey */ | ||||
| if (facepa[i] == totpart || cfra < (pars + facepa[i])->time) | if (facepa[i] == totpart || cfra < (pars + facepa[i])->time) { | ||||
| mindex = totvert + totpart; | mindex = totvert + totpart; | ||||
| else | } | ||||
| else { | |||||
| mindex = totvert + facepa[i]; | mindex = totvert + facepa[i]; | ||||
| } | |||||
| mf = &mface[i]; | mf = &mface[i]; | ||||
| /* set face vertices to exist in particle group */ | /* set face vertices to exist in particle group */ | ||||
| BLI_edgehash_reinsert(vertpahash, mf->v1, mindex, NULL); | BLI_edgehash_reinsert(vertpahash, mf->v1, mindex, NULL); | ||||
| BLI_edgehash_reinsert(vertpahash, mf->v2, mindex, NULL); | BLI_edgehash_reinsert(vertpahash, mf->v2, mindex, NULL); | ||||
| BLI_edgehash_reinsert(vertpahash, mf->v3, mindex, NULL); | BLI_edgehash_reinsert(vertpahash, mf->v3, mindex, NULL); | ||||
| if (mf->v4) | if (mf->v4) { | ||||
| BLI_edgehash_reinsert(vertpahash, mf->v4, mindex, NULL); | BLI_edgehash_reinsert(vertpahash, mf->v4, mindex, NULL); | ||||
| } | } | ||||
| } | |||||
| /* make new vertice indexes & count total vertices after duplication */ | /* make new vertice indexes & count total vertices after duplication */ | ||||
| ehi = BLI_edgehashIterator_new(vertpahash); | ehi = BLI_edgehashIterator_new(vertpahash); | ||||
| for (; !BLI_edgehashIterator_isDone(ehi); BLI_edgehashIterator_step(ehi)) { | for (; !BLI_edgehashIterator_isDone(ehi); BLI_edgehashIterator_step(ehi)) { | ||||
| BLI_edgehashIterator_setValue(ehi, POINTER_FROM_INT(totdup)); | BLI_edgehashIterator_setValue(ehi, POINTER_FROM_INT(totdup)); | ||||
| totdup++; | totdup++; | ||||
| } | } | ||||
| BLI_edgehashIterator_free(ehi); | BLI_edgehashIterator_free(ehi); | ||||
| /* the final duplicated vertices */ | /* the final duplicated vertices */ | ||||
| explode = CDDM_from_template_ex(dm, totdup, 0, totface - delface, 0, 0, CD_MASK_DERIVEDMESH | CD_MASK_FACECORNERS); | explode = BKE_mesh_new_nomain_from_template(mesh, totdup, 0, totface - delface, 0, 0); | ||||
| mtface = CustomData_get_layer_named(&explode->faceData, CD_MTFACE, emd->uvname); | |||||
| mtface = CustomData_get_layer_named(&explode->fdata, CD_MTFACE, emd->uvname); | |||||
| /*dupvert = CDDM_get_verts(explode);*/ | /*dupvert = CDDM_get_verts(explode);*/ | ||||
| /* getting back to object space */ | /* getting back to object space */ | ||||
| invert_m4_m4(imat, ctx->object->obmat); | invert_m4_m4(imat, ctx->object->obmat); | ||||
| psmd->psys->lattice_deform_data = psys_create_lattice_deform_data(&sim); | psmd->psys->lattice_deform_data = psys_create_lattice_deform_data(&sim); | ||||
| /* duplicate & displace vertices */ | /* duplicate & displace vertices */ | ||||
| ehi = BLI_edgehashIterator_new(vertpahash); | ehi = BLI_edgehashIterator_new(vertpahash); | ||||
| for (; !BLI_edgehashIterator_isDone(ehi); BLI_edgehashIterator_step(ehi)) { | for (; !BLI_edgehashIterator_isDone(ehi); BLI_edgehashIterator_step(ehi)) { | ||||
| MVert source; | MVert source; | ||||
| MVert *dest; | MVert *dest; | ||||
| /* get particle + vertex from hash */ | /* get particle + vertex from hash */ | ||||
| BLI_edgehashIterator_getKey(ehi, &ed_v1, &ed_v2); | BLI_edgehashIterator_getKey(ehi, &ed_v1, &ed_v2); | ||||
| ed_v2 -= totvert; | ed_v2 -= totvert; | ||||
| v = POINTER_AS_INT(BLI_edgehashIterator_getValue(ehi)); | v = POINTER_AS_INT(BLI_edgehashIterator_getValue(ehi)); | ||||
| dm->getVert(dm, ed_v1, &source); | source = mesh->mvert[ed_v1]; | ||||
| dest = CDDM_get_vert(explode, v); | dest = &explode->mvert[v]; | ||||
| CustomData_copy_data(&mesh->vdata, &explode->vdata, ed_v1, v, 1); | |||||
| DM_copy_vert_data(dm, explode, ed_v1, v, 1); | |||||
| *dest = source; | *dest = source; | ||||
| if (ed_v2 != totpart) { | if (ed_v2 != totpart) { | ||||
| /* get particle */ | /* get particle */ | ||||
| pa = pars + ed_v2; | pa = pars + ed_v2; | ||||
| psys_get_birth_coords(&sim, pa, &birth, 0, 0); | psys_get_birth_coords(&sim, pa, &birth, 0, 0); | ||||
| state.time = cfra; | state.time = cfra; | ||||
| psys_get_particle_state(&sim, ed_v2, &state, 1); | psys_get_particle_state(&sim, ed_v2, &state, 1); | ||||
| vertco = CDDM_get_vert(explode, v)->co; | vertco = explode->mvert[v].co; | ||||
| mul_m4_v3(ctx->object->obmat, vertco); | mul_m4_v3(ctx->object->obmat, vertco); | ||||
| sub_v3_v3(vertco, birth.co); | sub_v3_v3(vertco, birth.co); | ||||
| /* apply rotation, size & location */ | /* apply rotation, size & location */ | ||||
| sub_qt_qtqt(rot, state.rot, birth.rot); | sub_qt_qtqt(rot, state.rot, birth.rot); | ||||
| mul_qt_v3(rot, vertco); | mul_qt_v3(rot, vertco); | ||||
| if (emd->flag & eExplodeFlag_PaSize) | if (emd->flag & eExplodeFlag_PaSize) { | ||||
| mul_v3_fl(vertco, pa->size); | mul_v3_fl(vertco, pa->size); | ||||
| } | |||||
| add_v3_v3(vertco, state.co); | add_v3_v3(vertco, state.co); | ||||
| mul_m4_v3(imat, vertco); | mul_m4_v3(imat, vertco); | ||||
| } | } | ||||
| } | } | ||||
| BLI_edgehashIterator_free(ehi); | BLI_edgehashIterator_free(ehi); | ||||
| /*map new vertices to faces*/ | /*map new vertices to faces*/ | ||||
| for (i = 0, u = 0; i < totface; i++) { | for (i = 0, u = 0; i < totface; i++) { | ||||
| MFace source; | MFace source; | ||||
| int orig_v4; | int orig_v4; | ||||
| if (facepa[i] != totpart) { | if (facepa[i] != totpart) { | ||||
| pa = pars + facepa[i]; | pa = pars + facepa[i]; | ||||
| if (pa->alive == PARS_UNBORN && (emd->flag & eExplodeFlag_Unborn) == 0) continue; | if (pa->alive == PARS_UNBORN && (emd->flag & eExplodeFlag_Unborn) == 0) continue; | ||||
| if (pa->alive == PARS_ALIVE && (emd->flag & eExplodeFlag_Alive) == 0) continue; | if (pa->alive == PARS_ALIVE && (emd->flag & eExplodeFlag_Alive) == 0) continue; | ||||
| if (pa->alive == PARS_DEAD && (emd->flag & eExplodeFlag_Dead) == 0) continue; | if (pa->alive == PARS_DEAD && (emd->flag & eExplodeFlag_Dead) == 0) continue; | ||||
| } | } | ||||
| dm->getTessFace(dm, i, &source); | source = mesh->mface[i]; | ||||
| mf = CDDM_get_tessface(explode, u); | mf = &explode->mface[u]; | ||||
| orig_v4 = source.v4; | orig_v4 = source.v4; | ||||
| if (facepa[i] != totpart && cfra < pa->time) | if (facepa[i] != totpart && cfra < pa->time) { | ||||
| mindex = totvert + totpart; | mindex = totvert + totpart; | ||||
| else | } | ||||
| else { | |||||
| mindex = totvert + facepa[i]; | mindex = totvert + facepa[i]; | ||||
| } | |||||
| source.v1 = edgecut_get(vertpahash, source.v1, mindex); | source.v1 = edgecut_get(vertpahash, source.v1, mindex); | ||||
| source.v2 = edgecut_get(vertpahash, source.v2, mindex); | source.v2 = edgecut_get(vertpahash, source.v2, mindex); | ||||
| source.v3 = edgecut_get(vertpahash, source.v3, mindex); | source.v3 = edgecut_get(vertpahash, source.v3, mindex); | ||||
| if (source.v4) | if (source.v4) { | ||||
| source.v4 = edgecut_get(vertpahash, source.v4, mindex); | source.v4 = edgecut_get(vertpahash, source.v4, mindex); | ||||
| } | |||||
| DM_copy_tessface_data(dm, explode, i, u, 1); | CustomData_copy_data(&mesh->fdata, &explode->fdata, i, u, 1); | ||||
| *mf = source; | *mf = source; | ||||
| /* override uv channel for particle age */ | /* override uv channel for particle age */ | ||||
| if (mtface) { | if (mtface) { | ||||
| float age = (cfra - pa->time) / pa->lifetime; | float age = (cfra - pa->time) / pa->lifetime; | ||||
| /* Clamp to this range to avoid flipping to the other side of the coordinates. */ | /* Clamp to this range to avoid flipping to the other side of the coordinates. */ | ||||
| CLAMP(age, 0.001f, 0.999f); | CLAMP(age, 0.001f, 0.999f); | ||||
| mtf = mtface + u; | mtf = mtface + u; | ||||
| mtf->uv[0][0] = mtf->uv[1][0] = mtf->uv[2][0] = mtf->uv[3][0] = age; | mtf->uv[0][0] = mtf->uv[1][0] = mtf->uv[2][0] = mtf->uv[3][0] = age; | ||||
| mtf->uv[0][1] = mtf->uv[1][1] = mtf->uv[2][1] = mtf->uv[3][1] = 0.5f; | mtf->uv[0][1] = mtf->uv[1][1] = mtf->uv[2][1] = mtf->uv[3][1] = 0.5f; | ||||
| } | } | ||||
| test_index_face(mf, &explode->faceData, u, (orig_v4 ? 4 : 3)); | test_index_face(mf, &explode->fdata, u, (orig_v4 ? 4 : 3)); | ||||
| u++; | u++; | ||||
| } | } | ||||
| /* cleanup */ | /* cleanup */ | ||||
| BLI_edgehash_free(vertpahash, NULL); | BLI_edgehash_free(vertpahash, NULL); | ||||
| /* finalization */ | /* finalization */ | ||||
| CDDM_calc_edges_tessface(explode); | BKE_mesh_calc_edges_tessface(explode); | ||||
| CDDM_tessfaces_to_faces(explode); | BKE_mesh_convert_mfaces_to_mpolys(explode); | ||||
| explode->dirty |= DM_DIRTY_NORMALS; | explode->runtime.cd_dirty_vert |= CD_MASK_NORMAL; | ||||
| if (psmd->psys->lattice_deform_data) { | if (psmd->psys->lattice_deform_data) { | ||||
| end_latt_deform(psmd->psys->lattice_deform_data); | end_latt_deform(psmd->psys->lattice_deform_data); | ||||
| psmd->psys->lattice_deform_data = NULL; | psmd->psys->lattice_deform_data = NULL; | ||||
| } | } | ||||
| return explode; | return explode; | ||||
| } | } | ||||
| static ParticleSystemModifierData *findPrecedingParticlesystem(Object *ob, ModifierData *emd) | static ParticleSystemModifierData *findPrecedingParticlesystem(Object *ob, ModifierData *emd) | ||||
| { | { | ||||
| ModifierData *md; | ModifierData *md; | ||||
| ParticleSystemModifierData *psmd = NULL; | ParticleSystemModifierData *psmd = NULL; | ||||
| for (md = ob->modifiers.first; emd != md; md = md->next) { | for (md = ob->modifiers.first; emd != md; md = md->next) { | ||||
| if (md->type == eModifierType_ParticleSystem) | if (md->type == eModifierType_ParticleSystem) { | ||||
| psmd = (ParticleSystemModifierData *) md; | psmd = (ParticleSystemModifierData *) md; | ||||
| } | } | ||||
| } | |||||
| return psmd; | return psmd; | ||||
| } | } | ||||
| static DerivedMesh *applyModifier_DM( | static Mesh *applyModifier( | ||||
| ModifierData *md, const ModifierEvalContext *ctx, | ModifierData *md, const ModifierEvalContext *ctx, | ||||
| DerivedMesh *derivedData) | Mesh *mesh) | ||||
| { | { | ||||
| DerivedMesh *dm = derivedData; | |||||
| ExplodeModifierData *emd = (ExplodeModifierData *) md; | ExplodeModifierData *emd = (ExplodeModifierData *) md; | ||||
| ParticleSystemModifierData *psmd = findPrecedingParticlesystem(ctx->object, md); | ParticleSystemModifierData *psmd = findPrecedingParticlesystem(ctx->object, md); | ||||
| if (psmd) { | if (psmd) { | ||||
| ParticleSystem *psys = psmd->psys; | ParticleSystem *psys = psmd->psys; | ||||
| if (psys == NULL || psys->totpart == 0) return derivedData; | if (psys == NULL || psys->totpart == 0) { | ||||
| if (psys->part == NULL || psys->particles == NULL) return derivedData; | return mesh; | ||||
| if (psmd->mesh_final == NULL) return derivedData; | } | ||||
| if (psys->part == NULL || psys->particles == NULL) { | |||||
| return mesh; | |||||
| } | |||||
| if (psmd->mesh_final == NULL) { | |||||
| return mesh; | |||||
| } | |||||
| DM_ensure_tessface(dm); /* BMESH - UNTIL MODIFIER IS UPDATED FOR MPoly */ | BKE_mesh_tessface_ensure(mesh); /* BMESH - UNTIL MODIFIER IS UPDATED FOR MPoly */ | ||||
| /* 1. find faces to be exploded if needed */ | /* 1. find faces to be exploded if needed */ | ||||
| if (emd->facepa == NULL || | if (emd->facepa == NULL || | ||||
| psmd->flag & eParticleSystemFlag_Pars || | psmd->flag & eParticleSystemFlag_Pars || | ||||
| emd->flag & eExplodeFlag_CalcFaces || | emd->flag & eExplodeFlag_CalcFaces || | ||||
| MEM_allocN_len(emd->facepa) / sizeof(int) != dm->getNumTessFaces(dm)) | MEM_allocN_len(emd->facepa) / sizeof(int) != mesh->totface) | ||||
| { | { | ||||
| if (psmd->flag & eParticleSystemFlag_Pars) | if (psmd->flag & eParticleSystemFlag_Pars) { | ||||
| psmd->flag &= ~eParticleSystemFlag_Pars; | psmd->flag &= ~eParticleSystemFlag_Pars; | ||||
| } | |||||
| if (emd->flag & eExplodeFlag_CalcFaces) | if (emd->flag & eExplodeFlag_CalcFaces) { | ||||
| emd->flag &= ~eExplodeFlag_CalcFaces; | emd->flag &= ~eExplodeFlag_CalcFaces; | ||||
| } | |||||
| createFacepa(emd, psmd, derivedData); | createFacepa(emd, psmd, mesh); | ||||
| } | } | ||||
| /* 2. create new mesh */ | /* 2. create new mesh */ | ||||
| Scene *scene = DEG_get_evaluated_scene(ctx->depsgraph); | Scene *scene = DEG_get_evaluated_scene(ctx->depsgraph); | ||||
| if (emd->flag & eExplodeFlag_EdgeCut) { | if (emd->flag & eExplodeFlag_EdgeCut) { | ||||
| int *facepa = emd->facepa; | int *facepa = emd->facepa; | ||||
| DerivedMesh *splitdm = cutEdges(emd, dm); | Mesh *split_m = cutEdges(emd, mesh); | ||||
| DerivedMesh *explode = explodeMesh(emd, psmd, ctx, scene, splitdm); | Mesh *explode = explodeMesh(emd, psmd, ctx, scene, split_m); | ||||
| MEM_freeN(emd->facepa); | MEM_freeN(emd->facepa); | ||||
| emd->facepa = facepa; | emd->facepa = facepa; | ||||
| splitdm->release(splitdm); | BKE_id_free(NULL, split_m); | ||||
Not Done Inline ActionsThe new code for that is: explode->runtime.cd_dirty_vert |= CD_MASK_NORMAL; brecht: The new code for that is:
```
explode->runtime.cd_dirty_vert |= CD_MASK_NORMAL;
``` | |||||
| return explode; | return explode; | ||||
| } | } | ||||
| else { | else { | ||||
| return explodeMesh(emd, psmd, ctx, scene, derivedData); | return explodeMesh(emd, psmd, ctx, scene, mesh); | ||||
| } | } | ||||
| } | } | ||||
| return derivedData; | return mesh; | ||||
| } | } | ||||
| applyModifier_DM_wrapper(applyModifier, applyModifier_DM) | |||||
| ModifierTypeInfo modifierType_Explode = { | ModifierTypeInfo modifierType_Explode = { | ||||
| /* name */ "Explode", | /* name */ "Explode", | ||||
| /* structName */ "ExplodeModifierData", | /* structName */ "ExplodeModifierData", | ||||
| /* structSize */ sizeof(ExplodeModifierData), | /* structSize */ sizeof(ExplodeModifierData), | ||||
| /* type */ eModifierTypeType_Constructive, | /* type */ eModifierTypeType_Constructive, | ||||
| /* flags */ eModifierTypeFlag_AcceptsMesh, | /* flags */ eModifierTypeFlag_AcceptsMesh, | ||||
| /* copyData */ copyData, | /* copyData */ copyData, | ||||
| Show All 25 Lines | |||||
Can you rename this to BKE_mesh_calc_edges_tessface() and move it to mesh_validate.c?