[Bf-blender-cvs] [2f04e2d] cycles-ptex-49: Start using BPXRect for IMB ptex regions

Nicholas Bishop noreply at git.blender.org
Thu Feb 12 14:16:46 CET 2015


Commit: 2f04e2d2a3f291cf2ed1832ea614755cee2a046a
Author: Nicholas Bishop
Date:   Thu Feb 12 00:42:11 2015 +0100
Branches: cycles-ptex-49
https://developer.blender.org/rB2f04e2d2a3f291cf2ed1832ea614755cee2a046a

Start using BPXRect for IMB ptex regions

Filter borders can now be calculated entirely with BPXRects and a
packed image. This should make it easier to unify some code paths and
also make partial updates while painting much simpler to implement.

TODO: fix BPX include in IMB_imbuf_types.h

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

M	extern/ptex/BPX_ptex.h
M	extern/ptex/bpx_c_api.cpp
M	source/blender/blenkernel/intern/bke_ptex.c
M	source/blender/editors/sculpt_paint/paint_image_proj.c
M	source/blender/gpu/intern/gpu_extensions.c
M	source/blender/imbuf/IMB_imbuf_types.h
M	source/blender/imbuf/intern/imb_ptex.c

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

diff --git a/extern/ptex/BPX_ptex.h b/extern/ptex/BPX_ptex.h
index 1dd10ba..cd72041 100644
--- a/extern/ptex/BPX_ptex.h
+++ b/extern/ptex/BPX_ptex.h
@@ -88,10 +88,9 @@ bool BPX_image_input_seek_subimage(BPXImageInput *input, const int subimage,
 
 bool BPX_image_input_read(BPXImageBuf *bpx_dst, BPXImageInput *bpx_src);
 
-bool BPX_rect_borders_update(BPXImageBuf *bpx_buf,
-							 const BPXRect *dst_rect,
-							 const BPXRect src_rect[BPX_RECT_NUM_SIDES],
-							 const BPXEdge src_edge[BPX_RECT_NUM_SIDES]);
+/* TODO, stride here is not such a nice API */
+bool BPX_rect_borders_update(BPXImageBuf *bpx_buf, const BPXRect *dst_rect,
+							 const void *rects, const int rects_stride);
 
 bool BPX_image_buf_quad_split(BPXImageBuf *dst[4], const BPXImageBuf *src);
 
@@ -116,7 +115,7 @@ BPXImageBuf *BPX_image_buf_ptex_pack(BPXImageInput *bpx_src,
 struct BPXPackedLayout;
 struct BPXPackedLayout *BPX_packed_layout_new(int count);
 void BPX_packed_layout_add(struct BPXPackedLayout *layout,
-						   int u_res, int v_res, int id);
+						   const BPXRect *rect);
 void BPX_packed_layout_finalize(struct BPXPackedLayout *layout);
 int BPX_packed_layout_width(const struct BPXPackedLayout *layout);
 int BPX_packed_layout_height(const struct BPXPackedLayout *layout);
diff --git a/extern/ptex/bpx_c_api.cpp b/extern/ptex/bpx_c_api.cpp
index 6356c8b..b891a53 100644
--- a/extern/ptex/bpx_c_api.cpp
+++ b/extern/ptex/bpx_c_api.cpp
@@ -340,35 +340,53 @@ static bool bpx_corner_average(ImageBuf &buf, const int dst_co[2],
 	return true;
 }
 
-bool BPX_rect_borders_update(BPXImageBuf *bpx_buf,
-							 const BPXRect *dst_rect,
-							 const BPXRect src_rect[BPX_RECT_NUM_SIDES],
-							 const BPXEdge src_edge[BPX_RECT_NUM_SIDES])
+bool BPX_rect_borders_update(BPXImageBuf *bpx_buf, const BPXRect *dst_rect,
+							 const void *rects_v, const int rects_stride)
 {
-	if (!bpx_buf || !dst_rect) {
+	if (!bpx_buf || !rects_v) {
 		return false;
 	}
 
 	ImageBuf &buf = *bpx_image_buf_to_oiio_image_buf(bpx_buf);
 	const ROI dst_roi = bpx_rect_to_oiio_roi(*dst_rect);
 
+	const unsigned char *rects_uc = static_cast<const unsigned char*>(rects_v);
+
 	// Sample adjacent regions to create filter edges
 	for (int i = 0; i < BPX_RECT_NUM_SIDES; i++) {
-		const ROI src_roi = bpx_rect_to_oiio_roi(src_rect[i]);
 		const BPXRectSide dst_side = static_cast<BPXRectSide>(i);
 		const bool dst_reverse = false;
 		const BPXEdge dst_edge = {dst_side, dst_reverse};
-		bpx_create_border(buf, dst_roi, dst_edge, src_roi, src_edge[i]);
+
+		const BPXRectSideAdj &adj = dst_rect->adj[i];
+		const BPXRect *src_rect;
+		BPXEdge src_edge;
+		if (adj.index == BPX_RECT_SIDE_ADJ_NONE) {
+			// Re-use own border, effectively clamping the filter
+			src_rect = dst_rect;
+			src_edge.side = dst_side;
+			src_edge.reverse = false;
+
+		}
+		else {
+			const int offset = adj.index * rects_stride;
+			src_rect = reinterpret_cast<const BPXRect *>(rects_uc + offset);
+			src_edge.side = adj.side;
+			src_edge.reverse = true;
+		}
+			
+		const ROI src_roi = bpx_rect_to_oiio_roi(*src_rect);
+		bpx_create_border(buf, dst_roi, dst_edge, src_roi, src_edge);
 	}
 
-	// Average adjacent borders to fill in corners (not really correct
-	// but I'm guessing the difference won't be visible, and anyway
-	// this is only for bilinear filtering)
+	// Average adjacent borders to fill in
+	// corners. TODO(nicholasbishop): need to improve this, it is
+	// noticable after all
 	const int dst_co[BPX_RECT_NUM_SIDES][2] = {
-		{dst_rect->xbegin - 1, dst_rect->ybegin - 1},
-		{dst_rect->xend      , dst_rect->ybegin - 1},
-		{dst_rect->xend      , dst_rect->yend      },
-		{dst_rect->xbegin - 1, dst_rect->yend      }
+		{dst_roi.xbegin - 1, dst_roi.ybegin - 1},
+		{dst_roi.xend      , dst_roi.ybegin - 1},
+		{dst_roi.xend      , dst_roi.yend      },
+		{dst_roi.xbegin - 1, dst_roi.yend      }
 	};
 	const int src_co[BPX_RECT_NUM_SIDES][CORNER_NUM_SOURCES][2] = {
 		{{dst_co[0][0] + 1, dst_co[0][1]    },
@@ -812,10 +830,10 @@ static int bpx_mesh_face_find_edge(const BPXPtexMesh &mesh,
 }
 
 // TODO(nicholasbishop): deduplicate with bke_ptex.c
-static bool bpx_ptex_adj_layout_item(int &adj_layout_item, BPXEdge &adj_edge,
-									 const BPXPtexMesh &mesh,
-									 const int f1, const int fv1,
-									 const BPXRectSide &side1)
+static bool bpx_ptex_adj_rect(const BPXPtexMesh &mesh,
+							  const int f1, const int fv1,
+							  const BPXRectSide &side1,
+							  BPXRectSideAdj &r_adj)
 {
 	const int nsides1 = mesh.faces.at(f1).len;
 	const int region1 = mesh.faces.at(f1).vert_index;
@@ -824,27 +842,15 @@ static bool bpx_ptex_adj_layout_item(int &adj_layout_item, BPXEdge &adj_edge,
 	const int vn = mesh.face_vert_indices[region1 + (fv1 + 1) % nsides1];
 	const int vp = mesh.face_vert_indices[region1 + (nsides1 + fv1 - 1) % nsides1];
 
-	// TODO
-	//if (side1 == BPX_RECT_SIDE_TOP || side1 == BPX_RECT_SIDE_RIGHT) {
-	if (0) {
-		// Reuse self
-		adj_layout_item = region1 + fv1;
-		adj_edge.side = side1;
-		return true;
-	}
-
-	// TODO?
-	adj_edge.reverse = true;
-
 	if (side1 == BPX_RECT_SIDE_BOTTOM) {
 		// Previous loop
-		adj_layout_item = region1 + ((nsides1 + fv1 - 1) % nsides1);
-		adj_edge.side = BPX_RECT_SIDE_LEFT;
+		r_adj.index = region1 + ((nsides1 + fv1 - 1) % nsides1);
+		r_adj.side = BPX_RECT_SIDE_LEFT;
 	}
 	else if (side1 == BPX_RECT_SIDE_LEFT) {
 		// Next loop
-		adj_layout_item = region1 + ((fv1 + 1) % nsides1);
-		adj_edge.side = BPX_RECT_SIDE_BOTTOM;
+		r_adj.index = region1 + ((fv1 + 1) % nsides1);
+		r_adj.side = BPX_RECT_SIDE_BOTTOM;
 	}
 	else {
 		const int v2 = (side1 == BPX_RECT_SIDE_TOP) ? vn : vp;
@@ -858,9 +864,7 @@ static bool bpx_ptex_adj_layout_item(int &adj_layout_item, BPXEdge &adj_edge,
 		// Map to other face
 		const int f2 = bpx_mesh_other_face(*edge, f1);
 		if (f2 == BPX_ADJ_NONE) {
-			// Reuse self
-			adj_layout_item = region1 + fv1;
-			adj_edge.side = side1;
+			r_adj.index = BPX_RECT_SIDE_ADJ_NONE;
 			return true;
 		}
 
@@ -870,19 +874,17 @@ static bool bpx_ptex_adj_layout_item(int &adj_layout_item, BPXEdge &adj_edge,
 		// Find same edge in other face
 		const int fv2 = bpx_mesh_face_find_edge(mesh, f2, *edge);
 		if (fv2 == BPX_ADJ_NONE) {
-			// Reuse self
-			adj_layout_item = region1 + fv1;
-			adj_edge.side = side1;
+			r_adj.index = BPX_RECT_SIDE_ADJ_NONE;
 			return true;
 		}
 
 		if (side1 == BPX_RECT_SIDE_TOP) {
-			adj_layout_item = region2 + ((fv2 + 1) % nsides2);
-			adj_edge.side = BPX_RECT_SIDE_RIGHT;
+			r_adj.index = region2 + ((fv2 + 1) % nsides2);
+			r_adj.side = BPX_RECT_SIDE_RIGHT;
 		}
 		else if (side1 == BPX_RECT_SIDE_RIGHT) {
-			adj_layout_item = region2 + fv2;
-			adj_edge.side = BPX_RECT_SIDE_TOP;
+			r_adj.index = region2 + fv2;
+			r_adj.side = BPX_RECT_SIDE_TOP;
 		}
 		else {
 			return false;
@@ -925,65 +927,30 @@ static bool bpx_ptex_mesh_init(BPXPtexMesh &mesh, ImageInput &src)
 	return true;
 }
 
-static bool bpx_ptex_filter_borders_update_from_file(ImageBuf &dst,
-													 ImageInput &src,
-													 BPXPackedLayout &layout)
+int BPX_packed_layout_num_regions(const BPXPackedLayout *layout)
 {
-	BPXPtexMesh mesh;
-	if (!bpx_ptex_mesh_init(mesh, src)) {
-		return false;
-	}
-
-	const BPXPackedLayout::Items &items = layout.get_items();
-
-	const int num_faces = mesh.faces.size();
-	for (int face_index = 0; face_index < num_faces; face_index++) {
-		const BPXPtexMeshFace &face = mesh.faces[face_index];
-		for (int fv = 0; fv < face.len; fv++) {
-			const int cur_layout_item = face.vert_index + fv;
-			if (cur_layout_item >= items.size()) {
-				return false;
-			}
-
-			const BPXPackedLayout::Item &item = items[cur_layout_item];
-			const BPXRect dst_rect = item.rect;
-
-			// TODO
-			BPXRect adj_rect[4];
-			BPXEdge adj_edge[4];
-
-			for (int side = 0; side < BPX_RECT_NUM_SIDES; side++) {
-				const BPXRectSide bpx_side = static_cast<BPXRectSide>(side);
-				int adj_layout_item = BPX_ADJ_NONE;
+	return layout->get_items().size();
+}
 
-				bpx_ptex_adj_layout_item(adj_layout_item, adj_edge[side],
-										 mesh, face_index, fv, bpx_side);
+static bool bpx_ptex_filter_borders_update(ImageBuf &buf,
+										   const BPXPackedLayout &layout)
+{
+	BPXImageBuf *bpx_buf = bpx_image_buf_from_oiio_image_buf(&buf);
 
-				if (adj_layout_item == BPX_ADJ_NONE ||
-					adj_layout_item >= items.size())
-				{
-					return false;
-				}
-				const BPXPackedLayout::Item &adj_item = items[adj_layout_item];
-				adj_rect[side] = adj_item.rect;
-			}
+	const BPXPackedLayout::Items &items = layout.get_items();
+	const void *rects = items.data();
+	const int rects_stride = sizeof(BPXPackedLayout::Item);
 
-			if (!BPX_rect_borders_update(bpx_image_buf_from_oiio_image_buf(&dst),
-										 &dst_rect, adj_rect, adj_edge))
-			{
-				return false;
-			}
+	const int num_rects = items.size();
+	for (int i = 0; i < num_rects; i++) {
+		if (!BPX_rect_borders_update(bpx_buf, &items[i].rect,
+									 rects, rects_stride)) {
+			return false;
 		}
 	}
-
 	return true;
 }
 
-int BPX_packed_layout_num_regions(const BPXPackedLayout *layout)
-{
-	return layout->get_items().size();
-}
-
 static bool bpx_image_buf_ptex_layout(BPXPackedLayout &layout, ImageInput &in,
 									  const BPXPtexMesh &mesh)
 {
@@ -1003,33 +970,39 @@ static bool bpx_image_buf_ptex_layout(BPXPackedLayout &layout, ImageInput &in,
 			}
 
 			// Width and height should already be powers of two
-			int w = spec.width;
-			int h = spec.height;
+			BPXRect rect;
+			rect.xbegin = 0;
+			rect.ybegin = 0;
+			rect.xend = spec.width;
+			rect.yend = spec.height;
 
+			// Halve/rotate subquads
 			if (is_quad) {
-				const int hw = std::max(1, w / 2);
-				const int hh = std::max(1, h / 2);
+				const int hw = std::max(1, spec.width  / 2);
+				const int hh = std::max(1, spec.height / 2);
 
 				if (fv % 2 == 0) {
-					w = hw;
-					h = hh;
+					rect.xend = hw;
+					rect.yend = hh;
 				}
 				else {
-					w = hh;
-					h = hw;
+					rect.xend = hh;
+					rect.yend = hw;
 				}
 			}
 			else {
 				subimage++;
 			}
 
-			// TODO(nicholasbishop): will add adjacency data here
-			BPXRect r;
-			r.xbegin = 0;
-			r.ybegin = 0;
-			r.xend = w;
-			r.yend = h;
-			layout.add_rect(r);
+			// Add

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list