Modifier Stack: Limit calculation to required data.
authorBen Batt <benbatt@gmail.com>
Tue, 5 Dec 2006 17:42:03 +0000 (17:42 +0000)
committerBen Batt <benbatt@gmail.com>
Tue, 5 Dec 2006 17:42:03 +0000 (17:42 +0000)
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.

30 files changed:
source/blender/blenkernel/BKE_DerivedMesh.h
source/blender/blenkernel/BKE_customdata.h
source/blender/blenkernel/BKE_displist.h
source/blender/blenkernel/BKE_modifier.h
source/blender/blenkernel/intern/DerivedMesh.c
source/blender/blenkernel/intern/anim.c
source/blender/blenkernel/intern/customdata.c
source/blender/blenkernel/intern/displist.c
source/blender/blenkernel/intern/exotic.c
source/blender/blenkernel/intern/mesh.c
source/blender/blenkernel/intern/modifier.c
source/blender/blenkernel/intern/object.c
source/blender/blenkernel/intern/softbody.c
source/blender/blenkernel/intern/subsurf_ccg.c
source/blender/blenlib/BLI_editVert.h
source/blender/makesdna/DNA_customdata_types.h
source/blender/makesdna/DNA_object_types.h
source/blender/python/api2_2x/Mesh.c
source/blender/python/api2_2x/NMesh.c
source/blender/render/intern/source/convertblender.c
source/blender/src/drawimage.c
source/blender/src/drawmesh.c
source/blender/src/drawobject.c
source/blender/src/editface.c
source/blender/src/editmesh_mods.c
source/blender/src/editobject.c
source/blender/src/poseobject.c
source/blender/src/transform_conversions.c
source/blender/src/verse_object.c
source/blender/src/vpaint.c

index 8a72b9ae2a90ad8d5b4f3e31609f67eb79a352c8..f7c771394b8edd7a2bea039a1382ca104e80945f 100644 (file)
@@ -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
 
index ce32f06e320e946a3bb90dafcb1d1614f3c4e7b4..d48340998e0c0870f77483d4c5a6b4b3ca915605 100644 (file)
@@ -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
index 04f3aadbe3c1f85e9c9fcbf5d663b8bdc839602a..979ed31fb2000e09bb4313ed06ac5ed957f3534d 100644 (file)
@@ -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);
index a4c050429e51ea0485c9c48231d71152e1213b4c..586ee4e8552c064bc2de8fe882fa75fbbc440e36 100644 (file)
 #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
index 462a5c09387c6ff7df3ccebfe453e2405131b2b5..8c3e807abd90d7ed43451f5ec9867d3af64d3421 100644 (file)
 #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; }
 
index ad97128bb379e25595bc4e9eb9889bc649ea5b47..849a7f316f24f569db6ea9a38289112d12eb4008 100644 (file)
@@ -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);
index 422107fa2733a5389555dac74771671e3758317b..508021ef74cf1bbe415aae9a4fc1d70df5efd94e 100644 (file)
@@ -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);
+}
index 763a4cdc0a09f24c849ef8245d4ca08e06c51374..1cedbe1338e4444fd6de1a690c546ae5e59f4542 100644 (file)
@@ -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;
                
index 0848d2b71a0abf3a7059edd2861719f6c8301ccc..4946066e4b3e70835cd4556ce5d2b64c479b742a 100644 (file)
@@ -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;
                
index 6de2717ba46c7a9b52f925bafaff8b102bc23fba..52c094acca443bb0df963a4b710b1a7bbba8bca5 100644 (file)
@@ -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);
 
index b1037da270ef40dc745370a769becffafe0ce1cf..43c513aaa1b538f294caf7015c7749389a59446f 100644 (file)
@@ -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
index af2d562b33154f3d96c6c8b39dff9474339c0ce5..a8bf87c966ffc56b5c53ab2e385fdfae30fcb446 100644 (file)
@@ -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);
index acbf4df653ad42906ff8d86945910fa69b337246..ad3ea337c5571e6ce3a7a1c78d963f04ba504d73 100644 (file)
@@ -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);
index 44845ed706bbaed22d519d1ba0efdb30e3af67e0..5f7b656d45acfaada717f1a23190983067146164 100644 (file)
@@ -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);
index d39cd748fb1009ddc4c5d32b9d1c23a1f3433ee6..e81e7db57ca565bce75236c7dc3daf6666d11372 100644 (file)
@@ -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;
index 08b0345af8de329b65523166de2bbf5f40aa0e4d..00c303c035761c4dda9826a295a7452c6ff8cb79 100644 (file)
@@ -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
index f9055dfc11bcc34a8d5868f5797f0be602c95a03..a27c6520787fd05d2891ee61f6c5a7b492f765fd 100644 (file)
@@ -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 */
index 01fce68137d08b1e69fd501f65cf588c6e822beb..8e0d5e9328423a6163bc3db6639fdb89cbc149d8 100644 (file)
@@ -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 );
index 5df435ecb2a4abba50b6b7da0e3df5007df24fb6..7cd3d74673f289fb4e7ef073806ebdf29589eb75 100644 (file)
@@ -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);
                }
index 7232e0e6e715ad5ab5f91987e2a7c87c8207b774..6268971bb798ac5270956b8bebda421909b14738 100644 (file)
@@ -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) {
index 3d11568a8bce9727961be97fbe8880cc88af6134..7e77432158eec3ab215348cba55c0e02c85ee613 100644 (file)
@@ -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);
index ac9940f5a022381a0666596a39d68f985c0a5367..c6b0a874ff412d260e2f8e178ada8885a2d9b498 100644 (file)
@@ -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? */
index 5bc188c6ac66e0b3a7f593c1940a81f75becd95d..94917c996710bad8601fcce9b750e83d43045417 100644 (file)
@@ -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)
index fa40d210303fcdd460be0a238b8c3b9356a8b0e6..ba9174f0c4dd901d801ed4f34b017dea02a80975 100644 (file)
@@ -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;
index f0b1aa7ebd6425ff4ec9d862306b8e141e669545..bd20e68830dfd248574aa482adda4d4ebda37520 100644 (file)
@@ -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);
 
index eef50449b8a70aefab929c03ef52580b56a47d7a..a22ed7674f7069a081005e4a6980436a5cdd476f 100644 (file)
@@ -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);
index aa82544217c4382029192c499d8e6237ee84197c..f2fe70737a8bb85e951fd09c618fb1c36873a06f 100644 (file)
@@ -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;
        
index 395020ddb683a46753ca80918920accd165517cf..3dafd08d57e4fb4b1058a818c551ea93fea2c322 100755 (executable)
@@ -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);
index 6f6113b75dca9d93b7853d02879c2f6ff63818be..2a285d828b9f64f2d235cc2d8fe00a1040e9e4e8 100644 (file)
@@ -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());
                }
        }
 
index 916bca354e0fc0f3b79443e9f130e55abc2a7a30..6ee817aeb5f22f375b4fb2d4b8a5017602e36fe1 100644 (file)
@@ -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");
                        }