Fix for bug #8052: particle emit from verts and volume didn't support
authorBrecht Van Lommel <brechtvanlommel@pandora.be>
Mon, 18 Feb 2008 10:49:46 +0000 (10:49 +0000)
committerBrecht Van Lommel <brechtvanlommel@pandora.be>
Mon, 18 Feb 2008 10:49:46 +0000 (10:49 +0000)
subsurf/derivedmesh mapping yet.

Also added int-to-pointer and back conversion function to solve warnings.
Note that it is only allowed to store an int in a pointer and then get
it back, but not a pointer in an int!

source/blender/blenkernel/BKE_particle.h
source/blender/blenkernel/BKE_utildefines.h
source/blender/blenkernel/intern/icons.c
source/blender/blenkernel/intern/modifier.c
source/blender/blenkernel/intern/particle.c
source/blender/blenkernel/intern/particle_system.c
source/blender/blenkernel/intern/subsurf_ccg.c

index df0a459..85fa079 100644 (file)
@@ -295,7 +295,7 @@ void reset_particle(struct ParticleData *pa, struct ParticleSystem *psys, struct
 
 void do_effectors(int pa_no, struct ParticleData *pa, struct ParticleKey *state, struct Object *ob, struct ParticleSystem *psys, float *force_field, float *vel,float framestep, float cfra);
 
-void psys_calc_dmfaces(struct Object *ob, struct DerivedMesh *dm, struct ParticleSystem *psys);
+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, float *fw, struct LinkNode *node);
 
 /* ParticleEffectorCache->type */
index aa2be23..fa0f2f7 100644 (file)
 #endif
 #define GS(a)  (*((short *)(a)))
 
+/* Warning-free macros for storing ints in pointers. Use these _only_
+ * for storing an int in a pointer, not a pointer in an int (64bit)! */
+#define SET_INT_IN_POINTER(i) ((void*)(long)(i))
+#define GET_INT_FROM_POINTER(i) ((int)(long)(i))
+
 #endif
 
index f144d2b..cab7865 100644 (file)
@@ -48,6 +48,7 @@
 #include "BLI_ghash.h"
 
 #include "BKE_icons.h"
+#include "BKE_utildefines.h"
 
 #define GS(a)  (*((short *)(a)))
 
@@ -87,7 +88,7 @@ static int get_next_free_id()
                return gNextIconId++;
        
        /* now we try to find the smallest icon id not stored in the gIcons hash */
-       while (BLI_ghash_lookup(gIcons, (void *)startId) && startId>=gFirstIconId) 
+       while (BLI_ghash_lookup(gIcons, SET_INT_IN_POINTER(startId)) && startId>=gFirstIconId) 
                startId++;
 
        /* if we found a suitable one that isnt used yet, return it */
@@ -216,7 +217,7 @@ void BKE_icon_changed(int id)
        
        if (!id) return;
 
-       icon = BLI_ghash_lookup(gIcons, (void *)id);
+       icon = BLI_ghash_lookup(gIcons, SET_INT_IN_POINTER(id));
        
        if (icon)
        {
@@ -258,7 +259,7 @@ int BKE_icon_getid(struct ID* id)
        new_icon->drawinfo = 0;
        new_icon->drawinfo_free = 0;
 
-       BLI_ghash_insert(gIcons, (void *)id->icon_id, new_icon);
+       BLI_ghash_insert(gIcons, SET_INT_IN_POINTER(id->icon_id), new_icon);
        
        return id->icon_id;
 }
