diff options
author | Daniel Dunbar <daniel@zuster.org> | 2005-07-20 08:14:21 +0400 |
---|---|---|
committer | Daniel Dunbar <daniel@zuster.org> | 2005-07-20 08:14:21 +0400 |
commit | 259c7b6cad39720dd98044e90238f130716485c7 (patch) | |
tree | 72f4cb7fd4ceae3250c607ba594254ce52a6fecb /source/blender/blenkernel | |
parent | ca1873df56db3a28fd650b132bdf74b992d0232c (diff) |
- added modifier_dependsOnTime to check if modifier needs updating
based on time change. would be nice if dep graph could handle this.
- made dep check if modifiers need update on time change
- fix render crash (access null)
- added new Build Effect modifier type. compared to old one works as
a full member of modifier system, means can apply subsurf, etc on
it, reorder, what have you. and it is all nice and self contained.
- removed old Build effect, old files convert to new style on load
- couldn't help myself, added a randomize feature to build effect
- removed Python BuildEffect support
Diffstat (limited to 'source/blender/blenkernel')
-rw-r--r-- | source/blender/blenkernel/BKE_effect.h | 1 | ||||
-rw-r--r-- | source/blender/blenkernel/BKE_modifier.h | 10 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/DerivedMesh.c | 48 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/depsgraph.c | 12 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/effect.c | 33 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/modifier.c | 243 |
6 files changed, 279 insertions, 68 deletions
diff --git a/source/blender/blenkernel/BKE_effect.h b/source/blender/blenkernel/BKE_effect.h index 4ed2febc0d7..df413fe5c9d 100644 --- a/source/blender/blenkernel/BKE_effect.h +++ b/source/blender/blenkernel/BKE_effect.h @@ -50,7 +50,6 @@ struct Effect *copy_effect(struct Effect *eff); void copy_act_effect(struct Object *ob); void copy_effects(struct ListBase *lbn, struct ListBase *lb); void deselectall_eff(struct Object *ob); -void set_buildvars(struct Object *ob, int *start, int *end); struct Particle *new_particle(struct PartEff *paf); struct PartEff *give_parteff(struct Object *ob); void where_is_particle(struct PartEff *paf, struct Particle *pa, float ctime, float *vec); diff --git a/source/blender/blenkernel/BKE_modifier.h b/source/blender/blenkernel/BKE_modifier.h index fab705a3a8c..94c847d50d8 100644 --- a/source/blender/blenkernel/BKE_modifier.h +++ b/source/blender/blenkernel/BKE_modifier.h @@ -1,6 +1,6 @@ /** * - * $$ + * $Id$ * * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** * @@ -88,6 +88,12 @@ typedef struct ModifierTypeInfo { */ void (*updateDepgraph)(struct ModifierData *md, struct DagForest *forest, struct Object *ob, struct DagNode *obNode); + /* Should return true if the modifier needs to be recalculated on time changes. + * + * This function is optional (assumes false if not present). + */ + int (*dependsOnTime)(struct ModifierData *md); + /* Only for deform types, should apply the deformation * to the given vertex array. Object is guaranteed to be * non-NULL. @@ -121,5 +127,7 @@ typedef struct ModifierTypeInfo { ModifierTypeInfo *modifierType_get_info(ModifierType type); +int modifier_dependsOnTime(struct ModifierData *md); + #endif diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c index 4f89e8e5634..8dfe4d0c2ef 100644 --- a/source/blender/blenkernel/intern/DerivedMesh.c +++ b/source/blender/blenkernel/intern/DerivedMesh.c @@ -148,12 +148,10 @@ static void meshDM_drawVerts(DerivedMesh *dm) { MeshDerivedMesh *mdm = (MeshDerivedMesh*) dm; Mesh *me = mdm->me; - int a, start=0, end=me->totvert; - - if (mdm->ob) set_buildvars(mdm->ob, &start, &end); + int a; glBegin(GL_POINTS); - for(a= start; a<end; a++) { + for(a=0; a<me->totvert; a++) { glVertex3fv(mdm->verts[ a].co); } glEnd(); @@ -162,15 +160,10 @@ static void meshDM_drawEdges(DerivedMesh *dm) { MeshDerivedMesh *mdm = (MeshDerivedMesh*) dm; Mesh *me= mdm->me; - int a, start= 0, end= me->totface; + int a; MFace *mface = me->mface; - if (mdm->ob) set_buildvars(mdm->ob, &start, &end); - mface+= start; - - // edges can't cope with buildvars, draw with - // faces if build is in use. - if(me->medge && start==0 && end==me->totface) { + if(me->medge) { MEdge *medge= me->medge; glBegin(GL_LINES); @@ -184,7 +177,7 @@ static void meshDM_drawEdges(DerivedMesh *dm) } else { glBegin(GL_LINES); - for(a=start; a<end; a++, mface++) { + for(a=0; a<me->totface; a++, mface++) { int test= mface->edcode; if(test) { @@ -225,13 +218,10 @@ static void meshDM_drawLooseEdges(DerivedMesh *dm) MeshDerivedMesh *mdm = (MeshDerivedMesh*) dm; Mesh *me = mdm->me; MFace *mface= me->mface; - int a, start=0, end=me->totface; + int a; - if (mdm->ob) set_buildvars(mdm->ob, &start, &end); - mface+= start; - glBegin(GL_LINES); - for(a=start; a<end; a++, mface++) { + for(a=0; a<me->totface; a++, mface++) { if(!mface->v3) { glVertex3fv(mdm->verts[mface->v3].co); glVertex3fv(mdm->verts[mface->v4].co); @@ -246,12 +236,9 @@ static void meshDM_drawFacesSolid(DerivedMesh *dm, int (*setMaterial)(int)) MVert *mvert= mdm->verts; MFace *mface= me->mface; float *nors = mdm->nors; - int a, start=0, end=me->totface; + int a; int glmode=-1, shademodel=-1, matnr=-1, drawCurrentMat=1; - if (mdm->ob) set_buildvars(mdm->ob, &start, &end); - mface+= start; - #define PASSVERT(index, punoBit) { \ if (shademodel==GL_SMOOTH) { \ short *no = mvert[index].no; \ @@ -265,7 +252,7 @@ static void meshDM_drawFacesSolid(DerivedMesh *dm, int (*setMaterial)(int)) } glBegin(glmode=GL_QUADS); - for(a=start; a<end; a++, mface++, nors+=3) { + for(a=0; a<me->totface; a++, mface++, nors+=3) { if(mface->v3) { int new_glmode, new_matnr, new_shademodel; @@ -306,14 +293,9 @@ static void meshDM_drawFacesColored(DerivedMesh *dm, int useTwoSide, unsigned ch MeshDerivedMesh *mdm = (MeshDerivedMesh*) dm; Mesh *me= mdm->me; MFace *mface= me->mface; - int a, glmode, start=0, end=me->totface; + int a, glmode; unsigned char *cp1, *cp2; - if (mdm->ob) set_buildvars(mdm->ob, &start, &end); - mface+= start; - col1+= 4*start; - if(col2) col2+= 4*start; - cp1= col1; if(col2) { cp2= col2; @@ -330,7 +312,7 @@ static void meshDM_drawFacesColored(DerivedMesh *dm, int useTwoSide, unsigned ch glShadeModel(GL_SMOOTH); glBegin(glmode=GL_QUADS); - for(a=start; a<end; a++, mface++, cp1+= 16) { + for(a=0; a<me->totface; a++, mface++, cp1+= 16) { if(mface->v3) { int new_glmode= mface->v4?GL_QUADS:GL_TRIANGLES; @@ -379,11 +361,9 @@ static void meshDM_drawFacesTex(DerivedMesh *dm, int (*setDrawParams)(TFace *tf, MFace *mface= me->mface; TFace *tface = me->tface; float *nors = mdm->nors; - int a, start=0, end=me->totface; + int a; - if (mdm->ob) set_buildvars(mdm->ob, &start, &end); - - for (a=start; a<end; a++) { + for (a=0; a<me->totface; a++) { MFace *mf= &mface[a]; TFace *tf = tface?&tface[a]:NULL; unsigned char *cp= NULL; @@ -1016,7 +996,7 @@ DerivedMesh *derivedmesh_from_displistmesh(DispListMesh *dlm) static void mesh_calc_modifiers(Mesh *me, Object *ob, float (*inputVertexCos)[3], DerivedMesh **deform_r, DerivedMesh **final_r, int useRenderParams, int useDeform) { - ModifierData *md=ob->modifiers.first; + ModifierData *md= ob?ob->modifiers.first:NULL; float (*deformedVerts)[3]; DerivedMesh *dm; int a, numVerts = me->totvert; diff --git a/source/blender/blenkernel/intern/depsgraph.c b/source/blender/blenkernel/intern/depsgraph.c index 018ceac2bc4..a50eb21ecb7 100644 --- a/source/blender/blenkernel/intern/depsgraph.c +++ b/source/blender/blenkernel/intern/depsgraph.c @@ -1403,6 +1403,17 @@ void DAG_scene_flush_update(Scene *sce) } } +static int object_modifiers_use_time(Object *ob) +{ + ModifierData *md; + + for (md=ob->modifiers.first; md; md=md->next) + if (modifier_dependsOnTime(md)) + return 1; + + return 0; +} + /* flag all objects that need recalc, for changes in time for example */ void DAG_scene_update_flags(Scene *sce, unsigned int lay) { @@ -1426,6 +1437,7 @@ void DAG_scene_update_flags(Scene *sce, unsigned int lay) if(ob->action) ob->recalc |= OB_RECALC_DATA; else if(ob->nlastrips.first) ob->recalc |= OB_RECALC_DATA; else if(ob->softflag & OB_SB_ENABLE) ob->recalc |= OB_RECALC_DATA; + else if(object_modifiers_use_time(ob)) ob->recalc |= OB_RECALC_DATA; else { Mesh *me; Curve *cu; diff --git a/source/blender/blenkernel/intern/effect.c b/source/blender/blenkernel/intern/effect.c index 98810ede1ce..5dd63fddd44 100644 --- a/source/blender/blenkernel/intern/effect.c +++ b/source/blender/blenkernel/intern/effect.c @@ -83,20 +83,11 @@ Effect *add_effect(int type) { Effect *eff=0; - BuildEff *bld; PartEff *paf; WaveEff *wav; int a; switch(type) { - case EFF_BUILD: - bld= MEM_callocN(sizeof(BuildEff), "neweff"); - eff= (Effect *)bld; - - bld->sfra= 1.0; - bld->len= 100.0; - break; - case EFF_PARTICLE: paf= MEM_callocN(sizeof(PartEff), "neweff"); eff= (Effect *)paf; @@ -194,7 +185,7 @@ void copy_act_effect(Object *ob) } /* when it comes here: add new effect */ - eff= add_effect(EFF_BUILD); + eff= add_effect(EFF_PARTICLE); BLI_addtail(&ob->effect, eff); } @@ -225,28 +216,6 @@ void deselectall_eff(Object *ob) } } -void set_buildvars(Object *ob, int *start, int *end) -{ - BuildEff *bld; - float ctime; - - bld= ob->effect.first; - while(bld) { - if(bld->type==EFF_BUILD) { - ctime= bsystem_time(ob, 0, (float)G.scene->r.cfra, bld->sfra-1.0f); - if(ctime < 0.0) { - *end= *start; - } - else if(ctime < bld->len) { - *end= *start+ (int)((*end - *start)*ctime/bld->len); - } - - return; - } - bld= bld->next; - } -} - /* ***************** PARTICLES ***************** */ Particle *new_particle(PartEff *paf) diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c index 9bba515fbbf..d3d48a6f5f3 100644 --- a/source/blender/blenkernel/intern/modifier.c +++ b/source/blender/blenkernel/intern/modifier.c @@ -1,18 +1,24 @@ #include "string.h" +#include "BLI_rand.h" + #include "MEM_guardedalloc.h" #include "DNA_mesh_types.h" #include "DNA_meshdata_types.h" #include "DNA_modifier_types.h" #include "DNA_object_types.h" +#include "DNA_scene_types.h" +#include "BKE_global.h" #include "BKE_utildefines.h" #include "BKE_DerivedMesh.h" #include "BKE_displist.h" #include "BKE_modifier.h" #include "BKE_lattice.h" #include "BKE_subsurf.h" +#include "BKE_object.h" +#include "BKE_mesh.h" #include "depsgraph_private.h" /***/ @@ -145,6 +151,227 @@ static void *subsurfModifier_applyModifier(ModifierData *md, void *data, Object } } +/* Build */ + +static ModifierData *buildModifier_allocData(void) +{ + BuildModifierData *bmd = allocModifierData(eModifierType_Build, sizeof(BuildModifierData)); + + bmd->start = 1.0; + bmd->length = 100.0; + + return (ModifierData*) bmd; +} + +static int buildModifier_isDisabled(ModifierData *md) +{ + return 0; +} + +static int buildModifier_dependsOnTime(ModifierData *md) +{ + return 1; +} + +static void *buildModifier_applyModifier(ModifierData *md, void *data, Object *ob, DerivedMesh *dm, float (*vertexCos)[3], int useRenderParams) +{ + BuildModifierData *bmd = (BuildModifierData*) md; + DispListMesh *dlm=NULL, *ndlm = MEM_callocN(sizeof(*ndlm), "build_dlm"); + MVert *mvert; + MEdge *medge; + MFace *mface; + MCol *mcol; + TFace *tface; + int totvert, totedge, totface; + int i,j; + float frac; + + if (dm) { + dlm = dm->convertToDispListMesh(dm); + mvert = dlm->mvert; + medge = dlm->medge; + mface = dlm->mface; + mcol = dlm->mcol; + tface = dlm->tface; + totvert = dlm->totvert; + totedge = dlm->totedge; + totface = dlm->totface; + } else { + Mesh *me = data; + mvert = me->mvert; + medge = me->medge; + mface = me->mface; + mcol = me->mcol; + tface = me->tface; + totvert = me->totvert; + totedge = me->totedge; + totface = me->totface; + } + + if (ob) { + frac = bsystem_time(ob, 0, (float)G.scene->r.cfra, bmd->start-1.0f)/bmd->length; + } else { + frac = G.scene->r.cfra - bmd->start/bmd->length; + } + CLAMP(frac, 0.0, 1.0); + + ndlm->totface = totface*frac; + ndlm->totedge = totedge*frac; + if (ndlm->totface) { + ndlm->mvert = MEM_mallocN(sizeof(*ndlm->mvert)*totvert, "build_mvert"); + memcpy(ndlm->mvert, mvert, sizeof(*mvert)*totvert); + for (i=0; i<totvert; i++) { + ndlm->mvert[i].flag = 0; + } + + if (bmd->randomize) { + ndlm->mface = MEM_dupallocN(mface); + BLI_array_randomize(ndlm->mface, sizeof(*mface), totface, bmd->seed); + + if (tface) { + ndlm->tface = MEM_dupallocN(tface); + BLI_array_randomize(ndlm->tface, sizeof(*tface), totface, bmd->seed); + } else if (mcol) { + ndlm->mcol = MEM_dupallocN(mcol); + BLI_array_randomize(ndlm->mcol, sizeof(*mcol)*4, totface, bmd->seed); + } + } else { + ndlm->mface = MEM_mallocN(sizeof(*ndlm->mface)*ndlm->totface, "build_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]; + + ndlm->mvert[mf->v1].flag = 1; + ndlm->mvert[mf->v2].flag = 1; + if (mf->v3) { + ndlm->mvert[mf->v3].flag = 1; + if (mf->v4) ndlm->mvert[mf->v4].flag = 1; + } + } + + /* Store remapped indices in *((int*) mv->no) */ + ndlm->totvert = 0; + for (i=0; i<totvert; i++) { + MVert *mv = &ndlm->mvert[i]; + + if (mv->flag) + *((int*) mv->no) = ndlm->totvert++; + } + + /* Remap face vertex indices */ + for (i=0; i<ndlm->totface; i++) { + MFace *mf = &ndlm->mface[i]; + + mf->v1 = *((int*) ndlm->mvert[mf->v1].no); + mf->v2 = *((int*) ndlm->mvert[mf->v2].no); + if (mf->v3) { + mf->v3 = *((int*) ndlm->mvert[mf->v3].no); + if (mf->v4) mf->v4 = *((int*) ndlm->mvert[mf->v4].no); + } + } + /* Copy in all edges that have both vertices (remap in process) */ + if (totedge) { + ndlm->totedge = 0; + ndlm->medge = MEM_mallocN(sizeof(*ndlm->medge)*totedge, "build_med"); + + for (i=0; i<totedge; i++) { + MEdge *med = &medge[i]; + + if (ndlm->mvert[med->v1].flag && ndlm->mvert[med->v2].flag) { + MEdge *nmed = &ndlm->medge[ndlm->totedge++]; + + memcpy(nmed, med, sizeof(*med)); + + nmed->v1 = *((int*) ndlm->mvert[nmed->v1].no); + nmed->v2 = *((int*) ndlm->mvert[nmed->v2].no); + } + } + } + + /* Collapse vertex array to remove unused verts */ + for(i=j=0; i<totvert; i++) { + MVert *mv = &ndlm->mvert[i]; + + if (mv->flag) { + if (j!=i) + memcpy(&ndlm->mvert[j], mv, sizeof(*mv)); + j++; + } + } + } else if (ndlm->totedge) { + ndlm->mvert = MEM_mallocN(sizeof(*ndlm->mvert)*totvert, "build_mvert"); + memcpy(ndlm->mvert, mvert, sizeof(*mvert)*totvert); + for (i=0; i<totvert; i++) { + ndlm->mvert[i].flag = 0; + } + + if (bmd->randomize) { + ndlm->medge = MEM_dupallocN(medge); + BLI_array_randomize(ndlm->medge, sizeof(*medge), totedge, bmd->seed); + } else { + ndlm->medge = MEM_mallocN(sizeof(*ndlm->medge)*ndlm->totedge, "build_mf"); + memcpy(ndlm->medge, medge, sizeof(*medge)*ndlm->totedge); + } + + for (i=0; i<ndlm->totedge; i++) { + MEdge *med = &ndlm->medge[i]; + + ndlm->mvert[med->v1].flag = 1; + ndlm->mvert[med->v2].flag = 1; + } + + /* Store remapped indices in *((int*) mv->no) */ + ndlm->totvert = 0; + for (i=0; i<totvert; i++) { + MVert *mv = &ndlm->mvert[i]; + + if (mv->flag) + *((int*) mv->no) = ndlm->totvert++; + } + + /* Remap edge vertex indices */ + for (i=0; i<ndlm->totedge; i++) { + MEdge *med = &ndlm->medge[i]; + + med->v1 = *((int*) ndlm->mvert[med->v1].no); + med->v2 = *((int*) ndlm->mvert[med->v2].no); + } + + /* Collapse vertex array to remove unused verts */ + for(i=j=0; i<totvert; i++) { + MVert *mv = &ndlm->mvert[i]; + + if (mv->flag) { + if (j!=i) + memcpy(&ndlm->mvert[j], mv, sizeof(*mv)); + j++; + } + } + } else { + ndlm->totvert = totvert*frac; + + ndlm->mvert = MEM_mallocN(sizeof(*ndlm->mvert)*ndlm->totvert, "build_mvert"); + memcpy(ndlm->mvert, mvert, sizeof(*mvert)*ndlm->totvert); + } + + if (dm) dm->release(dm); + if (dlm) displistmesh_free(dlm); + + mesh_calc_normals(ndlm->mvert, ndlm->totvert, ndlm->mface, ndlm->totface, &ndlm->nors); + + return derivedmesh_from_displistmesh(ndlm); +} + /***/ static ModifierTypeInfo typeArr[NUM_MODIFIER_TYPES]; @@ -194,6 +421,16 @@ ModifierTypeInfo *modifierType_get_info(ModifierType type) mti->isDisabled = subsurfModifier_isDisabled; mti->applyModifier = subsurfModifier_applyModifier; + mti = &typeArr[eModifierType_Build]; + strcpy(mti->name, "Build"); + strcpy(mti->structName, "BuildModifierData"); + mti->type = eModifierTypeType_Nonconstructive; + mti->flags = eModifierTypeFlag_AcceptsMesh; + mti->allocData = buildModifier_allocData; + mti->isDisabled = buildModifier_isDisabled; + mti->dependsOnTime = buildModifier_dependsOnTime; + mti->applyModifier = buildModifier_applyModifier; + typeArrInit = 0; } @@ -204,3 +441,9 @@ ModifierTypeInfo *modifierType_get_info(ModifierType type) } } +int modifier_dependsOnTime(ModifierData *md) +{ + ModifierTypeInfo *mti = modifierType_get_info(md->type); + + return mti->dependsOnTime && mti->dependsOnTime(md); +} |