[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [16841] trunk/blender/source/blender: Fix for bug #17302: subsurf + particle size vertex groups did not
Brecht Van Lommel
brecht at blender.org
Tue Sep 30 08:12:47 CEST 2008
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. @@
More information about the Bf-blender-cvs
mailing list