support for 'origspace' data layer - used for hair on subsurf mesh.
authorCampbell Barton <ideasman42@gmail.com>
Sun, 5 Feb 2012 11:30:26 +0000 (11:30 +0000)
committerCampbell Barton <ideasman42@gmail.com>
Sun, 5 Feb 2012 11:30:26 +0000 (11:30 +0000)
currently only works for 3/4 sided faces.

12 files changed:
source/blender/blenkernel/BKE_DerivedMesh.h
source/blender/blenkernel/BKE_mesh.h
source/blender/blenkernel/intern/DerivedMesh.c
source/blender/blenkernel/intern/customdata.c
source/blender/blenkernel/intern/mesh.c
source/blender/blenkernel/intern/particle.c
source/blender/blenkernel/intern/particle_system.c
source/blender/blenkernel/intern/subsurf_ccg.c
source/blender/makesdna/DNA_customdata_types.h
source/blender/makesdna/DNA_meshdata_types.h
source/blender/modifiers/intern/MOD_ngoninterp.c
source/blender/modifiers/intern/MOD_particlesystem.c

index 9041add3c6698b0ec58d80c54402a0abb8a54cef..9fa64d01a0a807684670f6e80fd0df8554a95804 100644 (file)
@@ -484,6 +484,7 @@ void *DM_get_vert_data_layer(struct DerivedMesh *dm, int type);
 void *DM_get_edge_data_layer(struct DerivedMesh *dm, int type);
 void *DM_get_tessface_data_layer(struct DerivedMesh *dm, int type);
 void *DM_get_poly_data_layer(struct DerivedMesh *dm, int type);
+void *DM_get_loop_data_layer(struct DerivedMesh *dm, int type);
 
 /* custom data setting functions
  * copy supplied data into first layer of type using layer's copy function
@@ -676,6 +677,8 @@ void DM_calc_auto_bump_scale(DerivedMesh *dm);
 /* Set object's bounding box based on DerivedMesh min/max data */
 void DM_set_object_boundbox(struct Object *ob, DerivedMesh *dm);
 
+void DM_init_origspace(DerivedMesh *dm);
+
 /* debug only */
 #ifndef NDEBUG
 char *DM_debug_info(DerivedMesh *dm);
index 270e07ba661dd43f11268e4019a04a353a5b7521..598b57b0cfe8097579836a19fe795cecef3ea447 100644 (file)
@@ -267,7 +267,7 @@ void BKE_mesh_ensure_tessface(struct Mesh *mesh);
 void mesh_loops_to_mface_corners(struct CustomData *fdata, struct CustomData *ldata,
                                  struct CustomData *pdata, int lindex[4], int findex,
                                  const int polyindex, const int mf_len,
-                                 const int numTex, const int numCol, const int hasWCol);
+                                 const int numTex, const int numCol, const int hasWCol, const int hasOrigSpace);
 
 #ifdef __cplusplus
 }
index 939fe2caa17ac0bb5200046cc16c6d3f09f3a960..ec7780eed5dda6b53efe4ea0990ee593bf345ea4 100644 (file)
@@ -562,6 +562,11 @@ void *DM_get_poly_data_layer(DerivedMesh *dm, int type)
        return CustomData_get_layer(&dm->polyData, type);
 }
 
