[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [57334] trunk/blender/source/blender/bmesh /operators/bmo_subdivide.c: optimize customdata lookups for subdivision.
Campbell Barton
ideasman42 at gmail.com
Mon Jun 10 07:18:45 CEST 2013
Revision: 57334
http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=57334
Author: campbellbarton
Date: 2013-06-10 05:18:45 +0000 (Mon, 10 Jun 2013)
Log Message:
-----------
optimize customdata lookups for subdivision.
Modified Paths:
--------------
trunk/blender/source/blender/bmesh/operators/bmo_subdivide.c
Modified: trunk/blender/source/blender/bmesh/operators/bmo_subdivide.c
===================================================================
--- trunk/blender/source/blender/bmesh/operators/bmo_subdivide.c 2013-06-10 05:10:58 UTC (rev 57333)
+++ trunk/blender/source/blender/bmesh/operators/bmo_subdivide.c 2013-06-10 05:18:45 UTC (rev 57334)
@@ -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 @@
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 @@
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 @@
* 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 @@
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 @@
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 @@
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 @@
/* 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 @@
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 @@
/* 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 @@
/* 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,17 +1231,15 @@
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) {
bm_subdivide_multicut(bm, e, ¶ms, e->v1, e->v2);
@@ -1229,5 +1247,5 @@
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);
}
More information about the Bf-blender-cvs
mailing list