BMesh: minor optimizations for shapekey lookups on conversion
authorCampbell Barton <ideasman42@gmail.com>
Tue, 22 Apr 2014 14:49:28 +0000 (00:49 +1000)
committerCampbell Barton <ideasman42@gmail.com>
Tue, 22 Apr 2014 14:49:28 +0000 (00:49 +1000)
source/blender/bmesh/intern/bmesh_mesh_conv.c

index e9c000539301fb8eda94b5d4555f6fba3db47a6c..b7be0cc0ae2397d43fc3e6b3a2aba5038d3f8515 100644 (file)
@@ -233,12 +233,12 @@ void BM_mesh_bm_from_me(BMesh *bm, Mesh *me,
        BMEdge *e, **etable = NULL;
        BMFace *f;
        float (*keyco)[3] = NULL;
-       int *keyi;
        int totuv, i, j;
 
        int cd_vert_bweight_offset;
        int cd_edge_bweight_offset;
        int cd_edge_crease_offset;
+       int cd_shape_keyindex_offset;
 
        /* free custom data */
        /* this isnt needed in most cases but do just incase */
@@ -325,6 +325,7 @@ void BM_mesh_bm_from_me(BMesh *bm, Mesh *me,
        cd_vert_bweight_offset = CustomData_get_offset(&bm->vdata, CD_BWEIGHT);
        cd_edge_bweight_offset = CustomData_get_offset(&bm->edata, CD_BWEIGHT);
        cd_edge_crease_offset  = CustomData_get_offset(&bm->edata, CD_CREASE);
+       cd_shape_keyindex_offset = me->key ? CustomData_get_offset(&bm->vdata, CD_SHAPE_KEYINDEX) : -1;
 
        for (i = 0, mvert = me->mvert; i < me->totvert; i++, mvert++) {
                v = vtable[i] = BM_vert_create(bm, keyco && set_key ? keyco[i] : mvert->co, NULL, BM_CREATE_SKIP_CD);
@@ -348,10 +349,7 @@ void BM_mesh_bm_from_me(BMesh *bm, Mesh *me,
                /* set shapekey data */
                if (me->key) {
                        /* set shape key original index */
-                       keyi = CustomData_bmesh_get(&bm->vdata, v->head.data, CD_SHAPE_KEYINDEX);
-                       if (keyi) {
-                               *keyi = i;
-                       }
+                       if (cd_shape_keyindex_offset != -1) BM_ELEM_CD_SET_INT(v, cd_shape_keyindex_offset, i);
 
                        for (block = me->key->block.first, j = 0; block; block = block->next, j++) {
                                float *co = CustomData_bmesh_get_n(&bm->vdata, v->head.data, CD_SHAPEKEY, j);
@@ -496,9 +494,9 @@ void BM_mesh_bm_from_me(BMesh *bm, Mesh *me,
  */
 static BMVert **bm_to_mesh_vertex_map(BMesh *bm, int ototvert)
 {
+       const int cd_shape_keyindex_offset = CustomData_get_offset(&bm->vdata, CD_SHAPE_KEYINDEX);
        BMVert **vertMap = NULL;
        BMVert *eve;
-       int index;
        int i = 0;
        BMIter iter;
 
@@ -506,32 +504,22 @@ static BMVert **bm_to_mesh_vertex_map(BMesh *bm, int ototvert)
        BLI_assert(ototvert > 0);
 
        vertMap = MEM_callocN(sizeof(*vertMap) * ototvert, "vertMap");
-       if (CustomData_has_layer(&bm->vdata, CD_SHAPE_KEYINDEX)) {
-               int *keyi;
-               BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) {
-                       keyi = CustomData_bmesh_get(&bm->vdata, eve->head.data, CD_SHAPE_KEYINDEX);
-                       if (keyi) {
-                               if (((index = *keyi) != ORIGINDEX_NONE) && (index < ototvert)) {
-                                       vertMap[index] = eve;
-                               }
-                       }
-                       else {
-                               if (i < ototvert) {
-                                       vertMap[i] = eve;
-                               }
+       if (cd_shape_keyindex_offset != -1) {
+               BM_ITER_MESH_INDEX (eve, &iter, bm, BM_VERTS_OF_MESH, i) {
+                       const int keyi = BM_ELEM_CD_GET_INT(eve, cd_shape_keyindex_offset);
+                       if ((keyi != ORIGINDEX_NONE) && (keyi < ototvert)) {
+                               vertMap[keyi] = eve;
                        }
-                       i++;
                }
        }
        else {
-               BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) {
+               BM_ITER_MESH_INDEX (eve, &iter, bm, BM_VERTS_OF_MESH, i) {
                        if (i < ototvert) {
                                vertMap[i] = eve;
                        }
                        else {
                                break;
                        }
-                       i++;
                }
        }
 
@@ -825,6 +813,8 @@ void BM_mesh_bm_to_me(BMesh *bm, Mesh *me, bool do_tessface)
        /* see comment below, this logic is in twice */
 
        if (me->key) {
+               const int cd_shape_keyindex_offset = CustomData_get_offset(&bm->vdata, CD_SHAPE_KEYINDEX);
+
                KeyBlock *currkey;
                KeyBlock *actkey = BLI_findlink(&me->key->block, bm->shapenr - 1);
 
@@ -868,16 +858,17 @@ void BM_mesh_bm_to_me(BMesh *bm, Mesh *me, bool do_tessface)
                                }
                        }
 
-                       if (act_is_basis) { /* active key is a base */
+                       /* active key is a base */
+                       if (act_is_basis && (cd_shape_keyindex_offset != -1)) {
                                float (*fp)[3] = actkey->data;
-                               int *keyi;
 
                                ofs = MEM_callocN(sizeof(float) * 3 * bm->totvert,  "currkey->data");
                                mvert = me->mvert;
                                BM_ITER_MESH_INDEX (eve, &iter, bm, BM_VERTS_OF_MESH, i) {
-                                       keyi = CustomData_bmesh_get(&bm->vdata, eve->head.data, CD_SHAPE_KEYINDEX);
-                                       if (keyi && *keyi != ORIGINDEX_NONE) {
-                                               sub_v3_v3v3(ofs[i], mvert->co, fp[*keyi]);
+                                       const int keyi = BM_ELEM_CD_GET_INT(eve, cd_shape_keyindex_offset);
+
+                                       if (keyi != ORIGINDEX_NONE) {
+                                               sub_v3_v3v3(ofs[i], mvert->co, fp[keyi]);
                                        }
                                        else {
                                                /* if there are new vertices in the mesh, we can't propagate the offset
@@ -894,12 +885,14 @@ void BM_mesh_bm_to_me(BMesh *bm, Mesh *me, bool do_tessface)
                }
 
                for (currkey = me->key->block.first; currkey; currkey = currkey->next) {
-                       int apply_offset = (ofs && (currkey != actkey) && (bm->shapenr - 1 == currkey->relative));
-                       int *keyi;
+                       const bool apply_offset = (ofs && (currkey != actkey) && (bm->shapenr - 1 == currkey->relative));
+                       int cd_shape_offset;
+                       int keyi;
                        float (*ofs_pt)[3] = ofs;
-                       float *newkey, *oldkey, *fp;
+                       float *newkey, (*oldkey)[3], *fp;
 
                        j = bm_to_mesh_shape_layer_index_from_kb(bm, currkey);
+                       cd_shape_offset = CustomData_get_n_offset(&bm->vdata, CD_SHAPEKEY, j);
 
 
                        fp = newkey = MEM_callocN(me->key->elemsize * bm->totvert,  "currkey->data");
@@ -912,26 +905,29 @@ void BM_mesh_bm_to_me(BMesh *bm, Mesh *me, bool do_tessface)
                                        copy_v3_v3(fp, eve->co);
 
                                        if (actkey != me->key->refkey) { /* important see bug [#30771] */
-                                               if (oldverts) {
-                                                       keyi = CustomData_bmesh_get(&bm->vdata, eve->head.data, CD_SHAPE_KEYINDEX);
-                                                       if (*keyi != ORIGINDEX_NONE && *keyi < currkey->totelem) { /* valid old vertex */
-                                                               copy_v3_v3(mvert->co, oldverts[*keyi].co);
+                                               if (cd_shape_keyindex_offset != -1) {
+                                                       if (oldverts) {
+                                                               keyi = BM_ELEM_CD_GET_INT(eve, cd_shape_keyindex_offset);
+                                                               if (keyi != ORIGINDEX_NONE && keyi < currkey->totelem) { /* valid old vertex */
+                                                                       copy_v3_v3(mvert->co, oldverts[keyi].co);
+                                                               }
                                                        }
                                                }
                                        }
                                }
                                else if (j != -1) {
                                        /* in most cases this runs */
-                                       copy_v3_v3(fp, CustomData_bmesh_get_n(&bm->vdata, eve->head.data, CD_SHAPEKEY, j));
+                                       copy_v3_v3(fp, BM_ELEM_CD_GET_VOID_P(eve, cd_shape_offset));
                                }
-                               else if (oldkey &&
-                                        (keyi = CustomData_bmesh_get(&bm->vdata, eve->head.data, CD_SHAPE_KEYINDEX)) &&
-                                        (*keyi != ORIGINDEX_NONE && *keyi < currkey->totelem))
+                               else if ((oldkey != NULL) &&
+                                        (cd_shape_keyindex_offset != -1) &&
+                                        ((keyi = BM_ELEM_CD_GET_INT(eve, cd_shape_keyindex_offset)) != ORIGINDEX_NONE) &&
+                                        (keyi < currkey->totelem))
                                {
                                        /* old method of reconstructing keys via vertice's original key indices,
                                         * currently used if the new method above fails (which is theoretically
                                         * possible in certain cases of undo) */
-                                       copy_v3_v3(fp, &oldkey[3 * (*keyi)]);
+                                       copy_v3_v3(fp, oldkey[keyi]);
                                }
                                else {
                                        /* fail! fill in with dummy value */