[Bf-blender-cvs] [a6082a1] cycles-ptex-49: Improve performance of mesh iteration in ptex_pack_loops

Nicholas Bishop noreply at git.blender.org
Sun Feb 8 17:46:55 CET 2015


Commit: a6082a1652e928f006e8e5de738f7e36ca71fa26
Author: Nicholas Bishop
Date:   Sun Feb 8 17:24:40 2015 +0100
Branches: cycles-ptex-49
https://developer.blender.org/rBa6082a1652e928f006e8e5de738f7e36ca71fa26

Improve performance of mesh iteration in ptex_pack_loops

===================================================================

M	source/blender/blenkernel/intern/bke_ptex.c

===================================================================

diff --git a/source/blender/blenkernel/intern/bke_ptex.c b/source/blender/blenkernel/intern/bke_ptex.c
index 6c80d3c..058345f 100644
--- a/source/blender/blenkernel/intern/bke_ptex.c
+++ b/source/blender/blenkernel/intern/bke_ptex.c
@@ -316,13 +316,92 @@ static void bpx_rect_from_im_ptex_region(BPXRect *dst,
 	dst->yend = src->y + src->height;
 }
 
-static void ptex_adj_edge(int *adj_loop,
+/* Constants */
+enum {
+	BKE_PTEX_NO_ADJ_POLY = -1,
+
+	/* Filtering expects edges to have one or two adjacent polys */
+	BKE_PTEX_MAX_ADJ_POLYS = 2
+};
+
+typedef struct {
+	int polys[BKE_PTEX_MAX_ADJ_POLYS];
+} BKEPtexEdgeAdj;
+
+static BKEPtexEdgeAdj *bke_ptex_edge_adj_alloc(const Mesh *me)
+{
+	BKEPtexEdgeAdj *adj;
+	int edge_index;
+
+	adj = MEM_mallocN(sizeof(*adj) * me->totedge, "BKEPtexEdgeAdj");
+	for (edge_index = 0; edge_index < me->totedge; edge_index++) {
+		int i;
+		for (i = 0; i < BKE_PTEX_MAX_ADJ_POLYS; i++) {
+			adj[edge_index].polys[i] = BKE_PTEX_NO_ADJ_POLY;
+		}
+	}
+
+	return adj;
+}
+
+/* TODO(nicholasbishop): code like this probably already exists
+ * somewhere? */
+static BKEPtexEdgeAdj *bke_ptex_edge_adj_init(const Mesh *me)
+{
+	BKEPtexEdgeAdj *adj;
+	int poly_index;
+
+	adj = bke_ptex_edge_adj_alloc(me);
+	if (!adj) {
+		return NULL;
+	}
+
+	for (poly_index = 0; poly_index < me->totpoly; poly_index++) {
+		const MPoly *p = &me->mpoly[poly_index];
+		int i;
+		for (i = 0; i < p->totloop; i++) {
+			const int li = p->loopstart + i;
+			const MLoop *l = &me->mloop[li];
+			const int ei = l->e;
+			int j;
+
+			BLI_assert(ei >= 0 && ei < me->totedge);
+			for (j = 0; j < BKE_PTEX_MAX_ADJ_POLYS; j++) {
+				if (adj[ei].polys[j] == BKE_PTEX_NO_ADJ_POLY) {
+					adj[ei].polys[j] = poly_index;
+					break;
+				}
+			}
+		}
+	}
+
+	return adj;
+}
+
+static int bke_ptex_edge_adj_other_poly(const BKEPtexEdgeAdj *edge_adj,
+										const int poly_index)
+{
+	if (edge_adj) {
+		int i;
+		for (i = 0; i < BKE_PTEX_MAX_ADJ_POLYS; i++) {
+			if (edge_adj->polys[i] == poly_index) {
+				return edge_adj->polys[BKE_PTEX_MAX_ADJ_POLYS - i - 1];
+			}
+		}
+	}
+	return BKE_PTEX_NO_ADJ_POLY;
+}
+
+static void ptex_adj_edge(const BKEPtexEdgeAdj *adj,
+						  int *adj_loop,
 						  BPXEdge *adj_edge,
 						  const Mesh *me,
-						  const MPoly *p1,
+						  const int poly_index1,
 						  const int loop_offset,
 						  const BPXSide loop_side)
 {
+	const MPoly *p1 = &me->mpoly[poly_index1];
+
 	BLI_assert(adj_loop);
 	BLI_assert(adj_edge);
 	BLI_assert(loop_offset >= 0 && loop_offset < p1->totloop);
@@ -344,8 +423,8 @@ static void ptex_adj_edge(int *adj_loop,
 	}
 	else {
 		const MLoop *l1;
+		int poly_index2;
 		int e1_offset;
-		int i;
 
 		if (loop_side == BPX_SIDE_TOP) {
 			e1_offset = loop_offset;
@@ -354,19 +433,18 @@ static void ptex_adj_edge(int *adj_loop,
 			e1_offset = (p1->totloop + loop_offset - 1) % p1->totloop;
 		}
 		l1 = &me->mloop[p1->loopstart + e1_offset];
-		
-		/* TODO(nicholasbishop: use proper lookup here to avoid long
-		 * iteration */
-		for (i = 0; i < me->totpoly; i++) {
-			const MPoly *p2 = &me->mpoly[i];
-			int j;
-
-			if (p1 == p2) {
-				continue;
-			}
 
-			for (j = 0; j < p2->totloop; j++) {
-				const int li2 = p2->loopstart + j;
+		poly_index2 = bke_ptex_edge_adj_other_poly(&adj[l1->e], poly_index1);
+		if (poly_index2 == BKE_PTEX_NO_ADJ_POLY) {
+			/* Reuse self */
+			(*adj_loop) = p1->loopstart + loop_offset;
+			adj_edge->side = loop_side;
+		}
+		else {
+			MPoly *p2 = &me->mpoly[poly_index2];
+			int i;
+			for (i = 0; i < p2->totloop; i++) {
+				const int li2 = p2->loopstart + i;
 				const MLoop *l2 = &me->mloop[li2];
 				if (l1->e == l2->e) {
 					/* TODO(nicholasbishop): probably making an
@@ -376,11 +454,11 @@ static void ptex_adj_edge(int *adj_loop,
 					/* Next loop */
 					
 					if (loop_side == BPX_SIDE_TOP) {
-						(*adj_loop) = p2->loopstart + ((j + 1) % p2->totloop);
+						(*adj_loop) = p2->loopstart + ((i + 1) % p2->totloop);
 						adj_edge->side = BPX_SIDE_RIGHT;
 					}
 					else {
-						(*adj_loop) = p2->loopstart + j;
+						(*adj_loop) = p2->loopstart + i;
 						adj_edge->side = BPX_SIDE_TOP;
 					}
 					return;
@@ -397,8 +475,13 @@ static void ptex_adj_edge(int *adj_loop,
 static void ptex_filter_borders_update(ImBuf *ibuf, const Mesh *me)
 {
 	BPXImageBuf *bpx_buf = IMB_imbuf_as_bpx_image_buf(ibuf);
+	BKEPtexEdgeAdj *adj = bke_ptex_edge_adj_init(me);
 	int i;
 
+	if (!adj) {
+		return;
+	}
+
 	BLI_assert(bpx_buf);
 
 	for (i = 0; i < me->totpoly; i++) {
@@ -419,7 +502,7 @@ static void ptex_filter_borders_update(ImBuf *ibuf, const Mesh *me)
 			for (k = 0; k < 4; k++) {
 				int adj_loop = -1;
 
-				ptex_adj_edge(&adj_loop, &adj_edge[k], me, p, j, k);
+				ptex_adj_edge(adj, &adj_loop, &adj_edge[k], me, i, j, k);
 				BLI_assert(adj_loop >= 0);
 
 				bpx_rect_from_im_ptex_region(&adj_rect[k],
@@ -434,6 +517,7 @@ static void ptex_filter_borders_update(ImBuf *ibuf, const Mesh *me)
 		}
 	}
 
+	MEM_freeN(adj);
 	BPX_image_buf_free(bpx_buf);
 }




More information about the Bf-blender-cvs mailing list