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
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')
-rw-r--r--source/blender/editors/armature/armature_skinning.c4
-rw-r--r--source/blender/editors/armature/meshlaplacian.c2
-rw-r--r--source/blender/editors/include/ED_mesh.h13
-rw-r--r--source/blender/editors/mesh/editface.c28
-rw-r--r--source/blender/editors/mesh/editmesh_utils.c6
-rw-r--r--source/blender/editors/mesh/meshtools.c92
-rw-r--r--source/blender/editors/object/object_edit.c4
-rw-r--r--source/blender/editors/object/object_shapekey.c6
-rw-r--r--source/blender/editors/object/object_vgroup.c4
-rw-r--r--source/blender/editors/physics/particle_edit.c131
-rw-r--r--source/blender/editors/physics/particle_object.c21
-rw-r--r--source/blender/editors/sculpt_paint/paint_vertex.c10
-rw-r--r--source/blender/editors/transform/transform_conversions.c6
-rw-r--r--source/blender/editors/util/ed_util.c4
14 files changed, 172 insertions, 159 deletions
diff --git a/source/blender/editors/armature/armature_skinning.c b/source/blender/editors/armature/armature_skinning.c
index c621d6f99c0..28fddbab796 100644
--- a/source/blender/editors/armature/armature_skinning.c
+++ b/source/blender/editors/armature/armature_skinning.c
@@ -214,7 +214,7 @@ static void envelope_bone_weighting(Object *ob, Mesh *mesh, float (*verts)[3], i
continue;
}
- iflip = (dgroupflip) ? mesh_get_x_mirror_vert(ob, i, use_topology) : -1;
+ iflip = (dgroupflip) ? mesh_get_x_mirror_vert(ob, NULL, i, use_topology) : -1;
/* for each skinnable bone */
for (j = 0; j < numbones; ++j) {
@@ -411,7 +411,7 @@ static void add_verts_to_dgroups(ReportList *reports, Scene *scene, Object *ob,
}
/* only generated in some cases but can call anyway */
- ED_mesh_mirror_spatial_table(ob, NULL, NULL, 'e');
+ ED_mesh_mirror_spatial_table(ob, NULL, NULL, NULL, 'e');
/* free the memory allocated */
MEM_freeN(bonelist);
diff --git a/source/blender/editors/armature/meshlaplacian.c b/source/blender/editors/armature/meshlaplacian.c
index 549b60c2ece..4bda8285029 100644
--- a/source/blender/editors/armature/meshlaplacian.c
+++ b/source/blender/editors/armature/meshlaplacian.c
@@ -675,7 +675,7 @@ void heat_bone_weighting(Object *ob, Mesh *me, float (*verts)[3], int numsource,
if (dgroupflip) {
vertsflipped = MEM_callocN(sizeof(int) * me->totvert, "vertsflipped");
for (a = 0; a < me->totvert; a++)
- vertsflipped[a] = mesh_get_x_mirror_vert(ob, a, use_topology);
+ vertsflipped[a] = mesh_get_x_mirror_vert(ob, NULL, a, use_topology);
}
/* compute weights per bone */
diff --git a/source/blender/editors/include/ED_mesh.h b/source/blender/editors/include/ED_mesh.h
index c509aeb4ac2..f072e707d00 100644
--- a/source/blender/editors/include/ED_mesh.h
+++ b/source/blender/editors/include/ED_mesh.h
@@ -218,8 +218,8 @@ typedef struct MirrTopoStore_t {
int prev_ob_mode;
} MirrTopoStore_t;
-bool ED_mesh_mirrtopo_recalc_check(struct Mesh *me, const int ob_mode, MirrTopoStore_t *mesh_topo_store);
-void ED_mesh_mirrtopo_init(struct Mesh *me, const int ob_mode, MirrTopoStore_t *mesh_topo_store,
+bool ED_mesh_mirrtopo_recalc_check(struct Mesh *me, struct DerivedMesh *dm, const int ob_mode, MirrTopoStore_t *mesh_topo_store);
+void ED_mesh_mirrtopo_init(struct Mesh *me, struct DerivedMesh *dm, const int ob_mode, MirrTopoStore_t *mesh_topo_store,
const bool skip_em_vert_array_init);
void ED_mesh_mirrtopo_free(MirrTopoStore_t *mesh_topo_store);
@@ -308,17 +308,18 @@ int join_mesh_exec(struct bContext *C, struct wmOperator *op);
int join_mesh_shapes_exec(struct bContext *C, struct wmOperator *op);
/* mirror lookup api */
-int ED_mesh_mirror_spatial_table(struct Object *ob, struct BMEditMesh *em, const float co[3], char mode);
-int ED_mesh_mirror_topo_table(struct Object *ob, char mode);
+int ED_mesh_mirror_spatial_table(
+ struct Object *ob, struct BMEditMesh *em, struct DerivedMesh *dm, const float co[3], char mode);
+int ED_mesh_mirror_topo_table(struct Object *ob, struct DerivedMesh *dm, char mode);
/* retrieves mirrored cache vert, or NULL if there isn't one.
* note: calling this without ensuring the mirror cache state
* is bad.*/
-int mesh_get_x_mirror_vert(struct Object *ob, int index, const bool use_topology);
+int mesh_get_x_mirror_vert(struct Object *ob, struct DerivedMesh *dm, int index, const bool use_topology);
struct BMVert *editbmesh_get_x_mirror_vert(struct Object *ob, struct BMEditMesh *em,
struct BMVert *eve, const float co[3],
int index, const bool use_topology);
-int *mesh_get_x_mirror_faces(struct Object *ob, struct BMEditMesh *em);
+int *mesh_get_x_mirror_faces(struct Object *ob, struct BMEditMesh *em, struct DerivedMesh *dm);
int ED_mesh_mirror_get_vert(struct Object *ob, int index);
diff --git a/source/blender/editors/mesh/editface.c b/source/blender/editors/mesh/editface.c
index e5b4e661773..01be8f848aa 100644
--- a/source/blender/editors/mesh/editface.c
+++ b/source/blender/editors/mesh/editface.c
@@ -632,12 +632,16 @@ static int mirrtopo_vert_sort(const void *v1, const void *v2)
return 0;
}
-bool ED_mesh_mirrtopo_recalc_check(Mesh *me, const int ob_mode, MirrTopoStore_t *mesh_topo_store)
+bool ED_mesh_mirrtopo_recalc_check(Mesh *me, DerivedMesh *dm, const int ob_mode, MirrTopoStore_t *mesh_topo_store)
{
int totvert;
int totedge;
- if (me->edit_btmesh) {
+ if (dm) {
+ totvert = dm->getNumVerts(dm);
+ totedge = dm->getNumEdges(dm);
+ }
+ else if (me->edit_btmesh) {
totvert = me->edit_btmesh->bm->totvert;
totedge = me->edit_btmesh->bm->totedge;
}
@@ -659,11 +663,11 @@ bool ED_mesh_mirrtopo_recalc_check(Mesh *me, const int ob_mode, MirrTopoStore_t
}
-void ED_mesh_mirrtopo_init(Mesh *me, const int ob_mode, MirrTopoStore_t *mesh_topo_store,
+void ED_mesh_mirrtopo_init(Mesh *me, DerivedMesh *dm, const int ob_mode, MirrTopoStore_t *mesh_topo_store,
const bool skip_em_vert_array_init)
{
- MEdge *medge;
- BMEditMesh *em = me->edit_btmesh;
+ MEdge *medge = NULL, *med;
+ BMEditMesh *em = dm ? NULL : me->edit_btmesh;
/* editmode*/
BMEdge *eed;
@@ -692,7 +696,7 @@ void ED_mesh_mirrtopo_init(Mesh *me, const int ob_mode, MirrTopoStore_t *mesh_to
totvert = em->bm->totvert;
}
else {
- totvert = me->totvert;
+ totvert = dm ? dm->getNumVerts(dm) : me->totvert;
}
topo_hash = MEM_callocN(totvert * sizeof(MirrTopoHash_t), "TopoMirr");
@@ -708,10 +712,11 @@ void ED_mesh_mirrtopo_init(Mesh *me, const int ob_mode, MirrTopoStore_t *mesh_to
}
}
else {
- totedge = me->totedge;
+ totedge = dm ? dm->getNumEdges(dm) : me->totedge;
+ medge = dm ? dm->getEdgeArray(dm) : me->medge;
- for (a = 0, medge = me->medge; a < me->totedge; a++, medge++) {
- const unsigned int i1 = medge->v1, i2 = medge->v2;
+ for (a = 0, med = medge; a < totedge; a++, med++) {
+ const unsigned int i1 = med->v1, i2 = med->v2;
topo_hash[i1]++;
topo_hash[i2]++;
}
@@ -736,8 +741,8 @@ void ED_mesh_mirrtopo_init(Mesh *me, const int ob_mode, MirrTopoStore_t *mesh_to
}
}
else {
- for (a = 0, medge = me->medge; a < me->totedge; a++, medge++) {
- const unsigned int i1 = medge->v1, i2 = medge->v2;
+ for (a = 0, med = medge; a < totedge; a++, med++) {
+ const unsigned int i1 = med->v1, i2 = med->v2;
topo_hash[i1] += topo_hash_prev[i2] * topo_pass;
topo_hash[i2] += topo_hash_prev[i1] * topo_pass;
tot_unique_edges += (topo_hash[i1] != topo_hash[i2]);
@@ -782,7 +787,6 @@ void ED_mesh_mirrtopo_init(Mesh *me, const int ob_mode, MirrTopoStore_t *mesh_to
}
}
-
for (a = 0; a < totvert; a++) {
topo_pairs[a].hash = topo_hash[a];
topo_pairs[a].v_index = a;
diff --git a/source/blender/editors/mesh/editmesh_utils.c b/source/blender/editors/mesh/editmesh_utils.c
index 9cf80c8f4cf..feb0ef73f15 100644
--- a/source/blender/editors/mesh/editmesh_utils.c
+++ b/source/blender/editors/mesh/editmesh_utils.c
@@ -415,8 +415,8 @@ void EDBM_mesh_free(BMEditMesh *em)
/* These tables aren't used yet, so it's not strictly necessary
* to 'end' them (with 'e' param) but if someone tries to start
* using them, having these in place will save a lot of pain */
- ED_mesh_mirror_spatial_table(NULL, NULL, NULL, 'e');
- ED_mesh_mirror_topo_table(NULL, 'e');
+ ED_mesh_mirror_spatial_table(NULL, NULL, NULL, NULL, 'e');
+ ED_mesh_mirror_topo_table(NULL, NULL, 'e');
BKE_editmesh_free(em);
}
@@ -1140,7 +1140,7 @@ void EDBM_verts_mirror_cache_begin_ex(BMEditMesh *em, const int axis, const bool
BM_mesh_elem_index_ensure(bm, BM_VERT);
if (use_topology) {
- ED_mesh_mirrtopo_init(me, -1, &mesh_topo_store, true);
+ ED_mesh_mirrtopo_init(me, NULL, -1, &mesh_topo_store, true);
}
else {
tree = BLI_kdtree_new(bm->totvert);
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];
diff --git a/source/blender/editors/object/object_edit.c b/source/blender/editors/object/object_edit.c
index 64a69542e38..67c9f6e98da 100644
--- a/source/blender/editors/object/object_edit.c
+++ b/source/blender/editors/object/object_edit.c
@@ -342,8 +342,8 @@ static bool ED_object_editmode_load_ex(Main *bmain, Object *obedit, const bool f
me->edit_btmesh = NULL;
}
if (obedit->restore_mode & OB_MODE_WEIGHT_PAINT) {
- ED_mesh_mirror_spatial_table(NULL, NULL, NULL, 'e');
- ED_mesh_mirror_topo_table(NULL, 'e');
+ ED_mesh_mirror_spatial_table(NULL, NULL, NULL, NULL, 'e');
+ ED_mesh_mirror_topo_table(NULL, NULL, 'e');
}
}
else if (obedit->type == OB_ARMATURE) {
diff --git a/source/blender/editors/object/object_shapekey.c b/source/blender/editors/object/object_shapekey.c
index ed71af71ac9..39bd34456be 100644
--- a/source/blender/editors/object/object_shapekey.c
+++ b/source/blender/editors/object/object_shapekey.c
@@ -131,10 +131,10 @@ static bool object_shape_key_mirror(bContext *C, Object *ob,
float *fp1, *fp2;
float tvec[3];
- ED_mesh_mirror_spatial_table(ob, NULL, NULL, 's');
+ ED_mesh_mirror_spatial_table(ob, NULL, NULL, NULL, 's');
for (i1 = 0, mv = me->mvert; i1 < me->totvert; i1++, mv++) {
- i2 = mesh_get_x_mirror_vert(ob, i1, use_topology);
+ i2 = mesh_get_x_mirror_vert(ob, NULL, i1, use_topology);
if (i2 == i1) {
fp1 = ((float *)kb->data) + i1 * 3;
fp1[0] = -fp1[0];
@@ -162,7 +162,7 @@ static bool object_shape_key_mirror(bContext *C, Object *ob,
}
}
- ED_mesh_mirror_spatial_table(ob, NULL, NULL, 'e');
+ ED_mesh_mirror_spatial_table(ob, NULL, NULL, NULL, 'e');
}
else if (ob->type == OB_LATTICE) {
Lattice *lt = ob->data;
diff --git a/source/blender/editors/object/object_vgroup.c b/source/blender/editors/object/object_vgroup.c
index 2271baf46a5..c0b0303404e 100644
--- a/source/blender/editors/object/object_vgroup.c
+++ b/source/blender/editors/object/object_vgroup.c
@@ -517,7 +517,7 @@ static void ED_mesh_defvert_mirror_update_ob(Object *ob, int def_nr, int vidx)
if (vidx == -1)
return;
- vidx_mirr = mesh_get_x_mirror_vert(ob, vidx, use_topology);
+ vidx_mirr = mesh_get_x_mirror_vert(ob, NULL, vidx, use_topology);
if ((vidx_mirr) >= 0 && (vidx_mirr != vidx)) {
MDeformVert *dvert_src = &me->dvert[vidx];
@@ -2244,7 +2244,7 @@ void ED_vgroup_mirror(Object *ob,
for (vidx = 0, mv = me->mvert; vidx < me->totvert; vidx++, mv++) {
if ((mv->flag & ME_VERT_TMP_TAG) == 0) {
- if ((vidx_mirr = mesh_get_x_mirror_vert(ob, vidx, use_topology)) != -1) {
+ if ((vidx_mirr = mesh_get_x_mirror_vert(ob, NULL, vidx, use_topology)) != -1) {
if (vidx != vidx_mirr) {
mv_mirr = &me->mvert[vidx_mirr];
if ((mv_mirr->flag & ME_VERT_TMP_TAG) == 0) {
diff --git a/source/blender/editors/physics/particle_edit.c b/source/blender/editors/physics/particle_edit.c
index 64ad3a100cc..deba3bbca32 100644
--- a/source/blender/editors/physics/particle_edit.c
+++ b/source/blender/editors/physics/particle_edit.c
@@ -659,7 +659,7 @@ static void foreach_mouse_hit_key(PEData *data, ForKeyMatFunc func, int selected
if (selected==0 || key->flag & PEK_SELECT) {
if (key_inside_circle(data, data->rad, KEY_WCO, &data->dist)) {
if (edit->psys && !(edit->psys->flag & PSYS_GLOBAL_HAIR)) {
- psys_mat_hair_to_global(data->ob, psmd->dm, psys->part->from, psys->particles + p, mat);
+ psys_mat_hair_to_global(data->ob, psmd->dm_final, psys->part->from, psys->particles + p, mat);
invert_m4_m4(imat, mat);
}
@@ -674,7 +674,7 @@ static void foreach_mouse_hit_key(PEData *data, ForKeyMatFunc func, int selected
if (selected==0 || key->flag & PEK_SELECT) {
if (key_inside_circle(data, data->rad, KEY_WCO, &data->dist)) {
if (edit->psys && !(edit->psys->flag & PSYS_GLOBAL_HAIR)) {
- psys_mat_hair_to_global(data->ob, psmd->dm, psys->part->from, psys->particles + p, mat);
+ psys_mat_hair_to_global(data->ob, psmd->dm_final, psys->part->from, psys->particles + p, mat);
invert_m4_m4(imat, mat);
}
@@ -761,7 +761,7 @@ static void PE_update_mirror_cache(Object *ob, ParticleSystem *psys)
psmd= psys_get_modifier(ob, psys);
totpart= psys->totpart;
- if (!psmd->dm)
+ if (!psmd->dm_final)
return;
tree= BLI_kdtree_new(totpart);
@@ -769,7 +769,7 @@ static void PE_update_mirror_cache(Object *ob, ParticleSystem *psys)
/* insert particles into kd tree */
LOOP_PARTICLES {
key = pa->hair;
- psys_mat_hair_to_orco(ob, psmd->dm, psys->part->from, pa, mat);
+ psys_mat_hair_to_orco(ob, psmd->dm_final, psys->part->from, pa, mat);
copy_v3_v3(co, key->co);
mul_m4_v3(mat, co);
BLI_kdtree_insert(tree, p, co);
@@ -783,7 +783,7 @@ static void PE_update_mirror_cache(Object *ob, ParticleSystem *psys)
LOOP_PARTICLES {
key = pa->hair;
- psys_mat_hair_to_orco(ob, psmd->dm, psys->part->from, pa, mat);
+ psys_mat_hair_to_orco(ob, psmd->dm_final, psys->part->from, pa, mat);
copy_v3_v3(co, key->co);
mul_m4_v3(mat, co);
co[0] = -co[0];
@@ -898,7 +898,7 @@ static void PE_apply_mirror(Object *ob, ParticleSystem *psys)
edit= psys->edit;
psmd= psys_get_modifier(ob, psys);
- if (!psmd->dm)
+ if (!psmd->dm_final)
return;
if (!edit->mirror_cache)
@@ -911,7 +911,7 @@ static void PE_apply_mirror(Object *ob, ParticleSystem *psys)
* to avoid doing mirror twice */
LOOP_POINTS {
if (point->flag & PEP_EDIT_RECALC) {
- PE_mirror_particle(ob, psmd->dm, psys, psys->particles + p, NULL);
+ PE_mirror_particle(ob, psmd->dm_final, psys, psys->particles + p, NULL);
if (edit->mirror_cache[p] != -1)
edit->points[edit->mirror_cache[p]].flag &= ~PEP_EDIT_RECALC;
@@ -946,11 +946,11 @@ static void pe_deflect_emitter(Scene *scene, Object *ob, PTCacheEdit *edit)
psys = edit->psys;
psmd = psys_get_modifier(ob, psys);
- if (!psmd->dm)
+ if (!psmd->dm_final)
return;
LOOP_EDITED_POINTS {
- psys_mat_hair_to_object(ob, psmd->dm, psys->part->from, psys->particles + p, hairmat);
+ psys_mat_hair_to_object(ob, psmd->dm_final, psys->part->from, psys->particles + p, hairmat);
LOOP_KEYS {
mul_m4_v3(hairmat, key->co);
@@ -1095,7 +1095,7 @@ void recalc_lengths(PTCacheEdit *edit)
/* calculate a tree for finding nearest emitter's vertice */
void recalc_emitter_field(Object *ob, ParticleSystem *psys)
{
- DerivedMesh *dm=psys_get_modifier(ob, psys)->dm;
+ DerivedMesh *dm=psys_get_modifier(ob, psys)->dm_final;
PTCacheEdit *edit= psys->edit;
float *vec, *nor;
int i, totface /*, totvert*/;
@@ -1188,12 +1188,12 @@ void update_world_cos(Object *ob, PTCacheEdit *edit)
POINT_P; KEY_K;
float hairmat[4][4];
- if (psys==0 || psys->edit==0 || psmd->dm==NULL)
+ if (psys==0 || psys->edit==0 || psmd->dm_final==NULL)
return;
LOOP_POINTS {
if (!(psys->flag & PSYS_GLOBAL_HAIR))
- psys_mat_hair_to_global(ob, psmd->dm, psys->part->from, psys->particles+p, hairmat);
+ psys_mat_hair_to_global(ob, psmd->dm_final, psys->part->from, psys->particles+p, hairmat);
LOOP_KEYS {
copy_v3_v3(key->world_co, key->co);
@@ -1839,7 +1839,7 @@ int PE_lasso_select(bContext *C, const int mcords[][2], const short moves, bool
LOOP_VISIBLE_POINTS {
if (edit->psys && !(psys->flag & PSYS_GLOBAL_HAIR))
- psys_mat_hair_to_global(ob, psmd->dm, psys->part->from, psys->particles + p, mat);
+ psys_mat_hair_to_global(ob, psmd->dm_final, psys->part->from, psys->particles + p, mat);
if (pset->selectmode==SCE_SELECT_POINT) {
LOOP_KEYS {
@@ -2273,7 +2273,7 @@ static int remove_tagged_particles(Object *ob, ParticleSystem *psys, int mirror)
psmd= psys_get_modifier(ob, psys);
LOOP_TAGGED_POINTS {
- PE_mirror_particle(ob, psmd->dm, psys, psys->particles + p, NULL);
+ PE_mirror_particle(ob, psmd->dm_final, psys, psys->particles + p, NULL);
}
}
@@ -2353,7 +2353,7 @@ static void remove_tagged_keys(Object *ob, ParticleSystem *psys)
LOOP_POINTS {
LOOP_TAGGED_KEYS {
- PE_mirror_particle(ob, psmd->dm, psys, psys->particles + p, NULL);
+ PE_mirror_particle(ob, psmd->dm_final, psys, psys->particles + p, NULL);
break;
}
}
@@ -2567,7 +2567,7 @@ static int remove_doubles_exec(bContext *C, wmOperator *op)
/* insert particles into kd tree */
LOOP_SELECTED_POINTS {
- psys_mat_hair_to_object(ob, psmd->dm, psys->part->from, psys->particles+p, mat);
+ psys_mat_hair_to_object(ob, psmd->dm_final, psys->part->from, psys->particles+p, mat);
copy_v3_v3(co, point->keys->co);
mul_m4_v3(mat, co);
BLI_kdtree_insert(tree, p, co);
@@ -2577,7 +2577,7 @@ static int remove_doubles_exec(bContext *C, wmOperator *op)
/* tag particles to be removed */
LOOP_SELECTED_POINTS {
- psys_mat_hair_to_object(ob, psmd->dm, psys->part->from, psys->particles+p, mat);
+ psys_mat_hair_to_object(ob, psmd->dm_final, psys->part->from, psys->particles+p, mat);
copy_v3_v3(co, point->keys->co);
mul_m4_v3(mat, co);
@@ -2808,13 +2808,17 @@ static void PE_mirror_x(Scene *scene, Object *ob, int tagged)
return;
psmd= psys_get_modifier(ob, psys);
- if (!psmd->dm)
+ if (!psmd->dm_final)
return;
+ const bool use_dm_final_indices = (psys->part->use_modifier_stack && !psmd->dm_final->deformedOnly);
+
/* NOTE: this is not nice to use tessfaces but hard to avoid since pa->num uses tessfaces */
BKE_mesh_tessface_ensure(me);
- mirrorfaces= mesh_get_x_mirror_faces(ob, NULL);
+ /* Note: In case psys uses DM tessface indices, we mirror final DM iteslef, not orig mesh. Avoids an (impossible)
+ * dm -> orig -> dm tessface indices conversion... */
+ mirrorfaces = mesh_get_x_mirror_faces(ob, NULL, use_dm_final_indices ? psmd->dm_final : NULL);
if (!edit->mirror_cache)
PE_update_mirror_cache(ob, psys);
@@ -2823,11 +2827,12 @@ static void PE_mirror_x(Scene *scene, Object *ob, int tagged)
newtotpart= psys->totpart;
LOOP_VISIBLE_POINTS {
pa = psys->particles + p;
+
if (!tagged) {
if (point_is_selected(point)) {
if (edit->mirror_cache[p] != -1) {
/* already has a mirror, don't need to duplicate */
- PE_mirror_particle(ob, psmd->dm, psys, pa, NULL);
+ PE_mirror_particle(ob, psmd->dm_final, psys, pa, NULL);
continue;
}
else
@@ -2840,6 +2845,8 @@ static void PE_mirror_x(Scene *scene, Object *ob, int tagged)
}
if (newtotpart != psys->totpart) {
+ MFace *mtessface = use_dm_final_indices ? psmd->dm_final->getTessFaceArray(psmd->dm_final) : me->mface;
+
/* allocate new arrays and copy existing */
new_pars= MEM_callocN(newtotpart*sizeof(ParticleData), "ParticleData new");
new_points= MEM_callocN(newtotpart*sizeof(PTCacheEditPoint), "PTCacheEditPoint new");
@@ -2869,10 +2876,12 @@ static void PE_mirror_x(Scene *scene, Object *ob, int tagged)
for (p=0, point=edit->points; p<totpart; p++, point++) {
pa = psys->particles + p;
+ const int pa_num = pa->num;
if (point->flag & PEP_HIDE)
continue;
- if (!(point->flag & PEP_TAG) || mirrorfaces[pa->num*2] == -1)
+
+ if (!(point->flag & PEP_TAG) || mirrorfaces[pa_num * 2] == -1)
continue;
/* duplicate */
@@ -2882,27 +2891,31 @@ static void PE_mirror_x(Scene *scene, Object *ob, int tagged)
if (point->keys) newpoint->keys= MEM_dupallocN(point->keys);
/* rotate weights according to vertex index rotation */
- rotation= mirrorfaces[pa->num*2+1];
+ rotation= mirrorfaces[pa_num * 2 + 1];
newpa->fuv[0] = pa->fuv[2];
newpa->fuv[1] = pa->fuv[1];
newpa->fuv[2] = pa->fuv[0];
newpa->fuv[3] = pa->fuv[3];
- while (rotation-- > 0)
- if (me->mface[pa->num].v4) {
+ while (rotation--) {
+ if (mtessface[pa_num].v4) {
SHIFT4(float, newpa->fuv[0], newpa->fuv[1], newpa->fuv[2], newpa->fuv[3]);
}
else {
SHIFT3(float, newpa->fuv[0], newpa->fuv[1], newpa->fuv[2]);
}
+ }
- /* assign face inddex */
- newpa->num= mirrorfaces[pa->num*2];
- newpa->num_dmcache= psys_particle_dm_face_lookup(ob, psmd->dm, newpa->num, newpa->fuv, NULL);
+ /* assign face index */
+ /* NOTE: mesh_get_x_mirror_faces generates -1 for non-found mirror, same as DMCACHE_NOTFOUND... */
+ newpa->num = mirrorfaces[pa_num * 2];
- if ((newpa->num_dmcache != DMCACHE_NOTFOUND) && psys->part->use_modifier_stack && !psmd->dm->deformedOnly) {
- newpa->num = newpa->num_dmcache;
+ if (use_dm_final_indices) {
newpa->num_dmcache = DMCACHE_ISCHILD;
}
+ else {
+ newpa->num_dmcache = psys_particle_dm_face_lookup(
+ psmd->dm_final, psmd->dm_deformed, newpa->num, newpa->fuv, NULL);
+ }
/* update edit key pointers */
key= newpoint->keys;
@@ -2912,7 +2925,7 @@ static void PE_mirror_x(Scene *scene, Object *ob, int tagged)
}
/* map key positions as mirror over x axis */
- PE_mirror_particle(ob, psmd->dm, psys, pa, newpa);
+ PE_mirror_particle(ob, psmd->dm_final, psys, pa, newpa);
newpa++;
newpoint++;
@@ -3360,7 +3373,7 @@ static int particle_intersect_dm(Scene *scene, Object *ob, DerivedMesh *dm,
totface=dm->getNumTessFaces(dm);
mface=dm->getTessFaceDataArray(dm, CD_MFACE);
mvert=dm->getVertDataArray(dm, CD_MVERT);
-
+
/* lets intersect the faces */
for (i=0; i<totface; i++, mface++) {
if (vert_cos) {
@@ -3452,6 +3465,7 @@ static int brush_add(PEData *data, short number)
{
Scene *scene= data->scene;
Object *ob= data->ob;
+ DerivedMesh *dm;
PTCacheEdit *edit = data->edit;
ParticleSystem *psys= edit->psys;
ParticleData *add_pars;
@@ -3465,11 +3479,7 @@ static int brush_add(PEData *data, short number)
float framestep, timestep;
short size= pset->brush[PE_BRUSH_ADD].size;
short size2= size*size;
- DerivedMesh *dm=0;
RNG *rng;
- const int *index_mf_to_mpoly;
- const int *index_mp_to_orig;
- bool release_dm = false;
invert_m4_m4(imat, ob->obmat);
@@ -3487,15 +3497,13 @@ static int brush_add(PEData *data, short number)
timestep= psys_get_timestep(&sim);
- if (psmd->dm->deformedOnly || psys->part->use_modifier_stack)
- dm = psmd->dm;
+ if (psys->part->use_modifier_stack || psmd->dm_final->deformedOnly) {
+ dm = psmd->dm_final;
+ }
else {
- dm = mesh_get_derived_deform(scene, ob, CD_MASK_BAREMESH | CD_MASK_MFACE);
- release_dm = true;
+ dm = psmd->dm_deformed;
}
-
- index_mf_to_mpoly = dm->getTessFaceDataArray(dm, CD_ORIGINDEX);
- index_mp_to_orig = dm->getPolyDataArray(dm, CD_ORIGINDEX);
+ BLI_assert(dm);
for (i=0; i<number; i++) {
if (number>1) {
@@ -3523,16 +3531,22 @@ static int brush_add(PEData *data, short number)
/* warning, returns the derived mesh face */
if (particle_intersect_dm(scene, ob, dm, 0, co1, co2, &min_d, &add_pars[n].num_dmcache, add_pars[n].fuv, 0, 0, 0, 0)) {
- if (index_mf_to_mpoly && index_mp_to_orig)
- add_pars[n].num = DM_origindex_mface_mpoly(index_mf_to_mpoly, index_mp_to_orig, add_pars[n].num_dmcache);
- else
+ if (psys->part->use_modifier_stack && !psmd->dm_final->deformedOnly) {
+ add_pars[n].num = add_pars[n].num_dmcache;
+ add_pars[n].num_dmcache = DMCACHE_ISCHILD;
+ }
+ else if (dm == psmd->dm_deformed) {
+ /* Final DM is not same topology as orig mesh, we have to map num_dmcache to real final dm. */
+ add_pars[n].num = add_pars[n].num_dmcache;
+ add_pars[n].num_dmcache = psys_particle_dm_face_lookup(
+ psmd->dm_final, psmd->dm_deformed,
+ add_pars[n].num, add_pars[n].fuv, NULL);
+ }
+ else {
add_pars[n].num = add_pars[n].num_dmcache;
+ }
- if (psys_particle_dm_face_lookup(ob, psmd->dm, add_pars[n].num_dmcache, add_pars[n].fuv, NULL) != DMCACHE_NOTFOUND) {
- if (psys->part->use_modifier_stack && !psmd->dm->deformedOnly) {
- add_pars[n].num = add_pars[n].num_dmcache;
- add_pars[n].num_dmcache = DMCACHE_ISCHILD;
- }
+ if (add_pars[n].num != DMCACHE_NOTFOUND) {
n++;
}
}
@@ -3567,7 +3581,7 @@ static int brush_add(PEData *data, short number)
tree=BLI_kdtree_new(psys->totpart);
for (i=0, pa=psys->particles; i<totpart; i++, pa++) {
- psys_particle_on_dm(psmd->dm, psys->part->from, pa->num, pa->num_dmcache, pa->fuv, pa->foffset, cur_co, 0, 0, 0, 0, 0);
+ psys_particle_on_dm(psmd->dm_final, psys->part->from, pa->num, pa->num_dmcache, pa->fuv, pa->foffset, cur_co, 0, 0, 0, 0, 0);
BLI_kdtree_insert(tree, i, cur_co);
}
@@ -3611,7 +3625,7 @@ static int brush_add(PEData *data, short number)
int w, maxw;
float maxd, totw=0.0, weight[3];
- psys_particle_on_dm(psmd->dm, psys->part->from, pa->num, pa->num_dmcache, pa->fuv, pa->foffset, co1, 0, 0, 0, 0, 0);
+ psys_particle_on_dm(psmd->dm_final, psys->part->from, pa->num, pa->num_dmcache, pa->fuv, pa->foffset, co1, 0, 0, 0, 0, 0);
maxw = BLI_kdtree_find_nearest_n(tree, co1, ptn, 3);
maxd= ptn[maxw-1].dist;
@@ -3676,7 +3690,7 @@ static int brush_add(PEData *data, short number)
}
}
for (k=0, hkey=pa->hair; k<pset->totaddkey; k++, hkey++) {
- psys_mat_hair_to_global(ob, psmd->dm, psys->part->from, pa, hairmat);
+ psys_mat_hair_to_global(ob, psmd->dm_final, psys->part->from, pa, hairmat);
invert_m4_m4(imat, hairmat);
mul_m4_v3(imat, hkey->co);
}
@@ -3688,9 +3702,6 @@ static int brush_add(PEData *data, short number)
MEM_freeN(add_pars);
- if (release_dm)
- dm->release(dm);
-
BLI_rng_free(rng);
return n;
@@ -3866,7 +3877,7 @@ static void brush_edit_apply(bContext *C, wmOperator *op, PointerRNA *itemptr)
case PE_BRUSH_PUFF:
{
if (edit->psys) {
- data.dm= psmd->dm;
+ data.dm= psmd->dm_final;
data.mval= mval;
data.rad= pe_brush_size_get(scene, brush);
data.select= selected;
@@ -3922,7 +3933,7 @@ static void brush_edit_apply(bContext *C, wmOperator *op, PointerRNA *itemptr)
case PE_BRUSH_WEIGHT:
{
if (edit->psys) {
- data.dm= psmd->dm;
+ data.dm= psmd->dm_final;
data.mval= mval;
data.rad= pe_brush_size_get(scene, brush);
@@ -4545,7 +4556,7 @@ int PE_minmax(Scene *scene, float min[3], float max[3])
LOOP_VISIBLE_POINTS {
if (psys)
- psys_mat_hair_to_global(ob, psmd->dm, psys->part->from, psys->particles+p, mat);
+ psys_mat_hair_to_global(ob, psmd->dm_final, psys->part->from, psys->particles+p, mat);
LOOP_SELECTED_KEYS {
copy_v3_v3(co, key->co);
@@ -4576,7 +4587,7 @@ void PE_create_particle_edit(Scene *scene, Object *ob, PointCache *cache, Partic
int totpoint;
/* no psmd->dm happens in case particle system modifier is not enabled */
- if (!(psys && psmd && psmd->dm) && !cache)
+ if (!(psys && psmd && psmd->dm_final) && !cache)
return;
if (cache && cache->flag & PTCACHE_DISK_CACHE)
diff --git a/source/blender/editors/physics/particle_object.c b/source/blender/editors/physics/particle_object.c
index 6d143fb13f3..ecd27646562 100644
--- a/source/blender/editors/physics/particle_object.c
+++ b/source/blender/editors/physics/particle_object.c
@@ -592,7 +592,7 @@ static void disconnect_hair(Scene *scene, Object *ob, ParticleSystem *psys)
point++;
}
- psys_mat_hair_to_global(ob, psmd->dm, psys->part->from, pa, hairmat);
+ psys_mat_hair_to_global(ob, psmd->dm_final, psys->part->from, pa, hairmat);
for (k=0, key=pa->hair; k<pa->totkey; k++, key++) {
mul_m4_v3(hairmat, key->co);
@@ -676,7 +676,7 @@ static bool remap_hair_emitter(Scene *scene, Object *ob, ParticleSystem *psys,
float from_ob_imat[4][4], to_ob_imat[4][4];
float from_imat[4][4], to_imat[4][4];
- if (!target_psmd->dm)
+ if (!target_psmd->dm_final)
return false;
if (!psys->part || psys->part->type != PART_HAIR)
return false;
@@ -690,15 +690,14 @@ static bool remap_hair_emitter(Scene *scene, Object *ob, ParticleSystem *psys,
invert_m4_m4(from_imat, from_mat);
invert_m4_m4(to_imat, to_mat);
- if (target_psmd->dm->deformedOnly) {
+ if (target_psmd->dm_final->deformedOnly) {
/* we don't want to mess up target_psmd->dm when converting to global coordinates below */
- dm = target_psmd->dm;
+ dm = target_psmd->dm_final;
}
else {
- /* warning: this rebuilds target_psmd->dm! */
- dm = mesh_get_derived_deform(scene, target_ob, CD_MASK_BAREMESH | CD_MASK_MFACE);
+ dm = target_psmd->dm_deformed;
}
- target_dm = target_psmd->dm;
+ target_dm = target_psmd->dm_final;
/* don't modify the original vertices */
dm = CDDM_copy(dm);
@@ -766,7 +765,7 @@ static bool remap_hair_emitter(Scene *scene, Object *ob, ParticleSystem *psys,
tpa->foffset = 0.0f;
tpa->num = nearest.index;
- tpa->num_dmcache = psys_particle_dm_face_lookup(target_ob, target_dm, tpa->num, tpa->fuv, NULL);
+ tpa->num_dmcache = psys_particle_dm_face_lookup(target_dm, dm, tpa->num, tpa->fuv, NULL);
}
else {
me = &medge[nearest.index];
@@ -1066,9 +1065,9 @@ static bool copy_particle_systems_to_object(Scene *scene, Object *ob_from, Parti
modifier_unique_name(&ob_to->modifiers, (ModifierData *)psmd);
psmd->psys = psys;
- psmd->dm = CDDM_copy(final_dm);
- CDDM_calc_normals(psmd->dm);
- DM_ensure_tessface(psmd->dm);
+ psmd->dm_final = CDDM_copy(final_dm);
+ CDDM_calc_normals(psmd->dm_final);
+ DM_ensure_tessface(psmd->dm_final);
if (psys_from->edit)
copy_particle_edit(scene, ob_to, psys, psys_from);
diff --git a/source/blender/editors/sculpt_paint/paint_vertex.c b/source/blender/editors/sculpt_paint/paint_vertex.c
index 5fa0c9fc71e..34870a112bc 100644
--- a/source/blender/editors/sculpt_paint/paint_vertex.c
+++ b/source/blender/editors/sculpt_paint/paint_vertex.c
@@ -412,7 +412,7 @@ bool ED_wpaint_fill(VPaint *wp, Object *ob, float paintweight)
dw->weight = paintweight;
if (me->editflag & ME_EDIT_MIRROR_X) { /* x mirror painting */
- int j = mesh_get_x_mirror_vert(ob, vidx, topology);
+ int j = mesh_get_x_mirror_vert(ob, NULL, vidx, topology);
if (j >= 0) {
/* copy, not paint again */
if (vgroup_mirror != -1) {
@@ -1718,7 +1718,7 @@ static void do_weight_paint_vertex(
/* from now on we can check if mirrors enabled if this var is -1 and not bother with the flag */
if (me->editflag & ME_EDIT_MIRROR_X) {
- index_mirr = mesh_get_x_mirror_vert(ob, index, topology);
+ index_mirr = mesh_get_x_mirror_vert(ob, NULL, index, topology);
vgroup_mirr = (wpi->vgroup_mirror != -1) ? wpi->vgroup_mirror : wpi->vgroup_active;
/* another possible error - mirror group _and_ active group are the same (which is fine),
@@ -1956,8 +1956,8 @@ static int wpaint_mode_toggle_exec(bContext *C, wmOperator *op)
}
/* weight paint specific */
- ED_mesh_mirror_spatial_table(NULL, NULL, NULL, 'e');
- ED_mesh_mirror_topo_table(NULL, 'e');
+ ED_mesh_mirror_spatial_table(NULL, NULL, NULL, NULL, 'e');
+ ED_mesh_mirror_topo_table(NULL, NULL, 'e');
paint_cursor_delete_textures();
}
@@ -1972,7 +1972,7 @@ static int wpaint_mode_toggle_exec(bContext *C, wmOperator *op)
BKE_paint_init(scene, ePaintWeight, PAINT_CURSOR_WEIGHT_PAINT);
/* weight paint specific */
- ED_mesh_mirror_spatial_table(ob, NULL, NULL, 's');
+ ED_mesh_mirror_spatial_table(ob, NULL, NULL, NULL, 's');
ED_vgroup_sync_from_pose(ob);
}
diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c
index dc0b153d6e9..c18501d0e36 100644
--- a/source/blender/editors/transform/transform_conversions.c
+++ b/source/blender/editors/transform/transform_conversions.c
@@ -1865,7 +1865,7 @@ static void createTransParticleVerts(bContext *C, TransInfo *t)
if (!(point->flag & PEP_TRANSFORM)) continue;
if (psys && !(psys->flag & PSYS_GLOBAL_HAIR))
- psys_mat_hair_to_global(ob, psmd->dm, psys->part->from, psys->particles + i, mat);
+ psys_mat_hair_to_global(ob, psmd->dm_final, psys->part->from, psys->particles + i, mat);
for (k = 0, key = point->keys; k < point->totkey; k++, key++) {
if (key->flag & PEK_USE_WCO) {
@@ -1939,7 +1939,7 @@ void flushTransParticles(TransInfo *t)
if (!(point->flag & PEP_TRANSFORM)) continue;
if (psys && !(psys->flag & PSYS_GLOBAL_HAIR)) {
- psys_mat_hair_to_global(ob, psmd->dm, psys->part->from, psys->particles + i, mat);
+ psys_mat_hair_to_global(ob, psmd->dm_final, psys->part->from, psys->particles + i, mat);
invert_m4_m4(imat, mat);
for (k = 0, key = point->keys; k < point->totkey; k++, key++) {
@@ -6280,7 +6280,7 @@ void special_aftertrans_update(bContext *C, TransInfo *t)
if (t->obedit->type == OB_MESH) {
BMEditMesh *em = BKE_editmesh_from_object(t->obedit);
/* table needs to be created for each edit command, since vertices can move etc */
- ED_mesh_mirror_spatial_table(t->obedit, em, NULL, 'e');
+ ED_mesh_mirror_spatial_table(t->obedit, em, NULL, NULL, 'e');
}
}
else if ((t->flag & T_POSE) && (t->poseobj)) {
diff --git a/source/blender/editors/util/ed_util.c b/source/blender/editors/util/ed_util.c
index 0463980dacd..1c3ab03c43a 100644
--- a/source/blender/editors/util/ed_util.c
+++ b/source/blender/editors/util/ed_util.c
@@ -151,8 +151,8 @@ void ED_editors_exit(bContext *C)
}
/* global in meshtools... */
- ED_mesh_mirror_spatial_table(NULL, NULL, NULL, 'e');
- ED_mesh_mirror_topo_table(NULL, 'e');
+ ED_mesh_mirror_spatial_table(NULL, NULL, NULL, NULL, 'e');
+ ED_mesh_mirror_topo_table(NULL, NULL, 'e');
}
/* flush any temp data from object editing to DNA before writing files,