Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBastien Montagne <montagne29@wanadoo.fr>2016-01-04 14:19:45 +0300
committerBastien Montagne <montagne29@wanadoo.fr>2016-01-04 14:19:45 +0300
commitaad24468e2d32d46e2c3b3b4a37302a4f1f27ab6 (patch)
treebf3824be66c324d4cc30add16a677a17b9181db7 /source/blender/editors/mesh/meshtools.c
parente83b3e577e59770dcd43a0c9dbf9ff3dcfda4365 (diff)
Fix T47038: Particles in Particle Edit Mode get added in completely wrong location.
It also fixes another issue (crash) related to symmetric editing. Quite involved, we (try to!) fix complete broken logic of parts of particle code, which would use poly index as tessface one (or vice-versa). Issue most probably goes back to BMesh integration time... This patch mostly fixes particle editing mode: - Adding/removing particles when using generative modifiers (like subsurf) should now work. - Adding/removing particles with a non-tessellated mesh (i.e. one having ngons) should also mostly work. - X-axis-mirror-editing particles over ngons does not really work, not sure why currently. - All this in both 'modes' (with or without using modifier stack for particles). Tech side: - Store a deformed-only DM in particle modifier data. - Rename existing DM to make it clear it's a final one. - Use deformed-only DM's tessface2poly mapping to 'solve' poly/tessface mismatches. - Make (part of) mirror-editing code able to use a DM instead of raw mesh, so that we can mirror based on final DM when editing particles using modifier stack (mandatory, since there is no way currently to find orig tessface from an final DM tessface index). Note that this patch is not really nice and clean (current particles are beyond hope on this side anyway), it's more like some urgency bandage. Whole crap needs complete rewrite anyway, BMesh's polygons make it really hard to work with current system (and looptri would not help much here). Also, did not test everything possibly affected by those changes, so it needs some users' testing & validation too. Reviewers: psy-fi Subscribers: dfelinto, eyecandy Maniphest Tasks: T47038 Differential Revision: https://developer.blender.org/D1685
Diffstat (limited to 'source/blender/editors/mesh/meshtools.c')
-rw-r--r--source/blender/editors/mesh/meshtools.c92
1 files changed, 45 insertions, 47 deletions
diff --git a/source/blender/editors/mesh/meshtools.c b/source/blender/editors/mesh/meshtools.c
index dee003135a2..431af56e13d 100644
--- a/source/blender/editors/mesh/meshtools.c
+++ b/source/blender/editors/mesh/meshtools.c
@@ -672,18 +672,15 @@ static struct { void *tree; } MirrKdStore = {NULL};
/* mode is 's' start, or 'e' end, or 'u' use */
/* if end, ob can be NULL */
-int ED_mesh_mirror_spatial_table(Object *ob, BMEditMesh *em, const float co[3], char mode)
+int ED_mesh_mirror_spatial_table(Object *ob, BMEditMesh *em, DerivedMesh *dm, const float co[3], char mode)
{
if (mode == 'u') { /* use table */
if (MirrKdStore.tree == NULL)
- ED_mesh_mirror_spatial_table(ob, em, NULL, 's');
+ ED_mesh_mirror_spatial_table(ob, em, dm, NULL, 's');
if (MirrKdStore.tree) {
KDTreeNearest nearest;
-
- int i;
-
- i = BLI_kdtree_find_nearest(MirrKdStore.tree, co, &nearest);
+ const int i = BLI_kdtree_find_nearest(MirrKdStore.tree, co, &nearest);
if (i != -1) {
if (nearest.dist < KD_THRESH) {
@@ -695,22 +692,15 @@ int ED_mesh_mirror_spatial_table(Object *ob, BMEditMesh *em, const float co[3],
}
else if (mode == 's') { /* start table */
Mesh *me = ob->data;
- int totvert;
+ const bool use_em = (!dm && em && me->edit_btmesh == em);
+ const int totvert = use_em ? em->bm->totvert : dm ? dm->getNumVerts(dm) : me->totvert;
if (MirrKdStore.tree) /* happens when entering this call without ending it */
- ED_mesh_mirror_spatial_table(ob, em, co, 'e');
-
- if (em && me->edit_btmesh == em) {
- totvert = em->bm->totvert;
- }
- else {
- totvert = me->totvert;
- }
+ ED_mesh_mirror_spatial_table(ob, em, dm, co, 'e');
MirrKdStore.tree = BLI_kdtree_new(totvert);
- if (em && me->edit_btmesh == em) {
-
+ if (use_em) {
BMVert *eve;
BMIter iter;
int i;
@@ -723,10 +713,10 @@ int ED_mesh_mirror_spatial_table(Object *ob, BMEditMesh *em, const float co[3],
}
}
else {
- MVert *mvert;
+ MVert *mvert = dm ? dm->getVertArray(dm) : me->mvert;
int i;
- for (i = 0, mvert = me->mvert; i < me->totvert; i++, mvert++) {
+ for (i = 0; i < totvert; i++, mvert++) {
BLI_kdtree_insert(MirrKdStore.tree, i, mvert->co);
}
}
@@ -760,15 +750,15 @@ static MirrTopoStore_t mesh_topo_store = {NULL, -1. - 1, -1};
/* mode is 's' start, or 'e' end, or 'u' use */
/* if end, ob can be NULL */
/* note, is supposed return -1 on error, which callers are currently checking for, but is not used so far */
-int ED_mesh_mirror_topo_table(Object *ob, char mode)
+int ED_mesh_mirror_topo_table(Object *ob, DerivedMesh *dm, char mode)
{
if (mode == 'u') { /* use table */
- if (ED_mesh_mirrtopo_recalc_check(ob->data, ob->mode, &mesh_topo_store)) {
- ED_mesh_mirror_topo_table(ob, 's');
+ if (ED_mesh_mirrtopo_recalc_check(ob->data, dm, ob->mode, &mesh_topo_store)) {
+ ED_mesh_mirror_topo_table(ob, dm, 's');
}
}
else if (mode == 's') { /* start table */
- ED_mesh_mirrtopo_init(ob->data, ob->mode, &mesh_topo_store, false);
+ ED_mesh_mirrtopo_init(ob->data, dm, ob->mode, &mesh_topo_store, false);
}
else if (mode == 'e') { /* end table */
ED_mesh_mirrtopo_free(&mesh_topo_store);
@@ -783,35 +773,35 @@ int ED_mesh_mirror_topo_table(Object *ob, char mode)
/** \} */
-static int mesh_get_x_mirror_vert_spatial(Object *ob, int index)
+static int mesh_get_x_mirror_vert_spatial(Object *ob, DerivedMesh *dm, int index)
{
Mesh *me = ob->data;
- MVert *mvert;
+ MVert *mvert = dm ? dm->getVertArray(dm) : me->mvert;
float vec[3];
- mvert = me->mvert + index;
+ mvert = &mvert[index];
vec[0] = -mvert->co[0];
vec[1] = mvert->co[1];
vec[2] = mvert->co[2];
- return ED_mesh_mirror_spatial_table(ob, NULL, vec, 'u');
+ return ED_mesh_mirror_spatial_table(ob, NULL, dm, vec, 'u');
}
-static int mesh_get_x_mirror_vert_topo(Object *ob, int index)
+static int mesh_get_x_mirror_vert_topo(Object *ob, DerivedMesh *dm, int index)
{
- if (ED_mesh_mirror_topo_table(ob, 'u') == -1)
+ if (ED_mesh_mirror_topo_table(ob, dm, 'u') == -1)
return -1;
return mesh_topo_store.index_lookup[index];
}
-int mesh_get_x_mirror_vert(Object *ob, int index, const bool use_topology)
+int mesh_get_x_mirror_vert(Object *ob, DerivedMesh *dm, int index, const bool use_topology)
{
if (use_topology) {
- return mesh_get_x_mirror_vert_topo(ob, index);
+ return mesh_get_x_mirror_vert_topo(ob, dm, index);
}
else {
- return mesh_get_x_mirror_vert_spatial(ob, index);
+ return mesh_get_x_mirror_vert_spatial(ob, dm, index);
}
}
@@ -832,7 +822,7 @@ static BMVert *editbmesh_get_x_mirror_vert_spatial(Object *ob, BMEditMesh *em, c
vec[1] = co[1];
vec[2] = co[2];
- i = ED_mesh_mirror_spatial_table(ob, em, vec, 'u');
+ i = ED_mesh_mirror_spatial_table(ob, em, NULL, vec, 'u');
if (i != -1) {
return BM_vert_at_index(em->bm, i);
}
@@ -842,7 +832,7 @@ static BMVert *editbmesh_get_x_mirror_vert_spatial(Object *ob, BMEditMesh *em, c
static BMVert *editbmesh_get_x_mirror_vert_topo(Object *ob, struct BMEditMesh *em, BMVert *eve, int index)
{
intptr_t poinval;
- if (ED_mesh_mirror_topo_table(ob, 'u') == -1)
+ if (ED_mesh_mirror_topo_table(ob, NULL, 'u') == -1)
return NULL;
if (index == -1) {
@@ -897,7 +887,7 @@ int ED_mesh_mirror_get_vert(Object *ob, int index)
index_mirr = eve_mirr ? BM_elem_index_get(eve_mirr) : -1;
}
else {
- index_mirr = mesh_get_x_mirror_vert(ob, index, use_topology);
+ index_mirr = mesh_get_x_mirror_vert(ob, NULL, index, use_topology);
}
return index_mirr;
@@ -1007,31 +997,39 @@ static bool mirror_facecmp(const void *a, const void *b)
}
/* BMESH_TODO, convert to MPoly (functions above also) */
-int *mesh_get_x_mirror_faces(Object *ob, BMEditMesh *em)
+int *mesh_get_x_mirror_faces(Object *ob, BMEditMesh *em, DerivedMesh *dm)
{
Mesh *me = ob->data;
- MVert *mv, *mvert = me->mvert;
- MFace mirrormf, *mf, *hashmf, *mface = me->mface;
+ MVert *mv, *mvert;
+ MFace mirrormf, *mf, *hashmf, *mface;
GHash *fhash;
- const bool use_topology = (me->editflag & ME_EDIT_MIRROR_TOPO) != 0;
int *mirrorverts, *mirrorfaces;
+
+ BLI_assert(em == NULL); /* Does not work otherwise, currently... */
+
+ const bool use_topology = (me->editflag & ME_EDIT_MIRROR_TOPO) != 0;
+ const int totvert = dm ? dm->getNumVerts(dm) : me->totvert;
+ const int totface = dm ? dm->getNumTessFaces(dm) : me->totface;
int a;
- mirrorverts = MEM_callocN(sizeof(int) * me->totvert, "MirrorVerts");
- mirrorfaces = MEM_callocN(sizeof(int) * 2 * me->totface, "MirrorFaces");
+ mirrorverts = MEM_callocN(sizeof(int) * totvert, "MirrorVerts");
+ mirrorfaces = MEM_callocN(sizeof(int) * 2 * totface, "MirrorFaces");
+
+ mvert = dm ? dm->getVertArray(dm) : me->mvert;
+ mface = dm ? dm->getTessFaceArray(dm) : me->mface;
- ED_mesh_mirror_spatial_table(ob, em, NULL, 's');
+ ED_mesh_mirror_spatial_table(ob, em, dm, NULL, 's');
- for (a = 0, mv = mvert; a < me->totvert; a++, mv++)
- mirrorverts[a] = mesh_get_x_mirror_vert(ob, a, use_topology);
+ for (a = 0, mv = mvert; a < totvert; a++, mv++)
+ mirrorverts[a] = mesh_get_x_mirror_vert(ob, dm, a, use_topology);
- ED_mesh_mirror_spatial_table(ob, em, NULL, 'e');
+ ED_mesh_mirror_spatial_table(ob, em, dm, NULL, 'e');
fhash = BLI_ghash_new_ex(mirror_facehash, mirror_facecmp, "mirror_facehash gh", me->totface);
- for (a = 0, mf = mface; a < me->totface; a++, mf++)
+ for (a = 0, mf = mface; a < totface; a++, mf++)
BLI_ghash_insert(fhash, mf, mf);
- for (a = 0, mf = mface; a < me->totface; a++, mf++) {
+ for (a = 0, mf = mface; a < totface; a++, mf++) {
mirrormf.v1 = mirrorverts[mf->v3];
mirrormf.v2 = mirrorverts[mf->v2];
mirrormf.v3 = mirrorverts[mf->v1];