@@ -267,7 +268,7 @@ Icon* BKE_icon_get(int icon_id)
 {
        Icon* icon = 0;
 
-       icon = BLI_ghash_lookup(gIcons, (void*)icon_id);
+       icon = BLI_ghash_lookup(gIcons, SET_INT_IN_POINTER(icon_id));
        
        if (!icon) {
                printf("BKE_icon_get: Internal error, no icon for icon ID: %d\n", icon_id);
@@ -281,7 +282,7 @@ void BKE_icon_set(int icon_id, struct Icon* icon)
 {
        Icon* old_icon = 0;
 
-       old_icon = BLI_ghash_lookup(gIcons, (void*)icon_id);
+       old_icon = BLI_ghash_lookup(gIcons, SET_INT_IN_POINTER(icon_id));
 
        if (old_icon)
        {
@@ -289,7 +290,7 @@ void BKE_icon_set(int icon_id, struct Icon* icon)
                return;
        }
 
-       BLI_ghash_insert(gIcons, (void *)icon_id, icon);
+       BLI_ghash_insert(gIcons, SET_INT_IN_POINTER(icon_id), icon);
 }
 
 void BKE_icon_delete(struct ID* id)
@@ -297,6 +298,6 @@ void BKE_icon_delete(struct ID* id)
 
        if (!id->icon_id) return; /* no icon defined for library object */
 
-       BLI_ghash_remove(gIcons, (void*)id->icon_id, 0, icon_free);
+       BLI_ghash_remove(gIcons, SET_INT_IN_POINTER(id->icon_id), 0, icon_free);
        id->icon_id = 0;
 }
index ead7f4f..91892f5 100644 (file)
@@ -435,18 +435,18 @@ static DerivedMesh *buildModifier_applyModifier(ModifierData *md, Object *ob,
                        MFace mf;
                        dm->getFace(dm, faceMap[i], &mf);
 
-                       if(!BLI_ghash_haskey(vertHash, (void *)mf.v1))
-                               BLI_ghash_insert(vertHash, (void *)mf.v1,
-                                                (void *)BLI_ghash_size(vertHash));
-                       if(!BLI_ghash_haskey(vertHash, (void *)mf.v2))
-                               BLI_ghash_insert(vertHash, (void *)mf.v2,
-                                                (void *)BLI_ghash_size(vertHash));
-                       if(!BLI_ghash_haskey(vertHash, (void *)mf.v3))
-                               BLI_ghash_insert(vertHash, (void *)mf.v3,
-                                                (void *)BLI_ghash_size(vertHash));
-                       if(mf.v4 && !BLI_ghash_haskey(vertHash, (void *)mf.v4))
-                               BLI_ghash_insert(vertHash, (void *)mf.v4,
-                                                (void *)BLI_ghash_size(vertHash));
+                       if(!BLI_ghash_haskey(vertHash, SET_INT_IN_POINTER(mf.v1)))
+                               BLI_ghash_insert(vertHash, SET_INT_IN_POINTER(mf.v1),
+                                                SET_INT_IN_POINTER(BLI_ghash_size(vertHash)));
+                       if(!BLI_ghash_haskey(vertHash, SET_INT_IN_POINTER(mf.v2)))
+                               BLI_ghash_insert(vertHash, SET_INT_IN_POINTER(mf.v2),
+                                                SET_INT_IN_POINTER(BLI_ghash_size(vertHash)));
+                       if(!BLI_ghash_haskey(vertHash, SET_INT_IN_POINTER(mf.v3)))
+                               BLI_ghash_insert(vertHash, SET_INT_IN_POINTER(mf.v3),
+                                                SET_INT_IN_POINTER(BLI_ghash_size(vertHash)));
+                       if(mf.v4 && !BLI_ghash_haskey(vertHash, SET_INT_IN_POINTER(mf.v4)))
+                               BLI_ghash_insert(vertHash, SET_INT_IN_POINTER(mf.v4),
+                                                SET_INT_IN_POINTER(BLI_ghash_size(vertHash)));
                }
 
                /* get the set of edges that will be in the new mesh (i.e. all edges
@@ -457,10 +457,10 @@ static DerivedMesh *buildModifier_applyModifier(ModifierData *md, Object *ob,
                        MEdge me;
                        dm->getEdge(dm, i, &me);
 
-                       if(BLI_ghash_haskey(vertHash, (void *)me.v1)
-                          && BLI_ghash_haskey(vertHash, (void *)me.v2))
+                       if(BLI_ghash_haskey(vertHash, SET_INT_IN_POINTER(me.v1))
+                          && BLI_ghash_haskey(vertHash, SET_INT_IN_POINTER(me.v2)))
                                BLI_ghash_insert(edgeHash,
-                                                (void *)BLI_ghash_size(edgeHash), (void *)i);
+                                                SET_INT_IN_POINTER(BLI_ghash_size(edgeHash)), SET_INT_IN_POINTER(i));
                }
        } else if(numEdges) {
                if(bmd->randomize)
@@ -474,12 +474,12 @@ static DerivedMesh *buildModifier_applyModifier(ModifierData *md, Object *ob,
                        MEdge me;
                        dm->getEdge(dm, edgeMap[i], &me);
 
-                       if(!BLI_ghash_haskey(vertHash, (void *)me.v1))
-                               BLI_ghash_insert(vertHash, (void *)me.v1,
-                                                (void *)BLI_ghash_size(vertHash));
-                       if(!BLI_ghash_haskey(vertHash, (void *)me.v2))
-                               BLI_ghash_insert(vertHash, (void *)me.v2,
-                                                (void *)BLI_ghash_size(vertHash));
+                       if(!BLI_ghash_haskey(vertHash, SET_INT_IN_POINTER(me.v1)))
+                               BLI_ghash_insert(vertHash, SET_INT_IN_POINTER(me.v1),
+                                                SET_INT_IN_POINTER(BLI_ghash_size(vertHash)));
+                       if(!BLI_ghash_haskey(vertHash, SET_INT_IN_POINTER(me.v2)))
+                               BLI_ghash_insert(vertHash, SET_INT_IN_POINTER(me.v2),
+                                                SET_INT_IN_POINTER(BLI_ghash_size(vertHash)));
                }
 
                /* get the set of edges that will be in the new mesh
@@ -488,8 +488,8 @@ static DerivedMesh *buildModifier_applyModifier(ModifierData *md, Object *ob,
                        MEdge me;
                        dm->getEdge(dm, edgeMap[i], &me);
 
-                       BLI_ghash_insert(edgeHash, (void *)BLI_ghash_size(edgeHash),
-                                        (void *)edgeMap[i]);
+                       BLI_ghash_insert(edgeHash, SET_INT_IN_POINTER(BLI_ghash_size(edgeHash)),
+                                        SET_INT_IN_POINTER(edgeMap[i]));
                }
        } else {
                int numVerts = dm->getNumVerts(dm) * frac;
@@ -502,7 +502,7 @@ static DerivedMesh *buildModifier_applyModifier(ModifierData *md, Object *ob,
                 * mapped to the new indices
                 */
                for(i = 0; i < numVerts; ++i)
-                       BLI_ghash_insert(vertHash, (void *)vertMap[i], (void *)i);
+                       BLI_ghash_insert(vertHash, SET_INT_IN_POINTER(vertMap[i]), SET_INT_IN_POINTER(i));
        }
 
        /* now we know the number of verts, edges and faces, we can create
@@ -517,8 +517,8 @@ static DerivedMesh *buildModifier_applyModifier(ModifierData *md, Object *ob,
                BLI_ghashIterator_step(hashIter)) {
                MVert source;
                MVert *dest;
-               int oldIndex = (int)BLI_ghashIterator_getKey(hashIter);
-               int newIndex = (int)BLI_ghashIterator_getValue(hashIter);
+               int oldIndex = GET_INT_FROM_POINTER(BLI_ghashIterator_getKey(hashIter));
+               int newIndex = GET_INT_FROM_POINTER(BLI_ghashIterator_getValue(hashIter));
 
                dm->getVert(dm, oldIndex, &source);
                dest = CDDM_get_vert(result, newIndex);
@@ -532,13 +532,13 @@ static DerivedMesh *buildModifier_applyModifier(ModifierData *md, Object *ob,
        for(i = 0; i < BLI_ghash_size(edgeHash); ++i) {
                MEdge source;
                MEdge *dest;
-               int oldIndex = (int)BLI_ghash_lookup(edgeHash, (void *)i);
+               int oldIndex = GET_INT_FROM_POINTER(BLI_ghash_lookup(edgeHash, SET_INT_IN_POINTER(i)));
 
                dm->getEdge(dm, oldIndex, &source);
                dest = CDDM_get_edge(result, i);
 
-               source.v1 = (int)BLI_ghash_lookup(vertHash, (void *)source.v1);
-               source.v2 = (int)BLI_ghash_lookup(vertHash, (void *)source.v2);
+               source.v1 = GET_INT_FROM_POINTER(BLI_ghash_lookup(vertHash, SET_INT_IN_POINTER(source.v1)));
+               source.v2 = GET_INT_FROM_POINTER(BLI_ghash_lookup(vertHash, SET_INT_IN_POINTER(source.v2)));
 
                DM_copy_edge_data(dm, result, oldIndex, i, 1);
                *dest = source;
@@ -555,11 +555,11 @@ static DerivedMesh *buildModifier_applyModifier(ModifierData *md, Object *ob,
 
                orig_v4 = source.v4;
 
-               source.v1 = (int)BLI_ghash_lookup(vertHash, (void *)source.v1);
-               source.v2 = (int)BLI_ghash_lookup(vertHash, (void *)source.v2);
-               source.v3 = (int)BLI_ghash_lookup(vertHash, (void *)source.v3);
+               source.v1 = GET_INT_FROM_POINTER(BLI_ghash_lookup(vertHash, SET_INT_IN_POINTER(source.v1)));
+               source.v2 = GET_INT_FROM_POINTER(BLI_ghash_lookup(vertHash, SET_INT_IN_POINTER(source.v2)));
+               source.v3 = GET_INT_FROM_POINTER(BLI_ghash_lookup(vertHash, SET_INT_IN_POINTER(source.v3)));
                if(source.v4)
-                       source.v4 = (int)BLI_ghash_lookup(vertHash, (void *)source.v4);
+                       source.v4 = GET_INT_FROM_POINTER(BLI_ghash_lookup(vertHash, SET_INT_IN_POINTER(source.v4)));
 
                DM_copy_face_data(dm, result, faceMap[i], i, 1);
                *dest = source;
index d7e430e..2538ddf 100644 (file)
@@ -539,8 +539,8 @@ void psys_render_restore(Object *ob, ParticleSystem *psys)
        psmd->totdmface= data->totdmface;
        psmd->flag &= ~eParticleSystemFlag_psys_updated;
 
-       if(psys->part->from==PART_FROM_FACE && psmd->dm)
-               psys_calc_dmfaces(ob, psmd->dm, psys);
+       if(psmd->dm)
+               psys_calc_dmcache(ob, psmd->dm, psys);
 
        MEM_freeN(data);
        psys->renderdata= NULL;
@@ -1086,7 +1086,7 @@ int psys_particle_dm_face_lookup(Object *ob, DerivedMesh *dm, int index, float *
        
        if(node) { /* we have a linked list of faces that we use, faster! */
                for(;node; node=node->next) {
-                       findex= (int)node->link;
+                       findex= GET_INT_FROM_POINTER(node->link);
                        faceuv= osface[findex].uv;
                        quad= mface[findex].v4;
 
@@ -1122,24 +1122,30 @@ int psys_particle_dm_face_lookup(Object *ob, DerivedMesh *dm, int index, float *
 }
 
 /* interprets particle data to get a point on a mesh in object space */
-#define PARTICLE_ERROR(_nor, _vec) _vec[0]=_vec[1]=_vec[2]=0.0; if(_nor){ _nor[0]=_nor[1]=0.0; _nor[2]=1.0; }
+#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)
 {
+       float temp1[3];
        float (*orcodata)[3];
 
-       if(index < 0){ /* 'no dm' error has happened! */
-               PARTICLE_ERROR(nor, vec);
+       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*/
-               float temp1[3];
-
                if(from == PART_FROM_VERT) {
                        if(index >= dm->getNumVerts(dm)) {
-                               PARTICLE_ERROR(nor, vec);
+                               PARTICLE_ON_DM_ERROR;
                                return;
                        }
        
@@ -1162,7 +1168,7 @@ void psys_particle_on_dm(Object *ob, DerivedMesh *dm, int from, int index, int i
                        int uv_index;
 
                        if(index >= dm->getNumFaces(dm)) {
-                               PARTICLE_ERROR(nor, vec);
+                               PARTICLE_ON_DM_ERROR;
                                return;
                        }
                        
@@ -1191,7 +1197,7 @@ void psys_particle_on_dm(Object *ob, DerivedMesh *dm, int from, int index, int i
                        we need a customdata layer like UV's so we can position the particle */
                
                /* Only face supported at the moment */
-               if (from==PART_FROM_FACE) {
+               if(ELEM(from, PART_FROM_FACE, PART_FROM_VOLUME)) {
                        /* find a face on the derived mesh that uses this face */
                        Mesh *me= (Mesh*)ob->data;
                        MVert *mvert;
@@ -1209,7 +1215,7 @@ void psys_particle_on_dm(Object *ob, DerivedMesh *dm, int from, int index, int i
 
                        /* For this to work we need origindex and OrigSpace coords */
                        if(origindex==NULL || osface==NULL || index>=me->totface) {
-                               PARTICLE_ERROR(nor, vec);
+                               PARTICLE_ON_DM_ERROR;
                                return;
                        }
                        
@@ -1224,7 +1230,7 @@ void psys_particle_on_dm(Object *ob, DerivedMesh *dm, int from, int index, int i
                        * its a BUG watch out for this error! */
                        if (i==-1) {
                                printf("Cannot find original face %i\n", index);
-                               PARTICLE_ERROR(nor, vec);
+                               PARTICLE_ON_DM_ERROR;
                                return;
                        }
                        else if(i >= totface)
@@ -1237,15 +1243,46 @@ void psys_particle_on_dm(Object *ob, DerivedMesh *dm, int from, int index, int i
                        /* we need to modify the original weights to become weights for
                         * the derived mesh face */
                        psys_origspace_to_w(osface, mface->v4, fw, fw_mod);
-                       psys_interpolate_face(mvert,mface,mtface,orcodata,fw_mod,vec,nor,utan,vtan,orco,ornor);
+
+                       if(from==PART_FROM_VOLUME){
+                               psys_interpolate_face(mvert,mface,mtface,orcodata,fw_mod,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_mod,vec,nor,utan,vtan,orco,ornor);
+               }
+               else if(from == PART_FROM_VERT) {
+                       if (index_dmcache == DMCACHE_NOTFOUND || index_dmcache > dm->getNumVerts(dm)) {
+                               PARTICLE_ON_DM_ERROR;
+                               return;
+                       }
+
+                       dm->getVertCo(dm,index_dmcache,vec);
+                       if(nor) {
+                               dm->getVertNo(dm,index_dmcache,nor);
+                               Normalize(nor);
+                       }
+                       if(orco)
+                               VECCOPY(orco, orcodata[index])
+                       if(ornor) {
+                               dm->getVertNo(dm,index_dmcache,nor);
+                               Normalize(nor);
+                       }
+                       if(utan && vtan) {
+                               utan[0]= utan[1]= utan[2]= 0.0f;
+                               vtan[0]= vtan[1]= vtan[2]= 0.0f;
+                       }
                }
                else {
-                       /* TODO PARTICLE - support verts and volume */
-                       PARTICLE_ERROR(nor, vec);
+                       PARTICLE_ON_DM_ERROR;
                }
        }
 }
-#undef PARTICLE_ERROR
+#undef PARTICLE_ON_DM_ERROR
 
 ParticleSystemModifierData *psys_get_modifier(Object *ob, ParticleSystem *psys)
 {
@@ -3274,7 +3311,7 @@ void psys_get_particle_on_path(Object *ob, ParticleSystem *psys, int p, Particle
        ChildParticle *cpa;
        ParticleTexture ptex;
        ParticleKey *kkey[2] = {NULL, NULL};
-       HairKey *hkey[2];
+       HairKey *hkey[2] = {NULL, NULL};
        ParticleKey *par=0, keys[4];
 
        float t, real_t, dfra, keytime, frs_sec = G.scene->r.frs_sec;
index e90fc4a..9136579 100644 (file)
@@ -180,12 +180,13 @@ static void alloc_child_particles(ParticleSystem *psys, int tot)
        }
 }
 
-/* only run this if from == PART_FROM_FACE */
-void psys_calc_dmfaces(Object *ob, DerivedMesh *dm, ParticleSystem *psys)
+void psys_calc_dmcache(Object *ob, DerivedMesh *dm, ParticleSystem *psys)
 {
-       /* use for building derived mesh face-origin info,
-       node - the allocated links - total derived mesh face count 
-       node_array - is the array of nodes alligned with the base mesh's faces, so each original face can reference its derived faces
+       /* use for building derived mesh mapping info:
+
+          node: the allocated links - total derived mesh element count 
+          nodearray: the array of nodes aligned with the base mesh's elements, so
+                     each original elements can reference its derived elements
        */
        Mesh *me= (Mesh*)ob->data;
        ParticleData *pa= 0;
@@ -194,57 +195,59 @@ void psys_calc_dmfaces(Object *ob, DerivedMesh *dm, ParticleSystem *psys)
        /* CACHE LOCATIONS */
        if(!dm->deformedOnly) {
                /* Will use later to speed up subsurf/derivedmesh */
+               LinkNode *node, *nodedmelem, **nodearray;
+               int totdmelem, totelem, i, *origindex;
+
+               if(psys->part->from == PART_FROM_VERT) {
+                       totdmelem= dm->getNumVerts(dm);
+                       totelem= me->totvert;
+                       origindex= DM_get_vert_data_layer(dm, CD_ORIGINDEX);
+               }
+               else { /* FROM_FACE/FROM_VOLUME */
+                       totdmelem= dm->getNumFaces(dm);
+                       totelem= me->totface;
+                       origindex= DM_get_face_data_layer(dm, CD_ORIGINDEX);
+               }
        
-               int tot_dm_face = dm->getNumFaces(dm);
-               int totface = me->totface;
-               int *origindex = DM_get_face_data_layer(dm, CD_ORIGINDEX);
-               int i;
-               LinkNode *node, *node_dm_faces, **node_array;
-               
-               node_dm_faces = node = MEM_callocN(sizeof(LinkNode)*tot_dm_face, "faceindicies");
-               node_array = MEM_callocN(sizeof(LinkNode *)*totface, "faceindicies array");
+               nodedmelem= MEM_callocN(sizeof(LinkNode)*totdmelem, "psys node elems");
+               nodearray= MEM_callocN(sizeof(LinkNode *)*totelem, "psys node array");
                
-               for(i=0; i < tot_dm_face; i++, origindex++, node++) {
-                       node->link = (void *)i; // or use the index?
+               for(i=0, node=nodedmelem; i<totdmelem; i++, origindex++, node++) {
+                       node->link= SET_INT_IN_POINTER(i);
+
                        if(*origindex != -1) {
-                               if(node_array[*origindex]) {
+                               if(nodearray[*origindex]) {
                                        /* prepend */
-                                       node->next = node_array[*origindex];
-                                       node_array[*origindex] = node;
-                               } else {
-                                       node_array[*origindex] = node;
+                                       node->next = nodearray[*origindex];
+                                       nodearray[*origindex]= node;
                                }
+                               else
+                                       nodearray[*origindex]= node;
                        }
                }
                
-               /* cache the faces! */
-
-
+               /* cache the verts/faces! */
                for(p=0,pa=psys->particles; p<psys->totpart; p++,pa++) {
-                       //i = pa->num;
-                       //if (i<totface) // should never happen
-                       i = psys_particle_dm_face_lookup(ob, dm, pa->num, pa->fuv, node_array[pa->num]);
-                       pa->num_dmcache = i;
+                       if(psys->part->from == PART_FROM_VERT) {
+                               if(nodearray[pa->num])
+                                       pa->num_dmcache= GET_INT_FROM_POINTER(nodearray[pa->num]->link);
+                       }
+                       else { /* FROM_FACE/FROM_VOLUME */
+                               i= psys_particle_dm_face_lookup(ob, dm, pa->num, pa->fuv, nodearray[pa->num]);
+                               pa->num_dmcache= i;
+                       }
                }
 
-               //for (i=0; i < totface; i++) {
-               //      i = psys_particle_dm_face_lookup(ob, dm, node_array[], fuv, (LinkNode*)NULL);
-               //}
-               MEM_freeN(node_array);
-               MEM_freeN(node_dm_faces);
-               
-       } else {
-               /* set the num_dmcache to an invalid value, just incase */
-               /* TODO PARTICLE, make the following line unnecessary, each function should know to use the num or num_dmcache */
+               MEM_freeN(nodearray);
+               MEM_freeN(nodedmelem);
+       }
+       else {
+               /* TODO PARTICLE, make the following line unnecessary, each function
+                * should know to use the num or num_dmcache, set the num_dmcache to
+                * an invalid value, just incase */
                
-               /*
-               for(p=0,pa=psys->particles; p<psys->totpart; p++,pa++) {
-                       pa->num_dmcache = pa->num;
-               }
-               */
-               for(p=0,pa=psys->particles; p<psys->totpart; p++,pa++) {
+               for(p=0,pa=psys->particles; p<psys->totpart; p++,pa++)
                        pa->num_dmcache = -1;
-               }
        }
 }
 
@@ -1271,8 +1274,7 @@ static void distribute_particles_on_dm(DerivedMesh *finaldm, Object *ob, Particl
        else
                exec_distribution(&pthreads[0]);
 
-       if (from == PART_FROM_FACE)
-               psys_calc_dmfaces(ob, finaldm, psys);
+       psys_calc_dmcache(ob, finaldm, psys);
 
        ctx= pthreads[0].ctx;
        if(ctx->dm != finaldm)
@@ -4273,7 +4275,7 @@ static void hair_step(Object *ob, ParticleSystemModifierData *psmd, ParticleSyst
 
        if(psys->recalc & PSYS_DISTR)
                /* need this for changing subsurf levels */
-               psys_calc_dmfaces(ob, psmd->dm, psys);
+               psys_calc_dmcache(ob, psmd->dm, psys);
 
        if(psys->effectors.first)
                psys_end_effectors(psys);
index 9c9c4a8..0108c7a 100644 (file)
@@ -224,7 +224,7 @@ static void get_face_uv_map_vert(UvVertMap *vmap, struct MFace *mf, int fi, CCGV
                                break;
                }
 
-               fverts[j]= (CCGVertHDL)(nv->f*4 + nv->tfindex);
+               fverts[j]= SET_INT_IN_POINTER(nv->f*4 + nv->tfindex);
        }
 }
 
@@ -262,7 +262,7 @@ static int ss_sync_from_uv(CCGSubSurf *ss, CCGSubSurf *origss, DerivedMesh *dm,
                for (v=get_uv_map_vert(vmap, i); v; v=v->next) {
                        if (v->separate) {
                                CCGVert *ssv;
-                               CCGVertHDL vhdl = (CCGVertHDL)(v->f*4 + v->tfindex);
+                               CCGVertHDL vhdl = SET_INT_IN_POINTER(v->f*4 + v->tfindex);
                                float uv[3];
 
                                uv[0]= (tface+v->f)->uv[v->tfindex][0];
@@ -280,20 +280,20 @@ static int ss_sync_from_uv(CCGSubSurf *ss, CCGSubSurf *origss, DerivedMesh *dm,
        for (i=0; i<totface; i++) {
                MFace *mf = &((MFace*) mface)[i];
                int nverts= mf->v4? 4: 3;
-               CCGFace *origf= ccgSubSurf_getFace(origss, (CCGFaceHDL)i);
+               CCGFace *origf= ccgSubSurf_getFace(origss, SET_INT_IN_POINTER(i));
                unsigned int *fv = &mf->v1;
 
                get_face_uv_map_vert(vmap, mf, i, fverts);
 
                for (j=0; j<nverts; j++) {
-                       int v0 = (int)fverts[j];
-                       int v1 = (int)fverts[(j+1)%nverts];
+                       int v0 = GET_INT_FROM_POINTER(fverts[j]);
+                       int v1 = GET_INT_FROM_POINTER(fverts[(j+1)%nverts]);
                        MVert *mv0 = mvert + *(fv+j);
                        MVert *mv1 = mvert + *(fv+((j+1)%nverts));
 
                        if (!BLI_edgehash_haskey(ehash, v0, v1)) {
                                CCGEdge *e, *orige= ccgSubSurf_getFaceEdge(origss, origf, j);
-                               CCGEdgeHDL ehdl= (CCGEdgeHDL)(i*4 + j);
+                               CCGEdgeHDL ehdl= SET_INT_IN_POINTER(i*4 + j);
                                float crease;
 
                                if ((mv0->flag&mv1->flag) & ME_VERT_MERGED)
@@ -316,7 +316,7 @@ static int ss_sync_from_uv(CCGSubSurf *ss, CCGSubSurf *origss, DerivedMesh *dm,
                CCGFace *f;
 
                get_face_uv_map_vert(vmap, mf, i, fverts);
-               ccgSubSurf_syncFace(ss, (CCGFaceHDL)i, nverts, fverts, &f);
+               ccgSubSurf_syncFace(ss, SET_INT_IN_POINTER(i), nverts, fverts, &f);
        }
 
        free_uv_vert_map(vmap);
@@ -358,7 +358,7 @@ static void set_subsurf_uv(CCGSubSurf *ss, DerivedMesh *dm, DerivedMesh *result,
        fi = ccgSubSurf_getFaceIterator(uvss);
        for(; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) {
                CCGFace *f = ccgFaceIterator_getCurrent(fi);
-               faceMap[(int) ccgSubSurf_getFaceFaceHandle(uvss, f)] = f;
+               faceMap[GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(uvss, f))] = f;
        }
        ccgFaceIterator_free(fi);
 
@@ -502,7 +502,7 @@ DerivedMesh *ss_to_cdderivedmesh(CCGSubSurf *ss, int ssFromEditmesh,
        for(; !ccgVertIterator_isStopped(vi); ccgVertIterator_next(vi)) {
                CCGVert *v = ccgVertIterator_getCurrent(vi);
 
-               vertMap2[(int) ccgSubSurf_getVertVertHandle(ss, v)] = v;
+               vertMap2[GET_INT_FROM_POINTER(ccgSubSurf_getVertVertHandle(ss, v))] = v;
        }
        ccgVertIterator_free(vi);
 
@@ -512,7 +512,7 @@ DerivedMesh *ss_to_cdderivedmesh(CCGSubSurf *ss, int ssFromEditmesh,
        for(; !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) {
                CCGEdge *e = ccgEdgeIterator_getCurrent(ei);
 
-               edgeMap2[(int) ccgSubSurf_getEdgeEdgeHandle(ss, e)] = e;
+               edgeMap2[GET_INT_FROM_POINTER(ccgSubSurf_getEdgeEdgeHandle(ss, e))] = e;
        }
 
        totface = ccgSubSurf_getNumFaces(ss);
@@ -521,7 +521,7 @@ DerivedMesh *ss_to_cdderivedmesh(CCGSubSurf *ss, int ssFromEditmesh,
        for(; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) {
                CCGFace *f = ccgFaceIterator_getCurrent(fi);
 
-               faceMap2[(int) ccgSubSurf_getFaceFaceHandle(ss, f)] = f;
+               faceMap2[GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(ss, f))] = f;
        }
        ccgFaceIterator_free(fi);
 
@@ -549,7 +549,7 @@ DerivedMesh *ss_to_cdderivedmesh(CCGSubSurf *ss, int ssFromEditmesh,
                for(S = 0; S < numVerts; S++) {
                        CCGVert *v = ccgSubSurf_getFaceVert(ss, f, S);
 
-                       vertIdx[S] = (int)ccgSubSurf_getVertVertHandle(ss, v);
+                       vertIdx[S] = GET_INT_FROM_POINTER(ccgSubSurf_getVertVertHandle(ss, v));
                }
 
                DM_interp_vert_data(dm, result, vertIdx, weight[0][0], numVerts, i);
@@ -613,9 +613,9 @@ DerivedMesh *ss_to_cdderivedmesh(CCGSubSurf *ss, int ssFromEditmesh,
 
                CCGVert *v;
                v = ccgSubSurf_getEdgeVert0(ss, e);
-               vertIdx[0] = (int)ccgSubSurf_getVertVertHandle(ss, v);
+               vertIdx[0] = GET_INT_FROM_POINTER(ccgSubSurf_getVertVertHandle(ss, v));
                v = ccgSubSurf_getEdgeVert1(ss, e);
-               vertIdx[1] = (int)ccgSubSurf_getVertVertHandle(ss, v);
+               vertIdx[1] = GET_INT_FROM_POINTER(ccgSubSurf_getVertVertHandle(ss, v));
 
                for(x = 1; x < edgeSize - 1; x++) {
                        float w[2];
@@ -638,7 +638,7 @@ DerivedMesh *ss_to_cdderivedmesh(CCGSubSurf *ss, int ssFromEditmesh,
                CCGVert *v = vertMap2[index];
                int vertIdx;
 
-               vertIdx = (int)ccgSubSurf_getVertVertHandle(ss, v);
+               vertIdx = GET_INT_FROM_POINTER(ccgSubSurf_getVertVertHandle(ss, v));
 
                DM_copy_vert_data(dm, result, vertIdx, i, 1);
                VecCopyf(mvert->co, ccgSubSurf_getVertData(ss, v));
@@ -699,7 +699,7 @@ DerivedMesh *ss_to_cdderivedmesh(CCGSubSurf *ss, int ssFromEditmesh,
        for(index = 0; index < totedge; index++) {
                CCGEdge *e = edgeMap2[index];
                unsigned int flags = 0;
-               int edgeIdx = (int)ccgSubSurf_getEdgeEdgeHandle(ss, e);
+               int edgeIdx = GET_INT_FROM_POINTER(ccgSubSurf_getEdgeEdgeHandle(ss, e));
 
                if(!ccgSubSurf_getEdgeNumFaces(ss, e)) flags |= ME_LOOSEEDGE;
 
@@ -733,7 +733,7 @@ DerivedMesh *ss_to_cdderivedmesh(CCGSubSurf *ss, int ssFromEditmesh,
                int mat_nr;
                int flag;
                int mapIndex = ccgDM_getFaceMapIndex(NULL, ss, f);
-               int faceIdx = (int)ccgSubSurf_getFaceFaceHandle(ss, f);
+               int faceIdx = GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(ss, f));
 
                if(!ssFromEditmesh) {
                        MFace origMFace;
@@ -837,9 +837,9 @@ static void ss_sync_from_derivedmesh(CCGSubSurf *ss, DerivedMesh *dm,
                CCGVert *v;
 
                if(vertexCos) {
-                       ccgSubSurf_syncVert(ss, (CCGVertHDL)i, vertexCos[i], 0, &v);
+                       ccgSubSurf_syncVert(ss, SET_INT_IN_POINTER(i), vertexCos[i], 0, &v);
                } else {
-                       ccgSubSurf_syncVert(ss, (CCGVertHDL)i, mv->co, 0, &v);
+                       ccgSubSurf_syncVert(ss, SET_INT_IN_POINTER(i), mv->co, 0, &v);
                }
 
                ((int*)ccgSubSurf_getVertUserData(ss, v))[1] = *index;
@@ -854,8 +854,8 @@ static void ss_sync_from_derivedmesh(CCGSubSurf *ss, DerivedMesh *dm,
                crease = useFlatSubdiv ? creaseFactor :
                                         me->crease * creaseFactor / 255.0f;
 
-               ccgSubSurf_syncEdge(ss, (CCGEdgeHDL)i, (CCGVertHDL)me->v1,
-                                   (CCGVertHDL)me->v2, crease, &e);
+               ccgSubSurf_syncEdge(ss, SET_INT_IN_POINTER(i), SET_INT_IN_POINTER(me->v1),
+                                   SET_INT_IN_POINTER(me->v2), crease, &e);
 
                ((int*)ccgSubSurf_getEdgeUserData(ss, e))[1] = *index;
        }
@@ -865,16 +865,16 @@ static void ss_sync_from_derivedmesh(CCGSubSurf *ss, DerivedMesh *dm,
        for (i = 0; i < totface; i++, mf++, index++) {
                CCGFace *f;
 
-               fVerts[0] = (CCGVertHDL) mf->v1;
-               fVerts[1] = (CCGVertHDL) mf->v2;
-               fVerts[2] = (CCGVertHDL) mf->v3;
-               fVerts[3] = (CCGVertHDL) mf->v4;
+               fVerts[0] = SET_INT_IN_POINTER(mf->v1);
+               fVerts[1] = SET_INT_IN_POINTER(mf->v2);
+               fVerts[2] = SET_INT_IN_POINTER(mf->v3);
+               fVerts[3] = SET_INT_IN_POINTER(mf->v4);
 
                // this is very bad, means mesh is internally consistent.
                // it is not really possible to continue without modifying
                // other parts of code significantly to handle missing faces.
                // since this really shouldn't even be possible we just bail.
-               if(ccgSubSurf_syncFace(ss, (CCGFaceHDL)i, fVerts[3] ? 4 : 3,
+               if(ccgSubSurf_syncFace(ss, SET_INT_IN_POINTER(i), fVerts[3] ? 4 : 3,
                                       fVerts, &f) == eCCGError_InvalidValue) {
                        static int hasGivenError = 0;
 
@@ -1272,7 +1272,7 @@ static void ccgDM_copyFinalEdgeArray(DerivedMesh *dm, MEdge *medge)
                CCGEdge *e = ccgdm->edgeMap[index].edge;
                unsigned int flags = 0;
                int x;
-               int edgeIdx = (int)ccgSubSurf_getEdgeEdgeHandle(ss, e);
+               int edgeIdx = GET_INT_FROM_POINTER(ccgSubSurf_getEdgeEdgeHandle(ss, e));
 
                if(!ccgSubSurf_getEdgeNumFaces(ss, e)) flags |= ME_LOOSEEDGE;
 
@@ -1356,7 +1356,7 @@ static void ccgdm_getVertCos(DerivedMesh *dm, float (*cos)[3]) {
        for (; !ccgVertIterator_isStopped(vi); ccgVertIterator_next(vi)) {
                CCGVert *v = ccgVertIterator_getCurrent(vi);
 
-               vertMap2[(int) ccgSubSurf_getVertVertHandle(ss, v)] = v;
+               vertMap2[GET_INT_FROM_POINTER(ccgSubSurf_getVertVertHandle(ss, v))] = v;
        }
        ccgVertIterator_free(vi);
 
@@ -1366,7 +1366,7 @@ static void ccgdm_getVertCos(DerivedMesh *dm, float (*cos)[3]) {
        for (i=0; !ccgEdgeIterator_isStopped(ei); i++,ccgEdgeIterator_next(ei)) {
                CCGEdge *e = ccgEdgeIterator_getCurrent(ei);
 
-               edgeMap2[(int) ccgSubSurf_getEdgeEdgeHandle(ss, e)] = e;
+               edgeMap2[GET_INT_FROM_POINTER(ccgSubSurf_getEdgeEdgeHandle(ss, e))] = e;
        }
 
        totface = ccgSubSurf_getNumFaces(ss);
@@ -1375,7 +1375,7 @@ static void ccgdm_getVertCos(DerivedMesh *dm, float (*cos)[3]) {
        for (; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) {
                CCGFace *f = ccgFaceIterator_getCurrent(fi);
 
-               faceMap2[(int) ccgSubSurf_getFaceFaceHandle(ss, f)] = f;
+               faceMap2[GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(ss, f))] = f;
        }
        ccgFaceIterator_free(fi);
 
@@ -1612,7 +1612,7 @@ static void ccgDM_drawFacesSolid(DerivedMesh *dm, int (*setMaterial)(int)) {
        for (; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) {
                CCGFace *f = ccgFaceIterator_getCurrent(fi);
                int S, x, y, numVerts = ccgSubSurf_getFaceNumVerts(ss, f);
-               int index = (int) ccgSubSurf_getFaceFaceHandle(ss, f);
+               int index = GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(ss, f));
                int drawSmooth, mat_nr;
 
                if(faceFlags) {
@@ -1752,7 +1752,7 @@ static void ccgDM_drawFacesTex_common(DerivedMesh *dm,
                CCGFace *f = ccgdm->faceMap[i].face;
                int S, x, y, numVerts = ccgSubSurf_getFaceNumVerts(ss, f);
                int drawSmooth, index = ccgDM_getFaceMapIndex(ccgdm, ss, f);
-               int origIndex = (int)ccgSubSurf_getFaceFaceHandle(ss, f);
+               int origIndex = GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(ss, f));
                unsigned char *cp= NULL;
                int mat_nr;
 
@@ -1923,7 +1923,7 @@ static void ccgDM_drawMappedFaces(DerivedMesh *dm, int (*setDrawOptions)(void *u
                int drawSmooth, index = ccgDM_getFaceMapIndex(ccgdm, ss, f);
                int origIndex;
 
-               origIndex = (int)ccgSubSurf_getFaceFaceHandle(ss, f);
+               origIndex = GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(ss, f));
 
                if(faceFlags) drawSmooth = (faceFlags[origIndex*4] & ME_SMOOTH);
                else drawSmooth = 1;
@@ -2166,7 +2166,7 @@ static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss,
        for(; !ccgVertIterator_isStopped(vi); ccgVertIterator_next(vi)) {
                CCGVert *v = ccgVertIterator_getCurrent(vi);
 
-               ccgdm->vertMap[(int) ccgSubSurf_getVertVertHandle(ss, v)].vert = v;
+               ccgdm->vertMap[GET_INT_FROM_POINTER(ccgSubSurf_getVertVertHandle(ss, v))].vert = v;
        }
        ccgVertIterator_free(vi);
 
@@ -2176,7 +2176,7 @@ static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss,
        for(; !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) {
                CCGEdge *e = ccgEdgeIterator_getCurrent(ei);
 
-               ccgdm->edgeMap[(int) ccgSubSurf_getEdgeEdgeHandle(ss, e)].edge = e;
+               ccgdm->edgeMap[GET_INT_FROM_POINTER(ccgSubSurf_getEdgeEdgeHandle(ss, e))].edge = e;
        }
 
        totface = ccgSubSurf_getNumFaces(ss);
@@ -2185,7 +2185,7 @@ static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss,
        for(; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) {
                CCGFace *f = ccgFaceIterator_getCurrent(fi);
 
-               ccgdm->faceMap[(int) ccgSubSurf_getFaceFaceHandle(ss, f)].face = f;
+               ccgdm->faceMap[GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(ss, f))].face = f;
        }
        ccgFaceIterator_free(fi);
 
@@ -2218,7 +2218,7 @@ static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss,
                int numVerts = ccgSubSurf_getFaceNumVerts(ss, f);
                int numFinalEdges = numVerts * (gridSideEdges + gridInternalEdges);
                int mapIndex = ccgDM_getFaceMapIndex(ccgdm, ss, f);
-               int origIndex = (int)ccgSubSurf_getFaceFaceHandle(ss, f);
+               int origIndex = GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(ss, f));
                FaceVertWeight *weight = (numVerts == 4) ? qweight : tweight;
                int S, x, y;
                int vertIdx[4];
@@ -2233,7 +2233,7 @@ static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss,
                for(S = 0; S < numVerts; S++) {
                        CCGVert *v = ccgSubSurf_getFaceVert(ss, f, S);
 
-                       vertIdx[S] = (int)ccgSubSurf_getVertVertHandle(ss, v);
+                       vertIdx[S] = GET_INT_FROM_POINTER(ccgSubSurf_getVertVertHandle(ss, v));
                }
 
                DM_interp_vert_data(dm, &ccgdm->dm, vertIdx, weight[0][0],
@@ -2339,13 +2339,13 @@ static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss,
                int mapIndex = ccgDM_getEdgeMapIndex(ccgdm, ss, e);
                int x;
                int vertIdx[2];
-               int edgeIdx = (int)ccgSubSurf_getEdgeEdgeHandle(ss, e);
+               int edgeIdx = GET_INT_FROM_POINTER(ccgSubSurf_getEdgeEdgeHandle(ss, e));
 
                CCGVert *v;
                v = ccgSubSurf_getEdgeVert0(ss, e);
-               vertIdx[0] = (int)ccgSubSurf_getVertVertHandle(ss, v);
+               vertIdx[0] = GET_INT_FROM_POINTER(ccgSubSurf_getVertVertHandle(ss, v));
                v = ccgSubSurf_getEdgeVert1(ss, e);
-               vertIdx[1] = (int)ccgSubSurf_getVertVertHandle(ss, v);
+               vertIdx[1] = GET_INT_FROM_POINTER(ccgSubSurf_getVertVertHandle(ss, v));
 
                ccgdm->edgeMap[index].startVert = vertNum;
                ccgdm->edgeMap[index].startEdge = edgeNum;
@@ -2379,7 +2379,7 @@ static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss,
                int mapIndex = ccgDM_getVertMapIndex(ccgdm, ccgdm->ss, v);
                int vertIdx;
 
-               vertIdx = (int)ccgSubSurf_getVertVertHandle(ss, v);
+               vertIdx = GET_INT_FROM_POINTER(ccgSubSurf_getVertVertHandle(ss, v));
 
                ccgdm->vertMap[index].startVert = vertNum;
 
@@ -2512,7 +2512,7 @@ void subsurf_calculate_limit_positions(Mesh *me, float (*positions_r)[3])
        vi = ccgSubSurf_getVertIterator(ss);
        for (; !ccgVertIterator_isStopped(vi); ccgVertIterator_next(vi)) {
                CCGVert *v = ccgVertIterator_getCurrent(vi);
-               int idx = (int) ccgSubSurf_getVertVertHandle(ss, v);
+               int idx = GET_INT_FROM_POINTER(ccgSubSurf_getVertVertHandle(ss, v));
                int N = ccgSubSurf_getVertNumEdges(ss, v);
                int numFaces = ccgSubSurf_getVertNumFaces(ss, v);
                float *co;