Commit: aad24468e2d32d46e2c3b3b4a37302a4f1f27ab6
Author: Bastien Montagne
Date:   Mon Jan 4 12:19:45 2016 +0100
Branches: master
https://developer.blender.org/rBaad24468e2d32d46e2c3b3b4a37302a4f1f27ab6

Fix T47038: Particles in Particle Edit Mode get added in completely wrong 
location.

It also fixes another issue (crash) related to symmetric editing.

Quite involved, we (try to!) fix complete broken logic of parts of particle 
code, which would use poly index
as tessface one (or vice-versa). Issue most probably goes back to BMesh 
integration time...

This patch mostly fixes particle editing mode:
  - Adding/removing particles when using generative modifiers (like subsurf) 
should now work.
  - Adding/removing particles with a non-tessellated mesh (i.e. one having 
ngons) should also mostly work.
  - X-axis-mirror-editing particles over ngons does not really work, not sure 
why currently.
  - All this in both 'modes' (with or without using modifier stack for 
particles).

Tech side:
  - Store a deformed-only DM in particle modifier data.
  - Rename existing DM to make it clear it's a final one.
  - Use deformed-only DM's tessface2poly mapping to 'solve' poly/tessface 
mismatches.
  - Make (part of) mirror-editing code able to use a DM instead of raw mesh, so 
that we can mirror based on final DM
    when editing particles using modifier stack (mandatory, since there is no 
way currently to find orig tessface
    from an final DM tessface index).

Note that this patch is not really nice and clean (current particles are beyond 
hope on this side anyway),
it's more like some urgency bandage. Whole crap needs complete rewrite anyway,
BMesh's polygons make it really hard to work with current system (and looptri 
would not help much here).

Also, did not test everything possibly affected by those changes, so it needs 
some users' testing & validation too.

Reviewers: psy-fi

Subscribers: dfelinto, eyecandy

Maniphest Tasks: T47038

Differential Revision: https://developer.blender.org/D1685

===================================================================

M       source/blender/blenkernel/BKE_particle.h
M       source/blender/blenkernel/intern/DerivedMesh.c
M       source/blender/blenkernel/intern/object.c
M       source/blender/blenkernel/intern/particle.c
M       source/blender/blenkernel/intern/particle_distribute.c
M       source/blender/blenkernel/intern/particle_system.c
M       source/blender/blenlib/BLI_math_vector.h
M       source/blender/blenlib/intern/math_vector_inline.c
M       source/blender/blenloader/intern/readfile.c
M       source/blender/editors/armature/armature_skinning.c
M       source/blender/editors/armature/meshlaplacian.c
M       source/blender/editors/include/ED_mesh.h
M       source/blender/editors/mesh/editface.c
M       source/blender/editors/mesh/editmesh_utils.c
M       source/blender/editors/mesh/meshtools.c
M       source/blender/editors/object/object_edit.c
M       source/blender/editors/object/object_shapekey.c
M       source/blender/editors/object/object_vgroup.c
M       source/blender/editors/physics/particle_edit.c
M       source/blender/editors/physics/particle_object.c
M       source/blender/editors/sculpt_paint/paint_vertex.c
M       source/blender/editors/transform/transform_conversions.c
M       source/blender/editors/util/ed_util.c
M       source/blender/makesdna/DNA_modifier_types.h
M       source/blender/makesdna/DNA_particle_types.h
M       source/blender/makesrna/intern/rna_object_api.c
M       source/blender/makesrna/intern/rna_particle.c
M       source/blender/modifiers/intern/MOD_explode.c
M       source/blender/modifiers/intern/MOD_particleinstance.c
M       source/blender/modifiers/intern/MOD_particlesystem.c
M       source/blender/render/intern/source/convertblender.c
M       source/blender/render/intern/source/pointdensity.c
M       source/blenderplayer/bad_level_call_stubs/stubs.c

===================================================================

diff --git a/source/blender/blenkernel/BKE_particle.h 
b/source/blender/blenkernel/BKE_particle.h
index 00cc48c..ed45375 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 e26e514..9fc4383 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 89f22b8..b448bec 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 b3be567..39f0e7c 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_

@@ Diff output truncated at 10240 characters. @@

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
http://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to