[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [48921] trunk/blender/source/blender/ blenkernel/intern/mask_rasterize.c: mask rasterizer - test if buckets overlap the face before adding the face into the bucket .
Campbell Barton
ideasman42 at gmail.com
Sat Jul 14 19:58:42 CEST 2012
Revision: 48921
http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=48921
Author: campbellbarton
Date: 2012-07-14 17:58:42 +0000 (Sat, 14 Jul 2012)
Log Message:
-----------
mask rasterizer - test if buckets overlap the face before adding the face into the bucket.
Modified Paths:
--------------
trunk/blender/source/blender/blenkernel/intern/mask_rasterize.c
Modified: trunk/blender/source/blender/blenkernel/intern/mask_rasterize.c
===================================================================
--- trunk/blender/source/blender/blenkernel/intern/mask_rasterize.c 2012-07-14 17:30:49 UTC (rev 48920)
+++ trunk/blender/source/blender/blenkernel/intern/mask_rasterize.c 2012-07-14 17:58:42 UTC (rev 48921)
@@ -217,28 +217,166 @@
}
}
+static int layer_bucket_isect_test(MaskRasterLayer *layer, unsigned int face_index,
+ const unsigned int bucket_x, const unsigned int bucket_y,
+ const float bucket_x_size, const float bucket_y_size)
+{
+ const float xmin = layer->bounds.xmin + (bucket_x_size * bucket_x);
+ const float ymin = layer->bounds.ymin + (bucket_y_size * bucket_y);
+ const float xmax = xmin + bucket_x_size;
+ const float ymax = ymin + bucket_y_size;
+ const float bucket_quad[4][2] = {{xmin, ymin},
+ {xmin, ymax},
+ {xmax, ymax},
+ {xmax, ymin}};
+
+ unsigned int *face = layer->face_array[face_index];
+ float (*cos)[3] = layer->face_coords;
+
+// float dummy_lambda;
+
+ if (face[3] == TRI_VERT) {
+ const float *v1 = cos[face[0]];
+ const float *v2 = cos[face[1]];
+ const float *v3 = cos[face[2]];
+
+ /* bucket corner in tri? */
+ if (isect_point_tri_v2(bucket_quad[0], v1, v2, v3) ||
+ isect_point_tri_v2(bucket_quad[1], v1, v2, v3) ||
+ isect_point_tri_v2(bucket_quad[2], v1, v2, v3) ||
+ isect_point_tri_v2(bucket_quad[3], v1, v2, v3))
+ {
+ return TRUE;
+ }
+
+ /* line intersect */
+#if 1
+ if (isect_line_line_v2(bucket_quad[0], bucket_quad[1], v1, v2) ||
+ isect_line_line_v2(bucket_quad[0], bucket_quad[1], v2, v3) ||
+ isect_line_line_v2(bucket_quad[0], bucket_quad[1], v3, v1) ||
+
+ isect_line_line_v2(bucket_quad[1], bucket_quad[2], v1, v2) ||
+ isect_line_line_v2(bucket_quad[1], bucket_quad[2], v2, v3) ||
+ isect_line_line_v2(bucket_quad[1], bucket_quad[2], v3, v1) ||
+
+ isect_line_line_v2(bucket_quad[2], bucket_quad[3], v1, v2) ||
+ isect_line_line_v2(bucket_quad[2], bucket_quad[3], v2, v3) ||
+ isect_line_line_v2(bucket_quad[2], bucket_quad[3], v3, v1) ||
+
+ isect_line_line_v2(bucket_quad[3], bucket_quad[0], v1, v2) ||
+ isect_line_line_v2(bucket_quad[3], bucket_quad[0], v2, v3) ||
+ isect_line_line_v2(bucket_quad[3], bucket_quad[0], v3, v1)
+
+ )
+ {
+ return TRUE;
+ }
+#else
+ /* line intersect */
+ if (isect_line_tri_v3(bucket_quad[0], bucket_quad[1], v1, v2, v3, &dummy_lambda, NULL) ||
+ isect_line_tri_v3(bucket_quad[1], bucket_quad[2], v1, v2, v3, &dummy_lambda, NULL) ||
+ isect_line_tri_v3(bucket_quad[2], bucket_quad[3], v1, v2, v3, &dummy_lambda, NULL) ||
+ isect_line_tri_v3(bucket_quad[3], bucket_quad[0], v1, v2, v3, &dummy_lambda, NULL))
+ {
+ return TRUE;
+ }
+
+#endif
+ return FALSE;
+ }
+ else {
+ const float *v1 = cos[face[0]];
+ const float *v2 = cos[face[1]];
+ const float *v3 = cos[face[2]];
+ const float *v4 = cos[face[3]];
+
+ /* bucket corner in tri? */
+ if (isect_point_tri_v2(bucket_quad[0], v1, v2, v3) ||
+ isect_point_tri_v2(bucket_quad[1], v1, v2, v3) ||
+ isect_point_tri_v2(bucket_quad[2], v1, v2, v3) ||
+ isect_point_tri_v2(bucket_quad[3], v1, v2, v3))
+ {
+ return TRUE;
+ }
+ else if (isect_point_tri_v2(bucket_quad[0], v1, v3, v4) ||
+ isect_point_tri_v2(bucket_quad[1], v1, v3, v4) ||
+ isect_point_tri_v2(bucket_quad[2], v1, v3, v4) ||
+ isect_point_tri_v2(bucket_quad[3], v1, v3, v4))
+ {
+ return TRUE;
+ }
+
+ /* line intersect */
+#if 1
+ if (isect_line_line_v2(bucket_quad[0], bucket_quad[1], v1, v2) ||
+ isect_line_line_v2(bucket_quad[0], bucket_quad[1], v2, v3) ||
+ isect_line_line_v2(bucket_quad[0], bucket_quad[1], v3, v4) ||
+ isect_line_line_v2(bucket_quad[0], bucket_quad[1], v4, v1) ||
+
+ isect_line_line_v2(bucket_quad[1], bucket_quad[2], v1, v2) ||
+ isect_line_line_v2(bucket_quad[1], bucket_quad[2], v2, v3) ||
+ isect_line_line_v2(bucket_quad[1], bucket_quad[2], v3, v4) ||
+ isect_line_line_v2(bucket_quad[1], bucket_quad[2], v4, v1) ||
+
+ isect_line_line_v2(bucket_quad[2], bucket_quad[3], v1, v2) ||
+ isect_line_line_v2(bucket_quad[2], bucket_quad[3], v2, v3) ||
+ isect_line_line_v2(bucket_quad[2], bucket_quad[3], v3, v4) ||
+ isect_line_line_v2(bucket_quad[2], bucket_quad[3], v4, v1) ||
+
+ isect_line_line_v2(bucket_quad[3], bucket_quad[0], v1, v2) ||
+ isect_line_line_v2(bucket_quad[3], bucket_quad[0], v2, v3) ||
+ isect_line_line_v2(bucket_quad[3], bucket_quad[0], v3, v4) ||
+ isect_line_line_v2(bucket_quad[3], bucket_quad[0], v4, v1)
+
+ )
+ {
+ return TRUE;
+ }
+#else
+ if (isect_line_tri_v3(bucket_quad[0], bucket_quad[1], v1, v2, v3, &dummy_lambda, NULL) ||
+ isect_line_tri_v3(bucket_quad[1], bucket_quad[2], v1, v2, v3, &dummy_lambda, NULL) ||
+ isect_line_tri_v3(bucket_quad[2], bucket_quad[3], v1, v2, v3, &dummy_lambda, NULL) ||
+ isect_line_tri_v3(bucket_quad[3], bucket_quad[0], v1, v2, v3, &dummy_lambda, NULL))
+ {
+ return TRUE;
+ }
+ else if (isect_line_tri_v3(bucket_quad[0], bucket_quad[1], v1, v3, v4, &dummy_lambda, NULL) ||
+ isect_line_tri_v3(bucket_quad[1], bucket_quad[2], v1, v3, v4, &dummy_lambda, NULL) ||
+ isect_line_tri_v3(bucket_quad[2], bucket_quad[3], v1, v3, v4, &dummy_lambda, NULL) ||
+ isect_line_tri_v3(bucket_quad[3], bucket_quad[0], v1, v3, v4, &dummy_lambda, NULL))
+ {
+ return TRUE;
+ }
+#endif
+
+ return FALSE;
+ }
+}
+
static void layer_bucket_init(MaskRasterLayer *layer, const float pixel_size)
{
MemArena *arena = BLI_memarena_new(1 << 16, __func__);
- {
- const float dims[2] = {layer->bounds.xmax - layer->bounds.xmin,
- layer->bounds.ymax - layer->bounds.ymin};
+ const float bucket_dim_x = layer->bounds.xmax - layer->bounds.xmin;
+ const float bucket_dim_y = layer->bounds.ymax - layer->bounds.ymin;
- layer->buckets_x = (dims[0] / pixel_size) / (float)BUCKET_PIXELS_PER_CELL;
- layer->buckets_y = (dims[1] / pixel_size) / (float)BUCKET_PIXELS_PER_CELL;
+ layer->buckets_x = (bucket_dim_x / pixel_size) / (float)BUCKET_PIXELS_PER_CELL;
+ layer->buckets_y = (bucket_dim_y / pixel_size) / (float)BUCKET_PIXELS_PER_CELL;
// printf("bucket size %ux%u\n", layer->buckets_x, layer->buckets_y);
- CLAMP(layer->buckets_x, 8, 512);
- CLAMP(layer->buckets_y, 8, 512);
+ CLAMP(layer->buckets_x, 8, 512);
+ CLAMP(layer->buckets_y, 8, 512);
- layer->buckets_xy_scalar[0] = (1.0f / (dims[0] + FLT_EPSILON)) * layer->buckets_x;
- layer->buckets_xy_scalar[1] = (1.0f / (dims[1] + FLT_EPSILON)) * layer->buckets_y;
- }
+ layer->buckets_xy_scalar[0] = (1.0f / (bucket_dim_x + FLT_EPSILON)) * layer->buckets_x;
+ layer->buckets_xy_scalar[1] = (1.0f / (bucket_dim_y + FLT_EPSILON)) * layer->buckets_y;
{
+ /* width and height of each bucket */
+ const float bucket_size_x = bucket_dim_x / layer->buckets_x;
+ const float bucket_size_y = bucket_dim_y / layer->buckets_y;
+
unsigned int *face = &layer->face_array[0][0];
float (*cos)[3] = layer->face_coords;
@@ -283,22 +421,27 @@
const unsigned int xi_max = (unsigned int) ((xmax - layer->bounds.xmin) * layer->buckets_xy_scalar[0]);
const unsigned int yi_min = (unsigned int) ((ymin - layer->bounds.ymin) * layer->buckets_xy_scalar[1]);
const unsigned int yi_max = (unsigned int) ((ymax - layer->bounds.ymin) * layer->buckets_xy_scalar[1]);
+ void *face_index_void = SET_UINT_IN_POINTER(face_index);
unsigned int xi, yi;
- for (xi = xi_min; xi <= xi_max; xi++) {
- for (yi = yi_min; yi <= yi_max; yi++) {
- unsigned int bucket_index = (layer->buckets_x * yi) + xi;
+ for (yi = yi_min; yi <= yi_max; yi++) {
+ unsigned int bucket_index = (layer->buckets_x * yi) + xi_min;
+ for (xi = xi_min; xi <= xi_max; xi++, bucket_index++) {
+ // unsigned int bucket_index = (layer->buckets_x * yi) + xi; /* correct but do in outer loop */
BLI_assert(xi < layer->buckets_x);
BLI_assert(yi < layer->buckets_y);
BLI_assert(bucket_index < bucket_tot);
- BLI_linklist_prepend_arena(&bucketstore[bucket_index],
- SET_UINT_IN_POINTER(face_index),
- arena);
-
- bucketstore_tot[bucket_index]++;
+ /* check if the bucket intersects with the face */
+ /* note: there is a tradeoff here since checking box/tri intersections isn't
+ * as optimal as it could be, but checking pixels against faces they will never intersect
+ * with is likely the greater slowdown here - so check if the cell intersects the face */
+ if (layer_bucket_isect_test(layer, face_index, xi, yi, bucket_size_x, bucket_size_y)) {
+ BLI_linklist_prepend_arena(&bucketstore[bucket_index], face_index_void, arena);
+ bucketstore_tot[bucket_index]++;
+ }
}
}
}
@@ -343,8 +486,7 @@
const short do_aspect_correct, const short do_mask_aa,
const short do_feather)
{
- /* TODO: real size */
- const int resol = SPLINE_RESOL;
+ const int resol = SPLINE_RESOL; /* TODO: real size */
const float pixel_size = 1.0f / MIN2(width, height);
const float zvec[3] = {0.0f, 0.0f, 1.0f};
More information about the Bf-blender-cvs
mailing list