+void *DM_get_loop_data_layer(DerivedMesh *dm, int type)
+{
+       return CustomData_get_layer(&dm->loopData, type);
+}
+
 void DM_set_vert_data(DerivedMesh *dm, int index, int type, void *data)
 {
        CustomData_set(&dm->vertData, index, type, data);
@@ -1504,9 +1509,12 @@ static void mesh_calc_modifiers(Scene *scene, Object *ob, float (*inputVertexCos
                                add_orco_dm(ob, NULL, dm, clothorcodm, CD_CLOTH_ORCO);
 
                        /* add an origspace layer if needed */
-                       if(((CustomDataMask)GET_INT_FROM_POINTER(curr->link)) & CD_MASK_ORIGSPACE)
-                               if(!CustomData_has_layer(&dm->faceData, CD_ORIGSPACE))
-                                       DM_add_tessface_layer(dm, CD_ORIGSPACE, CD_DEFAULT, NULL);
+                       if(((CustomDataMask)GET_INT_FROM_POINTER(curr->link)) & CD_MASK_ORIGSPACE_MLOOP) {
+                               if(!CustomData_has_layer(&dm->loopData, CD_ORIGSPACE_MLOOP)) {
+                                       DM_add_loop_layer(dm, CD_ORIGSPACE_MLOOP, CD_CALLOC, NULL);
+                                       DM_init_origspace(dm);
+                               }
+                       }
 
                        ndm = mti->applyModifier(md, ob, dm, useRenderParams, useCache);
 
@@ -1825,9 +1833,12 @@ static void editbmesh_calc_modifiers(Scene *scene, Object *ob, BMEditMesh *em, D
 
                        DM_set_only_copy(dm, mask | CD_MASK_ORIGINDEX);
 
-                       if(mask & CD_MASK_ORIGSPACE)
-                               if(!CustomData_has_layer(&dm->faceData, CD_ORIGSPACE))
-                                       DM_add_tessface_layer(dm, CD_ORIGSPACE, CD_DEFAULT, NULL);
+                       if(mask & CD_MASK_ORIGSPACE_MLOOP) {
+                               if(!CustomData_has_layer(&dm->loopData, CD_ORIGSPACE_MLOOP)) {
+                                       DM_add_loop_layer(dm, CD_ORIGSPACE_MLOOP, CD_CALLOC, NULL);
+                                       DM_init_origspace(dm);
+                               }
+                       }
                        
                        if (mti->applyModifierEM)
                                ndm = mti->applyModifierEM(md, ob, em, dm);
@@ -2859,6 +2870,30 @@ static DerivedMesh *navmesh_dm_createNavMeshForVisualization(DerivedMesh *dm)
 /* --- NAVMESH (end) --- */
 
 
+void DM_init_origspace(DerivedMesh *dm)
+{
+       static float default_osf[4][2] = {{0, 0}, {1, 0}, {1, 1}, {0, 1}};
+
+       OrigSpaceLoop *lof_array = CustomData_get_layer(&dm->loopData, CD_ORIGSPACE_MLOOP);
+       OrigSpaceLoop *lof;
+       const int numpoly = dm->getNumPolys(dm);
+       // const int numloop = dm->getNumLoops(dm);
+       MPoly *mp = dm->getPolyArray(dm);
+       int i, j;
+
+       for (i = 0; i < numpoly; i++, mp++) {
+               /* only quads/tri's for now */
+               if (mp->totloop == 3 || mp->totloop == 4) {
+                       lof = lof_array + mp->loopstart;
+                       for (j = 0; j < mp->totloop; j++, lof++) {
+                               copy_v2_v2(lof->uv, default_osf[j]);
+                       }
+               }
+       }
+}
+
+
+
 /* derivedmesh info printing function,
  * to help track down differences DM output */
 
@@ -2910,6 +2945,10 @@ char *DM_debug_info(DerivedMesh *dm)
        dm_debug_info_layers(dynstr, dm, dm->getVertDataArray);
        BLI_dynstr_appendf(dynstr, "    ),\n");
 
+       BLI_dynstr_appendf(dynstr, "    'loopLayers': (\n");
+       dm_debug_info_layers(dynstr, dm, DM_get_loop_data_layer);
+       BLI_dynstr_appendf(dynstr, "    ),\n");
+
        BLI_dynstr_appendf(dynstr, "    'edgeLayers': (\n");
        dm_debug_info_layers(dynstr, dm, dm->getEdgeDataArray);
        BLI_dynstr_appendf(dynstr, "    ),\n");
@@ -2918,7 +2957,7 @@ char *DM_debug_info(DerivedMesh *dm)
        dm_debug_info_layers(dynstr, dm, dm->getTessFaceDataArray);
        BLI_dynstr_appendf(dynstr, "    ),\n");
 
-       BLI_dynstr_appendf(dynstr, "    'PolyLayers': (\n");
+       BLI_dynstr_appendf(dynstr, "    'polyLayers': (\n");
        dm_debug_info_layers(dynstr, dm, DM_get_poly_data_layer);
        BLI_dynstr_appendf(dynstr, "    ),\n");
 
index 4dbb143a73e0256039cbb1d46503f7d56009a509..b7066dbcd84edba68566d333eb3d45a9171ed289 100644 (file)
@@ -871,6 +871,77 @@ static void layerInterp_mloopuv(void **sources, float *weights,
        }
 }
 
+/* origspace is almost exact copy of mloopuv's, keep in sync */
+static void layerCopyValue_mloop_origspace(void *source, void *dest)
+{
+       OrigSpaceLoop *luv1 = source, *luv2 = dest;
+
+       copy_v2_v2(luv2->uv, luv1->uv);
+}
+
+static int layerEqual_mloop_origspace(void *data1, void *data2)
+{
+       OrigSpaceLoop *luv1 = data1, *luv2 = data2;
+
+       return len_squared_v2v2(luv1->uv, luv2->uv) < 0.00001f;
+}
+
+static void layerMultiply_mloop_origspace(void *data, float fac)
+{
+       OrigSpaceLoop *luv = data;
+
+       mul_v2_fl(luv->uv, fac);
+}
+
+static void layerInitMinMax_mloop_origspace(void *vmin, void *vmax)
+{
+       OrigSpaceLoop *min = vmin, *max = vmax;
+
+       INIT_MINMAX2(min->uv, max->uv);
+}
+
+static void layerDoMinMax_mloop_origspace(void *data, void *vmin, void *vmax)
+{
+       OrigSpaceLoop *min = vmin, *max = vmax, *luv = data;
+
+       DO_MINMAX2(luv->uv, min->uv, max->uv);
+}
+
+static void layerAdd_mloop_origspace(void *data1, void *data2)
+{
+       OrigSpaceLoop *l1 = data1, *l2 = data2;
+
+       add_v2_v2(l1->uv, l2->uv);
+}
+
+static void layerInterp_mloop_origspace(void **sources, float *weights,
+                                float *sub_weights, int count, void *dest)
+{
+       OrigSpaceLoop *mluv = dest;
+       float *uv= mluv->uv;
+       int i;
+
+       zero_v2(uv);
+
+       if (sub_weights) {
+               const float *sub_weight = sub_weights;
+               for(i = 0; i < count; i++) {
+                       float weight = weights ? weights[i] : 1.0f;
+                       OrigSpaceLoop *src = sources[i];
+                       madd_v2_v2fl(uv, src->uv, (*sub_weight) * weight);
+                       sub_weight++;
+               }
+       }
+       else {
+               for(i = 0; i < count; i++) {
+                       float weight = weights ? weights[i] : 1;
+                       OrigSpaceLoop *src = sources[i];
+                       madd_v2_v2fl(uv, src->uv, weight);
+               }
+       }
+}
+/* --- end copy */
+
 static void layerInterp_mcol(void **sources, float *weights,
                                                         float *sub_weights, int count, void *dest)
 {
@@ -1079,7 +1150,11 @@ static const LayerTypeInfo LAYERTYPEINFO[CD_NUMTYPES] = {
        {sizeof(float), "", 0, "BevelWeight", NULL, NULL, layerInterp_bweight},
        /* 30: CD_CREASE */
        {sizeof(float), "", 0, "SubSurfCrease", NULL, NULL, layerInterp_bweight},
-       /* 31: CD_WEIGHT_MLOOPCOL */
+    /* 31: CD_ORIGSPACE_MLOOP */
+       {sizeof(OrigSpaceLoop), "OrigSpaceLoop", 1, "OS Loop", NULL, NULL, layerInterp_mloop_origspace, NULL, NULL,
+        layerEqual_mloop_origspace, layerMultiply_mloop_origspace, layerInitMinMax_mloop_origspace,
+        layerAdd_mloop_origspace, layerDoMinMax_mloop_origspace, layerCopyValue_mloop_origspace},
+       /* 32: CD_WEIGHT_MLOOPCOL */
        {sizeof(MLoopCol), "MLoopCol", 1, "WeightLoopCol", NULL, NULL, layerInterp_mloopcol, NULL,
         layerDefault_mloopcol, layerEqual_mloopcol, layerMultiply_mloopcol, layerInitMinMax_mloopcol,
         layerAdd_mloopcol, layerDoMinMax_mloopcol, layerCopyValue_mloopcol},
@@ -1100,7 +1175,7 @@ static const char *LAYERTYPENAMES[CD_NUMTYPES] = {
 /* BMESH ONLY */
        ,
        /* 25-29 */ "CDMPoly", "CDMLoop", "CDShapeKeyIndex", "CDShapeKey", "CDBevelWeight",
-       /* 30-31 */ "CDSubSurfCrease", "CDWeightLoopCol"
+       /* 30-32 */ "CDSubSurfCrease", "CDOrigSpaceLoop", "CDWeightLoopCol"
 /* END BMESH ONLY */
 
 };
@@ -1123,7 +1198,7 @@ const CustomDataMask CD_MASK_DERIVEDMESH =
        CD_MASK_MSTICKY | CD_MASK_MDEFORMVERT | CD_MASK_MTFACE |
        CD_MASK_MCOL | CD_MASK_PROP_FLT | CD_MASK_PROP_INT | CD_MASK_CLOTH_ORCO |
        CD_MASK_MLOOPUV | CD_MASK_MLOOPCOL | CD_MASK_MTEXPOLY | CD_MASK_WEIGHT_MLOOPCOL |
-       CD_MASK_PROP_STR | CD_MASK_ORIGSPACE | CD_MASK_ORCO | CD_MASK_TANGENT | 
+       CD_MASK_PROP_STR | CD_MASK_ORIGSPACE | CD_MASK_ORIGSPACE_MLOOP | CD_MASK_ORCO | CD_MASK_TANGENT |
        CD_MASK_WEIGHT_MCOL | CD_MASK_NORMAL | CD_MASK_SHAPEKEY | CD_MASK_RECAST |
        CD_MASK_ORIGINDEX | CD_MASK_POLYINDEX;
 const CustomDataMask CD_MASK_BMESH = CD_MASK_MLOOPUV | CD_MASK_MLOOPCOL | CD_MASK_MTEXPOLY |
@@ -2395,6 +2470,9 @@ void CustomData_from_bmeshpoly(CustomData *fdata, CustomData *pdata, CustomData
                else if (ldata->layers[i].type == CD_WEIGHT_MLOOPCOL) {
                        CustomData_add_layer_named(fdata, CD_WEIGHT_MCOL, CD_CALLOC, NULL, total, ldata->layers[i].name);
                }
+               else if (ldata->layers[i].type == CD_ORIGSPACE_MLOOP) {
+                       CustomData_add_layer_named(fdata, CD_ORIGSPACE, CD_CALLOC, NULL, total, ldata->layers[i].name);
+               }
        }
 }
 
index 7f217eb8e628406adc3ac929f77895b97aa9f46f..2a78bbca7fb8ed5dbabef31717052f253c0fb7d0 100644 (file)
@@ -2177,7 +2177,8 @@ void mesh_loops_to_mface_corners(CustomData *fdata, CustomData *ldata,
                                  /* cache values to avoid lookups every time */
                                  const int numTex, /* CustomData_number_of_layers(pdata, CD_MTEXPOLY) */
                                  const int numCol, /* CustomData_number_of_layers(ldata, CD_MLOOPCOL) */
-                                 const int hasWCol /* CustomData_has_layer(ldata, CD_WEIGHT_MLOOPCOL) */
+                                 const int hasWCol, /* CustomData_has_layer(ldata, CD_WEIGHT_MLOOPCOL) */
+                                 const int hasOrigSpace /* CustomData_has_layer(ldata, CD_ORIGSPACE_MLOOP) */
                                  )
 {
        MTFace *texface;
@@ -2228,6 +2229,17 @@ void mesh_loops_to_mface_corners(CustomData *fdata, CustomData *ldata,
                        mcol[j].a = mloopcol->a;
                }
        }
+
+       if (hasOrigSpace) {
+               OrigSpaceFace *of = CustomData_get(fdata, findex, CD_ORIGSPACE);
+               OrigSpaceLoop *lof;
+
+               for (j=0; j < mf_len; j++) {
+                       lof = CustomData_get(ldata, lindex[j], CD_ORIGSPACE_MLOOP);
+                       of->uv[j][0] = lof->uv[0];
+                       of->uv[j][1] = lof->uv[1];
+               }
+       }
 }
 
 /*
@@ -2269,6 +2281,7 @@ int mesh_recalcTesselation(CustomData *fdata,
        const int numTex = CustomData_number_of_layers(pdata, CD_MTEXPOLY);
        const int numCol = CustomData_number_of_layers(ldata, CD_MLOOPCOL);
        const int hasWCol = CustomData_has_layer(ldata, CD_WEIGHT_MLOOPCOL);
+       const int hasOrigSpace = CustomData_has_layer(ldata, CD_ORIGSPACE_MLOOP);
 
        mpoly = CustomData_get_layer(pdata, CD_MPOLY);
        mloop = CustomData_get_layer(ldata, CD_MLOOP);
@@ -2493,7 +2506,7 @@ int mesh_recalcTesselation(CustomData *fdata,
 #else
                                            3,
 #endif
-                                           numTex, numCol, hasWCol);
+                                           numTex, numCol, hasWCol, hasOrigSpace);
 
 
 #ifdef USE_TESSFACE_QUADS
@@ -2531,6 +2544,7 @@ int mesh_mpoly_to_mface(struct CustomData *fdata, struct CustomData *ldata,
        const int numTex = CustomData_number_of_layers(pdata, CD_MTEXPOLY);
        const int numCol = CustomData_number_of_layers(ldata, CD_MLOOPCOL);
        const int hasWCol = CustomData_has_layer(ldata, CD_WEIGHT_MLOOPCOL);
+       const int hasOrigSpace = CustomData_has_layer(ldata, CD_ORIGSPACE_MLOOP);
 
        mpoly = CustomData_get_layer(pdata, CD_MPOLY);
        mloop = CustomData_get_layer(ldata, CD_MLOOP);
@@ -2588,7 +2602,7 @@ int mesh_mpoly_to_mface(struct CustomData *fdata, struct CustomData *ldata,
 
                                mesh_loops_to_mface_corners(fdata, ldata, pdata,
                                                            lindex, k, i, 3,
-                                                           numTex, numCol, hasWCol);
+                                                           numTex, numCol, hasWCol, hasOrigSpace);
                                test_index_face(mf, fdata, k, 3);
                        }
                        else {
@@ -2608,7 +2622,7 @@ int mesh_mpoly_to_mface(struct CustomData *fdata, struct CustomData *ldata,
 
                                mesh_loops_to_mface_corners(fdata, ldata, pdata,
                                                            lindex, k, i, 4,
-                                                           numTex, numCol, hasWCol);
+                                                           numTex, numCol, hasWCol, hasOrigSpace);
                                test_index_face(mf, fdata, k, 4);
                        }
 
index 98413d79358e8fed6a5fae0cf8415cdc8bebd5a2..ec3f71e6713f28c297ad5e07e7c01ec92e284fca 100644 (file)
@@ -1587,13 +1587,13 @@ static void psys_origspace_to_w(OrigSpaceFace *osface, int quad, const float w[4
 int psys_particle_dm_face_lookup(Object *ob, DerivedMesh *dm, int index, const float fw[4], struct LinkNode *node)
 {
        Mesh *me= (Mesh*)ob->data;
-       MFace *mface;
+       MPoly *mface;
        OrigSpaceFace *osface;
        int *origindex;
        int quad, findex, totface;
        float uv[2], (*faceuv)[2];
 
-       mface = dm->getTessFaceDataArray(dm, CD_MFACE);
+       mface = dm->getPolyArray(dm);
        origindex = dm->getTessFaceDataArray(dm, CD_ORIGINDEX);
        osface = dm->getTessFaceDataArray(dm, CD_ORIGSPACE);
 
@@ -1609,7 +1609,7 @@ int psys_particle_dm_face_lookup(Object *ob, DerivedMesh *dm, int index, const f
                        return DMCACHE_NOTFOUND;
                }
        }
-       else if(index >= me->totface)
+       else if(index >= me->totpoly)
                return DMCACHE_NOTFOUND; /* index not in the original mesh */
 
        psys_w_to_origspace(fw, uv);
@@ -1618,7 +1618,7 @@ int psys_particle_dm_face_lookup(Object *ob, DerivedMesh *dm, int index, const f
                for(;node; node=node->next) {
                        findex= GET_INT_FROM_POINTER(node->link);
                        faceuv= osface[findex].uv;
-                       quad= mface[findex].v4;
+                       quad = (mface[findex].totloop == 4);
 
                        /* check that this intersects - Its possible this misses :/ -
                         * could also check its not between */
@@ -1634,7 +1634,7 @@ int psys_particle_dm_face_lookup(Object *ob, DerivedMesh *dm, int index, const f
                for(findex=0; findex<totface; findex++) {
                        if(origindex[findex] == index) {
                                faceuv= osface[findex].uv;
-                               quad= mface[findex].v4;
+                               quad = (mface[findex].totloop == 4);
 
                                /* check that this intersects - Its possible this misses :/ -
                                 * could also check its not between */
index 5356615b122d9a5d41178ee53518eabaf67e13f0..75bf89fb032799f07df267d56bb223fdabf60483 100644 (file)
@@ -353,7 +353,7 @@ void psys_calc_dmcache(Object *ob, DerivedMesh *dm, ParticleSystem *psys)
                }
                else { /* FROM_FACE/FROM_VOLUME */
                        totdmelem= dm->getNumTessFaces(dm);
-                       totelem= me->totface;
+                       totelem= me->totpoly;
                        origindex= dm->getTessFaceDataArray(dm, CD_ORIGINDEX);
                }
        
index 7f2aa947db54bde802766c55c23c08721a37bf5a..3352766a859e135b549f919495f364926d2699fb 100644 (file)
@@ -2388,7 +2388,7 @@ static void ccgDM_release(DerivedMesh *dm) {
 
 static void ccg_loops_to_corners(CustomData *fdata, CustomData *ldata, 
                                  CustomData *pdata, int loopstart, int findex,  int polyindex,
-                                 const int numTex, const int numCol, const int hasWCol)
+                                 const int numTex, const int numCol, const int hasWCol, const int hasOrigSpace)
 {
        MTFace *texface;
        MTexPoly *texpoly;
@@ -2438,6 +2438,17 @@ static void ccg_loops_to_corners(CustomData *fdata, CustomData *ldata,
                        mcol[j].a = mloopcol->a;
                }
        }
+
+       if (hasOrigSpace) {
+               OrigSpaceFace *of = CustomData_get(fdata, findex, CD_ORIGSPACE);
+               OrigSpaceLoop *lof;
+
+               lof = CustomData_get(ldata, loopstart, CD_ORIGSPACE_MLOOP);
+               for (j=0; j<4; j++, lof++) {
+                       of->uv[j][0] = lof->uv[0];
+                       of->uv[j][1] = lof->uv[1];
+               }
+       }
 }
 
 static void *ccgDM_get_vert_data_layer(DerivedMesh *dm, int type)
@@ -2855,7 +2866,8 @@ static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss,
        int gridFaces, gridCuts;
        /*int gridSideVerts;*/
        int gridSideEdges;
-       int numTex, numCol, hasWCol;
+       int numTex, numCol;
+       int hasWCol, hasOrigSpace;
        int gridInternalEdges;
        float *w = NULL;
        WeightTable wtable = {0};
@@ -2874,11 +2886,18 @@ static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss,
        numTex = CustomData_number_of_layers(&ccgdm->dm.loopData, CD_MLOOPUV);
        numCol = CustomData_number_of_layers(&ccgdm->dm.loopData, CD_MLOOPCOL);
        hasWCol = CustomData_has_layer(&ccgdm->dm.loopData, CD_WEIGHT_MLOOPCOL);
+       hasOrigSpace = CustomData_has_layer(&ccgdm->dm.loopData, CD_ORIGSPACE_MLOOP);
        
-       if (numTex && CustomData_number_of_layers(&ccgdm->dm.faceData, CD_MTFACE) != numTex)
-               CustomData_from_bmeshpoly(&ccgdm->dm.faceData, &ccgdm->dm.polyData, &ccgdm->dm.loopData, ccgSubSurf_getNumFinalFaces(ss));
-       else if (numCol && CustomData_number_of_layers(&ccgdm->dm.faceData, CD_MCOL) != numCol)
-               CustomData_from_bmeshpoly(&ccgdm->dm.faceData, &ccgdm->dm.polyData, &ccgdm->dm.loopData, ccgSubSurf_getNumFinalFaces(ss));
+       if (
+               (numTex && CustomData_number_of_layers(&ccgdm->dm.faceData, CD_MTFACE) != numTex)  ||
+               (numCol && CustomData_number_of_layers(&ccgdm->dm.faceData, CD_MCOL) != numCol)    ||
+               (hasOrigSpace && !CustomData_has_layer(&ccgdm->dm.faceData, CD_ORIGSPACE)) )
+       {
+               CustomData_from_bmeshpoly(&ccgdm->dm.faceData,
+                                         &ccgdm->dm.polyData,
+                                         &ccgdm->dm.loopData,
+                                         ccgSubSurf_getNumFinalFaces(ss));
+       }
 
        ccgdm->dm.getMinMax = ccgDM_getMinMax;
        ccgdm->dm.getNumVerts = ccgDM_getNumVerts;
@@ -3143,7 +3162,7 @@ static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss,
                                        /*generate tesselated face data used for drawing*/
                                        ccg_loops_to_corners(&ccgdm->dm.faceData, &ccgdm->dm.loopData,
                                                             &ccgdm->dm.polyData, loopindex2-4, faceNum, faceNum,
-                                                            numTex, numCol, hasWCol);
+                                                            numTex, numCol, hasWCol, hasOrigSpace);
                                        
                                        /*set original index data*/
                                        if (faceOrigIndex) {
index 4855f5eb3a1da038cc8e8eca981f27179fc6a09f..751fc45284d3fa76a5eefdc3515221dbe4ce077c 100644 (file)
@@ -63,11 +63,13 @@ typedef struct CustomDataExternal {
  * layers, each with a data type (e.g. MTFace, MDeformVert, etc.). */
 typedef struct CustomData {
        CustomDataLayer *layers;      /* CustomDataLayers, ordered by type */
-       int typemap[32];              /* runtime only! - maps types to indices of first layer of that type,
+       int typemap[33];              /* runtime only! - maps types to indices of first layer of that type,
                                       * MUST be >= CD_NUMTYPES, but we cant use a define here.
                                       * Correct size is ensured in CustomData_update_typemap assert() */
+       int pad1;
+
        int totlayer, maxlayer;       /* number of layers, size of layers array */
-       int totsize, pad;             /* in editmode, total size of all data layers */
+       int totsize, pad2;             /* in editmode, total size of all data layers */
        void *pool;                   /* Bmesh: Memory pool for allocation of blocks */
        CustomDataExternal *external; /* external file storing customdata layers */
 } CustomData;
@@ -106,10 +108,11 @@ typedef struct CustomData {
 #define CD_SHAPEKEY            28
 #define CD_BWEIGHT             29
 #define CD_CREASE              30
-#define CD_WEIGHT_MLOOPCOL     31
+#define CD_ORIGSPACE_MLOOP     31
+#define CD_WEIGHT_MLOOPCOL     32
 /* BMESH ONLY END */
 
-#define CD_NUMTYPES            32
+#define CD_NUMTYPES            33
 
 /* Bits for CustomDataMask */
 #define CD_MASK_MVERT          (1 << CD_MVERT)
@@ -143,7 +146,8 @@ typedef struct CustomData {
 #define CD_MASK_SHAPEKEY       (1 << CD_SHAPEKEY)
 #define CD_MASK_BWEIGHT                (1 << CD_BWEIGHT)
 #define CD_MASK_CREASE         (1 << CD_CREASE)
-#define CD_MASK_WEIGHT_MLOOPCOL (1 << CD_WEIGHT_MLOOPCOL)
+#define CD_MASK_ORIGSPACE_MLOOP        (1 << CD_ORIGSPACE_MLOOP)
+#define CD_MASK_WEIGHT_MLOOPCOL (1L << CD_WEIGHT_MLOOPCOL)
 /* BMESH ONLY END */
 
 /* CustomData.flag */
index ed13ae00632c7393f4c30c4771b2d3a4fc9a5723..3a34ba38a76dda72b4b6650e10f8055668ea7a05 100644 (file)
@@ -146,6 +146,10 @@ typedef struct OrigSpaceFace {
        float uv[4][2];
 } OrigSpaceFace;
 
+typedef struct OrigSpaceLoop {
+       float uv[2];
+} OrigSpaceLoop;
+
 typedef struct MDisps {
        /* Strange bug in SDNA: if disps pointer comes first, it fails to see totdisp */
        int totdisp;
index 264578ea3d89eb2137cf40826175acffde79dda4..498e5d3bdeabef98af40c4e2eed8284bd6521b56 100644 (file)
@@ -94,6 +94,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *UNUSED(ob),
        int numTex;
        int numCol;
        int hasWCol;
+       int hasOrigSpace;
 
        if (nmd->resolution <= 0)
                return dm;
@@ -120,6 +121,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *UNUSED(ob),
        numTex = CustomData_number_of_layers(&dm->polyData, CD_MTEXPOLY);
        numCol = CustomData_number_of_layers(&dummy->loopData, CD_MLOOPCOL);
        hasWCol = CustomData_has_layer(&dummy->loopData, CD_WEIGHT_MLOOPCOL);
+       hasOrigSpace = CustomData_has_layer(&dummy->loopData, CD_ORIGSPACE_MLOOP);
 
        /*copy original verts here, so indices stay correct*/
        omvert = dm->getVertArray(dm);
@@ -272,7 +274,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *UNUSED(ob),
                
                mesh_loops_to_mface_corners(&cddm->faceData, &dummy->loopData, &dm->polyData,
                                            lindex, i, origf[i], 3,
-                                           numTex, numCol, hasWCol);
+                                           numTex, numCol, hasWCol, hasOrigSpace);
        }
        
        CustomData_copy_data(&dm->vertData, &cddm->vertData, 0, 0, dm->numVertData);
index 98a1921f14bc654c5c44036f4a05150fef7fb425..10e43afebe22e875deaaf602914e9b2fb1afcdf0 100644 (file)
@@ -112,7 +112,7 @@ static CustomDataMask requiredDataMask(Object *UNUSED(ob), ModifierData *md)
        
        /* particles only need this if they are after a non deform modifier, and
        * the modifier stack will only create them in that case. */
-       dataMask |= CD_MASK_ORIGSPACE|CD_MASK_ORIGINDEX;
+       dataMask |= CD_MASK_ORIGSPACE_MLOOP|CD_MASK_ORIGINDEX;
 
        dataMask |= CD_MASK_ORCO;