Fix for [#26133] Explode modifier doesn't care about UVs (Option "split edges")
* This is basically a total rewrite of the edge split algorithm. The old one didn't handle tris at all and quads were cut wrong in some cases too with the addition of not handling uv coordinates at all. * This new algorithm uses a flag system to categorize different splits and the identical but rotated cases in a similar way to how marching cubes indexes different cases. * It cuts quads and tris and creates proper uv's for the new faces too. * I also renamed the option to "edge cut" to differentiate if from the edge split modifier and added an option to override a uv-channel in the exploded mesh with particle age as x-coordinate so that the shrapnel can be faded out nicely etc.
This commit is contained in:
parent
00c05c8404
commit
3bee6abb74
@ -259,9 +259,11 @@ class DATA_PT_modifiers(ModifierButtonsPanel, bpy.types.Panel):
|
|||||||
sub = col.column()
|
sub = col.column()
|
||||||
sub.active = bool(md.vertex_group)
|
sub.active = bool(md.vertex_group)
|
||||||
sub.prop(md, "protect")
|
sub.prop(md, "protect")
|
||||||
|
col.label(text="Particle UV")
|
||||||
|
col.prop_search(md, "particle_uv", ob.data, "uv_textures", text="")
|
||||||
|
|
||||||
col = split.column()
|
col = split.column()
|
||||||
col.prop(md, "use_edge_split")
|
col.prop(md, "use_edge_cut")
|
||||||
col.prop(md, "show_unborn")
|
col.prop(md, "show_unborn")
|
||||||
col.prop(md, "show_alive")
|
col.prop(md, "show_alive")
|
||||||
col.prop(md, "show_dead")
|
col.prop(md, "show_dead")
|
||||||
|
@ -588,7 +588,7 @@ typedef struct ParticleInstanceModifierData {
|
|||||||
typedef enum {
|
typedef enum {
|
||||||
eExplodeFlag_CalcFaces = (1<<0),
|
eExplodeFlag_CalcFaces = (1<<0),
|
||||||
eExplodeFlag_PaSize = (1<<1),
|
eExplodeFlag_PaSize = (1<<1),
|
||||||
eExplodeFlag_EdgeSplit = (1<<2),
|
eExplodeFlag_EdgeCut = (1<<2),
|
||||||
eExplodeFlag_Unborn = (1<<3),
|
eExplodeFlag_Unborn = (1<<3),
|
||||||
eExplodeFlag_Alive = (1<<4),
|
eExplodeFlag_Alive = (1<<4),
|
||||||
eExplodeFlag_Dead = (1<<5),
|
eExplodeFlag_Dead = (1<<5),
|
||||||
@ -599,6 +599,7 @@ typedef struct ExplodeModifierData {
|
|||||||
int *facepa;
|
int *facepa;
|
||||||
short flag, vgroup;
|
short flag, vgroup;
|
||||||
float protect;
|
float protect;
|
||||||
|
char uvname[32];
|
||||||
} ExplodeModifierData;
|
} ExplodeModifierData;
|
||||||
|
|
||||||
typedef struct MultiresModifierData {
|
typedef struct MultiresModifierData {
|
||||||
|
@ -1720,9 +1720,9 @@ static void rna_def_modifier_explode(BlenderRNA *brna)
|
|||||||
RNA_def_property_ui_text(prop, "Protect", "Clean vertex group edges");
|
RNA_def_property_ui_text(prop, "Protect", "Clean vertex group edges");
|
||||||
RNA_def_property_update(prop, 0, "rna_Modifier_update");
|
RNA_def_property_update(prop, 0, "rna_Modifier_update");
|
||||||
|
|
||||||
prop= RNA_def_property(srna, "use_edge_split", PROP_BOOLEAN, PROP_NONE);
|
prop= RNA_def_property(srna, "use_edge_cut", PROP_BOOLEAN, PROP_NONE);
|
||||||
RNA_def_property_boolean_sdna(prop, NULL, "flag", eExplodeFlag_EdgeSplit);
|
RNA_def_property_boolean_sdna(prop, NULL, "flag", eExplodeFlag_EdgeCut);
|
||||||
RNA_def_property_ui_text(prop, "Split Edges", "Split face edges for nicer shrapnel");
|
RNA_def_property_ui_text(prop, "Cut Edges", "Cut face edges for nicer shrapnel");
|
||||||
RNA_def_property_update(prop, 0, "rna_Modifier_update");
|
RNA_def_property_update(prop, 0, "rna_Modifier_update");
|
||||||
|
|
||||||
prop= RNA_def_property(srna, "show_unborn", PROP_BOOLEAN, PROP_NONE);
|
prop= RNA_def_property(srna, "show_unborn", PROP_BOOLEAN, PROP_NONE);
|
||||||
@ -1744,6 +1744,12 @@ static void rna_def_modifier_explode(BlenderRNA *brna)
|
|||||||
RNA_def_property_boolean_sdna(prop, NULL, "flag", eExplodeFlag_PaSize);
|
RNA_def_property_boolean_sdna(prop, NULL, "flag", eExplodeFlag_PaSize);
|
||||||
RNA_def_property_ui_text(prop, "Size", "Use particle size for the shrapnel");
|
RNA_def_property_ui_text(prop, "Size", "Use particle size for the shrapnel");
|
||||||
RNA_def_property_update(prop, 0, "rna_Modifier_update");
|
RNA_def_property_update(prop, 0, "rna_Modifier_update");
|
||||||
|
|
||||||
|
prop= RNA_def_property(srna, "particle_uv", PROP_STRING, PROP_NONE);
|
||||||
|
RNA_def_property_string_sdna(prop, NULL, "uvname");
|
||||||
|
RNA_def_property_string_maxlength(prop, 32);
|
||||||
|
RNA_def_property_ui_text(prop, "Particle UV", "UV Layer to change with particle age");
|
||||||
|
RNA_def_property_update(prop, 0, "rna_Modifier_update");
|
||||||
}
|
}
|
||||||
|
|
||||||
static void rna_def_modifier_cloth(BlenderRNA *brna)
|
static void rna_def_modifier_cloth(BlenderRNA *brna)
|
||||||
|
@ -180,15 +180,370 @@ static void createFacepa(ExplodeModifierData *emd,
|
|||||||
BLI_kdtree_free(tree);
|
BLI_kdtree_free(tree);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int edgesplit_get(EdgeHash *edgehash, int v1, int v2)
|
static int edgecut_get(EdgeHash *edgehash, int v1, int v2)
|
||||||
{
|
{
|
||||||
return GET_INT_FROM_POINTER(BLI_edgehash_lookup(edgehash, v1, v2));
|
return GET_INT_FROM_POINTER(BLI_edgehash_lookup(edgehash, v1, v2));
|
||||||
}
|
}
|
||||||
|
|
||||||
static DerivedMesh * splitEdges(ExplodeModifierData *emd, DerivedMesh *dm){
|
|
||||||
|
const short add_faces[24] = {
|
||||||
|
0,
|
||||||
|
0, 0, 2, 0, 1, 2, 2, 0, 2, 1,
|
||||||
|
2, 2, 2, 2, 3, 0, 0, 0, 1, 0,
|
||||||
|
1, 1, 2
|
||||||
|
};
|
||||||
|
|
||||||
|
MFace *get_dface(DerivedMesh *dm, DerivedMesh *split, int cur, int i, MFace *mf)
|
||||||
|
{
|
||||||
|
MFace *df = CDDM_get_face(split, cur);
|
||||||
|
DM_copy_face_data(dm, split, i, cur, 1);
|
||||||
|
*df = *mf;
|
||||||
|
return df;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define SET_VERTS(a, b, c, d) \
|
||||||
|
v[0]=mf->v##a; uv[0]=a-1; \
|
||||||
|
v[1]=mf->v##b; uv[1]=b-1; \
|
||||||
|
v[2]=mf->v##c; uv[2]=c-1; \
|
||||||
|
v[3]=mf->v##d; uv[3]=d-1;
|
||||||
|
|
||||||
|
#define GET_ES(v1, v2) edgecut_get(eh, v1, v2);
|
||||||
|
#define INT_UV(uvf, c0, c1) interp_v2_v2v2(uvf, mf->uv[c0], mf->uv[c1], 0.5f);
|
||||||
|
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
MFace *df1 = get_dface(dm, split, cur, i, mf);
|
||||||
|
MFace *df2 = get_dface(dm, split, cur+1, i, mf);
|
||||||
|
MFace *df3 = get_dface(dm, split, cur+2, i, mf);
|
||||||
|
|
||||||
|
facepa[cur] = vertpa[v1];
|
||||||
|
df1->v1 = v1;
|
||||||
|
df1->v2 = GET_ES(v1, v2)
|
||||||
|
df1->v3 = GET_ES(v2, v3)
|
||||||
|
df1->v4 = v3;
|
||||||
|
df1->flag |= ME_FACE_SEL;
|
||||||
|
|
||||||
|
facepa[cur+1] = vertpa[v2];
|
||||||
|
df2->v1 = GET_ES(v1, v2)
|
||||||
|
df2->v2 = v2;
|
||||||
|
df2->v3 = GET_ES(v2, v3)
|
||||||
|
df2->v4 = 0;
|
||||||
|
df2->flag &= ~ME_FACE_SEL;
|
||||||
|
|
||||||
|
facepa[cur+2] = vertpa[v1];
|
||||||
|
df3->v1 = v1;
|
||||||
|
df3->v2 = v3;
|
||||||
|
df3->v3 = v4;
|
||||||
|
df3->v4 = 0;
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
MTFace *mf, *df1, *df2, *df3;
|
||||||
|
int l;
|
||||||
|
|
||||||
|
for(l=0; l<numlayer; l++) {
|
||||||
|
mf = CustomData_get_layer_n(&split->faceData, CD_MTFACE, l);
|
||||||
|
df1 = mf+cur;
|
||||||
|
df2 = df1 + 1;
|
||||||
|
df3 = df1 + 2;
|
||||||
|
mf = CustomData_get_layer_n(&dm->faceData, CD_MTFACE, l);
|
||||||
|
mf += i;
|
||||||
|
|
||||||
|
copy_v2_v2(df1->uv[0], mf->uv[c0]);
|
||||||
|
INT_UV(df1->uv[1], c0, c1)
|
||||||
|
INT_UV(df1->uv[2], c1, c2)
|
||||||
|
copy_v2_v2(df1->uv[3], mf->uv[c2]);
|
||||||
|
|
||||||
|
INT_UV(df2->uv[0], c0, c1)
|
||||||
|
copy_v2_v2(df2->uv[1], mf->uv[c1]);
|
||||||
|
INT_UV(df2->uv[2], c1, c2)
|
||||||
|
|
||||||
|
copy_v2_v2(df3->uv[0], mf->uv[c0]);
|
||||||
|
copy_v2_v2(df3->uv[1], mf->uv[c2]);
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
MFace *df1 = get_dface(dm, split, cur, i, mf);
|
||||||
|
MFace *df2 = get_dface(dm, split, cur+1, i, mf);
|
||||||
|
|
||||||
|
facepa[cur] = vertpa[v1];
|
||||||
|
df1->v1 = v1;
|
||||||
|
df1->v2 = v2;
|
||||||
|
df1->v3 = GET_ES(v2, v3)
|
||||||
|
df1->v4 = GET_ES(v1, v4)
|
||||||
|
df1->flag |= ME_FACE_SEL;
|
||||||
|
|
||||||
|
facepa[cur+1] = vertpa[v3];
|
||||||
|
df2->v1 = GET_ES(v1, v4)
|
||||||
|
df2->v2 = GET_ES(v2, v3)
|
||||||
|
df2->v3 = v3;
|
||||||
|
df2->v4 = v4;
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
MTFace *mf, *df1, *df2;
|
||||||
|
int l;
|
||||||
|
|
||||||
|
for(l=0; l<numlayer; l++) {
|
||||||
|
mf = CustomData_get_layer_n(&split->faceData, CD_MTFACE, l);
|
||||||
|
df1 = mf+cur;
|
||||||
|
df2 = df1 + 1;
|
||||||
|
mf = CustomData_get_layer_n(&dm->faceData, CD_MTFACE, l);
|
||||||
|
mf += i;
|
||||||
|
|
||||||
|
copy_v2_v2(df1->uv[0], mf->uv[c0]);
|
||||||
|
copy_v2_v2(df1->uv[1], mf->uv[c1]);
|
||||||
|
INT_UV(df1->uv[2], c1, c2)
|
||||||
|
INT_UV(df1->uv[3], c0, c3)
|
||||||
|
|
||||||
|
INT_UV(df2->uv[0], c0, c3)
|
||||||
|
INT_UV(df2->uv[1], c1, c2)
|
||||||
|
copy_v2_v2(df2->uv[2], mf->uv[c2]);
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
MFace *df1 = get_dface(dm, split, cur, i, mf);
|
||||||
|
MFace *df2 = get_dface(dm, split, cur+1, i, mf);
|
||||||
|
MFace *df3 = get_dface(dm, split, cur+2, i, mf);
|
||||||
|
MFace *df4 = get_dface(dm, split, cur+3, i, mf);
|
||||||
|
|
||||||
|
facepa[cur] = vertpa[v1];
|
||||||
|
df1->v1 = v1;
|
||||||
|
df1->v2 = GET_ES(v1, v2)
|
||||||
|
df1->v3 = GET_ES(v1, v3)
|
||||||
|
df1->v4 = GET_ES(v1, v4)
|
||||||
|
df1->flag |= ME_FACE_SEL;
|
||||||
|
|
||||||
|
facepa[cur+1] = vertpa[v2];
|
||||||
|
df2->v1 = GET_ES(v1, v2)
|
||||||
|
df2->v2 = v2;
|
||||||
|
df2->v3 = GET_ES(v2, v3)
|
||||||
|
df2->v4 = GET_ES(v1, v3)
|
||||||
|
df2->flag |= ME_FACE_SEL;
|
||||||
|
|
||||||
|
facepa[cur+2] = vertpa[v3];
|
||||||
|
df3->v1 = GET_ES(v1, v3)
|
||||||
|
df3->v2 = GET_ES(v2, v3)
|
||||||
|
df3->v3 = v3;
|
||||||
|
df3->v4 = GET_ES(v3, v4)
|
||||||
|
df3->flag |= ME_FACE_SEL;
|
||||||
|
|
||||||
|
facepa[cur+3] = vertpa[v4];
|
||||||
|
df4->v1 = GET_ES(v1, v4)
|
||||||
|
df4->v2 = GET_ES(v1, v3)
|
||||||
|
df4->v3 = GET_ES(v3, v4)
|
||||||
|
df4->v4 = v4;
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
MTFace *mf, *df1, *df2, *df3, *df4;
|
||||||
|
int l;
|
||||||
|
|
||||||
|
for(l=0; l<numlayer; l++) {
|
||||||
|
mf = CustomData_get_layer_n(&split->faceData, CD_MTFACE, l);
|
||||||
|
df1 = mf+cur;
|
||||||
|
df2 = df1 + 1;
|
||||||
|
df3 = df1 + 2;
|
||||||
|
df4 = df1 + 3;
|
||||||
|
mf = CustomData_get_layer_n(&dm->faceData, CD_MTFACE, l);
|
||||||
|
mf += i;
|
||||||
|
|
||||||
|
copy_v2_v2(df1->uv[0], mf->uv[c0]);
|
||||||
|
INT_UV(df1->uv[1], c0, c1)
|
||||||
|
INT_UV(df1->uv[2], c0, c2)
|
||||||
|
INT_UV(df1->uv[3], c0, c3)
|
||||||
|
|
||||||
|
INT_UV(df2->uv[0], c0, c1)
|
||||||
|
copy_v2_v2(df2->uv[1], mf->uv[c1]);
|
||||||
|
INT_UV(df2->uv[2], c1, c2)
|
||||||
|
INT_UV(df2->uv[3], c0, c2)
|
||||||
|
|
||||||
|
INT_UV(df3->uv[0], c0, c2)
|
||||||
|
INT_UV(df3->uv[1], c1, c2)
|
||||||
|
copy_v2_v2(df3->uv[2], mf->uv[c2]);
|
||||||
|
INT_UV(df3->uv[3], c2, c3)
|
||||||
|
|
||||||
|
INT_UV(df4->uv[0], c0, c3)
|
||||||
|
INT_UV(df4->uv[1], c0, c2)
|
||||||
|
INT_UV(df4->uv[2], c2, 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)
|
||||||
|
{
|
||||||
|
MFace *df1 = get_dface(dm, split, cur, i, mf);
|
||||||
|
MFace *df2 = get_dface(dm, split, cur+1, i, mf);
|
||||||
|
MFace *df3 = get_dface(dm, split, cur+2, i, mf);
|
||||||
|
|
||||||
|
facepa[cur] = vertpa[v1];
|
||||||
|
df1->v1 = v1;
|
||||||
|
df1->v2 = GET_ES(v1, v2)
|
||||||
|
df1->v3 = GET_ES(v2, v3)
|
||||||
|
df1->v4 = GET_ES(v1, v4)
|
||||||
|
df1->flag |= ME_FACE_SEL;
|
||||||
|
|
||||||
|
facepa[cur+1] = vertpa[v2];
|
||||||
|
df2->v1 = GET_ES(v1, v2)
|
||||||
|
df2->v2 = v2;
|
||||||
|
df2->v3 = GET_ES(v2, v3)
|
||||||
|
df2->v4 = 0;
|
||||||
|
df2->flag &= ~ME_FACE_SEL;
|
||||||
|
|
||||||
|
facepa[cur+2] = vertpa[v4];
|
||||||
|
df3->v1 = GET_ES(v1, v4)
|
||||||
|
df3->v2 = GET_ES(v2, v3)
|
||||||
|
df3->v3 = v3;
|
||||||
|
df3->v4 = v4;
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
MTFace *mf, *df1, *df2, *df3;
|
||||||
|
int l;
|
||||||
|
|
||||||
|
for(l=0; l<numlayer; l++) {
|
||||||
|
mf = CustomData_get_layer_n(&split->faceData, CD_MTFACE, l);
|
||||||
|
df1 = mf+cur;
|
||||||
|
df2 = df1 + 1;
|
||||||
|
df3 = df1 + 2;
|
||||||
|
mf = CustomData_get_layer_n(&dm->faceData, CD_MTFACE, l);
|
||||||
|
mf += i;
|
||||||
|
|
||||||
|
copy_v2_v2(df1->uv[0], mf->uv[c0]);
|
||||||
|
INT_UV(df1->uv[1], c0, c1)
|
||||||
|
INT_UV(df1->uv[2], c1, c2)
|
||||||
|
INT_UV(df1->uv[3], c0, c3)
|
||||||
|
|
||||||
|
INT_UV(df2->uv[0], c0, c1)
|
||||||
|
copy_v2_v2(df2->uv[1], mf->uv[c1]);
|
||||||
|
INT_UV(df2->uv[2], c1, c2)
|
||||||
|
|
||||||
|
INT_UV(df3->uv[0], c0, c3)
|
||||||
|
INT_UV(df3->uv[1], c1, c2)
|
||||||
|
copy_v2_v2(df3->uv[2], mf->uv[c2]);
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
MFace *df1 = get_dface(dm, split, cur, i, mf);
|
||||||
|
MFace *df2 = get_dface(dm, split, cur+1, i, mf);
|
||||||
|
|
||||||
|
facepa[cur] = vertpa[v1];
|
||||||
|
df1->v1 = v1;
|
||||||
|
df1->v2 = GET_ES(v1, v2)
|
||||||
|
df1->v3 = GET_ES(v1, v3)
|
||||||
|
df1->v4 = 0;
|
||||||
|
df1->flag &= ~ME_FACE_SEL;
|
||||||
|
|
||||||
|
facepa[cur+1] = vertpa[v2];
|
||||||
|
df2->v1 = GET_ES(v1, v2)
|
||||||
|
df2->v2 = v2;
|
||||||
|
df2->v3 = v3;
|
||||||
|
df2->v4 = GET_ES(v1, v3)
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
MTFace *mf, *df1, *df2;
|
||||||
|
int l;
|
||||||
|
|
||||||
|
for(l=0; l<numlayer; l++) {
|
||||||
|
mf = CustomData_get_layer_n(&split->faceData, CD_MTFACE, l);
|
||||||
|
df1 = mf+cur;
|
||||||
|
df2 = df1 + 1;
|
||||||
|
mf = CustomData_get_layer_n(&dm->faceData, CD_MTFACE, l);
|
||||||
|
mf += i;
|
||||||
|
|
||||||
|
copy_v2_v2(df1->uv[0], mf->uv[c0]);
|
||||||
|
INT_UV(df1->uv[1], c0, c1)
|
||||||
|
INT_UV(df1->uv[2], c0, c2)
|
||||||
|
|
||||||
|
INT_UV(df2->uv[0], c0, c1)
|
||||||
|
copy_v2_v2(df2->uv[1], mf->uv[c1]);
|
||||||
|
copy_v2_v2(df2->uv[2], mf->uv[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)
|
||||||
|
{
|
||||||
|
MFace *df1 = get_dface(dm, split, cur, i, mf);
|
||||||
|
MFace *df2 = get_dface(dm, split, cur+1, i, mf);
|
||||||
|
MFace *df3 = get_dface(dm, split, cur+2, i, mf);
|
||||||
|
|
||||||
|
facepa[cur] = vertpa[v1];
|
||||||
|
df1->v1 = v1;
|
||||||
|
df1->v2 = GET_ES(v1, v2)
|
||||||
|
df1->v3 = GET_ES(v2, v3)
|
||||||
|
df1->v4 = GET_ES(v1, v3)
|
||||||
|
df1->flag |= ME_FACE_SEL;
|
||||||
|
|
||||||
|
facepa[cur+1] = vertpa[v2];
|
||||||
|
df2->v1 = GET_ES(v1, v2)
|
||||||
|
df2->v2 = v2;
|
||||||
|
df2->v3 = GET_ES(v2, v3)
|
||||||
|
df2->v4 = 0;
|
||||||
|
df2->flag &= ~ME_FACE_SEL;
|
||||||
|
|
||||||
|
facepa[cur+2] = vertpa[v3];
|
||||||
|
df3->v1 = GET_ES(v1, v3)
|
||||||
|
df3->v2 = GET_ES(v2, v3)
|
||||||
|
df3->v3 = v3;
|
||||||
|
df3->v4 = 0;
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
MTFace *mf, *df1, *df2, *df3;
|
||||||
|
int l;
|
||||||
|
|
||||||
|
for(l=0; l<numlayer; l++) {
|
||||||
|
mf = CustomData_get_layer_n(&split->faceData, CD_MTFACE, l);
|
||||||
|
df1 = mf+cur;
|
||||||
|
df2 = df1 + 1;
|
||||||
|
df3 = df1 + 2;
|
||||||
|
mf = CustomData_get_layer_n(&dm->faceData, CD_MTFACE, l);
|
||||||
|
mf += i;
|
||||||
|
|
||||||
|
copy_v2_v2(df1->uv[0], mf->uv[c0]);
|
||||||
|
INT_UV(df1->uv[1], c0, c1)
|
||||||
|
INT_UV(df1->uv[2], c1, c2)
|
||||||
|
INT_UV(df1->uv[3], c0, c2)
|
||||||
|
|
||||||
|
INT_UV(df2->uv[0], c0, c1)
|
||||||
|
copy_v2_v2(df2->uv[1], mf->uv[c1]);
|
||||||
|
INT_UV(df2->uv[2], c1, c2)
|
||||||
|
|
||||||
|
INT_UV(df2->uv[0], c0, c2)
|
||||||
|
INT_UV(df2->uv[1], c1, c2)
|
||||||
|
copy_v2_v2(df2->uv[2], mf->uv[c2]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static DerivedMesh * cutEdges(ExplodeModifierData *emd, DerivedMesh *dm){
|
||||||
DerivedMesh *splitdm;
|
DerivedMesh *splitdm;
|
||||||
MFace *mf=0,*df1=0,*df2=0,*df3=0;
|
MFace *mf=NULL,*df1=NULL,*df2=NULL,*df3=NULL,*df4=NULL;
|
||||||
MFace *mface=dm->getFaceArray(dm);
|
MFace *mface=dm->getFaceArray(dm);
|
||||||
|
MTFace *mtf = NULL, *dtf1=NULL, *dtf2=NULL, *dtf3=NULL, *dtf4=NULL;
|
||||||
MVert *dupve, *mv;
|
MVert *dupve, *mv;
|
||||||
EdgeHash *edgehash;
|
EdgeHash *edgehash;
|
||||||
EdgeHashIterator *ehi;
|
EdgeHashIterator *ehi;
|
||||||
@ -199,7 +554,8 @@ static DerivedMesh * splitEdges(ExplodeModifierData *emd, DerivedMesh *dm){
|
|||||||
int *vertpa = MEM_callocN(sizeof(int)*totvert,"explode_vertpa2");
|
int *vertpa = MEM_callocN(sizeof(int)*totvert,"explode_vertpa2");
|
||||||
int *facepa = emd->facepa;
|
int *facepa = emd->facepa;
|
||||||
int *fs, totesplit=0,totfsplit=0,totin=0,curdupface=0,curdupin=0;
|
int *fs, totesplit=0,totfsplit=0,totin=0,curdupface=0,curdupin=0;
|
||||||
int i,j,v1,v2,v3,v4,esplit;
|
int i,j,v1,v2,v3,v4,esplit, v[4], uv[4];
|
||||||
|
int numlayer;
|
||||||
|
|
||||||
edgehash= BLI_edgehash_new();
|
edgehash= BLI_edgehash_new();
|
||||||
|
|
||||||
@ -214,52 +570,48 @@ static DerivedMesh * splitEdges(ExplodeModifierData *emd, DerivedMesh *dm){
|
|||||||
|
|
||||||
/* 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++) {
|
||||||
if(mf->v4){
|
|
||||||
v1=vertpa[mf->v1];
|
v1=vertpa[mf->v1];
|
||||||
v2=vertpa[mf->v2];
|
v2=vertpa[mf->v2];
|
||||||
v3=vertpa[mf->v3];
|
v3=vertpa[mf->v3];
|
||||||
v4=vertpa[mf->v4];
|
|
||||||
|
|
||||||
if(v1!=v2){
|
if(v1!=v2){
|
||||||
BLI_edgehash_insert(edgehash, mf->v1, mf->v2, NULL);
|
BLI_edgehash_insert(edgehash, mf->v1, mf->v2, NULL);
|
||||||
(*fs)++;
|
(*fs) |= 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(v2!=v3){
|
if(v2!=v3){
|
||||||
BLI_edgehash_insert(edgehash, mf->v2, mf->v3, NULL);
|
BLI_edgehash_insert(edgehash, mf->v2, mf->v3, NULL);
|
||||||
(*fs)++;
|
(*fs) |= 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(mf->v4){
|
||||||
|
v4=vertpa[mf->v4];
|
||||||
|
|
||||||
if(v3!=v4){
|
if(v3!=v4){
|
||||||
BLI_edgehash_insert(edgehash, mf->v3, mf->v4, NULL);
|
BLI_edgehash_insert(edgehash, mf->v3, mf->v4, NULL);
|
||||||
(*fs)++;
|
(*fs) |= 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(v1!=v4){
|
if(v1!=v4){
|
||||||
BLI_edgehash_insert(edgehash, mf->v1, mf->v4, NULL);
|
BLI_edgehash_insert(edgehash, mf->v1, mf->v4, NULL);
|
||||||
(*fs)++;
|
(*fs) |= 8;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(*fs==2){
|
/* mark center vertex as a fake edge split */
|
||||||
if((v1==v2 && v3==v4) || (v1==v4 && v2==v3))
|
if(*fs == 15)
|
||||||
*fs=1;
|
BLI_edgehash_insert(edgehash, mf->v1, mf->v3, NULL);
|
||||||
else if(v1!=v2){
|
|
||||||
if(v1!=v4)
|
|
||||||
BLI_edgehash_insert(edgehash, mf->v2, mf->v3, NULL);
|
|
||||||
else
|
|
||||||
BLI_edgehash_insert(edgehash, mf->v3, mf->v4, NULL);
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
if(v1!=v4)
|
|
||||||
BLI_edgehash_insert(edgehash, mf->v1, mf->v2, NULL);
|
|
||||||
else
|
|
||||||
BLI_edgehash_insert(edgehash, mf->v1, mf->v4, NULL);
|
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
(*fs) |= 16; /* mark face as tri */
|
||||||
|
|
||||||
|
if(v1!=v3){
|
||||||
|
BLI_edgehash_insert(edgehash, mf->v1, mf->v3, NULL);
|
||||||
|
(*fs) |= 4;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* count splits & reindex */
|
/* 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)) {
|
||||||
@ -269,24 +621,11 @@ static DerivedMesh * splitEdges(ExplodeModifierData *emd, DerivedMesh *dm){
|
|||||||
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++)
|
||||||
if(*fs==1)
|
totfsplit += add_faces[*fs];
|
||||||
totfsplit+=1;
|
|
||||||
else if(*fs==2)
|
|
||||||
totfsplit+=2;
|
|
||||||
else if(*fs==3)
|
|
||||||
totfsplit+=3;
|
|
||||||
else if(*fs==4){
|
|
||||||
totfsplit+=3;
|
|
||||||
|
|
||||||
mf=dm->getFaceData(dm,i,CD_MFACE);//CDDM_get_face(dm,i);
|
splitdm= CDDM_from_template(dm, totesplit, 0, totface+totfsplit);
|
||||||
|
numlayer = CustomData_number_of_layers(&splitdm->faceData, CD_MTFACE);
|
||||||
if(vertpa[mf->v1]!=vertpa[mf->v2] && vertpa[mf->v2]!=vertpa[mf->v3])
|
|
||||||
totin++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
splitdm= CDDM_from_template(dm, totesplit+totin, dm->getNumEdges(dm),totface+totfsplit);
|
|
||||||
|
|
||||||
/* 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++){
|
||||||
@ -298,19 +637,10 @@ static DerivedMesh * splitEdges(ExplodeModifierData *emd, DerivedMesh *dm){
|
|||||||
DM_copy_vert_data(dm, splitdm, i, i, 1);
|
DM_copy_vert_data(dm, splitdm, i, i, 1);
|
||||||
*dest = source;
|
*dest = source;
|
||||||
}
|
}
|
||||||
for(i=0; i<totface; i++){
|
|
||||||
MFace source;
|
|
||||||
MFace *dest;
|
|
||||||
dm->getFace(dm, i, &source);
|
|
||||||
dest = CDDM_get_face(splitdm, i);
|
|
||||||
|
|
||||||
DM_copy_face_data(dm, splitdm, i, i, 1);
|
|
||||||
*dest = source;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* override original facepa (original pointer is saved in caller function) */
|
/* override original facepa (original pointer is saved in caller function) */
|
||||||
facepa= MEM_callocN(sizeof(int)*(totface+totfsplit),"explode_facepa");
|
facepa= MEM_callocN(sizeof(int)*(totface+totfsplit),"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 */
|
||||||
@ -333,320 +663,101 @@ static DerivedMesh * splitEdges(ExplodeModifierData *emd, DerivedMesh *dm){
|
|||||||
BLI_edgehashIterator_free(ehi);
|
BLI_edgehashIterator_free(ehi);
|
||||||
|
|
||||||
/* create new faces */
|
/* create new faces */
|
||||||
curdupface=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++){
|
||||||
if(*fs){
|
mf = dm->getFaceData(dm, i, CD_MFACE);
|
||||||
mf=CDDM_get_face(splitdm,i);
|
|
||||||
|
|
||||||
v1=vertpa[mf->v1];
|
switch(*fs) {
|
||||||
v2=vertpa[mf->v2];
|
case 3:
|
||||||
v3=vertpa[mf->v3];
|
case 10:
|
||||||
v4=vertpa[mf->v4];
|
case 11:
|
||||||
/* ouch! creating new faces & remapping them to new verts is no fun */
|
case 15:
|
||||||
if(*fs==1){
|
SET_VERTS(1, 2, 3, 4)
|
||||||
df1=CDDM_get_face(splitdm,curdupface);
|
break;
|
||||||
DM_copy_face_data(splitdm,splitdm,i,curdupface,1);
|
case 5:
|
||||||
*df1=*mf;
|
case 6:
|
||||||
curdupface++;
|
case 7:
|
||||||
|
SET_VERTS(2, 3, 4, 1)
|
||||||
if(v1==v2){
|
break;
|
||||||
df1->v1=edgesplit_get(edgehash, mf->v1, mf->v4);
|
case 9:
|
||||||
df1->v2=edgesplit_get(edgehash, mf->v2, mf->v3);
|
case 13:
|
||||||
mf->v3=df1->v2;
|
SET_VERTS(4, 1, 2, 3)
|
||||||
mf->v4=df1->v1;
|
break;
|
||||||
}
|
case 12:
|
||||||
else{
|
case 14:
|
||||||
df1->v1=edgesplit_get(edgehash, mf->v1, mf->v2);
|
SET_VERTS(3, 4, 1, 2)
|
||||||
df1->v4=edgesplit_get(edgehash, mf->v3, mf->v4);
|
break;
|
||||||
mf->v2=df1->v1;
|
case 21:
|
||||||
mf->v3=df1->v4;
|
case 23:
|
||||||
|
SET_VERTS(1, 2, 3, 4)
|
||||||
|
break;
|
||||||
|
case 19:
|
||||||
|
SET_VERTS(2, 3, 1, 4)
|
||||||
|
break;
|
||||||
|
case 22:
|
||||||
|
SET_VERTS(3, 1, 2, 4)
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
facepa[i]=v1;
|
switch(*fs) {
|
||||||
facepa[curdupface-1]=v3;
|
case 3:
|
||||||
|
case 6:
|
||||||
|
case 9:
|
||||||
|
case 12:
|
||||||
|
remap_faces_3_6_9_12(dm, splitdm, mf, facepa, vertpa, i, edgehash, curdupface, v[0], v[1], v[2], v[3]);
|
||||||
|
if(numlayer)
|
||||||
|
remap_uvs_3_6_9_12(dm, splitdm, numlayer, i, curdupface, uv[0], uv[1], uv[2], uv[3]);
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
case 10:
|
||||||
|
remap_faces_5_10(dm, splitdm, mf, facepa, vertpa, i, edgehash, curdupface, v[0], v[1], v[2], v[3]);
|
||||||
|
if(numlayer)
|
||||||
|
remap_uvs_5_10(dm, splitdm, numlayer, i, curdupface, uv[0], uv[1], uv[2], uv[3]);
|
||||||
|
break;
|
||||||
|
case 15:
|
||||||
|
remap_faces_15(dm, splitdm, mf, facepa, vertpa, i, edgehash, curdupface, v[0], v[1], v[2], v[3]);
|
||||||
|
if(numlayer)
|
||||||
|
remap_uvs_15(dm, splitdm, numlayer, i, curdupface, uv[0], uv[1], uv[2], uv[3]);
|
||||||
|
break;
|
||||||
|
case 7:
|
||||||
|
case 11:
|
||||||
|
case 13:
|
||||||
|
case 14:
|
||||||
|
remap_faces_7_11_13_14(dm, splitdm, mf, facepa, vertpa, i, edgehash, curdupface, v[0], v[1], v[2], v[3]);
|
||||||
|
if(numlayer)
|
||||||
|
remap_uvs_7_11_13_14(dm, splitdm, numlayer, i, curdupface, uv[0], uv[1], uv[2], uv[3]);
|
||||||
|
break;
|
||||||
|
case 19:
|
||||||
|
case 21:
|
||||||
|
case 22:
|
||||||
|
remap_faces_19_21_22(dm, splitdm, mf, facepa, vertpa, i, edgehash, curdupface, v[0], v[1], v[2]);
|
||||||
|
if(numlayer)
|
||||||
|
remap_uvs_19_21_22(dm, splitdm, numlayer, i, curdupface, uv[0], uv[1], uv[2]);
|
||||||
|
break;
|
||||||
|
case 23:
|
||||||
|
remap_faces_23(dm, splitdm, mf, facepa, vertpa, i, edgehash, curdupface, v[0], v[1], v[2]);
|
||||||
|
if(numlayer)
|
||||||
|
remap_uvs_23(dm, splitdm, numlayer, i, curdupface, uv[0], uv[1], uv[2]);
|
||||||
|
break;
|
||||||
|
case 0:
|
||||||
|
case 16:
|
||||||
|
df1 = get_dface(dm, splitdm, curdupface, i, mf);
|
||||||
|
facepa[curdupface] = vertpa[mf->v1];
|
||||||
|
|
||||||
test_index_face(df1, &splitdm->faceData, curdupface, (df1->v4 ? 4 : 3));
|
if(df1->v4)
|
||||||
}
|
df1->flag |= ME_FACE_SEL;
|
||||||
if(*fs==2){
|
else
|
||||||
df1=CDDM_get_face(splitdm,curdupface);
|
df1->flag &= ~ME_FACE_SEL;
|
||||||
DM_copy_face_data(splitdm,splitdm,i,curdupface,1);
|
break;
|
||||||
*df1=*mf;
|
|
||||||
curdupface++;
|
|
||||||
|
|
||||||
df2=CDDM_get_face(splitdm,curdupface);
|
|
||||||
DM_copy_face_data(splitdm,splitdm,i,curdupface,1);
|
|
||||||
*df2=*mf;
|
|
||||||
curdupface++;
|
|
||||||
|
|
||||||
if(v1!=v2){
|
|
||||||
if(v1!=v4){
|
|
||||||
df1->v1=edgesplit_get(edgehash, mf->v1, mf->v4);
|
|
||||||
df1->v2=edgesplit_get(edgehash, mf->v1, mf->v2);
|
|
||||||
df2->v1=df1->v3=mf->v2;
|
|
||||||
df2->v3=df1->v4=mf->v4;
|
|
||||||
df2->v2=mf->v3;
|
|
||||||
|
|
||||||
mf->v2=df1->v2;
|
|
||||||
mf->v3=df1->v1;
|
|
||||||
|
|
||||||
df2->v4=mf->v4=0;
|
|
||||||
|
|
||||||
facepa[i]=v1;
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
df1->v2=edgesplit_get(edgehash, mf->v1, mf->v2);
|
|
||||||
df1->v3=edgesplit_get(edgehash, mf->v2, mf->v3);
|
|
||||||
df1->v4=mf->v3;
|
|
||||||
df2->v2=mf->v3;
|
|
||||||
df2->v3=mf->v4;
|
|
||||||
|
|
||||||
mf->v1=df1->v2;
|
|
||||||
mf->v3=df1->v3;
|
|
||||||
|
|
||||||
df2->v4=mf->v4=0;
|
|
||||||
|
|
||||||
facepa[i]=v2;
|
|
||||||
}
|
|
||||||
facepa[curdupface-1]=facepa[curdupface-2]=v3;
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
if(v1!=v4){
|
|
||||||
df1->v3=edgesplit_get(edgehash, mf->v3, mf->v4);
|
|
||||||
df1->v4=edgesplit_get(edgehash, mf->v1, mf->v4);
|
|
||||||
df1->v2=mf->v3;
|
|
||||||
|
|
||||||
mf->v1=df1->v4;
|
|
||||||
mf->v2=df1->v3;
|
|
||||||
mf->v3=mf->v4;
|
|
||||||
|
|
||||||
df2->v4=mf->v4=0;
|
|
||||||
|
|
||||||
facepa[i]=v4;
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
df1->v3=edgesplit_get(edgehash, mf->v2, mf->v3);
|
|
||||||
df1->v4=edgesplit_get(edgehash, mf->v3, mf->v4);
|
|
||||||
df1->v1=mf->v4;
|
|
||||||
df1->v2=mf->v2;
|
|
||||||
df2->v3=mf->v4;
|
|
||||||
|
|
||||||
mf->v1=df1->v4;
|
|
||||||
mf->v2=df1->v3;
|
|
||||||
|
|
||||||
df2->v4=mf->v4=0;
|
|
||||||
|
|
||||||
facepa[i]=v3;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
facepa[curdupface-1]=facepa[curdupface-2]=v1;
|
curdupface += add_faces[*fs]+1;
|
||||||
}
|
}
|
||||||
|
|
||||||
test_index_face(df1, &splitdm->faceData, curdupface-2, (df1->v4 ? 4 : 3));
|
for(i=0; i<curdupface; i++) {
|
||||||
test_index_face(df1, &splitdm->faceData, curdupface-1, (df1->v4 ? 4 : 3));
|
mf = CDDM_get_face(splitdm, i);
|
||||||
}
|
test_index_face(mf, &splitdm->faceData, i, (mf->flag & ME_FACE_SEL ? 4 : 3));
|
||||||
else if(*fs==3){
|
|
||||||
df1=CDDM_get_face(splitdm,curdupface);
|
|
||||||
DM_copy_face_data(splitdm,splitdm,i,curdupface,1);
|
|
||||||
*df1=*mf;
|
|
||||||
curdupface++;
|
|
||||||
|
|
||||||
df2=CDDM_get_face(splitdm,curdupface);
|
|
||||||
DM_copy_face_data(splitdm,splitdm,i,curdupface,1);
|
|
||||||
*df2=*mf;
|
|
||||||
curdupface++;
|
|
||||||
|
|
||||||
df3=CDDM_get_face(splitdm,curdupface);
|
|
||||||
DM_copy_face_data(splitdm,splitdm,i,curdupface,1);
|
|
||||||
*df3=*mf;
|
|
||||||
curdupface++;
|
|
||||||
|
|
||||||
if(v1==v2){
|
|
||||||
df2->v1=df1->v1=edgesplit_get(edgehash, mf->v1, mf->v4);
|
|
||||||
df3->v1=df1->v2=edgesplit_get(edgehash, mf->v2, mf->v3);
|
|
||||||
df3->v3=df2->v2=df1->v3=edgesplit_get(edgehash, mf->v3, mf->v4);
|
|
||||||
df3->v2=mf->v3;
|
|
||||||
df2->v3=mf->v4;
|
|
||||||
df1->v4=df2->v4=df3->v4=0;
|
|
||||||
|
|
||||||
mf->v3=df1->v2;
|
|
||||||
mf->v4=df1->v1;
|
|
||||||
|
|
||||||
facepa[i]=facepa[curdupface-3]=v1;
|
|
||||||
facepa[curdupface-1]=v3;
|
|
||||||
facepa[curdupface-2]=v4;
|
|
||||||
}
|
|
||||||
else if(v2==v3){
|
|
||||||
df3->v1=df2->v3=df1->v1=edgesplit_get(edgehash, mf->v1, mf->v4);
|
|
||||||
df2->v2=df1->v2=edgesplit_get(edgehash, mf->v1, mf->v2);
|
|
||||||
df3->v2=df1->v3=edgesplit_get(edgehash, mf->v3, mf->v4);
|
|
||||||
|
|
||||||
df3->v3=mf->v4;
|
|
||||||
df2->v1=mf->v1;
|
|
||||||
df1->v4=df2->v4=df3->v4=0;
|
|
||||||
|
|
||||||
mf->v1=df1->v2;
|
|
||||||
mf->v4=df1->v3;
|
|
||||||
|
|
||||||
facepa[i]=facepa[curdupface-3]=v2;
|
|
||||||
facepa[curdupface-1]=v4;
|
|
||||||
facepa[curdupface-2]=v1;
|
|
||||||
}
|
|
||||||
else if(v3==v4){
|
|
||||||
df3->v2=df2->v1=df1->v1=edgesplit_get(edgehash, mf->v1, mf->v2);
|
|
||||||
df2->v3=df1->v2=edgesplit_get(edgehash, mf->v2, mf->v3);
|
|
||||||
df3->v3=df1->v3=edgesplit_get(edgehash, mf->v1, mf->v4);
|
|
||||||
|
|
||||||
df3->v1=mf->v1;
|
|
||||||
df2->v2=mf->v2;
|
|
||||||
df1->v4=df2->v4=df3->v4=0;
|
|
||||||
|
|
||||||
mf->v1=df1->v3;
|
|
||||||
mf->v2=df1->v2;
|
|
||||||
|
|
||||||
facepa[i]=facepa[curdupface-3]=v3;
|
|
||||||
facepa[curdupface-1]=v1;
|
|
||||||
facepa[curdupface-2]=v2;
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
df3->v1=df1->v1=edgesplit_get(edgehash, mf->v1, mf->v2);
|
|
||||||
df3->v3=df2->v1=df1->v2=edgesplit_get(edgehash, mf->v2, mf->v3);
|
|
||||||
df2->v3=df1->v3=edgesplit_get(edgehash, mf->v3, mf->v4);
|
|
||||||
|
|
||||||
df3->v2=mf->v2;
|
|
||||||
df2->v2=mf->v3;
|
|
||||||
df1->v4=df2->v4=df3->v4=0;
|
|
||||||
|
|
||||||
mf->v2=df1->v1;
|
|
||||||
mf->v3=df1->v3;
|
|
||||||
|
|
||||||
facepa[i]=facepa[curdupface-3]=v1;
|
|
||||||
facepa[curdupface-1]=v2;
|
|
||||||
facepa[curdupface-2]=v3;
|
|
||||||
}
|
|
||||||
|
|
||||||
test_index_face(df1, &splitdm->faceData, curdupface-3, (df1->v4 ? 4 : 3));
|
|
||||||
test_index_face(df1, &splitdm->faceData, curdupface-2, (df1->v4 ? 4 : 3));
|
|
||||||
test_index_face(df1, &splitdm->faceData, curdupface-1, (df1->v4 ? 4 : 3));
|
|
||||||
}
|
|
||||||
else if(*fs==4){
|
|
||||||
if(v1!=v2 && v2!=v3){
|
|
||||||
|
|
||||||
/* set new vert to face center */
|
|
||||||
mv=CDDM_get_vert(splitdm,mf->v1);
|
|
||||||
dupve=CDDM_get_vert(splitdm,curdupin);
|
|
||||||
DM_copy_vert_data(splitdm,splitdm,mf->v1,curdupin,1);
|
|
||||||
*dupve=*mv;
|
|
||||||
|
|
||||||
mv=CDDM_get_vert(splitdm,mf->v2);
|
|
||||||
VECADD(dupve->co,dupve->co,mv->co);
|
|
||||||
mv=CDDM_get_vert(splitdm,mf->v3);
|
|
||||||
VECADD(dupve->co,dupve->co,mv->co);
|
|
||||||
mv=CDDM_get_vert(splitdm,mf->v4);
|
|
||||||
VECADD(dupve->co,dupve->co,mv->co);
|
|
||||||
mul_v3_fl(dupve->co,0.25);
|
|
||||||
|
|
||||||
|
|
||||||
df1=CDDM_get_face(splitdm,curdupface);
|
|
||||||
DM_copy_face_data(splitdm,splitdm,i,curdupface,1);
|
|
||||||
*df1=*mf;
|
|
||||||
curdupface++;
|
|
||||||
|
|
||||||
df2=CDDM_get_face(splitdm,curdupface);
|
|
||||||
DM_copy_face_data(splitdm,splitdm,i,curdupface,1);
|
|
||||||
*df2=*mf;
|
|
||||||
curdupface++;
|
|
||||||
|
|
||||||
df3=CDDM_get_face(splitdm,curdupface);
|
|
||||||
DM_copy_face_data(splitdm,splitdm,i,curdupface,1);
|
|
||||||
*df3=*mf;
|
|
||||||
curdupface++;
|
|
||||||
|
|
||||||
df1->v1=edgesplit_get(edgehash, mf->v1, mf->v2);
|
|
||||||
df3->v2=df1->v3=edgesplit_get(edgehash, mf->v2, mf->v3);
|
|
||||||
|
|
||||||
df2->v1=edgesplit_get(edgehash, mf->v1, mf->v4);
|
|
||||||
df3->v4=df2->v3=edgesplit_get(edgehash, mf->v3, mf->v4);
|
|
||||||
|
|
||||||
df3->v1=df2->v2=df1->v4=curdupin;
|
|
||||||
|
|
||||||
mf->v2=df1->v1;
|
|
||||||
mf->v3=curdupin;
|
|
||||||
mf->v4=df2->v1;
|
|
||||||
|
|
||||||
curdupin++;
|
|
||||||
|
|
||||||
facepa[i]=v1;
|
|
||||||
facepa[curdupface-3]=v2;
|
|
||||||
facepa[curdupface-2]=v3;
|
|
||||||
facepa[curdupface-1]=v4;
|
|
||||||
|
|
||||||
test_index_face(df1, &splitdm->faceData, curdupface-3, (df1->v4 ? 4 : 3));
|
|
||||||
|
|
||||||
test_index_face(df1, &splitdm->faceData, curdupface-2, (df1->v4 ? 4 : 3));
|
|
||||||
test_index_face(df1, &splitdm->faceData, curdupface-1, (df1->v4 ? 4 : 3));
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
df1=CDDM_get_face(splitdm,curdupface);
|
|
||||||
DM_copy_face_data(splitdm,splitdm,i,curdupface,1);
|
|
||||||
*df1=*mf;
|
|
||||||
curdupface++;
|
|
||||||
|
|
||||||
df2=CDDM_get_face(splitdm,curdupface);
|
|
||||||
DM_copy_face_data(splitdm,splitdm,i,curdupface,1);
|
|
||||||
*df2=*mf;
|
|
||||||
curdupface++;
|
|
||||||
|
|
||||||
df3=CDDM_get_face(splitdm,curdupface);
|
|
||||||
DM_copy_face_data(splitdm,splitdm,i,curdupface,1);
|
|
||||||
*df3=*mf;
|
|
||||||
curdupface++;
|
|
||||||
|
|
||||||
if(v2==v3){
|
|
||||||
df1->v1=edgesplit_get(edgehash, mf->v1, mf->v2);
|
|
||||||
df3->v1=df1->v2=df1->v3=edgesplit_get(edgehash, mf->v2, mf->v3);
|
|
||||||
df2->v1=df1->v4=edgesplit_get(edgehash, mf->v1, mf->v4);
|
|
||||||
|
|
||||||
df3->v3=df2->v3=edgesplit_get(edgehash, mf->v3, mf->v4);
|
|
||||||
|
|
||||||
df3->v2=mf->v3;
|
|
||||||
df3->v4=0;
|
|
||||||
|
|
||||||
mf->v2=df1->v1;
|
|
||||||
mf->v3=df1->v4;
|
|
||||||
mf->v4=0;
|
|
||||||
|
|
||||||
facepa[i]=v1;
|
|
||||||
facepa[curdupface-3]=facepa[curdupface-2]=v2;
|
|
||||||
facepa[curdupface-1]=v3;
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
df3->v1=df2->v1=df1->v2=edgesplit_get(edgehash, mf->v1, mf->v2);
|
|
||||||
df2->v4=df1->v3=edgesplit_get(edgehash, mf->v3, mf->v4);
|
|
||||||
df1->v4=edgesplit_get(edgehash, mf->v1, mf->v4);
|
|
||||||
|
|
||||||
df3->v3=df2->v2=edgesplit_get(edgehash, mf->v2, mf->v3);
|
|
||||||
|
|
||||||
df3->v4=0;
|
|
||||||
|
|
||||||
mf->v1=df1->v4;
|
|
||||||
mf->v2=df1->v3;
|
|
||||||
mf->v3=mf->v4;
|
|
||||||
mf->v4=0;
|
|
||||||
|
|
||||||
facepa[i]=v4;
|
|
||||||
facepa[curdupface-3]=facepa[curdupface-2]=v1;
|
|
||||||
facepa[curdupface-1]=v2;
|
|
||||||
}
|
|
||||||
|
|
||||||
test_index_face(df1, &splitdm->faceData, curdupface-3, (df1->v4 ? 4 : 3));
|
|
||||||
test_index_face(df1, &splitdm->faceData, curdupface-2, (df1->v4 ? 4 : 3));
|
|
||||||
test_index_face(df1, &splitdm->faceData, curdupface-1, (df1->v4 ? 4 : 3));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
test_index_face(df1, &splitdm->faceData, i, (df1->v4 ? 4 : 3));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
BLI_edgehash_free(edgehash, NULL);
|
BLI_edgehash_free(edgehash, NULL);
|
||||||
@ -675,6 +786,7 @@ static DerivedMesh * explodeMesh(ExplodeModifierData *emd,
|
|||||||
int *facepa=emd->facepa;
|
int *facepa=emd->facepa;
|
||||||
int totdup=0,totvert=0,totface=0,totpart=0;
|
int totdup=0,totvert=0,totface=0,totpart=0;
|
||||||
int i, j, v, mindex=0;
|
int i, j, v, mindex=0;
|
||||||
|
MTFace *mtface = NULL, *mtf;
|
||||||
|
|
||||||
totface= dm->getNumFaces(dm);
|
totface= dm->getNumFaces(dm);
|
||||||
totvert= dm->getNumVerts(dm);
|
totvert= dm->getNumVerts(dm);
|
||||||
@ -724,6 +836,7 @@ static DerivedMesh * explodeMesh(ExplodeModifierData *emd,
|
|||||||
|
|
||||||
/* the final duplicated vertices */
|
/* the final duplicated vertices */
|
||||||
explode= CDDM_from_template(dm, totdup, 0,totface);
|
explode= CDDM_from_template(dm, totdup, 0,totface);
|
||||||
|
mtface = CustomData_get_layer_named(&explode->faceData, CD_MTFACE, emd->uvname);
|
||||||
/*dupvert= CDDM_get_verts(explode);*/
|
/*dupvert= CDDM_get_verts(explode);*/
|
||||||
|
|
||||||
/* getting back to object space */
|
/* getting back to object space */
|
||||||
@ -800,16 +913,28 @@ static DerivedMesh * explodeMesh(ExplodeModifierData *emd,
|
|||||||
else
|
else
|
||||||
mindex = totvert+facepa[i];
|
mindex = totvert+facepa[i];
|
||||||
|
|
||||||
source.v1 = edgesplit_get(vertpahash, source.v1, mindex);
|
source.v1 = edgecut_get(vertpahash, source.v1, mindex);
|
||||||
source.v2 = edgesplit_get(vertpahash, source.v2, mindex);
|
source.v2 = edgecut_get(vertpahash, source.v2, mindex);
|
||||||
source.v3 = edgesplit_get(vertpahash, source.v3, mindex);
|
source.v3 = edgecut_get(vertpahash, source.v3, mindex);
|
||||||
if(source.v4)
|
if(source.v4)
|
||||||
source.v4 = edgesplit_get(vertpahash, source.v4, mindex);
|
source.v4 = edgecut_get(vertpahash, source.v4, mindex);
|
||||||
|
|
||||||
DM_copy_face_data(dm,explode,i,i,1);
|
DM_copy_face_data(dm,explode,i,i,1);
|
||||||
|
|
||||||
*mf = source;
|
*mf = source;
|
||||||
|
|
||||||
|
/* override uv channel for particle age */
|
||||||
|
if(mtface) {
|
||||||
|
float age = (cfra - pa->time)/pa->lifetime;
|
||||||
|
/* Clamp to this range to avoid flipping to the other side of the coordinates. */
|
||||||
|
CLAMP(age, 0.001f, 0.999f);
|
||||||
|
|
||||||
|
mtf = mtface + i;
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
test_index_face(mf, &explode->faceData, i, (orig_v4 ? 4 : 3));
|
test_index_face(mf, &explode->faceData, i, (orig_v4 ? 4 : 3));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -870,9 +995,9 @@ static DerivedMesh * applyModifier(ModifierData *md, Object *ob,
|
|||||||
createFacepa(emd,psmd,derivedData);
|
createFacepa(emd,psmd,derivedData);
|
||||||
}
|
}
|
||||||
/* 2. create new mesh */
|
/* 2. create new mesh */
|
||||||
if(emd->flag & eExplodeFlag_EdgeSplit){
|
if(emd->flag & eExplodeFlag_EdgeCut){
|
||||||
int *facepa = emd->facepa;
|
int *facepa = emd->facepa;
|
||||||
DerivedMesh *splitdm=splitEdges(emd,dm);
|
DerivedMesh *splitdm=cutEdges(emd,dm);
|
||||||
DerivedMesh *explode=explodeMesh(emd, psmd, md->scene, ob, splitdm);
|
DerivedMesh *explode=explodeMesh(emd, psmd, md->scene, ob, splitdm);
|
||||||
|
|
||||||
MEM_freeN(emd->facepa);
|
MEM_freeN(emd->facepa);
|
||||||
|
Loading…
Reference in New Issue
Block a user