Revision: 16841
          
http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=16841
Author:   blendix
Date:     2008-09-30 08:12:47 +0200 (Tue, 30 Sep 2008)

Log Message:
-----------
Fix for bug #17302: subsurf + particle size vertex groups did not
work correct, also refactored some code here to make it more clear.

Modified Paths:
--------------
    trunk/blender/source/blender/blenkernel/BKE_particle.h
    trunk/blender/source/blender/blenkernel/intern/modifier.c
    trunk/blender/source/blender/blenkernel/intern/particle.c
    trunk/blender/source/blender/blenkernel/intern/particle_system.c
    trunk/blender/source/blender/render/intern/source/convertblender.c
    trunk/blender/source/blender/src/editparticle.c

Modified: trunk/blender/source/blender/blenkernel/BKE_particle.h
===================================================================
--- trunk/blender/source/blender/blenkernel/BKE_particle.h      2008-09-30 
05:51:51 UTC (rev 16840)
+++ trunk/blender/source/blender/blenkernel/BKE_particle.h      2008-09-30 
06:12:47 UTC (rev 16841)
@@ -226,7 +226,7 @@
 
 void copy_particle_key(struct ParticleKey *to, struct ParticleKey *from, int 
time);
 
-void psys_particle_on_emitter(struct Object *ob, struct 
ParticleSystemModifierData *psmd, int distr, int index, int index_dmcache, 
float *fuv, float foffset, float *vec, float *nor, float *utan, float *vtan, 
float *orco, float *ornor);
+void psys_particle_on_emitter(struct ParticleSystemModifierData *psmd, int 
distr, int index, int index_dmcache, float *fuv, float foffset, float *vec, 
float *nor, float *utan, float *vtan, float *orco, float *ornor);
 struct ParticleSystemModifierData *psys_get_modifier(struct Object *ob, struct 
ParticleSystem *psys);
 
 struct ParticleSettings *psys_new_settings(char *name, struct Main *main);
@@ -284,11 +284,12 @@
 float *psys_cache_vgroup(struct DerivedMesh *dm, struct ParticleSystem *psys, 
int vgroup);
 void psys_get_texture(struct Object *ob, struct Material *ma, struct 
ParticleSystemModifierData *psmd, struct ParticleSystem *psys, struct 
ParticleData *pa, struct ParticleTexture *ptex, int event);
 void psys_interpolate_face(struct MVert *mvert, struct MFace *mface, struct 
MTFace *tface, float (*orcodata)[3], float *uv, float *vec, float *nor, float 
*utan, float *vtan, float *orco, float *ornor);
+float psys_particle_value_from_verts(struct DerivedMesh *dm, short from, 
struct ParticleData *pa, float *values);
 float psys_interpolate_value_from_verts(struct DerivedMesh *dm, short from, 
int index, float *fw, float *values);
 void psys_get_from_key(struct ParticleKey *key, float *loc, float *vel, float 
*rot, float *time);
 
 int psys_intersect_dm(struct Object *ob, struct DerivedMesh *dm, float 
*vert_cos, float *co1, float* co2, float *min_d, int *min_face, float *min_uv, 
float *face_minmax, float *pa_minmax, float radius, float *ipoint);
-void psys_particle_on_dm(struct Object *ob, struct DerivedMesh *dm, int from, 
int index, int index_dmcache, float *fw, float foffset, float *vec, float *nor, 
float *utan, float *vtan, float *orco, float *ornor);
+void psys_particle_on_dm(struct DerivedMesh *dm, int from, int index, int 
index_dmcache, float *fw, float foffset, float *vec, float *nor, float *utan, 
float *vtan, float *orco, float *ornor);
 
 /* particle_system.c */
 void initialize_particle(struct ParticleData *pa, int p, struct Object *ob, 
struct ParticleSystem *psys, struct ParticleSystemModifierData *psmd);

Modified: trunk/blender/source/blender/blenkernel/intern/modifier.c
===================================================================
--- trunk/blender/source/blender/blenkernel/intern/modifier.c   2008-09-30 
05:51:51 UTC (rev 16840)
+++ trunk/blender/source/blender/blenkernel/intern/modifier.c   2008-09-30 
06:12:47 UTC (rev 16841)
@@ -6543,7 +6543,7 @@
        /* make tree of emitter locations */
        tree=BLI_kdtree_new(totpart);
        for(p=0,pa=psys->particles; p<totpart; p++,pa++){
-               
psys_particle_on_dm(ob,psmd->dm,psys->part->from,pa->num,pa->num_dmcache,pa->fuv,pa->foffset,co,0,0,0,0,0);
+               
psys_particle_on_dm(psmd->dm,psys->part->from,pa->num,pa->num_dmcache,pa->fuv,pa->foffset,co,0,0,0,0,0);
                BLI_kdtree_insert(tree, p, co, NULL);
        }
        BLI_kdtree_balance(tree);
