optimize customdata lookups for subdivision.
This commit is contained in:
@@ -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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user