Fix #113752: Explode modifier edge cut option broken
`EdgeHash` was replaced by `VectorSet`, but the changes in the data structure hid some other changes, causing incorrect indices to be used. Instead use `Map` and explicitly build the indices similar to how they were counted in a separate loop before. Caused by: 425b87160716276ab2583f035b0c67c59dcd526e
This commit is contained in:
parent
753e9e0f2b
commit
74af0528f4
@ -11,11 +11,11 @@
|
||||
#include "BLI_utildefines.h"
|
||||
|
||||
#include "BLI_kdtree.h"
|
||||
#include "BLI_map.hh"
|
||||
#include "BLI_math_matrix.h"
|
||||
#include "BLI_math_rotation.h"
|
||||
#include "BLI_math_vector.h"
|
||||
#include "BLI_rand.h"
|
||||
#include "BLI_vector_set.hh"
|
||||
|
||||
#include "BLT_translation.h"
|
||||
|
||||
@ -208,9 +208,9 @@ static void createFacepa(ExplodeModifierData *emd, ParticleSystemModifierData *p
|
||||
BLI_rng_free(rng);
|
||||
}
|
||||
|
||||
static int edgecut_get(const blender::VectorSet<blender::OrderedEdge> &edgehash, uint v1, uint v2)
|
||||
static int edgecut_get(const blender::Map<blender::OrderedEdge, int> &edgehash, uint v1, uint v2)
|
||||
{
|
||||
return edgehash.index_of({int(v1), int(v2)});
|
||||
return edgehash.lookup({int(v1), int(v2)});
|
||||
}
|
||||
|
||||
static const short add_faces[24] = {
|
||||
@ -249,7 +249,7 @@ static void remap_faces_3_6_9_12(Mesh *mesh,
|
||||
int *facepa,
|
||||
const int *vertpa,
|
||||
int i,
|
||||
const blender::VectorSet<blender::OrderedEdge> &eh,
|
||||
const blender::Map<blender::OrderedEdge, int> &eh,
|
||||
int cur,
|
||||
int v1,
|
||||
int v2,
|
||||
@ -319,7 +319,7 @@ static void remap_faces_5_10(Mesh *mesh,
|
||||
int *facepa,
|
||||
const int *vertpa,
|
||||
int i,
|
||||
const blender::VectorSet<blender::OrderedEdge> &eh,
|
||||
const blender::Map<blender::OrderedEdge, int> &eh,
|
||||
int cur,
|
||||
int v1,
|
||||
int v2,
|
||||
@ -377,7 +377,7 @@ static void remap_faces_15(Mesh *mesh,
|
||||
int *facepa,
|
||||
const int *vertpa,
|
||||
int i,
|
||||
const blender::VectorSet<blender::OrderedEdge> &eh,
|
||||
const blender::Map<blender::OrderedEdge, int> &eh,
|
||||
int cur,
|
||||
int v1,
|
||||
int v2,
|
||||
@ -463,7 +463,7 @@ static void remap_faces_7_11_13_14(Mesh *mesh,
|
||||
int *facepa,
|
||||
const int *vertpa,
|
||||
int i,
|
||||
const blender::VectorSet<blender::OrderedEdge> &eh,
|
||||
const blender::Map<blender::OrderedEdge, int> &eh,
|
||||
int cur,
|
||||
int v1,
|
||||
int v2,
|
||||
@ -534,7 +534,7 @@ static void remap_faces_19_21_22(Mesh *mesh,
|
||||
int *facepa,
|
||||
const int *vertpa,
|
||||
int i,
|
||||
const blender::VectorSet<blender::OrderedEdge> &eh,
|
||||
const blender::Map<blender::OrderedEdge, int> &eh,
|
||||
int cur,
|
||||
int v1,
|
||||
int v2,
|
||||
@ -590,7 +590,7 @@ static void remap_faces_23(Mesh *mesh,
|
||||
int *facepa,
|
||||
const int *vertpa,
|
||||
int i,
|
||||
const blender::VectorSet<blender::OrderedEdge> &eh,
|
||||
const blender::Map<blender::OrderedEdge, int> &eh,
|
||||
int cur,
|
||||
int v1,
|
||||
int v2,
|
||||
@ -670,7 +670,8 @@ static Mesh *cutEdges(ExplodeModifierData *emd, Mesh *mesh)
|
||||
uv[4] = {0, 0, 0, 0}; /* To quite gcc barking... */
|
||||
int layers_num;
|
||||
|
||||
blender::VectorSet<blender::OrderedEdge> edgehash;
|
||||
int totesplit = totvert;
|
||||
blender::Map<blender::OrderedEdge, int> edgehash;
|
||||
|
||||
/* recreate vertpa from facepa calculation */
|
||||
for (i = 0, mf = mface; i < totface; i++, mf++) {
|
||||
@ -689,12 +690,12 @@ static Mesh *cutEdges(ExplodeModifierData *emd, Mesh *mesh)
|
||||
v3 = vertpa[mf->v3];
|
||||
|
||||
if (v1 != v2) {
|
||||
edgehash.add({mf->v1, mf->v2});
|
||||
edgehash.lookup_or_add_cb({mf->v1, mf->v2}, [&]() { return totesplit++; });
|
||||
(*fs) |= 1;
|
||||
}
|
||||
|
||||
if (v2 != v3) {
|
||||
edgehash.add({mf->v2, mf->v3});
|
||||
edgehash.lookup_or_add_cb({mf->v2, mf->v3}, [&]() { return totesplit++; });
|
||||
(*fs) |= 2;
|
||||
}
|
||||
|
||||
@ -702,25 +703,25 @@ static Mesh *cutEdges(ExplodeModifierData *emd, Mesh *mesh)
|
||||
v4 = vertpa[mf->v4];
|
||||
|
||||
if (v3 != v4) {
|
||||
edgehash.add({mf->v3, mf->v4});
|
||||
edgehash.lookup_or_add_cb({mf->v3, mf->v4}, [&]() { return totesplit++; });
|
||||
(*fs) |= 4;
|
||||
}
|
||||
|
||||
if (v1 != v4) {
|
||||
edgehash.add({mf->v1, mf->v4});
|
||||
edgehash.lookup_or_add_cb({mf->v1, mf->v4}, [&]() { return totesplit++; });
|
||||
(*fs) |= 8;
|
||||
}
|
||||
|
||||
/* mark center vertex as a fake edge split */
|
||||
if (*fs == 15) {
|
||||
edgehash.add({mf->v1, mf->v3});
|
||||
edgehash.lookup_or_add_cb({mf->v1, mf->v3}, [&]() { return totesplit++; });
|
||||
}
|
||||
}
|
||||
else {
|
||||
(*fs) |= 16; /* mark face as tri */
|
||||
|
||||
if (v1 != v3) {
|
||||
edgehash.add({mf->v1, mf->v3});
|
||||
edgehash.lookup_or_add_cb({mf->v1, mf->v3}, [&]() { return totesplit++; });
|
||||
(*fs) |= 4;
|
||||
}
|
||||
}
|
||||
@ -734,7 +735,7 @@ static Mesh *cutEdges(ExplodeModifierData *emd, Mesh *mesh)
|
||||
}
|
||||
|
||||
split_m = BKE_mesh_new_nomain_from_template_ex(
|
||||
mesh, totvert + edgehash.size(), 0, totface + totfsplit, 0, 0, CD_MASK_EVERYTHING);
|
||||
mesh, totesplit, 0, totface + totfsplit, 0, 0, CD_MASK_EVERYTHING);
|
||||
|
||||
layers_num = CustomData_number_of_layers(&split_m->fdata_legacy, CD_MTFACE);
|
||||
|
||||
@ -757,9 +758,9 @@ static Mesh *cutEdges(ExplodeModifierData *emd, Mesh *mesh)
|
||||
emd->facepa = facepa;
|
||||
|
||||
/* create new verts */
|
||||
for (const int esplit : edgehash.index_range()) {
|
||||
const int ed_v1 = edgehash[esplit].v_low;
|
||||
const int ed_v2 = edgehash[esplit].v_high;
|
||||
for (const auto [edge, esplit] : edgehash.items()) {
|
||||
const int ed_v1 = edge.v_low;
|
||||
const int ed_v2 = edge.v_high;
|
||||
|
||||
CustomData_free_elem(&split_m->vert_data, esplit, 1);
|
||||
CustomData_copy_data(&split_m->vert_data, &split_m->vert_data, ed_v2, esplit, 1);
|
||||
@ -912,7 +913,7 @@ static Mesh *explodeMesh(ExplodeModifierData *emd,
|
||||
float ctime;
|
||||
// float timestep;
|
||||
const int *facepa = emd->facepa;
|
||||
int totvert = 0, totface = 0, totpart = 0, delface = 0;
|
||||
int totdup = 0, totvert = 0, totface = 0, totpart = 0, delface = 0;
|
||||
int i, u;
|
||||
uint mindex = 0;
|
||||
|
||||
@ -933,7 +934,7 @@ static Mesh *explodeMesh(ExplodeModifierData *emd,
|
||||
ctime = BKE_scene_ctime_get(scene);
|
||||
|
||||
/* hash table for vertex <-> particle relations */
|
||||
blender::VectorSet<blender::OrderedEdge> vertpahash;
|
||||
blender::Map<blender::OrderedEdge, int> vertpahash;
|
||||
|
||||
for (i = 0; i < totface; i++) {
|
||||
if (facepa[i] != totpart) {
|
||||
@ -962,17 +963,17 @@ static Mesh *explodeMesh(ExplodeModifierData *emd,
|
||||
mf = &mface[i];
|
||||
|
||||
/* set face vertices to exist in particle group */
|
||||
vertpahash.add({mf->v1, mindex});
|
||||
vertpahash.add({mf->v2, mindex});
|
||||
vertpahash.add({mf->v3, mindex});
|
||||
vertpahash.lookup_or_add_cb({mf->v1, mindex}, [&]() { return totdup++; });
|
||||
vertpahash.lookup_or_add_cb({mf->v2, mindex}, [&]() { return totdup++; });
|
||||
vertpahash.lookup_or_add_cb({mf->v3, mindex}, [&]() { return totdup++; });
|
||||
if (mf->v4) {
|
||||
vertpahash.add({mf->v4, mindex});
|
||||
vertpahash.lookup_or_add_cb({mf->v4, mindex}, [&]() { return totdup++; });
|
||||
}
|
||||
}
|
||||
|
||||
/* the final duplicated vertices */
|
||||
explode = BKE_mesh_new_nomain_from_template_ex(
|
||||
mesh, vertpahash.size(), 0, totface - delface, 0, 0, CD_MASK_EVERYTHING);
|
||||
mesh, totdup, 0, totface - delface, 0, 0, CD_MASK_EVERYTHING);
|
||||
|
||||
MTFace *mtface = static_cast<MTFace *>(CustomData_get_layer_named_for_write(
|
||||
&explode->fdata_legacy, CD_MTFACE, emd->uvname, explode->totface_legacy));
|
||||
@ -985,10 +986,9 @@ static Mesh *explodeMesh(ExplodeModifierData *emd,
|
||||
const blender::Span<blender::float3> positions = mesh->vert_positions();
|
||||
blender::MutableSpan<blender::float3> explode_positions = explode->vert_positions_for_write();
|
||||
|
||||
for (const int v : vertpahash.index_range()) {
|
||||
/* get particle + vertex from hash */
|
||||
int ed_v1 = vertpahash[v].v_low;
|
||||
int ed_v2 = vertpahash[v].v_high;
|
||||
for (const auto [edge, v] : vertpahash.items()) {
|
||||
int ed_v1 = edge.v_low;
|
||||
int ed_v2 = edge.v_high;
|
||||
ed_v2 -= totvert;
|
||||
|
||||
copy_v3_v3(explode_positions[v], positions[ed_v1]);
|
||||
|
Loading…
Reference in New Issue
Block a user