@@ -7146,7 +7146,7 @@
                        pa= pars+i;
 
                        /* get particle state */
-                       psys_particle_on_emitter(ob, 
psmd,part->from,pa->num,-1,pa->fuv,pa->foffset,loc0,nor,0,0,0,0);
+                       
psys_particle_on_emitter(psmd,part->from,pa->num,-1,pa->fuv,pa->foffset,loc0,nor,0,0,0,0);
                        Mat4MulVecfl(ob->obmat,loc0);
 
                        state.time=cfra;

Modified: trunk/blender/source/blender/blenkernel/intern/particle.c
===================================================================
--- trunk/blender/source/blender/blenkernel/intern/particle.c   2008-09-30 
05:51:51 UTC (rev 16840)
+++ trunk/blender/source/blender/blenkernel/intern/particle.c   2008-09-30 
06:12:47 UTC (rev 16841)
@@ -1117,8 +1117,8 @@
        }
 }
 
-/* find the derived mesh face for a particle, set the mf passed.
-This is slow, can be optimized but only for many lookups, return the face 
lookup index*/
+/* 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, float 
*fw, struct LinkNode *node)
 {
        Mesh *me= (Mesh*)ob->data;
@@ -1186,169 +1186,143 @@
        return DMCACHE_NOTFOUND;
 }
 
-/* interprets particle data to get a point on a mesh in object space */
-#define PARTICLE_ON_DM_ERROR \
-       { 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; } \
-         if(ornor) { ornor[0]=ornor[1]=0.0; ornor[2]=1.0; } \
-         if(utan) { utan[0]=utan[1]=utan[2]=0.0; } \
-         if(vtan) { vtan[0]=vtan[1]=vtan[2]=0.0; } }
-
-void psys_particle_on_dm(Object *ob, DerivedMesh *dm, int from, int index, int 
index_dmcache, float *fw, float foffset, float *vec, float *nor, float *utan, 
float *vtan, float *orco, float *ornor)
+static int psys_map_index_on_dm(DerivedMesh *dm, int from, int index, int 
index_dmcache, float *fw, float foffset, int *mapindex, float *mapfw)
 {
-       float temp1[3];
-       float (*orcodata)[3];
+       if(index < 0)
+               return 0;
 
-       if(index < 0) { /* 'no dm' error has happened! */
-               PARTICLE_ON_DM_ERROR;
-               return;
-       }
-       orcodata= dm->getVertDataArray(dm, CD_ORCO);
-
        if (dm->deformedOnly || index_dmcache == DMCACHE_ISCHILD) {
-               /* this works for meshes with deform verts only - constructive 
modifiers wont work properly*/
+               /* for meshes that are either only defined or for child 
particles, the
+                * index and fw do not require any mapping, so we can directly 
use it */
                if(from == PART_FROM_VERT) {
-                       if(index >= dm->getNumVerts(dm)) {
-                               PARTICLE_ON_DM_ERROR;
-                               return;
-                       }
-       
-                       dm->getVertCo(dm,index,vec);
-                       if(nor){
-                               dm->getVertNo(dm,index,nor);
-                               Normalize(nor);
-                       }
-                       if(orco)
-                               VECCOPY(orco, orcodata[index])
-                       if(ornor) {
-                               dm->getVertNo(dm,index,nor);
-                               Normalize(nor);
-                       }
+                       if(index >= dm->getNumVerts(dm))
+                               return 0;
+
+                       *mapindex = index;
                }
-               else { /* PART_FROM_FACE / PART_FROM_VOLUME */
-                       MFace *mface;
-                       MTFace *mtface=0;
-                       MVert *mvert;
-                       int uv_index;
+               else  { /* FROM_FACE/FROM_VOLUME */
+                       if(index >= dm->getNumFaces(dm))
+                               return 0;
 
-                       if(index >= dm->getNumFaces(dm)) {
-                               PARTICLE_ON_DM_ERROR;
-                               return;
-                       }
-                       
-                       mface=dm->getFaceData(dm,index,CD_MFACE);
-                       mvert=dm->getVertDataArray(dm,CD_MVERT);
-                       
uv_index=CustomData_get_active_layer_index(&dm->faceData,CD_MTFACE);
-
-                       if(uv_index>=0){
-                               CustomDataLayer 
*layer=&dm->faceData.layers[uv_index];
-                               mtface= &((MTFace*)layer->data)[index];
-                       }
-
-                       if(from==PART_FROM_VOLUME){
-                               
psys_interpolate_face(mvert,mface,mtface,orcodata,fw,vec,temp1,utan,vtan,orco,ornor);
-                               if(nor)
-                                       VECCOPY(nor,temp1);
-                               Normalize(temp1);
-                               VecMulf(temp1,-foffset);
-                               VECADD(vec,vec,temp1);
-                       }
-                       else
-                               
psys_interpolate_face(mvert,mface,mtface,orcodata,fw,vec,nor,utan,vtan,orco,ornor);
+                       *mapindex = index;
+                       QUATCOPY(mapfw, fw);
                }
        } else {
-               /* Need to support constructive modifiers, this is a bit more 
tricky
-                       we need a customdata layer like UV's so we can position 
the particle */
-               
-               /* Only face supported at the moment */
-               if(ELEM(from, PART_FROM_FACE, PART_FROM_VOLUME)) {
+               /* for other meshes that have been modified, we try to map the 
particle
+                * to their new location, which means a different index, and 
for faces
+                * also a new face interpolation weights */
+               if(from == PART_FROM_VERT) {
+                       if (index_dmcache == DMCACHE_NOTFOUND || index_dmcache 
> dm->getNumVerts(dm))
+                               return 0;
+
+                       *mapindex = index_dmcache;
+               }
+               else  { /* FROM_FACE/FROM_VOLUME */
                        /* find a face on the derived mesh that uses this face 
*/
-                       Mesh *me= (Mesh*)ob->data;
-                       MVert *mvert;
                        MFace *mface;
-                       MTFace *mtface;
                        OrigSpaceFace *osface;
-                       int *origindex;
-                       float fw_mod[4];
-                       int i, totface;
-                       
-                       mvert= dm->getVertDataArray(dm,CD_MVERT);
+                       int i;
 
+                       i = index_dmcache;
+
+                       if(i== DMCACHE_NOTFOUND || i >= dm->getNumFaces(dm))
+                               return 0;
+
+                       *mapindex = i;
+
+                       /* modify the original weights to become
+                        * weights for the derived mesh face */
                        osface= dm->getFaceDataArray(dm, CD_ORIGSPACE);
-                       origindex= dm->getFaceDataArray(dm, CD_ORIGINDEX);
+                       mface= dm->getFaceData(dm, i, CD_MFACE);
 
-                       /* For this to work we need origindex and OrigSpace 
coords */
-                       if(origindex==NULL || osface==NULL || 
index>=me->totface) {
-                               PARTICLE_ON_DM_ERROR;
-                               return;
-                       }
-                       
-                       if (index_dmcache == DMCACHE_NOTFOUND)
-                               i = psys_particle_dm_face_lookup(ob, dm, index, 
fw, (LinkNode*)NULL);
+                       if(osface == NULL)
+                               mapfw[0]= mapfw[1]= mapfw[2]= mapfw[3]= 0.0f;
                        else
-                               i = index_dmcache;
+                               psys_origspace_to_w(&osface[i], mface->v4, fw, 
mapfw);
+               }
+       }
 
-                       totface = dm->getNumFaces(dm);
+       return 1;
+}
 
-                       /* Any time this happens, and the face has not been 
removed,
-                       * its a BUG watch out for this error! */
-                       if (i==-1) {
-                               printf("Cannot find original face %i\n", index);
-                               PARTICLE_ON_DM_ERROR;
-                               return;
-                       }
-                       else if(i >= totface)
-                               return;
+/* 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, float *fw, float foffset, float *vec, float *nor, float *utan, 
float *vtan, float *orco, float *ornor)
+{
+       float tmpnor[3], mapfw[4];
+       float (*orcodata)[3];
+       int mapindex;
 
-                       mface= dm->getFaceData(dm, i, CD_MFACE);
-                       mtface= dm->getFaceData(dm, i, CD_MTFACE); 
-                       osface += i;
+       if(!psys_map_index_on_dm(dm, 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; }
+               if(ornor) { ornor[0]=ornor[1]=0.0; ornor[2]=1.0; }
+               if(utan) { utan[0]=utan[1]=utan[2]=0.0; }
+               if(vtan) { vtan[0]=vtan[1]=vtan[2]=0.0; }
 
-                       /* we need to modify the original weights to become 
weights for
-                        * the derived mesh face */

@@ 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