From 4f8079d49cc0cc037ef429123ee6faf031b5c333 Mon Sep 17 00:00:00 2001 From: Ben Batt Date: Tue, 5 Dec 2006 17:42:03 +0000 Subject: [PATCH] Modifier Stack: Limit calculation to required data. This commit upgrades the modifier stack to only calculate the data which is needed, either by modifiers further down the stack or by other functions at the end of the stack (e.g. drawing functions). This speeds up modifier stack recalculation, especially where vertex groups and UV coordinates are concerned. For example, a mesh with an Armature modifier followed by a Subsurf modifier would previously have required the Subsurf modifier to interpolate all the vertex groups in the mesh, slowing down modifier calculations considerably. With this update, vertex group data is not propagated beyond the Armature modifier, so calculations are faster. Note that this depends on the order of modifiers in the stack. If the Armature and Subsurf modifiers were swapped in the above example, the Subsurf modifier would have to interpolate vertex groups, as they are needed by the Armature modifier. --- source/blender/blenkernel/BKE_DerivedMesh.h | 38 +++- source/blender/blenkernel/BKE_customdata.h | 23 ++- source/blender/blenkernel/BKE_displist.h | 3 +- source/blender/blenkernel/BKE_modifier.h | 29 ++- .../blender/blenkernel/intern/DerivedMesh.c | 166 ++++++++++++++---- source/blender/blenkernel/intern/anim.c | 8 +- source/blender/blenkernel/intern/customdata.c | 38 +++- source/blender/blenkernel/intern/displist.c | 8 +- source/blender/blenkernel/intern/exotic.c | 4 +- source/blender/blenkernel/intern/mesh.c | 4 +- source/blender/blenkernel/intern/modifier.c | 113 ++++++++++++ source/blender/blenkernel/intern/object.c | 2 +- source/blender/blenkernel/intern/softbody.c | 8 +- .../blender/blenkernel/intern/subsurf_ccg.c | 4 +- source/blender/blenlib/BLI_editVert.h | 4 + .../blender/makesdna/DNA_customdata_types.h | 12 ++ source/blender/makesdna/DNA_object_types.h | 2 + source/blender/python/api2_2x/Mesh.c | 4 +- source/blender/python/api2_2x/NMesh.c | 6 +- .../render/intern/source/convertblender.c | 3 +- source/blender/src/drawimage.c | 3 +- source/blender/src/drawmesh.c | 4 +- source/blender/src/drawobject.c | 21 ++- source/blender/src/editface.c | 2 +- source/blender/src/editmesh_mods.c | 2 +- source/blender/src/editobject.c | 2 +- source/blender/src/poseobject.c | 2 +- source/blender/src/transform_conversions.c | 4 +- source/blender/src/verse_object.c | 4 +- source/blender/src/vpaint.c | 2 +- 30 files changed, 418 insertions(+), 107 deletions(-) diff --git a/source/blender/blenkernel/BKE_DerivedMesh.h b/source/blender/blenkernel/BKE_DerivedMesh.h index 8a72b9ae2a9..f7c771394b8 100644 --- a/source/blender/blenkernel/BKE_DerivedMesh.h +++ b/source/blender/blenkernel/BKE_DerivedMesh.h @@ -46,6 +46,7 @@ */ #include "DNA_customdata_types.h" +#include "BKE_customdata.h" struct MVert; struct MEdge; @@ -295,6 +296,12 @@ int DM_release(DerivedMesh *dm); */ void DM_to_mesh(DerivedMesh *dm, struct Mesh *me); +/* set the CD_FLAG_NOCOPY flag in custom data layers where the mask is + * zero for the layer type, so only layer types specified by the mask + * will be copied + */ +void DM_set_only_copy(DerivedMesh *dm, CustomDataMask mask); + /* adds a vertex/edge/face custom data layer to a DerivedMesh, optionally * backed by an external data array * if layer != NULL, it is used as the layer data array, otherwise new memory @@ -337,7 +344,7 @@ void DM_set_face_data(struct DerivedMesh *dm, int index, int type, void *data); /* custom data copy functions * copy count elements from source_index in source to dest_index in dest - * these copy all layers for which the LAYERFLAG_NOCOPY flag is not set + * these copy all layers for which the CD_FLAG_NOCOPY flag is not set */ void DM_copy_vert_data(struct DerivedMesh *source, struct DerivedMesh *dest, int source_index, int dest_index, int count); @@ -396,21 +403,34 @@ void DM_swap_face_data(struct DerivedMesh *dm, int index, int *corner_indices); float *mesh_get_mapped_verts_nors(struct Object *ob); /* */ -DerivedMesh *mesh_get_derived_final(struct Object *ob); -DerivedMesh *mesh_get_derived_deform(struct Object *ob); +DerivedMesh *mesh_get_derived_final(struct Object *ob, + CustomDataMask dataMask); +DerivedMesh *mesh_get_derived_deform(struct Object *ob, + CustomDataMask dataMask); DerivedMesh *mesh_create_derived_for_modifier(struct Object *ob, struct ModifierData *md); -DerivedMesh *mesh_create_derived_render(struct Object *ob); -DerivedMesh *mesh_create_derived_view(struct Object *ob); /* same as above but wont use render settings */ -DerivedMesh *mesh_create_derived_no_deform(struct Object *ob, float (*vertCos)[3]); -DerivedMesh *mesh_create_derived_no_deform_render(struct Object *ob, float (*vertCos)[3]); +DerivedMesh *mesh_create_derived_render(struct Object *ob, + CustomDataMask dataMask); +/* same as above but wont use render settings */ +DerivedMesh *mesh_create_derived_view(struct Object *ob, + CustomDataMask dataMask); +DerivedMesh *mesh_create_derived_no_deform(struct Object *ob, + float (*vertCos)[3], + CustomDataMask dataMask); +DerivedMesh *mesh_create_derived_no_deform_render(struct Object *ob, + float (*vertCos)[3], + CustomDataMask dataMask); DerivedMesh *editmesh_get_derived_base(void); -DerivedMesh *editmesh_get_derived_cage(void); -DerivedMesh *editmesh_get_derived_cage_and_final(DerivedMesh **final_r); +DerivedMesh *editmesh_get_derived_cage(CustomDataMask dataMask); +DerivedMesh *editmesh_get_derived_cage_and_final(DerivedMesh **final_r, + CustomDataMask dataMask); void weight_to_rgb(float input, float *fr, float *fg, float *fb); +/* determines required DerivedMesh data according to view and edit modes */ +CustomDataMask get_viewedit_datamask(); + #endif diff --git a/source/blender/blenkernel/BKE_customdata.h b/source/blender/blenkernel/BKE_customdata.h index ce32f06e320..d48340998e0 100644 --- a/source/blender/blenkernel/BKE_customdata.h +++ b/source/blender/blenkernel/BKE_customdata.h @@ -36,9 +36,10 @@ struct CustomData; struct CustomDataLayer; typedef int CustomDataMask; -extern CustomDataMask CD_MASK_MESH[]; -extern CustomDataMask CD_MASK_EDITMESH[]; -extern CustomDataMask CD_MASK_DERIVEDMESH[]; +extern const CustomDataMask CD_MASK_BAREMESH; +extern const CustomDataMask CD_MASK_MESH; +extern const CustomDataMask CD_MASK_EDITMESH; +extern const CustomDataMask CD_MASK_DERIVEDMESH; /* for ORIGINDEX layer type, indicates no original index for this element */ #define ORIGINDEX_NONE -1 @@ -54,15 +55,15 @@ extern CustomDataMask CD_MASK_DERIVEDMESH[]; #define CD_REFERENCE 3 /* reference original pointers, set layer flag NOFREE */ /* initialises a CustomData object with the same layer setup as source. - * mask must be an array of length CD_NUMTYPES elements, that indicates + * mask is a bitfield where (mask & (1 << (layer type))) indicates * if a layer should be copied or not. alloctype must be one of the above. */ void CustomData_copy(const struct CustomData *source, struct CustomData *dest, - CustomDataMask *mask, int alloctype, int totelem); + CustomDataMask mask, int alloctype, int totelem); /* same as the above, except that will preserve existing layers, and only add * the layers that were not there yet */ void CustomData_merge(const struct CustomData *source, struct CustomData *dest, - CustomDataMask *mask, int alloctype, int totelem); + CustomDataMask mask, int alloctype, int totelem); /* frees data associated with a CustomData object (doesn't free the object * itself, though) @@ -105,6 +106,13 @@ int CustomData_has_layer(const struct CustomData *data, int type); * returns the layer data */ void *CustomData_duplicate_referenced_layer(struct CustomData *data, int type); +/* set the CD_FLAG_NOCOPY flag in custom data layers where the mask is + * zero for the layer type, so only layer types specified by the mask + * will be copied + */ +void CustomData_set_only_copy(const struct CustomData *data, + CustomDataMask mask); + /* copies data from one CustomData object to another * objects need not be compatible, each source layer is copied to the * first dest layer of correct type (if there is none, the layer is skipped) @@ -191,4 +199,7 @@ void CustomData_from_em_block(const struct CustomData *source, void CustomData_file_write_info(int type, char **structname, int *structnum); int CustomData_sizeof(int type); +/* get the name of a layer type */ +const char *CustomData_layertype_name(int type); + #endif diff --git a/source/blender/blenkernel/BKE_displist.h b/source/blender/blenkernel/BKE_displist.h index 04f3aadbe3c..979ed31fb20 100644 --- a/source/blender/blenkernel/BKE_displist.h +++ b/source/blender/blenkernel/BKE_displist.h @@ -36,6 +36,7 @@ #define BKE_DISPLIST_H #include "DNA_customdata_types.h" +#include "BKE_customdata.h" /* dl->type */ #define DL_POLY 0 @@ -109,7 +110,7 @@ extern void addnormalsDispList(struct Object *ob, struct ListBase *lb); extern void count_displist(struct ListBase *lb, int *totvert, int *totface); extern void freedisplist(struct ListBase *lb); extern int displist_has_faces(struct ListBase *lb); -extern void makeDerivedMesh(struct Object *ob); +extern void makeDerivedMesh(struct Object *ob, CustomDataMask dataMask); extern void makeDispListSurf(struct Object *ob, struct ListBase *dispbase, int forRender); extern void makeDispListCurveTypes(struct Object *ob, int forOrco); extern void makeDispListMBall(struct Object *ob); diff --git a/source/blender/blenkernel/BKE_modifier.h b/source/blender/blenkernel/BKE_modifier.h index a4c050429e5..586ee4e8552 100644 --- a/source/blender/blenkernel/BKE_modifier.h +++ b/source/blender/blenkernel/BKE_modifier.h @@ -33,12 +33,15 @@ #ifndef BKE_MODIFIER_H #define BKE_MODIFIER_H +#include "BKE_customdata.h" + struct EditMesh; struct DerivedMesh; struct DagForest; struct DagNode; struct Object; struct ListBase; +struct LinkNode; struct bArmature; typedef enum { @@ -102,7 +105,6 @@ typedef struct ModifierTypeInfo { */ void (*copyData)(ModifierData *md, ModifierData *target); - /********************* Deform modifier functions *********************/ /* Only for deform types, should apply the deformation @@ -170,6 +172,24 @@ typedef struct ModifierTypeInfo { */ void (*initData)(ModifierData *md); + /* Should return a CustomDataMask indicating what data this + * modifier needs. If (mask & (1 << (layer type))) != 0, this modifier + * needs that custom data layer. This function's return value can change + * depending on the modifier's settings. + * + * Note that this means extra data (e.g. vertex groups) - it is assumed + * that all modifiers need mesh data and deform modifiers need vertex + * coordinates. + * + * Note that this limits the number of custom data layer types to 32. + * + * If this function is not present or it returns 0, it is assumed that + * no extra data is needed. + * + * This function is optional. + */ + CustomDataMask (*requiredDataMask)(ModifierData *md); + /* Free internal modifier data variables, this function should * not free the md variable itself. * @@ -253,6 +273,13 @@ struct Object *modifiers_isDeformedByArmature(struct Object *ob); int modifiers_usesArmature(struct Object *ob, struct bArmature *arm); int modifiers_isDeformed(struct Object *ob); +/* Calculates and returns a linked list of CustomDataMasks indicating the + * data required by each modifier in the stack pointed to by md for correct + * evaluation, assuming the data indicated by dataMask is required at the + * end of the stack. + */ +struct LinkNode *modifiers_calcDataMasks(ModifierData *md, + CustomDataMask dataMask); ModifierData *modifiers_getVirtualModifierList(struct Object *ob); #endif diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c index 462a5c09387..8c3e807abd9 100644 --- a/source/blender/blenkernel/intern/DerivedMesh.c +++ b/source/blender/blenkernel/intern/DerivedMesh.c @@ -51,11 +51,15 @@ #include "DNA_object_force.h" #include "DNA_object_fluidsim.h" // N_T #include "DNA_scene_types.h" // N_T +#include "DNA_view3d_types.h" +#include "DNA_screen_types.h" +#include "DNA_space_types.h" #include "BLI_arithb.h" #include "BLI_blenlib.h" #include "BLI_edgehash.h" #include "BLI_editVert.h" +#include "BLI_linklist.h" #include "BKE_utildefines.h" #include "BKE_cdderivedmesh.h" @@ -271,6 +275,13 @@ void DM_to_mesh(DerivedMesh *dm, Mesh *me) *me = tmp; } +void DM_set_only_copy(DerivedMesh *dm, CustomDataMask mask) +{ + CustomData_set_only_copy(&dm->vertData, mask); + CustomData_set_only_copy(&dm->edgeData, mask); + CustomData_set_only_copy(&dm->faceData, mask); +} + void DM_add_vert_layer(DerivedMesh *dm, int type, int flag, void *layer) { CustomData_add_layer(&dm->vertData, type, flag, layer, dm->numVertData); @@ -1554,13 +1565,45 @@ DerivedMesh *mesh_create_derived_for_modifier(Object *ob, ModifierData *md) return dm; } +CustomDataMask get_viewedit_datamask() +{ + CustomDataMask mask = CD_MASK_BAREMESH; + ScrArea *sa; + + /* check if we need tfaces & mcols due to face select or texture paint */ + if(G.f & G_FACESELECT || G.f & G_TEXTUREPAINT) { + mask |= CD_MASK_MTFACE | CD_MASK_MCOL; + } else { + /* check if we need tfaces & mcols due to view mode */ + for(sa = G.curscreen->areabase.first; sa; sa = sa->next) { + if(sa->spacetype == SPACE_VIEW3D) { + View3D *view = sa->spacedata.first; + if(view->drawtype == OB_SHADED) { + /* this includes normals for mesh_create_shadedColors */ + mask |= CD_MASK_MTFACE | CD_MASK_MCOL | CD_MASK_NORMAL; + } + if(view->drawtype == OB_TEXTURE) { + mask |= CD_MASK_MTFACE | CD_MASK_MCOL; + } + } + } + } + + /* check if we need mcols due to vertex paint or weightpaint */ + if(G.f & G_VERTEXPAINT || G.f & G_WEIGHTPAINT) + mask |= CD_MASK_MCOL; + + return mask; +} + static void mesh_calc_modifiers(Object *ob, float (*inputVertexCos)[3], DerivedMesh **deform_r, DerivedMesh **final_r, int useRenderParams, int useDeform, - int needMapping) + int needMapping, CustomDataMask dataMask) { Mesh *me = ob->data; ModifierData *md = modifiers_getVirtualModifierList(ob); + LinkNode *datamasks, *curr; float (*deformedVerts)[3] = NULL; DerivedMesh *dm; int numVerts = me->totvert; @@ -1569,6 +1612,12 @@ static void mesh_calc_modifiers(Object *ob, float (*inputVertexCos)[3], modifiers_clearErrors(ob); + /* we always want to keep original indices */ + dataMask |= CD_MASK_ORIGINDEX; + + datamasks = modifiers_calcDataMasks(md, dataMask); + curr = datamasks; + if(deform_r) *deform_r = NULL; *final_r = NULL; @@ -1596,7 +1645,7 @@ static void mesh_calc_modifiers(Object *ob, float (*inputVertexCos)[3], deformedVerts = mesh_getVertexCos(me, &numVerts); /* Apply all leading deforming modifiers */ - for(; md; md = md->next) { + for(; md; md = md->next, curr = curr->next) { ModifierTypeInfo *mti = modifierType_getInfo(md->type); if((md->mode & required_mode) != required_mode) continue; @@ -1659,7 +1708,7 @@ static void mesh_calc_modifiers(Object *ob, float (*inputVertexCos)[3], if(me->vnode) dm = derivedmesh_from_versemesh(me->vnode, deformedVerts); #endif - for(; md; md = md->next) { + for(; md; md = md->next, curr = curr->next) { ModifierTypeInfo *mti = modifierType_getInfo(md->type); if((md->mode & required_mode) != required_mode) continue; @@ -1717,6 +1766,9 @@ static void mesh_calc_modifiers(Object *ob, float (*inputVertexCos)[3], } } + /* set the DerivedMesh to only copy needed data */ + DM_set_only_copy(dm, (CustomDataMask)curr->link); + ndm = mti->applyModifier(md, ob, dm, useRenderParams, !inputVertexCos); @@ -1772,6 +1824,8 @@ static void mesh_calc_modifiers(Object *ob, float (*inputVertexCos)[3], if(deformedVerts && deformedVerts != inputVertexCos) MEM_freeN(deformedVerts); + BLI_linklist_free(datamasks, NULL); + /* restore mesh in any case */ if(fluidsimMeshUsed) ob->data = ob->fluidsimSettings->orgMesh; } @@ -1790,7 +1844,9 @@ static float (*editmesh_getVertexCos(EditMesh *em, int *numVerts_r))[3] return cos; } -static void editmesh_calc_modifiers(DerivedMesh **cage_r, DerivedMesh **final_r) +static void editmesh_calc_modifiers(DerivedMesh **cage_r, + DerivedMesh **final_r, + CustomDataMask dataMask) { Object *ob = G.obedit; EditMesh *em = G.editMesh; @@ -1799,6 +1855,7 @@ static void editmesh_calc_modifiers(DerivedMesh **cage_r, DerivedMesh **final_r) DerivedMesh *dm; int i, numVerts = 0, cageIndex = modifiers_getCageIndex(ob, NULL); int required_mode = eModifierMode_Realtime | eModifierMode_Editmode; + LinkNode *datamasks, *curr; modifiers_clearErrors(ob); @@ -1807,7 +1864,15 @@ static void editmesh_calc_modifiers(DerivedMesh **cage_r, DerivedMesh **final_r) } dm = NULL; - for(i = 0, md = ob->modifiers.first; md; i++, md = md->next) { + md = ob->modifiers.first; + + /* we always want to keep original indices */ + dataMask |= CD_MASK_ORIGINDEX; + + datamasks = modifiers_calcDataMasks(md, dataMask); + + curr = datamasks; + for(i = 0; md; i++, md = md->next, curr = curr->next) { ModifierTypeInfo *mti = modifierType_getInfo(md->type); if((md->mode & required_mode) != required_mode) continue; @@ -1869,6 +1934,9 @@ static void editmesh_calc_modifiers(DerivedMesh **cage_r, DerivedMesh **final_r) } } + /* set the DerivedMesh to only copy needed data */ + DM_set_only_copy(dm, (CustomDataMask)curr->link); + ndm = mti->applyModifierEM(md, ob, em, dm); if (ndm) { @@ -1898,6 +1966,8 @@ static void editmesh_calc_modifiers(DerivedMesh **cage_r, DerivedMesh **final_r) } } + BLI_linklist_free(datamasks, NULL); + /* Yay, we are done. If we have a DerivedMesh and deformed vertices need * to apply these back onto the DerivedMesh. If we have no DerivedMesh * then we need to build one. @@ -2020,7 +2090,7 @@ static void clear_mesh_caches(Object *ob) } } -static void mesh_build_data(Object *ob) +static void mesh_build_data(Object *ob, CustomDataMask dataMask) { Mesh *me = ob->data; float min[3], max[3]; @@ -2046,8 +2116,9 @@ static void mesh_build_data(Object *ob) CustomData_add_layer(&me->fdata, CD_MCOL, CD_FLAG_NOFREE, wpcol, me->totface); me->mcol= wpcol; - mesh_calc_modifiers(ob, NULL, &ob->derivedDeform, &ob->derivedFinal, 0, 1, - needMapping); + mesh_calc_modifiers(ob, NULL, &ob->derivedDeform, + &ob->derivedFinal, 0, 1, + needMapping, dataMask); CustomData_free_layer(&me->fdata, CD_MCOL, me->totface); if (wpcol) MEM_freeN(wpcol); @@ -2057,7 +2128,8 @@ static void mesh_build_data(Object *ob) me->mcol= mcol; } else { mesh_calc_modifiers(ob, NULL, &ob->derivedDeform, - &ob->derivedFinal, 0, 1, needMapping); + &ob->derivedFinal, 0, 1, + needMapping, dataMask); } INIT_MINMAX(min, max); @@ -2068,10 +2140,11 @@ static void mesh_build_data(Object *ob) ob->derivedFinal->needsFree = 0; ob->derivedDeform->needsFree = 0; + ob->lastDataMask = dataMask; } } -static void editmesh_build_data(void) +static void editmesh_build_data(CustomDataMask dataMask) { float min[3], max[3]; @@ -2092,7 +2165,8 @@ static void editmesh_build_data(void) em->derivedCage = NULL; } - editmesh_calc_modifiers(&em->derivedCage, &em->derivedFinal); + editmesh_calc_modifiers(&em->derivedCage, &em->derivedFinal, dataMask); + em->lastDataMask = dataMask; INIT_MINMAX(min, max); @@ -2104,14 +2178,14 @@ static void editmesh_build_data(void) em->derivedCage->needsFree = 0; } -void makeDerivedMesh(Object *ob) +void makeDerivedMesh(Object *ob, CustomDataMask dataMask) { if (ob==G.obedit) { - editmesh_build_data(); + editmesh_build_data(dataMask); } else { PartEff *paf= give_parteff(ob); - mesh_build_data(ob); + mesh_build_data(ob, dataMask); if(paf) { if((paf->flag & PAF_STATIC) || (ob->recalc & OB_RECALC_TIME)==0) @@ -2122,23 +2196,29 @@ void makeDerivedMesh(Object *ob) /***/ -DerivedMesh *mesh_get_derived_final(Object *ob) +DerivedMesh *mesh_get_derived_final(Object *ob, CustomDataMask dataMask) { - if (!ob->derivedFinal) - mesh_build_data(ob); + /* if there's no derived mesh or the last data mask used doesn't include + * the data we need, rebuild the derived mesh + */ + if(!ob->derivedFinal || (dataMask & ob->lastDataMask) != dataMask) + mesh_build_data(ob, dataMask); return ob->derivedFinal; } -DerivedMesh *mesh_get_derived_deform(Object *ob) +DerivedMesh *mesh_get_derived_deform(Object *ob, CustomDataMask dataMask) { - if (!ob->derivedDeform) - mesh_build_data(ob); + /* if there's no derived mesh or the last data mask used doesn't include + * the data we need, rebuild the derived mesh + */ + if(!ob->derivedDeform || (dataMask & ob->lastDataMask) != dataMask) + mesh_build_data(ob, dataMask); return ob->derivedDeform; } -DerivedMesh *mesh_create_derived_render(Object *ob) +DerivedMesh *mesh_create_derived_render(Object *ob, CustomDataMask dataMask) { DerivedMesh *final; Mesh *m= get_mesh(ob); @@ -2150,7 +2230,7 @@ DerivedMesh *mesh_create_derived_render(Object *ob) multires_set_level(ob,m); } - mesh_calc_modifiers(ob, NULL, NULL, &final, 1, 1, 0); + mesh_calc_modifiers(ob, NULL, NULL, &final, 1, 1, 0, dataMask); /* Propagate the changes to render level - fails if mesh topology changed */ if(m->mr) { @@ -2170,48 +2250,60 @@ DerivedMesh *mesh_create_derived_render(Object *ob) return final; } -DerivedMesh *mesh_create_derived_view(Object *ob) +DerivedMesh *mesh_create_derived_view(Object *ob, CustomDataMask dataMask) { DerivedMesh *final; - mesh_calc_modifiers(ob, NULL, NULL, &final, 0, 1, 0); + mesh_calc_modifiers(ob, NULL, NULL, &final, 0, 1, 0, dataMask); return final; } -DerivedMesh *mesh_create_derived_no_deform(Object *ob, float (*vertCos)[3]) +DerivedMesh *mesh_create_derived_no_deform(Object *ob, float (*vertCos)[3], + CustomDataMask dataMask) { DerivedMesh *final; - mesh_calc_modifiers(ob, vertCos, NULL, &final, 0, 0, 0); + mesh_calc_modifiers(ob, vertCos, NULL, &final, 0, 0, 0, dataMask); return final; } -DerivedMesh *mesh_create_derived_no_deform_render(Object *ob, float (*vertCos)[3]) +DerivedMesh *mesh_create_derived_no_deform_render(Object *ob, + float (*vertCos)[3], + CustomDataMask dataMask) { DerivedMesh *final; - mesh_calc_modifiers(ob, vertCos, NULL, &final, 1, 0, 0); + mesh_calc_modifiers(ob, vertCos, NULL, &final, 1, 0, 0, dataMask); return final; } /***/ -DerivedMesh *editmesh_get_derived_cage_and_final(DerivedMesh **final_r) +DerivedMesh *editmesh_get_derived_cage_and_final(DerivedMesh **final_r, + CustomDataMask dataMask) { - if (!G.editMesh->derivedCage) - editmesh_build_data(); + /* if there's no derived mesh or the last data mask used doesn't include + * the data we need, rebuild the derived mesh + */ + if(!G.editMesh->derivedCage || + (G.editMesh->lastDataMask & dataMask) != dataMask) + editmesh_build_data(dataMask); *final_r = G.editMesh->derivedFinal; return G.editMesh->derivedCage; } -DerivedMesh *editmesh_get_derived_cage(void) +DerivedMesh *editmesh_get_derived_cage(CustomDataMask dataMask) { - if (!G.editMesh->derivedCage) - editmesh_build_data(); + /* if there's no derived mesh or the last data mask used doesn't include + * the data we need, rebuild the derived mesh + */ + if(!G.editMesh->derivedCage || + (G.editMesh->lastDataMask & dataMask) != dataMask) + editmesh_build_data(dataMask); return G.editMesh->derivedCage; } @@ -2258,7 +2350,7 @@ float *mesh_get_mapped_verts_nors(Object *ob) if(ob->type!=OB_MESH || me->totvert==0) return NULL; - dm= mesh_get_derived_final(ob); + dm= mesh_get_derived_final(ob, CD_MASK_BAREMESH); vertexcosnos= MEM_callocN(6*sizeof(float)*me->totvert, "vertexcosnos map"); if(dm->foreachMappedVert) { @@ -2322,7 +2414,7 @@ void writeBobjgz(char *filename, struct Object *ob, int useGlobalCoords, int app return; } - dm = mesh_create_derived_render(ob); + dm = mesh_create_derived_render(ob, CD_MASK_BAREMESH); //dm = mesh_create_derived_no_deform(ob,NULL); mvert = dm->getVertArray(dm); @@ -2426,7 +2518,7 @@ void initElbeemMesh(struct Object *ob, float *verts; int *tris; - dm = mesh_create_derived_render(ob); + dm = mesh_create_derived_render(ob, CD_MASK_BAREMESH); //dm = mesh_create_derived_no_deform(ob,NULL); if(!dm) { *numVertices = *numTriangles = 0; *triangles=NULL; *vertices=NULL; } diff --git a/source/blender/blenkernel/intern/anim.c b/source/blender/blenkernel/intern/anim.c index ad97128bb37..849a7f316f2 100644 --- a/source/blender/blenkernel/intern/anim.c +++ b/source/blender/blenkernel/intern/anim.c @@ -410,9 +410,9 @@ static void vertex_duplilist(ListBase *lb, Scene *sce, Object *par) lay= G.scene->lay; if(par==G.obedit) - dm= editmesh_get_derived_cage(); + dm= editmesh_get_derived_cage(CD_MASK_BAREMESH); else - dm = mesh_get_derived_deform(par); + dm = mesh_get_derived_deform(par, CD_MASK_BAREMESH); totvert = dm->getNumVerts(dm); @@ -473,7 +473,7 @@ static void face_duplilist(ListBase *lb, Scene *sce, Object *par) if(par==G.obedit) { int totvert; - dm= editmesh_get_derived_cage(); + dm= editmesh_get_derived_cage(CD_MASK_BAREMESH); totface= dm->getNumFaces(dm); mface= MEM_mallocN(sizeof(MFace)*totface, "mface temp"); @@ -483,7 +483,7 @@ static void face_duplilist(ListBase *lb, Scene *sce, Object *par) dm->copyVertArray(dm, mvert); } else { - dm = mesh_get_derived_deform(par); + dm = mesh_get_derived_deform(par, CD_MASK_BAREMESH); totface= dm->getNumFaces(dm); mface= dm->getFaceArray(dm); diff --git a/source/blender/blenkernel/intern/customdata.c b/source/blender/blenkernel/intern/customdata.c index 422107fa273..508021ef74c 100644 --- a/source/blender/blenkernel/intern/customdata.c +++ b/source/blender/blenkernel/intern/customdata.c @@ -374,12 +374,17 @@ const char *LAYERTYPENAMES[CD_NUMTYPES] = { "CDMVert", "CDMSticky", "CDMDeformVert", "CDMEdge", "CDMFace", "CDMTFace", "CDMCol", "CDOrigIndex", "CDNormal", "CDFlags"}; -CustomDataMask CD_MASK_MESH[CD_NUMTYPES] = { - 1, 1, 1, 1, 1, 1, 1, 0, 0, 0}; -CustomDataMask CD_MASK_EDITMESH[CD_NUMTYPES] = { - 0, 1, 1, 0, 0, 1, 1, 0, 0, 0}; -CustomDataMask CD_MASK_DERIVEDMESH[CD_NUMTYPES] = { - 0, 1, 1, 0, 0, 1, 1, 1, 0, 0}; +const CustomDataMask CD_MASK_BAREMESH = + CD_MASK_MVERT | CD_MASK_MEDGE | CD_MASK_MFACE; +const CustomDataMask CD_MASK_MESH = + CD_MASK_MVERT | CD_MASK_MEDGE | CD_MASK_MFACE | + CD_MASK_MSTICKY | CD_MASK_MDEFORMVERT | CD_MASK_MTFACE | CD_MASK_MCOL; +const CustomDataMask CD_MASK_EDITMESH = + CD_MASK_MSTICKY | CD_MASK_MDEFORMVERT | CD_MASK_MTFACE | + CD_MASK_MCOL; +const CustomDataMask CD_MASK_DERIVEDMESH = + CD_MASK_MSTICKY | CD_MASK_MDEFORMVERT | CD_MASK_MTFACE | + CD_MASK_MCOL | CD_MASK_ORIGINDEX; static const LayerTypeInfo *layerType_getInfo(int type) { @@ -412,7 +417,7 @@ static void CustomData_update_offsets(CustomData *data) } void CustomData_merge(const struct CustomData *source, struct CustomData *dest, - CustomDataMask *mask, int alloctype, int totelem) + CustomDataMask mask, int alloctype, int totelem) { const LayerTypeInfo *typeInfo; CustomDataLayer *layer; @@ -424,7 +429,7 @@ void CustomData_merge(const struct CustomData *source, struct CustomData *dest, typeInfo = layerType_getInfo(layer->type); if(layer->flag & CD_FLAG_NOCOPY) continue; - else if(mask && !mask[layer->type]) continue; + else if(!(mask & (1 << layer->type))) continue; else if(CustomData_has_layer(dest, layer->type)) continue; type = layer->type; @@ -451,7 +456,7 @@ void CustomData_merge(const struct CustomData *source, struct CustomData *dest, } void CustomData_copy(const struct CustomData *source, struct CustomData *dest, - CustomDataMask *mask, int alloctype, int totelem) + CustomDataMask mask, int alloctype, int totelem) { memset(dest, 0, sizeof(*dest)); @@ -650,6 +655,16 @@ int CustomData_compat(const CustomData *data1, const CustomData *data2) return 1; } +void CustomData_set_only_copy(const struct CustomData *data, + CustomDataMask mask) +{ + int i; + + for(i = 0; i < data->totlayer; ++i) + if(!(mask & (1 << data->layers[i].type))) + data->layers[i].flag |= CD_FLAG_NOCOPY; +} + void CustomData_copy_data(const CustomData *source, CustomData *dest, int source_index, int dest_index, int count) { @@ -1109,3 +1124,8 @@ int CustomData_sizeof(int type) return type_info->size; } + +const char *CustomData_layertype_name(int type) +{ + return layerType_getName(type); +} diff --git a/source/blender/blenkernel/intern/displist.c b/source/blender/blenkernel/intern/displist.c index 763a4cdc0a0..1cedbe1338e 100644 --- a/source/blender/blenkernel/intern/displist.c +++ b/source/blender/blenkernel/intern/displist.c @@ -449,15 +449,17 @@ static void mesh_create_shadedColors(Render *re, Object *ob, int onlyForMesh, un unsigned int *col1, *col2; float *orco, *vnors, *nors, imat[3][3], mat[4][4], vec[3]; int a, i, need_orco, totface, totvert; + CustomDataMask dataMask = CD_MASK_BAREMESH | CD_MASK_MCOL + | CD_MASK_MTFACE | CD_MASK_NORMAL; init_fastshade_for_ob(re, ob, &need_orco, mat, imat); orco = (need_orco)? mesh_create_orco(ob): NULL; if (onlyForMesh) - dm = mesh_get_derived_deform(ob); + dm = mesh_get_derived_deform(ob, dataMask); else - dm = mesh_get_derived_final(ob); + dm = mesh_get_derived_final(ob, dataMask); mvert = dm->getVertArray(dm); mface = dm->getFaceArray(dm); @@ -474,7 +476,7 @@ static void mesh_create_shadedColors(Render *re, Object *ob, int onlyForMesh, un *col1_r = col1 = MEM_mallocN(sizeof(*col1)*totface*4, "col1"); if (col2_r && (me->flag & ME_TWOSIDED)) - col2 = MEM_mallocN(sizeof(*col2)*totface*4, "col1"); + col2 = MEM_mallocN(sizeof(*col2)*totface*4, "col2"); else col2 = NULL; diff --git a/source/blender/blenkernel/intern/exotic.c b/source/blender/blenkernel/intern/exotic.c index 0848d2b71a0..4946066e4b3 100644 --- a/source/blender/blenkernel/intern/exotic.c +++ b/source/blender/blenkernel/intern/exotic.c @@ -2495,7 +2495,7 @@ static int write_derivedmesh_stl(FILE *fpSTL, Object *ob, DerivedMesh *dm) static int write_object_stl(FILE *fpSTL, Object *ob, Mesh *me) { int numfacets = 0; - DerivedMesh *dm = mesh_get_derived_final(ob); + DerivedMesh *dm = mesh_get_derived_final(ob, CD_MASK_BAREMESH); numfacets += write_derivedmesh_stl(fpSTL, ob, dm); @@ -2649,7 +2649,7 @@ static void write_videoscape_mesh(Object *ob, char *str) } } else { - DerivedMesh *dm = mesh_get_derived_deform(ob); + DerivedMesh *dm = mesh_get_derived_deform(ob, CD_MASK_BAREMESH); me= ob->data; diff --git a/source/blender/blenkernel/intern/mesh.c b/source/blender/blenkernel/intern/mesh.c index 6de2717ba46..52c094acca4 100644 --- a/source/blender/blenkernel/intern/mesh.c +++ b/source/blender/blenkernel/intern/mesh.c @@ -505,9 +505,9 @@ static float *make_orco_mesh_internal(Object *ob, int render) /* Apply orco-changing modifiers */ if (render) { - dm = mesh_create_derived_no_deform_render(ob, vcos); + dm = mesh_create_derived_no_deform_render(ob, vcos, CD_MASK_BAREMESH); } else { - dm = mesh_create_derived_no_deform(ob, vcos); + dm = mesh_create_derived_no_deform(ob, vcos, CD_MASK_BAREMESH); } totvert = dm->getNumVerts(dm); diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c index b1037da270e..43c513aaa1b 100644 --- a/source/blender/blenkernel/intern/modifier.c +++ b/source/blender/blenkernel/intern/modifier.c @@ -119,6 +119,17 @@ static void curveModifier_copyData(ModifierData *md, ModifierData *target) strncpy(tcmd->name, cmd->name, 32); } +CustomDataMask curveModifier_requiredDataMask(ModifierData *md) +{ + CurveModifierData *cmd = (CurveModifierData *)md; + CustomDataMask dataMask = 0; + + /* ask for vertexgroups if we need them */ + if(cmd->name[0]) dataMask |= (1 << CD_MDEFORMVERT); + + return dataMask; +} + static int curveModifier_isDisabled(ModifierData *md) { CurveModifierData *cmd = (CurveModifierData*) md; @@ -184,6 +195,17 @@ static void latticeModifier_copyData(ModifierData *md, ModifierData *target) strncpy(tlmd->name, lmd->name, 32); } +CustomDataMask latticeModifier_requiredDataMask(ModifierData *md) +{ + LatticeModifierData *lmd = (LatticeModifierData *)md; + CustomDataMask dataMask = 0; + + /* ask for vertexgroups if we need them */ + if(lmd->name[0]) dataMask |= (1 << CD_MDEFORMVERT); + + return dataMask; +} + static int latticeModifier_isDisabled(ModifierData *md) { LatticeModifierData *lmd = (LatticeModifierData*) md; @@ -2203,6 +2225,20 @@ static void displaceModifier_copyData(ModifierData *md, ModifierData *target) *tdmd = *dmd; } +CustomDataMask displaceModifier_requiredDataMask(ModifierData *md) +{ + DisplaceModifierData *dmd = (DisplaceModifierData *)md; + CustomDataMask dataMask = 0; + + /* ask for vertexgroups if we need them */ + if(dmd->defgrp_name[0]) dataMask |= (1 << CD_MDEFORMVERT); + + /* ask for UV coordinates if we need them */ + if(dmd->texmapping == MOD_DISP_MAP_UV) dataMask |= (1 << CD_MTFACE); + + return dataMask; +} + static void displaceModifier_foreachObjectLink(ModifierData *md, Object *ob, ObjectWalkFunc walk, void *userData) { @@ -2496,6 +2532,16 @@ static void uvprojectModifier_copyData(ModifierData *md, ModifierData *target) tumd->aspecty = umd->aspecty; } +CustomDataMask uvprojectModifier_requiredDataMask(ModifierData *md) +{ + CustomDataMask dataMask = 0; + + /* ask for UV coordinates */ + dataMask |= (1 << CD_MTFACE); + + return dataMask; +} + static void uvprojectModifier_foreachObjectLink(ModifierData *md, Object *ob, ObjectWalkFunc walk, void *userData) { @@ -3054,6 +3100,16 @@ static void armatureModifier_copyData(ModifierData *md, ModifierData *target) strncpy(tamd->defgrp_name, amd->defgrp_name, 32); } +CustomDataMask armatureModifier_requiredDataMask(ModifierData *md) +{ + CustomDataMask dataMask = 0; + + /* ask for vertexgroups */ + dataMask |= (1 << CD_MDEFORMVERT); + + return dataMask; +} + static int armatureModifier_isDisabled(ModifierData *md) { ArmatureModifierData *amd = (ArmatureModifierData*) md; @@ -3134,6 +3190,17 @@ static void hookModifier_copyData(ModifierData *md, ModifierData *target) strncpy(thmd->name, hmd->name, 32); } +CustomDataMask hookModifier_requiredDataMask(ModifierData *md) +{ + HookModifierData *hmd = (HookModifierData *)md; + CustomDataMask dataMask = 0; + + /* ask for vertexgroups if we need them */ + if(!hmd->indexar && hmd->name[0]) dataMask |= (1 << CD_MDEFORMVERT); + + return dataMask; +} + static void hookModifier_freeData(ModifierData *md) { HookModifierData *hmd = (HookModifierData*) md; @@ -3413,6 +3480,7 @@ ModifierTypeInfo *modifierType_getInfo(ModifierType type) | eModifierTypeFlag_SupportsEditmode; mti->initData = curveModifier_initData; mti->copyData = curveModifier_copyData; + mti->requiredDataMask = curveModifier_requiredDataMask; mti->isDisabled = curveModifier_isDisabled; mti->foreachObjectLink = curveModifier_foreachObjectLink; mti->updateDepgraph = curveModifier_updateDepgraph; @@ -3424,6 +3492,7 @@ ModifierTypeInfo *modifierType_getInfo(ModifierType type) mti->flags = eModifierTypeFlag_AcceptsCVs | eModifierTypeFlag_SupportsEditmode; mti->copyData = latticeModifier_copyData; + mti->requiredDataMask = latticeModifier_requiredDataMask; mti->isDisabled = latticeModifier_isDisabled; mti->foreachObjectLink = latticeModifier_foreachObjectLink; mti->updateDepgraph = latticeModifier_updateDepgraph; @@ -3490,6 +3559,7 @@ ModifierTypeInfo *modifierType_getInfo(ModifierType type) mti->flags = eModifierTypeFlag_AcceptsMesh|eModifierTypeFlag_SupportsEditmode; mti->initData = displaceModifier_initData; mti->copyData = displaceModifier_copyData; + mti->requiredDataMask = displaceModifier_requiredDataMask; mti->foreachObjectLink = displaceModifier_foreachObjectLink; mti->foreachIDLink = displaceModifier_foreachIDLink; mti->updateDepgraph = displaceModifier_updateDepgraph; @@ -3505,6 +3575,7 @@ ModifierTypeInfo *modifierType_getInfo(ModifierType type) | eModifierTypeFlag_EnableInEditmode; mti->initData = uvprojectModifier_initData; mti->copyData = uvprojectModifier_copyData; + mti->requiredDataMask = uvprojectModifier_requiredDataMask; mti->foreachObjectLink = uvprojectModifier_foreachObjectLink; mti->foreachIDLink = uvprojectModifier_foreachIDLink; mti->updateDepgraph = uvprojectModifier_updateDepgraph; @@ -3536,6 +3607,7 @@ ModifierTypeInfo *modifierType_getInfo(ModifierType type) | eModifierTypeFlag_SupportsEditmode; mti->initData = armatureModifier_initData; mti->copyData = armatureModifier_copyData; + mti->requiredDataMask = armatureModifier_requiredDataMask; mti->isDisabled = armatureModifier_isDisabled; mti->foreachObjectLink = armatureModifier_foreachObjectLink; mti->updateDepgraph = armatureModifier_updateDepgraph; @@ -3548,6 +3620,7 @@ ModifierTypeInfo *modifierType_getInfo(ModifierType type) | eModifierTypeFlag_SupportsEditmode; mti->initData = hookModifier_initData; mti->copyData = hookModifier_copyData; + mti->requiredDataMask = hookModifier_requiredDataMask; mti->freeData = hookModifier_freeData; mti->isDisabled = hookModifier_isDisabled; mti->foreachObjectLink = hookModifier_foreachObjectLink; @@ -3761,6 +3834,46 @@ int modifiers_isSoftbodyEnabled(Object *ob) return (md && md->mode & (eModifierMode_Realtime | eModifierMode_Render)); } +LinkNode *modifiers_calcDataMasks(ModifierData *md, CustomDataMask dataMask) +{ + LinkNode *dataMasks = NULL; + LinkNode *curr, *prev; + + /* build a list of modifier data requirements in reverse order */ + for(; md; md = md->next) { + ModifierTypeInfo *mti = modifierType_getInfo(md->type); + CustomDataMask mask = 0; + + if(mti->requiredDataMask) mask = mti->requiredDataMask(md); + + BLI_linklist_prepend(&dataMasks, (void *)mask); + } + + /* build the list of required data masks - each mask in the list must + * include all elements of the masks that follow it + * + * note the list is currently in reverse order, so "masks that follow it" + * actually means "masks that precede it" at the moment + */ + for(curr = dataMasks, prev = NULL; curr; prev = curr, curr = curr->next) { + if(prev) { + CustomDataMask prev_mask = (CustomDataMask)prev->link; + CustomDataMask curr_mask = (CustomDataMask)curr->link; + + curr->link = (void *)(curr_mask | prev_mask); + } else { + CustomDataMask curr_mask = (CustomDataMask)curr->link; + + curr->link = (void *)(curr_mask | dataMask); + } + } + + /* reverse the list so it's in the correct order */ + BLI_linklist_reverse(&dataMasks); + + return dataMasks; +} + ModifierData *modifiers_getVirtualModifierList(Object *ob) { /* Kinda hacky, but should be fine since we are never diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c index af2d562b331..a8bf87c966f 100644 --- a/source/blender/blenkernel/intern/object.c +++ b/source/blender/blenkernel/intern/object.c @@ -2007,7 +2007,7 @@ void object_handle_update(Object *ob) /* includes all keys and modifiers */ if(ob->type==OB_MESH) { - makeDerivedMesh(ob); + makeDerivedMesh(ob, get_viewedit_datamask()); } else if(ob->type==OB_MBALL) { makeDispListMBall(ob); diff --git a/source/blender/blenkernel/intern/softbody.c b/source/blender/blenkernel/intern/softbody.c index acbf4df653a..ad3ea337c55 100644 --- a/source/blender/blenkernel/intern/softbody.c +++ b/source/blender/blenkernel/intern/softbody.c @@ -492,9 +492,9 @@ void ccd_build_deflector_hache(Object *vertexowner,GHash *hash) DerivedMesh *dm= NULL; if(ob->softflag & OB_SB_COLLFINAL) { /* so maybe someone wants overkill to collide with subsurfed */ - dm = mesh_get_derived_final(ob); + dm = mesh_get_derived_final(ob, CD_MASK_BAREMESH); } else { - dm = mesh_get_derived_deform(ob); + dm = mesh_get_derived_deform(ob, CD_MASK_BAREMESH); } if(dm){ @@ -534,9 +534,9 @@ void ccd_update_deflector_hache(Object *vertexowner,GHash *hash) DerivedMesh *dm= NULL; if(ob->softflag & OB_SB_COLLFINAL) { /* so maybe someone wants overkill to collide with subsurfed */ - dm = mesh_get_derived_final(ob); + dm = mesh_get_derived_final(ob, CD_MASK_BAREMESH); } else { - dm = mesh_get_derived_deform(ob); + dm = mesh_get_derived_deform(ob, CD_MASK_BAREMESH); } if(dm){ ccd_Mesh *ccdmesh = BLI_ghash_lookup(hash,ob); diff --git a/source/blender/blenkernel/intern/subsurf_ccg.c b/source/blender/blenkernel/intern/subsurf_ccg.c index 44845ed706b..5f7b656d45a 100644 --- a/source/blender/blenkernel/intern/subsurf_ccg.c +++ b/source/blender/blenkernel/intern/subsurf_ccg.c @@ -507,7 +507,7 @@ DerivedMesh *ss_to_cdderivedmesh(CCGSubSurf *ss, int ssFromEditmesh, tface = NULL; } - if(useSubsurfUv && tface) { + if(useSubsurfUv && result->getFaceDataArray(result, CD_MTFACE)) { uvss = _getSubSurf(NULL, ccgSubSurf_getSubdivisionLevels(ss), 0, 1, 0); @@ -2141,7 +2141,7 @@ static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss, } ccgFaceIterator_free(fi); - if(useSubsurfUv && tface) { + if(useSubsurfUv && dm->getFaceDataArray(&ccgdm->dm, CD_MTFACE)) { /* not for editmesh currently */ uvss = _getSubSurf(NULL, ccgSubSurf_getSubdivisionLevels(ss), 0, 1, 0); diff --git a/source/blender/blenlib/BLI_editVert.h b/source/blender/blenlib/BLI_editVert.h index d39cd748fb1..e81e7db57ca 100644 --- a/source/blender/blenlib/BLI_editVert.h +++ b/source/blender/blenlib/BLI_editVert.h @@ -164,6 +164,10 @@ typedef struct EditMesh * to derived final, care should be taken on release. */ struct DerivedMesh *derivedCage, *derivedFinal; + /* the custom data layer mask that was last used to calculate + * derivedCage and derivedFinal + */ + int lastDataMask; char retopo_mode; /* 0=OFF, 1=ON, 2=PAINT */ struct RetopoPaintData *retopo_paint_data; diff --git a/source/blender/makesdna/DNA_customdata_types.h b/source/blender/makesdna/DNA_customdata_types.h index 08b0345af8d..00c303c0357 100644 --- a/source/blender/makesdna/DNA_customdata_types.h +++ b/source/blender/makesdna/DNA_customdata_types.h @@ -62,6 +62,18 @@ typedef struct CustomData { #define CD_FLAGS 9 #define CD_NUMTYPES 10 +/* Bits for CustomDataMask */ +#define CD_MASK_MVERT (1 << CD_MVERT) +#define CD_MASK_MSTICKY (1 << CD_MSTICKY) +#define CD_MASK_MDEFORMVERT (1 << CD_MDEFORMVERT) +#define CD_MASK_MEDGE (1 << CD_MEDGE) +#define CD_MASK_MFACE (1 << CD_MFACE) +#define CD_MASK_MTFACE (1 << CD_MTFACE) +#define CD_MASK_MCOL (1 << CD_MCOL) +#define CD_MASK_ORIGINDEX (1 << CD_ORIGINDEX) +#define CD_MASK_NORMAL (1 << CD_NORMAL) +#define CD_MASK_FLAGS (1 << CD_FLAGS) + /* CustomData.flag */ /* indicates layer should not be copied by CustomData_from_template or diff --git a/source/blender/makesdna/DNA_object_types.h b/source/blender/makesdna/DNA_object_types.h index f9055dfc11b..a27c6520787 100644 --- a/source/blender/makesdna/DNA_object_types.h +++ b/source/blender/makesdna/DNA_object_types.h @@ -210,6 +210,8 @@ typedef struct Object { struct FluidsimSettings *fluidsimSettings; /* if fluidsim enabled, store additional settings */ struct DerivedMesh *derivedDeform, *derivedFinal; + int lastDataMask; /* the custom data layer mask that was last used to calculate derivedDeform and derivedFinal */ + int pad; /*#ifdef WITH_VERSE*/ void *vnode; /* pointer at object VerseNode */ diff --git a/source/blender/python/api2_2x/Mesh.c b/source/blender/python/api2_2x/Mesh.c index 01fce68137d..8e0d5e93284 100644 --- a/source/blender/python/api2_2x/Mesh.c +++ b/source/blender/python/api2_2x/Mesh.c @@ -5573,9 +5573,9 @@ static PyObject *Mesh_getFromObject( BPy_Mesh * self, PyObject * args ) /* Write the display mesh into the dummy mesh */ if (render) - dm = mesh_create_derived_render( ob ); + dm = mesh_create_derived_render( ob, CD_MASK_MESH ); else - dm = mesh_create_derived_view( ob ); + dm = mesh_create_derived_view( ob, CD_MASK_MESH ); tmpmesh = add_mesh( ); DM_to_mesh( dm, tmpmesh ); diff --git a/source/blender/python/api2_2x/NMesh.c b/source/blender/python/api2_2x/NMesh.c index 5df435ecb2a..7cd3d74673f 100644 --- a/source/blender/python/api2_2x/NMesh.c +++ b/source/blender/python/api2_2x/NMesh.c @@ -1455,7 +1455,7 @@ static PyObject *NMesh_update( PyObject *self, PyObject *a, PyObject *kwd ) } /* recalculate the derived mesh before trying to use it */ - makeDerivedMesh(nmesh->object); + makeDerivedMesh(nmesh->object, CD_MASK_BAREMESH); make_vertexcol(1); countall(); @@ -2557,7 +2557,9 @@ static PyObject *M_NMesh_GetRawFromObject( PyObject * self, PyObject * args ) break; case OB_MESH: { - DerivedMesh *dm = mesh_create_derived_render( ob ); + CustomDataMask dataMask = CD_MASK_BAREMESH | CD_MASK_MTFACE + | CD_MASK_MCOL; + DerivedMesh *dm = mesh_create_derived_render( ob, dataMask ); nmesh = new_NMesh_internal( ob->data, dm ); dm->release(dm); } diff --git a/source/blender/render/intern/source/convertblender.c b/source/blender/render/intern/source/convertblender.c index 7232e0e6e71..6268971bb79 100644 --- a/source/blender/render/intern/source/convertblender.c +++ b/source/blender/render/intern/source/convertblender.c @@ -1836,7 +1836,8 @@ static void init_render_mesh(Render *re, Object *ob, Object *par, int only_verts ob->data= me; } - dm = mesh_create_derived_render(ob); + dm = mesh_create_derived_render(ob, + CD_MASK_BAREMESH | CD_MASK_MTFACE | CD_MASK_MCOL); /* (Multires) Now switch the meshes back around */ if(me->mr) { diff --git a/source/blender/src/drawimage.c b/source/blender/src/drawimage.c index 3d11568a8bc..7e77432158e 100644 --- a/source/blender/src/drawimage.c +++ b/source/blender/src/drawimage.c @@ -401,7 +401,8 @@ void draw_tfaces(void) DerivedMesh *dm; /* draw final mesh with modifiers applied */ - dm = mesh_get_derived_final(OBACT); + dm = mesh_get_derived_final(OBACT, + CD_MASK_BAREMESH | CD_MASK_MTFACE); glColor3ub(112, 112, 112); if (dm->drawUVEdges) dm->drawUVEdges(dm); diff --git a/source/blender/src/drawmesh.c b/source/blender/src/drawmesh.c index ac9940f5a02..c6b0a874ff4 100644 --- a/source/blender/src/drawmesh.c +++ b/source/blender/src/drawmesh.c @@ -977,7 +977,7 @@ void draw_tface_mesh(Object *ob, Mesh *me, int dt) if(me==NULL) return; - dm = mesh_get_derived_final(ob); + dm = mesh_get_derived_final(ob, get_viewedit_datamask()); glShadeModel(GL_SMOOTH); @@ -1031,7 +1031,7 @@ void draw_tface_mesh(Object *ob, Mesh *me, int dt) /* drawing game engine text hack */ if (!editing && prop && me->tface) { - DerivedMesh *ddm = mesh_get_derived_deform(ob); + DerivedMesh *ddm = mesh_get_derived_deform(ob, CD_MASK_BAREMESH); MFace *mface= me->mface; MTFace *tface= me->mtface; MCol *mcol= me->mcol; /* why does mcol exist? */ diff --git a/source/blender/src/drawobject.c b/source/blender/src/drawobject.c index 5bc188c6ac6..94917c99671 100644 --- a/source/blender/src/drawobject.c +++ b/source/blender/src/drawobject.c @@ -1137,7 +1137,7 @@ static void mesh_foreachScreenVert__mapFunc(void *userData, int index, float *co void mesh_foreachScreenVert(void (*func)(void *userData, EditVert *eve, int x, int y, int index), void *userData, int clipVerts) { struct { void (*func)(void *userData, EditVert *eve, int x, int y, int index); void *userData; int clipVerts; float pmat[4][4], vmat[4][4]; } data; - DerivedMesh *dm = editmesh_get_derived_cage(); + DerivedMesh *dm = editmesh_get_derived_cage(CD_MASK_BAREMESH); data.func = func; data.userData = userData; @@ -1179,7 +1179,7 @@ static void mesh_foreachScreenEdge__mapFunc(void *userData, int index, float *v0 void mesh_foreachScreenEdge(void (*func)(void *userData, EditEdge *eed, int x0, int y0, int x1, int y1, int index), void *userData, int clipVerts) { struct { void (*func)(void *userData, EditEdge *eed, int x0, int y0, int x1, int y1, int index); void *userData; int clipVerts; float pmat[4][4], vmat[4][4]; } data; - DerivedMesh *dm = editmesh_get_derived_cage(); + DerivedMesh *dm = editmesh_get_derived_cage(CD_MASK_BAREMESH); data.func = func; data.userData = userData; @@ -1209,7 +1209,7 @@ static void mesh_foreachScreenFace__mapFunc(void *userData, int index, float *ce void mesh_foreachScreenFace(void (*func)(void *userData, EditFace *efa, int x, int y, int index), void *userData) { struct { void (*func)(void *userData, EditFace *efa, int x, int y, int index); void *userData; float pmat[4][4], vmat[4][4]; } data; - DerivedMesh *dm = editmesh_get_derived_cage(); + DerivedMesh *dm = editmesh_get_derived_cage(CD_MASK_BAREMESH); data.func = func; data.userData = userData; @@ -2150,7 +2150,8 @@ static int draw_mesh_object(Base *base, int dt, int flag) if (G.obedit!=ob) finalDM = cageDM = editmesh_get_derived_base(); else - cageDM = editmesh_get_derived_cage_and_final(&finalDM); + cageDM = editmesh_get_derived_cage_and_final(&finalDM, + get_viewedit_datamask()); if(dt>OB_WIRE) init_gl_materials(ob, 0); // no transp in editmode, the fancy draw over goes bad then draw_em_fancy(ob, G.editMesh, cageDM, finalDM, dt); @@ -2167,8 +2168,10 @@ static int draw_mesh_object(Base *base, int dt, int flag) /* don't create boundbox here with mesh_get_bb(), the derived system will make it, puts deformed bb's OK */ if(me->totface<=4 || boundbox_clip(ob->obmat, me->bb)) { - DerivedMesh *baseDM = mesh_get_derived_deform(ob); - DerivedMesh *realDM = mesh_get_derived_final(ob); + DerivedMesh *baseDM + = mesh_get_derived_deform(ob, get_viewedit_datamask()); + DerivedMesh *realDM + = mesh_get_derived_final(ob, get_viewedit_datamask()); if(dt==OB_SOLID) has_alpha= init_gl_materials(ob, (base->flag & OB_FROMDUPLI)==0); if(baseDM && realDM) draw_mesh_fancy(base, baseDM, realDM, dt, flag); @@ -4275,7 +4278,7 @@ static int bbs_mesh_wire__setDrawOpts(void *userData, int index) static void bbs_mesh_solid(Object *ob) { - DerivedMesh *dm = mesh_get_derived_final(ob); + DerivedMesh *dm = mesh_get_derived_final(ob, get_viewedit_datamask()); Mesh *me = (Mesh*)ob->data; glColor3ub(0, 0, 0); @@ -4311,7 +4314,7 @@ void draw_object_backbufsel(Object *ob) switch( ob->type) { case OB_MESH: if(ob==G.obedit) { - DerivedMesh *dm = editmesh_get_derived_cage(); + DerivedMesh *dm = editmesh_get_derived_cage(CD_MASK_BAREMESH); EM_init_index_arrays(1, 1, 1); @@ -4356,7 +4359,7 @@ void draw_object_instance(Object *ob, int dt, int outline) if(G.obedit && ob->data==G.obedit->data) edm= editmesh_get_derived_base(); else - dm = mesh_get_derived_final(ob); + dm = mesh_get_derived_final(ob, CD_MASK_BAREMESH); if(dt<=OB_WIRE) { if(dm) diff --git a/source/blender/src/editface.c b/source/blender/src/editface.c index fa40d210303..ba9174f0c4d 100644 --- a/source/blender/src/editface.c +++ b/source/blender/src/editface.c @@ -1584,7 +1584,7 @@ void texpaint_pick_uv(Object *ob, Mesh *mesh, unsigned int faceindex, short *xy, float v1[2], v2[2], v3[2], v4[2], p[2], w[3]; float absw, minabsw; int nvert; - DerivedMesh *dm = mesh_get_derived_final(ob); + DerivedMesh *dm = mesh_get_derived_final(ob, CD_MASK_BAREMESH); int *index = dm->getFaceDataArray(dm, CD_ORIGINDEX); MTFace *tface = dm->getFaceDataArray(dm, CD_MTFACE), *tf; int numfaces = dm->getNumFaces(dm), a; diff --git a/source/blender/src/editmesh_mods.c b/source/blender/src/editmesh_mods.c index f0b1aa7ebd6..bd20e68830d 100644 --- a/source/blender/src/editmesh_mods.c +++ b/source/blender/src/editmesh_mods.c @@ -625,7 +625,7 @@ static void draw_dm_mapped_face_center(DerivedMesh *dm, EditFace *efa) static void unified_select_draw(EditVert *eve, EditEdge *eed, EditFace *efa) { - DerivedMesh *dm = editmesh_get_derived_cage(); + DerivedMesh *dm = editmesh_get_derived_cage(CD_MASK_BAREMESH); glDrawBuffer(GL_FRONT); diff --git a/source/blender/src/editobject.c b/source/blender/src/editobject.c index eef50449b8a..a22ed7674f7 100644 --- a/source/blender/src/editobject.c +++ b/source/blender/src/editobject.c @@ -2567,7 +2567,7 @@ void convertmenu(void) G.totmesh++; /* make new mesh data from the original copy */ - dm= mesh_get_derived_final(ob1); + dm= mesh_get_derived_final(ob1, CD_MASK_MESH); /* dm= mesh_create_derived_no_deform(ob1, NULL); this was called original (instead of get_derived). man o man why! (ton) */ DM_to_mesh(dm, ob1->data); diff --git a/source/blender/src/poseobject.c b/source/blender/src/poseobject.c index aa82544217c..f2fe70737a8 100644 --- a/source/blender/src/poseobject.c +++ b/source/blender/src/poseobject.c @@ -755,7 +755,7 @@ void pose_adds_vgroups(Object *meshobj) if(poseobj==NULL || (poseobj->flag & OB_POSEMODE)==0) return; - dm = mesh_get_derived_final(meshobj); + dm = mesh_get_derived_final(meshobj, CD_MASK_BAREMESH); map.meshobj= meshobj; diff --git a/source/blender/src/transform_conversions.c b/source/blender/src/transform_conversions.c index 395020ddb68..3dafd08d57e 100755 --- a/source/blender/src/transform_conversions.c +++ b/source/blender/src/transform_conversions.c @@ -1521,11 +1521,11 @@ static float *get_crazy_mapped_editverts(void) /* this call disables subsurf and enables the underlying modifier to deform, apparently */ modifiers_setOnCage(G.obedit, md); /* make it all over */ - makeDerivedMesh(G.obedit); + makeDerivedMesh(G.obedit, CD_MASK_BAREMESH); } /* now get the cage */ - dm= editmesh_get_derived_cage(); + dm= editmesh_get_derived_cage(CD_MASK_BAREMESH); vertexcos= MEM_mallocN(3*sizeof(float)*G.totvert, "vertexcos map"); dm->foreachMappedVert(dm, make_vertexcos__mapFunc, vertexcos); diff --git a/source/blender/src/verse_object.c b/source/blender/src/verse_object.c index 6f6113b75dc..2a285d828b9 100644 --- a/source/blender/src/verse_object.c +++ b/source/blender/src/verse_object.c @@ -414,7 +414,7 @@ void b_verse_unsubscribe(VNode *vnode) } /* reinitialize object derived mesh */ - makeDerivedMesh(ob); + makeDerivedMesh(ob, get_viewedit_datamask()); DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA); } else if(vnode->type==V_NT_BITMAP) { @@ -445,7 +445,7 @@ void post_link_set(VLink *vlink) me = (Mesh*)((VGeomData*)target->data)->mesh; if(ob && me && ob->data!=me) { ob->data = me; - makeDerivedMesh(ob); + makeDerivedMesh(ob, get_viewedit_datamask()); } } diff --git a/source/blender/src/vpaint.c b/source/blender/src/vpaint.c index 916bca354e0..6ee817aeb5f 100644 --- a/source/blender/src/vpaint.c +++ b/source/blender/src/vpaint.c @@ -988,7 +988,7 @@ static void sample_wpaint(int mode) extern float editbutvweight; float w1, w2, w3, w4, co[3], fac; - dm = mesh_get_derived_final(ob); + dm = mesh_get_derived_final(ob, CD_MASK_BAREMESH); if(dm->getVertCo==NULL) { notice("Not supported yet"); }