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:
-rw-r--r--source/blender/blenkernel/BKE_particle.h8
-rw-r--r--source/blender/blenkernel/intern/DerivedMesh.c58
-rw-r--r--source/blender/blenkernel/intern/object.c13
-rw-r--r--source/blender/blenkernel/intern/particle.c216
-rw-r--r--source/blender/blenkernel/intern/particle_distribute.c14
-rw-r--r--source/blender/blenkernel/intern/particle_system.c41
-rw-r--r--source/blender/blenlib/BLI_math_vector.h2
-rw-r--r--source/blender/blenlib/intern/math_vector_inline.c7
-rw-r--r--source/blender/blenloader/intern/readfile.c3
-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
-rw-r--r--source/blender/makesdna/DNA_modifier_types.h3
-rw-r--r--source/blender/makesdna/DNA_particle_types.h1
-rw-r--r--source/blender/makesrna/intern/rna_object_api.c2
-rw-r--r--source/blender/makesrna/intern/rna_particle.c39
-rw-r--r--source/blender/modifiers/intern/MOD_explode.c2
-rw-r--r--source/blender/modifiers/intern/MOD_particleinstance.c2
-rw-r--r--source/blender/modifiers/intern/MOD_particlesystem.c60
-rw-r--r--source/blender/render/intern/source/convertblender.c50
-rw-r--r--source/blender/render/intern/source/pointdensity.c6
-rw-r--r--source/blenderplayer/bad_level_call_stubs/stubs.c4
33 files changed, 501 insertions, 361 deletions
diff --git a/source/blender/blenkernel/BKE_particle.h b/source/blender/blenkernel/BKE_particle.h
index 00cc48cf713..ed453754648 100644
--- a/source/blender/blenkernel/BKE_particle.h
+++ b/source/blender/blenkernel/BKE_particle.h
@@ -302,7 +302,7 @@ void psys_free_path_cache(struct ParticleSystem *psys, struct PTCacheEdit *edit)
void psys_free(struct Object *ob, struct ParticleSystem *psys);
void psys_render_set(struct Object *ob, struct ParticleSystem *psys, float viewmat[4][4], float winmat[4][4], int winx, int winy, int timeoffset);
-void psys_render_restore(struct Object *ob, struct ParticleSystem *psys);
+void psys_render_restore(struct Scene *scene, struct Object *ob, struct ParticleSystem *psys);
bool psys_render_simplify_params(struct ParticleSystem *psys, struct ChildParticle *cpa, float *params);
void psys_interpolate_uvs(const struct MTFace *tface, int quad, const float w[4], float uvco[2]);
@@ -413,15 +413,15 @@ void psys_get_from_key(struct ParticleKey *key, float loc[3], float vel[3], floa
/* BLI_bvhtree_ray_cast callback */
void BKE_psys_collision_neartest_cb(void *userdata, int index, const struct BVHTreeRay *ray, struct BVHTreeRayHit *hit);
-void psys_particle_on_dm(struct DerivedMesh *dm, int from, int index, int index_dmcache,
+void psys_particle_on_dm(struct DerivedMesh *dm_final, int from, int index, int index_dmcache,
const float fw[4], float foffset, float vec[3], float nor[3], float utan[3], float vtan[3],
float orco[3], float ornor[3]);
/* particle_system.c */
void distribute_particles(struct ParticleSimulationData *sim, int from);
void initialize_particle(struct ParticleSimulationData *sim, struct ParticleData *pa);
-void psys_calc_dmcache(struct Object *ob, struct DerivedMesh *dm, struct ParticleSystem *psys);
-int psys_particle_dm_face_lookup(struct Object *ob, struct DerivedMesh *dm, int index, const float fw[4], struct LinkNode *node);
+void psys_calc_dmcache(struct Object *ob, struct DerivedMesh *dm_final, struct DerivedMesh *dm_deformed, struct ParticleSystem *psys);
+int psys_particle_dm_face_lookup(struct DerivedMesh *dm_final, struct DerivedMesh *dm_deformed, int findex, const float fw[4], struct LinkNode **poly_nodes);
void reset_particle(struct ParticleSimulationData *sim, struct ParticleData *pa, float dtime, float cfra);
diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c
index e26e5148ff6..9fc438319cb 100644
--- a/source/blender/blenkernel/intern/DerivedMesh.c
+++ b/source/blender/blenkernel/intern/DerivedMesh.c
@@ -43,6 +43,7 @@
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
+#include "BLI_array.h"
#include "BLI_blenlib.h"
#include "BLI_bitmap.h"
#include "BLI_math.h"
@@ -3668,26 +3669,73 @@ static DerivedMesh *navmesh_dm_createNavMeshForVisualization(DerivedMesh *dm)
void DM_init_origspace(DerivedMesh *dm)
{
- static float default_osf[4][2] = {{0, 0}, {1, 0}, {1, 1}, {0, 1}};
+ const float default_osf[4][2] = {{0, 0}, {1, 0}, {1, 1}, {0, 1}};
OrigSpaceLoop *lof_array = CustomData_get_layer(&dm->loopData, CD_ORIGSPACE_MLOOP);
- OrigSpaceLoop *lof;
const int numpoly = dm->getNumPolys(dm);
// const int numloop = dm->getNumLoops(dm);
+ MVert *mv = dm->getVertArray(dm);
+ MLoop *ml = dm->getLoopArray(dm);
MPoly *mp = dm->getPolyArray(dm);
- int i, j;
+ int i, j, k;
+
+ float (*vcos_2d)[2] = NULL;
+ BLI_array_staticdeclare(vcos_2d, 64);
for (i = 0; i < numpoly; i++, mp++) {
- /* only quads/tri's for now */
+ OrigSpaceLoop *lof = lof_array + mp->loopstart;
+
if (mp->totloop == 3 || mp->totloop == 4) {
- lof = lof_array + mp->loopstart;
for (j = 0; j < mp->totloop; j++, lof++) {
copy_v2_v2(lof->uv, default_osf[j]);
}
}
+ else {
+ MLoop *l = &ml[mp->loopstart];
+ float p_nor[3], co[3];
+ float mat[3][3];
+
+ float min[2] = {FLT_MAX, FLT_MAX}, max[2] = {FLT_MIN, FLT_MIN};
+ float translate[2], scale[2];
+
+ BKE_mesh_calc_poly_normal(mp, l, mv, p_nor);
+ axis_dominant_v3_to_m3(mat, p_nor);
+
+ BLI_array_empty(vcos_2d);
+ BLI_array_reserve(vcos_2d, mp->totloop);
+ for (j = 0; j < mp->totloop; j++, l++) {
+ mul_v3_m3v3(co, mat, mv[l->v].co);
+ copy_v2_v2(vcos_2d[j], co);
+
+ for (k = 0; k < 2; k++) {
+ if (co[k] > max[k])
+ max[k] = co[k];
+ else if (co[k] < min[k])
+ min[k] = co[k];
+ }
+ }
+
+ /* Brings min to (0, 0). */
+ negate_v2_v2(translate, min);
+
+ /* Scale will bring max to (1, 1). */
+ sub_v2_v2v2(scale, max, min);
+ if (scale[0] == 0.0f)
+ scale[0] = 1e-9f;
+ if (scale[1] == 0.0f)
+ scale[1] = 1e-9f;
+ invert_v2(scale);
+
+ /* Finally, transform all vcos_2d into ((0, 0), (1, 1)) square and assing them as origspace. */
+ for (j = 0; j < mp->totloop; j++, lof++) {
+ add_v2_v2v2(lof->uv, vcos_2d[j], translate);
+ mul_v2_v2(lof->uv, scale);
+ }
+ }
}
dm->dirty |= DM_DIRTY_TESS_CDLAYERS;
+ BLI_array_free(vcos_2d);
}
diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c
index 89f22b8e742..b448bec84e3 100644
--- a/source/blender/blenkernel/intern/object.c
+++ b/source/blender/blenkernel/intern/object.c
@@ -364,10 +364,15 @@ void BKE_object_free_caches(Object *object)
for (md = object->modifiers.first; md != NULL; md = md->next) {
if (md->type == eModifierType_ParticleSystem) {
ParticleSystemModifierData *psmd = (ParticleSystemModifierData *) md;
- if (psmd->dm != NULL) {
- psmd->dm->needsFree = 1;
- psmd->dm->release(psmd->dm);
- psmd->dm = NULL;
+ if (psmd->dm_final != NULL) {
+ psmd->dm_final->needsFree = 1;
+ psmd->dm_final->release(psmd->dm_final);
+ psmd->dm_final = NULL;
+ if (psmd->dm_deformed != NULL) {
+ psmd->dm_deformed->needsFree = 1;
+ psmd->dm_deformed->release(psmd->dm_deformed);
+ psmd->dm_deformed = NULL;
+ }
psmd->flag |= eParticleSystemFlag_file_loaded;
update_flag |= OB_RECALC_DATA;
}
diff --git a/source/blender/blenkernel/intern/particle.c b/source/blender/blenkernel/intern/particle.c
index b3be5676607..39f0e7cbb84 100644
--- a/source/blender/blenkernel/intern/particle.c
+++ b/source/blender/blenkernel/intern/particle.c
@@ -623,8 +623,8 @@ void psys_render_set(Object *ob, ParticleSystem *psys, float viewmat[4][4], floa
data->childcachebufs.last = psys->childcachebufs.last;
data->totchildcache = psys->totchildcache;
- if (psmd->dm)
- data->dm = CDDM_copy(psmd->dm);
+ if (psmd->dm_final)
+ data->dm = CDDM_copy(psmd->dm_final);
data->totdmvert = psmd->totdmvert;
data->totdmedge = psmd->totdmedge;
data->totdmface = psmd->totdmface;
@@ -651,7 +651,7 @@ void psys_render_set(Object *ob, ParticleSystem *psys, float viewmat[4][4], floa
psys->recalc |= PSYS_RECALC_RESET;
}
-void psys_render_restore(Object *ob, ParticleSystem *psys)
+void psys_render_restore(Scene *scene, Object *ob, ParticleSystem *psys)
{
ParticleRenderData *data;
ParticleSystemModifierData *psmd = psys_get_modifier(ob, psys);
@@ -665,9 +665,14 @@ void psys_render_restore(Object *ob, ParticleSystem *psys)
if (data->elems)
MEM_freeN(data->elems);
- if (psmd->dm) {
- psmd->dm->needsFree = 1;
- psmd->dm->release(psmd->dm);
+ if (psmd->dm_final) {
+ psmd->dm_final->needsFree = 1;
+ psmd->dm_final->release(psmd->dm_final);
+ }
+ if (psmd->dm_deformed) {
+ psmd->dm_deformed->needsFree = 1;
+ psmd->dm_deformed->release(psmd->dm_deformed);
+ psmd->dm_deformed = NULL;
}
psys_free_path_cache(psys, NULL);
@@ -689,14 +694,19 @@ void psys_render_restore(Object *ob, ParticleSystem *psys)
psys->childcachebufs.last = data->childcachebufs.last;
psys->totchildcache = data->totchildcache;
- psmd->dm = data->dm;
+ psmd->dm_final = data->dm;
psmd->totdmvert = data->totdmvert;
psmd->totdmedge = data->totdmedge;
psmd->totdmface = data->totdmface;
psmd->flag &= ~eParticleSystemFlag_psys_updated;
- if (psmd->dm)
- psys_calc_dmcache(ob, psmd->dm, psys);
+ if (psmd->dm_final) {
+ if (!psmd->dm_final->deformedOnly) {
+ psmd->dm_deformed = CDDM_copy(mesh_get_derived_deform(scene, ob, CD_MASK_BAREMESH | CD_MASK_MFACE));
+ DM_ensure_tessface(psmd->dm_deformed);
+ }
+ psys_calc_dmcache(ob, psmd->dm_final, psmd->dm_deformed, psys);
+ }
MEM_freeN(data);
psys->renderdata = NULL;
@@ -1383,78 +1393,114 @@ static void psys_origspace_to_w(OrigSpaceFace *osface, int quad, const float w[4
}
}
-/* find the derived mesh face for a particle, set the mf passed. this is slow
- * and can be optimized but only for many lookups. returns the face index. */
-int psys_particle_dm_face_lookup(Object *ob, DerivedMesh *dm, int index, const float fw[4], struct LinkNode *node)
+/**
+ * Find the final derived mesh tessface for a particle, from its original tessface index.
+ * This is slow and can be optimized but only for many lookups.
+ *
+ * \param dm_final final DM, it may not have the same topology as original mesh.
+ * \param dm_deformed deformed-only DM, it has the exact same topology as original mesh.
+ * \param findex_orig the input tessface index.
+ * \param fw face weights (position of the particle inside the \a findex_orig tessface).
+ * \param poly_nodes may be NULL, otherwise an array of linked list, one for each final DM polygon, containing all
+ * its tessfaces indices.
+ * \return the DM tessface index.
+ */
+int psys_particle_dm_face_lookup(
+ DerivedMesh *dm_final, DerivedMesh *dm_deformed,
+ int findex_orig, const float fw[4], struct LinkNode **poly_nodes)
{
- Mesh *me = (Mesh *)ob->data;
- MPoly *mpoly;
- OrigSpaceFace *osface;
- int quad, findex, totface;
+ MFace *mtessface_final;
+ OrigSpaceFace *osface_final;
+ int totface_final;
+ int pindex_orig;
float uv[2], (*faceuv)[2];
- /* double lookup */
- const int *index_mf_to_mpoly = dm->getTessFaceDataArray(dm, CD_ORIGINDEX);
- const int *index_mp_to_orig = dm->getPolyDataArray(dm, CD_ORIGINDEX);
- if (index_mf_to_mpoly == NULL) {
- index_mp_to_orig = NULL;
+ const int *index_mf_to_mpoly_deformed = NULL;
+ const int *index_mf_to_mpoly = NULL;
+ const int *index_mp_to_orig = NULL;
+
+ index_mf_to_mpoly = dm_final->getTessFaceDataArray(dm_final, CD_ORIGINDEX);
+ index_mp_to_orig = dm_final->getPolyDataArray(dm_final, CD_ORIGINDEX);
+ BLI_assert(index_mf_to_mpoly);
+
+ if (dm_deformed) {
+ index_mf_to_mpoly_deformed = dm_deformed->getTessFaceDataArray(dm_deformed, CD_ORIGINDEX);
+ }
+ else {
+ BLI_assert(dm_final->deformedOnly);
+ index_mf_to_mpoly_deformed = index_mf_to_mpoly;
+ }
+ BLI_assert(index_mf_to_mpoly_deformed);
+
+ pindex_orig = index_mf_to_mpoly_deformed[findex_orig];
+
+ if (dm_deformed == NULL) {
+ dm_deformed = dm_final;
}
- totface = dm->getNumTessFaces(dm);
- if (!totface) {
+ index_mf_to_mpoly_deformed = NULL;
+
+ totface_final = dm_final->getNumTessFaces(dm_final);
+ if (!totface_final) {
return DMCACHE_NOTFOUND;
}
- mpoly = dm->getPolyArray(dm);
- osface = dm->getTessFaceDataArray(dm, CD_ORIGSPACE);
+ mtessface_final = dm_final->getTessFaceArray(dm_final);
+ osface_final = dm_final->getTessFaceDataArray(dm_final, CD_ORIGSPACE);
- if (osface == NULL || index_mf_to_mpoly == NULL) {
- /* Assume we don't need osface data */
- if (index < totface) {
+ if (osface_final == NULL) {
+ /* Assume we don't need osface_final data, and we get a direct 1-1 mapping... */
+ if (findex_orig < totface_final) {
//printf("\tNO CD_ORIGSPACE, assuming not needed\n");
- return index;
+ return findex_orig;
}
else {
printf("\tNO CD_ORIGSPACE, error out of range\n");
return DMCACHE_NOTFOUND;
}
}
- else if (index >= me->totpoly)
+ else if (findex_orig >= dm_deformed->getNumTessFaces(dm_deformed)) {
return DMCACHE_NOTFOUND; /* index not in the original mesh */
+ }
psys_w_to_origspace(fw, uv);
- if (node) { /* we have a linked list of faces that we use, faster! */
- for (; node; node = node->next) {
- findex = GET_INT_FROM_POINTER(node->link);
- faceuv = osface[findex].uv;
- quad = (mpoly[findex].totloop == 4);
+ if (poly_nodes) {
+ /* we can have a restricted linked list of faces to check, faster! */
+ LinkNode *tessface_node = poly_nodes[pindex_orig];
+
+ for (; tessface_node; tessface_node = tessface_node->next) {
+ int findex_dst = GET_INT_FROM_POINTER(tessface_node->link);
+ faceuv = osface_final[findex_dst].uv;
/* check that this intersects - Its possible this misses :/ -
* could also check its not between */
- if (quad) {
- if (isect_point_quad_v2(uv, faceuv[0], faceuv[1], faceuv[2], faceuv[3]))
- return findex;
+ if (mtessface_final[findex_dst].v4) {
+ if (isect_point_quad_v2(uv, faceuv[0], faceuv[1], faceuv[2], faceuv[3])) {
+ return findex_dst;
+ }
+ }
+ else if (isect_point_tri_v2(uv, faceuv[0], faceuv[1], faceuv[2])) {
+ return findex_dst;
}
- else if (isect_point_tri_v2(uv, faceuv[0], faceuv[1], faceuv[2]))
- return findex;
}
}
else { /* if we have no node, try every face */
- for (findex = 0; findex < totface; findex++) {
- const int findex_orig = DM_origindex_mface_mpoly(index_mf_to_mpoly, index_mp_to_orig, findex);
- if (findex_orig == index) {
- faceuv = osface[findex].uv;
- quad = (mpoly[findex].totloop == 4);
+ for (int findex_dst = 0; findex_dst < totface_final; findex_dst++) {
+ /* If current tessface from 'final' DM and orig tessface (given by index) map to the same orig poly... */
+ if (DM_origindex_mface_mpoly(index_mf_to_mpoly, index_mp_to_orig, findex_dst) == pindex_orig) {
+ faceuv = osface_final[findex_dst].uv;
/* check that this intersects - Its possible this misses :/ -
* could also check its not between */
- if (quad) {
- if (isect_point_quad_v2(uv, faceuv[0], faceuv[1], faceuv[2], faceuv[3]))
- return findex;
+ if (mtessface_final[findex_dst].v4) {
+ if (isect_point_quad_v2(uv, faceuv[0], faceuv[1], faceuv[2], faceuv[3])) {
+ return findex_dst;
+ }
+ }
+ else if (isect_point_tri_v2(uv, faceuv[0], faceuv[1], faceuv[2])) {
+ return findex_dst;
}
- else if (isect_point_tri_v2(uv, faceuv[0], faceuv[1], faceuv[2]))
- return findex;
}
}
}
@@ -1523,7 +1569,7 @@ static int psys_map_index_on_dm(DerivedMesh *dm, int from, int index, int index_
}
/* interprets particle data to get a point on a mesh in object space */
-void psys_particle_on_dm(DerivedMesh *dm, int from, int index, int index_dmcache,
+void psys_particle_on_dm(DerivedMesh *dm_final, int from, int index, int index_dmcache,
const float fw[4], float foffset, float vec[3], float nor[3], float utan[3], float vtan[3],
float orco[3], float ornor[3])
{
@@ -1531,7 +1577,7 @@ void psys_particle_on_dm(DerivedMesh *dm, int from, int index, int index_dmcache
float (*orcodata)[3];
int mapindex;
- if (!psys_map_index_on_dm(dm, from, index, index_dmcache, fw, foffset, &mapindex, mapfw)) {
+ if (!psys_map_index_on_dm(dm_final, from, index, index_dmcache, fw, foffset, &mapindex, mapfw)) {
if (vec) { vec[0] = vec[1] = vec[2] = 0.0; }
if (nor) { nor[0] = nor[1] = 0.0; nor[2] = 1.0; }
if (orco) { orco[0] = orco[1] = orco[2] = 0.0; }
@@ -1542,13 +1588,13 @@ void psys_particle_on_dm(DerivedMesh *dm, int from, int index, int index_dmcache
return;
}
- orcodata = dm->getVertDataArray(dm, CD_ORCO);
+ orcodata = dm_final->getVertDataArray(dm_final, CD_ORCO);
if (from == PART_FROM_VERT) {
- dm->getVertCo(dm, mapindex, vec);
+ dm_final->getVertCo(dm_final, mapindex, vec);
if (nor) {
- dm->getVertNo(dm, mapindex, nor);
+ dm_final->getVertNo(dm_final, mapindex, nor);
normalize_v3(nor);
}
@@ -1556,7 +1602,7 @@ void psys_particle_on_dm(DerivedMesh *dm, int from, int index, int index_dmcache
copy_v3_v3(orco, orcodata[mapindex]);
if (ornor) {
- dm->getVertNo(dm, mapindex, ornor);
+ dm_final->getVertNo(dm_final, mapindex, ornor);
normalize_v3(ornor);
}
@@ -1570,9 +1616,9 @@ void psys_particle_on_dm(DerivedMesh *dm, int from, int index, int index_dmcache
MTFace *mtface;
MVert *mvert;
- mface = dm->getTessFaceData(dm, mapindex, CD_MFACE);
- mvert = dm->getVertDataArray(dm, CD_MVERT);
- mtface = CustomData_get_layer(&dm->faceData, CD_MTFACE);
+ mface = dm_final->getTessFaceData(dm_final, mapindex, CD_MFACE);
+ mvert = dm_final->getVertDataArray(dm_final, CD_MVERT);
+ mtface = CustomData_get_layer(&dm_final->faceData, CD_MTFACE);
if (mtface)
mtface += mapindex;
@@ -1689,7 +1735,7 @@ void psys_particle_on_emitter(ParticleSystemModifierData *psmd, int from, int in
float fuv[4], float foffset, float vec[3], float nor[3], float utan[3], float vtan[3],
float orco[3], float ornor[3])
{
- if (psmd && psmd->dm) {
+ if (psmd && psmd->dm_final) {
if (psmd->psys->part->distr == PART_DISTR_GRID && psmd->psys->part->from != PART_FROM_VERT) {
if (vec)
copy_v3_v3(vec, fuv);
@@ -1699,7 +1745,7 @@ void psys_particle_on_emitter(ParticleSystemModifierData *psmd, int from, int in
return;
}
/* we cant use the num_dmcache */
- psys_particle_on_dm(psmd->dm, from, index, index_dmcache, fuv, foffset, vec, nor, utan, vtan, orco, ornor);
+ psys_particle_on_dm(psmd->dm_final, from, index, index_dmcache, fuv, foffset, vec, nor, utan, vtan, orco, ornor);
}
else
psys_particle_on_shape(from, index, fuv, vec, nor, utan, vtan, orco, ornor);
@@ -1971,7 +2017,7 @@ void psys_find_parents(ParticleSimulationData *sim)
psys_particle_on_emitter(sim->psmd, from, cpa->num, DMCACHE_ISCHILD, cpa->fuv, cpa->foffset, co, 0, 0, 0, orco, 0);
/* Check if particle doesn't exist because of texture influence. Insert only existing particles into kdtree. */
- get_cpa_texture(sim->psmd->dm, psys, part, psys->particles + cpa->pa[0], p, cpa->num, cpa->fuv, orco, &ptex, PAMAP_DENS | PAMAP_CHILD, psys->cfra);
+ get_cpa_texture(sim->psmd->dm_final, psys, part, psys->particles + cpa->pa[0], p, cpa->num, cpa->fuv, orco, &ptex, PAMAP_DENS | PAMAP_CHILD, psys->cfra);
if (ptex.exist >= psys_frand(psys, p + 24)) {
BLI_kdtree_insert(tree, p, orco);
@@ -2183,7 +2229,7 @@ static void psys_thread_create_path(ParticleTask *task, struct ChildParticle *cp
for (w = 0; w < 4; w++)
sub_v3_v3v3(off1[w], co, key[w]->co);
- psys_mat_hair_to_global(ob, ctx->sim.psmd->dm, psys->part->from, pa, hairmat);
+ psys_mat_hair_to_global(ob, ctx->sim.psmd->dm_final, psys->part->from, pa, hairmat);
}
else {
ParticleData *pa = psys->particles + cpa->parent;
@@ -2202,13 +2248,13 @@ static void psys_thread_create_path(ParticleTask *task, struct ChildParticle *cp
cpa_from = part->from;
cpa_num = pa->num;
/* XXX hack to avoid messed up particle num and subsequent crash (#40733) */
- if (cpa_num > ctx->sim.psmd->dm->getNumTessFaces(ctx->sim.psmd->dm))
+ if (cpa_num > ctx->sim.psmd->dm_final->getNumTessFaces(ctx->sim.psmd->dm_final))
cpa_num = 0;
cpa_fuv = pa->fuv;
psys_particle_on_emitter(ctx->sim.psmd, cpa_from, cpa_num, DMCACHE_ISCHILD, cpa_fuv, pa->foffset, co, ornor, 0, 0, orco, 0);
- psys_mat_hair_to_global(ob, ctx->sim.psmd->dm, psys->part->from, pa, hairmat);
+ psys_mat_hair_to_global(ob, ctx->sim.psmd->dm_final, psys->part->from, pa, hairmat);
}
child_keys->segments = ctx->segments;
@@ -2501,15 +2547,15 @@ void psys_cache_paths(ParticleSimulationData *sim, float cfra)
if ((psys->flag & PSYS_GLOBAL_HAIR) == 0) {
if ((psys->part->flag & PART_CHILD_EFFECT) == 0)
- vg_effector = psys_cache_vgroup(psmd->dm, psys, PSYS_VG_EFFECTOR);
+ vg_effector = psys_cache_vgroup(psmd->dm_final, psys, PSYS_VG_EFFECTOR);
if (!psys->totchild)
- vg_length = psys_cache_vgroup(psmd->dm, psys, PSYS_VG_LENGTH);
+ vg_length = psys_cache_vgroup(psmd->dm_final, psys, PSYS_VG_LENGTH);
}
/* ensure we have tessfaces to be used for mapping */
if (part->from != PART_FROM_VERT) {
- DM_ensure_tessface(psmd->dm);
+ DM_ensure_tessface(psmd->dm_final);
}
/*---first main loop: create all actual particles' paths---*/
@@ -2518,7 +2564,7 @@ void psys_cache_paths(ParticleSimulationData *sim, float cfra)
psys_get_texture(sim, pa, &ptex, PAMAP_LENGTH, 0.f);
pa_length = ptex.length * (1.0f - part->randlength * psys_frand(psys, psys->seed + p));
if (vg_length)
- pa_length *= psys_particle_value_from_verts(psmd->dm, part->from, pa, vg_length);
+ pa_length *= psys_particle_value_from_verts(psmd->dm_final, part->from, pa, vg_length);
}
pind.keyed = keyed;
@@ -2535,7 +2581,7 @@ void psys_cache_paths(ParticleSimulationData *sim, float cfra)
init_particle_interpolation(sim->ob, sim->psys, pa, &pind);
/* hairmat is needed for for non-hair particle too so we get proper rotations */
- psys_mat_hair_to_global(sim->ob, psmd->dm, psys->part->from, pa, hairmat);
+ psys_mat_hair_to_global(sim->ob, psmd->dm_final, psys->part->from, pa, hairmat);
copy_v3_v3(rotmat[0], hairmat[2]);
copy_v3_v3(rotmat[1], hairmat[1]);
copy_v3_v3(rotmat[2], hairmat[0]);
@@ -2590,7 +2636,7 @@ void psys_cache_paths(ParticleSimulationData *sim, float cfra)
if ((psys->part->flag & PART_CHILD_EFFECT) == 0) {
float effector = 1.0f;
if (vg_effector)
- effector *= psys_particle_value_from_verts(psmd->dm, psys->part->from, pa, vg_effector);
+ effector *= psys_particle_value_from_verts(psmd->dm_final, psys->part->from, pa, vg_effector);
sub_v3_v3v3(vec, (cache[p] + 1)->co, cache[p]->co);
length = len_v3(vec);
@@ -2735,7 +2781,7 @@ void psys_cache_edit_paths(Scene *scene, Object *ob, PTCacheEdit *edit, float cf
init_particle_interpolation(ob, psys, pa, &pind);
if (psys) {
- 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);
copy_v3_v3(rotmat[0], hairmat[2]);
copy_v3_v3(rotmat[1], hairmat[1]);
copy_v3_v3(rotmat[2], hairmat[0]);
@@ -3491,7 +3537,7 @@ void psys_get_texture(ParticleSimulationData *sim, ParticleData *pa, ParticleTex
mul_m4_v3(mtex->object->imat, texvec);
break;
case TEXCO_UV:
- if (get_particle_uv(sim->psmd->dm, pa, 0, pa->fuv, mtex->uvname, texvec))
+ if (get_particle_uv(sim->psmd->dm_final, pa, 0, pa->fuv, mtex->uvname, texvec))
break;
/* no break, failed to get uv's, so let's try orco's */
case TEXCO_ORCO:
@@ -3691,7 +3737,7 @@ void psys_get_particle_on_path(ParticleSimulationData *sim, int p, ParticleKey *
}
else if (!keyed && !cached && !(psys->flag & PSYS_GLOBAL_HAIR)) {
if ((pa->flag & PARS_REKEY) == 0) {
- psys_mat_hair_to_global(sim->ob, sim->psmd->dm, part->from, pa, hairmat);
+ psys_mat_hair_to_global(sim->ob, sim->psmd->dm_final, part->from, pa, hairmat);
mul_m4_v3(hairmat, state->co);
mul_mat3_m4_v3(hairmat, state->vel);
@@ -3758,7 +3804,7 @@ void psys_get_particle_on_path(ParticleSimulationData *sim, int p, ParticleKey *
psys_particle_on_emitter(psmd, part->from, pa->num, pa->num_dmcache, pa->fuv, pa->foffset, par_co, 0, 0, 0, par_orco, 0);
if (part->type == PART_HAIR)
- psys_mat_hair_to_global(sim->ob, sim->psmd->dm, psys->part->from, pa, hairmat);
+ psys_mat_hair_to_global(sim->ob, sim->psmd->dm_final, psys->part->from, pa, hairmat);
else
unit_m4(hairmat);
@@ -3779,7 +3825,7 @@ void psys_get_particle_on_path(ParticleSimulationData *sim, int p, ParticleKey *
psys_particle_on_emitter(psmd, part->from, pa->num, pa->num_dmcache, pa->fuv, pa->foffset, par_co, 0, 0, 0, par_orco, 0);
if (part->type == PART_HAIR) {
psys_particle_on_emitter(psmd, cpa_from, cpa_num, DMCACHE_ISCHILD, cpa_fuv, pa->foffset, co, 0, 0, 0, orco, 0);
- psys_mat_hair_to_global(sim->ob, sim->psmd->dm, psys->part->from, pa, hairmat);
+ psys_mat_hair_to_global(sim->ob, sim->psmd->dm_final, psys->part->from, pa, hairmat);
}
else {
copy_v3_v3(orco, cpa->fuv);
@@ -3798,7 +3844,7 @@ void psys_get_particle_on_path(ParticleSimulationData *sim, int p, ParticleKey *
/* get different child parameters from textures & vgroups */
memset(&ctx, 0, sizeof(ParticleThreadContext));
ctx.sim = *sim;
- ctx.dm = psmd->dm;
+ ctx.dm = psmd->dm_final;
ctx.ma = ma;
/* TODO: assign vertex groups */
get_child_modifier_parameters(part, &ctx, cpa, cpa_from, cpa_num, cpa_fuv, orco, &ptex);
@@ -4026,10 +4072,10 @@ void psys_get_dupli_texture(ParticleSystem *psys, ParticleSettings *part,
uv[0] = uv[1] = 0.f;
if (cpa) {
- if ((part->childtype == PART_CHILD_FACES) && (psmd->dm != NULL)) {
- mtface = CustomData_get_layer(&psmd->dm->faceData, CD_MTFACE);
+ if ((part->childtype == PART_CHILD_FACES) && (psmd->dm_final != NULL)) {
+ mtface = CustomData_get_layer(&psmd->dm_final->faceData, CD_MTFACE);
if (mtface) {
- mface = psmd->dm->getTessFaceData(psmd->dm, cpa->num, CD_MFACE);
+ mface = psmd->dm_final->getTessFaceData(psmd->dm_final, cpa->num, CD_MFACE);
mtface += cpa->num;
psys_interpolate_uvs(mtface, mface->v4, cpa->fuv, uv);
}
@@ -4042,21 +4088,21 @@ void psys_get_dupli_texture(ParticleSystem *psys, ParticleSettings *part,
}
}
- if ((part->from == PART_FROM_FACE) && (psmd->dm != NULL)) {
- mtface = CustomData_get_layer(&psmd->dm->faceData, CD_MTFACE);
+ if ((part->from == PART_FROM_FACE) && (psmd->dm_final != NULL)) {
+ mtface = CustomData_get_layer(&psmd->dm_final->faceData, CD_MTFACE);
num = pa->num_dmcache;
if (num == DMCACHE_NOTFOUND)
num = pa->num;
- if (num >= psmd->dm->getNumTessFaces(psmd->dm)) {
+ if (num >= psmd->dm_final->getNumTessFaces(psmd->dm_final)) {
/* happens when simplify is enabled
* gives invalid coords but would crash otherwise */
num = DMCACHE_NOTFOUND;
}
if (mtface && !ELEM(num, DMCACHE_NOTFOUND, DMCACHE_ISCHILD)) {
- mface = psmd->dm->getTessFaceData(psmd->dm, num, CD_MFACE);
+ mface = psmd->dm_final->getTessFaceData(psmd->dm_final, num, CD_MFACE);
mtface += num;
psys_interpolate_uvs(mtface, mface->v4, pa->fuv, uv);
}
@@ -4231,7 +4277,7 @@ void psys_apply_hair_lattice(Scene *scene, Object *ob, ParticleSystem *psys)
float hairmat[4][4], imat[4][4];
for (p = 0; p < psys->totpart; p++, pa++) {
- psys_mat_hair_to_global(sim.ob, sim.psmd->dm, psys->part->from, pa, hairmat);
+ psys_mat_hair_to_global(sim.ob, sim.psmd->dm_final, psys->part->from, pa, hairmat);
invert_m4_m4(imat, hairmat);
hkey = pa->hair;
diff --git a/source/blender/blenkernel/intern/particle_distribute.c b/source/blender/blenkernel/intern/particle_distribute.c
index 9523ece5f73..9f60cbb88e3 100644
--- a/source/blender/blenkernel/intern/particle_distribute.c
+++ b/source/blender/blenkernel/intern/particle_distribute.c
@@ -79,7 +79,7 @@ static void alloc_child_particles(ParticleSystem *psys, int tot)
}
}
-static void distribute_simple_children(Scene *scene, Object *ob, DerivedMesh *finaldm, ParticleSystem *psys)
+static void distribute_simple_children(Scene *scene, Object *ob, DerivedMesh *finaldm, DerivedMesh *deformdm, ParticleSystem *psys)
{
ChildParticle *cpa = NULL;
int i, p;
@@ -106,7 +106,7 @@ static void distribute_simple_children(Scene *scene, Object *ob, DerivedMesh *fi
}
}
/* dmcache must be updated for parent particles if children from faces is used */
- psys_calc_dmcache(ob, finaldm, psys);
+ psys_calc_dmcache(ob, finaldm, deformdm, psys);
}
static void distribute_grid(DerivedMesh *dm, ParticleSystem *psys)
{
@@ -763,7 +763,7 @@ static void distribute_invalid(Scene *scene, ParticleSystem *psys, int from)
static int psys_thread_context_init_distribute(ParticleThreadContext *ctx, ParticleSimulationData *sim, int from)
{
Scene *scene = sim->scene;
- DerivedMesh *finaldm = sim->psmd->dm;
+ DerivedMesh *finaldm = sim->psmd->dm_final;
Object *ob = sim->ob;
ParticleSystem *psys= sim->psys;
ParticleData *pa=0, *tpars= 0;
@@ -800,7 +800,7 @@ static int psys_thread_context_init_distribute(ParticleThreadContext *ctx, Parti
/* Simple children */
if (part->childtype != PART_CHILD_FACES) {
BLI_srandom(31415926 + psys->seed + psys->child_seed);
- distribute_simple_children(scene, ob, finaldm, psys);
+ distribute_simple_children(scene, ob, finaldm, sim->psmd->dm_deformed, psys);
return 0;
}
}
@@ -1110,7 +1110,7 @@ static void distribute_particles_on_dm(ParticleSimulationData *sim, int from)
TaskPool *task_pool;
ParticleThreadContext ctx;
ParticleTask *tasks;
- DerivedMesh *finaldm = sim->psmd->dm;
+ DerivedMesh *finaldm = sim->psmd->dm_final;
int i, totpart, numtasks;
/* create a task pool for distribution tasks */
@@ -1135,7 +1135,7 @@ static void distribute_particles_on_dm(ParticleSimulationData *sim, int from)
BLI_task_pool_free(task_pool);
- psys_calc_dmcache(sim->ob, finaldm, sim->psys);
+ psys_calc_dmcache(sim->ob, finaldm, sim->psmd->dm_deformed, sim->psys);
if (ctx.dm != finaldm)
ctx.dm->release(ctx.dm);
@@ -1159,7 +1159,7 @@ void distribute_particles(ParticleSimulationData *sim, int from)
int distr_error=0;
if (psmd) {
- if (psmd->dm)
+ if (psmd->dm_final)
distribute_particles_on_dm(sim, from);
else
distr_error=1;
diff --git a/source/blender/blenkernel/intern/particle_system.c b/source/blender/blenkernel/intern/particle_system.c
index 130b56987e2..bf506c8545b 100644
--- a/source/blender/blenkernel/intern/particle_system.c
+++ b/source/blender/blenkernel/intern/particle_system.c
@@ -311,7 +311,7 @@ int psys_get_tot_child(Scene *scene, ParticleSystem *psys)
/* Distribution */
/************************************************/
-void psys_calc_dmcache(Object *ob, DerivedMesh *dm, ParticleSystem *psys)
+void psys_calc_dmcache(Object *ob, DerivedMesh *dm_final, DerivedMesh *dm_deformed, ParticleSystem *psys)
{
/* use for building derived mesh mapping info:
*
@@ -324,13 +324,13 @@ void psys_calc_dmcache(Object *ob, DerivedMesh *dm, ParticleSystem *psys)
PARTICLE_P;
/* CACHE LOCATIONS */
- if (!dm->deformedOnly) {
+ if (!dm_final->deformedOnly) {
/* Will use later to speed up subsurf/derivedmesh */
LinkNode *node, *nodedmelem, **nodearray;
int totdmelem, totelem, i, *origindex, *origindex_poly = NULL;
if (psys->part->from == PART_FROM_VERT) {
- totdmelem= dm->getNumVerts(dm);
+ totdmelem= dm_final->getNumVerts(dm_final);
if (use_modifier_stack) {
totelem= totdmelem;
@@ -338,11 +338,11 @@ void psys_calc_dmcache(Object *ob, DerivedMesh *dm, ParticleSystem *psys)
}
else {
totelem= me->totvert;
- origindex= dm->getVertDataArray(dm, CD_ORIGINDEX);
+ origindex= dm_final->getVertDataArray(dm_final, CD_ORIGINDEX);
}
}
else { /* FROM_FACE/FROM_VOLUME */
- totdmelem= dm->getNumTessFaces(dm);
+ totdmelem= dm_final->getNumTessFaces(dm_final);
if (use_modifier_stack) {
totelem= totdmelem;
@@ -350,20 +350,20 @@ void psys_calc_dmcache(Object *ob, DerivedMesh *dm, ParticleSystem *psys)
origindex_poly= NULL;
}
else {
- totelem= me->totpoly;
- origindex= dm->getTessFaceDataArray(dm, CD_ORIGINDEX);
+ totelem = dm_deformed->getNumTessFaces(dm_deformed);
+ origindex = dm_final->getTessFaceDataArray(dm_final, CD_ORIGINDEX);
/* for face lookups we need the poly origindex too */
- origindex_poly= dm->getPolyDataArray(dm, CD_ORIGINDEX);
+ origindex_poly= dm_final->getPolyDataArray(dm_final, CD_ORIGINDEX);
if (origindex_poly == NULL) {
origindex= NULL;
}
}
}
-
+
nodedmelem= MEM_callocN(sizeof(LinkNode)*totdmelem, "psys node elems");
nodearray= MEM_callocN(sizeof(LinkNode *)*totelem, "psys node array");
-
+
for (i=0, node=nodedmelem; i<totdmelem; i++, node++) {
int origindex_final;
node->link = SET_INT_IN_POINTER(i);
@@ -392,7 +392,7 @@ void psys_calc_dmcache(Object *ob, DerivedMesh *dm, ParticleSystem *psys)
}
}
}
-
+
/* cache the verts/faces! */
LOOP_PARTICLES {
if (pa->num < 0) {
@@ -414,9 +414,7 @@ void psys_calc_dmcache(Object *ob, DerivedMesh *dm, ParticleSystem *psys)
pa->num_dmcache = DMCACHE_NOTFOUND;
}
else { /* FROM_FACE/FROM_VOLUME */
- /* Note that sometimes the pa->num is over the nodearray size, this is bad, maybe there is a better place to fix this,
- * but for now passing NULL is OK. every face will be searched for the particle so its slower - Campbell */
- pa->num_dmcache= psys_particle_dm_face_lookup(ob, dm, pa->num, pa->fuv, pa->num < totelem ? nodearray[pa->num] : NULL);
+ pa->num_dmcache = psys_particle_dm_face_lookup(dm_final, dm_deformed, pa->num, pa->fuv, nodearray);
}
}
}
@@ -429,8 +427,9 @@ void psys_calc_dmcache(Object *ob, DerivedMesh *dm, ParticleSystem *psys)
* should know to use the num or num_dmcache, set the num_dmcache to
* an invalid value, just in case */
- LOOP_PARTICLES
+ LOOP_PARTICLES {
pa->num_dmcache = DMCACHE_NOTFOUND;
+ }
}
}
@@ -439,7 +438,7 @@ void psys_thread_context_init(ParticleThreadContext *ctx, ParticleSimulationData
{
memset(ctx, 0, sizeof(ParticleThreadContext));
ctx->sim = *sim;
- ctx->dm = ctx->sim.psmd->dm;
+ ctx->dm = ctx->sim.psmd->dm_final;
ctx->ma = give_current_material(sim->ob, sim->psys->part->omat);
}
@@ -3054,7 +3053,7 @@ static void hair_create_input_dm(ParticleSimulationData *sim, int totpoint, int
pa->hair_index = hair_index;
use_hair = psys_hair_use_simulation(pa, max_length);
- psys_mat_hair_to_object(sim->ob, sim->psmd->dm, psys->part->from, pa, hairmat);
+ psys_mat_hair_to_object(sim->ob, sim->psmd->dm_final, psys->part->from, pa, hairmat);
mul_m4_m4m4(root_mat, sim->ob->obmat, hairmat);
normalize_m4(root_mat);
@@ -3209,7 +3208,7 @@ static void hair_step(ParticleSimulationData *sim, float cfra)
if (psys->recalc & PSYS_RECALC_RESET) {
/* need this for changing subsurf levels */
- psys_calc_dmcache(sim->ob, sim->psmd->dm, psys);
+ psys_calc_dmcache(sim->ob, sim->psmd->dm_final, sim->psmd->dm_deformed, psys);
if (psys->clmd)
cloth_free_modifier(psys->clmd);
@@ -3256,7 +3255,7 @@ static void save_hair(ParticleSimulationData *sim, float UNUSED(cfra))
if (pa->totkey) {
sub_v3_v3(key->co, root->co);
- psys_vec_rot_to_face(sim->psmd->dm, pa, key->co);
+ psys_vec_rot_to_face(sim->psmd->dm_final, pa, key->co);
}
key->time = pa->state.time;
@@ -4064,11 +4063,11 @@ void particle_system_update(Scene *scene, Object *ob, ParticleSystem *psys)
return;
}
- if (!sim.psmd->dm)
+ if (!sim.psmd->dm_final)
return;
if (part->from != PART_FROM_VERT) {
- DM_ensure_tessface(sim.psmd->dm);
+ DM_ensure_tessface(sim.psmd->dm_final);
}
/* execute drivers only, as animation has already been done */
diff --git a/source/blender/blenlib/BLI_math_vector.h b/source/blender/blenlib/BLI_math_vector.h
index 01c00ddb48e..c51446d6cc8 100644
--- a/source/blender/blenlib/BLI_math_vector.h
+++ b/source/blender/blenlib/BLI_math_vector.h
@@ -149,6 +149,8 @@ MINLINE void negate_v4_v4(float r[4], const float a[3]);
MINLINE void negate_v3_short(short r[3]);
+MINLINE void invert_v2(float r[2]);
+
MINLINE void abs_v2(float r[2]);
MINLINE void abs_v2_v2(float r[2], const float a[2]);
MINLINE void abs_v3(float r[3]);
diff --git a/source/blender/blenlib/intern/math_vector_inline.c b/source/blender/blenlib/intern/math_vector_inline.c
index e625ac18685..17e2da3f1cb 100644
--- a/source/blender/blenlib/intern/math_vector_inline.c
+++ b/source/blender/blenlib/intern/math_vector_inline.c
@@ -633,6 +633,13 @@ MINLINE void negate_v3_short(short r[3])
r[2] = (short)-r[2];
}
+MINLINE void invert_v2(float r[2])
+{
+ BLI_assert(!ELEM(0.0f, r[0], r[1]));
+ r[0] = 1.0f / r[0];
+ r[1] = 1.0f / r[1];
+}
+
MINLINE void abs_v2(float r[2])
{
r[0] = fabsf(r[0]);
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index a3bf673d5fa..86a7b10a378 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -5136,7 +5136,8 @@ static void direct_link_modifiers(FileData *fd, ListBase *lb)
else if (md->type == eModifierType_ParticleSystem) {
ParticleSystemModifierData *psmd = (ParticleSystemModifierData *)md;
- psmd->dm= NULL;
+ psmd->dm_final = NULL;
+ psmd->dm_deformed = NULL;
psmd->psys= newdataadr(fd, psmd->psys);
psmd->flag &= ~eParticleSystemFlag_psys_updated;
psmd->flag |= eParticleSystemFlag_file_loaded;
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,
diff --git a/source/blender/makesdna/DNA_modifier_types.h b/source/blender/makesdna/DNA_modifier_types.h
index 7bd29137aeb..d00e5d574fa 100644
--- a/source/blender/makesdna/DNA_modifier_types.h
+++ b/source/blender/makesdna/DNA_modifier_types.h
@@ -716,7 +716,8 @@ typedef struct ParticleSystemModifierData {
ModifierData modifier;
struct ParticleSystem *psys;
- struct DerivedMesh *dm;
+ struct DerivedMesh *dm_final; /* Final DM - its topology may differ from orig mesh. */
+ struct DerivedMesh *dm_deformed; /* Deformed-onle DM - its topology is same as orig mesh one. */
int totdmvert, totdmedge, totdmface;
short flag, pad;
} ParticleSystemModifierData;
diff --git a/source/blender/makesdna/DNA_particle_types.h b/source/blender/makesdna/DNA_particle_types.h
index 95cb5c84bed..b284a683f8e 100644
--- a/source/blender/makesdna/DNA_particle_types.h
+++ b/source/blender/makesdna/DNA_particle_types.h
@@ -109,6 +109,7 @@ typedef struct ParticleData {
float time, lifetime; /* dietime is not nescessarily time+lifetime as */
float dietime; /* particles can die unnaturally (collision) */
+ /* WARNING! Those two indices, when not affected to vertices, are for !!! TESSELLATED FACES !!!, not POLYGONS! */
int num; /* index to vert/edge/face */
int num_dmcache; /* index to derived mesh data (face) to avoid slow lookups */
diff --git a/source/blender/makesrna/intern/rna_object_api.c b/source/blender/makesrna/intern/rna_object_api.c
index 5645f018cad..ae8b3799bac 100644
--- a/source/blender/makesrna/intern/rna_object_api.c
+++ b/source/blender/makesrna/intern/rna_object_api.c
@@ -167,7 +167,7 @@ static void dupli_render_particle_set(Scene *scene, Object *ob, int level, int e
if (enable)
psys_render_set(ob, psys, mat, mat, 1, 1, 0.f);
else
- psys_render_restore(ob, psys);
+ psys_render_restore(scene, ob, psys);
}
}
diff --git a/source/blender/makesrna/intern/rna_particle.c b/source/blender/makesrna/intern/rna_particle.c
index 8d4be2af533..94b33916cf4 100644
--- a/source/blender/makesrna/intern/rna_particle.c
+++ b/source/blender/makesrna/intern/rna_particle.c
@@ -175,7 +175,7 @@ static void rna_ParticleHairKey_location_object_info(PointerRNA *ptr, ParticleSy
for (md = ob->modifiers.first; md; md = md->next) {
if (md->type == eModifierType_ParticleSystem) {
psmd = (ParticleSystemModifierData *) md;
- if (psmd && psmd->dm && psmd->psys) {
+ if (psmd && psmd->dm_final && psmd->psys) {
psys = psmd->psys;
for (i = 0, pa = psys->particles; i < psys->totpart; i++, pa++) {
/* hairkeys are stored sequentially in memory, so we can
@@ -210,7 +210,7 @@ static void rna_ParticleHairKey_location_object_get(PointerRNA *ptr, float *valu
}
else {
float hairmat[4][4];
- psys_mat_hair_to_object(ob, psmd->dm, psmd->psys->part->from, pa, hairmat);
+ psys_mat_hair_to_object(ob, psmd->dm_final, psmd->psys->part->from, pa, hairmat);
copy_v3_v3(values, hkey->co);
mul_m4_v3(hairmat, values);
}
@@ -240,7 +240,7 @@ static void rna_ParticleHairKey_location_object_set(PointerRNA *ptr, const float
float hairmat[4][4];
float imat[4][4];
- psys_mat_hair_to_object(ob, psmd->dm, psmd->psys->part->from, pa, hairmat);
+ psys_mat_hair_to_object(ob, psmd->dm_final, psmd->psys->part->from, pa, hairmat);
invert_m4_m4(imat, hairmat);
copy_v3_v3(hkey->co, values);
mul_m4_v3(imat, hkey->co);
@@ -263,7 +263,7 @@ static void rna_ParticleHairKey_co_object(HairKey *hairkey, Object *object, Part
}
else {
float hairmat[4][4];
- psys_mat_hair_to_object(object, modifier->dm, modifier->psys->part->from, particle, hairmat);
+ psys_mat_hair_to_object(object, modifier->dm_final, modifier->psys->part->from, particle, hairmat);
copy_v3_v3(n_co, hairkey->co);
mul_m4_v3(hairmat, n_co);
}
@@ -282,14 +282,14 @@ static void rna_Particle_uv_on_emitter(ParticleData *particle, ReportList *repor
int num = particle->num_dmcache;
int from = modifier->psys->part->from;
- if (!CustomData_has_layer(&modifier->dm->loopData, CD_MLOOPUV)) {
+ if (!CustomData_has_layer(&modifier->dm_final->loopData, CD_MLOOPUV)) {
BKE_report(reports, RPT_ERROR, "Mesh has no UV data");
return;
}
- DM_ensure_tessface(modifier->dm); /* BMESH - UNTIL MODIFIER IS UPDATED FOR MPoly */
+ DM_ensure_tessface(modifier->dm_final); /* BMESH - UNTIL MODIFIER IS UPDATED FOR MPoly */
if (num == DMCACHE_NOTFOUND)
- if (particle->num < modifier->dm->getNumTessFaces(modifier->dm))
+ if (particle->num < modifier->dm_final->getNumTessFaces(modifier->dm_final))
num = particle->num;
/* get uvco */
@@ -299,8 +299,8 @@ static void rna_Particle_uv_on_emitter(ParticleData *particle, ReportList *repor
MFace *mface;
MTFace *mtface;
- mface = modifier->dm->getTessFaceData(modifier->dm, num, CD_MFACE);
- mtface = (MTFace *)CustomData_get_layer_n(&modifier->dm->faceData, CD_MTFACE, 0);
+ mface = modifier->dm_final->getTessFaceData(modifier->dm_final, num, CD_MFACE);
+ mtface = (MTFace *)CustomData_get_layer_n(&modifier->dm_final->faceData, CD_MTFACE, 0);
if (mface && mtface) {
mtface += num;
@@ -446,8 +446,8 @@ static int rna_ParticleSystem_tessfaceidx_on_emitter(ParticleSystem *particlesys
int totface;
int num = -1;
- DM_ensure_tessface(modifier->dm); /* BMESH - UNTIL MODIFIER IS UPDATED FOR MPoly */
- totface = modifier->dm->getNumTessFaces(modifier->dm);
+ DM_ensure_tessface(modifier->dm_final); /* BMESH - UNTIL MODIFIER IS UPDATED FOR MPoly */
+ totface = modifier->dm_final->getNumTessFaces(modifier->dm_final);
/* 1. check that everything is ok & updated */
if (!particlesystem || !totface) {
@@ -476,9 +476,6 @@ static int rna_ParticleSystem_tessfaceidx_on_emitter(ParticleSystem *particlesys
if (particle_no < totpart) {
num = (ELEM(particle->num_dmcache, DMCACHE_ISCHILD, DMCACHE_NOTFOUND)) ? particle->num : particle->num_dmcache;
- if (num == DMCACHE_NOTFOUND)
- num = particle->num;
-
if (ELEM(part->from, PART_FROM_FACE, PART_FROM_VOLUME)) {
if (num != DMCACHE_NOTFOUND && num < totface) {
*r_fuv = &particle->fuv;
@@ -521,7 +518,7 @@ static void rna_ParticleSystem_uv_on_emitter(ParticleSystem *particlesystem, Rep
ParticleSystemModifierData *modifier, ParticleData *particle,
int particle_no, int uv_no, float r_uv[2])
{
- if (!CustomData_has_layer(&modifier->dm->loopData, CD_MLOOPUV)) {
+ if (!CustomData_has_layer(&modifier->dm_final->loopData, CD_MLOOPUV)) {
BKE_report(reports, RPT_ERROR, "Mesh has no UV data");
zero_v2(r_uv);
return;
@@ -538,8 +535,8 @@ static void rna_ParticleSystem_uv_on_emitter(ParticleSystem *particlesystem, Rep
zero_v2(r_uv);
}
else {
- MFace *mface = modifier->dm->getTessFaceData(modifier->dm, num, CD_MFACE);
- MTFace *mtface = (MTFace *)CustomData_get_layer_n(&modifier->dm->faceData, CD_MTFACE, uv_no);
+ MFace *mface = modifier->dm_final->getTessFaceData(modifier->dm_final, num, CD_MFACE);
+ MTFace *mtface = (MTFace *)CustomData_get_layer_n(&modifier->dm_final->faceData, CD_MTFACE, uv_no);
psys_interpolate_uvs(&mtface[num], mface->v4, *fuv, r_uv);
}
@@ -550,7 +547,7 @@ static void rna_ParticleSystem_mcol_on_emitter(ParticleSystem *particlesystem, R
ParticleSystemModifierData *modifier, ParticleData *particle,
int particle_no, int vcol_no, float r_mcol[3])
{
- if (!CustomData_has_layer(&modifier->dm->loopData, CD_MLOOPCOL)) {
+ if (!CustomData_has_layer(&modifier->dm_final->loopData, CD_MLOOPCOL)) {
BKE_report(reports, RPT_ERROR, "Mesh has no VCol data");
zero_v3(r_mcol);
return;
@@ -567,8 +564,8 @@ static void rna_ParticleSystem_mcol_on_emitter(ParticleSystem *particlesystem, R
zero_v3(r_mcol);
}
else {
- MFace *mface = modifier->dm->getTessFaceData(modifier->dm, num, CD_MFACE);
- MCol *mc = (MCol *)CustomData_get_layer_n(&modifier->dm->faceData, CD_MCOL, vcol_no);
+ MFace *mface = modifier->dm_final->getTessFaceData(modifier->dm_final, num, CD_MFACE);
+ MCol *mc = (MCol *)CustomData_get_layer_n(&modifier->dm_final->faceData, CD_MCOL, vcol_no);
MCol mcol;
psys_interpolate_mcol(&mc[num * 4], mface->v4, *fuv, &mcol);
@@ -595,7 +592,7 @@ static void rna_ParticleSystem_set_resolution(ParticleSystem *particlesystem, Sc
ParticleSystemModifierData *psmd = psys_get_modifier(object, particlesystem);
if (particlesystem->renderdata) {
- psys_render_restore(object, particlesystem);
+ psys_render_restore(scene, object, particlesystem);
}
psmd->flag &= ~eParticleSystemFlag_psys_updated;
diff --git a/source/blender/modifiers/intern/MOD_explode.c b/source/blender/modifiers/intern/MOD_explode.c
index d57ace8d7fe..1ac18858f56 100644
--- a/source/blender/modifiers/intern/MOD_explode.c
+++ b/source/blender/modifiers/intern/MOD_explode.c
@@ -1006,7 +1006,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob,
if (psys == NULL || psys->totpart == 0) return derivedData;
if (psys->part == NULL || psys->particles == NULL) return derivedData;
- if (psmd->dm == NULL) return derivedData;
+ if (psmd->dm_final== NULL) return derivedData;
/* 1. find faces to be exploded if needed */
if (emd->facepa == NULL ||
diff --git a/source/blender/modifiers/intern/MOD_particleinstance.c b/source/blender/modifiers/intern/MOD_particleinstance.c
index 289611ad90a..4e78e758dc3 100644
--- a/source/blender/modifiers/intern/MOD_particleinstance.c
+++ b/source/blender/modifiers/intern/MOD_particleinstance.c
@@ -351,7 +351,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob,
ChildParticle *cpa = psys->child + (p - psys->totpart);
pa = psys->particles + cpa->parent;
}
- psys_mat_hair_to_global(sim.ob, sim.psmd->dm, sim.psys->part->from, pa, hairmat);
+ psys_mat_hair_to_global(sim.ob, sim.psmd->dm_final, sim.psys->part->from, pa, hairmat);
copy_m3_m4(mat, hairmat);
/* to quaternion */
mat3_to_quat(frame, mat);
diff --git a/source/blender/modifiers/intern/MOD_particlesystem.c b/source/blender/modifiers/intern/MOD_particlesystem.c
index de1b11eddd9..6b2b999d596 100644
--- a/source/blender/modifiers/intern/MOD_particlesystem.c
+++ b/source/blender/modifiers/intern/MOD_particlesystem.c
@@ -51,17 +51,23 @@ static void initData(ModifierData *md)
{
ParticleSystemModifierData *psmd = (ParticleSystemModifierData *) md;
psmd->psys = NULL;
- psmd->dm = NULL;
+ psmd->dm_final = NULL;
+ psmd->dm_deformed = NULL;
psmd->totdmvert = psmd->totdmedge = psmd->totdmface = 0;
}
static void freeData(ModifierData *md)
{
ParticleSystemModifierData *psmd = (ParticleSystemModifierData *) md;
- if (psmd->dm) {
- psmd->dm->needsFree = 1;
- psmd->dm->release(psmd->dm);
- psmd->dm = NULL;
+ if (psmd->dm_final) {
+ psmd->dm_final->needsFree = 1;
+ psmd->dm_final->release(psmd->dm_final);
+ psmd->dm_final = NULL;
+ if (psmd->dm_deformed) {
+ psmd->dm_deformed->needsFree = 1;
+ psmd->dm_deformed->release(psmd->dm_deformed);
+ psmd->dm_deformed = NULL;
+ }
}
/* ED_object_modifier_remove may have freed this first before calling
@@ -78,7 +84,8 @@ static void copyData(ModifierData *md, ModifierData *target)
modifier_copyData_generic(md, target);
- tpsmd->dm = NULL;
+ tpsmd->dm_final = NULL;
+ tpsmd->dm_deformed = NULL;
tpsmd->totdmvert = tpsmd->totdmedge = tpsmd->totdmface = 0;
}
@@ -119,9 +126,14 @@ static void deformVerts(ModifierData *md, Object *ob,
}
/* clear old dm */
- if (psmd->dm) {
- psmd->dm->needsFree = 1;
- psmd->dm->release(psmd->dm);
+ if (psmd->dm_final) {
+ psmd->dm_final->needsFree = 1;
+ psmd->dm_final->release(psmd->dm_final);
+ if (psmd->dm_deformed) {
+ psmd->dm_deformed->needsFree = 1;
+ psmd->dm_deformed->release(psmd->dm_deformed);
+ psmd->dm_deformed = NULL;
+ }
}
else if (psmd->flag & eParticleSystemFlag_file_loaded) {
/* in file read dm just wasn't saved in file so no need to reset everything */
@@ -133,9 +145,9 @@ static void deformVerts(ModifierData *md, Object *ob,
}
/* make new dm */
- psmd->dm = CDDM_copy(dm);
- CDDM_apply_vert_coords(psmd->dm, vertexCos);
- CDDM_calc_normals(psmd->dm);
+ psmd->dm_final = CDDM_copy(dm);
+ CDDM_apply_vert_coords(psmd->dm_final, vertexCos);
+ CDDM_calc_normals(psmd->dm_final);
if (needsFree) {
dm->needsFree = 1;
@@ -143,19 +155,27 @@ static void deformVerts(ModifierData *md, Object *ob,
}
/* protect dm */
- psmd->dm->needsFree = 0;
+ psmd->dm_final->needsFree = 0;
+
+ DM_ensure_tessface(psmd->dm_final);
+
+ if (!psmd->dm_final->deformedOnly) {
+ /* XXX Think we can assume here that if current DM is not only-deformed, ob->deformedOnly has been set.
+ * This is awfully weak though. :| */
+ psmd->dm_deformed = CDDM_copy(ob->derivedDeform);
+ DM_ensure_tessface(psmd->dm_deformed);
+ }
/* report change in mesh structure */
- DM_ensure_tessface(psmd->dm);
- if (psmd->dm->getNumVerts(psmd->dm) != psmd->totdmvert ||
- psmd->dm->getNumEdges(psmd->dm) != psmd->totdmedge ||
- psmd->dm->getNumTessFaces(psmd->dm) != psmd->totdmface)
+ if (psmd->dm_final->getNumVerts(psmd->dm_final) != psmd->totdmvert ||
+ psmd->dm_final->getNumEdges(psmd->dm_final) != psmd->totdmedge ||
+ psmd->dm_final->getNumTessFaces(psmd->dm_final) != psmd->totdmface)
{
psys->recalc |= PSYS_RECALC_RESET;
- psmd->totdmvert = psmd->dm->getNumVerts(psmd->dm);
- psmd->totdmedge = psmd->dm->getNumEdges(psmd->dm);
- psmd->totdmface = psmd->dm->getNumTessFaces(psmd->dm);
+ psmd->totdmvert = psmd->dm_final->getNumVerts(psmd->dm_final);
+ psmd->totdmedge = psmd->dm_final->getNumEdges(psmd->dm_final);
+ psmd->totdmface = psmd->dm_final->getNumTessFaces(psmd->dm_final);
}
if (!(ob->transflag & OB_NO_PSYS_UPDATE)) {
diff --git a/source/blender/render/intern/source/convertblender.c b/source/blender/render/intern/source/convertblender.c
index 820e129b0ce..69e45fea74d 100644
--- a/source/blender/render/intern/source/convertblender.c
+++ b/source/blender/render/intern/source/convertblender.c
@@ -1392,16 +1392,16 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem
re->flag |= R_HALO;
- RE_set_customdata_names(obr, &psmd->dm->faceData);
- sd.totuv = CustomData_number_of_layers(&psmd->dm->faceData, CD_MTFACE);
- sd.totcol = CustomData_number_of_layers(&psmd->dm->faceData, CD_MCOL);
+ RE_set_customdata_names(obr, &psmd->dm_final->faceData);
+ sd.totuv = CustomData_number_of_layers(&psmd->dm_final->faceData, CD_MTFACE);
+ sd.totcol = CustomData_number_of_layers(&psmd->dm_final->faceData, CD_MCOL);
if (ma->texco & TEXCO_UV && sd.totuv) {
sd.uvco = MEM_callocN(sd.totuv * 2 * sizeof(float), "particle_uvs");
if (ma->strand_uvname[0]) {
- sd.override_uv = CustomData_get_named_layer_index(&psmd->dm->faceData, CD_MTFACE, ma->strand_uvname);
- sd.override_uv -= CustomData_get_layer_index(&psmd->dm->faceData, CD_MTFACE);
+ sd.override_uv = CustomData_get_named_layer_index(&psmd->dm_final->faceData, CD_MTFACE, ma->strand_uvname);
+ sd.override_uv -= CustomData_get_layer_index(&psmd->dm_final->faceData, CD_MTFACE);
}
}
else
@@ -1412,15 +1412,15 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem
/* 2.2 setup billboards */
if (part->ren_as == PART_DRAW_BB) {
- int first_uv = CustomData_get_layer_index(&psmd->dm->faceData, CD_MTFACE);
+ int first_uv = CustomData_get_layer_index(&psmd->dm_final->faceData, CD_MTFACE);
- bb.uv[0] = CustomData_get_named_layer_index(&psmd->dm->faceData, CD_MTFACE, psys->bb_uvname[0]);
+ bb.uv[0] = CustomData_get_named_layer_index(&psmd->dm_final->faceData, CD_MTFACE, psys->bb_uvname[0]);
if (bb.uv[0] < 0)
- bb.uv[0] = CustomData_get_active_layer_index(&psmd->dm->faceData, CD_MTFACE);
+ bb.uv[0] = CustomData_get_active_layer_index(&psmd->dm_final->faceData, CD_MTFACE);
- bb.uv[1] = CustomData_get_named_layer_index(&psmd->dm->faceData, CD_MTFACE, psys->bb_uvname[1]);
+ bb.uv[1] = CustomData_get_named_layer_index(&psmd->dm_final->faceData, CD_MTFACE, psys->bb_uvname[1]);
- bb.uv[2] = CustomData_get_named_layer_index(&psmd->dm->faceData, CD_MTFACE, psys->bb_uvname[2]);
+ bb.uv[2] = CustomData_get_named_layer_index(&psmd->dm_final->faceData, CD_MTFACE, psys->bb_uvname[2]);
if (first_uv >= 0) {
bb.uv[0] -= first_uv;
@@ -1500,9 +1500,9 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem
if (ma->amb != 0.0f)
do_surfacecache = true;
- totface= psmd->dm->getNumTessFaces(psmd->dm);
- index_mf_to_mpoly = psmd->dm->getTessFaceDataArray(psmd->dm, CD_ORIGINDEX);
- index_mp_to_orig = psmd->dm->getPolyDataArray(psmd->dm, CD_ORIGINDEX);
+ totface= psmd->dm_final->getNumTessFaces(psmd->dm_final);
+ index_mf_to_mpoly = psmd->dm_final->getTessFaceDataArray(psmd->dm_final, CD_ORIGINDEX);
+ index_mp_to_orig = psmd->dm_final->getPolyDataArray(psmd->dm_final, CD_ORIGINDEX);
if (index_mf_to_mpoly == NULL) {
index_mp_to_orig = NULL;
}
@@ -1557,10 +1557,10 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem
num= pa->num_dmcache;
if (num == DMCACHE_NOTFOUND)
- if (pa->num < psmd->dm->getNumTessFaces(psmd->dm))
+ if (pa->num < psmd->dm_final->getNumTessFaces(psmd->dm_final))
num= pa->num;
- get_particle_uvco_mcol(part->from, psmd->dm, pa->fuv, num, &sd);
+ get_particle_uvco_mcol(part->from, psmd->dm_final, pa->fuv, num, &sd);
pa_size = pa->size;
@@ -1611,17 +1611,17 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem
/* get uvco & mcol */
if (part->childtype==PART_CHILD_FACES) {
- get_particle_uvco_mcol(PART_FROM_FACE, psmd->dm, cpa->fuv, cpa->num, &sd);
+ get_particle_uvco_mcol(PART_FROM_FACE, psmd->dm_final, cpa->fuv, cpa->num, &sd);
}
else {
ParticleData *parent = psys->particles + cpa->parent;
num = parent->num_dmcache;
if (num == DMCACHE_NOTFOUND)
- if (parent->num < psmd->dm->getNumTessFaces(psmd->dm))
+ if (parent->num < psmd->dm_final->getNumTessFaces(psmd->dm_final))
num = parent->num;
- get_particle_uvco_mcol(part->from, psmd->dm, parent->fuv, num, &sd);
+ get_particle_uvco_mcol(part->from, psmd->dm_final, parent->fuv, num, &sd);
}
do_simplify = psys_render_simplify_params(psys, cpa, simplify);
@@ -1737,14 +1737,14 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem
sub_v3_v3v3(loc0, loc1, loc);
add_v3_v3v3(loc0, loc1, loc0);
- particle_curve(re, obr, psmd->dm, ma, &sd, loc1, loc0, seed, pa_co);
+ particle_curve(re, obr, psmd->dm_final, ma, &sd, loc1, loc0, seed, pa_co);
}
sd.first = 0;
sd.time = time;
if (k)
- particle_curve(re, obr, psmd->dm, ma, &sd, loc, loc1, seed, pa_co);
+ particle_curve(re, obr, psmd->dm_final, ma, &sd, loc, loc1, seed, pa_co);
copy_v3_v3(loc1, loc);
}
@@ -1803,7 +1803,7 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem
pa_co[0] = (part->draw & PART_ABS_PATH_TIME) ? (ct-pa_birthtime)/(pa_dietime-pa_birthtime) : ct;
pa_co[1] = (float)i/(float)(trail_count-1);
- particle_normal_ren(part->ren_as, part, re, obr, psmd->dm, ma, &sd, &bb, &state, seed, hasize, pa_co);
+ particle_normal_ren(part->ren_as, part, re, obr, psmd->dm_final, ma, &sd, &bb, &state, seed, hasize, pa_co);
}
}
else {
@@ -1839,7 +1839,7 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem
bb.lifetime = pa_dietime-pa_birthtime;
}
- particle_normal_ren(part->ren_as, part, re, obr, psmd->dm, ma, &sd, &bb, &state, seed, hasize, pa_co);
+ particle_normal_ren(part->ren_as, part, re, obr, psmd->dm_final, ma, &sd, &bb, &state, seed, hasize, pa_co);
}
}
@@ -1851,7 +1851,7 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem
}
if (do_surfacecache)
- strandbuf->surface= cache_strand_surface(re, obr, psmd->dm, mat, timeoffset);
+ strandbuf->surface= cache_strand_surface(re, obr, psmd->dm_final, mat, timeoffset);
/* 4. clean up */
#if 0 /* XXX old animation system */
@@ -4688,7 +4688,7 @@ static void add_render_object(Render *re, Object *ob, Object *par, DupliObject *
psys->flag |= PSYS_USE_IMAT;
init_render_object_data(re, obr, timeoffset);
if (!(re->r.scemode & R_VIEWPORT_PREVIEW))
- psys_render_restore(ob, psys);
+ psys_render_restore(re->scene, ob, psys);
psys->flag &= ~PSYS_USE_IMAT;
/* only add instance for objects that have not been used for dupli */
@@ -4888,7 +4888,7 @@ static void dupli_render_particle_set(Render *re, Object *ob, int timeoffset, in
if (enable)
psys_render_set(ob, psys, re->viewmat, re->winmat, re->winx, re->winy, timeoffset);
else
- psys_render_restore(ob, psys);
+ psys_render_restore(re->scene, ob, psys);
}
}
diff --git a/source/blender/render/intern/source/pointdensity.c b/source/blender/render/intern/source/pointdensity.c
index 4028d80fd86..756801a82e8 100644
--- a/source/blender/render/intern/source/pointdensity.c
+++ b/source/blender/render/intern/source/pointdensity.c
@@ -157,7 +157,7 @@ static void pointdensity_cache_psys(Scene *scene,
}
if ( !psys_check_enabled(ob, psys)) {
- psys_render_restore(ob, psys);
+ psys_render_restore(scene, ob, psys);
return;
}
@@ -253,7 +253,7 @@ static void pointdensity_cache_psys(Scene *scene,
}
if (use_render_params) {
- psys_render_restore(ob, psys);
+ psys_render_restore(scene, ob, psys);
}
}
@@ -711,7 +711,7 @@ static void particle_system_minmax(Scene *scene,
}
if (use_render_params) {
- psys_render_restore(object, psys);
+ psys_render_restore(scene, object, psys);
}
}
diff --git a/source/blenderplayer/bad_level_call_stubs/stubs.c b/source/blenderplayer/bad_level_call_stubs/stubs.c
index 458d883666e..5748b9e3225 100644
--- a/source/blenderplayer/bad_level_call_stubs/stubs.c
+++ b/source/blenderplayer/bad_level_call_stubs/stubs.c
@@ -498,8 +498,8 @@ void ED_object_constraint_tag_update(struct Object *ob, struct bConstraint *con)
void ED_vgroup_vert_add(struct Object *ob, struct bDeformGroup *dg, int vertnum, float weight, int assignmode) RET_NONE
void ED_vgroup_vert_remove(struct Object *ob, struct bDeformGroup *dg, int vertnum) RET_NONE
float ED_vgroup_vert_weight(struct Object *ob, struct bDeformGroup *dg, int vertnum) RET_ZERO
-int ED_mesh_mirror_topo_table(struct Object *ob, char mode) RET_ZERO
-int ED_mesh_mirror_spatial_table(struct Object *ob, struct BMEditMesh *em, const float co[3], char mode) RET_ZERO
+int ED_mesh_mirror_topo_table(struct Object *ob, struct DerivedMesh *dm, char mode) RET_ZERO
+int ED_mesh_mirror_spatial_table(struct Object *ob, struct BMEditMesh *em, struct DerivedMesh *dm, const float co[3], char mode) RET_ZERO
float ED_rollBoneToVector(EditBone *bone, const float new_up_axis[3], const bool axis_only) RET_ZERO
void ED_space_image_get_size(struct SpaceImage *sima, int *width, int *height) RET_NONE