Page MenuHome

explodemod_1.patch

File Metadata

Author
Janne Karhu (jhk)
Created
Nov 13 2013, 12:56 PM

explodemod_1.patch

Index: source/blender/blenkernel/intern/modifier.c
===================================================================
RCS file: /cvsroot/bf-blender/blender/source/blender/blenkernel/intern/modifier.c,v
retrieving revision 1.43
diff -u -r1.43 modifier.c
--- source/blender/blenkernel/intern/modifier.c 24 Sep 2005 20:17:48 -0000 1.43
+++ source/blender/blenkernel/intern/modifier.c 10 Oct 2005 14:59:51 -0000
@@ -30,6 +30,7 @@
#include "BKE_mesh.h"
#include "BKE_softbody.h"
#include "depsgraph_private.h"
+#include "BKE_effect.h"
#include "LOD_DependKludge.h"
#include "LOD_decimation.h"
@@ -964,6 +965,7 @@
waveModifier_deformVerts(md, ob, NULL, vertexCos, numVerts);
}
+
/* Armature */
static void armatureModifier_copyData(ModifierData *md, ModifierData *target)
@@ -1197,6 +1199,368 @@
return derivedmesh_from_displistmesh(dlm, NULL);
}
+/* Explode */
+
+static void explodeModifier_initData(ModifierData *md)
+{
+ ExplodeModifierData *emd = (ExplodeModifierData*) md;
+
+ emd->curvrot = 0.0f;
+ emd->dirrot = 0.0f;
+ emd->randrot = 0.0f;
+ emd->seed = 0;
+ emd->rand = 0.0f;
+ emd->dist = 0.0f;
+ emd->flag = 0;
+}
+
+static void explodeModifier_copyData(ModifierData *md, ModifierData *target)
+{
+ ExplodeModifierData *emd = (ExplodeModifierData*) md;
+ ExplodeModifierData *temd = (ExplodeModifierData*) target;
+
+ temd->curvrot = emd->curvrot;
+ temd->dirrot = emd->dirrot;
+ temd->randrot = emd->randrot;
+ temd->seed = emd->seed;
+ temd->rand = emd->rand;
+ temd->dist = emd->dist;
+ temd->flag = emd->flag;
+}
+
+static int explodeModifier_dependsOnTime(ModifierData *md)
+{
+ return 1;
+}
+static void *explodeModifier_applyModifier(ModifierData *md, Object *ob, void *derivedData, float (*vertexCos)[3], int useRenderParams, int isFinalCalc)
+{
+ ExplodeModifierData *emd = (ExplodeModifierData*) md;
+ DerivedMesh *dm = derivedData;
+ DispListMesh *dlm=NULL, *ndlm = MEM_callocN(sizeof(*ndlm), "explode_dlm");
+ MVert *mvert;
+ MVert *dupverts;
+ MEdge *medge;
+ MFace *mface;
+ MCol *mcol;
+ TFace *tface;
+ PartEff * paf = (PartEff*)(ob->effect.first);
+ RNG *rng;
+
+ int *vtop = 0, *vpart = 0, *fpart = 0;
+ int totvert, totedge, totface, i,j, totdups = 0;
+ float *fnors = 0, *pnors = 0, *pdist = 0, *prandv = 0, *prand = 0;
+ float imat[4][4], irot[4][4], rotmat[4][4];
+ float ctime = 0.0f;
+
+ /*check input*/
+ if (dm) {
+ dlm = dm->convertToDispListMesh(dm, 1);
+ mvert = MEM_callocN(sizeof(*mvert)*dlm->totvert, "explode_mvert");
+ memcpy(mvert, dlm->mvert, sizeof(*mvert)*dlm->totvert);
+ medge = dlm->medge;
+ mface = dlm->mface;
+ mcol = dlm->mcol;
+ tface = dlm->tface;
+ totvert = dlm->totvert;
+ totedge = dlm->totedge;
+ totface = dlm->totface;
+ } else {
+ Mesh *me = ob->data;
+ mvert = MEM_callocN(sizeof(*mvert)*me->totvert, "explode_mvert");
+ memcpy(mvert, me->mvert, sizeof(*mvert)*me->totvert);
+ medge = me->medge;
+ mface = me->mface;
+ mcol = me->mcol;
+ tface = me->tface;
+ totvert = me->totvert;
+ totedge = me->totedge;
+ totface = me->totface;
+ }
+
+ /*apply possible deform*/
+ if(vertexCos) for(i=0; i<totvert; i++)
+ VECCOPY(mvert[i].co,vertexCos[i]);
+
+ ndlm->totface = totface;
+ ndlm->totedge = totedge;
+ ndlm->totvert = totvert;
+
+ if(ob->ipoflag & OB_OFFS_PARTICLE) ctime = ob->sf;
+ ctime = bsystem_time(ob, 0, (float)G.scene->r.cfra, ctime);
+
+ /*just to make sure & if no particles copypaste input i.e. do nothing*/
+ /*doesn't work with isDisabled because it has no knowledge of ob (-->paf)*/
+ if(totface==0 || totvert==0 || paf==0 || paf->keys==0 || ctime < paf->sta || (paf->flag & PAF_DEFORM)==0) {
+ ndlm->mvert = MEM_callocN(sizeof(*mvert)*totvert, "explode_mvert");
+ memcpy(ndlm->mvert, mvert, sizeof(*mvert)*ndlm->totvert);
+
+ ndlm->mface = MEM_callocN(sizeof(*mface)*totface, "explode_mface");
+ memcpy(ndlm->mface, mface, sizeof(*mface)*ndlm->totface);
+
+ ndlm->medge = MEM_callocN(sizeof(*medge)*totedge, "explode_medge");
+ memcpy(ndlm->medge, medge, sizeof(*medge)*ndlm->totedge);
+
+ mesh_calc_normals(ndlm->mvert, ndlm->totvert, ndlm->mface, ndlm->totface, &ndlm->nors);
+
+ ndlm->tface = tface;
+ ndlm->mcol = mcol;
+ if (dlm) displistmesh_free(dlm);
+ if(mvert) MEM_freeN(mvert);
+ return derivedmesh_from_displistmesh(ndlm, NULL);
+ }
+
+ rng = rng_new(31415926 + emd->seed);
+ prandv = MEM_callocN(sizeof(float)*3*paf->totpart, "explode_prand");
+ prand = MEM_callocN(sizeof(float)*paf->totpart, "explode_frand");
+
+ /*initialize randoms*/
+ for(i=0; i<paf->totpart; i++) {
+ prandv[i*3] = rng_getFloat(rng);
+ prandv[i*3+1] = rng_getFloat(rng);
+ prandv[i*3+2] = rng_getFloat(rng);
+ prand[i]=rng_getFloat(rng);
+ }
+
+ /*create matrice from ob to global & only rotation matrice*/
+ inv_m4_m4(imat,ob->obmat);
+ cpy_m4_m4(irot,imat);
+ cpy_m4_m4(rotmat,ob->obmat);
+ irot[3][0] = irot[3][1] = irot[3][2] = 0.0;
+ rotmat[3][0] = rotmat[3][1] = rotmat[3][2] = 0.0;
+
+ mesh_calc_normals(mvert, totvert, mface, totface, &fnors);
+
+ /*initial particle group normals*/
+ pnors = MEM_callocN(sizeof(float)*3*paf->totpart, "explode_pnors");
+
+ pdist = MEM_callocN(sizeof(float)*paf->totpart, "explode_pdist");
+ for(i=0; i<paf->totpart; i++){
+ pdist[i] = 100.0f;
+ }
+
+ /*+1 is for untouched vertices*/
+ vtop = MEM_callocN(sizeof(int)*(paf->totpart+1)*totvert, "explode_vtop");
+ for(i=0; i<paf->totpart*totvert; i++){
+ vtop[i] = -1;
+ }
+
+ /*the particle nr associated with face*/
+ fpart = MEM_mallocN(sizeof(*fpart)*totface, "explode_fpart");
+
+ ndlm->mface = MEM_mallocN(sizeof(*ndlm->mface)*ndlm->totface, "explode_mf");
+ memcpy(ndlm->mface, mface, sizeof(*mface)*ndlm->totface);
+
+ if (tface) {
+ ndlm->tface = MEM_mallocN(sizeof(*ndlm->tface)*ndlm->totface, "build_tf");
+ memcpy(ndlm->tface, tface, sizeof(*tface)*ndlm->totface);
+ } else if (mcol) {
+ ndlm->mcol = MEM_mallocN(sizeof(*ndlm->mcol)*4*ndlm->totface, "build_mcol");
+ memcpy(ndlm->mcol, mcol, sizeof(*mcol)*4*ndlm->totface);
+ }
+
+ for (i=0; i<ndlm->totface; i++) {
+ MFace *mf = &ndlm->mface[i];
+ float fcenter[3], cdist,mdist = 100.0;
+ int mindex = 0;
+
+ /*calculate face center*/
+ VECCOPY(fcenter,mvert[mf->v1].co);
+ VECADD(fcenter,fcenter,mvert[mf->v2].co);
+ VECADD(fcenter,fcenter,mvert[mf->v3].co);
+ if(mf->v4) {
+ VECADD(fcenter,fcenter,mvert[mf->v4].co);
+ VecMulf(fcenter, 1.0/4.0);
+ }
+ else {
+ VecMulf(fcenter, 1.0/3.0);
+ }
+
+ Mat4MulVecfl(ob->obmat,fcenter);
+
+ /*find particle (at birth location) closest to face center*/
+ for(j=0; j<paf->totpart; j++) {
+ cdist = VecLenf(paf->keys[j*(paf->totkey)].co,fcenter);
+ if(cdist < mdist) {
+ mdist = cdist;
+ mindex = j;
+ }
+ }
+
+ if(ctime < paf->keys[mindex*(paf->totkey)].time || (emd->dist != 0.0 && mdist > emd->dist)) {
+ mindex = paf->totpart;
+ }
+ else {
+ /*set pnors to closest face normal in particle group*/
+ if(mdist < pdist[mindex]){
+ VECCOPY(pnors + 3*mindex,fnors + i*3);
+ pdist[mindex] = mdist;
+ }
+ }
+
+ fpart[i] = mindex;
+
+ /*set face vertices to exist in particle group*/
+ vtop[mindex*totvert+mf->v1] = 1;
+ vtop[mindex*totvert+mf->v2] = 1;
+ vtop[mindex*totvert+mf->v3] = 1;
+ if(mf->v4)
+ vtop[mindex*totvert+mf->v4] = 1;
+ }
+
+ /*make new vertice indexes & count total vertices after duplication*/
+ for(i=0; i<(paf->totpart+1)*totvert; i++){
+ if(vtop[i] != -1) {
+ vtop[i] = totdups++;
+ }
+ }
+
+ /*the final duplicated vertices*/
+ dupverts = MEM_mallocN(sizeof(*dupverts)*totdups, "explode_dupverts");
+
+ /*vertices' particle group*/
+ vpart = MEM_mallocN(sizeof(*vpart)*totdups, "explode_vpart");
+
+ /*duplicate vertices*/
+ for(i=0; i<paf->totpart+1; i++){
+ for(j=0; j<totvert; j++)
+ if(vtop[i*totvert+j] != -1) {
+ memcpy(dupverts + vtop[i*totvert+j], mvert + j, sizeof(*mvert));
+ vpart[vtop[i*totvert+j]] = i;
+ }
+ }
+
+ /*map new vertices to faces*/
+ for (i=0; i<ndlm->totface; i++) {
+ MFace *mf = &ndlm->mface[i];
+
+ mf->v1 = vtop[fpart[i]*totvert+mf->v1];
+ mf->v2 = vtop[fpart[i]*totvert+mf->v2];
+ mf->v3 = vtop[fpart[i]*totvert+mf->v3];
+ if(mf->v4)
+ mf->v4 = vtop[fpart[i]*totvert+mf->v4];
+ }
+
+ /*move vertices according to their particle groups*/
+ for (i=0; i<totdups; i++){
+ float vec[3];
+
+ Particle * pa = 0;
+
+ if(vpart[i] == paf->totpart) continue;
+
+ pa = paf->keys + vpart[i]*(paf->totkey);
+
+ where_is_particle(paf,pa,ctime,vec);
+ VECSUB(vec,vec,pa->co);
+ Mat4MulVecfl(irot,vec);
+
+ if(paf->stype==PAF_VECT && ctime > pa->time) {
+ float origo[3], nor[3], vec1[3], axis[3], mat[3][3], *q2, angle = 0.0f;
+
+ VECCOPY(origo,pa->co);
+ Mat4MulVecfl(imat, origo);
+ VECSUB(dupverts[i].co,dupverts[i].co,origo);
+
+ /*get particle normal*/
+ if(G.scene->r.cfra>pa->time+pa->lifetime) {
+ where_is_particle(paf,pa,ctime+0.1,vec1);
+ VECSUB(vec1,vec1,pa->co);
+ }
+ else {
+ vec1[0] = (float)((pa+paf->totkey-1)->no[0]);
+ vec1[1] = (float)((pa+paf->totkey-1)->no[1]);
+ vec1[2] = (float)((pa+paf->totkey-1)->no[2]);
+ }
+ Mat4MulVecfl(irot, vec1);
+
+ nor[0] = (float)(pnors[vpart[i]*3]);
+ nor[1] = (float)(pnors[vpart[i]*3+1]);
+ nor[2] = (float)(pnors[vpart[i]*3+2]);
+
+ Mat4MulVecfl(irot, nor);
+ Normalise(nor);
+ Normalise(vec1);
+ Crossf(axis,nor,vec1);
+ Normalise(axis);
+
+ if(emd->flag & eExplodeModifierFlag_FollowVec) {
+ angle = saacos(Inpf(nor,vec1));
+ if(angle < 0.001)
+ angle = 0.0;
+ }
+
+ if(ctime < pa->time+pa->lifetime)
+ angle += emd->curvrot*(ctime-pa->time)/pa->lifetime;
+ else
+ angle = emd->curvrot;
+
+ if(emd->rand!=0.0) {
+ angle*= 1.0f + emd->rand*(prand[vpart[i]] - 0.5f);
+ }
+
+ VecRotToMat3(axis,angle,mat);
+
+ Mat3MulVecfl(mat, dupverts[i].co);
+
+ if(emd->dirrot != 0.0) {
+ if(ctime < pa->time+pa->lifetime)
+ angle = emd->dirrot*(ctime-pa->time)/pa->lifetime;
+ else
+ angle = emd->dirrot;
+
+ if(emd->rand!=0.0) {
+ angle*= 1.0f + emd->rand*(prand[vpart[i]] - 0.5f);
+ }
+ VecRotToMat3(nor,angle,mat);
+
+ Mat3MulVecfl(mat, dupverts[i].co);
+ }
+
+ if(emd->randrot != 0.0) {
+ if(ctime < pa->time+pa->lifetime)
+ angle = emd->randrot*(ctime-pa->time)/pa->lifetime;
+ else
+ angle = emd->randrot;
+
+ if(emd->rand!=0.0) {
+ angle*= 1.0f + emd->rand*(prand[vpart[i]] - 0.5f);
+ }
+
+ axis[0] = prandv[vpart[i]*3];
+ axis[1] = prandv[vpart[i]*3+1];
+ axis[2] = prandv[vpart[i]*3+2];
+
+ VecRotToMat3(axis,angle,mat);
+
+ Mat3MulVecfl(mat, dupverts[i].co);
+ }
+ VECADD(dupverts[i].co,dupverts[i].co,origo);
+ }
+ VECADD(dupverts[i].co,dupverts[i].co,vec);
+ }
+
+ if (dlm) displistmesh_free(dlm);
+
+ ndlm->mvert = dupverts;
+ ndlm->totvert = totdups;
+
+ rng_free(rng);
+ if(fnors) MEM_freeN(fnors);
+ if(pnors) MEM_freeN(pnors);
+ if(pdist) MEM_freeN(pdist);
+ if(prandv) MEM_freeN(prandv);
+ if(prand) MEM_freeN(prand);
+ if(vpart) MEM_freeN(vpart);
+ if(vtop) MEM_freeN(vtop);
+ if(mvert) MEM_freeN(mvert);
+ if(fpart) MEM_freeN(fpart);
+
+ displistmesh_add_edges(ndlm);
+ mesh_calc_normals(ndlm->mvert, ndlm->totvert, ndlm->mface, ndlm->totface, &ndlm->nors);
+
+ return derivedmesh_from_displistmesh(ndlm, NULL);
+}
+
/***/
static ModifierTypeInfo typeArr[NUM_MODIFIER_TYPES];
@@ -1325,6 +1689,14 @@
mti->foreachObjectLink = booleanModifier_foreachObjectLink;
mti->updateDepgraph = booleanModifier_updateDepgraph;
+ mti = INIT_TYPE(Explode);
+ mti->type = eModifierTypeType_Nonconstructive;
+ mti->flags = eModifierTypeFlag_AcceptsMesh;
+ mti->initData = explodeModifier_initData;
+ mti->copyData = explodeModifier_copyData;
+ mti->dependsOnTime = explodeModifier_dependsOnTime;
+ mti->applyModifier = explodeModifier_applyModifier;
+
typeArrInit = 0;
#undef INIT_TYPE
}
Index: source/blender/makesdna/DNA_modifier_types.h
===================================================================
RCS file: /cvsroot/bf-blender/blender/source/blender/makesdna/DNA_modifier_types.h,v
retrieving revision 1.13
diff -u -r1.13 DNA_modifier_types.h
--- source/blender/makesdna/DNA_modifier_types.h 24 Sep 2005 20:17:48 -0000 1.13
+++ source/blender/makesdna/DNA_modifier_types.h 10 Oct 2005 14:59:51 -0000
@@ -18,6 +18,8 @@
eModifierType_Hook,
eModifierType_Softbody,
eModifierType_Boolean,
+ eModifierType_Displace,
+ eModifierType_Explode,
NUM_MODIFIER_TYPES
} ModifierType;
@@ -137,5 +139,15 @@
struct Object *object;
int operation, pad;
} BooleanModifierData;
+
+typedef enum {
+ eExplodeModifierFlag_FollowVec = (1<<0)
+} ExplodeModifierFlag;
+
+typedef struct ExplodeModifierData {
+ ModifierData modifier;
+ float curvrot, dirrot, randrot, rand, dist, pad;
+ int seed, flag;
+} ExplodeModifierData;
#endif
Index: source/blender/src/buttons_editing.c
===================================================================
RCS file: /cvsroot/bf-blender/blender/source/blender/src/buttons_editing.c,v
retrieving revision 1.216
diff -u -r1.216 buttons_editing.c
--- source/blender/src/buttons_editing.c 4 Oct 2005 15:58:25 -0000 1.216
+++ source/blender/src/buttons_editing.c 10 Oct 2005 15:05:45 -0000
@@ -1231,6 +1231,8 @@
height = 26;
} else if (md->type==eModifierType_Boolean) {
height = 46;
+ } else if (md->type==eModifierType_Explode) {
+ height = 200;
}
/* roundbox 4 free variables: corner-rounding, nop, roundbox type, shade */
@@ -1335,6 +1337,17 @@
BooleanModifierData *bmd = (BooleanModifierData*) md;
uiDefButI(block, MENU, B_MODIFIER_RECALC, "Operation%t|Intersect%x0|Union%x1|Difference%x2", lx,(cy-=19),buttonWidth,19, &bmd->operation, 0.0, 1.0, 0, 0, "Boolean operation to perform");
uiDefIDPoinBut(block, modifier_testMeshObj, B_CHANGEDEP, "Ob: ", lx, (cy-=19), buttonWidth,19, &bmd->object, "Mesh object to use for boolean operation");
+ } else if (md->type==eModifierType_Explode) {
+ ExplodeModifierData *emd = (ExplodeModifierData*) md;
+ uiDefButF(block, NUM, B_MODIFIER_RECALC, "Radius:", lx,(cy-=19),buttonWidth,19, &emd->dist, 0.0, 100.0, 100, 0, "Maximum radius for pieces, 0.0 is don't care");
+ uiDefBut(block, LABEL, 0, "Rotate around:", lx,(cy-=19),buttonWidth,19, NULL, 1.0, 0, 0, 0, "");
+ uiDefButF(block, NUM, B_MODIFIER_RECALC, "Dir:", lx,(cy-=19),buttonWidth,19, &emd->dirrot, 0.0, 100.0, 100, 0, "Rotate parts around particle normal");
+ uiDefButF(block, NUM, B_MODIFIER_RECALC, "Curv:", lx,(cy-=19),buttonWidth,19, &emd->curvrot, 0.0, 100.0, 100, 0, "Rotate parts in direction of particle path curvature");
+ uiDefButF(block, NUM, B_MODIFIER_RECALC, "Rand:", lx,(cy-=19),buttonWidth,19, &emd->randrot, 0.0, 100.0, 100, 0, "Rotate parts around random vector");
+ uiDefBut(block, LABEL, 0, "Rotation options:", lx,(cy-=19),buttonWidth,19, NULL, 1.0, 0, 0, 0, "");
+ uiDefButBitS(block, TOG, eExplodeModifierFlag_FollowVec, B_MODIFIER_RECALC, "Rotate to vec", lx, (cy-=19), buttonWidth,19,&emd->flag, 0, 0, 0, 0, "Rotate to particle normal");
+ uiDefButF(block, NUM, B_MODIFIER_RECALC, "RandAmnt:", lx,(cy-=19),buttonWidth,19, &emd->rand, 0.0, 1.0, 100, 0, "Individualization of rotations/part");
+ uiDefButI(block, NUM, B_CALCEFFECT, "Seed:", lx,(cy-=19),buttonWidth,19, &emd->seed, 0.0, 255.0, 0, 0, "Set an offset in the random table");
}
uiBlockEndAlign(block);

Event Timeline