[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, &params);
 	
 	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, &params);
+
 	/* go through and split edges */
 	BMO_ITER (e, &siter, op->slots_in, "edges", BM_EDGE) {
 		bm_subdivide_multicut(bm, e, &params, 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