diff options
Diffstat (limited to 'source/blender/bmesh')
-rw-r--r-- | source/blender/bmesh/operators/bmo_subdivide.c | 70 |
1 files changed, 44 insertions, 26 deletions
diff --git a/source/blender/bmesh/operators/bmo_subdivide.c b/source/blender/bmesh/operators/bmo_subdivide.c index 8e30da60f60..be0b7eed971 100644 --- a/source/blender/bmesh/operators/bmo_subdivide.c +++ b/source/blender/bmesh/operators/bmo_subdivide.c @@ -40,7 +40,6 @@ #include "intern/bmesh_private.h" #include "intern/bmesh_operators_private.h" - typedef struct SubDParams { int numcuts; float smooth; @@ -53,13 +52,33 @@ typedef struct SubDParams { bool use_sphere; bool use_fractal; int seed; - int origkey; /* shapekey holding displaced vertex coordinates for current geometry */ BMOperator *op; BMOpSlot *slot_edge_percents; /* BMO_slot_get(params->op->slots_in, "edge_percents"); */ BMOpSlot *slot_custom_patterns; /* BMO_slot_get(params->op->slots_in, "custom_patterns"); */ float fractal_ofs[3]; + + /* rumtime storage for shape key */ + struct { + int cd_vert_shape_offset; + int cd_vert_shape_offset_tmp; + int totlayer; + + /* shapekey holding displaced vertex coordinates for current geometry */ + int tmpkey; + } shape_info; + } SubDParams; +static void bmo_subd_init_shape_info(BMesh *bm, SubDParams *params) +{ + const int skey = CustomData_number_of_layers(&bm->vdata, CD_SHAPEKEY) - 1; + params->shape_info.tmpkey = skey; + params->shape_info.cd_vert_shape_offset = CustomData_get_offset(&bm->vdata, CD_SHAPEKEY); + params->shape_info.cd_vert_shape_offset_tmp = CustomData_get_n_offset(&bm->vdata, CD_SHAPEKEY, skey); + params->shape_info.totlayer = CustomData_number_of_layers(&bm->vdata, CD_SHAPEKEY); + +} + typedef void (*subd_pattern_fill_fp)(BMesh *bm, BMFace *face, BMVert **verts, const SubDParams *params); @@ -142,16 +161,15 @@ static BMEdge *connect_smallest_face(BMesh *bm, BMVert *v1, BMVert *v2, BMFace * return NULL; } /* calculates offset for co, based on fractal, sphere or smooth settings */ -static void alter_co(BMesh *bm, BMVert *v, BMEdge *UNUSED(origed), const SubDParams *params, float perc, +static void alter_co(BMVert *v, BMEdge *UNUSED(origed), const SubDParams *params, float perc, BMVert *vsta, BMVert *vend) { float tvec[3], prev_co[3], fac; - float *co = NULL; - int i, totlayer = CustomData_number_of_layers(&bm->vdata, CD_SHAPEKEY); + float *co = BM_ELEM_CD_GET_VOID_P(v, params->shape_info.cd_vert_shape_offset_tmp); + int i; BM_vert_normal_update_all(v); - co = CustomData_bmesh_get_n(&bm->vdata, v->head.data, CD_SHAPEKEY, params->origkey); copy_v3_v3(co, v->co); copy_v3_v3(prev_co, co); @@ -219,13 +237,15 @@ static void alter_co(BMesh *bm, BMVert *v, BMEdge *UNUSED(origed), const SubDPar * for now its ok to simply apply the difference IMHO - campbell */ sub_v3_v3v3(tvec, prev_co, co); - for (i = 0; i < totlayer; i++) { - if (params->origkey != i) { - co = CustomData_bmesh_get_n(&bm->vdata, v->head.data, CD_SHAPEKEY, i); - sub_v3_v3(co, tvec); + if (params->shape_info.totlayer > 1) { + /* skip the last layer since its the temp */ + i = params->shape_info.totlayer - 1; + co = BM_ELEM_CD_GET_VOID_P(v, params->shape_info.cd_vert_shape_offset); + while (i--) { + BLI_assert(co != BM_ELEM_CD_GET_VOID_P(v, params->shape_info.cd_vert_shape_offset_tmp)); + sub_v3_v3(co += 3, tvec); } } - } /* assumes in the edge is the correct interpolated vertices already */ @@ -243,7 +263,7 @@ static BMVert *bm_subdivide_edge_addvert(BMesh *bm, BMEdge *edge, BMEdge *oedge, BMO_elem_flag_enable(bm, ev, ELE_INNER); /* offset for smooth or sphere or fractal */ - alter_co(bm, ev, oedge, params, percent2, vsta, vend); + alter_co(ev, oedge, params, percent2, vsta, vend); #if 0 //BMESH_TODO /* clip if needed by mirror modifier */ @@ -313,8 +333,8 @@ static void bm_subdivide_multicut(BMesh *bm, BMEdge *edge, const SubDParams *par if (v->e && v->e->l) BM_CHECK_ELEMENT(v->e->l->f); } - alter_co(bm, v1, &e_tmp, params, 0, &v1_tmp, &v2_tmp); - alter_co(bm, v2, &e_tmp, params, 1.0, &v1_tmp, &v2_tmp); + alter_co(v1, &e_tmp, params, 0, &v1_tmp, &v2_tmp); + alter_co(v2, &e_tmp, params, 1.0, &v1_tmp, &v2_tmp); } /* note: the patterns are rotated as necessary to @@ -764,7 +784,7 @@ void bmo_subdivide_edges_exec(BMesh *bm, BMOperator *op) BLI_array_declare(verts); float smooth, fractal, along_normal; bool use_sphere, use_single_edge, use_grid_fill, use_only_quads; - int cornertype, skey, seed, i, j, matched, a, b, numcuts, totesel, smooth_falloff; + int cornertype, seed, i, j, matched, a, b, numcuts, totesel, smooth_falloff; BMO_slot_buffer_flag_enable(bm, op->slots_in, "edges", BM_EDGE, SUBD_SPLIT); @@ -815,10 +835,11 @@ void bmo_subdivide_edges_exec(BMesh *bm, BMOperator *op) /* add a temporary shapekey layer to store displacements on current geometry */ BM_data_layer_add(bm, &bm->vdata, CD_SHAPEKEY); - skey = CustomData_number_of_layers(&bm->vdata, CD_SHAPEKEY) - 1; + + bmo_subd_init_shape_info(bm, ¶ms); BM_ITER_MESH (v, &viter, bm, BM_VERTS_OF_MESH) { - float *co = CustomData_bmesh_get_n(&bm->vdata, v->head.data, CD_SHAPEKEY, skey); + float *co = BM_ELEM_CD_GET_VOID_P(v, params.shape_info.cd_vert_shape_offset_tmp); copy_v3_v3(co, v->co); } @@ -838,7 +859,6 @@ void bmo_subdivide_edges_exec(BMesh *bm, BMOperator *op) params.use_smooth_even = BMO_slot_get(op->slots_in, "use_smooth_even"); params.use_fractal = (fractal != 0.0f); params.use_sphere = use_sphere; - params.origkey = skey; if (params.use_fractal) { RNG *rng = BLI_rng_new_srandom(seed); @@ -987,7 +1007,7 @@ void bmo_subdivide_edges_exec(BMesh *bm, BMOperator *op) /* copy original-geometry displacements to current coordinates */ BM_ITER_MESH (v, &viter, bm, BM_VERTS_OF_MESH) { - float *co = CustomData_bmesh_get_n(&bm->vdata, v->head.data, CD_SHAPEKEY, skey); + float *co = BM_ELEM_CD_GET_VOID_P(v, params.shape_info.cd_vert_shape_offset_tmp); copy_v3_v3(v->co, co); } @@ -1132,11 +1152,11 @@ void bmo_subdivide_edges_exec(BMesh *bm, BMOperator *op) /* copy original-geometry displacements to current coordinates */ BM_ITER_MESH (v, &viter, bm, BM_VERTS_OF_MESH) { - float *co = CustomData_bmesh_get_n(&bm->vdata, v->head.data, CD_SHAPEKEY, skey); + float *co = BM_ELEM_CD_GET_VOID_P(v, params.shape_info.cd_vert_shape_offset_tmp); copy_v3_v3(v->co, co); } - BM_data_layer_free_n(bm, &bm->vdata, CD_SHAPEKEY, skey); + BM_data_layer_free_n(bm, &bm->vdata, CD_SHAPEKEY, params.shape_info.tmpkey); if (facedata) BLI_array_free(facedata); if (edges) BLI_array_free(edges); @@ -1211,16 +1231,14 @@ void bmo_bisect_edges_exec(BMesh *bm, BMOperator *op) BMOIter siter; BMEdge *e; SubDParams params = {0}; - int skey; params.numcuts = BMO_slot_int_get(op->slots_in, "cuts"); params.op = op; params.slot_edge_percents = BMO_slot_get(op->slots_in, "edge_percents"); BM_data_layer_add(bm, &bm->vdata, CD_SHAPEKEY); - skey = CustomData_number_of_layers(&bm->vdata, CD_SHAPEKEY) - 1; - - params.origkey = skey; + + bmo_subd_init_shape_info(bm, ¶ms); /* go through and split edges */ BMO_ITER (e, &siter, op->slots_in, "edges", BM_EDGE) { @@ -1229,5 +1247,5 @@ void bmo_bisect_edges_exec(BMesh *bm, BMOperator *op) BMO_slot_buffer_from_enabled_flag(bm, op, op->slots_out, "geom_split.out", BM_ALL_NOLOOP, ELE_SPLIT); - BM_data_layer_free_n(bm, &bm->vdata, CD_SHAPEKEY, skey); + BM_data_layer_free_n(bm, &bm->vdata, CD_SHAPEKEY, params.shape_info.tmpkey); } |