From ee7ae2cdbb24072707d74534a560133f9780b079 Mon Sep 17 00:00:00 2001 From: Bastien Montagne Date: Fri, 13 Jul 2012 20:50:32 +0000 Subject: [PATCH 001/108] Fix [#32013] Crash loading a 2.49b model Problems were in the old multires loading system. Actually, the sigsev itself was the easy part of the job (simply had to convert from tesselated data to polys/loops), but after that I was getting a horrible bunch of wild stray faces... It finally turned out it was a mismatch in two different subsurf structs used while computing a mdisps layer from the multires DM, leading to getting complete random normals (null ones, NAN ones...), leading to complete dummy tangent space matrix, leading to absurds mdisps values... Note: I also moved the copy of first layer's vertex and face data from old me->mr to mesh's v/fdata earlier in multire_load_old(), to be able to use general face_to_poly conversion function (later on we would have to do it by hand, the general function would erase our newly computed mdisps layer...). Took me the whole week (something like 20h) to track this down: multires + subsurf = C nightmare! --- source/blender/blenkernel/intern/multires.c | 38 ++++++++++++++------- 1 file changed, 25 insertions(+), 13 deletions(-) diff --git a/source/blender/blenkernel/intern/multires.c b/source/blender/blenkernel/intern/multires.c index 2bc5c37b41b..db39bf74e48 100644 --- a/source/blender/blenkernel/intern/multires.c +++ b/source/blender/blenkernel/intern/multires.c @@ -992,6 +992,9 @@ static void grid_tangent_matrix(float mat[3][3], const CCGKey *key, copy_v3_v3(mat[2], CCG_grid_elem_no(key, grid, x, y)); } +/* XXX WARNING: subsurf elements from dm and oldGridData *must* be of the same format (size), + * because this code uses CCGKey's info from dm to access oldGridData's normals + * (through the call to grid_tangent_matrix())! */ static void multiresModifier_disp_run(DerivedMesh *dm, Mesh *me, DerivedMesh *dm2, DispOp op, CCGElem **oldGridData, int totlvl) { CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm; @@ -2069,6 +2072,21 @@ void multires_load_old(Object *ob, Mesh *me) me->mface[i].mat_nr = lvl->faces[i].mat_nr; } + /* Copy the first-level data to the mesh */ + /* XXX We must do this before converting tessfaces to polys/lopps! */ + for (i = 0, l = me->mr->vdata.layers; i < me->mr->vdata.totlayer; ++i, ++l) + CustomData_add_layer(&me->vdata, l->type, CD_REFERENCE, l->data, me->totvert); + for (i = 0, l = me->mr->fdata.layers; i < me->mr->fdata.totlayer; ++i, ++l) + CustomData_add_layer(&me->fdata, l->type, CD_REFERENCE, l->data, me->totface); + memset(&me->mr->vdata, 0, sizeof(CustomData)); + memset(&me->mr->fdata, 0, sizeof(CustomData)); + + multires_load_old_vcols(me); + multires_load_old_face_flags(me); + + /* multiresModifier_subdivide (actually, multires_subdivide) expects polys, not tessfaces! */ + BKE_mesh_convert_mfaces_to_mpolys(me); + /* Add a multires modifier to the object */ md = ob->modifiers.first; while (md && modifierType_getInfo(md->type)->type == eModifierTypeType_OnlyDeform) @@ -2081,25 +2099,19 @@ void multires_load_old(Object *ob, Mesh *me) mmd->lvl = mmd->totlvl; orig = CDDM_from_mesh(me, NULL); - dm = multires_make_derived_from_derived(orig, mmd, ob, 0); - + /* XXX We *must* alloc paint mask here, else we have some kind of mismatch in + * multires_modifier_update_mdisps() (called by dm->release(dm)), which always creates the + * reference subsurfed dm with this option, before calling multiresModifier_disp_run(), + * which implitely expects both subsurfs from its first dm and oldGridData parameters to + * be of the same "format"! */ + dm = multires_make_derived_from_derived(orig, mmd, ob, MULTIRES_ALLOC_PAINT_MASK); + multires_load_old_dm(dm, me, mmd->totlvl + 1); multires_dm_mark_as_modified(dm, MULTIRES_COORDS_MODIFIED); dm->release(dm); orig->release(orig); - /* Copy the first-level data to the mesh */ - for (i = 0, l = me->mr->vdata.layers; i < me->mr->vdata.totlayer; ++i, ++l) - CustomData_add_layer(&me->vdata, l->type, CD_REFERENCE, l->data, me->totvert); - for (i = 0, l = me->mr->fdata.layers; i < me->mr->fdata.totlayer; ++i, ++l) - CustomData_add_layer(&me->fdata, l->type, CD_REFERENCE, l->data, me->totface); - memset(&me->mr->vdata, 0, sizeof(CustomData)); - memset(&me->mr->fdata, 0, sizeof(CustomData)); - - multires_load_old_vcols(me); - multires_load_old_face_flags(me); - /* Remove the old multires */ multires_free(me->mr); me->mr = NULL; From 9e09005e49e7a24535daaed85c9c0aedfee1b43a Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sat, 14 Jul 2012 00:33:58 +0000 Subject: [PATCH 002/108] add is_quad_convex_v2(), SET_UINT_IN_POINTER, GET_UINT_FROM_POINTER macros & some minor edits. --- source/blender/blenlib/BLI_math_geom.h | 1 + source/blender/blenlib/BLI_utildefines.h | 4 ++++ source/blender/blenlib/intern/math_geom.c | 7 +++++++ source/blender/blenlib/intern/rct.c | 7 +++++++ source/blender/editors/sculpt_paint/paint_image.c | 10 +++++----- 5 files changed, 24 insertions(+), 5 deletions(-) diff --git a/source/blender/blenlib/BLI_math_geom.h b/source/blender/blenlib/BLI_math_geom.h index 50345237a9f..6810067b35b 100644 --- a/source/blender/blenlib/BLI_math_geom.h +++ b/source/blender/blenlib/BLI_math_geom.h @@ -55,6 +55,7 @@ float area_quad_v3(const float a[3], const float b[3], const float c[3], const f float area_poly_v3(int nr, float verts[][3], const float normal[3]); int is_quad_convex_v3(const float v1[3], const float v2[3], const float v3[3], const float v4[3]); +int is_quad_convex_v2(const float v1[2], const float v2[2], const float v3[2], const float v4[2]); /********************************* Distance **********************************/ diff --git a/source/blender/blenlib/BLI_utildefines.h b/source/blender/blenlib/BLI_utildefines.h index f761f2edcba..536236c07ac 100644 --- a/source/blender/blenlib/BLI_utildefines.h +++ b/source/blender/blenlib/BLI_utildefines.h @@ -232,6 +232,10 @@ #define SET_INT_IN_POINTER(i) ((void *)(intptr_t)(i)) #define GET_INT_FROM_POINTER(i) ((int)(intptr_t)(i)) +#define SET_UINT_IN_POINTER(i) ((void *)(uintptr_t)(i)) +#define GET_UINT_FROM_POINTER(i) ((unsigned int)(uintptr_t)(i)) + + /* Macro to convert a value to string in the preprocessor * STRINGIFY_ARG: gives the argument as a string * STRINGIFY_APPEND: appends any argument 'b' onto the string argument 'a', diff --git a/source/blender/blenlib/intern/math_geom.c b/source/blender/blenlib/intern/math_geom.c index f9acb6ae1dd..097b14754be 100644 --- a/source/blender/blenlib/intern/math_geom.c +++ b/source/blender/blenlib/intern/math_geom.c @@ -3278,3 +3278,10 @@ int is_quad_convex_v3(const float v1[3], const float v2[3], const float v3[3], c /* linetests, the 2 diagonals have to instersect to be convex */ return (isect_line_line_v2(vec[0], vec[2], vec[1], vec[3]) > 0) ? TRUE : FALSE; } + +int is_quad_convex_v2(const float v1[2], const float v2[2], const float v3[2], const float v4[2]) +{ + /* linetests, the 2 diagonals have to instersect to be convex */ + return (isect_line_line_v2(v1, v3, v2, v4) > 0) ? TRUE : FALSE; +} + diff --git a/source/blender/blenlib/intern/rct.c b/source/blender/blenlib/intern/rct.c index c1ef3e27291..bdca1bb51bd 100644 --- a/source/blender/blenlib/intern/rct.c +++ b/source/blender/blenlib/intern/rct.c @@ -41,6 +41,13 @@ #include "DNA_vec_types.h" #include "BLI_rect.h" +/** + * Determine if a rect is empty. An empty + * rect is one with a zero (or negative) + * width or height. + * + * \return True if \a rect is empty. + */ int BLI_rcti_is_empty(const rcti *rect) { return ((rect->xmax <= rect->xmin) || (rect->ymax <= rect->ymin)); diff --git a/source/blender/editors/sculpt_paint/paint_image.c b/source/blender/editors/sculpt_paint/paint_image.c index 5e46a28a3b7..9746ba6dfa1 100644 --- a/source/blender/editors/sculpt_paint/paint_image.c +++ b/source/blender/editors/sculpt_paint/paint_image.c @@ -560,14 +560,14 @@ static int project_bucket_offset(const ProjPaintState *ps, const float projCoSS[ * ps->bucketRect[x + (y*ps->buckets_y)] */ /* please explain? - * projCoSS[0] - ps->screenMin[0] : zero origin - * ... / ps->screen_width : range from 0.0 to 1.0 - * ... * ps->buckets_x : use as a bucket index + * projCoSS[0] - ps->screenMin[0] : zero origin + * ... / ps->screen_width : range from 0.0 to 1.0 + * ... * ps->buckets_x : use as a bucket index * * Second multiplication does similar but for vertical offset */ - return ( (int)(((projCoSS[0] - ps->screenMin[0]) / ps->screen_width) * ps->buckets_x)) + - ( ( (int)(((projCoSS[1] - ps->screenMin[1]) / ps->screen_height) * ps->buckets_y)) * ps->buckets_x); + return ( (int)(((projCoSS[0] - ps->screenMin[0]) / ps->screen_width) * ps->buckets_x)) + + (((int)(((projCoSS[1] - ps->screenMin[1]) / ps->screen_height) * ps->buckets_y)) * ps->buckets_x); } static int project_bucket_offset_safe(const ProjPaintState *ps, const float projCoSS[2]) From f5a35c36341f0db987ffd70f4b55bca21eb58c7f Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sat, 14 Jul 2012 01:43:33 +0000 Subject: [PATCH 003/108] new mask rasterizer - replace kdopbvh with with own bucket lookups. --- .../blenkernel/intern/mask_rasterize.c | 311 ++++++++++++------ 1 file changed, 214 insertions(+), 97 deletions(-) diff --git a/source/blender/blenkernel/intern/mask_rasterize.c b/source/blender/blenkernel/intern/mask_rasterize.c index bb18166ba6d..fa12472cc55 100644 --- a/source/blender/blenkernel/intern/mask_rasterize.c +++ b/source/blender/blenkernel/intern/mask_rasterize.c @@ -34,20 +34,18 @@ #include "DNA_mask_types.h" #include "BLI_utildefines.h" -#include "BLI_kdopbvh.h" #include "BLI_scanfill.h" +#include "BLI_memarena.h" #include "BLI_math.h" #include "BLI_rect.h" #include "BLI_listbase.h" -#include "BLI_mempool.h" +#include "BLI_linklist.h" #include "BKE_mask.h" #ifndef USE_RASKTER -#define RESOL 32 - /** * A single #MaskRasterHandle contains multile #MaskRasterLayer's, * each #MaskRasterLayer does its own lookup which contributes to @@ -56,15 +54,22 @@ /* internal use only */ typedef struct MaskRasterLayer { - /* xy raytree */ - BVHTree *bvhtree; + /* geometry */ + unsigned int tri_tot; + unsigned int (*tri_array)[4]; /* access coords tri/quad */ + float (*tri_coords)[3]; /* xy, z 0-1 (1.0 == filled) */ + /* 2d bounds (to quickly skip raytree lookup) */ rctf bounds; - /* geometry */ - unsigned int (*tri_array)[4]; /* access coords tri/quad */ - float (*tri_coords)[3]; /* xy, z 0-1 (1.0 == filled) */ + + /* buckets */ + unsigned int **buckets_tri; + /* cache divide and subtract */ + float buckets_xy_scalar[2]; /* 1.0 / (buckets_width + FLT_EPSILON) */ + unsigned int buckets_x; + unsigned int buckets_y; /* copied direct from #MaskLayer.--- */ @@ -75,6 +80,7 @@ typedef struct MaskRasterLayer { } MaskRasterLayer; +static void layer_bucket_init(MaskRasterLayer *layer); /** * opaque local struct for mask pixel lookup, each MaskLayer needs one of these @@ -104,7 +110,6 @@ void BLI_maskrasterize_handle_free(MaskRasterHandle *mr_handle) /* raycast vars */ for (i = 0; i < layers_tot; i++, raslayers++) { - BLI_bvhtree_free(raslayers->bvhtree); if (raslayers->tri_array) { MEM_freeN(raslayers->tri_array); @@ -113,17 +118,33 @@ void BLI_maskrasterize_handle_free(MaskRasterHandle *mr_handle) if (raslayers->tri_coords) { MEM_freeN(raslayers->tri_coords); } + + if (raslayers->buckets_tri) { + const unsigned int bucket_tot = raslayers->buckets_x * raslayers->buckets_y; + unsigned int bucket_index; + for (bucket_index = 0; bucket_index < bucket_tot; bucket_index++) { + unsigned int *tri_index = raslayers->buckets_tri[bucket_index]; + if (tri_index) { + MEM_freeN(tri_index); + } + } + + MEM_freeN(raslayers->buckets_tri); + } } MEM_freeN(mr_handle->layers); MEM_freeN(mr_handle); } +#define RESOL 32 + #define PRINT_MASK_DEBUG printf #define SF_EDGE_IS_BOUNDARY 0xff #define SF_KEYINDEX_TEMP_ID ((unsigned int) -1) +#define TRI_TERMINATOR_ID ((unsigned int) -1) void maskrasterize_spline_differentiate_point_inset(float (*diff_feather_points)[2], float (*diff_points)[2], @@ -366,7 +387,6 @@ void BLI_maskrasterize_handle_init(MaskRasterHandle *mr_handle, struct Mask *mas rctf bounds; int tri_index; - BVHTree *bvhtree; float bvhcos[4][3]; /* now we have all the splines */ @@ -397,9 +417,6 @@ void BLI_maskrasterize_handle_init(MaskRasterHandle *mr_handle, struct Mask *mas tri_array = MEM_mallocN(sizeof(*tri_array) * (sf_tri_tot + tot_feather_quads), "maskrast_tri_index"); - /* */ - bvhtree = BLI_bvhtree_new(sf_tri_tot + tot_feather_quads, 0.000001f, 8, 6); - /* tri's */ tri = (unsigned int *)tri_array; for (sf_tri = sf_ctx.fillfacebase.first, tri_index = 0; sf_tri; sf_tri = sf_tri->next, tri_index++) { @@ -407,12 +424,6 @@ void BLI_maskrasterize_handle_init(MaskRasterHandle *mr_handle, struct Mask *mas *(tri++) = sf_tri->v2->tmp.u; *(tri++) = sf_tri->v3->tmp.u; *(tri++) = TRI_VERT; - - copy_v3_v3(bvhcos[0], tri_coords[*(tri - 4)]); - copy_v3_v3(bvhcos[1], tri_coords[*(tri - 3)]); - copy_v3_v3(bvhcos[2], tri_coords[*(tri - 2)]); - - BLI_bvhtree_insert(bvhtree, tri_index, (float *)bvhcos, 3); } /* start of feather faces... if we have this set, @@ -435,7 +446,7 @@ void BLI_maskrasterize_handle_init(MaskRasterHandle *mr_handle, struct Mask *mas copy_v3_v3(bvhcos[2], tri_coords[*(tri - 2)]); copy_v3_v3(bvhcos[3], tri_coords[*(tri - 1)]); - BLI_bvhtree_insert(bvhtree, tri_index++, (const float *)bvhcos, 4); + tri_index++; } } } @@ -444,21 +455,20 @@ void BLI_maskrasterize_handle_init(MaskRasterHandle *mr_handle, struct Mask *mas BLI_assert(tri_index == sf_tri_tot + tot_feather_quads); - BLI_bvhtree_balance(bvhtree); - { MaskRasterLayer *raslayer = &mr_handle->layers[masklay_index]; + raslayer->tri_tot = sf_tri_tot + tot_feather_quads; raslayer->tri_coords = tri_coords; raslayer->tri_array = tri_array; raslayer->bounds = bounds; - raslayer->bvhtree = bvhtree; /* copy as-is */ raslayer->alpha = masklay->alpha; raslayer->blend = masklay->blend; raslayer->blend_flag = masklay->blend_flag; + layer_bucket_init(raslayer); BLI_union_rctf(&mr_handle->bounds, &bounds); } @@ -471,11 +481,6 @@ void BLI_maskrasterize_handle_init(MaskRasterHandle *mr_handle, struct Mask *mas } } -//static void tri_flip_tri(unsigned int tri[3]) -//{ - -//} - /* 2D ray test */ static float maskrasterize_layer_z_depth_tri(const float pt[2], const float v1[3], const float v2[3], const float v3[3]) @@ -495,13 +500,8 @@ static float maskrasterize_layer_z_depth_quad(const float pt[2], } #endif -static void maskrasterize_layer_bvh_cb(void *userdata, int index, const BVHTreeRay *ray, BVHTreeRayHit *hit) +static float maskrasterize_layer_isect(unsigned int *tri, float (*cos)[3], const float dist_orig, const float xy[2]) { - MaskRasterLayer *layer = (struct MaskRasterLayer *)userdata; - unsigned int *tri = layer->tri_array[index]; - float (*cos)[3] = layer->tri_coords; - const float dist_orig = hit->dist; - /* we always cast from same place only need xy */ if (tri[3] == TRI_VERT) { /* --- tri --- */ @@ -511,17 +511,12 @@ static void maskrasterize_layer_bvh_cb(void *userdata, int index, const BVHTreeR (cos[1][2] < dist_orig) || (cos[2][2] < dist_orig)) { - if (isect_point_tri_v2(ray->origin, cos[tri[0]], cos[tri[1]], cos[tri[2]])) { + if (isect_point_tri_v2(xy, cos[tri[0]], cos[tri[1]], cos[tri[2]])) { /* we know all tris are close for now */ #if 0 - const float dist = maskrasterize_layer_z_depth_tri(ray->origin, cos[tri[0]], cos[tri[1]], cos[tri[2]]); - if (dist < dist_orig) { - hit->index = index; - hit->dist = dist; - } + return maskrasterize_layer_z_depth_tri(xy, cos[tri[0]], cos[tri[1]], cos[tri[2]]); #else - hit->index = index; - hit->dist = 0.0f; + return 0.0f; #endif } } @@ -538,27 +533,15 @@ static void maskrasterize_layer_bvh_cb(void *userdata, int index, const BVHTreeR /* needs work */ #if 0 - if (isect_point_quad_v2(ray->origin, cos[tri[0]], cos[tri[1]], cos[tri[2]], cos[tri[3]])) { - const float dist = maskrasterize_layer_z_depth_quad(ray->origin, cos[tri[0]], cos[tri[1]], cos[tri[2]], cos[tri[3]]); - if (dist < dist_orig) { - hit->index = index; - hit->dist = dist; - } + if (isect_point_quad_v2(xy, cos[tri[0]], cos[tri[1]], cos[tri[2]], cos[tri[3]])) { + return maskrasterize_layer_z_depth_quad(xy, cos[tri[0]], cos[tri[1]], cos[tri[2]], cos[tri[3]]); } #elif 1 - if (isect_point_tri_v2(ray->origin, cos[tri[0]], cos[tri[1]], cos[tri[2]])) { - const float dist = maskrasterize_layer_z_depth_tri(ray->origin, cos[tri[0]], cos[tri[1]], cos[tri[2]]); - if (dist < dist_orig) { - hit->index = index; - hit->dist = dist; - } + if (isect_point_tri_v2(xy, cos[tri[0]], cos[tri[1]], cos[tri[2]])) { + return maskrasterize_layer_z_depth_tri(xy, cos[tri[0]], cos[tri[1]], cos[tri[2]]); } - else if (isect_point_tri_v2(ray->origin, cos[tri[0]], cos[tri[2]], cos[tri[3]])) { - const float dist = maskrasterize_layer_z_depth_tri(ray->origin, cos[tri[0]], cos[tri[2]], cos[tri[3]]); - if (dist < dist_orig) { - hit->index = index; - hit->dist = dist; - } + else if (isect_point_tri_v2(xy, cos[tri[0]], cos[tri[2]], cos[tri[3]])) { + return maskrasterize_layer_z_depth_tri(xy, cos[tri[0]], cos[tri[2]], cos[tri[3]]); } #else /* cheat - we know first 2 verts are z0.0f and second 2 are z 1.0f */ @@ -566,8 +549,156 @@ static void maskrasterize_layer_bvh_cb(void *userdata, int index, const BVHTreeR #endif } } + + return 1.0f; } +static void layer_bucket_init(MaskRasterLayer *layer) +{ + MemArena *arena = BLI_memarena_new(1 << 16, __func__); + + /* TODO - calculate best bucket size */ + layer->buckets_x = 128; + layer->buckets_y = 128; + + layer->buckets_xy_scalar[0] = (1.0f / ((layer->bounds.xmax - layer->bounds.xmin) + FLT_EPSILON)) * layer->buckets_x; + layer->buckets_xy_scalar[1] = (1.0f / ((layer->bounds.ymax - layer->bounds.ymin) + FLT_EPSILON)) * layer->buckets_y; + + { + unsigned int *tri = &layer->tri_array[0][0]; + float (*cos)[3] = layer->tri_coords; + + const unsigned int bucket_tot = layer->buckets_x * layer->buckets_y; + LinkNode **bucketstore = MEM_callocN(bucket_tot * sizeof(LinkNode *), __func__); + unsigned int *bucketstore_tot = MEM_callocN(bucket_tot * sizeof(unsigned int), __func__); + + unsigned int tri_index; + + for (tri_index = 0; tri_index < layer->tri_tot; tri_index++, tri += 4) { + float xmin; + float xmax; + float ymin; + float ymax; + + if (tri[3] == TRI_VERT) { + const float *v1 = cos[tri[0]]; + const float *v2 = cos[tri[1]]; + const float *v3 = cos[tri[2]]; + + xmin = fminf(v1[0], fminf(v2[0], v3[0])); + xmax = fmaxf(v1[0], fmaxf(v2[0], v3[0])); + ymin = fminf(v1[1], fminf(v2[1], v3[1])); + ymax = fmaxf(v1[1], fmaxf(v2[1], v3[1])); + } + else { + const float *v1 = cos[tri[0]]; + const float *v2 = cos[tri[1]]; + const float *v3 = cos[tri[2]]; + const float *v4 = cos[tri[3]]; + + xmin = fminf(v1[0], fminf(v2[0], fminf(v3[0], v4[0]))); + xmax = fmaxf(v1[0], fmaxf(v2[0], fmaxf(v3[0], v4[0]))); + ymin = fminf(v1[1], fminf(v2[1], fminf(v3[1], v4[1]))); + ymax = fmaxf(v1[1], fmaxf(v2[1], fmaxf(v3[1], v4[1]))); + } + + + /* not essential but may as will skip any faces outside the view */ + if (!((xmax < 0.0f) || (ymax < 0.0f) || (xmin > 1.0f) || (ymin > 1.0f))) { + const unsigned int xi_min = (unsigned int) ((xmin - layer->bounds.xmin) * layer->buckets_xy_scalar[0]); + 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]); + + 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; + + 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(tri_index), + arena); + + bucketstore_tot[bucket_index]++; + } + } + } + } + + if (1) { + /* now convert linknodes into arrays for faster per pixel access */ + unsigned int **buckets_tri = MEM_mallocN(bucket_tot * sizeof(unsigned int **), __func__); + unsigned int bucket_index; + + for (bucket_index = 0; bucket_index < bucket_tot; bucket_index++) { + if (bucketstore_tot[bucket_index]) { + unsigned int *bucket = MEM_mallocN((bucketstore_tot[bucket_index] + 1) * sizeof(unsigned int), __func__); + LinkNode *bucket_node; + + buckets_tri[bucket_index] = bucket; + + for (bucket_node = bucketstore[bucket_index]; bucket_node; bucket_node = bucket_node->next) { + *bucket = GET_UINT_FROM_POINTER(bucket_node->link); + bucket++; + } + *bucket = TRI_TERMINATOR_ID; + } + else { + buckets_tri[bucket_index] = NULL; + } + } + + layer->buckets_tri = buckets_tri; + } + + MEM_freeN(bucketstore); + MEM_freeN(bucketstore_tot); + } + + BLI_memarena_free(arena); +} + +static unsigned int layer_bucket_index_from_xy(MaskRasterLayer *layer, const float xy[2]) +{ + BLI_assert(BLI_in_rctf_v(&layer->bounds, xy)); + + return ( (unsigned int)((xy[0] - layer->bounds.xmin) * layer->buckets_xy_scalar[0])) + + (((unsigned int)((xy[1] - layer->bounds.ymin) * layer->buckets_xy_scalar[1])) * layer->buckets_x); +} + +static float layer_bucket_depth_from_xy(MaskRasterLayer *layer, const float xy[2]) +{ + unsigned int index = layer_bucket_index_from_xy(layer, xy); + unsigned int *tri_index = layer->buckets_tri[index]; + + if (tri_index) { + float (*cos)[3] = layer->tri_coords; + float best_dist = 1.0f; + float test_dist; + while (*tri_index != TRI_TERMINATOR_ID) { + unsigned int *tri = layer->tri_array[*tri_index]; + if ((test_dist = maskrasterize_layer_isect(tri, cos, best_dist, xy)) < best_dist) { + best_dist = test_dist; + /* bail early */ + if (best_dist <= 0.0f) { + return 0.0f; + } + } + tri_index++; + } + return best_dist; + } + else { + return 1.0f; + } +} + + float BLI_maskrasterize_handle_sample(MaskRasterHandle *mr_handle, const float xy[2]) { /* TODO - AA jitter */ @@ -578,51 +709,37 @@ float BLI_maskrasterize_handle_sample(MaskRasterHandle *mr_handle, const float x MaskRasterLayer *layer = mr_handle->layers; /* raycast vars*/ - const float co[3] = {xy[0], xy[1], 0.0f}; - const float dir[3] = {0.0f, 0.0f, 1.0f}; - const float radius = 1.0f; - BVHTreeRayHit hit = {0}; /* return */ float value = 0.0f; for (i = 0; i < layers_tot; i++, layer++) { - if (BLI_in_rctf_v(&layer->bounds, xy)) { + /* --- hit (start) --- */ + const float dist = 1.0f - layer_bucket_depth_from_xy(layer, xy); + const float dist_ease = (3.0f * dist * dist - 2.0f * dist * dist * dist); - hit.dist = FLT_MAX; - hit.index = -1; + float v; + /* apply alpha */ + v = dist_ease * layer->alpha; - /* TODO, and axis aligned version of this function, avoids 2 casts */ - BLI_bvhtree_ray_cast(layer->bvhtree, co, dir, radius, &hit, maskrasterize_layer_bvh_cb, layer); + if (layer->blend_flag & MASK_BLENDFLAG_INVERT) { + v = 1.0f - v; + } - /* --- hit (start) --- */ - if (hit.index != -1) { - const float dist = 1.0f - hit.dist; - const float dist_ease = (3.0f * dist * dist - 2.0f * dist * dist * dist); - - float v; - /* apply alpha */ - v = dist_ease * layer->alpha; - - if (layer->blend_flag & MASK_BLENDFLAG_INVERT) { - v = 1.0f - v; - } - - switch (layer->blend) { - case MASK_BLEND_SUBTRACT: - { - value -= v; - break; - } - case MASK_BLEND_ADD: - default: - { - value += v; - break; - } - } - } + switch (layer->blend) { + case MASK_BLEND_SUBTRACT: + { + value -= v; + break; + } + case MASK_BLEND_ADD: + default: + { + value += v; + break; + } + } /* --- hit (end) --- */ } From aeaa95a525343d95258e9388076833530a6aa4ab Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sat, 14 Jul 2012 04:07:59 +0000 Subject: [PATCH 004/108] more minor speedups for new mask rasterizer --- build_files/cmake/config/blender_lite.cmake | 1 + .../blenkernel/intern/mask_rasterize.c | 40 ++++++++++--------- 2 files changed, 22 insertions(+), 19 deletions(-) diff --git a/build_files/cmake/config/blender_lite.cmake b/build_files/cmake/config/blender_lite.cmake index e2adc17a2e8..777fbbf0dba 100644 --- a/build_files/cmake/config/blender_lite.cmake +++ b/build_files/cmake/config/blender_lite.cmake @@ -17,6 +17,7 @@ set(WITH_FFTW3 OFF CACHE FORCE BOOL) set(WITH_LIBMV OFF CACHE FORCE BOOL) set(WITH_CARVE OFF CACHE FORCE BOOL) set(WITH_GAMEENGINE OFF CACHE FORCE BOOL) +set(WITH_COMPOSITOR OFF CACHE FORCE BOOL) set(WITH_GHOST_XDND OFF CACHE FORCE BOOL) set(WITH_IK_ITASC OFF CACHE FORCE BOOL) set(WITH_IMAGE_CINEON OFF CACHE FORCE BOOL) diff --git a/source/blender/blenkernel/intern/mask_rasterize.c b/source/blender/blenkernel/intern/mask_rasterize.c index fa12472cc55..5259fb496d1 100644 --- a/source/blender/blenkernel/intern/mask_rasterize.c +++ b/source/blender/blenkernel/intern/mask_rasterize.c @@ -148,13 +148,14 @@ void BLI_maskrasterize_handle_free(MaskRasterHandle *mr_handle) void maskrasterize_spline_differentiate_point_inset(float (*diff_feather_points)[2], float (*diff_points)[2], - const int tot_diff_point, const float ofs, const int do_test) + const unsigned int tot_diff_point, const float ofs, + const short do_test) { - int k_prev = tot_diff_point - 2; - int k_curr = tot_diff_point - 1; - int k_next = 0; + unsigned int k_prev = tot_diff_point - 2; + unsigned int k_curr = tot_diff_point - 1; + unsigned int k_next = 0; - int k; + unsigned int k; float d_prev[2]; float d_next[2]; @@ -174,9 +175,6 @@ void maskrasterize_spline_differentiate_point_inset(float (*diff_feather_points) sub_v2_v2v2(d_prev, co_prev, co_curr); normalize_v2(d_prev); - /* TODO, speedup by only doing one normalize per iter */ - - for (k = 0; k < tot_diff_point; k++) { co_prev = diff_points[k_prev]; @@ -223,7 +221,7 @@ void BLI_maskrasterize_handle_init(MaskRasterHandle *mr_handle, struct Mask *mas const float zvec[3] = {0.0f, 0.0f, 1.0f}; MaskLayer *masklay; - int masklay_index; + unsigned int masklay_index; mr_handle->layers_tot = BLI_countlist(&mask->masklayers); mr_handle->layers = MEM_mallocN(sizeof(MaskRasterLayer) * mr_handle->layers_tot, STRINGIFY(MaskRasterLayer)); @@ -506,6 +504,7 @@ static float maskrasterize_layer_isect(unsigned int *tri, float (*cos)[3], const if (tri[3] == TRI_VERT) { /* --- tri --- */ +#if 0 /* not essential but avoids unneeded extra lookups */ if ((cos[0][2] < dist_orig) || (cos[1][2] < dist_orig) || @@ -513,13 +512,17 @@ static float maskrasterize_layer_isect(unsigned int *tri, float (*cos)[3], const { if (isect_point_tri_v2(xy, cos[tri[0]], cos[tri[1]], cos[tri[2]])) { /* we know all tris are close for now */ -#if 0 return maskrasterize_layer_z_depth_tri(xy, cos[tri[0]], cos[tri[1]], cos[tri[2]]); -#else - return 0.0f; -#endif } } +#else + /* we know all tris are close for now */ + if (1) { + if (isect_point_tri_v2(xy, cos[tri[0]], cos[tri[1]], cos[tri[2]])) { + return 0.0f; + } + } +#endif } else { /* --- quad --- */ @@ -558,8 +561,8 @@ static void layer_bucket_init(MaskRasterLayer *layer) MemArena *arena = BLI_memarena_new(1 << 16, __func__); /* TODO - calculate best bucket size */ - layer->buckets_x = 128; - layer->buckets_y = 128; + layer->buckets_x = 256; + layer->buckets_y = 256; layer->buckets_xy_scalar[0] = (1.0f / ((layer->bounds.xmax - layer->bounds.xmin) + FLT_EPSILON)) * layer->buckets_x; layer->buckets_xy_scalar[1] = (1.0f / ((layer->bounds.ymax - layer->bounds.ymin) + FLT_EPSILON)) * layer->buckets_y; @@ -684,8 +687,9 @@ static float layer_bucket_depth_from_xy(MaskRasterLayer *layer, const float xy[2 unsigned int *tri = layer->tri_array[*tri_index]; if ((test_dist = maskrasterize_layer_isect(tri, cos, best_dist, xy)) < best_dist) { best_dist = test_dist; - /* bail early */ - if (best_dist <= 0.0f) { + /* comparing with 0.0f is OK here because triangles are always zero depth */ + if (best_dist == 0.0f) { + /* bail early, we're as close as possible */ return 0.0f; } } @@ -701,8 +705,6 @@ static float layer_bucket_depth_from_xy(MaskRasterLayer *layer, const float xy[2 float BLI_maskrasterize_handle_sample(MaskRasterHandle *mr_handle, const float xy[2]) { - /* TODO - AA jitter */ - if (BLI_in_rctf_v(&mr_handle->bounds, xy)) { const unsigned int layers_tot = mr_handle->layers_tot; unsigned int i; From ac8c56c6fc9e1a816160144b5cebe2e99ffa67fc Mon Sep 17 00:00:00 2001 From: Mitchell Stokes Date: Sat, 14 Jul 2012 04:43:32 +0000 Subject: [PATCH 005/108] BGE: Better fix for the textures not working with custom shaders regression. Now custom shaders work, and textures aren't uploaded twice for GLSL materials (my earlier fix had some bad logic). --- .../gameengine/Ketsji/KX_BlenderMaterial.cpp | 26 ++++++++++++------- source/gameengine/Ketsji/KX_BlenderMaterial.h | 2 ++ 2 files changed, 19 insertions(+), 9 deletions(-) diff --git a/source/gameengine/Ketsji/KX_BlenderMaterial.cpp b/source/gameengine/Ketsji/KX_BlenderMaterial.cpp index 79e6c35e6a2..014c68e8bee 100644 --- a/source/gameengine/Ketsji/KX_BlenderMaterial.cpp +++ b/source/gameengine/Ketsji/KX_BlenderMaterial.cpp @@ -154,15 +154,8 @@ void KX_BlenderMaterial::ReleaseMaterial() mBlenderShader->ReloadMaterial(); } -void KX_BlenderMaterial::OnConstruction(int layer) +void KX_BlenderMaterial::InitTextures() { - if (mConstructed) - // when material are reused between objects - return; - - if (mMaterial->glslmat) - SetBlenderGLSLShader(layer); - // for each unique material... int i; for (i=0; inum_enabled; i++) { @@ -177,7 +170,7 @@ void KX_BlenderMaterial::OnConstruction(int layer) } // If we're using glsl materials, the textures are handled by bf_gpu, so don't load them twice! // However, if we're using a custom shader, then we still need to load the textures ourselves. - else if (!mMaterial->glslmat || mBlenderShader) { + else if (!mMaterial->glslmat || mShader) { if ( mMaterial->img[i] ) { if ( ! mTextures[i].InitFromImage(i, mMaterial->img[i], (mMaterial->flag[i] &MIPMAP)!=0 )) spit("unable to initialize image("<glslmat) + SetBlenderGLSLShader(layer); + + InitTextures(); mBlendFunc[0] =0; mBlendFunc[1] =0; @@ -892,6 +897,9 @@ KX_PYMETHODDEF_DOC( KX_BlenderMaterial, getShader , "getShader()") if (!mShader && !mModified) { mShader = new BL_Shader(); mModified = true; + + // Using a custom shader, make sure to initialize textures + InitTextures(); } if (mShader && !mShader->GetError()) { diff --git a/source/gameengine/Ketsji/KX_BlenderMaterial.h b/source/gameengine/Ketsji/KX_BlenderMaterial.h index 3a6dda06320..8fc86ef9cf2 100644 --- a/source/gameengine/Ketsji/KX_BlenderMaterial.h +++ b/source/gameengine/Ketsji/KX_BlenderMaterial.h @@ -138,6 +138,8 @@ private: bool mModified; bool mConstructed; // if false, don't clean on exit + void InitTextures(); + void SetBlenderGLSLShader(int layer); void ActivatGLMaterials( RAS_IRasterizer* rasty )const; From 98520ce4deccb24e5992930694bb4189f6fce0f3 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sat, 14 Jul 2012 12:47:49 +0000 Subject: [PATCH 006/108] use gcc attributes for BLI alloc functions --- intern/guardedalloc/MEM_guardedalloc.h | 25 +++++------ intern/guardedalloc/intern/mallocn.c | 4 +- source/blender/blenlib/BLI_memarena.h | 39 +++++++++++++--- source/blender/blenlib/BLI_mempool.h | 62 +++++++++++++++++++++----- 4 files changed, 98 insertions(+), 32 deletions(-) diff --git a/intern/guardedalloc/MEM_guardedalloc.h b/intern/guardedalloc/MEM_guardedalloc.h index 7fcfba5afec..dfb3fe69474 100644 --- a/intern/guardedalloc/MEM_guardedalloc.h +++ b/intern/guardedalloc/MEM_guardedalloc.h @@ -60,8 +60,8 @@ #ifndef __MEM_GUARDEDALLOC_H__ #define __MEM_GUARDEDALLOC_H__ -#include /* needed for FILE* */ -#include "MEM_sys_types.h" /* needed for uintptr_t */ +#include /* needed for FILE* */ +#include "MEM_sys_types.h" /* needed for uintptr_t */ #ifdef __cplusplus extern "C" { @@ -70,7 +70,7 @@ extern "C" { /** Returns the length of the allocated memory segment pointed at * by vmemh. If the pointer was not previously allocated by this * module, the result is undefined.*/ - size_t MEM_allocN_len(void *vmemh) + size_t MEM_allocN_len(const void *vmemh) #ifdef __GNUC__ __attribute__((warn_unused_result)) #endif @@ -111,10 +111,10 @@ extern "C" { * Allocate a block of memory of size len, with tag name str. The * memory is cleared. The name must be static, because only a * pointer to it is stored ! */ - void *MEM_callocN(size_t len, const char * str) + void *MEM_callocN(size_t len, const char *str) #ifdef __GNUC__ __attribute__((warn_unused_result)) - __attribute__((nonnull)) + __attribute__((nonnull(2))) __attribute__((alloc_size(1))) #endif ; @@ -122,10 +122,10 @@ extern "C" { /** Allocate a block of memory of size len, with tag name str. The * name must be a static, because only a pointer to it is stored ! * */ - void *MEM_mallocN(size_t len, const char * str) + void *MEM_mallocN(size_t len, const char *str) #ifdef __GNUC__ __attribute__((warn_unused_result)) - __attribute__((nonnull)) + __attribute__((nonnull(2))) __attribute__((alloc_size(1))) #endif ; @@ -133,10 +133,10 @@ extern "C" { /** Same as callocN, clears memory and uses mmap (disk cached) if supported. * Can be free'd with MEM_freeN as usual. * */ - void *MEM_mapallocN(size_t len, const char * str) + void *MEM_mapallocN(size_t len, const char *str) #ifdef __GNUC__ __attribute__((warn_unused_result)) - __attribute__((nonnull)) + __attribute__((nonnull(2))) __attribute__((alloc_size(1))) #endif ; @@ -213,11 +213,10 @@ public: \ MEM_freeN(mem); \ } \ -#endif - +#endif /* __cplusplus */ #ifdef __cplusplus } -#endif +#endif /* __cplusplus */ -#endif +#endif /* __MEM_GUARDEDALLOC_H__ */ diff --git a/intern/guardedalloc/intern/mallocn.c b/intern/guardedalloc/intern/mallocn.c index 9ba8c0f3d58..7eda5a3ab5e 100644 --- a/intern/guardedalloc/intern/mallocn.c +++ b/intern/guardedalloc/intern/mallocn.c @@ -222,10 +222,10 @@ void MEM_set_memory_debug(void) malloc_debug_memset = 1; } -size_t MEM_allocN_len(void *vmemh) +size_t MEM_allocN_len(const void *vmemh) { if (vmemh) { - MemHead *memh = vmemh; + const MemHead *memh = vmemh; memh--; return memh->len; diff --git a/source/blender/blenlib/BLI_memarena.h b/source/blender/blenlib/BLI_memarena.h index abba03ece9d..2a2dd31b26f 100644 --- a/source/blender/blenlib/BLI_memarena.h +++ b/source/blender/blenlib/BLI_memarena.h @@ -50,16 +50,43 @@ extern "C" { struct MemArena; typedef struct MemArena MemArena; +struct MemArena *BLI_memarena_new(const int bufsize, const char *name) +#ifdef __GNUC__ +__attribute__((warn_unused_result)) +__attribute__((nonnull(2))) +#endif +; -struct MemArena *BLI_memarena_new(int bufsize, const char *name); -void BLI_memarena_free(struct MemArena *ma); +void BLI_memarena_free(struct MemArena *ma) +#ifdef __GNUC__ +__attribute__((nonnull(1))) +#endif +; -void BLI_memarena_use_malloc(struct MemArena *ma); -void BLI_memarena_use_calloc(struct MemArena *ma); +void BLI_memarena_use_malloc(struct MemArena *ma) +#ifdef __GNUC__ +__attribute__((nonnull(1))) +#endif +; +void BLI_memarena_use_calloc(struct MemArena *ma) +#ifdef __GNUC__ +__attribute__((nonnull(1))) +#endif +; -void BLI_memarena_use_align(struct MemArena *ma, int align); +void BLI_memarena_use_align(struct MemArena *ma, const int align) +#ifdef __GNUC__ +__attribute__((nonnull(1))) +#endif +; -void *BLI_memarena_alloc(struct MemArena *ma, int size); +void *BLI_memarena_alloc(struct MemArena *ma, int size) +#ifdef __GNUC__ +__attribute__((warn_unused_result)) +__attribute__((nonnull(1))) +__attribute__((alloc_size(2))) +#endif +; #ifdef __cplusplus } diff --git a/source/blender/blenlib/BLI_mempool.h b/source/blender/blenlib/BLI_mempool.h index 9d7c7d496c8..c773cfbe680 100644 --- a/source/blender/blenlib/BLI_mempool.h +++ b/source/blender/blenlib/BLI_mempool.h @@ -48,16 +48,47 @@ typedef struct BLI_mempool BLI_mempool; * first four bytes of the elements never contain the character string * 'free'. use with care.*/ -BLI_mempool *BLI_mempool_create(int esize, int totelem, int pchunk, int flag); -void *BLI_mempool_alloc(BLI_mempool *pool); -void *BLI_mempool_calloc(BLI_mempool *pool); -void BLI_mempool_free(BLI_mempool *pool, void *addr); -void BLI_mempool_destroy(BLI_mempool *pool); -int BLI_mempool_count(BLI_mempool *pool); -void *BLI_mempool_findelem(BLI_mempool *pool, int index); +BLI_mempool *BLI_mempool_create(int esize, int totelem, int pchunk, int flag) +#ifdef __GNUC__ +__attribute__((warn_unused_result)) +#endif +; +void *BLI_mempool_alloc(BLI_mempool *pool) +#ifdef __GNUC__ +__attribute__((warn_unused_result)) +__attribute__((nonnull(1))) +#endif +; +void *BLI_mempool_calloc(BLI_mempool *pool) +#ifdef __GNUC__ +__attribute__((warn_unused_result)) +__attribute__((nonnull(1))) +#endif +; +void BLI_mempool_free(BLI_mempool *pool, void *addr) +#ifdef __GNUC__ +__attribute__((nonnull(1, 2))) +#endif +; +void BLI_mempool_destroy(BLI_mempool *pool) +#ifdef __GNUC__ +__attribute__((nonnull(1))) +#endif +; +int BLI_mempool_count(BLI_mempool *pool) +#ifdef __GNUC__ +__attribute__((nonnull(1))) +#endif +; +void *BLI_mempool_findelem(BLI_mempool *pool, int index) +#ifdef __GNUC__ +__attribute__((warn_unused_result)) +__attribute__((nonnull(1))) +#endif +; /** iteration stuff. note: this may easy to produce bugs with **/ -/*private structure*/ +/* private structure */ typedef struct BLI_mempool_iter { BLI_mempool *pool; struct BLI_mempool_chunk *curchunk; @@ -70,11 +101,20 @@ enum { BLI_MEMPOOL_ALLOW_ITER = (1 << 1) }; -void BLI_mempool_iternew(BLI_mempool *pool, BLI_mempool_iter *iter); -void *BLI_mempool_iterstep(BLI_mempool_iter *iter); +void BLI_mempool_iternew(BLI_mempool *pool, BLI_mempool_iter *iter) +#ifdef __GNUC__ +__attribute__((nonnull(1, 2))) +#endif +; +void *BLI_mempool_iterstep(BLI_mempool_iter *iter) +#ifdef __GNUC__ +__attribute__((warn_unused_result)) +__attribute__((nonnull(1))) +#endif +; #ifdef __cplusplus } #endif -#endif +#endif /* __BLI_MEMPOOL_H__ */ From 01c3db149cfcd5cb357d8fc739bbe4beb08b35e7 Mon Sep 17 00:00:00 2001 From: Bastien Montagne Date: Sat, 14 Jul 2012 14:03:36 +0000 Subject: [PATCH 007/108] Fix [#32086] Missing bevel "hold shift" for better accuracy. This commit adds "shift" and numtype to both Bevel and Inset mesh operators. It also gets rid of the magicnumber used in NumInput to str operation (currently, 20 chars per element, now defined as NUM_STR_REP_LEN in ED_numinput.h). --- .../blender/editors/animation/anim_markers.c | 8 +- source/blender/editors/include/ED_numinput.h | 1 + source/blender/editors/mesh/editmesh_tools.c | 187 +++++++++++++----- source/blender/editors/transform/transform.c | 101 +++++----- source/blender/editors/util/numinput.c | 17 +- 5 files changed, 209 insertions(+), 105 deletions(-) diff --git a/source/blender/editors/animation/anim_markers.c b/source/blender/editors/animation/anim_markers.c index ea344e7e332..96044e2408e 100644 --- a/source/blender/editors/animation/anim_markers.c +++ b/source/blender/editors/animation/anim_markers.c @@ -848,14 +848,14 @@ static int ed_marker_move_modal(bContext *C, wmOperator *op, wmEvent *evt) } if (evt->val == KM_PRESS) { - float vec[3]; - char str_tx[256]; + float vec; + char str_tx[NUM_STR_REP_LEN]; if (handleNumInput(&mm->num, evt)) { - applyNumInput(&mm->num, vec); + applyNumInput(&mm->num, &vec); outputNumInput(&mm->num, str_tx); - RNA_int_set(op->ptr, "frames", vec[0]); + RNA_int_set(op->ptr, "frames", vec); ed_marker_move_apply(op); // ed_marker_header_update(C, op, str, (int)vec[0]); // strcat(str, str_tx); diff --git a/source/blender/editors/include/ED_numinput.h b/source/blender/editors/include/ED_numinput.h index 411df88fb28..126ea13f0b2 100644 --- a/source/blender/editors/include/ED_numinput.h +++ b/source/blender/editors/include/ED_numinput.h @@ -57,6 +57,7 @@ typedef struct NumInput { /*********************** NumInput ********************************/ void initNumInput(NumInput *n); +#define NUM_STR_REP_LEN 20 /* str must be NUM_STR_LEN * (idx_max + 1) length. */ void outputNumInput(NumInput *n, char *str); short hasNumInput(NumInput *n); void applyNumInput(NumInput *n, float *vec); diff --git a/source/blender/editors/mesh/editmesh_tools.c b/source/blender/editors/mesh/editmesh_tools.c index 4c7545fa4fa..29f38342dd2 100644 --- a/source/blender/editors/mesh/editmesh_tools.c +++ b/source/blender/editors/mesh/editmesh_tools.c @@ -58,6 +58,7 @@ #include "WM_types.h" #include "ED_mesh.h" +#include "ED_numinput.h" #include "ED_object.h" #include "ED_screen.h" #include "ED_transform.h" @@ -4305,23 +4306,31 @@ typedef struct { int mcenter[2]; float initial_length; int is_modal; + NumInput num_input; + float shift_factor; /* The current factor when shift is pressed. Negative when shift not active. */ } BevelData; #define HEADER_LENGTH 180 static void edbm_bevel_update_header(wmOperator *op, bContext *C) { - static char str[] = "Confirm: Enter/LClick, Cancel: (Esc/RMB), factor: %f, Use Dist (D): %s: Use Even (E): %s"; + static char str[] = "Confirm: Enter/LClick, Cancel: (Esc/RMB), factor: %s, Use Dist (D): %s: Use Even (E): %s"; char msg[HEADER_LENGTH]; ScrArea *sa = CTX_wm_area(C); + BevelData *opdata = op->customdata; if (sa) { + char factor_str[NUM_STR_REP_LEN]; + if (hasNumInput(&opdata->num_input)) + outputNumInput(&opdata->num_input, factor_str); + else + BLI_snprintf(factor_str, NUM_STR_REP_LEN, "%f", RNA_float_get(op->ptr, "percent")); BLI_snprintf(msg, HEADER_LENGTH, str, - RNA_float_get(op->ptr, "percent"), + factor_str, RNA_boolean_get(op->ptr, "use_dist") ? "On" : "Off", RNA_boolean_get(op->ptr, "use_even") ? "On" : "Off" - ); + ); ED_area_headerprint(sa, msg); } @@ -4384,7 +4393,11 @@ static int edbm_bevel_init(bContext *C, wmOperator *op, int is_modal) opdata->li = li; opdata->weights = NULL; opdata->is_modal = is_modal; - + opdata->shift_factor = -1.0f; + + initNumInput(&opdata->num_input); + opdata->num_input.flag = NUM_NO_NEGATIVE; + /* avoid the cost of allocating a bm copy */ if (is_modal) opdata->mesh_backup = EDBM_redo_state_store(em); @@ -4523,8 +4536,21 @@ static int edbm_bevel_invoke(bContext *C, wmOperator *op, wmEvent *event) static int edbm_bevel_modal(bContext *C, wmOperator *op, wmEvent *event) { BevelData *opdata = op->customdata; -// Scene *scene = CTX_data_scene(C); + if (event->val == KM_PRESS) { + /* Try to handle numeric inputs... */ + float factor; + + if (handleNumInput(&opdata->num_input, event)) { + applyNumInput(&opdata->num_input, &factor); + CLAMP(factor, 0.0f, 1.0f); + RNA_float_set(op->ptr, "percent", factor); + + edbm_bevel_calc(C, op); + edbm_bevel_update_header(op, C); + return OPERATOR_RUNNING_MODAL; + } + } switch (event->type) { case ESCKEY: case RIGHTMOUSE: @@ -4532,22 +4558,32 @@ static int edbm_bevel_modal(bContext *C, wmOperator *op, wmEvent *event) return OPERATOR_CANCELLED; case MOUSEMOVE: - { - float factor; - float mdiff[2]; + if (!hasNumInput(&opdata->num_input)) { + float factor; + float mdiff[2]; - mdiff[0] = opdata->mcenter[0] - event->mval[0]; - mdiff[1] = opdata->mcenter[1] - event->mval[1]; + mdiff[0] = opdata->mcenter[0] - event->mval[0]; + mdiff[1] = opdata->mcenter[1] - event->mval[1]; - factor = len_v2(mdiff) / opdata->initial_length; - factor = MAX2(1.0f - factor, 0.0f); + factor = -len_v2(mdiff) / opdata->initial_length + 1.0f; - RNA_float_set(op->ptr, "percent", factor); + /* Fake shift-transform... */ + if (event->shift) { + if (opdata->shift_factor < 0.0f) + opdata->shift_factor = RNA_float_get(op->ptr, "percent"); + factor = (factor - opdata->shift_factor) * 0.1f + opdata->shift_factor; + } + else if (opdata->shift_factor >= 0.0f) + opdata->shift_factor = -1.0f; - edbm_bevel_calc(C, op); - edbm_bevel_update_header(op, C); + CLAMP(factor, 0.0f, 1.0f); + + RNA_float_set(op->ptr, "percent", factor); + + edbm_bevel_calc(C, op); + edbm_bevel_update_header(op, C); + } return OPERATOR_RUNNING_MODAL; - } case LEFTMOUSE: case PADENTER: @@ -4598,8 +4634,8 @@ void MESH_OT_bevel(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; RNA_def_float(ot->srna, "percent", 0.0f, -FLT_MAX, FLT_MAX, "Percentage", "", 0.0f, 1.0f); -// XXX, disabled for 2.63 release, needs to work much better without overlap before we can give to users. -// RNA_def_int(ot->srna, "recursion", 1, 1, 50, "Recursion Level", "Recursion Level", 1, 8); + /* XXX, disabled for 2.63 release, needs to work much better without overlap before we can give to users. */ +/* RNA_def_int(ot->srna, "recursion", 1, 1, 50, "Recursion Level", "Recursion Level", 1, 8); */ RNA_def_boolean(ot->srna, "use_even", FALSE, "Even", "Calculate evenly spaced bevel"); RNA_def_boolean(ot->srna, "use_dist", FALSE, "Distance", "Interpret the percent in blender units"); @@ -4643,26 +4679,36 @@ typedef struct { int modify_depth; int is_modal; float initial_length; + int shift; + float shift_amount; BMBackup backup; BMEditMesh *em; + NumInput num_input; } InsetData; static void edbm_inset_update_header(wmOperator *op, bContext *C) { InsetData *opdata = op->customdata; - static char str[] = "Confirm: Enter/LClick, Cancel: (Esc/RClick), thickness: %f, depth (Ctrl to tweak): %f (%s), Outset (O): (%s)"; + static char str[] = "Confirm: Enter/LClick, Cancel: (Esc/RClick), thickness: %s, depth (Ctrl to tweak): %s (%s), Outset (O): (%s)"; char msg[HEADER_LENGTH]; ScrArea *sa = CTX_wm_area(C); if (sa) { + char flts_str[NUM_STR_REP_LEN * 2]; + if (hasNumInput(&opdata->num_input)) + outputNumInput(&opdata->num_input, flts_str); + else { + BLI_snprintf(flts_str, NUM_STR_REP_LEN, "%f", RNA_float_get(op->ptr, "thickness")); + BLI_snprintf(flts_str + NUM_STR_REP_LEN, NUM_STR_REP_LEN, "%f", RNA_float_get(op->ptr, "depth")); + } BLI_snprintf(msg, HEADER_LENGTH, str, - RNA_float_get(op->ptr, "thickness"), - RNA_float_get(op->ptr, "depth"), + flts_str, + flts_str + NUM_STR_REP_LEN, opdata->modify_depth ? "On" : "Off", RNA_boolean_get(op->ptr, "use_outset") ? "On" : "Off" - ); + ); ED_area_headerprint(sa, msg); } @@ -4680,9 +4726,14 @@ static int edbm_inset_init(bContext *C, wmOperator *op, int is_modal) opdata->old_thickness = 0.01; opdata->old_depth = 0.0; opdata->modify_depth = FALSE; + opdata->shift = FALSE; + opdata->shift_amount = 0.0f; opdata->is_modal = is_modal; opdata->em = em; + initNumInput(&opdata->num_input); + opdata->num_input.idx_max = 1; /* Two elements. */ + if (is_modal) opdata->backup = EDBM_redo_state_store(em); @@ -4814,34 +4865,17 @@ static int edbm_inset_invoke(bContext *C, wmOperator *op, wmEvent *event) static int edbm_inset_modal(bContext *C, wmOperator *op, wmEvent *event) { - InsetData *opdata; + InsetData *opdata = op->customdata; - opdata = op->customdata; + if (event->val == KM_PRESS) { + /* Try to handle numeric inputs... */ + float amounts[2]; - switch (event->type) { - case ESCKEY: - case RIGHTMOUSE: - edbm_inset_cancel(C, op); - return OPERATOR_CANCELLED; - - case MOUSEMOVE: - { - float mdiff[2]; - float amount; - - mdiff[0] = opdata->mcenter[0] - event->mval[0]; - mdiff[1] = opdata->mcenter[1] - event->mval[1]; - - if (opdata->modify_depth) { - amount = opdata->old_depth + (len_v2(mdiff) - opdata->initial_length) / opdata->initial_length; - RNA_float_set(op->ptr, "depth", amount); - } - else { - amount = opdata->old_thickness - (len_v2(mdiff) - opdata->initial_length) / opdata->initial_length; - amount = MAX2(amount, 0.0f); - - RNA_float_set(op->ptr, "thickness", amount); - } + if (handleNumInput(&opdata->num_input, event)) { + applyNumInput(&opdata->num_input, amounts); + amounts[0] = MAX2(amounts[0], 0.0f); + RNA_float_set(op->ptr, "thickness", amounts[0]); + RNA_float_set(op->ptr, "depth", amounts[1]); if (edbm_inset_calc(C, op)) { edbm_inset_update_header(op, C); @@ -4852,6 +4886,45 @@ static int edbm_inset_modal(bContext *C, wmOperator *op, wmEvent *event) return OPERATOR_CANCELLED; } } + } + switch (event->type) { + case ESCKEY: + case RIGHTMOUSE: + edbm_inset_cancel(C, op); + return OPERATOR_CANCELLED; + + case MOUSEMOVE: + if (!hasNumInput(&opdata->num_input)) { + float mdiff[2]; + float amount; + + mdiff[0] = opdata->mcenter[0] - event->mval[0]; + mdiff[1] = opdata->mcenter[1] - event->mval[1]; + + if (opdata->modify_depth) + amount = opdata->old_depth + len_v2(mdiff) / opdata->initial_length - 1.0f; + else + amount = opdata->old_thickness - len_v2(mdiff) / opdata->initial_length + 1.0f; + + /* Fake shift-transform... */ + if (opdata->shift) + amount = (amount - opdata->shift_amount) * 0.1f + opdata->shift_amount; + + if (opdata->modify_depth) + RNA_float_set(op->ptr, "depth", amount); + else { + amount = MAX2(amount, 0.0f); + RNA_float_set(op->ptr, "thickness", amount); + } + + if (edbm_inset_calc(C, op)) + edbm_inset_update_header(op, C); + else { + edbm_inset_cancel(C, op); + return OPERATOR_CANCELLED; + } + } + return OPERATOR_RUNNING_MODAL; case LEFTMOUSE: case PADENTER: @@ -4860,6 +4933,20 @@ static int edbm_inset_modal(bContext *C, wmOperator *op, wmEvent *event) edbm_inset_exit(C, op); return OPERATOR_FINISHED; + case LEFTSHIFTKEY: + case RIGHTSHIFTKEY: + if (event->val == KM_PRESS) { + if (opdata->modify_depth) + opdata->shift_amount = RNA_float_get(op->ptr, "depth"); + else + opdata->shift_amount = RNA_float_get(op->ptr, "thickness"); + opdata->shift = TRUE; + } + else { + opdata->shift_amount = 0.0f; + opdata->shift = FALSE; + } + return OPERATOR_RUNNING_MODAL; case LEFTCTRLKEY: case RIGHTCTRLKEY: @@ -4871,10 +4958,14 @@ static int edbm_inset_modal(bContext *C, wmOperator *op, wmEvent *event) if (event->val == KM_PRESS) { opdata->old_thickness = RNA_float_get(op->ptr, "thickness"); + if (opdata->shift) + opdata->shift_amount = opdata->old_thickness; opdata->modify_depth = TRUE; } else { opdata->old_depth = RNA_float_get(op->ptr, "depth"); + if (opdata->shift) + opdata->shift_amount = opdata->old_depth; opdata->modify_depth = FALSE; } opdata->initial_length = len_v2(mlen); diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c index b355e1ee436..e2752f5e828 100644 --- a/source/blender/editors/transform/transform.c +++ b/source/blender/editors/transform/transform.c @@ -2455,7 +2455,7 @@ int Warp(TransInfo *t, const int UNUSED(mval[2])) /* header print for NumInput */ if (hasNumInput(&t->num)) { - char c[20]; + char c[NUM_STR_REP_LEN]; outputNumInput(&(t->num), c); @@ -2584,7 +2584,7 @@ int Shear(TransInfo *t, const int UNUSED(mval[2])) /* header print for NumInput */ if (hasNumInput(&t->num)) { - char c[20]; + char c[NUM_STR_REP_LEN]; outputNumInput(&(t->num), c); @@ -2670,15 +2670,15 @@ void initResize(TransInfo *t) static void headerResize(TransInfo *t, float vec[3], char *str) { - char tvec[60]; + char tvec[NUM_STR_REP_LEN * 3]; char *spos = str; if (hasNumInput(&t->num)) { outputNumInput(&(t->num), tvec); } else { - BLI_snprintf(&tvec[0], 20, "%.4f", vec[0]); - BLI_snprintf(&tvec[20], 20, "%.4f", vec[1]); - BLI_snprintf(&tvec[40], 20, "%.4f", vec[2]); + BLI_snprintf(&tvec[0], NUM_STR_REP_LEN, "%.4f", vec[0]); + BLI_snprintf(&tvec[NUM_STR_REP_LEN], NUM_STR_REP_LEN, "%.4f", vec[1]); + BLI_snprintf(&tvec[NUM_STR_REP_LEN * 2], NUM_STR_REP_LEN, "%.4f", vec[2]); } if (t->con.mode & CON_APPLY) { @@ -2687,17 +2687,21 @@ static void headerResize(TransInfo *t, float vec[3], char *str) spos += sprintf(spos, "Scale: %s%s %s", &tvec[0], t->con.text, t->proptext); break; case 1: - spos += sprintf(spos, "Scale: %s : %s%s %s", &tvec[0], &tvec[20], t->con.text, t->proptext); + spos += sprintf(spos, "Scale: %s : %s%s %s", &tvec[0], &tvec[NUM_STR_REP_LEN], + t->con.text, t->proptext); break; case 2: - spos += sprintf(spos, "Scale: %s : %s : %s%s %s", &tvec[0], &tvec[20], &tvec[40], t->con.text, t->proptext); + spos += sprintf(spos, "Scale: %s : %s : %s%s %s", &tvec[0], &tvec[NUM_STR_REP_LEN], + &tvec[NUM_STR_REP_LEN * 2], t->con.text, t->proptext); } } else { if (t->flag & T_2D_EDIT) - spos += sprintf(spos, "Scale X: %s Y: %s%s %s", &tvec[0], &tvec[20], t->con.text, t->proptext); + spos += sprintf(spos, "Scale X: %s Y: %s%s %s", &tvec[0], &tvec[NUM_STR_REP_LEN], + t->con.text, t->proptext); else - spos += sprintf(spos, "Scale X: %s Y: %s Z: %s%s %s", &tvec[0], &tvec[20], &tvec[40], t->con.text, t->proptext); + spos += sprintf(spos, "Scale X: %s Y: %s Z: %s%s %s", &tvec[0], &tvec[NUM_STR_REP_LEN], + &tvec[NUM_STR_REP_LEN * 2], t->con.text, t->proptext); } if (t->flag & (T_PROP_EDIT | T_PROP_CONNECTED)) { @@ -3043,7 +3047,7 @@ int ToSphere(TransInfo *t, const int UNUSED(mval[2])) /* header print for NumInput */ if (hasNumInput(&t->num)) { - char c[20]; + char c[NUM_STR_REP_LEN]; outputNumInput(&(t->num), c); @@ -3389,7 +3393,7 @@ int Rotation(TransInfo *t, const int UNUSED(mval[2])) applySnapping(t, &final); if (hasNumInput(&t->num)) { - char c[20]; + char c[NUM_STR_REP_LEN]; applyNumInput(&t->num, &final); @@ -3488,13 +3492,13 @@ int Trackball(TransInfo *t, const int UNUSED(mval[2])) snapGrid(t, phi); if (hasNumInput(&t->num)) { - char c[40]; + char c[NUM_STR_REP_LEN * 2]; applyNumInput(&t->num, phi); outputNumInput(&(t->num), c); - spos += sprintf(spos, "Trackball: %s %s %s", &c[0], &c[20], t->proptext); + spos += sprintf(spos, "Trackball: %s %s %s", &c[0], &c[NUM_STR_REP_LEN], t->proptext); phi[0] = DEG2RADF(phi[0]); phi[1] = DEG2RADF(phi[1]); @@ -3573,9 +3577,9 @@ void initTranslation(TransInfo *t) static void headerTranslation(TransInfo *t, float vec[3], char *str) { char *spos = str; - char tvec[60]; - char distvec[20]; - char autoik[20]; + char tvec[NUM_STR_REP_LEN * 3]; + char distvec[NUM_STR_REP_LEN]; + char autoik[NUM_STR_REP_LEN]; float dist; if (hasNumInput(&t->num)) { @@ -3593,12 +3597,13 @@ static void headerTranslation(TransInfo *t, float vec[3], char *str) int i, do_split = t->scene->unit.flag & USER_UNIT_OPT_SPLIT ? 1 : 0; for (i = 0; i < 3; i++) - bUnit_AsString(&tvec[i * 20], 20, dvec[i] * t->scene->unit.scale_length, 4, t->scene->unit.system, B_UNIT_LENGTH, do_split, 1); + bUnit_AsString(&tvec[i * NUM_STR_REP_LEN], NUM_STR_REP_LEN, dvec[i] * t->scene->unit.scale_length, + 4, t->scene->unit.system, B_UNIT_LENGTH, do_split, 1); } else { sprintf(&tvec[0], "%.4f", dvec[0]); - sprintf(&tvec[20], "%.4f", dvec[1]); - sprintf(&tvec[40], "%.4f", dvec[2]); + sprintf(&tvec[NUM_STR_REP_LEN], "%.4f", dvec[1]); + sprintf(&tvec[NUM_STR_REP_LEN * 2], "%.4f", dvec[2]); } } @@ -3626,17 +3631,21 @@ static void headerTranslation(TransInfo *t, float vec[3], char *str) spos += sprintf(spos, "D: %s (%s)%s %s %s", &tvec[0], distvec, t->con.text, t->proptext, &autoik[0]); break; case 1: - spos += sprintf(spos, "D: %s D: %s (%s)%s %s %s", &tvec[0], &tvec[20], distvec, t->con.text, t->proptext, &autoik[0]); + spos += sprintf(spos, "D: %s D: %s (%s)%s %s %s", &tvec[0], &tvec[NUM_STR_REP_LEN], + distvec, t->con.text, t->proptext, &autoik[0]); break; case 2: - spos += sprintf(spos, "D: %s D: %s D: %s (%s)%s %s %s", &tvec[0], &tvec[20], &tvec[40], distvec, t->con.text, t->proptext, &autoik[0]); + spos += sprintf(spos, "D: %s D: %s D: %s (%s)%s %s %s", &tvec[0], &tvec[NUM_STR_REP_LEN], + &tvec[NUM_STR_REP_LEN * 2], distvec, t->con.text, t->proptext, &autoik[0]); } } else { if (t->flag & T_2D_EDIT) - spos += sprintf(spos, "Dx: %s Dy: %s (%s)%s %s", &tvec[0], &tvec[20], distvec, t->con.text, t->proptext); + spos += sprintf(spos, "Dx: %s Dy: %s (%s)%s %s", &tvec[0], &tvec[NUM_STR_REP_LEN], + distvec, t->con.text, t->proptext); else - spos += sprintf(spos, "Dx: %s Dy: %s Dz: %s (%s)%s %s %s", &tvec[0], &tvec[20], &tvec[40], distvec, t->con.text, t->proptext, &autoik[0]); + spos += sprintf(spos, "Dx: %s Dy: %s Dz: %s (%s)%s %s %s", &tvec[0], &tvec[NUM_STR_REP_LEN], + &tvec[NUM_STR_REP_LEN * 2], distvec, t->con.text, t->proptext, &autoik[0]); } if (t->flag & (T_PROP_EDIT | T_PROP_CONNECTED)) { @@ -3794,7 +3803,7 @@ int ShrinkFatten(TransInfo *t, const int UNUSED(mval[2])) /* header print for NumInput */ if (hasNumInput(&t->num)) { - char c[20]; + char c[NUM_STR_REP_LEN]; outputNumInput(&(t->num), c); @@ -3863,7 +3872,7 @@ int Tilt(TransInfo *t, const int UNUSED(mval[2])) snapGrid(t, &final); if (hasNumInput(&t->num)) { - char c[20]; + char c[NUM_STR_REP_LEN]; applyNumInput(&t->num, &final); @@ -3935,7 +3944,7 @@ int CurveShrinkFatten(TransInfo *t, const int UNUSED(mval[2])) /* header print for NumInput */ if (hasNumInput(&t->num)) { - char c[20]; + char c[NUM_STR_REP_LEN]; outputNumInput(&(t->num), c); sprintf(str, "Shrink/Fatten: %s", c); @@ -4003,7 +4012,7 @@ int MaskShrinkFatten(TransInfo *t, const int UNUSED(mval[2])) /* header print for NumInput */ if (hasNumInput(&t->num)) { - char c[20]; + char c[NUM_STR_REP_LEN]; outputNumInput(&(t->num), c); sprintf(str, "Shrink/Fatten: %s", c); @@ -4069,7 +4078,7 @@ int PushPull(TransInfo *t, const int UNUSED(mval[2])) /* header print for NumInput */ if (hasNumInput(&t->num)) { - char c[20]; + char c[NUM_STR_REP_LEN]; outputNumInput(&(t->num), c); @@ -4205,7 +4214,7 @@ int Bevel(TransInfo *t, const int UNUSED(mval[2])) /* header print for NumInput */ if (hasNumInput(&t->num)) { - char c[20]; + char c[NUM_STR_REP_LEN]; outputNumInput(&(t->num), c); @@ -4272,7 +4281,7 @@ int BevelWeight(TransInfo *t, const int UNUSED(mval[2])) /* header print for NumInput */ if (hasNumInput(&t->num)) { - char c[20]; + char c[NUM_STR_REP_LEN]; outputNumInput(&(t->num), c); @@ -4345,7 +4354,7 @@ int Crease(TransInfo *t, const int UNUSED(mval[2])) /* header print for NumInput */ if (hasNumInput(&t->num)) { - char c[20]; + char c[NUM_STR_REP_LEN]; outputNumInput(&(t->num), c); @@ -4405,14 +4414,14 @@ void initBoneSize(TransInfo *t) static void headerBoneSize(TransInfo *t, float vec[3], char *str) { - char tvec[60]; + char tvec[NUM_STR_REP_LEN * 3]; if (hasNumInput(&t->num)) { outputNumInput(&(t->num), tvec); } else { sprintf(&tvec[0], "%.4f", vec[0]); - sprintf(&tvec[20], "%.4f", vec[1]); - sprintf(&tvec[40], "%.4f", vec[2]); + sprintf(&tvec[NUM_STR_REP_LEN], "%.4f", vec[1]); + sprintf(&tvec[NUM_STR_REP_LEN * 2], "%.4f", vec[2]); } /* hmm... perhaps the y-axis values don't need to be shown? */ @@ -4420,10 +4429,12 @@ static void headerBoneSize(TransInfo *t, float vec[3], char *str) if (t->num.idx_max == 0) sprintf(str, "ScaleB: %s%s %s", &tvec[0], t->con.text, t->proptext); else - sprintf(str, "ScaleB: %s : %s : %s%s %s", &tvec[0], &tvec[20], &tvec[40], t->con.text, t->proptext); + sprintf(str, "ScaleB: %s : %s : %s%s %s", &tvec[0], &tvec[NUM_STR_REP_LEN], &tvec[NUM_STR_REP_LEN * 2], + t->con.text, t->proptext); } else { - sprintf(str, "ScaleB X: %s Y: %s Z: %s%s %s", &tvec[0], &tvec[20], &tvec[40], t->con.text, t->proptext); + sprintf(str, "ScaleB X: %s Y: %s Z: %s%s %s", &tvec[0], &tvec[NUM_STR_REP_LEN], &tvec[NUM_STR_REP_LEN * 2], + t->con.text, t->proptext); } } @@ -4536,7 +4547,7 @@ int BoneEnvelope(TransInfo *t, const int UNUSED(mval[2])) /* header print for NumInput */ if (hasNumInput(&t->num)) { - char c[20]; + char c[NUM_STR_REP_LEN]; outputNumInput(&(t->num), c); sprintf(str, "Envelope: %s", c); @@ -5428,7 +5439,7 @@ int EdgeSlide(TransInfo *t, const int UNUSED(mval[2])) CLAMP(final, -1.0f, 1.0f); if (hasNumInput(&t->num)) { - char c[20]; + char c[NUM_STR_REP_LEN]; applyNumInput(&t->num, &final); @@ -5494,7 +5505,7 @@ int BoneRoll(TransInfo *t, const int UNUSED(mval[2])) snapGrid(t, &final); if (hasNumInput(&t->num)) { - char c[20]; + char c[NUM_STR_REP_LEN]; applyNumInput(&t->num, &final); @@ -5566,7 +5577,7 @@ int BakeTime(TransInfo *t, const int mval[2]) /* header print for NumInput */ if (hasNumInput(&t->num)) { - char c[20]; + char c[NUM_STR_REP_LEN]; outputNumInput(&(t->num), c); @@ -5759,7 +5770,7 @@ void initSeqSlide(TransInfo *t) static void headerSeqSlide(TransInfo *t, float val[2], char *str) { - char tvec[60]; + char tvec[NUM_STR_REP_LEN * 3]; if (hasNumInput(&t->num)) { outputNumInput(&(t->num), tvec); @@ -6002,7 +6013,7 @@ void initTimeTranslate(TransInfo *t) static void headerTimeTranslate(TransInfo *t, char *str) { - char tvec[60]; + char tvec[NUM_STR_REP_LEN * 3]; /* if numeric input is active, use results from that, otherwise apply snapping to result */ if (hasNumInput(&t->num)) { @@ -6157,7 +6168,7 @@ void initTimeSlide(TransInfo *t) static void headerTimeSlide(TransInfo *t, float sval, char *str) { - char tvec[60]; + char tvec[NUM_STR_REP_LEN * 3]; if (hasNumInput(&t->num)) { outputNumInput(&(t->num), tvec); @@ -6299,7 +6310,7 @@ void initTimeScale(TransInfo *t) static void headerTimeScale(TransInfo *t, char *str) { - char tvec[60]; + char tvec[NUM_STR_REP_LEN * 3]; if (hasNumInput(&t->num)) outputNumInput(&(t->num), tvec); diff --git a/source/blender/editors/util/numinput.c b/source/blender/editors/util/numinput.c index 91290829662..281b682465d 100644 --- a/source/blender/editors/util/numinput.c +++ b/source/blender/editors/util/numinput.c @@ -66,6 +66,7 @@ void outputNumInput(NumInput *n, char *str) char cur; char inv[] = "1/"; short i, j; + const int ln = NUM_STR_REP_LEN; for (j = 0; j <= n->idx_max; j++) { /* if AFFECTALL and no number typed and cursor not on number, use first number */ @@ -85,34 +86,34 @@ void outputNumInput(NumInput *n, char *str) inv[0] = 0; if (n->val[i] > 1e10f || n->val[i] < -1e10f) - BLI_snprintf(&str[j * 20], 20, "%s%.4e%c", inv, n->val[i], cur); + BLI_snprintf(&str[j * ln], ln, "%s%.4e%c", inv, n->val[i], cur); else switch (n->ctrl[i]) { case 0: - BLI_snprintf(&str[j * 20], 20, "%sNONE%c", inv, cur); + BLI_snprintf(&str[j * ln], ln, "%sNONE%c", inv, cur); break; case 1: case -1: - BLI_snprintf(&str[j * 20], 20, "%s%.0f%c", inv, n->val[i], cur); + BLI_snprintf(&str[j * ln], ln, "%s%.0f%c", inv, n->val[i], cur); break; case 10: case -10: - BLI_snprintf(&str[j * 20], 20, "%s%.f.%c", inv, n->val[i], cur); + BLI_snprintf(&str[j * ln], ln, "%s%.f.%c", inv, n->val[i], cur); break; case 100: case -100: - BLI_snprintf(&str[j * 20], 20, "%s%.1f%c", inv, n->val[i], cur); + BLI_snprintf(&str[j * ln], ln, "%s%.1f%c", inv, n->val[i], cur); break; case 1000: case -1000: - BLI_snprintf(&str[j * 20], 20, "%s%.2f%c", inv, n->val[i], cur); + BLI_snprintf(&str[j * ln], ln, "%s%.2f%c", inv, n->val[i], cur); break; case 10000: case -10000: - BLI_snprintf(&str[j * 20], 20, "%s%.3f%c", inv, n->val[i], cur); + BLI_snprintf(&str[j * ln], ln, "%s%.3f%c", inv, n->val[i], cur); break; default: - BLI_snprintf(&str[j * 20], 20, "%s%.4e%c", inv, n->val[i], cur); + BLI_snprintf(&str[j * ln], ln, "%s%.4e%c", inv, n->val[i], cur); } } } From fc3cd6eb801d6c9a6a95d63198f0c815d4deb072 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sat, 14 Jul 2012 15:29:05 +0000 Subject: [PATCH 008/108] replace masking rasterizer with a more simple geometry based rasterizer (for the compositor). notes: - uncomment #define USE_RASKTER in BKE_mask.h to use the previous mask rasterizer. - slightly slower for regular masks but significantly faster for feather. - main benefit is that it threads well so works nice for tile compositor. - feather is lower quality, can use some improvements here. - feather can also use some interpolation enhancements, will do later. --- source/blender/blenkernel/BKE_mask.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/blenkernel/BKE_mask.h b/source/blender/blenkernel/BKE_mask.h index 50d8576dd91..5038ac5eb1b 100644 --- a/source/blender/blenkernel/BKE_mask.h +++ b/source/blender/blenkernel/BKE_mask.h @@ -206,7 +206,7 @@ void BKE_mask_init_layers(Mask *mask, struct layer_init_data *mlayer_data, int w #define MASKPOINT_DESEL_HANDLE(p) { (p)->bezt.f1 &= ~SELECT; (p)->bezt.f3 &= ~SELECT; } (void)0 /* disable to test alternate rasterizer */ -#define USE_RASKTER +/* #define USE_RASKTER */ /* mask_rasterize.c */ #ifndef USE_RASKTER From e4cfcdc3a601b6f2114000075cc0541930adcec6 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sat, 14 Jul 2012 15:29:45 +0000 Subject: [PATCH 009/108] header comment cleanup, explain whats the difference between confusingly named drarnode.c and node_draw.c. --- intern/guardedalloc/MEM_guardedalloc.h | 29 ++++++++++--------- intern/guardedalloc/intern/mallocn.c | 7 ++--- source/blender/blenlib/BLI_mempool.h | 2 +- source/blender/editors/space_node/drawnode.c | 2 +- source/blender/editors/space_node/node_draw.c | 2 +- 5 files changed, 22 insertions(+), 20 deletions(-) diff --git a/intern/guardedalloc/MEM_guardedalloc.h b/intern/guardedalloc/MEM_guardedalloc.h index dfb3fe69474..65ce7baba1e 100644 --- a/intern/guardedalloc/MEM_guardedalloc.h +++ b/intern/guardedalloc/MEM_guardedalloc.h @@ -20,19 +20,19 @@ * * The Original Code is: all of this file. * - * Contributor(s): none yet. + * Contributor(s): Brecht Van Lommel + * Campbell Barton * * ***** END GPL LICENSE BLOCK ***** */ -/** \file MEM_guardedalloc.h - * \ingroup MEM +/** + * \file MEM_guardedalloc.h + * \ingroup MEM + * + * \author Copyright (C) 2001 NaN Technologies B.V. + * \brief Read \ref MEMPage * - * \author Copyright (C) 2001 NaN Technologies B.V. - * \brief Read \ref MEMPage - */ - -/** * \page MEMPage Guarded memory(de)allocation * * \section aboutmem c-style guarded memory allocation @@ -118,8 +118,9 @@ extern "C" { __attribute__((alloc_size(1))) #endif ; - - /** Allocate a block of memory of size len, with tag name str. The + + /** + * Allocate a block of memory of size len, with tag name str. The * name must be a static, because only a pointer to it is stored ! * */ void *MEM_mallocN(size_t len, const char *str) @@ -129,8 +130,9 @@ extern "C" { __attribute__((alloc_size(1))) #endif ; - - /** Same as callocN, clears memory and uses mmap (disk cached) if supported. + + /** + * Same as callocN, clears memory and uses mmap (disk cached) if supported. * Can be free'd with MEM_freeN as usual. * */ void *MEM_mapallocN(size_t len, const char *str) @@ -171,7 +173,8 @@ extern "C" { /** Attempt to enforce OSX (or other OS's) to have malloc and stack nonzero */ void MEM_set_memory_debug(void); - /** Memory usage stats + /** + * Memory usage stats * - MEM_get_memory_in_use is all memory * - MEM_get_mapped_memory_in_use is a subset of all memory */ uintptr_t MEM_get_memory_in_use(void); diff --git a/intern/guardedalloc/intern/mallocn.c b/intern/guardedalloc/intern/mallocn.c index 7eda5a3ab5e..76df58f4a50 100644 --- a/intern/guardedalloc/intern/mallocn.c +++ b/intern/guardedalloc/intern/mallocn.c @@ -20,7 +20,8 @@ * * The Original Code is: all of this file. * - * Contributor(s): none yet. + * Contributor(s): Brecht Van Lommel + * Campbell Barton * * ***** END GPL LICENSE BLOCK ***** */ @@ -904,6 +905,4 @@ const char *MEM_name_ptr(void *vmemh) return "MEM_name_ptr(NULL)"; } } -#endif - -/* eof */ +#endif /* NDEBUG */ diff --git a/source/blender/blenlib/BLI_mempool.h b/source/blender/blenlib/BLI_mempool.h index c773cfbe680..8fd2166e6f8 100644 --- a/source/blender/blenlib/BLI_mempool.h +++ b/source/blender/blenlib/BLI_mempool.h @@ -31,7 +31,7 @@ /** \file BLI_mempool.h * \ingroup bli * \author Geoffrey Bantle - * \brief Simple fast memory allocator. + * \brief Simple fast memory allocator for fixed size chunks. */ #ifdef __cplusplus diff --git a/source/blender/editors/space_node/drawnode.c b/source/blender/editors/space_node/drawnode.c index c4b9d5989e1..2a5739db56f 100644 --- a/source/blender/editors/space_node/drawnode.c +++ b/source/blender/editors/space_node/drawnode.c @@ -27,9 +27,9 @@ /** \file blender/editors/space_node/drawnode.c * \ingroup spnode + * \brief lower level node drawing for nodes (boarders, headers etc), also node layout. */ - #include #include #include diff --git a/source/blender/editors/space_node/node_draw.c b/source/blender/editors/space_node/node_draw.c index adf52313307..708d7e0b5e6 100644 --- a/source/blender/editors/space_node/node_draw.c +++ b/source/blender/editors/space_node/node_draw.c @@ -26,9 +26,9 @@ /** \file blender/editors/space_node/node_draw.c * \ingroup spnode + * \brief higher level node drawing for the node editor. */ - #include #include #include From e144e7a82cdeb4288c3804c59473a501cc2477af Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sat, 14 Jul 2012 15:46:32 +0000 Subject: [PATCH 010/108] minor refactor for mask rasterizer --- .../blenkernel/intern/mask_rasterize.c | 320 +++++++++--------- 1 file changed, 166 insertions(+), 154 deletions(-) diff --git a/source/blender/blenkernel/intern/mask_rasterize.c b/source/blender/blenkernel/intern/mask_rasterize.c index 5259fb496d1..2f56e28c1a2 100644 --- a/source/blender/blenkernel/intern/mask_rasterize.c +++ b/source/blender/blenkernel/intern/mask_rasterize.c @@ -46,6 +46,15 @@ #ifndef USE_RASKTER +#define SPLINE_RESOL 32 + +#define SF_EDGE_IS_BOUNDARY 0xff +#define SF_KEYINDEX_TEMP_ID ((unsigned int) -1) + +#define TRI_TERMINATOR_ID ((unsigned int) -1) +#define TRI_VERT ((unsigned int) -1) + + /** * A single #MaskRasterHandle contains multile #MaskRasterLayer's, * each #MaskRasterLayer does its own lookup which contributes to @@ -82,6 +91,11 @@ typedef struct MaskRasterLayer { static void layer_bucket_init(MaskRasterLayer *layer); + +/* --------------------------------------------------------------------- */ +/* alloc / free functions */ +/* --------------------------------------------------------------------- */ + /** * opaque local struct for mask pixel lookup, each MaskLayer needs one of these */ @@ -137,15 +151,6 @@ void BLI_maskrasterize_handle_free(MaskRasterHandle *mr_handle) MEM_freeN(mr_handle); } -#define RESOL 32 - -#define PRINT_MASK_DEBUG printf - -#define SF_EDGE_IS_BOUNDARY 0xff - -#define SF_KEYINDEX_TEMP_ID ((unsigned int) -1) -#define TRI_TERMINATOR_ID ((unsigned int) -1) - void maskrasterize_spline_differentiate_point_inset(float (*diff_feather_points)[2], float (*diff_points)[2], const unsigned int tot_diff_point, const float ofs, @@ -208,7 +213,117 @@ void maskrasterize_spline_differentiate_point_inset(float (*diff_feather_points) } } -#define TRI_VERT ((unsigned int) -1) + +static void layer_bucket_init(MaskRasterLayer *layer) +{ + MemArena *arena = BLI_memarena_new(1 << 16, __func__); + + /* TODO - calculate best bucket size */ + layer->buckets_x = 256; + layer->buckets_y = 256; + + layer->buckets_xy_scalar[0] = (1.0f / ((layer->bounds.xmax - layer->bounds.xmin) + FLT_EPSILON)) * layer->buckets_x; + layer->buckets_xy_scalar[1] = (1.0f / ((layer->bounds.ymax - layer->bounds.ymin) + FLT_EPSILON)) * layer->buckets_y; + + { + unsigned int *tri = &layer->tri_array[0][0]; + float (*cos)[3] = layer->tri_coords; + + const unsigned int bucket_tot = layer->buckets_x * layer->buckets_y; + LinkNode **bucketstore = MEM_callocN(bucket_tot * sizeof(LinkNode *), __func__); + unsigned int *bucketstore_tot = MEM_callocN(bucket_tot * sizeof(unsigned int), __func__); + + unsigned int tri_index; + + for (tri_index = 0; tri_index < layer->tri_tot; tri_index++, tri += 4) { + float xmin; + float xmax; + float ymin; + float ymax; + + if (tri[3] == TRI_VERT) { + const float *v1 = cos[tri[0]]; + const float *v2 = cos[tri[1]]; + const float *v3 = cos[tri[2]]; + + xmin = fminf(v1[0], fminf(v2[0], v3[0])); + xmax = fmaxf(v1[0], fmaxf(v2[0], v3[0])); + ymin = fminf(v1[1], fminf(v2[1], v3[1])); + ymax = fmaxf(v1[1], fmaxf(v2[1], v3[1])); + } + else { + const float *v1 = cos[tri[0]]; + const float *v2 = cos[tri[1]]; + const float *v3 = cos[tri[2]]; + const float *v4 = cos[tri[3]]; + + xmin = fminf(v1[0], fminf(v2[0], fminf(v3[0], v4[0]))); + xmax = fmaxf(v1[0], fmaxf(v2[0], fmaxf(v3[0], v4[0]))); + ymin = fminf(v1[1], fminf(v2[1], fminf(v3[1], v4[1]))); + ymax = fmaxf(v1[1], fmaxf(v2[1], fmaxf(v3[1], v4[1]))); + } + + + /* not essential but may as will skip any faces outside the view */ + if (!((xmax < 0.0f) || (ymax < 0.0f) || (xmin > 1.0f) || (ymin > 1.0f))) { + const unsigned int xi_min = (unsigned int) ((xmin - layer->bounds.xmin) * layer->buckets_xy_scalar[0]); + 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]); + + 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; + + 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(tri_index), + arena); + + bucketstore_tot[bucket_index]++; + } + } + } + } + + if (1) { + /* now convert linknodes into arrays for faster per pixel access */ + unsigned int **buckets_tri = MEM_mallocN(bucket_tot * sizeof(unsigned int **), __func__); + unsigned int bucket_index; + + for (bucket_index = 0; bucket_index < bucket_tot; bucket_index++) { + if (bucketstore_tot[bucket_index]) { + unsigned int *bucket = MEM_mallocN((bucketstore_tot[bucket_index] + 1) * sizeof(unsigned int), + __func__); + LinkNode *bucket_node; + + buckets_tri[bucket_index] = bucket; + + for (bucket_node = bucketstore[bucket_index]; bucket_node; bucket_node = bucket_node->next) { + *bucket = GET_UINT_FROM_POINTER(bucket_node->link); + bucket++; + } + *bucket = TRI_TERMINATOR_ID; + } + else { + buckets_tri[bucket_index] = NULL; + } + } + + layer->buckets_tri = buckets_tri; + } + + MEM_freeN(bucketstore); + MEM_freeN(bucketstore_tot); + } + + BLI_memarena_free(arena); +} void BLI_maskrasterize_handle_init(MaskRasterHandle *mr_handle, struct Mask *mask, const int width, const int height, @@ -216,8 +331,8 @@ void BLI_maskrasterize_handle_init(MaskRasterHandle *mr_handle, struct Mask *mas const short do_feather) { /* TODO: real size */ - const int resol = RESOL; - const float aa_filter_size = 1.0f / MIN2(width, height); + const int resol = SPLINE_RESOL; + const float pixel_size = 1.0f / MIN2(width, height); const float zvec[3] = {0.0f, 0.0f, 1.0f}; MaskLayer *masklay; @@ -254,11 +369,13 @@ void BLI_maskrasterize_handle_init(MaskRasterHandle *mr_handle, struct Mask *mas float (*diff_feather_points)[2]; int tot_diff_feather_points; - diff_points = BKE_mask_spline_differentiate_with_resolution_ex(spline, resol, &tot_diff_point); + diff_points = BKE_mask_spline_differentiate_with_resolution_ex( + spline, resol, &tot_diff_point); /* dont ch*/ if (do_feather) { - diff_feather_points = BKE_mask_spline_feather_differentiated_points_with_resolution_ex(spline, resol, &tot_diff_feather_points); + diff_feather_points = BKE_mask_spline_feather_differentiated_points_with_resolution_ex( + spline, resol, &tot_diff_feather_points); } else { tot_diff_feather_points = 0; @@ -306,15 +423,16 @@ void BLI_maskrasterize_handle_init(MaskRasterHandle *mr_handle, struct Mask *mas if (do_mask_aa == TRUE) { if (do_feather == FALSE) { tot_diff_feather_points = tot_diff_point; - diff_feather_points = MEM_mallocN(sizeof(*diff_feather_points) * tot_diff_feather_points, __func__); + diff_feather_points = MEM_mallocN(sizeof(*diff_feather_points) * tot_diff_feather_points, + __func__); /* add single pixel feather */ maskrasterize_spline_differentiate_point_inset(diff_feather_points, diff_points, - tot_diff_point, aa_filter_size, FALSE); + tot_diff_point, pixel_size, FALSE); } else { /* ensure single pixel feather, on any zero feather areas */ maskrasterize_spline_differentiate_point_inset(diff_feather_points, diff_points, - tot_diff_point, aa_filter_size, TRUE); + tot_diff_point, pixel_size, TRUE); } } @@ -471,7 +589,7 @@ void BLI_maskrasterize_handle_init(MaskRasterHandle *mr_handle, struct Mask *mas BLI_union_rctf(&mr_handle->bounds, &bounds); } - PRINT_MASK_DEBUG("tris %d, feather tris %d\n", sf_tri_tot, tot_feather_quads); + /* printf("tris %d, feather tris %d\n", sf_tri_tot, tot_feather_quads); */ } /* add trianges */ @@ -479,6 +597,11 @@ void BLI_maskrasterize_handle_init(MaskRasterHandle *mr_handle, struct Mask *mas } } + +/* --------------------------------------------------------------------- */ +/* functions that run inside the sampling thread (keep fast!) */ +/* --------------------------------------------------------------------- */ + /* 2D ray test */ static float maskrasterize_layer_z_depth_tri(const float pt[2], const float v1[3], const float v2[3], const float v3[3]) @@ -516,7 +639,7 @@ static float maskrasterize_layer_isect(unsigned int *tri, float (*cos)[3], const } } #else - /* we know all tris are close for now */ + /* we know all tris are close for now */ if (1) { if (isect_point_tri_v2(xy, cos[tri[0]], cos[tri[1]], cos[tri[2]])) { return 0.0f; @@ -556,116 +679,6 @@ static float maskrasterize_layer_isect(unsigned int *tri, float (*cos)[3], const return 1.0f; } -static void layer_bucket_init(MaskRasterLayer *layer) -{ - MemArena *arena = BLI_memarena_new(1 << 16, __func__); - - /* TODO - calculate best bucket size */ - layer->buckets_x = 256; - layer->buckets_y = 256; - - layer->buckets_xy_scalar[0] = (1.0f / ((layer->bounds.xmax - layer->bounds.xmin) + FLT_EPSILON)) * layer->buckets_x; - layer->buckets_xy_scalar[1] = (1.0f / ((layer->bounds.ymax - layer->bounds.ymin) + FLT_EPSILON)) * layer->buckets_y; - - { - unsigned int *tri = &layer->tri_array[0][0]; - float (*cos)[3] = layer->tri_coords; - - const unsigned int bucket_tot = layer->buckets_x * layer->buckets_y; - LinkNode **bucketstore = MEM_callocN(bucket_tot * sizeof(LinkNode *), __func__); - unsigned int *bucketstore_tot = MEM_callocN(bucket_tot * sizeof(unsigned int), __func__); - - unsigned int tri_index; - - for (tri_index = 0; tri_index < layer->tri_tot; tri_index++, tri += 4) { - float xmin; - float xmax; - float ymin; - float ymax; - - if (tri[3] == TRI_VERT) { - const float *v1 = cos[tri[0]]; - const float *v2 = cos[tri[1]]; - const float *v3 = cos[tri[2]]; - - xmin = fminf(v1[0], fminf(v2[0], v3[0])); - xmax = fmaxf(v1[0], fmaxf(v2[0], v3[0])); - ymin = fminf(v1[1], fminf(v2[1], v3[1])); - ymax = fmaxf(v1[1], fmaxf(v2[1], v3[1])); - } - else { - const float *v1 = cos[tri[0]]; - const float *v2 = cos[tri[1]]; - const float *v3 = cos[tri[2]]; - const float *v4 = cos[tri[3]]; - - xmin = fminf(v1[0], fminf(v2[0], fminf(v3[0], v4[0]))); - xmax = fmaxf(v1[0], fmaxf(v2[0], fmaxf(v3[0], v4[0]))); - ymin = fminf(v1[1], fminf(v2[1], fminf(v3[1], v4[1]))); - ymax = fmaxf(v1[1], fmaxf(v2[1], fmaxf(v3[1], v4[1]))); - } - - - /* not essential but may as will skip any faces outside the view */ - if (!((xmax < 0.0f) || (ymax < 0.0f) || (xmin > 1.0f) || (ymin > 1.0f))) { - const unsigned int xi_min = (unsigned int) ((xmin - layer->bounds.xmin) * layer->buckets_xy_scalar[0]); - 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]); - - 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; - - 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(tri_index), - arena); - - bucketstore_tot[bucket_index]++; - } - } - } - } - - if (1) { - /* now convert linknodes into arrays for faster per pixel access */ - unsigned int **buckets_tri = MEM_mallocN(bucket_tot * sizeof(unsigned int **), __func__); - unsigned int bucket_index; - - for (bucket_index = 0; bucket_index < bucket_tot; bucket_index++) { - if (bucketstore_tot[bucket_index]) { - unsigned int *bucket = MEM_mallocN((bucketstore_tot[bucket_index] + 1) * sizeof(unsigned int), __func__); - LinkNode *bucket_node; - - buckets_tri[bucket_index] = bucket; - - for (bucket_node = bucketstore[bucket_index]; bucket_node; bucket_node = bucket_node->next) { - *bucket = GET_UINT_FROM_POINTER(bucket_node->link); - bucket++; - } - *bucket = TRI_TERMINATOR_ID; - } - else { - buckets_tri[bucket_index] = NULL; - } - } - - layer->buckets_tri = buckets_tri; - } - - MEM_freeN(bucketstore); - MEM_freeN(bucketstore_tot); - } - - BLI_memarena_free(arena); -} - static unsigned int layer_bucket_index_from_xy(MaskRasterLayer *layer, const float xy[2]) { BLI_assert(BLI_in_rctf_v(&layer->bounds, xy)); @@ -687,9 +700,9 @@ static float layer_bucket_depth_from_xy(MaskRasterLayer *layer, const float xy[2 unsigned int *tri = layer->tri_array[*tri_index]; if ((test_dist = maskrasterize_layer_isect(tri, cos, best_dist, xy)) < best_dist) { best_dist = test_dist; - /* comparing with 0.0f is OK here because triangles are always zero depth */ + /* comparing with 0.0f is OK here because triangles are always zero depth */ if (best_dist == 0.0f) { - /* bail early, we're as close as possible */ + /* bail early, we're as close as possible */ return 0.0f; } } @@ -702,7 +715,6 @@ static float layer_bucket_depth_from_xy(MaskRasterLayer *layer, const float xy[2 } } - float BLI_maskrasterize_handle_sample(MaskRasterHandle *mr_handle, const float xy[2]) { if (BLI_in_rctf_v(&mr_handle->bounds, xy)) { @@ -717,31 +729,31 @@ float BLI_maskrasterize_handle_sample(MaskRasterHandle *mr_handle, const float x for (i = 0; i < layers_tot; i++, layer++) { if (BLI_in_rctf_v(&layer->bounds, xy)) { - /* --- hit (start) --- */ - const float dist = 1.0f - layer_bucket_depth_from_xy(layer, xy); - const float dist_ease = (3.0f * dist * dist - 2.0f * dist * dist * dist); + /* --- hit (start) --- */ + const float dist = 1.0f - layer_bucket_depth_from_xy(layer, xy); + const float dist_ease = (3.0f * dist * dist - 2.0f * dist * dist * dist); - float v; - /* apply alpha */ - v = dist_ease * layer->alpha; + float v; + /* apply alpha */ + v = dist_ease * layer->alpha; - if (layer->blend_flag & MASK_BLENDFLAG_INVERT) { - v = 1.0f - v; - } + if (layer->blend_flag & MASK_BLENDFLAG_INVERT) { + v = 1.0f - v; + } - switch (layer->blend) { - case MASK_BLEND_SUBTRACT: - { - value -= v; - break; - } - case MASK_BLEND_ADD: - default: - { - value += v; - break; - } - } + switch (layer->blend) { + case MASK_BLEND_SUBTRACT: + { + value -= v; + break; + } + case MASK_BLEND_ADD: + default: + { + value += v; + break; + } + } /* --- hit (end) --- */ } From 1cbc6a6b4bab49774a91ecce14630717cbab763f Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sat, 14 Jul 2012 16:03:03 +0000 Subject: [PATCH 011/108] minor refactor, some comments and var names were misleading. --- .../blenkernel/intern/mask_rasterize.c | 182 +++++++++--------- 1 file changed, 92 insertions(+), 90 deletions(-) diff --git a/source/blender/blenkernel/intern/mask_rasterize.c b/source/blender/blenkernel/intern/mask_rasterize.c index 2f56e28c1a2..855dd2a2921 100644 --- a/source/blender/blenkernel/intern/mask_rasterize.c +++ b/source/blender/blenkernel/intern/mask_rasterize.c @@ -55,6 +55,10 @@ #define TRI_VERT ((unsigned int) -1) +/* --------------------------------------------------------------------- */ +/* local structs for mask rasterizeing */ +/* --------------------------------------------------------------------- */ + /** * A single #MaskRasterHandle contains multile #MaskRasterLayer's, * each #MaskRasterLayer does its own lookup which contributes to @@ -64,19 +68,19 @@ /* internal use only */ typedef struct MaskRasterLayer { /* geometry */ - unsigned int tri_tot; - unsigned int (*tri_array)[4]; /* access coords tri/quad */ - float (*tri_coords)[3]; /* xy, z 0-1 (1.0 == filled) */ + unsigned int face_tot; + unsigned int (*face_array)[4]; /* access coords tri/quad */ + float (*face_coords)[3]; /* xy, z 0-1 (1.0 == filled) */ - /* 2d bounds (to quickly skip raytree lookup) */ + /* 2d bounds (to quickly skip bucket lookup) */ rctf bounds; /* buckets */ - unsigned int **buckets_tri; + unsigned int **buckets_face; /* cache divide and subtract */ - float buckets_xy_scalar[2]; /* 1.0 / (buckets_width + FLT_EPSILON) */ + float buckets_xy_scalar[2]; /* (1.0 / (buckets_width + FLT_EPSILON)) * buckets_x */ unsigned int buckets_x; unsigned int buckets_y; @@ -89,13 +93,6 @@ typedef struct MaskRasterLayer { } MaskRasterLayer; -static void layer_bucket_init(MaskRasterLayer *layer); - - -/* --------------------------------------------------------------------- */ -/* alloc / free functions */ -/* --------------------------------------------------------------------- */ - /** * opaque local struct for mask pixel lookup, each MaskLayer needs one of these */ @@ -103,10 +100,15 @@ struct MaskRasterHandle { MaskRasterLayer *layers; unsigned int layers_tot; - /* 2d bounds (to quickly skip raytree lookup) */ + /* 2d bounds (to quickly skip bucket lookup) */ rctf bounds; }; + +/* --------------------------------------------------------------------- */ +/* alloc / free functions */ +/* --------------------------------------------------------------------- */ + MaskRasterHandle *BLI_maskrasterize_handle_new(void) { MaskRasterHandle *mr_handle; @@ -125,25 +127,25 @@ void BLI_maskrasterize_handle_free(MaskRasterHandle *mr_handle) /* raycast vars */ for (i = 0; i < layers_tot; i++, raslayers++) { - if (raslayers->tri_array) { - MEM_freeN(raslayers->tri_array); + if (raslayers->face_array) { + MEM_freeN(raslayers->face_array); } - if (raslayers->tri_coords) { - MEM_freeN(raslayers->tri_coords); + if (raslayers->face_coords) { + MEM_freeN(raslayers->face_coords); } - if (raslayers->buckets_tri) { + if (raslayers->buckets_face) { const unsigned int bucket_tot = raslayers->buckets_x * raslayers->buckets_y; unsigned int bucket_index; for (bucket_index = 0; bucket_index < bucket_tot; bucket_index++) { - unsigned int *tri_index = raslayers->buckets_tri[bucket_index]; - if (tri_index) { - MEM_freeN(tri_index); + unsigned int *face_index = raslayers->buckets_face[bucket_index]; + if (face_index) { + MEM_freeN(face_index); } } - MEM_freeN(raslayers->buckets_tri); + MEM_freeN(raslayers->buckets_face); } } @@ -226,25 +228,25 @@ static void layer_bucket_init(MaskRasterLayer *layer) layer->buckets_xy_scalar[1] = (1.0f / ((layer->bounds.ymax - layer->bounds.ymin) + FLT_EPSILON)) * layer->buckets_y; { - unsigned int *tri = &layer->tri_array[0][0]; - float (*cos)[3] = layer->tri_coords; + unsigned int *face = &layer->face_array[0][0]; + float (*cos)[3] = layer->face_coords; - const unsigned int bucket_tot = layer->buckets_x * layer->buckets_y; + const unsigned int bucket_tot = layer->buckets_x * layer->buckets_y; LinkNode **bucketstore = MEM_callocN(bucket_tot * sizeof(LinkNode *), __func__); unsigned int *bucketstore_tot = MEM_callocN(bucket_tot * sizeof(unsigned int), __func__); - unsigned int tri_index; + unsigned int face_index; - for (tri_index = 0; tri_index < layer->tri_tot; tri_index++, tri += 4) { + for (face_index = 0; face_index < layer->face_tot; face_index++, face += 4) { float xmin; float xmax; float ymin; float ymax; - if (tri[3] == TRI_VERT) { - const float *v1 = cos[tri[0]]; - const float *v2 = cos[tri[1]]; - const float *v3 = cos[tri[2]]; + if (face[3] == TRI_VERT) { + const float *v1 = cos[face[0]]; + const float *v2 = cos[face[1]]; + const float *v3 = cos[face[2]]; xmin = fminf(v1[0], fminf(v2[0], v3[0])); xmax = fmaxf(v1[0], fmaxf(v2[0], v3[0])); @@ -252,10 +254,10 @@ static void layer_bucket_init(MaskRasterLayer *layer) ymax = fmaxf(v1[1], fmaxf(v2[1], v3[1])); } else { - const float *v1 = cos[tri[0]]; - const float *v2 = cos[tri[1]]; - const float *v3 = cos[tri[2]]; - const float *v4 = cos[tri[3]]; + const float *v1 = cos[face[0]]; + const float *v2 = cos[face[1]]; + const float *v3 = cos[face[2]]; + const float *v4 = cos[face[3]]; xmin = fminf(v1[0], fminf(v2[0], fminf(v3[0], v4[0]))); xmax = fmaxf(v1[0], fmaxf(v2[0], fmaxf(v3[0], v4[0]))); @@ -282,7 +284,7 @@ static void layer_bucket_init(MaskRasterLayer *layer) BLI_assert(bucket_index < bucket_tot); BLI_linklist_prepend_arena(&bucketstore[bucket_index], - SET_UINT_IN_POINTER(tri_index), + SET_UINT_IN_POINTER(face_index), arena); bucketstore_tot[bucket_index]++; @@ -293,7 +295,7 @@ static void layer_bucket_init(MaskRasterLayer *layer) if (1) { /* now convert linknodes into arrays for faster per pixel access */ - unsigned int **buckets_tri = MEM_mallocN(bucket_tot * sizeof(unsigned int **), __func__); + unsigned int **buckets_face = MEM_mallocN(bucket_tot * sizeof(unsigned int **), __func__); unsigned int bucket_index; for (bucket_index = 0; bucket_index < bucket_tot; bucket_index++) { @@ -302,7 +304,7 @@ static void layer_bucket_init(MaskRasterLayer *layer) __func__); LinkNode *bucket_node; - buckets_tri[bucket_index] = bucket; + buckets_face[bucket_index] = bucket; for (bucket_node = bucketstore[bucket_index]; bucket_node; bucket_node = bucket_node->next) { *bucket = GET_UINT_FROM_POINTER(bucket_node->link); @@ -311,11 +313,11 @@ static void layer_bucket_init(MaskRasterLayer *layer) *bucket = TRI_TERMINATOR_ID; } else { - buckets_tri[bucket_index] = NULL; + buckets_face[bucket_index] = NULL; } } - layer->buckets_tri = buckets_tri; + layer->buckets_face = buckets_face; } MEM_freeN(bucketstore); @@ -497,22 +499,22 @@ void BLI_maskrasterize_handle_init(MaskRasterHandle *mr_handle, struct Mask *mas } if (sf_ctx.fillvertbase.first) { - unsigned int (*tri_array)[4], *tri; /* access coords */ - float (*tri_coords)[3], *cos; /* xy, z 0-1 (1.0 == filled) */ + unsigned int (*face_array)[4], *face; /* access coords */ + float (*face_coords)[3], *cos; /* xy, z 0-1 (1.0 == filled) */ int sf_tri_tot; rctf bounds; - int tri_index; + int face_index; float bvhcos[4][3]; /* now we have all the splines */ - tri_coords = MEM_mallocN((sizeof(float) * 3) * sf_vert_tot, "maskrast_tri_coords"); + face_coords = MEM_mallocN((sizeof(float) * 3) * sf_vert_tot, "maskrast_face_coords"); /* init bounds */ BLI_rctf_init_minmax(&bounds); /* coords */ - cos = (float *)tri_coords; + cos = (float *)face_coords; for (sf_vert = sf_ctx.fillvertbase.first; sf_vert; sf_vert = sf_vert_next) { sf_vert_next = sf_vert->next; copy_v3_v3(cos, sf_vert->co); @@ -531,52 +533,52 @@ void BLI_maskrasterize_handle_init(MaskRasterHandle *mr_handle, struct Mask *mas /* main scanfill */ sf_tri_tot = BLI_scanfill_calc_ex(&sf_ctx, FALSE, zvec); - tri_array = MEM_mallocN(sizeof(*tri_array) * (sf_tri_tot + tot_feather_quads), "maskrast_tri_index"); + face_array = MEM_mallocN(sizeof(*face_array) * (sf_tri_tot + tot_feather_quads), "maskrast_face_index"); /* tri's */ - tri = (unsigned int *)tri_array; - for (sf_tri = sf_ctx.fillfacebase.first, tri_index = 0; sf_tri; sf_tri = sf_tri->next, tri_index++) { - *(tri++) = sf_tri->v1->tmp.u; - *(tri++) = sf_tri->v2->tmp.u; - *(tri++) = sf_tri->v3->tmp.u; - *(tri++) = TRI_VERT; + face = (unsigned int *)face_array; + for (sf_tri = sf_ctx.fillfacebase.first, face_index = 0; sf_tri; sf_tri = sf_tri->next, face_index++) { + *(face++) = sf_tri->v1->tmp.u; + *(face++) = sf_tri->v2->tmp.u; + *(face++) = sf_tri->v3->tmp.u; + *(face++) = TRI_VERT; } /* start of feather faces... if we have this set, - * 'tri_index' is kept from loop above */ + * 'face_index' is kept from loop above */ - BLI_assert(tri_index == sf_tri_tot); + BLI_assert(face_index == sf_tri_tot); if (tot_feather_quads) { ScanFillEdge *sf_edge; for (sf_edge = sf_ctx.filledgebase.first; sf_edge; sf_edge = sf_edge->next) { if (sf_edge->tmp.c == SF_EDGE_IS_BOUNDARY) { - *(tri++) = sf_edge->v1->tmp.u; - *(tri++) = sf_edge->v2->tmp.u; - *(tri++) = sf_edge->v2->keyindex; - *(tri++) = sf_edge->v1->keyindex; + *(face++) = sf_edge->v1->tmp.u; + *(face++) = sf_edge->v2->tmp.u; + *(face++) = sf_edge->v2->keyindex; + *(face++) = sf_edge->v1->keyindex; - copy_v3_v3(bvhcos[0], tri_coords[*(tri - 4)]); - copy_v3_v3(bvhcos[1], tri_coords[*(tri - 3)]); - copy_v3_v3(bvhcos[2], tri_coords[*(tri - 2)]); - copy_v3_v3(bvhcos[3], tri_coords[*(tri - 1)]); + copy_v3_v3(bvhcos[0], face_coords[*(face - 4)]); + copy_v3_v3(bvhcos[1], face_coords[*(face - 3)]); + copy_v3_v3(bvhcos[2], face_coords[*(face - 2)]); + copy_v3_v3(bvhcos[3], face_coords[*(face - 1)]); - tri_index++; + face_index++; } } } - fprintf(stderr, "%d %d\n", tri_index, sf_tri_tot + tot_feather_quads); + // fprintf(stderr, "%d %d\n", face_index, sf_face_tot + tot_feather_quads); - BLI_assert(tri_index == sf_tri_tot + tot_feather_quads); + BLI_assert(face_index == sf_tri_tot + tot_feather_quads); { MaskRasterLayer *raslayer = &mr_handle->layers[masklay_index]; - raslayer->tri_tot = sf_tri_tot + tot_feather_quads; - raslayer->tri_coords = tri_coords; - raslayer->tri_array = tri_array; + raslayer->face_tot = sf_tri_tot + tot_feather_quads; + raslayer->face_coords = face_coords; + raslayer->face_array = face_array; raslayer->bounds = bounds; /* copy as-is */ @@ -621,10 +623,10 @@ static float maskrasterize_layer_z_depth_quad(const float pt[2], } #endif -static float maskrasterize_layer_isect(unsigned int *tri, float (*cos)[3], const float dist_orig, const float xy[2]) +static float maskrasterize_layer_isect(unsigned int *face, float (*cos)[3], const float dist_orig, const float xy[2]) { /* we always cast from same place only need xy */ - if (tri[3] == TRI_VERT) { + if (face[3] == TRI_VERT) { /* --- tri --- */ #if 0 @@ -633,15 +635,15 @@ static float maskrasterize_layer_isect(unsigned int *tri, float (*cos)[3], const (cos[1][2] < dist_orig) || (cos[2][2] < dist_orig)) { - if (isect_point_tri_v2(xy, cos[tri[0]], cos[tri[1]], cos[tri[2]])) { + if (isect_point_tri_v2(xy, cos[face[0]], cos[face[1]], cos[face[2]])) { /* we know all tris are close for now */ - return maskrasterize_layer_z_depth_tri(xy, cos[tri[0]], cos[tri[1]], cos[tri[2]]); + return maskrasterize_layer_z_depth_tri(xy, cos[face[0]], cos[face[1]], cos[face[2]]); } } #else /* we know all tris are close for now */ if (1) { - if (isect_point_tri_v2(xy, cos[tri[0]], cos[tri[1]], cos[tri[2]])) { + if (isect_point_tri_v2(xy, cos[face[0]], cos[face[1]], cos[face[2]])) { return 0.0f; } } @@ -659,15 +661,15 @@ static float maskrasterize_layer_isect(unsigned int *tri, float (*cos)[3], const /* needs work */ #if 0 - if (isect_point_quad_v2(xy, cos[tri[0]], cos[tri[1]], cos[tri[2]], cos[tri[3]])) { - return maskrasterize_layer_z_depth_quad(xy, cos[tri[0]], cos[tri[1]], cos[tri[2]], cos[tri[3]]); + if (isect_point_quad_v2(xy, cos[face[0]], cos[face[1]], cos[face[2]], cos[face[3]])) { + return maskrasterize_layer_z_depth_quad(xy, cos[face[0]], cos[face[1]], cos[face[2]], cos[face[3]]); } #elif 1 - if (isect_point_tri_v2(xy, cos[tri[0]], cos[tri[1]], cos[tri[2]])) { - return maskrasterize_layer_z_depth_tri(xy, cos[tri[0]], cos[tri[1]], cos[tri[2]]); + if (isect_point_tri_v2(xy, cos[face[0]], cos[face[1]], cos[face[2]])) { + return maskrasterize_layer_z_depth_tri(xy, cos[face[0]], cos[face[1]], cos[face[2]]); } - else if (isect_point_tri_v2(xy, cos[tri[0]], cos[tri[2]], cos[tri[3]])) { - return maskrasterize_layer_z_depth_tri(xy, cos[tri[0]], cos[tri[2]], cos[tri[3]]); + else if (isect_point_tri_v2(xy, cos[face[0]], cos[face[2]], cos[face[3]])) { + return maskrasterize_layer_z_depth_tri(xy, cos[face[0]], cos[face[2]], cos[face[3]]); } #else /* cheat - we know first 2 verts are z0.0f and second 2 are z 1.0f */ @@ -679,7 +681,7 @@ static float maskrasterize_layer_isect(unsigned int *tri, float (*cos)[3], const return 1.0f; } -static unsigned int layer_bucket_index_from_xy(MaskRasterLayer *layer, const float xy[2]) +BLI_INLINE unsigned int layer_bucket_index_from_xy(MaskRasterLayer *layer, const float xy[2]) { BLI_assert(BLI_in_rctf_v(&layer->bounds, xy)); @@ -690,23 +692,23 @@ static unsigned int layer_bucket_index_from_xy(MaskRasterLayer *layer, const flo static float layer_bucket_depth_from_xy(MaskRasterLayer *layer, const float xy[2]) { unsigned int index = layer_bucket_index_from_xy(layer, xy); - unsigned int *tri_index = layer->buckets_tri[index]; + unsigned int *face_index = layer->buckets_face[index]; - if (tri_index) { - float (*cos)[3] = layer->tri_coords; + if (face_index) { + unsigned int (*face_array)[4] = layer->face_array; + float (*cos)[3] = layer->face_coords; float best_dist = 1.0f; - float test_dist; - while (*tri_index != TRI_TERMINATOR_ID) { - unsigned int *tri = layer->tri_array[*tri_index]; - if ((test_dist = maskrasterize_layer_isect(tri, cos, best_dist, xy)) < best_dist) { + while (*face_index != TRI_TERMINATOR_ID) { + const float test_dist = maskrasterize_layer_isect(face_array[*face_index], cos, best_dist, xy); + if (test_dist < best_dist) { best_dist = test_dist; /* comparing with 0.0f is OK here because triangles are always zero depth */ if (best_dist == 0.0f) { - /* bail early, we're as close as possible */ + /* bail early, we're as close as possible */ return 0.0f; } } - tri_index++; + face_index++; } return best_dist; } From f67ee4ff00bcb651821fc5478a21456122d2fa43 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sat, 14 Jul 2012 16:54:10 +0000 Subject: [PATCH 012/108] add dynamic bucket xy resolution based on pixel size, also remove some redundant copying. --- .../blenkernel/intern/mask_rasterize.c | 84 ++++++++++--------- 1 file changed, 44 insertions(+), 40 deletions(-) diff --git a/source/blender/blenkernel/intern/mask_rasterize.c b/source/blender/blenkernel/intern/mask_rasterize.c index 855dd2a2921..c4690f1d7c1 100644 --- a/source/blender/blenkernel/intern/mask_rasterize.c +++ b/source/blender/blenkernel/intern/mask_rasterize.c @@ -47,6 +47,7 @@ #ifndef USE_RASKTER #define SPLINE_RESOL 32 +#define BUCKET_PIXELS_PER_CELL 8 #define SF_EDGE_IS_BOUNDARY 0xff #define SF_KEYINDEX_TEMP_ID ((unsigned int) -1) @@ -62,7 +63,8 @@ /** * A single #MaskRasterHandle contains multile #MaskRasterLayer's, * each #MaskRasterLayer does its own lookup which contributes to - * the final pixel with its own blending mode and the final pixel is blended between these. + * the final pixel with its own blending mode and the final pixel + * is blended between these. */ /* internal use only */ @@ -122,30 +124,30 @@ void BLI_maskrasterize_handle_free(MaskRasterHandle *mr_handle) { const unsigned int layers_tot = mr_handle->layers_tot; unsigned int i; - MaskRasterLayer *raslayers = mr_handle->layers; + MaskRasterLayer *layer = mr_handle->layers; /* raycast vars */ - for (i = 0; i < layers_tot; i++, raslayers++) { + for (i = 0; i < layers_tot; i++, layer++) { - if (raslayers->face_array) { - MEM_freeN(raslayers->face_array); + if (layer->face_array) { + MEM_freeN(layer->face_array); } - if (raslayers->face_coords) { - MEM_freeN(raslayers->face_coords); + if (layer->face_coords) { + MEM_freeN(layer->face_coords); } - if (raslayers->buckets_face) { - const unsigned int bucket_tot = raslayers->buckets_x * raslayers->buckets_y; + if (layer->buckets_face) { + const unsigned int bucket_tot = layer->buckets_x * layer->buckets_y; unsigned int bucket_index; for (bucket_index = 0; bucket_index < bucket_tot; bucket_index++) { - unsigned int *face_index = raslayers->buckets_face[bucket_index]; + unsigned int *face_index = layer->buckets_face[bucket_index]; if (face_index) { MEM_freeN(face_index); } } - MEM_freeN(raslayers->buckets_face); + MEM_freeN(layer->buckets_face); } } @@ -154,9 +156,9 @@ void BLI_maskrasterize_handle_free(MaskRasterHandle *mr_handle) } -void maskrasterize_spline_differentiate_point_inset(float (*diff_feather_points)[2], float (*diff_points)[2], - const unsigned int tot_diff_point, const float ofs, - const short do_test) +void maskrasterize_spline_differentiate_point_outset(float (*diff_feather_points)[2], float (*diff_points)[2], + const unsigned int tot_diff_point, const float ofs, + const short do_test) { unsigned int k_prev = tot_diff_point - 2; unsigned int k_curr = tot_diff_point - 1; @@ -184,7 +186,7 @@ void maskrasterize_spline_differentiate_point_inset(float (*diff_feather_points) for (k = 0; k < tot_diff_point; k++) { - co_prev = diff_points[k_prev]; + /* co_prev = diff_points[k_prev]; */ /* precalc */ co_curr = diff_points[k_curr]; co_next = diff_points[k_next]; @@ -209,23 +211,32 @@ void maskrasterize_spline_differentiate_point_inset(float (*diff_feather_points) /* use next iter */ copy_v2_v2(d_prev, d_next); - k_prev = k_curr; + /* k_prev = k_curr; */ /* precalc */ k_curr = k_next; k_next++; } } -static void layer_bucket_init(MaskRasterLayer *layer) +static void layer_bucket_init(MaskRasterLayer *layer, const float pixel_size) { MemArena *arena = BLI_memarena_new(1 << 16, __func__); - /* TODO - calculate best bucket size */ - layer->buckets_x = 256; - layer->buckets_y = 256; + { + const float dims[2] = {layer->bounds.xmax - layer->bounds.xmin, + layer->bounds.ymax - layer->bounds.ymin}; - layer->buckets_xy_scalar[0] = (1.0f / ((layer->bounds.xmax - layer->bounds.xmin) + FLT_EPSILON)) * layer->buckets_x; - layer->buckets_xy_scalar[1] = (1.0f / ((layer->bounds.ymax - layer->bounds.ymin) + FLT_EPSILON)) * layer->buckets_y; + layer->buckets_x = (dims[0] / pixel_size) / (float)BUCKET_PIXELS_PER_CELL; + layer->buckets_y = (dims[1] / 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); + + 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; + } { unsigned int *face = &layer->face_array[0][0]; @@ -428,12 +439,12 @@ void BLI_maskrasterize_handle_init(MaskRasterHandle *mr_handle, struct Mask *mas diff_feather_points = MEM_mallocN(sizeof(*diff_feather_points) * tot_diff_feather_points, __func__); /* add single pixel feather */ - maskrasterize_spline_differentiate_point_inset(diff_feather_points, diff_points, + maskrasterize_spline_differentiate_point_outset(diff_feather_points, diff_points, tot_diff_point, pixel_size, FALSE); } else { /* ensure single pixel feather, on any zero feather areas */ - maskrasterize_spline_differentiate_point_inset(diff_feather_points, diff_points, + maskrasterize_spline_differentiate_point_outset(diff_feather_points, diff_points, tot_diff_point, pixel_size, TRUE); } } @@ -505,8 +516,6 @@ void BLI_maskrasterize_handle_init(MaskRasterHandle *mr_handle, struct Mask *mas rctf bounds; int face_index; - float bvhcos[4][3]; - /* now we have all the splines */ face_coords = MEM_mallocN((sizeof(float) * 3) * sf_vert_tot, "maskrast_face_coords"); @@ -559,11 +568,6 @@ void BLI_maskrasterize_handle_init(MaskRasterHandle *mr_handle, struct Mask *mas *(face++) = sf_edge->v2->keyindex; *(face++) = sf_edge->v1->keyindex; - copy_v3_v3(bvhcos[0], face_coords[*(face - 4)]); - copy_v3_v3(bvhcos[1], face_coords[*(face - 3)]); - copy_v3_v3(bvhcos[2], face_coords[*(face - 2)]); - copy_v3_v3(bvhcos[3], face_coords[*(face - 1)]); - face_index++; } } @@ -574,19 +578,19 @@ void BLI_maskrasterize_handle_init(MaskRasterHandle *mr_handle, struct Mask *mas BLI_assert(face_index == sf_tri_tot + tot_feather_quads); { - MaskRasterLayer *raslayer = &mr_handle->layers[masklay_index]; + MaskRasterLayer *layer = &mr_handle->layers[masklay_index]; - raslayer->face_tot = sf_tri_tot + tot_feather_quads; - raslayer->face_coords = face_coords; - raslayer->face_array = face_array; - raslayer->bounds = bounds; + layer->face_tot = sf_tri_tot + tot_feather_quads; + layer->face_coords = face_coords; + layer->face_array = face_array; + layer->bounds = bounds; /* copy as-is */ - raslayer->alpha = masklay->alpha; - raslayer->blend = masklay->blend; - raslayer->blend_flag = masklay->blend_flag; + layer->alpha = masklay->alpha; + layer->blend = masklay->blend; + layer->blend_flag = masklay->blend_flag; - layer_bucket_init(raslayer); + layer_bucket_init(layer, pixel_size); BLI_union_rctf(&mr_handle->bounds, &bounds); } From 8a9d1c0a795aad31c19cc3f0c70e2f53578f49dd Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Sat, 14 Jul 2012 17:30:49 +0000 Subject: [PATCH 013/108] Fix #31021: Render settings are not taken into account for curves Refactored code a bit to make naming a bit more clear and added a function to create mesh from given display list rather than from object's displist. Tested using plain curves (which doesn't imply using derived meshes) and curves with constructive modifiers (which are using derived meshed). --- source/blender/blenkernel/BKE_cdderivedmesh.h | 2 +- source/blender/blenkernel/BKE_mesh.h | 3 ++- .../blender/blenkernel/intern/cdderivedmesh.c | 6 +++--- source/blender/blenkernel/intern/displist.c | 4 ++-- source/blender/blenkernel/intern/mesh.c | 17 +++++++++++------ source/blender/makesrna/intern/rna_object_api.c | 13 ++++++++++--- 6 files changed, 29 insertions(+), 16 deletions(-) diff --git a/source/blender/blenkernel/BKE_cdderivedmesh.h b/source/blender/blenkernel/BKE_cdderivedmesh.h index 37763003099..eeebcdafe48 100644 --- a/source/blender/blenkernel/BKE_cdderivedmesh.h +++ b/source/blender/blenkernel/BKE_cdderivedmesh.h @@ -66,7 +66,7 @@ struct DerivedMesh *CDDM_from_curve(struct Object *ob); /* creates a CDDerivedMesh from the given curve object and specified dispbase */ /* useful for OrcoDM creation for curves with constructive modifiers */ -DerivedMesh *CDDM_from_curve_customDB(struct Object *ob, struct ListBase *dispbase); +DerivedMesh *CDDM_from_curve_displist(struct Object *ob, struct ListBase *dispbase); /* Copies the given DerivedMesh with verts, faces & edges stored as * custom element data. diff --git a/source/blender/blenkernel/BKE_mesh.h b/source/blender/blenkernel/BKE_mesh.h index abd0c4d96db..6fac915d520 100644 --- a/source/blender/blenkernel/BKE_mesh.h +++ b/source/blender/blenkernel/BKE_mesh.h @@ -141,10 +141,11 @@ void BKE_mesh_from_metaball(struct ListBase *lb, struct Mesh *me); int BKE_mesh_nurbs_to_mdata(struct Object *ob, struct MVert **allvert, int *totvert, struct MEdge **alledge, int *totedge, struct MLoop **allloop, struct MPoly **allpoly, int *totloop, int *totpoly); -int BKE_mesh_nurbs_to_mdata_customdb(struct Object *ob, struct ListBase *dispbase, struct MVert **allvert, int *_totvert, +int BKE_mesh_nurbs_displist_to_mdata(struct Object *ob, struct ListBase *dispbase, struct MVert **allvert, int *_totvert, struct MEdge **alledge, int *_totedge, struct MLoop **allloop, struct MPoly **allpoly, int *_totloop, int *_totpoly); void BKE_mesh_from_nurbs(struct Object *ob); +void BKE_mesh_from_nurbs_displist(struct Object *ob, struct ListBase *dispbase); void BKE_mesh_from_curve(struct Scene *scene, struct Object *ob); void free_dverts(struct MDeformVert *dvert, int totvert); void copy_dverts(struct MDeformVert *dst, struct MDeformVert *src, int totvert); /* __NLA */ diff --git a/source/blender/blenkernel/intern/cdderivedmesh.c b/source/blender/blenkernel/intern/cdderivedmesh.c index e5e73061d52..e5afc852846 100644 --- a/source/blender/blenkernel/intern/cdderivedmesh.c +++ b/source/blender/blenkernel/intern/cdderivedmesh.c @@ -1709,10 +1709,10 @@ DerivedMesh *CDDM_from_mesh(Mesh *mesh, Object *UNUSED(ob)) DerivedMesh *CDDM_from_curve(Object *ob) { - return CDDM_from_curve_customDB(ob, &ob->disp); + return CDDM_from_curve_displist(ob, &ob->disp); } -DerivedMesh *CDDM_from_curve_customDB(Object *ob, ListBase *dispbase) +DerivedMesh *CDDM_from_curve_displist(Object *ob, ListBase *dispbase) { DerivedMesh *dm; CDDerivedMesh *cddm; @@ -1722,7 +1722,7 @@ DerivedMesh *CDDM_from_curve_customDB(Object *ob, ListBase *dispbase) MPoly *allpoly; int totvert, totedge, totloop, totpoly; - if (BKE_mesh_nurbs_to_mdata_customdb(ob, dispbase, &allvert, &totvert, &alledge, + if (BKE_mesh_nurbs_displist_to_mdata(ob, dispbase, &allvert, &totvert, &alledge, &totedge, &allloop, &allpoly, &totloop, &totpoly) != 0) { /* Error initializing mdata. This often happens when curve is empty */ diff --git a/source/blender/blenkernel/intern/displist.c b/source/blender/blenkernel/intern/displist.c index 9b349598db1..8011efebaac 100644 --- a/source/blender/blenkernel/intern/displist.c +++ b/source/blender/blenkernel/intern/displist.c @@ -948,7 +948,7 @@ static void curve_calc_modifiers_post(Scene *scene, Object *ob, ListBase *dispba curve_to_filledpoly(cu, nurb, dispbase); } - dm = CDDM_from_curve_customDB(ob, dispbase); + dm = CDDM_from_curve_displist(ob, dispbase); CDDM_calc_normals_mapping(dm); } @@ -1038,7 +1038,7 @@ static DerivedMesh *create_orco_dm(Scene *scene, Object *ob) /* OrcoDM should be created from underformed disp lists */ BKE_displist_make_curveTypes_forOrco(scene, ob, &disp); - dm = CDDM_from_curve_customDB(ob, &disp); + dm = CDDM_from_curve_displist(ob, &disp); BKE_displist_free(&disp); diff --git a/source/blender/blenkernel/intern/mesh.c b/source/blender/blenkernel/intern/mesh.c index 8d81e7b595d..c5752e193df 100644 --- a/source/blender/blenkernel/intern/mesh.c +++ b/source/blender/blenkernel/intern/mesh.c @@ -1230,7 +1230,7 @@ int BKE_mesh_nurbs_to_mdata(Object *ob, MVert **allvert, int *totvert, MEdge **alledge, int *totedge, MLoop **allloop, MPoly **allpoly, int *totloop, int *totpoly) { - return BKE_mesh_nurbs_to_mdata_customdb(ob, &ob->disp, + return BKE_mesh_nurbs_displist_to_mdata(ob, &ob->disp, allvert, totvert, alledge, totedge, allloop, allpoly, @@ -1242,7 +1242,7 @@ int BKE_mesh_nurbs_to_mdata(Object *ob, MVert **allvert, int *totvert, /* Initialize mverts, medges and, faces for converting nurbs to mesh and derived mesh */ /* use specified dispbase */ -int BKE_mesh_nurbs_to_mdata_customdb(Object *ob, ListBase *dispbase, +int BKE_mesh_nurbs_displist_to_mdata(Object *ob, ListBase *dispbase, MVert **allvert, int *_totvert, MEdge **alledge, int *_totedge, MLoop **allloop, MPoly **allpoly, @@ -1462,7 +1462,7 @@ int BKE_mesh_nurbs_to_mdata_customdb(Object *ob, ListBase *dispbase, } /* this may fail replacing ob->data, be sure to check ob->type */ -void BKE_mesh_from_nurbs(Object *ob) +void BKE_mesh_from_nurbs_displist(Object *ob, ListBase *dispbase) { Main *bmain = G.main; Object *ob1; @@ -1478,9 +1478,9 @@ void BKE_mesh_from_nurbs(Object *ob) cu = ob->data; if (dm == NULL) { - if (BKE_mesh_nurbs_to_mdata(ob, &allvert, &totvert, - &alledge, &totedge, &allloop, - &allpoly, &totloop, &totpoly) != 0) + if (BKE_mesh_nurbs_displist_to_mdata(ob, dispbase, &allvert, &totvert, + &alledge, &totedge, &allloop, + &allpoly, &totloop, &totpoly) != 0) { /* Error initializing */ return; @@ -1534,6 +1534,11 @@ void BKE_mesh_from_nurbs(Object *ob) } } +void BKE_mesh_from_nurbs(Object *ob) +{ + return BKE_mesh_from_nurbs_displist(ob, &ob->disp); +} + typedef struct EdgeLink { Link *next, *prev; void *edge; diff --git a/source/blender/makesrna/intern/rna_object_api.c b/source/blender/makesrna/intern/rna_object_api.c index a3e538da9b1..ae8c331bf1e 100644 --- a/source/blender/makesrna/intern/rna_object_api.c +++ b/source/blender/makesrna/intern/rna_object_api.c @@ -84,7 +84,9 @@ Mesh *rna_Object_to_mesh(Object *ob, ReportList *reports, Scene *sce, int apply_ switch (ob->type) { case OB_FONT: case OB_CURVE: - case OB_SURF: + case OB_SURF: { + ListBase dispbase = {NULL, NULL}; + DerivedMesh *derivedFinal = NULL; /* copies object and modifiers (but not the data) */ tmpobj = BKE_object_copy(ob); @@ -105,12 +107,16 @@ Mesh *rna_Object_to_mesh(Object *ob, ReportList *reports, Scene *sce, int apply_ copycu->editnurb = tmpcu->editnurb; /* get updated display list, and convert to a mesh */ - BKE_displist_make_curveTypes(sce, tmpobj, 0); + BKE_displist_make_curveTypes_forRender(sce, tmpobj, &dispbase, &derivedFinal, FALSE); copycu->editfont = NULL; copycu->editnurb = NULL; - BKE_mesh_from_nurbs(tmpobj); + tmpobj->derivedFinal = derivedFinal; + + BKE_mesh_from_nurbs_displist(tmpobj, &dispbase); + + BKE_displist_free(&dispbase); /* BKE_mesh_from_nurbs changes the type to a mesh, check it worked */ if (tmpobj->type != OB_MESH) { @@ -121,6 +127,7 @@ Mesh *rna_Object_to_mesh(Object *ob, ReportList *reports, Scene *sce, int apply_ tmpmesh = tmpobj->data; BKE_libblock_free_us(&G.main->object, tmpobj); break; + } case OB_MBALL: { /* metaballs don't have modifiers, so just convert to mesh */ From 83d1fac2e471ae3278e1e6b12041de71b0038b87 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sat, 14 Jul 2012 17:58:42 +0000 Subject: [PATCH 014/108] mask rasterizer - test if buckets overlap the face before adding the face into the bucket. --- .../blenkernel/intern/mask_rasterize.c | 182 ++++++++++++++++-- 1 file changed, 162 insertions(+), 20 deletions(-) diff --git a/source/blender/blenkernel/intern/mask_rasterize.c b/source/blender/blenkernel/intern/mask_rasterize.c index c4690f1d7c1..ecceb282392 100644 --- a/source/blender/blenkernel/intern/mask_rasterize.c +++ b/source/blender/blenkernel/intern/mask_rasterize.c @@ -217,28 +217,166 @@ void maskrasterize_spline_differentiate_point_outset(float (*diff_feather_points } } +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 @@ static void layer_bucket_init(MaskRasterLayer *layer, const float pixel_size) 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 @@ void BLI_maskrasterize_handle_init(MaskRasterHandle *mr_handle, struct Mask *mas 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}; From 6946294ab95c3a32ca3d6c39daff6b5d24f4c724 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sat, 14 Jul 2012 18:37:48 +0000 Subject: [PATCH 015/108] rename vars for line dist funcs to make more sense --- source/blender/blenlib/intern/math_geom.c | 40 +++++++++++------------ 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/source/blender/blenlib/intern/math_geom.c b/source/blender/blenlib/intern/math_geom.c index 097b14754be..c2311bf33ba 100644 --- a/source/blender/blenlib/intern/math_geom.c +++ b/source/blender/blenlib/intern/math_geom.c @@ -162,51 +162,51 @@ float area_poly_v3(int nr, float verts[][3], const float normal[3]) /********************************* Distance **********************************/ -/* distance v1 to line v2-v3 +/* distance p to line v1-v2 * using Hesse formula, NO LINE PIECE! */ -float dist_to_line_v2(const float v1[2], const float v2[2], const float v3[2]) +float dist_to_line_v2(const float p[2], const float l1[2], const float l2[2]) { float a[2], deler; - a[0] = v2[1] - v3[1]; - a[1] = v3[0] - v2[0]; + a[0] = l1[1] - l2[1]; + a[1] = l2[0] - l1[0]; deler = (float)sqrt(a[0] * a[0] + a[1] * a[1]); if (deler == 0.0f) return 0; - return fabsf((v1[0] - v2[0]) * a[0] + (v1[1] - v2[1]) * a[1]) / deler; + return fabsf((p[0] - l1[0]) * a[0] + (p[1] - l1[1]) * a[1]) / deler; } -/* distance v1 to line-piece v2-v3 */ -float dist_to_line_segment_v2(const float v1[2], const float v2[2], const float v3[2]) +/* distance p to line-piece v1-v2 */ +float dist_to_line_segment_v2(const float p[2], const float l1[2], const float l2[2]) { float labda, rc[2], pt[2], len; - rc[0] = v3[0] - v2[0]; - rc[1] = v3[1] - v2[1]; + rc[0] = l2[0] - l1[0]; + rc[1] = l2[1] - l1[1]; len = rc[0] * rc[0] + rc[1] * rc[1]; if (len == 0.0f) { - rc[0] = v1[0] - v2[0]; - rc[1] = v1[1] - v2[1]; + rc[0] = p[0] - l1[0]; + rc[1] = p[1] - l1[1]; return (float)(sqrt(rc[0] * rc[0] + rc[1] * rc[1])); } - labda = (rc[0] * (v1[0] - v2[0]) + rc[1] * (v1[1] - v2[1])) / len; + labda = (rc[0] * (p[0] - l1[0]) + rc[1] * (p[1] - l1[1])) / len; if (labda <= 0.0f) { - pt[0] = v2[0]; - pt[1] = v2[1]; + pt[0] = l1[0]; + pt[1] = l1[1]; } else if (labda >= 1.0f) { - pt[0] = v3[0]; - pt[1] = v3[1]; + pt[0] = l2[0]; + pt[1] = l2[1]; } else { - pt[0] = labda * rc[0] + v2[0]; - pt[1] = labda * rc[1] + v2[1]; + pt[0] = labda * rc[0] + l1[0]; + pt[1] = labda * rc[1] + l1[1]; } - rc[0] = pt[0] - v1[0]; - rc[1] = pt[1] - v1[1]; + rc[0] = pt[0] - p[0]; + rc[1] = pt[1] - p[1]; return sqrtf(rc[0] * rc[0] + rc[1] * rc[1]); } From a52153a618688bcabb9812959e7b1de7c4b92f71 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sat, 14 Jul 2012 18:42:59 +0000 Subject: [PATCH 016/108] mask rasterization: use a simpler method to check if a bucket intersects with a triangle. --- .../blenkernel/intern/mask_rasterize.c | 162 ++++++------------ source/blender/blenlib/BLI_math_geom.h | 3 +- source/blender/blenlib/intern/math_geom.c | 9 +- 3 files changed, 62 insertions(+), 112 deletions(-) diff --git a/source/blender/blenkernel/intern/mask_rasterize.c b/source/blender/blenkernel/intern/mask_rasterize.c index ecceb282392..9041e304444 100644 --- a/source/blender/blenkernel/intern/mask_rasterize.c +++ b/source/blender/blenkernel/intern/mask_rasterize.c @@ -217,73 +217,52 @@ void maskrasterize_spline_differentiate_point_outset(float (*diff_feather_points } } +/* this function is not exact, sometimes it retuns false positives, + * the main point of it is to clear out _almost_ all bucket/face non-intersections, + * returning TRUE in corner cases is ok but missing an intersection is NOT. + * + * method used + * - check if the center of the buckets bounding box is intersecting the face + * - if not get the max radius to a corner of the bucket and see how close we + * are to any of the triangle edges. + */ 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 bucket_size_x, const float bucket_size_y, + const float bucket_max_rad_squared) { - 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; + const float xmin = layer->bounds.xmin + (bucket_size_x * bucket_x); + const float ymin = layer->bounds.ymin + (bucket_size_y * bucket_y); + const float xmax = xmin + bucket_size_x; + const float ymax = ymin + bucket_size_y; + + float cent[2] = {(xmin + xmax) * 0.5f, + (ymin + ymax) * 0.5f}; 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)) - { + if (isect_point_tri_v2(cent, 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; + else { + if ((dist_squared_to_line_segment_v2(cent, v1, v2) < bucket_max_rad_squared) || + (dist_squared_to_line_segment_v2(cent, v2, v3) < bucket_max_rad_squared) || + (dist_squared_to_line_segment_v2(cent, v3, v1) < bucket_max_rad_squared)) + { + return TRUE; + } + else { + // printf("skip tri\n"); + return FALSE; + } } -#endif - return FALSE; } else { const float *v1 = cos[face[0]]; @@ -291,66 +270,25 @@ static int layer_bucket_isect_test(MaskRasterLayer *layer, unsigned int face_ind 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)) - { + if (isect_point_tri_v2(cent, 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)) - { + else if (isect_point_tri_v2(cent, 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 ((dist_squared_to_line_segment_v2(cent, v1, v2) < bucket_max_rad_squared) || + (dist_squared_to_line_segment_v2(cent, v2, v3) < bucket_max_rad_squared) || + (dist_squared_to_line_segment_v2(cent, v3, v4) < bucket_max_rad_squared) || + (dist_squared_to_line_segment_v2(cent, v4, v1) < bucket_max_rad_squared)) + { + return TRUE; + } + else { + // printf("skip quad\n"); + return FALSE; + } } -#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; } } @@ -374,8 +312,10 @@ static void layer_bucket_init(MaskRasterLayer *layer, const float pixel_size) { /* 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; + const float bucket_size_x = (bucket_dim_x + FLT_EPSILON) / layer->buckets_x; + const float bucket_size_y = (bucket_dim_y + FLT_EPSILON) / layer->buckets_y; + const float bucket_max_rad = (maxf(bucket_size_x, bucket_size_y) * M_SQRT2) + FLT_EPSILON; + const float bucket_max_rad_squared = bucket_max_rad * bucket_max_rad; unsigned int *face = &layer->face_array[0][0]; float (*cos)[3] = layer->face_coords; @@ -438,7 +378,11 @@ static void layer_bucket_init(MaskRasterLayer *layer, const float pixel_size) /* 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)) { + if (layer_bucket_isect_test(layer, face_index, + xi, yi, + bucket_size_x, bucket_size_y, + bucket_max_rad_squared)) + { BLI_linklist_prepend_arena(&bucketstore[bucket_index], face_index_void, arena); bucketstore_tot[bucket_index]++; } diff --git a/source/blender/blenlib/BLI_math_geom.h b/source/blender/blenlib/BLI_math_geom.h index 6810067b35b..70450156d98 100644 --- a/source/blender/blenlib/BLI_math_geom.h +++ b/source/blender/blenlib/BLI_math_geom.h @@ -60,7 +60,8 @@ int is_quad_convex_v2(const float v1[2], const float v2[2], const float v3[2], c /********************************* Distance **********************************/ float dist_to_line_v2(const float p[2], const float l1[2], const float l2[2]); -float dist_to_line_segment_v2(const float p[2], const float l1[2], const float l2[2]); +float dist_squared_to_line_segment_v2(const float p[2], const float l1[2], const float l2[2]); +float dist_to_line_segment_v2(const float p[2], const float l1[2], const float l2[2]); void closest_to_line_segment_v2(float closest[2], const float p[2], const float l1[2], const float l2[2]); float dist_to_plane_normalized_v3(const float p[3], const float plane_co[3], const float plane_no_unit[3]); diff --git a/source/blender/blenlib/intern/math_geom.c b/source/blender/blenlib/intern/math_geom.c index c2311bf33ba..74e685ee238 100644 --- a/source/blender/blenlib/intern/math_geom.c +++ b/source/blender/blenlib/intern/math_geom.c @@ -178,7 +178,7 @@ float dist_to_line_v2(const float p[2], const float l1[2], const float l2[2]) } /* distance p to line-piece v1-v2 */ -float dist_to_line_segment_v2(const float p[2], const float l1[2], const float l2[2]) +float dist_squared_to_line_segment_v2(const float p[2], const float l1[2], const float l2[2]) { float labda, rc[2], pt[2], len; @@ -207,7 +207,12 @@ float dist_to_line_segment_v2(const float p[2], const float l1[2], const float l rc[0] = pt[0] - p[0]; rc[1] = pt[1] - p[1]; - return sqrtf(rc[0] * rc[0] + rc[1] * rc[1]); + return (rc[0] * rc[0] + rc[1] * rc[1]); +} + +float dist_to_line_segment_v2(const float p[2], const float l1[2], const float l2[2]) +{ + return sqrtf(dist_squared_to_line_segment_v2(p, l1, l2)); } /* point closest to v1 on line v2-v3 in 2D */ From 52c0f44659719b63fb618794e80f0aedf4129335 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sat, 14 Jul 2012 18:57:16 +0000 Subject: [PATCH 017/108] zealous bounds checking broke the invert option. --- .../blenkernel/intern/mask_rasterize.c | 83 ++++++++++--------- 1 file changed, 42 insertions(+), 41 deletions(-) diff --git a/source/blender/blenkernel/intern/mask_rasterize.c b/source/blender/blenkernel/intern/mask_rasterize.c index 9041e304444..d2b6a189aba 100644 --- a/source/blender/blenkernel/intern/mask_rasterize.c +++ b/source/blender/blenkernel/intern/mask_rasterize.c @@ -239,8 +239,8 @@ static int layer_bucket_isect_test(MaskRasterLayer *layer, unsigned int face_ind const float xmax = xmin + bucket_size_x; const float ymax = ymin + bucket_size_y; - float cent[2] = {(xmin + xmax) * 0.5f, - (ymin + ymax) * 0.5f}; + const float cent[2] = {(xmin + xmax) * 0.5f, + (ymin + ymax) * 0.5f}; if (face[3] == TRI_VERT) { const float *v1 = cos[face[0]]; @@ -809,53 +809,54 @@ static float layer_bucket_depth_from_xy(MaskRasterLayer *layer, const float xy[2 float BLI_maskrasterize_handle_sample(MaskRasterHandle *mr_handle, const float xy[2]) { - if (BLI_in_rctf_v(&mr_handle->bounds, xy)) { - const unsigned int layers_tot = mr_handle->layers_tot; - unsigned int i; - MaskRasterLayer *layer = mr_handle->layers; + /* can't do this because some layers may invert */ + /* if (BLI_in_rctf_v(&mr_handle->bounds, xy)) */ - /* raycast vars*/ + const unsigned int layers_tot = mr_handle->layers_tot; + unsigned int i; + MaskRasterLayer *layer = mr_handle->layers; - /* return */ - float value = 0.0f; + /* raycast vars*/ - for (i = 0; i < layers_tot; i++, layer++) { - if (BLI_in_rctf_v(&layer->bounds, xy)) { - /* --- hit (start) --- */ - const float dist = 1.0f - layer_bucket_depth_from_xy(layer, xy); - const float dist_ease = (3.0f * dist * dist - 2.0f * dist * dist * dist); + /* return */ + float value = 0.0f; - float v; - /* apply alpha */ - v = dist_ease * layer->alpha; + for (i = 0; i < layers_tot; i++, layer++) { + float dist_ease; + float v; - if (layer->blend_flag & MASK_BLENDFLAG_INVERT) { - v = 1.0f - v; - } - - switch (layer->blend) { - case MASK_BLEND_SUBTRACT: - { - value -= v; - break; - } - case MASK_BLEND_ADD: - default: - { - value += v; - break; - } - } - /* --- hit (end) --- */ - - } + if (BLI_in_rctf_v(&layer->bounds, xy)) { + /* --- hit (start) --- */ + const float dist = 1.0f - layer_bucket_depth_from_xy(layer, xy); + dist_ease = (3.0f * dist * dist - 2.0f * dist * dist * dist); + } + else { + dist_ease = 0.0f; } - return CLAMPIS(value, 0.0f, 1.0f); - } - else { - return 0.0f; + /* apply alpha */ + v = dist_ease * layer->alpha; + + if (layer->blend_flag & MASK_BLENDFLAG_INVERT) { + v = 1.0f - v; + } + + switch (layer->blend) { + case MASK_BLEND_SUBTRACT: + { + value -= v; + break; + } + case MASK_BLEND_ADD: + default: + { + value += v; + break; + } + } } + + return CLAMPIS(value, 0.0f, 1.0f); } #endif /* USE_RASKTER */ From 6986f671ee10bc7261ee37bc1a3444c9708fbe28 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sat, 14 Jul 2012 19:21:13 +0000 Subject: [PATCH 018/108] code cleanup --- .../blenkernel/intern/mask_rasterize.c | 28 ++++++++----------- 1 file changed, 12 insertions(+), 16 deletions(-) diff --git a/source/blender/blenkernel/intern/mask_rasterize.c b/source/blender/blenkernel/intern/mask_rasterize.c index d2b6a189aba..d036e7eb15a 100644 --- a/source/blender/blenkernel/intern/mask_rasterize.c +++ b/source/blender/blenkernel/intern/mask_rasterize.c @@ -461,6 +461,7 @@ void BLI_maskrasterize_handle_init(MaskRasterHandle *mr_handle, struct Mask *mas BLI_scanfill_begin(&sf_ctx); for (spline = masklay->splines.first; spline; spline = spline->next) { + // const unsigned int is_cyclic = (spline->flag & MASK_SPLINE_CYCLIC) != 0; float (*diff_points)[2]; int tot_diff_point; @@ -471,7 +472,6 @@ void BLI_maskrasterize_handle_init(MaskRasterHandle *mr_handle, struct Mask *mas diff_points = BKE_mask_spline_differentiate_with_resolution_ex( spline, resol, &tot_diff_point); - /* dont ch*/ if (do_feather) { diff_feather_points = BKE_mask_spline_feather_differentiated_points_with_resolution_ex( spline, resol, &tot_diff_feather_points); @@ -567,7 +567,7 @@ void BLI_maskrasterize_handle_init(MaskRasterHandle *mr_handle, struct Mask *mas BLI_assert(tot_diff_feather_points == tot_diff_point); - /* note: only added for convenience, we dont infact use these to scanfill, + /* note: only added for convenience, we don't infact use these to scanfill, * only to create feather faces after scanfill */ for (j = 0; j < tot_diff_feather_points; j++) { copy_v2_v2(co_feather, diff_feather_points[j]); @@ -816,41 +816,37 @@ float BLI_maskrasterize_handle_sample(MaskRasterHandle *mr_handle, const float x unsigned int i; MaskRasterLayer *layer = mr_handle->layers; - /* raycast vars*/ - - /* return */ + /* return value */ float value = 0.0f; for (i = 0; i < layers_tot; i++, layer++) { - float dist_ease; - float v; + float value_layer; if (BLI_in_rctf_v(&layer->bounds, xy)) { - /* --- hit (start) --- */ const float dist = 1.0f - layer_bucket_depth_from_xy(layer, xy); - dist_ease = (3.0f * dist * dist - 2.0f * dist * dist * dist); + const float dist_ease = (3.0f * dist * dist - 2.0f * dist * dist * dist); + + /* apply alpha */ + value_layer = dist_ease * layer->alpha; } else { - dist_ease = 0.0f; + value_layer = 0.0f; } - /* apply alpha */ - v = dist_ease * layer->alpha; - if (layer->blend_flag & MASK_BLENDFLAG_INVERT) { - v = 1.0f - v; + value_layer = 1.0f - value_layer; } switch (layer->blend) { case MASK_BLEND_SUBTRACT: { - value -= v; + value -= value_layer; break; } case MASK_BLEND_ADD: default: { - value += v; + value += value_layer; break; } } From 5e7f8b83edaa82caabfea3bfaa72ff27c8e0e9d1 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sat, 14 Jul 2012 20:29:17 +0000 Subject: [PATCH 019/108] mask rasterizer, render unclosed splines as lines. --- .../blenkernel/intern/mask_rasterize.c | 182 +++++++++++++----- 1 file changed, 138 insertions(+), 44 deletions(-) diff --git a/source/blender/blenkernel/intern/mask_rasterize.c b/source/blender/blenkernel/intern/mask_rasterize.c index d036e7eb15a..a08118e6fa2 100644 --- a/source/blender/blenkernel/intern/mask_rasterize.c +++ b/source/blender/blenkernel/intern/mask_rasterize.c @@ -46,6 +46,7 @@ #ifndef USE_RASKTER +#define SPLINE_RESOL_CAP 32 #define SPLINE_RESOL 32 #define BUCKET_PIXELS_PER_CELL 8 @@ -443,6 +444,11 @@ void BLI_maskrasterize_handle_init(MaskRasterHandle *mr_handle, struct Mask *mas for (masklay = mask->masklayers.first, masklay_index = 0; masklay; masklay = masklay->next, masklay_index++) { + const unsigned int tot_splines = BLI_countlist(&masklay->splines); + /* we need to store vertex ranges for open splines for filling */ + unsigned int (*open_spline_ranges)[2] = MEM_callocN(sizeof(open_spline_ranges) * tot_splines, __func__); + unsigned int open_spline_index = 0; + MaskSpline *spline; /* scanfill */ @@ -461,7 +467,7 @@ void BLI_maskrasterize_handle_init(MaskRasterHandle *mr_handle, struct Mask *mas BLI_scanfill_begin(&sf_ctx); for (spline = masklay->splines.first; spline; spline = spline->next) { - // const unsigned int is_cyclic = (spline->flag & MASK_SPLINE_CYCLIC) != 0; + const unsigned int is_cyclic = (spline->flag & MASK_SPLINE_CYCLIC) != 0; float (*diff_points)[2]; int tot_diff_point; @@ -535,58 +541,115 @@ void BLI_maskrasterize_handle_init(MaskRasterHandle *mr_handle, struct Mask *mas } } - copy_v2_v2(co, diff_points[0]); - sf_vert_prev = BLI_scanfill_vert_add(&sf_ctx, co); - sf_vert_prev->tmp.u = sf_vert_tot; - sf_vert_prev->keyindex = sf_vert_tot + tot_diff_point; /* absolute index of feather vert */ - sf_vert_tot++; - - /* TODO, an alternate functions so we can avoid double vector copy! */ - for (j = 1; j < tot_diff_point; j++) { - copy_v2_v2(co, diff_points[j]); - sf_vert = BLI_scanfill_vert_add(&sf_ctx, co); - sf_vert->tmp.u = sf_vert_tot; - sf_vert->keyindex = sf_vert_tot + tot_diff_point; /* absolute index of feather vert */ + if (is_cyclic) { + copy_v2_v2(co, diff_points[0]); + sf_vert_prev = BLI_scanfill_vert_add(&sf_ctx, co); + sf_vert_prev->tmp.u = sf_vert_tot; + sf_vert_prev->keyindex = sf_vert_tot + tot_diff_point; /* absolute index of feather vert */ sf_vert_tot++; - } - sf_vert = sf_vert_prev; - sf_vert_prev = sf_ctx.fillvertbase.last; - - for (j = 0; j < tot_diff_point; j++) { - ScanFillEdge *sf_edge = BLI_scanfill_edge_add(&sf_ctx, sf_vert_prev, sf_vert); - sf_edge->tmp.c = SF_EDGE_IS_BOUNDARY; - - sf_vert_prev = sf_vert; - sf_vert = sf_vert->next; - } - - if (diff_feather_points) { - float co_feather[3]; - co_feather[2] = 1.0f; - - BLI_assert(tot_diff_feather_points == tot_diff_point); - - /* note: only added for convenience, we don't infact use these to scanfill, - * only to create feather faces after scanfill */ - for (j = 0; j < tot_diff_feather_points; j++) { - copy_v2_v2(co_feather, diff_feather_points[j]); - sf_vert = BLI_scanfill_vert_add(&sf_ctx, co_feather); - - /* no need for these attrs */ -#if 0 + /* TODO, an alternate functions so we can avoid double vector copy! */ + for (j = 1; j < tot_diff_point; j++) { + copy_v2_v2(co, diff_points[j]); + sf_vert = BLI_scanfill_vert_add(&sf_ctx, co); sf_vert->tmp.u = sf_vert_tot; sf_vert->keyindex = sf_vert_tot + tot_diff_point; /* absolute index of feather vert */ -#endif - sf_vert->keyindex = SF_KEYINDEX_TEMP_ID; sf_vert_tot++; } - if (diff_feather_points) { - MEM_freeN(diff_feather_points); + sf_vert = sf_vert_prev; + sf_vert_prev = sf_ctx.fillvertbase.last; + + for (j = 0; j < tot_diff_point; j++) { + ScanFillEdge *sf_edge = BLI_scanfill_edge_add(&sf_ctx, sf_vert_prev, sf_vert); + sf_edge->tmp.c = SF_EDGE_IS_BOUNDARY; + + sf_vert_prev = sf_vert; + sf_vert = sf_vert->next; } - tot_feather_quads += tot_diff_point; + if (diff_feather_points) { + float co_feather[3]; + co_feather[2] = 1.0f; + + BLI_assert(tot_diff_feather_points == tot_diff_point); + + /* note: only added for convenience, we don't infact use these to scanfill, + * only to create feather faces after scanfill */ + for (j = 0; j < tot_diff_feather_points; j++) { + copy_v2_v2(co_feather, diff_feather_points[j]); + sf_vert = BLI_scanfill_vert_add(&sf_ctx, co_feather); + + /* no need for these attrs */ + #if 0 + sf_vert->tmp.u = sf_vert_tot; + sf_vert->keyindex = sf_vert_tot + tot_diff_point; /* absolute index of feather vert */ + #endif + sf_vert->keyindex = SF_KEYINDEX_TEMP_ID; + sf_vert_tot++; + } + + if (diff_feather_points) { + MEM_freeN(diff_feather_points); + } + + tot_feather_quads += tot_diff_point; + } + } + else { + /* unfilled spline (non cyclic) */ + if (diff_feather_points) { + + float co_diff[3]; + + float co_feather[3]; + co_feather[2] = 1.0f; + + + open_spline_ranges[open_spline_index ][0] = sf_vert_tot; + open_spline_ranges[open_spline_index ][1] = tot_diff_point; + open_spline_index++; + + + /* TODO, an alternate functions so we can avoid double vector copy! */ + for (j = 0; j < tot_diff_point; j++) { + + /* center vert */ + copy_v2_v2(co, diff_points[j]); + sf_vert = BLI_scanfill_vert_add(&sf_ctx, co); + sf_vert->tmp.u = sf_vert_tot; + sf_vert->keyindex = SF_KEYINDEX_TEMP_ID; + sf_vert_tot++; + + + /* feather vert A */ + copy_v2_v2(co_feather, diff_feather_points[j]); + sf_vert = BLI_scanfill_vert_add(&sf_ctx, co_feather); + sf_vert->tmp.u = sf_vert_tot; + sf_vert->keyindex = SF_KEYINDEX_TEMP_ID; + sf_vert_tot++; + + + /* feather vert B */ + sub_v2_v2v2(co_diff, co, co_feather); + add_v2_v2v2(co_feather, co, co_diff); + sf_vert = BLI_scanfill_vert_add(&sf_ctx, co_feather); + sf_vert->tmp.u = sf_vert_tot; + sf_vert->keyindex = SF_KEYINDEX_TEMP_ID; + sf_vert_tot++; + + tot_feather_quads += 2; + } + tot_feather_quads -= 2; + + MEM_freeN(diff_feather_points); + + /* ack these are infact tris, but they are extra faces so no matter, + * +1 becausing adding one vert results in 2 tris (joining the existing endpoints) + */ + // tot_feather_quads + ((SPLINE_RESOL_CAP + 1) * 2); + + } } } @@ -659,6 +722,37 @@ void BLI_maskrasterize_handle_init(MaskRasterHandle *mr_handle, struct Mask *mas } } + /* feather only splines */ + while (open_spline_index > 0) { + unsigned int start_vidx = open_spline_ranges[--open_spline_index][0]; + unsigned int tot_diff_point_sub1 = open_spline_ranges[ open_spline_index][1] - 1; + unsigned int k, j; + + j = start_vidx; + + /* subtract one since we reference next vertex triple */ + for (k = 0; k < tot_diff_point_sub1; k++, j += 3) { + + BLI_assert(j == start_vidx + (k * 3)); + + *(face++) = j + 0; + *(face++) = j + 1; + *(face++) = j + 4; /* next span */ + *(face++) = j + 3; /* next span */ + + face_index++; + + *(face++) = j + 0; + *(face++) = j + 3; /* next span */ + *(face++) = j + 5; /* next span */ + *(face++) = j + 2; + + face_index++; + } + } + + MEM_freeN(open_spline_ranges); + // fprintf(stderr, "%d %d\n", face_index, sf_face_tot + tot_feather_quads); BLI_assert(face_index == sf_tri_tot + tot_feather_quads); From 41fe8b9ea94fa6877d35a51567cd83b255431306 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sat, 14 Jul 2012 20:53:52 +0000 Subject: [PATCH 020/108] use a different setting for fill/cyclic - you may want to have unfilled cyclic curves. --- release/scripts/startup/bl_ui/space_clip.py | 4 +++- source/blender/blenkernel/intern/mask_rasterize.c | 7 +++---- source/blender/editors/mask/mask_draw.c | 3 +++ source/blender/makesdna/DNA_mask_types.h | 5 ++++- source/blender/makesrna/intern/rna_mask.c | 7 +++++++ 5 files changed, 20 insertions(+), 6 deletions(-) diff --git a/release/scripts/startup/bl_ui/space_clip.py b/release/scripts/startup/bl_ui/space_clip.py index d937837e5d1..874405bd66b 100644 --- a/release/scripts/startup/bl_ui/space_clip.py +++ b/release/scripts/startup/bl_ui/space_clip.py @@ -733,7 +733,9 @@ class CLIP_PT_active_mask_spline(Panel): col = layout.column() col.prop(spline, "weight_interpolation") - col.prop(spline, "use_cyclic") + rowsub = col.row() + rowsub.prop(spline, "use_cyclic") + rowsub.prop(spline, "use_fill") class CLIP_PT_active_mask_point(Panel): diff --git a/source/blender/blenkernel/intern/mask_rasterize.c b/source/blender/blenkernel/intern/mask_rasterize.c index a08118e6fa2..815f3ab34e3 100644 --- a/source/blender/blenkernel/intern/mask_rasterize.c +++ b/source/blender/blenkernel/intern/mask_rasterize.c @@ -467,7 +467,7 @@ void BLI_maskrasterize_handle_init(MaskRasterHandle *mr_handle, struct Mask *mas BLI_scanfill_begin(&sf_ctx); for (spline = masklay->splines.first; spline; spline = spline->next) { - const unsigned int is_cyclic = (spline->flag & MASK_SPLINE_CYCLIC) != 0; + const unsigned int is_fill = (spline->flag & MASK_SPLINE_NOFILL) == 0; float (*diff_points)[2]; int tot_diff_point; @@ -541,7 +541,7 @@ void BLI_maskrasterize_handle_init(MaskRasterHandle *mr_handle, struct Mask *mas } } - if (is_cyclic) { + if (is_fill) { copy_v2_v2(co, diff_points[0]); sf_vert_prev = BLI_scanfill_vert_add(&sf_ctx, co); sf_vert_prev->tmp.u = sf_vert_tot; @@ -597,7 +597,7 @@ void BLI_maskrasterize_handle_init(MaskRasterHandle *mr_handle, struct Mask *mas } } else { - /* unfilled spline (non cyclic) */ + /* unfilled spline */ if (diff_feather_points) { float co_diff[3]; @@ -605,7 +605,6 @@ void BLI_maskrasterize_handle_init(MaskRasterHandle *mr_handle, struct Mask *mas float co_feather[3]; co_feather[2] = 1.0f; - open_spline_ranges[open_spline_index ][0] = sf_vert_tot; open_spline_ranges[open_spline_index ][1] = tot_diff_point; open_spline_index++; diff --git a/source/blender/editors/mask/mask_draw.c b/source/blender/editors/mask/mask_draw.c index f080b9f96e7..f378d5452a4 100644 --- a/source/blender/editors/mask/mask_draw.c +++ b/source/blender/editors/mask/mask_draw.c @@ -388,6 +388,9 @@ static void draw_spline_curve(MaskLayer *masklay, MaskSpline *spline, mask_draw_curve_type(spline, feather_points, tot_feather_point, TRUE, is_smooth, is_active, rgb_tmp, draw_type); + + /* TODO, draw mirror values when MASK_SPLINE_NOFILL is set */ + MEM_freeN(feather_points); /* draw main curve */ diff --git a/source/blender/makesdna/DNA_mask_types.h b/source/blender/makesdna/DNA_mask_types.h index 52fedd72e86..4c2330965ee 100644 --- a/source/blender/makesdna/DNA_mask_types.h +++ b/source/blender/makesdna/DNA_mask_types.h @@ -137,7 +137,10 @@ typedef struct MaskLayer { /* MaskSpline->flag */ /* reserve (1 << 0) for SELECT */ -#define MASK_SPLINE_CYCLIC (1 << 1) +enum { + MASK_SPLINE_CYCLIC = (1 << 1), + MASK_SPLINE_NOFILL = (1 << 2) +}; /* MaskSpline->weight_interp */ #define MASK_SPLINE_INTERP_LINEAR 1 diff --git a/source/blender/makesrna/intern/rna_mask.c b/source/blender/makesrna/intern/rna_mask.c index b879d2b19f7..e6fd47985cb 100644 --- a/source/blender/makesrna/intern/rna_mask.c +++ b/source/blender/makesrna/intern/rna_mask.c @@ -566,6 +566,13 @@ static void rna_def_maskSpline(BlenderRNA *brna) RNA_def_property_boolean_sdna(prop, NULL, "flag", MASK_SPLINE_CYCLIC); RNA_def_property_ui_text(prop, "Cyclic", "Make this spline a closed loop"); RNA_def_property_update(prop, 0, "rna_Mask_update_data"); + + /* fill */ + prop = RNA_def_property(srna, "use_fill", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); + RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", MASK_SPLINE_NOFILL); + RNA_def_property_ui_text(prop, "Fill", "Make this spline filled"); + RNA_def_property_update(prop, 0, "rna_Mask_update_data"); } static void rna_def_mask_layer(BlenderRNA *brna) From 1cee8ea8ed5064b5ec32e00eef2654fd76b7a3f5 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sat, 14 Jul 2012 23:23:24 +0000 Subject: [PATCH 021/108] unfilled-cyclic curves now works as expected, also fix for own crash on 32bit systems. --- .../blenkernel/intern/mask_rasterize.c | 56 ++++++++++++++----- 1 file changed, 41 insertions(+), 15 deletions(-) diff --git a/source/blender/blenkernel/intern/mask_rasterize.c b/source/blender/blenkernel/intern/mask_rasterize.c index 815f3ab34e3..4093757fffd 100644 --- a/source/blender/blenkernel/intern/mask_rasterize.c +++ b/source/blender/blenkernel/intern/mask_rasterize.c @@ -96,6 +96,12 @@ typedef struct MaskRasterLayer { } MaskRasterLayer; +typedef struct MaskRasterSplineInfo { + unsigned int vertex_offset; + unsigned int vertex_total; + unsigned int is_cyclic; +} MaskRasterSplineInfo; + /** * opaque local struct for mask pixel lookup, each MaskLayer needs one of these */ @@ -107,7 +113,6 @@ struct MaskRasterHandle { rctf bounds; }; - /* --------------------------------------------------------------------- */ /* alloc / free functions */ /* --------------------------------------------------------------------- */ @@ -446,7 +451,7 @@ void BLI_maskrasterize_handle_init(MaskRasterHandle *mr_handle, struct Mask *mas const unsigned int tot_splines = BLI_countlist(&masklay->splines); /* we need to store vertex ranges for open splines for filling */ - unsigned int (*open_spline_ranges)[2] = MEM_callocN(sizeof(open_spline_ranges) * tot_splines, __func__); + MaskRasterSplineInfo *open_spline_ranges = MEM_callocN(sizeof(*open_spline_ranges) * tot_splines, __func__); unsigned int open_spline_index = 0; MaskSpline *spline; @@ -467,6 +472,7 @@ void BLI_maskrasterize_handle_init(MaskRasterHandle *mr_handle, struct Mask *mas BLI_scanfill_begin(&sf_ctx); for (spline = masklay->splines.first; spline; spline = spline->next) { + const unsigned int is_cyclic = (spline->flag & MASK_SPLINE_CYCLIC) != 0; const unsigned int is_fill = (spline->flag & MASK_SPLINE_NOFILL) == 0; float (*diff_points)[2]; @@ -605,8 +611,9 @@ void BLI_maskrasterize_handle_init(MaskRasterHandle *mr_handle, struct Mask *mas float co_feather[3]; co_feather[2] = 1.0f; - open_spline_ranges[open_spline_index ][0] = sf_vert_tot; - open_spline_ranges[open_spline_index ][1] = tot_diff_point; + open_spline_ranges[open_spline_index].vertex_offset = sf_vert_tot; + open_spline_ranges[open_spline_index].vertex_total = tot_diff_point; + open_spline_ranges[open_spline_index].is_cyclic = is_cyclic; open_spline_index++; @@ -639,7 +646,10 @@ void BLI_maskrasterize_handle_init(MaskRasterHandle *mr_handle, struct Mask *mas tot_feather_quads += 2; } - tot_feather_quads -= 2; + + if (!is_cyclic) { + tot_feather_quads -= 2; + } MEM_freeN(diff_feather_points); @@ -723,8 +733,8 @@ void BLI_maskrasterize_handle_init(MaskRasterHandle *mr_handle, struct Mask *mas /* feather only splines */ while (open_spline_index > 0) { - unsigned int start_vidx = open_spline_ranges[--open_spline_index][0]; - unsigned int tot_diff_point_sub1 = open_spline_ranges[ open_spline_index][1] - 1; + unsigned int start_vidx = open_spline_ranges[--open_spline_index].vertex_offset; + unsigned int tot_diff_point_sub1 = open_spline_ranges[ open_spline_index].vertex_total - 1; unsigned int k, j; j = start_vidx; @@ -734,17 +744,33 @@ void BLI_maskrasterize_handle_init(MaskRasterHandle *mr_handle, struct Mask *mas BLI_assert(j == start_vidx + (k * 3)); - *(face++) = j + 0; - *(face++) = j + 1; - *(face++) = j + 4; /* next span */ - *(face++) = j + 3; /* next span */ + *(face++) = j + 3; /* next span */ /* z 1 */ + *(face++) = j + 0; /* z 1 */ + *(face++) = j + 1; /* z 0 */ + *(face++) = j + 4; /* next span */ /* z 0 */ face_index++; - *(face++) = j + 0; - *(face++) = j + 3; /* next span */ - *(face++) = j + 5; /* next span */ - *(face++) = j + 2; + *(face++) = j + 0; /* z 1 */ + *(face++) = j + 3; /* next span */ /* z 1 */ + *(face++) = j + 5; /* next span */ /* z 0 */ + *(face++) = j + 2; /* z 0 */ + + face_index++; + } + + if (open_spline_ranges[open_spline_index].is_cyclic) { + *(face++) = start_vidx + 3; /* next span */ /* z 1 */ + *(face++) = j + 0; /* z 1 */ + *(face++) = j + 1; /* z 0 */ + *(face++) = start_vidx + 4; /* next span */ /* z 0 */ + + face_index++; + + *(face++) = j + 0; /* z 1 */ + *(face++) = start_vidx + 3; /* next span */ /* z 1 */ + *(face++) = start_vidx + 5; /* next span */ /* z 0 */ + *(face++) = j + 2; /* z 0 */ face_index++; } From 593163e6e5b97bb9006d4f2d45d667957291f54d Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sat, 14 Jul 2012 23:26:54 +0000 Subject: [PATCH 022/108] fix for minor error in previous commit (wasnt connecting right faces for cyclic mask), also avoid doing more area calculations then needed when checking if the mouse is moving away from uiBlock. --- source/blender/blenkernel/intern/mask_rasterize.c | 8 ++++---- source/blender/editors/interface/interface_handlers.c | 11 +++++------ 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/source/blender/blenkernel/intern/mask_rasterize.c b/source/blender/blenkernel/intern/mask_rasterize.c index 4093757fffd..fb1ea31456d 100644 --- a/source/blender/blenkernel/intern/mask_rasterize.c +++ b/source/blender/blenkernel/intern/mask_rasterize.c @@ -760,16 +760,16 @@ void BLI_maskrasterize_handle_init(MaskRasterHandle *mr_handle, struct Mask *mas } if (open_spline_ranges[open_spline_index].is_cyclic) { - *(face++) = start_vidx + 3; /* next span */ /* z 1 */ + *(face++) = start_vidx + 0; /* next span */ /* z 1 */ *(face++) = j + 0; /* z 1 */ *(face++) = j + 1; /* z 0 */ - *(face++) = start_vidx + 4; /* next span */ /* z 0 */ + *(face++) = start_vidx + 1; /* next span */ /* z 0 */ face_index++; *(face++) = j + 0; /* z 1 */ - *(face++) = start_vidx + 3; /* next span */ /* z 1 */ - *(face++) = start_vidx + 5; /* next span */ /* z 0 */ + *(face++) = start_vidx + 0; /* next span */ /* z 1 */ + *(face++) = start_vidx + 2; /* next span */ /* z 0 */ *(face++) = j + 2; /* z 0 */ face_index++; diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c index 613ab2fa6c8..0a9665ffc15 100644 --- a/source/blender/editors/interface/interface_handlers.c +++ b/source/blender/editors/interface/interface_handlers.c @@ -5937,14 +5937,13 @@ static int ui_mouse_motion_towards_check(uiBlock *block, uiPopupBlockHandle *men newp[0] = mx; newp[1] = my; - if (len_v2v2(oldp, newp) < 4.0f) + if (len_squared_v2v2(oldp, newp) < (4.0f * 4.0f)) return menu->dotowards; - closer = 0; - closer |= isect_point_tri_v2(newp, oldp, p1, p2); - closer |= isect_point_tri_v2(newp, oldp, p2, p3); - closer |= isect_point_tri_v2(newp, oldp, p3, p4); - closer |= isect_point_tri_v2(newp, oldp, p4, p1); + closer = (isect_point_tri_v2(newp, oldp, p1, p2) || + isect_point_tri_v2(newp, oldp, p2, p3) || + isect_point_tri_v2(newp, oldp, p3, p4) || + isect_point_tri_v2(newp, oldp, p4, p1)); if (!closer) menu->dotowards = 0; From f8bf58e0f21c59c4440165fbad55b082846b6b54 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sun, 15 Jul 2012 00:07:41 +0000 Subject: [PATCH 023/108] fix for some bugs when the mask layer was outside the view, also clamp the layer buckets within the view. --- .../blenkernel/intern/mask_rasterize.c | 98 +++++++++++++------ 1 file changed, 66 insertions(+), 32 deletions(-) diff --git a/source/blender/blenkernel/intern/mask_rasterize.c b/source/blender/blenkernel/intern/mask_rasterize.c index fb1ea31456d..7c5173645bf 100644 --- a/source/blender/blenkernel/intern/mask_rasterize.c +++ b/source/blender/blenkernel/intern/mask_rasterize.c @@ -298,6 +298,17 @@ static int layer_bucket_isect_test(MaskRasterLayer *layer, unsigned int face_ind } } +static void layer_bucket_init_dummy(MaskRasterLayer *layer) +{ + layer->buckets_x = 0; + layer->buckets_y = 0; + + layer->buckets_xy_scalar[0] = 0.0f; + layer->buckets_xy_scalar[1] = 0.0f; + + layer->buckets_face = NULL; +} + static void layer_bucket_init(MaskRasterLayer *layer, const float pixel_size) { MemArena *arena = BLI_memarena_new(1 << 16, __func__); @@ -363,34 +374,42 @@ static void layer_bucket_init(MaskRasterLayer *layer, const float pixel_size) /* not essential but may as will skip any faces outside the view */ if (!((xmax < 0.0f) || (ymax < 0.0f) || (xmin > 1.0f) || (ymin > 1.0f))) { - const unsigned int xi_min = (unsigned int) ((xmin - layer->bounds.xmin) * layer->buckets_xy_scalar[0]); - 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; + CLAMP(xmin, 0.0f, 1.0f); + CLAMP(ymin, 0.0f, 1.0f); + CLAMP(xmax, 0.0f, 1.0f); + CLAMP(ymax, 0.0f, 1.0f); - 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 */ + { + const unsigned int xi_min = (unsigned int) ((xmin - layer->bounds.xmin) * layer->buckets_xy_scalar[0]); + 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); - BLI_assert(xi < layer->buckets_x); - BLI_assert(yi < layer->buckets_y); - BLI_assert(bucket_index < bucket_tot); + unsigned int xi, yi; - /* 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, - bucket_max_rad_squared)) - { - BLI_linklist_prepend_arena(&bucketstore[bucket_index], face_index_void, arena); - bucketstore_tot[bucket_index]++; + 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); + + /* 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, + bucket_max_rad_squared)) + { + BLI_linklist_prepend_arena(&bucketstore[bucket_index], face_index_void, arena); + bucketstore_tot[bucket_index]++; + } } } } @@ -436,6 +455,7 @@ void BLI_maskrasterize_handle_init(MaskRasterHandle *mr_handle, struct Mask *mas const short do_aspect_correct, const short do_mask_aa, const short do_feather) { + const rctf default_bounds = {0.0f, 1.0f, 0.0f, 1.0f}; const int resol = SPLINE_RESOL; /* TODO: real size */ const float pixel_size = 1.0f / MIN2(width, height); @@ -785,19 +805,33 @@ void BLI_maskrasterize_handle_init(MaskRasterHandle *mr_handle, struct Mask *mas { MaskRasterLayer *layer = &mr_handle->layers[masklay_index]; - layer->face_tot = sf_tri_tot + tot_feather_quads; - layer->face_coords = face_coords; - layer->face_array = face_array; - layer->bounds = bounds; + if (BLI_isect_rctf(&default_bounds, &bounds, &bounds)) { + layer->face_tot = sf_tri_tot + tot_feather_quads; + layer->face_coords = face_coords; + layer->face_array = face_array; + layer->bounds = bounds; + + layer_bucket_init(layer, pixel_size); + + BLI_union_rctf(&mr_handle->bounds, &bounds); + } + else { + MEM_freeN(face_coords); + MEM_freeN(face_array); + + layer->face_tot = 0; + layer->face_coords = NULL; + layer->face_array = NULL; + + layer_bucket_init_dummy(layer); + + BLI_rctf_init(&layer->bounds, -1.0f, -1.0f, -1.0f, -1.0f); + } /* copy as-is */ layer->alpha = masklay->alpha; layer->blend = masklay->blend; layer->blend_flag = masklay->blend_flag; - - layer_bucket_init(layer, pixel_size); - - BLI_union_rctf(&mr_handle->bounds, &bounds); } /* printf("tris %d, feather tris %d\n", sf_tri_tot, tot_feather_quads); */ From 7cc5af4ef3869f6a1d2766eb5643f94e2f540cfa Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sun, 15 Jul 2012 00:29:56 +0000 Subject: [PATCH 024/108] minor refactor for rect functions. more consistent naming. --- .../blenkernel/intern/mask_rasterize.c | 10 ++++----- source/blender/blenlib/BLI_rect.h | 22 +++++++++---------- source/blender/blenlib/intern/rct.c | 20 ++++++++--------- .../operations/COM_KeyingScreenOperation.cpp | 2 +- source/blender/editors/gpencil/drawgpencil.c | 2 +- .../editors/interface/interface_draw.c | 2 +- source/blender/editors/screen/area.c | 2 +- source/blender/editors/screen/screen_ops.c | 2 +- source/blender/editors/sculpt_paint/sculpt.c | 2 +- source/blender/editors/space_file/file_ops.c | 4 ++-- .../editors/space_image/image_buttons.c | 2 +- source/blender/editors/space_node/drawnode.c | 4 ++-- source/blender/editors/space_node/node_edit.c | 2 +- .../blender/editors/space_node/node_select.c | 2 +- .../blender/editors/space_node/node_state.c | 2 +- .../editors/space_sequencer/sequencer_edit.c | 2 +- .../space_sequencer/sequencer_select.c | 2 +- .../blender/editors/space_view3d/drawobject.c | 2 +- .../editors/space_view3d/view3d_draw.c | 2 +- .../editors/space_view3d/view3d_view.c | 2 +- source/blender/render/intern/source/shadbuf.c | 2 +- source/blender/windowmanager/intern/wm_draw.c | 4 ++-- .../windowmanager/intern/wm_event_system.c | 2 +- 23 files changed, 49 insertions(+), 49 deletions(-) diff --git a/source/blender/blenkernel/intern/mask_rasterize.c b/source/blender/blenkernel/intern/mask_rasterize.c index 7c5173645bf..cd3b6c71c09 100644 --- a/source/blender/blenkernel/intern/mask_rasterize.c +++ b/source/blender/blenkernel/intern/mask_rasterize.c @@ -403,9 +403,9 @@ static void layer_bucket_init(MaskRasterLayer *layer, const float pixel_size) * 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, - bucket_max_rad_squared)) + xi, yi, + bucket_size_x, bucket_size_y, + bucket_max_rad_squared)) { BLI_linklist_prepend_arena(&bucketstore[bucket_index], face_index_void, arena); bucketstore_tot[bucket_index]++; @@ -805,7 +805,7 @@ void BLI_maskrasterize_handle_init(MaskRasterHandle *mr_handle, struct Mask *mas { MaskRasterLayer *layer = &mr_handle->layers[masklay_index]; - if (BLI_isect_rctf(&default_bounds, &bounds, &bounds)) { + if (BLI_rctf_isect(&default_bounds, &bounds, &bounds)) { layer->face_tot = sf_tri_tot + tot_feather_quads; layer->face_coords = face_coords; layer->face_array = face_array; @@ -813,7 +813,7 @@ void BLI_maskrasterize_handle_init(MaskRasterHandle *mr_handle, struct Mask *mas layer_bucket_init(layer, pixel_size); - BLI_union_rctf(&mr_handle->bounds, &bounds); + BLI_rctf_union(&mr_handle->bounds, &bounds); } else { MEM_freeN(face_coords); diff --git a/source/blender/blenlib/BLI_rect.h b/source/blender/blenlib/BLI_rect.h index 8a9794b77c9..1c06e107c1f 100644 --- a/source/blender/blenlib/BLI_rect.h +++ b/source/blender/blenlib/BLI_rect.h @@ -49,23 +49,23 @@ void BLI_rctf_init_minmax(struct rctf *rect); void BLI_rcti_do_minmax_v(struct rcti *rect, const int xy[2]); void BLI_rctf_do_minmax_v(struct rctf *rect, const float xy[2]); -void BLI_translate_rctf(struct rctf *rect, float x, float y); -void BLI_translate_rcti(struct rcti *rect, int x, int y); -void BLI_resize_rcti(struct rcti *rect, int x, int y); -void BLI_resize_rctf(struct rctf *rect, float x, float y); +void BLI_rctf_translate(struct rctf *rect, float x, float y); +void BLI_rcti_translate(struct rcti *rect, int x, int y); +void BLI_rcti_resize(struct rcti *rect, int x, int y); +void BLI_rctf_resize(struct rctf *rect, float x, float y); int BLI_in_rcti(const struct rcti *rect, const int x, const int y); int BLI_in_rcti_v(const struct rcti *rect, const int xy[2]); int BLI_in_rctf(const struct rctf *rect, const float x, const float y); int BLI_in_rctf_v(const struct rctf *rect, const float xy[2]); -int BLI_segment_in_rcti(const struct rcti *rect, const int s1[2], const int s2[2]); +int BLI_rcti_isect_segment(const struct rcti *rect, const int s1[2], const int s2[2]); #if 0 /* NOT NEEDED YET */ -int BLI_segment_in_rctf(struct rcti *rect, int s1[2], int s2[2]); +int BLI_rctf_isect_segment(struct rcti *rect, int s1[2], int s2[2]); #endif -int BLI_isect_rctf(const struct rctf *src1, const struct rctf *src2, struct rctf *dest); -int BLI_isect_rcti(const struct rcti *src1, const struct rcti *src2, struct rcti *dest); -void BLI_union_rctf(struct rctf *rctf1, const struct rctf *rctf2); -void BLI_union_rcti(struct rcti *rcti1, const struct rcti *rcti2); -void BLI_copy_rcti_rctf(struct rcti *tar, const struct rctf *src); +int BLI_rctf_isect(const struct rctf *src1, const struct rctf *src2, struct rctf *dest); +int BLI_rcti_isect(const struct rcti *src1, const struct rcti *src2, struct rcti *dest); +void BLI_rctf_union(struct rctf *rctf1, const struct rctf *rctf2); +void BLI_rcti_union(struct rcti *rcti1, const struct rcti *rcti2); +void BLI_rcti_rctf_copy(struct rcti *tar, const struct rctf *src); void print_rctf(const char *str, const struct rctf *rect); void print_rcti(const char *str, const struct rcti *rect); diff --git a/source/blender/blenlib/intern/rct.c b/source/blender/blenlib/intern/rct.c index bdca1bb51bd..658d45ad171 100644 --- a/source/blender/blenlib/intern/rct.c +++ b/source/blender/blenlib/intern/rct.c @@ -115,7 +115,7 @@ static int isect_segments(const int v1[2], const int v2[2], const int v3[2], con } } -int BLI_segment_in_rcti(const rcti *rect, const int s1[2], const int s2[2]) +int BLI_rcti_isect_segment(const rcti *rect, const int s1[2], const int s2[2]) { /* first do outside-bounds check for both points of the segment */ if (s1[0] < rect->xmin && s2[0] < rect->xmin) return 0; @@ -150,7 +150,7 @@ int BLI_segment_in_rcti(const rcti *rect, const int s1[2], const int s2[2]) } } -void BLI_union_rctf(rctf *rct1, const rctf *rct2) +void BLI_rctf_union(rctf *rct1, const rctf *rct2) { if (rct1->xmin > rct2->xmin) rct1->xmin = rct2->xmin; if (rct1->xmax < rct2->xmax) rct1->xmax = rct2->xmax; @@ -158,7 +158,7 @@ void BLI_union_rctf(rctf *rct1, const rctf *rct2) if (rct1->ymax < rct2->ymax) rct1->ymax = rct2->ymax; } -void BLI_union_rcti(rcti *rct1, const rcti *rct2) +void BLI_rcti_union(rcti *rct1, const rcti *rct2) { if (rct1->xmin > rct2->xmin) rct1->xmin = rct2->xmin; if (rct1->xmax < rct2->xmax) rct1->xmax = rct2->xmax; @@ -234,14 +234,14 @@ void BLI_rctf_do_minmax_v(struct rctf *rect, const float xy[2]) if (xy[1] > rect->ymax) rect->ymax = xy[1]; } -void BLI_translate_rcti(rcti *rect, int x, int y) +void BLI_rcti_translate(rcti *rect, int x, int y) { rect->xmin += x; rect->ymin += y; rect->xmax += x; rect->ymax += y; } -void BLI_translate_rctf(rctf *rect, float x, float y) +void BLI_rctf_translate(rctf *rect, float x, float y) { rect->xmin += x; rect->ymin += y; @@ -250,7 +250,7 @@ void BLI_translate_rctf(rctf *rect, float x, float y) } /* change width & height around the central location */ -void BLI_resize_rcti(rcti *rect, int x, int y) +void BLI_rcti_resize(rcti *rect, int x, int y) { rect->xmin = rect->xmax = (rect->xmax + rect->xmin) / 2; rect->ymin = rect->ymax = (rect->ymax + rect->ymin) / 2; @@ -260,7 +260,7 @@ void BLI_resize_rcti(rcti *rect, int x, int y) rect->ymax = rect->ymin + y; } -void BLI_resize_rctf(rctf *rect, float x, float y) +void BLI_rctf_resize(rctf *rect, float x, float y) { rect->xmin = rect->xmax = (rect->xmax + rect->xmin) * 0.5f; rect->ymin = rect->ymax = (rect->ymax + rect->ymin) * 0.5f; @@ -270,7 +270,7 @@ void BLI_resize_rctf(rctf *rect, float x, float y) rect->ymax = rect->ymin + y; } -int BLI_isect_rctf(const rctf *src1, const rctf *src2, rctf *dest) +int BLI_rctf_isect(const rctf *src1, const rctf *src2, rctf *dest) { float xmin, xmax; float ymin, ymax; @@ -300,7 +300,7 @@ int BLI_isect_rctf(const rctf *src1, const rctf *src2, rctf *dest) } } -int BLI_isect_rcti(const rcti *src1, const rcti *src2, rcti *dest) +int BLI_rcti_isect(const rcti *src1, const rcti *src2, rcti *dest) { int xmin, xmax; int ymin, ymax; @@ -330,7 +330,7 @@ int BLI_isect_rcti(const rcti *src1, const rcti *src2, rcti *dest) } } -void BLI_copy_rcti_rctf(rcti *tar, const rctf *src) +void BLI_rcti_rctf_copy(rcti *tar, const rctf *src) { tar->xmin = floorf(src->xmin + 0.5f); tar->xmax = floorf((src->xmax - src->xmin) + 0.5f); diff --git a/source/blender/compositor/operations/COM_KeyingScreenOperation.cpp b/source/blender/compositor/operations/COM_KeyingScreenOperation.cpp index fd3a8d64357..87a8fd22758 100644 --- a/source/blender/compositor/operations/COM_KeyingScreenOperation.cpp +++ b/source/blender/compositor/operations/COM_KeyingScreenOperation.cpp @@ -247,7 +247,7 @@ void *KeyingScreenOperation::initializeTileData(rcti *rect) tile_data = (TileData *) MEM_callocN(sizeof(TileData), "keying screen tile data"); for (i = 0; i < triangulation->triangles_total; i++) { - bool ok = BLI_isect_rctf(&rect_float, &triangulation->triangles_AABB[i], NULL); + bool ok = BLI_rctf_isect(&rect_float, &triangulation->triangles_AABB[i], NULL); if (ok) { tile_data->triangles_total++; diff --git a/source/blender/editors/gpencil/drawgpencil.c b/source/blender/editors/gpencil/drawgpencil.c index bc912fc8c76..7906d632f86 100644 --- a/source/blender/editors/gpencil/drawgpencil.c +++ b/source/blender/editors/gpencil/drawgpencil.c @@ -769,7 +769,7 @@ void draw_gpencil_view3d(Scene *scene, View3D *v3d, ARegion *ar, short only3d) if ((rv3d->persp == RV3D_CAMOB) && !(G.f & G_RENDER_OGL)) { rctf rectf; ED_view3d_calc_camera_border(scene, ar, v3d, rv3d, &rectf, TRUE); /* no shift */ - BLI_copy_rcti_rctf(&rect, &rectf); + BLI_rcti_rctf_copy(&rect, &rectf); } else { rect.xmin = 0; diff --git a/source/blender/editors/interface/interface_draw.c b/source/blender/editors/interface/interface_draw.c index e576b71e442..1d88838ecc5 100644 --- a/source/blender/editors/interface/interface_draw.c +++ b/source/blender/editors/interface/interface_draw.c @@ -1353,7 +1353,7 @@ void ui_draw_but_CURVE(ARegion *ar, uiBut *but, uiWidgetColors *wcol, rcti *rect scissor_new.ymin = ar->winrct.ymin + rect->ymin; scissor_new.xmax = ar->winrct.xmin + rect->xmax; scissor_new.ymax = ar->winrct.ymin + rect->ymax; - BLI_isect_rcti(&scissor_new, &ar->winrct, &scissor_new); + BLI_rcti_isect(&scissor_new, &ar->winrct, &scissor_new); glScissor(scissor_new.xmin, scissor_new.ymin, scissor_new.xmax - scissor_new.xmin, scissor_new.ymax - scissor_new.ymin); /* calculate offset and zoom */ diff --git a/source/blender/editors/screen/area.c b/source/blender/editors/screen/area.c index 714700ec8f1..f8ca150e28e 100644 --- a/source/blender/editors/screen/area.c +++ b/source/blender/editors/screen/area.c @@ -403,7 +403,7 @@ void region_scissor_winrct(ARegion *ar, rcti *winrct) while (ar->prev) { ar = ar->prev; - if (BLI_isect_rcti(winrct, &ar->winrct, NULL)) { + if (BLI_rcti_isect(winrct, &ar->winrct, NULL)) { if (ar->flag & RGN_FLAG_HIDDEN) ; else if (ar->alignment & RGN_SPLIT_PREV) ; else if (ar->alignment == RGN_OVERLAP_LEFT) { diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c index 547e7bc8e5a..c97e91f74b6 100644 --- a/source/blender/editors/screen/screen_ops.c +++ b/source/blender/editors/screen/screen_ops.c @@ -827,7 +827,7 @@ static int area_dupli_invoke(bContext *C, wmOperator *op, wmEvent *event) /* adds window to WM */ rect = sa->totrct; - BLI_translate_rcti(&rect, win->posx, win->posy); + BLI_rcti_translate(&rect, win->posx, win->posy); newwin = WM_window_open(C, &rect); /* allocs new screen and adds to newly created window, using window size */ diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c index bfac2922c2b..35d508c5a1f 100644 --- a/source/blender/editors/sculpt_paint/sculpt.c +++ b/source/blender/editors/sculpt_paint/sculpt.c @@ -369,7 +369,7 @@ static int sculpt_get_redraw_rect(ARegion *ar, RegionView3D *rv3d, ss = ob->sculpt; if (ss->cache) { if (!BLI_rcti_is_empty(&ss->cache->previous_r)) - BLI_union_rcti(rect, &ss->cache->previous_r); + BLI_rcti_union(rect, &ss->cache->previous_r); } return 1; diff --git a/source/blender/editors/space_file/file_ops.c b/source/blender/editors/space_file/file_ops.c index 9591e624296..6856ce996e7 100644 --- a/source/blender/editors/space_file/file_ops.c +++ b/source/blender/editors/space_file/file_ops.c @@ -248,7 +248,7 @@ static int file_border_select_modal(bContext *C, wmOperator *op, wmEvent *event) rect.xmax = RNA_int_get(op->ptr, "xmax"); rect.ymax = RNA_int_get(op->ptr, "ymax"); - BLI_isect_rcti(&(ar->v2d.mask), &rect, &rect); + BLI_rcti_isect(&(ar->v2d.mask), &rect, &rect); sel = file_selection_get(C, &rect, 0); if ( (sel.first != params->sel_first) || (sel.last != params->sel_last) ) { @@ -288,7 +288,7 @@ static int file_border_select_exec(bContext *C, wmOperator *op) file_deselect_all(sfile, SELECTED_FILE); } - BLI_isect_rcti(&(ar->v2d.mask), &rect, &rect); + BLI_rcti_isect(&(ar->v2d.mask), &rect, &rect); ret = file_select(C, &rect, select ? FILE_SEL_ADD : FILE_SEL_REMOVE, 0); if (FILE_SELECT_DIR == ret) { diff --git a/source/blender/editors/space_image/image_buttons.c b/source/blender/editors/space_image/image_buttons.c index 99969405f9c..7989a8e1b34 100644 --- a/source/blender/editors/space_image/image_buttons.c +++ b/source/blender/editors/space_image/image_buttons.c @@ -280,7 +280,7 @@ static void preview_cb(struct ScrArea *sa, struct uiBlock *block) ui_graphics_to_window_rct(sa->win, &dispf, disprect); /* correction for gla draw */ - BLI_translate_rcti(disprect, -curarea->winrct.xmin, -curarea->winrct.ymin); + BLI_rcti_translate(disprect, -curarea->winrct.xmin, -curarea->winrct.ymin); calc_image_view(sima, 'p'); // printf("winrct %d %d %d %d\n", disprect->xmin, disprect->ymin,disprect->xmax, disprect->ymax); diff --git a/source/blender/editors/space_node/drawnode.c b/source/blender/editors/space_node/drawnode.c index 2a5739db56f..87a07407ee6 100644 --- a/source/blender/editors/space_node/drawnode.c +++ b/source/blender/editors/space_node/drawnode.c @@ -523,7 +523,7 @@ static void node_update_group(const bContext *C, bNodeTree *ntree, bNode *gnode) counter = 0; } else - BLI_union_rctf(rect, &node->totr); + BLI_rctf_union(rect, &node->totr); } /* add some room for links to group sockets */ @@ -954,7 +954,7 @@ static void node_update_frame(const bContext *UNUSED(C), bNodeTree *ntree, bNode data->flag &= ~NODE_FRAME_RESIZEABLE; } else - BLI_union_rctf(&rect, &noderect); + BLI_rctf_union(&rect, &noderect); } /* now adjust the frame size from view-space bounding box */ diff --git a/source/blender/editors/space_node/node_edit.c b/source/blender/editors/space_node/node_edit.c index c4e72fa4a51..82f3eb1890d 100644 --- a/source/blender/editors/space_node/node_edit.c +++ b/source/blender/editors/space_node/node_edit.c @@ -1521,7 +1521,7 @@ static bNode *visible_node(SpaceNode *snode, rctf *rct) bNode *node; for (node = snode->edittree->nodes.last; node; node = node->prev) { - if (BLI_isect_rctf(&node->totr, rct, NULL)) + if (BLI_rctf_isect(&node->totr, rct, NULL)) break; } return node; diff --git a/source/blender/editors/space_node/node_select.c b/source/blender/editors/space_node/node_select.c index e7be750928d..1ea763a413d 100644 --- a/source/blender/editors/space_node/node_select.c +++ b/source/blender/editors/space_node/node_select.c @@ -474,7 +474,7 @@ static int node_borderselect_exec(bContext *C, wmOperator *op) UI_view2d_region_to_view(&ar->v2d, rect.xmax, rect.ymax, &rectf.xmax, &rectf.ymax); for (node= snode->edittree->nodes.first; node; node= node->next) { - if (BLI_isect_rctf(&rectf, &node->totr, NULL)) { + if (BLI_rctf_isect(&rectf, &node->totr, NULL)) { if (gesture_mode==GESTURE_MODAL_SELECT) node_select(node); else diff --git a/source/blender/editors/space_node/node_state.c b/source/blender/editors/space_node/node_state.c index 5463d4a8ff0..b21d31ad619 100644 --- a/source/blender/editors/space_node/node_state.c +++ b/source/blender/editors/space_node/node_state.c @@ -78,7 +78,7 @@ static void snode_home(ScrArea *UNUSED(sa), ARegion *ar, SpaceNode* snode) ar->v2d.cur= node->totr; } else { - BLI_union_rctf(cur, &node->totr); + BLI_rctf_union(cur, &node->totr); } } } diff --git a/source/blender/editors/space_sequencer/sequencer_edit.c b/source/blender/editors/space_sequencer/sequencer_edit.c index 1c3d2b61488..82e2730c59e 100644 --- a/source/blender/editors/space_sequencer/sequencer_edit.c +++ b/source/blender/editors/space_sequencer/sequencer_edit.c @@ -2124,7 +2124,7 @@ static int sequencer_view_zoom_ratio_exec(bContext *C, wmOperator *op) float facx = (v2d->mask.xmax - v2d->mask.xmin) / winx; float facy = (v2d->mask.ymax - v2d->mask.ymin) / winy; - BLI_resize_rctf(&v2d->cur, (int)(winx * facx * ratio) + 1, (int)(winy * facy * ratio) + 1); + BLI_rctf_resize(&v2d->cur, (int)(winx * facx * ratio) + 1, (int)(winy * facy * ratio) + 1); ED_region_tag_redraw(CTX_wm_region(C)); diff --git a/source/blender/editors/space_sequencer/sequencer_select.c b/source/blender/editors/space_sequencer/sequencer_select.c index a55f0edc06c..7849f84e777 100644 --- a/source/blender/editors/space_sequencer/sequencer_select.c +++ b/source/blender/editors/space_sequencer/sequencer_select.c @@ -875,7 +875,7 @@ static int sequencer_borderselect_exec(bContext *C, wmOperator *op) for (seq = ed->seqbasep->first; seq; seq = seq->next) { seq_rectf(seq, &rq); - if (BLI_isect_rctf(&rq, &rectf, NULL)) { + if (BLI_rctf_isect(&rq, &rectf, NULL)) { if (selecting) seq->flag |= SELECT; else seq->flag &= ~SEQ_ALLSEL; recurs_sel_seq(seq); diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c index b651dfcb8db..c1b2e2f07e2 100644 --- a/source/blender/editors/space_view3d/drawobject.c +++ b/source/blender/editors/space_view3d/drawobject.c @@ -2162,7 +2162,7 @@ static void mesh_foreachScreenEdge__mapFunc(void *userData, int index, const flo /* make an int copy */ int s_int[2][2] = {{s[0][0], s[0][1]}, {s[1][0], s[1][1]}}; - if (!BLI_segment_in_rcti(&data->win_rect, s_int[0], s_int[1])) { + if (!BLI_rcti_isect_segment(&data->win_rect, s_int[0], s_int[1])) { return; } } diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c index 1ace4688991..1dbc40a0c07 100644 --- a/source/blender/editors/space_view3d/view3d_draw.c +++ b/source/blender/editors/space_view3d/view3d_draw.c @@ -2028,7 +2028,7 @@ void view3d_update_depths_rect(ARegion *ar, ViewDepths *d, rcti *rect) r.ymax = ar->winy - 1; /* Constrain rect to depth bounds */ - BLI_isect_rcti(&r, rect, rect); + BLI_rcti_isect(&r, rect, rect); /* assign values to compare with the ViewDepths */ x = rect->xmin; diff --git a/source/blender/editors/space_view3d/view3d_view.c b/source/blender/editors/space_view3d/view3d_view.c index bc41ecd1dc5..3abfda78ec3 100644 --- a/source/blender/editors/space_view3d/view3d_view.c +++ b/source/blender/editors/space_view3d/view3d_view.c @@ -1786,7 +1786,7 @@ static int game_engine_exec(bContext *C, wmOperator *op) cam_frame.xmax = cam_framef.xmax + ar->winrct.xmin; cam_frame.ymin = cam_framef.ymin + ar->winrct.ymin; cam_frame.ymax = cam_framef.ymax + ar->winrct.ymin; - BLI_isect_rcti(&ar->winrct, &cam_frame, &cam_frame); + BLI_rcti_isect(&ar->winrct, &cam_frame, &cam_frame); } else { cam_frame.xmin = ar->winrct.xmin; diff --git a/source/blender/render/intern/source/shadbuf.c b/source/blender/render/intern/source/shadbuf.c index e13da98ecb4..9995a3cbd17 100644 --- a/source/blender/render/intern/source/shadbuf.c +++ b/source/blender/render/intern/source/shadbuf.c @@ -1815,7 +1815,7 @@ static void isb_bsp_face_inside(ISBBranch *bspn, BSPFace *face) return; /* if face boundbox is outside of branch rect, give up */ - if (0==BLI_isect_rctf((rctf *)&face->box, (rctf *)&bspn->box, NULL)) + if (0==BLI_rctf_isect((rctf *)&face->box, (rctf *)&bspn->box, NULL)) return; /* test all points inside branch */ diff --git a/source/blender/windowmanager/intern/wm_draw.c b/source/blender/windowmanager/intern/wm_draw.c index ff1f47cbbaa..8652870e280 100644 --- a/source/blender/windowmanager/intern/wm_draw.c +++ b/source/blender/windowmanager/intern/wm_draw.c @@ -193,7 +193,7 @@ static void wm_flush_regions_down(bScreen *screen, rcti *dirty) for (sa = screen->areabase.first; sa; sa = sa->next) { for (ar = sa->regionbase.first; ar; ar = ar->next) { - if (BLI_isect_rcti(dirty, &ar->winrct, NULL)) { + if (BLI_rcti_isect(dirty, &ar->winrct, NULL)) { ar->do_draw = RGN_DRAW; memset(&ar->drawrct, 0, sizeof(ar->drawrct)); ar->swap = WIN_NONE_OK; @@ -208,7 +208,7 @@ static void wm_flush_regions_up(bScreen *screen, rcti *dirty) ARegion *ar; for (ar = screen->regionbase.first; ar; ar = ar->next) { - if (BLI_isect_rcti(dirty, &ar->winrct, NULL)) { + if (BLI_rcti_isect(dirty, &ar->winrct, NULL)) { ar->do_draw = RGN_DRAW; memset(&ar->drawrct, 0, sizeof(ar->drawrct)); ar->swap = WIN_NONE_OK; diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c index 4b762f94d34..b591805f288 100644 --- a/source/blender/windowmanager/intern/wm_event_system.c +++ b/source/blender/windowmanager/intern/wm_event_system.c @@ -1636,7 +1636,7 @@ static int handler_boundbox_test(wmEventHandler *handler, wmEvent *event) if (handler->bbwin) { if (handler->bblocal) { rcti rect = *handler->bblocal; - BLI_translate_rcti(&rect, handler->bbwin->xmin, handler->bbwin->ymin); + BLI_rcti_translate(&rect, handler->bbwin->xmin, handler->bbwin->ymin); if (BLI_in_rcti_v(&rect, &event->x)) return 1; From 02bac0bebfcf7f56d5ff7f04a122ec8144424e3d Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sun, 15 Jul 2012 03:11:07 +0000 Subject: [PATCH 025/108] falloff option for mask layers --- release/scripts/startup/bl_ui/space_clip.py | 1 + .../blenkernel/intern/mask_rasterize.c | 29 ++++++++++++++++--- source/blender/makesdna/DNA_mask_types.h | 2 ++ source/blender/makesrna/intern/rna_mask.c | 7 +++++ 4 files changed, 35 insertions(+), 4 deletions(-) diff --git a/release/scripts/startup/bl_ui/space_clip.py b/release/scripts/startup/bl_ui/space_clip.py index 874405bd66b..ac724518e85 100644 --- a/release/scripts/startup/bl_ui/space_clip.py +++ b/release/scripts/startup/bl_ui/space_clip.py @@ -707,6 +707,7 @@ class CLIP_PT_mask_layers(Panel): row.prop(active_layer, "invert", text="", icon='IMAGE_ALPHA') layout.prop(active_layer, "blend") + layout.prop(active_layer, "falloff") class CLIP_PT_active_mask_spline(Panel): diff --git a/source/blender/blenkernel/intern/mask_rasterize.c b/source/blender/blenkernel/intern/mask_rasterize.c index cd3b6c71c09..b415e9f1ba8 100644 --- a/source/blender/blenkernel/intern/mask_rasterize.c +++ b/source/blender/blenkernel/intern/mask_rasterize.c @@ -32,6 +32,7 @@ #include "DNA_vec_types.h" #include "DNA_mask_types.h" +#include "DNA_scene_types.h" #include "BLI_utildefines.h" #include "BLI_scanfill.h" @@ -93,6 +94,7 @@ typedef struct MaskRasterLayer { float alpha; char blend; char blend_flag; + char falloff; } MaskRasterLayer; @@ -832,6 +834,7 @@ void BLI_maskrasterize_handle_init(MaskRasterHandle *mr_handle, struct Mask *mas layer->alpha = masklay->alpha; layer->blend = masklay->blend; layer->blend_flag = masklay->blend_flag; + layer->falloff = masklay->falloff; } /* printf("tris %d, feather tris %d\n", sf_tri_tot, tot_feather_quads); */ @@ -976,11 +979,29 @@ float BLI_maskrasterize_handle_sample(MaskRasterHandle *mr_handle, const float x float value_layer; if (BLI_in_rctf_v(&layer->bounds, xy)) { - const float dist = 1.0f - layer_bucket_depth_from_xy(layer, xy); - const float dist_ease = (3.0f * dist * dist - 2.0f * dist * dist * dist); + float val = 1.0f - layer_bucket_depth_from_xy(layer, xy); - /* apply alpha */ - value_layer = dist_ease * layer->alpha; + switch (layer->falloff) { + case PROP_SMOOTH: + /* ease - gives less hard lines for dilate/erode feather */ + val = (3.0f * val * val - 2.0f * val * val * val); + break; + case PROP_SPHERE: + val = sqrtf(2.0f * val - val * val); + break; + case PROP_ROOT: + val = sqrtf(val); + break; + case PROP_SHARP: + val = val * val; + break; + case PROP_LIN: + default: + /* nothing */ + break; + } + + value_layer = val * layer->alpha; } else { value_layer = 0.0f; diff --git a/source/blender/makesdna/DNA_mask_types.h b/source/blender/makesdna/DNA_mask_types.h index 4c2330965ee..dd9ea508723 100644 --- a/source/blender/makesdna/DNA_mask_types.h +++ b/source/blender/makesdna/DNA_mask_types.h @@ -127,6 +127,8 @@ typedef struct MaskLayer { float alpha; char blend; char blend_flag; + char falloff; + char pad[7]; char flag; /* for animation */ char restrictflag; /* matching 'Object' flag of the same name - eventually use in the outliner */ diff --git a/source/blender/makesrna/intern/rna_mask.c b/source/blender/makesrna/intern/rna_mask.c index e6fd47985cb..2b89dd02dae 100644 --- a/source/blender/makesrna/intern/rna_mask.c +++ b/source/blender/makesrna/intern/rna_mask.c @@ -35,6 +35,7 @@ #include "BKE_tracking.h" #include "RNA_define.h" +#include "RNA_enum_types.h" #include "rna_internal.h" @@ -653,6 +654,12 @@ static void rna_def_mask_layer(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Restrict View", "Invert the mask black/white"); RNA_def_property_update(prop, NC_MASK | NA_EDITED, NULL); + prop = RNA_def_property(srna, "falloff", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_sdna(prop, NULL, "falloff"); + RNA_def_property_enum_items(prop, proportional_falloff_curve_only_items); + RNA_def_property_ui_text(prop, "Falloff", "Falloff type the feather"); + RNA_def_property_update(prop, NC_MASK | NA_EDITED, NULL); + } static void rna_def_masklayers(BlenderRNA *brna, PropertyRNA *cprop) From 10253f73bcdfc9aee865e06e9000505e08e009dd Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Sun, 15 Jul 2012 10:48:19 +0000 Subject: [PATCH 026/108] Fixed deadlock caused by thread locks added in 48893 This deadlock was caused by lock of threads using LOCK_DRAW_IMAGE mutex and lock used in render result acquire functions. So if image draw would lock LOCK_DRAW_IMAGE before compositor operation released render result it'll lead into a deadlock. --- source/blender/editors/space_image/image_draw.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/source/blender/editors/space_image/image_draw.c b/source/blender/editors/space_image/image_draw.c index 88eb280ea6b..cf78eaabd88 100644 --- a/source/blender/editors/space_image/image_draw.c +++ b/source/blender/editors/space_image/image_draw.c @@ -777,11 +777,11 @@ void draw_image_main(SpaceImage *sima, ARegion *ar, Scene *scene) ED_space_image_release_buffer(sima, lock); - /* render info */ - if (ima && show_render) - draw_render_info(scene, ima, ar); - if (show_viewer) { BLI_unlock_thread(LOCK_DRAW_IMAGE); } + + /* render info */ + if (ima && show_render) + draw_render_info(scene, ima, ar); } From 474b9224722953b36b46a00e1a8201858f2a99ae Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sun, 15 Jul 2012 11:33:13 +0000 Subject: [PATCH 027/108] fix: node background image move operator didn't take zoom into account when clamping pan bounds. --- source/blender/editors/space_node/node_edit.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/source/blender/editors/space_node/node_edit.c b/source/blender/editors/space_node/node_edit.c index 82f3eb1890d..5e5ffe2049c 100644 --- a/source/blender/editors/space_node/node_edit.c +++ b/source/blender/editors/space_node/node_edit.c @@ -1573,11 +1573,13 @@ static int snode_bg_viewmove_modal(bContext *C, wmOperator *op, wmEvent *event) static int snode_bg_viewmove_invoke(bContext *C, wmOperator *op, wmEvent *event) { + SpaceNode *snode = CTX_wm_space_node(C); ARegion *ar = CTX_wm_region(C); NodeViewMove *nvm; Image *ima; ImBuf *ibuf; - int pad = 10; + const float pad = 32.0f; /* better be bigger then scrollbars */ + void *lock; ima = BKE_image_verify_viewer(IMA_TYPE_COMPOSITE, "Viewer Node"); @@ -1593,10 +1595,10 @@ static int snode_bg_viewmove_invoke(bContext *C, wmOperator *op, wmEvent *event) nvm->mvalo[0] = event->mval[0]; nvm->mvalo[1] = event->mval[1]; - nvm->xmin = -(ar->winx / 2) - ibuf->x / 2 + pad; - nvm->xmax = ar->winx / 2 + ibuf->x / 2 - pad; - nvm->ymin = -(ar->winy / 2) - ibuf->y / 2 + pad; - nvm->ymax = ar->winy / 2 + ibuf->y / 2 - pad; + nvm->xmin = -(ar->winx / 2) - (ibuf->x * (0.5f * snode->zoom)) + pad; + nvm->xmax = (ar->winx / 2) + (ibuf->x * (0.5f * snode->zoom)) - pad; + nvm->ymin = -(ar->winy / 2) - (ibuf->y * (0.5f * snode->zoom)) + pad; + nvm->ymax = (ar->winy / 2) + (ibuf->y * (0.5f * snode->zoom)) - pad; BKE_image_release_ibuf(ima, lock); From 380c5d66a8717ebe7b0d124302a39c7068f04efb Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sun, 15 Jul 2012 11:35:13 +0000 Subject: [PATCH 028/108] math function to get the intersection point between 2 lines (not 2 segments which we already have). --- source/blender/blenlib/BLI_math_geom.h | 1 + source/blender/blenlib/intern/math_geom.c | 15 +++++++++++++++ 2 files changed, 16 insertions(+) diff --git a/source/blender/blenlib/BLI_math_geom.h b/source/blender/blenlib/BLI_math_geom.h index 70450156d98..b163be4a70c 100644 --- a/source/blender/blenlib/BLI_math_geom.h +++ b/source/blender/blenlib/BLI_math_geom.h @@ -87,6 +87,7 @@ void limit_dist_v3(float v1[3], float v2[3], const float dist); #define ISECT_LINE_LINE_EXACT 1 #define ISECT_LINE_LINE_CROSS 2 +int isect_line_line_v2_point(const float v1[2], const float v2[2], const float v3[2], const float v4[2], float vi[2]); int isect_line_line_v2(const float a1[2], const float a2[2], const float b1[2], const float b2[2]); int isect_line_line_v2_int(const int a1[2], const int a2[2], const int b1[2], const int b2[2]); int isect_line_sphere_v3(const float l1[3], const float l2[3], const float sp[3], const float r, float r_p1[3], float r_p2[3]); diff --git a/source/blender/blenlib/intern/math_geom.c b/source/blender/blenlib/intern/math_geom.c index 74e685ee238..eb30366573b 100644 --- a/source/blender/blenlib/intern/math_geom.c +++ b/source/blender/blenlib/intern/math_geom.c @@ -317,6 +317,21 @@ int isect_line_line_v2_int(const int v1[2], const int v2[2], const int v3[2], co return ISECT_LINE_LINE_NONE; } +/* intersect Line-Line, floats - gives intersection point */ +int isect_line_line_v2_point(const float v1[2], const float v2[2], const float v3[2], const float v4[2], float vi[2]) +{ + float div; + + div = (v2[0] - v1[0]) * (v4[1] - v3[1]) - (v2[1] - v1[1]) * (v4[0] - v3[0]); + if (div == 0.0f) return ISECT_LINE_LINE_COLINEAR; + + vi[0] = ((v3[0] - v4[0]) * (v1[0] * v2[1] - v1[1] * v2[0]) - (v1[0] - v2[0]) * (v3[0] * v4[1] - v3[1] * v4[0])) / div; + vi[1] = ((v3[1] - v4[1]) * (v1[0] * v2[1] - v1[1] * v2[0]) - (v1[1] - v2[1]) * (v3[0] * v4[1] - v3[1] * v4[0])) / div; + + return ISECT_LINE_LINE_CROSS; +} + + /* intersect Line-Line, floats */ int isect_line_line_v2(const float v1[2], const float v2[2], const float v3[2], const float v4[2]) { From b67b73e2d85d35ac0e0f6d4b5afe41a431200b01 Mon Sep 17 00:00:00 2001 From: Bastien Montagne Date: Sun, 15 Jul 2012 12:53:16 +0000 Subject: [PATCH 029/108] "Fix" [#32033] In the execution result of with_automatic_weight, the difference is seen right and left. This auto/heat vgroup creation seems to be fuzzy/unstable (each run gives a slightly different result). I have not the competences (nor time) to investigate that laplacian stuff, so for now just adding an option when parenting to an armature with envelope/heat, to mirror weights along the X axis (as it is done by default when doing it from the Weight Paint mode). --- source/blender/editors/include/ED_object.h | 3 +- .../blender/editors/object/object_relations.c | 43 ++++++++++++++++--- .../editors/space_outliner/outliner_edit.c | 4 +- 3 files changed, 41 insertions(+), 9 deletions(-) diff --git a/source/blender/editors/include/ED_object.h b/source/blender/editors/include/ED_object.h index 9209bbb2db7..38f0077c368 100644 --- a/source/blender/editors/include/ED_object.h +++ b/source/blender/editors/include/ED_object.h @@ -84,7 +84,8 @@ typedef enum eParentType { extern struct EnumPropertyItem prop_clear_parent_types[]; extern struct EnumPropertyItem prop_make_parent_types[]; -int ED_object_parent_set(struct ReportList *reports, struct Main *bmain, struct Scene *scene, struct Object *ob, struct Object *par, int partype); +int ED_object_parent_set(struct ReportList *reports, struct Main *bmain, struct Scene *scene, struct Object *ob, + struct Object *par, int partype, int xmirror); void ED_object_parent_clear(struct Object *ob, int type); struct Base *ED_object_scene_link(struct Scene *scene, struct Object *ob); diff --git a/source/blender/editors/object/object_relations.c b/source/blender/editors/object/object_relations.c index d7c882ba51e..860ff24cafd 100644 --- a/source/blender/editors/object/object_relations.c +++ b/source/blender/editors/object/object_relations.c @@ -518,7 +518,8 @@ EnumPropertyItem prop_make_parent_types[] = { {0, NULL, 0, NULL, NULL} }; -int ED_object_parent_set(ReportList *reports, Main *bmain, Scene *scene, Object *ob, Object *par, int partype) +int ED_object_parent_set(ReportList *reports, Main *bmain, Scene *scene, Object *ob, Object *par, + int partype, int xmirror) { bPoseChannel *pchan = NULL; int pararm = ELEM4(partype, PAR_ARMATURE, PAR_ARMATURE_NAME, PAR_ARMATURE_ENVELOPE, PAR_ARMATURE_AUTO); @@ -641,12 +642,12 @@ int ED_object_parent_set(ReportList *reports, Main *bmain, Scene *scene, Object } else if (pararm && ob->type == OB_MESH && par->type == OB_ARMATURE) { if (partype == PAR_ARMATURE_NAME) - create_vgroups_from_armature(reports, scene, ob, par, ARM_GROUPS_NAME, 0); + create_vgroups_from_armature(reports, scene, ob, par, ARM_GROUPS_NAME, FALSE); else if (partype == PAR_ARMATURE_ENVELOPE) - create_vgroups_from_armature(reports, scene, ob, par, ARM_GROUPS_ENVELOPE, 0); + create_vgroups_from_armature(reports, scene, ob, par, ARM_GROUPS_ENVELOPE, xmirror); else if (partype == PAR_ARMATURE_AUTO) { WM_cursor_wait(1); - create_vgroups_from_armature(reports, scene, ob, par, ARM_GROUPS_AUTO, 0); + create_vgroups_from_armature(reports, scene, ob, par, ARM_GROUPS_AUTO, xmirror); WM_cursor_wait(0); } /* get corrected inverse */ @@ -674,11 +675,12 @@ static int parent_set_exec(bContext *C, wmOperator *op) Scene *scene = CTX_data_scene(C); Object *par = ED_object_active_context(C); int partype = RNA_enum_get(op->ptr, "type"); + int xmirror = RNA_enum_get(op->ptr, "xmirror"); int ok = 1; CTX_DATA_BEGIN (C, Object *, ob, selected_editable_objects) { - if (!ED_object_parent_set(op->reports, bmain, scene, ob, par, partype)) { + if (!ED_object_parent_set(op->reports, bmain, scene, ob, par, partype, xmirror)) { ok = 0; break; } @@ -728,6 +730,33 @@ static int parent_set_invoke(bContext *C, wmOperator *UNUSED(op), wmEvent *UNUSE return OPERATOR_CANCELLED; } +static int parent_set_draw_check_prop(PointerRNA *ptr, PropertyRNA *prop) +{ + const char *prop_id = RNA_property_identifier(prop); + int type = RNA_enum_get(ptr, "type"); + + /* Only show XMirror for PAR_ARMATURE_ENVELOPE and PAR_ARMATURE_AUTO! */ + if (strcmp(prop_id, "xmirror") == 0) { + if (ELEM(type, PAR_ARMATURE_ENVELOPE, PAR_ARMATURE_AUTO)) + return TRUE; + else + return FALSE; + } + + return TRUE; +} + +static void parent_set_ui(bContext *C, wmOperator *op) +{ + uiLayout *layout = op->layout; + wmWindowManager *wm = CTX_wm_manager(C); + PointerRNA ptr; + + RNA_pointer_create(&wm->id, op->type->srna, op->properties, &ptr); + + /* Main auto-draw call. */ + uiDefAutoButsRNA(layout, &ptr, parent_set_draw_check_prop, '\0'); +} void OBJECT_OT_parent_set(wmOperatorType *ot) { @@ -739,13 +768,15 @@ void OBJECT_OT_parent_set(wmOperatorType *ot) /* api callbacks */ ot->invoke = parent_set_invoke; ot->exec = parent_set_exec; - ot->poll = ED_operator_object_active; + ot->ui = parent_set_ui; /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; RNA_def_enum(ot->srna, "type", prop_make_parent_types, 0, "Type", ""); + RNA_def_boolean(ot->srna, "xmirror", FALSE, "X Mirror", + "Apply weights symmetrically along X axis, for Envelope/Automatic vertex groups creation"); } /* ************ Make Parent Without Inverse Operator ******************* */ diff --git a/source/blender/editors/space_outliner/outliner_edit.c b/source/blender/editors/space_outliner/outliner_edit.c index 449914feae4..0388ba86b84 100644 --- a/source/blender/editors/space_outliner/outliner_edit.c +++ b/source/blender/editors/space_outliner/outliner_edit.c @@ -1423,7 +1423,7 @@ static int parent_drop_exec(bContext *C, wmOperator *op) RNA_string_get(op->ptr, "child", childname); ob = (Object *)BKE_libblock_find_name(ID_OB, childname); - ED_object_parent_set(op->reports, bmain, scene, ob, par, partype); + ED_object_parent_set(op->reports, bmain, scene, ob, par, partype, FALSE); DAG_scene_sort(bmain, scene); DAG_ids_flush_update(bmain, 0); @@ -1514,7 +1514,7 @@ static int parent_drop_invoke(bContext *C, wmOperator *op, wmEvent *event) } if ((par->type != OB_ARMATURE) && (par->type != OB_CURVE) && (par->type != OB_LATTICE)) { - if (ED_object_parent_set(op->reports, bmain, scene, ob, par, partype)) { + if (ED_object_parent_set(op->reports, bmain, scene, ob, par, partype, FALSE)) { DAG_scene_sort(bmain, scene); DAG_ids_flush_update(bmain, 0); WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, NULL); From 1723d51edb4dad9458a4d40f792642cdaea2d2ed Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sun, 15 Jul 2012 15:11:52 +0000 Subject: [PATCH 030/108] replace fminf with minf --- .../blender/blenkernel/intern/mask_rasterize.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/source/blender/blenkernel/intern/mask_rasterize.c b/source/blender/blenkernel/intern/mask_rasterize.c index b415e9f1ba8..5c9e480d730 100644 --- a/source/blender/blenkernel/intern/mask_rasterize.c +++ b/source/blender/blenkernel/intern/mask_rasterize.c @@ -356,10 +356,10 @@ static void layer_bucket_init(MaskRasterLayer *layer, const float pixel_size) const float *v2 = cos[face[1]]; const float *v3 = cos[face[2]]; - xmin = fminf(v1[0], fminf(v2[0], v3[0])); - xmax = fmaxf(v1[0], fmaxf(v2[0], v3[0])); - ymin = fminf(v1[1], fminf(v2[1], v3[1])); - ymax = fmaxf(v1[1], fmaxf(v2[1], v3[1])); + xmin = minf(v1[0], minf(v2[0], v3[0])); + xmax = maxf(v1[0], maxf(v2[0], v3[0])); + ymin = minf(v1[1], minf(v2[1], v3[1])); + ymax = maxf(v1[1], maxf(v2[1], v3[1])); } else { const float *v1 = cos[face[0]]; @@ -367,10 +367,10 @@ static void layer_bucket_init(MaskRasterLayer *layer, const float pixel_size) const float *v3 = cos[face[2]]; const float *v4 = cos[face[3]]; - xmin = fminf(v1[0], fminf(v2[0], fminf(v3[0], v4[0]))); - xmax = fmaxf(v1[0], fmaxf(v2[0], fmaxf(v3[0], v4[0]))); - ymin = fminf(v1[1], fminf(v2[1], fminf(v3[1], v4[1]))); - ymax = fmaxf(v1[1], fmaxf(v2[1], fmaxf(v3[1], v4[1]))); + xmin = minf(v1[0], minf(v2[0], minf(v3[0], v4[0]))); + xmax = maxf(v1[0], maxf(v2[0], maxf(v3[0], v4[0]))); + ymin = minf(v1[1], minf(v2[1], minf(v3[1], v4[1]))); + ymax = maxf(v1[1], maxf(v2[1], maxf(v3[1], v4[1]))); } From 701a16c9dd67fed0f3ab814d946b6036f3a037b8 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sun, 15 Jul 2012 16:16:34 +0000 Subject: [PATCH 031/108] moving mask rasterizer file, this breaks building, will fix next commit --- .../intern/mask_rasterize.c => maskraster/maskraster.c} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename source/blender/{blenkernel/intern/mask_rasterize.c => maskraster/maskraster.c} (100%) diff --git a/source/blender/blenkernel/intern/mask_rasterize.c b/source/blender/maskraster/maskraster.c similarity index 100% rename from source/blender/blenkernel/intern/mask_rasterize.c rename to source/blender/maskraster/maskraster.c From 8c77b35f4f0cbd75187b7f888429a57d59d00eeb Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sun, 15 Jul 2012 16:57:21 +0000 Subject: [PATCH 032/108] svn merge -r48944:48942 . revert moving the file, adding a new module didnt resolve linking issue. --- .../maskraster.c => blenkernel/intern/mask_rasterize.c} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename source/blender/{maskraster/maskraster.c => blenkernel/intern/mask_rasterize.c} (100%) diff --git a/source/blender/maskraster/maskraster.c b/source/blender/blenkernel/intern/mask_rasterize.c similarity index 100% rename from source/blender/maskraster/maskraster.c rename to source/blender/blenkernel/intern/mask_rasterize.c From 4f6cc9a9aae865537ed8e3ee6b9f2171ec8acbfe Mon Sep 17 00:00:00 2001 From: Mitchell Stokes Date: Mon, 16 Jul 2012 03:43:57 +0000 Subject: [PATCH 033/108] BGE: The Action Actuator now returns correct values to work with the Actuator Sensor. --- source/gameengine/Converter/BL_ActionActuator.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/gameengine/Converter/BL_ActionActuator.cpp b/source/gameengine/Converter/BL_ActionActuator.cpp index b580fc31585..cab6d0fc376 100644 --- a/source/gameengine/Converter/BL_ActionActuator.cpp +++ b/source/gameengine/Converter/BL_ActionActuator.cpp @@ -339,7 +339,7 @@ bool BL_ActionActuator::Update(double curtime, bool frame) } } - return true; + return m_flag & ACT_FLAG_ATTEMPT_PLAY; } #ifdef WITH_PYTHON From 6f01b0b11fee61bf6f945eaaa2cf72f87a84a965 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 16 Jul 2012 06:39:40 +0000 Subject: [PATCH 034/108] small speedup for mask rasterizer, only do single sided check for triangle intersection. --- source/blender/blenkernel/intern/mask_rasterize.c | 10 ++++++---- source/blender/blenlib/BLI_math_geom.h | 1 + source/blender/blenlib/intern/math_geom.c | 14 ++++++++++++++ 3 files changed, 21 insertions(+), 4 deletions(-) diff --git a/source/blender/blenkernel/intern/mask_rasterize.c b/source/blender/blenkernel/intern/mask_rasterize.c index 5c9e480d730..dfdcad9cc43 100644 --- a/source/blender/blenkernel/intern/mask_rasterize.c +++ b/source/blender/blenkernel/intern/mask_rasterize.c @@ -727,9 +727,9 @@ void BLI_maskrasterize_handle_init(MaskRasterHandle *mr_handle, struct Mask *mas /* tri's */ face = (unsigned int *)face_array; for (sf_tri = sf_ctx.fillfacebase.first, face_index = 0; sf_tri; sf_tri = sf_tri->next, face_index++) { - *(face++) = sf_tri->v1->tmp.u; - *(face++) = sf_tri->v2->tmp.u; *(face++) = sf_tri->v3->tmp.u; + *(face++) = sf_tri->v2->tmp.u; + *(face++) = sf_tri->v1->tmp.u; *(face++) = TRI_VERT; } @@ -881,7 +881,7 @@ static float maskrasterize_layer_isect(unsigned int *face, float (*cos)[3], cons (cos[1][2] < dist_orig) || (cos[2][2] < dist_orig)) { - if (isect_point_tri_v2(xy, cos[face[0]], cos[face[1]], cos[face[2]])) { + if (isect_point_tri_v2_cw(xy, cos[face[0]], cos[face[1]], cos[face[2]])) { /* we know all tris are close for now */ return maskrasterize_layer_z_depth_tri(xy, cos[face[0]], cos[face[1]], cos[face[2]]); } @@ -889,7 +889,7 @@ static float maskrasterize_layer_isect(unsigned int *face, float (*cos)[3], cons #else /* we know all tris are close for now */ if (1) { - if (isect_point_tri_v2(xy, cos[face[0]], cos[face[1]], cos[face[2]])) { + if (isect_point_tri_v2_cw(xy, cos[face[0]], cos[face[1]], cos[face[2]])) { return 0.0f; } } @@ -911,6 +911,8 @@ static float maskrasterize_layer_isect(unsigned int *face, float (*cos)[3], cons return maskrasterize_layer_z_depth_quad(xy, cos[face[0]], cos[face[1]], cos[face[2]], cos[face[3]]); } #elif 1 + /* don't use isect_point_tri_v2_cw because we could have bowtie quads */ + if (isect_point_tri_v2(xy, cos[face[0]], cos[face[1]], cos[face[2]])) { return maskrasterize_layer_z_depth_tri(xy, cos[face[0]], cos[face[1]], cos[face[2]]); } diff --git a/source/blender/blenlib/BLI_math_geom.h b/source/blender/blenlib/BLI_math_geom.h index b163be4a70c..f799b7b0ebe 100644 --- a/source/blender/blenlib/BLI_math_geom.h +++ b/source/blender/blenlib/BLI_math_geom.h @@ -154,6 +154,7 @@ int isect_ray_tri_epsilon_v3(const float p1[3], const float d[3], int isect_point_quad_v2(const float p[2], const float a[2], const float b[2], const float c[2], const float d[2]); int isect_point_tri_v2(const float v1[2], const float v2[2], const float v3[2], const float pt[2]); +int isect_point_tri_v2_cw(const float pt[2], const float v1[2], const float v2[2], const float v3[2]); int isect_point_tri_v2_int(const int x1, const int y1, const int x2, const int y2, const int a, const int b); int isect_point_tri_prism_v3(const float p[3], const float v1[3], const float v2[3], const float v3[3]); diff --git a/source/blender/blenlib/intern/math_geom.c b/source/blender/blenlib/intern/math_geom.c index eb30366573b..661c47821fd 100644 --- a/source/blender/blenlib/intern/math_geom.c +++ b/source/blender/blenlib/intern/math_geom.c @@ -606,6 +606,20 @@ static short IsectLLPt2Df(const float x0, const float y0, const float x1, const /* point in tri */ +/* only single direction */ +int isect_point_tri_v2_cw(const float pt[2], const float v1[2], const float v2[2], const float v3[2]) +{ + if (line_point_side_v2(v1, v2, pt) >= 0.0f) { + if (line_point_side_v2(v2, v3, pt) >= 0.0f) { + if (line_point_side_v2(v3, v1, pt) >= 0.0f) { + return 1; + } + } + } + + return 0; +} + int isect_point_tri_v2(const float pt[2], const float v1[2], const float v2[2], const float v3[2]) { if (line_point_side_v2(v1, v2, pt) >= 0.0f) { From 8e7aa500219ac71c9f36b0312508fa5f867e3690 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 16 Jul 2012 07:04:10 +0000 Subject: [PATCH 035/108] fix crash for empty or single vertex layers. --- source/blender/blenkernel/intern/mask_rasterize.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/source/blender/blenkernel/intern/mask_rasterize.c b/source/blender/blenkernel/intern/mask_rasterize.c index dfdcad9cc43..991d58b01bf 100644 --- a/source/blender/blenkernel/intern/mask_rasterize.c +++ b/source/blender/blenkernel/intern/mask_rasterize.c @@ -617,10 +617,6 @@ void BLI_maskrasterize_handle_init(MaskRasterHandle *mr_handle, struct Mask *mas sf_vert_tot++; } - if (diff_feather_points) { - MEM_freeN(diff_feather_points); - } - tot_feather_quads += tot_diff_point; } } @@ -673,8 +669,6 @@ void BLI_maskrasterize_handle_init(MaskRasterHandle *mr_handle, struct Mask *mas tot_feather_quads -= 2; } - MEM_freeN(diff_feather_points); - /* ack these are infact tris, but they are extra faces so no matter, * +1 becausing adding one vert results in 2 tris (joining the existing endpoints) */ @@ -687,9 +681,13 @@ void BLI_maskrasterize_handle_init(MaskRasterHandle *mr_handle, struct Mask *mas if (diff_points) { MEM_freeN(diff_points); } + + if (diff_feather_points) { + MEM_freeN(diff_feather_points); + } } - if (sf_ctx.fillvertbase.first) { + { unsigned int (*face_array)[4], *face; /* access coords */ float (*face_coords)[3], *cos; /* xy, z 0-1 (1.0 == filled) */ int sf_tri_tot; From 60cfbaeb1eb4067a2b545a2e480d8eecb94ec417 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 16 Jul 2012 07:23:16 +0000 Subject: [PATCH 036/108] mask blending modes: lighten/darken/multiply/replace --- .../blenkernel/intern/mask_rasterize.c | 41 ++++++++++++------- source/blender/makesdna/DNA_mask_types.h | 6 ++- source/blender/makesrna/intern/rna_mask.c | 4 ++ 3 files changed, 36 insertions(+), 15 deletions(-) diff --git a/source/blender/blenkernel/intern/mask_rasterize.c b/source/blender/blenkernel/intern/mask_rasterize.c index 991d58b01bf..8bac736e1c9 100644 --- a/source/blender/blenkernel/intern/mask_rasterize.c +++ b/source/blender/blenkernel/intern/mask_rasterize.c @@ -979,21 +979,21 @@ float BLI_maskrasterize_handle_sample(MaskRasterHandle *mr_handle, const float x float value_layer; if (BLI_in_rctf_v(&layer->bounds, xy)) { - float val = 1.0f - layer_bucket_depth_from_xy(layer, xy); + value_layer = 1.0f - layer_bucket_depth_from_xy(layer, xy); switch (layer->falloff) { case PROP_SMOOTH: /* ease - gives less hard lines for dilate/erode feather */ - val = (3.0f * val * val - 2.0f * val * val * val); + value_layer = (3.0f * value_layer * value_layer - 2.0f * value_layer * value_layer * value_layer); break; case PROP_SPHERE: - val = sqrtf(2.0f * val - val * val); + value_layer = sqrtf(2.0f * value_layer - value_layer * value_layer); break; case PROP_ROOT: - val = sqrtf(val); + value_layer = sqrtf(value_layer); break; case PROP_SHARP: - val = val * val; + value_layer = value_layer * value_layer; break; case PROP_LIN: default: @@ -1001,7 +1001,9 @@ float BLI_maskrasterize_handle_sample(MaskRasterHandle *mr_handle, const float x break; } - value_layer = val * layer->alpha; + if (layer->blend != MASK_BLEND_REPLACE) { + value_layer *= layer->alpha; + } } else { value_layer = 0.0f; @@ -1012,17 +1014,28 @@ float BLI_maskrasterize_handle_sample(MaskRasterHandle *mr_handle, const float x } switch (layer->blend) { - case MASK_BLEND_SUBTRACT: - { - value -= value_layer; - break; - } case MASK_BLEND_ADD: - default: - { value += value_layer; break; - } + case MASK_BLEND_SUBTRACT: + value -= value_layer; + break; + case MASK_BLEND_LIGHTEN: + value = maxf(value, value_layer); + break; + case MASK_BLEND_DARKEN: + value = minf(value, value_layer); + break; + case MASK_BLEND_MUL: + value *= value_layer; + break; + case MASK_BLEND_REPLACE: + value = (value * (1.0f - layer->alpha)) + (value_layer * layer->alpha); + break; + default: /* same as add */ + BLI_assert(0); + value += value_layer; + break; } } diff --git a/source/blender/makesdna/DNA_mask_types.h b/source/blender/makesdna/DNA_mask_types.h index dd9ea508723..f231cba0df7 100644 --- a/source/blender/makesdna/DNA_mask_types.h +++ b/source/blender/makesdna/DNA_mask_types.h @@ -168,7 +168,11 @@ enum { /* masklay->blend */ enum { MASK_BLEND_ADD = 0, - MASK_BLEND_SUBTRACT = 1 + MASK_BLEND_SUBTRACT = 1, + MASK_BLEND_LIGHTEN = 2, + MASK_BLEND_DARKEN = 3, + MASK_BLEND_MUL = 4, + MASK_BLEND_REPLACE = 5, }; /* masklay->blend_flag */ diff --git a/source/blender/makesrna/intern/rna_mask.c b/source/blender/makesrna/intern/rna_mask.c index 2b89dd02dae..e347dffe51d 100644 --- a/source/blender/makesrna/intern/rna_mask.c +++ b/source/blender/makesrna/intern/rna_mask.c @@ -581,6 +581,10 @@ static void rna_def_mask_layer(BlenderRNA *brna) static EnumPropertyItem masklay_blend_mode_items[] = { {MASK_BLEND_ADD, "ADD", 0, "Add", ""}, {MASK_BLEND_SUBTRACT, "SUBTRACT", 0, "Subtract", ""}, + {MASK_BLEND_LIGHTEN, "LIGHTEN", 0, "Lighten", ""}, + {MASK_BLEND_DARKEN, "DARKEN", 0, "Darken", ""}, + {MASK_BLEND_MUL, "MUL", 0, "Multiply", ""}, + {MASK_BLEND_REPLACE, "REPLACE", 0, "Replace", ""}, {0, NULL, 0, NULL, NULL} }; From 5b04685f49d13f58b4b6159d6bd6d6f970bc56bb Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 16 Jul 2012 08:26:42 +0000 Subject: [PATCH 037/108] handy cmake list macros for inserting items into a list before/after existing items --- build_files/cmake/macros.cmake | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/build_files/cmake/macros.cmake b/build_files/cmake/macros.cmake index 3608f41e369..bceeb5acc86 100644 --- a/build_files/cmake/macros.cmake +++ b/build_files/cmake/macros.cmake @@ -23,6 +23,25 @@ # # ***** END GPL LICENSE BLOCK ***** +macro(list_insert_after + list_id item_check item_add + ) + set(_index) + list(FIND ${list_id} "${item_check}" _index) + math(EXPR _index "${_index} + 1") + list(INSERT ${list_id} "${_index}" ${item_add}) + unset(_index) +endmacro() + +macro(list_insert_before + list_id item_check item_add + ) + set(_index) + list(FIND ${list_id} "${item_check}" _index) + list(INSERT ${list_id} "${_index}" ${item_add}) + unset(_index) +endmacro() + # foo_bar.spam --> foo_barMySuffix.spam macro(file_suffix file_name_new file_name file_suffix From 4cacff234225d81c44144551fd295a24a9b3c30c Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 16 Jul 2012 08:42:55 +0000 Subject: [PATCH 038/108] fix for linking with scons. --- source/blender/compositor/SConscript | 2 +- source/blender/nodes/composite/node_composite_tree.c | 2 ++ source/blender/windowmanager/intern/wm_init_exit.c | 6 ++++++ source/creator/CMakeLists.txt | 7 +++---- 4 files changed, 12 insertions(+), 5 deletions(-) diff --git a/source/blender/compositor/SConscript b/source/blender/compositor/SConscript index af0d4109acc..d7f18cfa436 100644 --- a/source/blender/compositor/SConscript +++ b/source/blender/compositor/SConscript @@ -11,4 +11,4 @@ incs += '../opencl ../nodes ../nodes/intern ../nodes/composite ' if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'linuxcross', 'win64-vc'): incs += ' ' + env['BF_PTHREADS_INC'] -env.BlenderLib ( 'bf_composite', sources, Split(incs), defines=defs, libtype=['core'], priority = [191] ) +env.BlenderLib ( 'bf_composite', sources, Split(incs), defines=defs, libtype=['core'], priority = [164] ) diff --git a/source/blender/nodes/composite/node_composite_tree.c b/source/blender/nodes/composite/node_composite_tree.c index 43edc06194d..18ab3b7d6d1 100644 --- a/source/blender/nodes/composite/node_composite_tree.c +++ b/source/blender/nodes/composite/node_composite_tree.c @@ -684,6 +684,8 @@ static void ntreeCompositExecTreeOld(bNodeTree *ntree, RenderData *rd, int do_pr } #endif +void *COM_linker_hack = NULL; + void ntreeCompositExecTree(bNodeTree *ntree, RenderData *rd, int rendering, int do_preview) { #ifdef WITH_COMPOSITOR diff --git a/source/blender/windowmanager/intern/wm_init_exit.c b/source/blender/windowmanager/intern/wm_init_exit.c index 3dbb3b7ef66..b9170d703aa 100644 --- a/source/blender/windowmanager/intern/wm_init_exit.c +++ b/source/blender/windowmanager/intern/wm_init_exit.c @@ -199,6 +199,12 @@ void WM_init(bContext *C, int argc, const char **argv) #endif BLI_strncpy(G.lib, G.main->name, FILE_MAX); + + if (1) { + extern void *COM_linker_hack; + extern void *COM_execute; + COM_linker_hack = COM_execute; + } } void WM_init_splash(bContext *C) diff --git a/source/creator/CMakeLists.txt b/source/creator/CMakeLists.txt index abfbe366b88..9571153d037 100644 --- a/source/creator/CMakeLists.txt +++ b/source/creator/CMakeLists.txt @@ -909,10 +909,9 @@ endif() ) if(WITH_COMPOSITOR) - #added for opencl compositor - list(APPEND BLENDER_SORTED_LIBS bf_compositor) - list(APPEND BLENDER_SORTED_LIBS bf_opencl) - list(APPEND BLENDER_SORTED_LIBS bf_blenkernel) # hrmf, needed for BKE_mask only + # added for opencl compositor + list_insert_before(BLENDER_SORTED_LIBS "bf_blenkernel" "bf_compositor") + list_insert_after(BLENDER_SORTED_LIBS "bf_compositor" "bf_opencl") endif() if(WITH_LIBMV) From a2e2489f611eabcaa2d388379fcc4256bc0a6b38 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 16 Jul 2012 08:53:11 +0000 Subject: [PATCH 039/108] correct own naming error BLI -> BKE --- source/blender/blenkernel/BKE_mask.h | 8 ++++---- source/blender/blenkernel/intern/mask_rasterize.c | 8 ++++---- .../blender/compositor/operations/COM_MaskOperation.cpp | 8 ++++---- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/source/blender/blenkernel/BKE_mask.h b/source/blender/blenkernel/BKE_mask.h index 5038ac5eb1b..411350764b3 100644 --- a/source/blender/blenkernel/BKE_mask.h +++ b/source/blender/blenkernel/BKE_mask.h @@ -213,13 +213,13 @@ void BKE_mask_init_layers(Mask *mask, struct layer_init_data *mlayer_data, int w struct MaskRasterHandle; typedef struct MaskRasterHandle MaskRasterHandle; -MaskRasterHandle *BLI_maskrasterize_handle_new(void); -void BLI_maskrasterize_handle_free(MaskRasterHandle *mr_handle); -void BLI_maskrasterize_handle_init(MaskRasterHandle *mr_handle, struct Mask *mask, +MaskRasterHandle *BKE_maskrasterize_handle_new(void); +void BKE_maskrasterize_handle_free(MaskRasterHandle *mr_handle); +void BKE_maskrasterize_handle_init(MaskRasterHandle *mr_handle, struct Mask *mask, const int width, const int height, const short do_aspect_correct, const short do_mask_aa, const short do_feather); -float BLI_maskrasterize_handle_sample(MaskRasterHandle *mr_handle, const float xy[2]); +float BKE_maskrasterize_handle_sample(MaskRasterHandle *mr_handle, const float xy[2]); #endif /* USE_RASKTER */ #endif /* __BKE_MASK_H__ */ diff --git a/source/blender/blenkernel/intern/mask_rasterize.c b/source/blender/blenkernel/intern/mask_rasterize.c index 8bac736e1c9..5428e8c6335 100644 --- a/source/blender/blenkernel/intern/mask_rasterize.c +++ b/source/blender/blenkernel/intern/mask_rasterize.c @@ -119,7 +119,7 @@ struct MaskRasterHandle { /* alloc / free functions */ /* --------------------------------------------------------------------- */ -MaskRasterHandle *BLI_maskrasterize_handle_new(void) +MaskRasterHandle *BKE_maskrasterize_handle_new(void) { MaskRasterHandle *mr_handle; @@ -128,7 +128,7 @@ MaskRasterHandle *BLI_maskrasterize_handle_new(void) return mr_handle; } -void BLI_maskrasterize_handle_free(MaskRasterHandle *mr_handle) +void BKE_maskrasterize_handle_free(MaskRasterHandle *mr_handle) { const unsigned int layers_tot = mr_handle->layers_tot; unsigned int i; @@ -452,7 +452,7 @@ static void layer_bucket_init(MaskRasterLayer *layer, const float pixel_size) BLI_memarena_free(arena); } -void BLI_maskrasterize_handle_init(MaskRasterHandle *mr_handle, struct Mask *mask, +void BKE_maskrasterize_handle_init(MaskRasterHandle *mr_handle, struct Mask *mask, const int width, const int height, const short do_aspect_correct, const short do_mask_aa, const short do_feather) @@ -963,7 +963,7 @@ static float layer_bucket_depth_from_xy(MaskRasterLayer *layer, const float xy[2 } } -float BLI_maskrasterize_handle_sample(MaskRasterHandle *mr_handle, const float xy[2]) +float BKE_maskrasterize_handle_sample(MaskRasterHandle *mr_handle, const float xy[2]) { /* can't do this because some layers may invert */ /* if (BLI_in_rctf_v(&mr_handle->bounds, xy)) */ diff --git a/source/blender/compositor/operations/COM_MaskOperation.cpp b/source/blender/compositor/operations/COM_MaskOperation.cpp index d2a4854efee..057a749080a 100644 --- a/source/blender/compositor/operations/COM_MaskOperation.cpp +++ b/source/blender/compositor/operations/COM_MaskOperation.cpp @@ -152,9 +152,9 @@ void MaskOperation::initExecution() const int width = this->getWidth(); const int height = this->getHeight(); - this->m_rasterMaskHandle = BLI_maskrasterize_handle_new(); + this->m_rasterMaskHandle = BKE_maskrasterize_handle_new(); - BLI_maskrasterize_handle_init(this->m_rasterMaskHandle, this->m_mask, width, height, TRUE, this->m_do_smooth, this->m_do_feather); + BKE_maskrasterize_handle_init(this->m_rasterMaskHandle, this->m_mask, width, height, TRUE, this->m_do_smooth, this->m_do_feather); } } } @@ -162,7 +162,7 @@ void MaskOperation::initExecution() void MaskOperation::deinitExecution() { if (this->m_rasterMaskHandle) { - BLI_maskrasterize_handle_free(this->m_rasterMaskHandle); + BKE_maskrasterize_handle_free(this->m_rasterMaskHandle); this->m_rasterMaskHandle = NULL; } @@ -197,7 +197,7 @@ void MaskOperation::executePixel(float *color, int x, int y, void *data) { const float xy[2] = {x / (float)this->m_maskWidth, y / (float)this->m_maskHeight}; if (this->m_rasterMaskHandle) { - color[0] = BLI_maskrasterize_handle_sample(this->m_rasterMaskHandle, xy); + color[0] = BKE_maskrasterize_handle_sample(this->m_rasterMaskHandle, xy); } else { color[0] = 0.0f; From 407347fd1f8ac7ac37a4df13a22bb58490c67631 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 16 Jul 2012 09:41:38 +0000 Subject: [PATCH 040/108] mask fill/cyclic toggle wasnt refreshing compo nodes --- source/blender/makesrna/intern/rna_mask.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/blender/makesrna/intern/rna_mask.c b/source/blender/makesrna/intern/rna_mask.c index e347dffe51d..f417458212d 100644 --- a/source/blender/makesrna/intern/rna_mask.c +++ b/source/blender/makesrna/intern/rna_mask.c @@ -566,14 +566,14 @@ static void rna_def_maskSpline(BlenderRNA *brna) RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); RNA_def_property_boolean_sdna(prop, NULL, "flag", MASK_SPLINE_CYCLIC); RNA_def_property_ui_text(prop, "Cyclic", "Make this spline a closed loop"); - RNA_def_property_update(prop, 0, "rna_Mask_update_data"); + RNA_def_property_update(prop, NC_MASK | NA_EDITED, "rna_Mask_update_data"); /* fill */ prop = RNA_def_property(srna, "use_fill", PROP_BOOLEAN, PROP_NONE); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", MASK_SPLINE_NOFILL); RNA_def_property_ui_text(prop, "Fill", "Make this spline filled"); - RNA_def_property_update(prop, 0, "rna_Mask_update_data"); + RNA_def_property_update(prop, NC_MASK | NA_EDITED, "rna_Mask_update_data"); } static void rna_def_mask_layer(BlenderRNA *brna) From 9a385d12e37644bd7e56224e781a30652ae1ed84 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 16 Jul 2012 10:36:40 +0000 Subject: [PATCH 041/108] add 2d version of interp_weights_poly_v3 --- source/blender/blenlib/BLI_math_geom.h | 3 +- source/blender/blenlib/intern/math_geom.c | 67 ++++++++++++++++++++--- 2 files changed, 61 insertions(+), 9 deletions(-) diff --git a/source/blender/blenlib/BLI_math_geom.h b/source/blender/blenlib/BLI_math_geom.h index f799b7b0ebe..4c037b6e73c 100644 --- a/source/blender/blenlib/BLI_math_geom.h +++ b/source/blender/blenlib/BLI_math_geom.h @@ -191,7 +191,8 @@ void plot_line_v2v2i(const int p1[2], const int p2[2], int (*callback)(int, int, /* tri or quad, d can be NULL */ void interp_weights_face_v3(float w[4], const float a[3], const float b[3], const float c[3], const float d[3], const float p[3]); -void interp_weights_poly_v3(float w[], float v[][3], const int n, const float p[3]); +void interp_weights_poly_v3(float w[], float v[][3], const int n, const float co[3]); +void interp_weights_poly_v2(float w[], float v[][2], const int n, const float co[2]); void interp_cubic_v3(float x[3], float v[3], const float x1[3], const float v1[3], const float x2[3], const float v2[3], const float t); diff --git a/source/blender/blenlib/intern/math_geom.c b/source/blender/blenlib/intern/math_geom.c index 661c47821fd..3c62a433705 100644 --- a/source/blender/blenlib/intern/math_geom.c +++ b/source/blender/blenlib/intern/math_geom.c @@ -2148,7 +2148,7 @@ int interp_sparse_array(float *array, int const list_size, const float skipval) /* Mean value weights - smooth interpolation weights for polygons with * more than 3 vertices */ -static float mean_value_half_tan(const float v1[3], const float v2[3], const float v3[3]) +static float mean_value_half_tan_v3(const float v1[3], const float v2[3], const float v3[3]) { float d2[3], d3[3], cross[3], area, dot, len; @@ -2160,10 +2160,32 @@ static float mean_value_half_tan(const float v1[3], const float v2[3], const flo dot = dot_v3v3(d2, d3); len = len_v3(d2) * len_v3(d3); - if (area == 0.0f) - return 0.0f; - else + if (LIKELY(area != 0.0f)) { return (len - dot) / area; + } + else { + return 0.0f; + } +} +static float mean_value_half_tan_v2(const float v1[2], const float v2[2], const float v3[2]) +{ + float d2[2], d3[2], area, dot, len; + + sub_v2_v2v2(d2, v2, v1); + sub_v2_v2v2(d3, v3, v1); + + /* different from the 3d version but still correct */ + area = cross_v2v2(d2, d3); + + dot = dot_v2v2(d2, d3); + len = len_v2(d2) * len_v2(d3); + + if (LIKELY(area != 0.0f)) { + return (len - dot) / area; + } + else { + return 0.0f; + } } void interp_weights_poly_v3(float *w, float v[][3], const int n, const float co[3]) @@ -2178,17 +2200,46 @@ void interp_weights_poly_v3(float *w, float v[][3], const int n, const float co[ vprev = (i == 0) ? v[n - 1] : v[i - 1]; vnext = (i == n - 1) ? v[0] : v[i + 1]; - t1 = mean_value_half_tan(co, vprev, vmid); - t2 = mean_value_half_tan(co, vmid, vnext); + t1 = mean_value_half_tan_v3(co, vprev, vmid); + t2 = mean_value_half_tan_v3(co, vmid, vnext); len = len_v3v3(co, vmid); w[i] = (t1 + t2) / len; totweight += w[i]; } - if (totweight != 0.0f) - for (i = 0; i < n; i++) + if (totweight != 0.0f) { + for (i = 0; i < n; i++) { w[i] /= totweight; + } + } +} + +void interp_weights_poly_v2(float *w, float v[][2], const int n, const float co[2]) +{ + float totweight, t1, t2, len, *vmid, *vprev, *vnext; + int i; + + totweight = 0.0f; + + for (i = 0; i < n; i++) { + vmid = v[i]; + vprev = (i == 0) ? v[n - 1] : v[i - 1]; + vnext = (i == n - 1) ? v[0] : v[i + 1]; + + t1 = mean_value_half_tan_v2(co, vprev, vmid); + t2 = mean_value_half_tan_v2(co, vmid, vnext); + + len = len_v2v2(co, vmid); + w[i] = (t1 + t2) / len; + totweight += w[i]; + } + + if (totweight != 0.0f) { + for (i = 0; i < n; i++) { + w[i] /= totweight; + } + } } /* (x1,v1)(t1=0)------(x2,v2)(t2=1), 0 (x,v)(t) */ From 273bb8fa901568b8017b2fc621eea368acc6b039 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 16 Jul 2012 12:01:18 +0000 Subject: [PATCH 042/108] barycentric_weights_v2_quad wasn't working quite right, rewrite as an expanded version of interp_weights_poly_v2() that cuts down duplicate calculations. --- source/blender/blenlib/intern/math_geom.c | 50 ++++++++++++++--------- 1 file changed, 31 insertions(+), 19 deletions(-) diff --git a/source/blender/blenlib/intern/math_geom.c b/source/blender/blenlib/intern/math_geom.c index 3c62a433705..da4846e7af1 100644 --- a/source/blender/blenlib/intern/math_geom.c +++ b/source/blender/blenlib/intern/math_geom.c @@ -1977,34 +1977,44 @@ void barycentric_weights_v2(const float v1[2], const float v2[2], const float v3 } /* same as #barycentric_weights_v2 but works with a quad, - * note: untested for values outside the quad's bounds. - * note: there may be a more efficient method to do this, just figured it out - campbell */ + * note: untested for values outside the quad's bounds + * this is #interp_weights_poly_v2 expanded for quads only */ void barycentric_weights_v2_quad(const float v1[2], const float v2[2], const float v3[2], const float v4[2], const float co[2], float w[4]) { - float wtot; +#define MEAN_VALUE_HALF_TAN_V2(_area, i1, i2) ((_area = cross_v2v2(dirs[i1], dirs[i2])) != 0.0f ? \ + (((lens[i1] * lens[i2]) - dot_v2v2(dirs[i1], dirs[i2])) / _area) : 0.0f) - const float areas_co[4] = { - area_tri_signed_v2(v1, v2, co), - area_tri_signed_v2(v2, v3, co), - area_tri_signed_v2(v3, v4, co), - area_tri_signed_v2(v4, v1, co), + float wtot, area; + + const float dirs[4][2] = { + {v1[0] - co[0], v1[1] - co[1]}, + {v2[0] - co[0], v2[1] - co[1]}, + {v3[0] - co[0], v3[1] - co[1]}, + {v4[0] - co[0], v4[1] - co[1]}, }; - const float areas_diag[4] = { - area_tri_signed_v2(v4, v1, v2), - area_tri_signed_v2(v1, v2, v3), - area_tri_signed_v2(v2, v3, v4), - area_tri_signed_v2(v3, v4, v1), + const float lens[4] = { + len_v2(dirs[0]), + len_v2(dirs[1]), + len_v2(dirs[2]), + len_v2(dirs[3]), }; - const float u = areas_co[3] / (areas_co[1] + areas_co[3]); - const float v = areas_co[0] / (areas_co[0] + areas_co[2]); + /* inline mean_value_half_tan four times here */ + float t[4] = { + MEAN_VALUE_HALF_TAN_V2(area, 0, 1), + MEAN_VALUE_HALF_TAN_V2(area, 1, 2), + MEAN_VALUE_HALF_TAN_V2(area, 2, 3), + MEAN_VALUE_HALF_TAN_V2(area, 3, 0), + }; - w[0] = ((1.0f - u) * (1.0f - v)) * sqrtf(areas_diag[0] / areas_diag[2]); - w[1] = (( u) * (1.0f - v)) * sqrtf(areas_diag[1] / areas_diag[3]); - w[2] = (( u) * ( v)) * sqrtf(areas_diag[2] / areas_diag[0]); - w[3] = ((1.0f - u) * ( v)) * sqrtf(areas_diag[3] / areas_diag[1]); +#undef MEAN_VALUE_HALF_TAN_V2 + + w[0] = (t[3] + t[0]) / lens[0]; + w[1] = (t[0] + t[1]) / lens[1]; + w[2] = (t[1] + t[2]) / lens[2]; + w[3] = (t[2] + t[3]) / lens[3]; wtot = w[0] + w[1] + w[2] + w[3]; @@ -2190,6 +2200,7 @@ static float mean_value_half_tan_v2(const float v1[2], const float v2[2], const void interp_weights_poly_v3(float *w, float v[][3], const int n, const float co[3]) { + /* TODO: t1 and t2 overlap each iter, we could call this only once per iter and reuse previous value */ float totweight, t1, t2, len, *vmid, *vprev, *vnext; int i; @@ -2217,6 +2228,7 @@ void interp_weights_poly_v3(float *w, float v[][3], const int n, const float co[ void interp_weights_poly_v2(float *w, float v[][2], const int n, const float co[2]) { + /* TODO: t1 and t2 overlap each iter, we could call this only once per iter and reuse previous value */ float totweight, t1, t2, len, *vmid, *vprev, *vnext; int i; From e32d963478b2589e2f48bf86eb3894fcac58efe5 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 16 Jul 2012 12:08:28 +0000 Subject: [PATCH 043/108] mask rasterizer - use quad interpolation - gets rid of ugly diagonal banding, introduces glitch with bowtie quads, will have to fix next. --- source/blender/blenkernel/intern/mask_rasterize.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/source/blender/blenkernel/intern/mask_rasterize.c b/source/blender/blenkernel/intern/mask_rasterize.c index 5428e8c6335..ef87f47993c 100644 --- a/source/blender/blenkernel/intern/mask_rasterize.c +++ b/source/blender/blenkernel/intern/mask_rasterize.c @@ -849,6 +849,7 @@ void BKE_maskrasterize_handle_init(MaskRasterHandle *mr_handle, struct Mask *mas /* --------------------------------------------------------------------- */ /* 2D ray test */ +#if 0 static float maskrasterize_layer_z_depth_tri(const float pt[2], const float v1[3], const float v2[3], const float v3[3]) { @@ -856,14 +857,16 @@ static float maskrasterize_layer_z_depth_tri(const float pt[2], barycentric_weights_v2(v1, v2, v3, pt, w); return (v1[2] * w[0]) + (v2[2] * w[1]) + (v3[2] * w[2]); } +#endif -#if 0 +#if 1 static float maskrasterize_layer_z_depth_quad(const float pt[2], const float v1[3], const float v2[3], const float v3[3], const float v4[3]) { float w[4]; barycentric_weights_v2_quad(v1, v2, v3, v4, pt, w); - return (v1[2] * w[0]) + (v2[2] * w[1]) + (v3[2] * w[2]) + (v4[2] * w[3]); + //return (v1[2] * w[0]) + (v2[2] * w[1]) + (v3[2] * w[2]) + (v4[2] * w[3]); + return (1.0f * w[2]) + (1.0f * w[3]); /* we can make this assumption for small speedup */ } #endif @@ -904,8 +907,12 @@ static float maskrasterize_layer_isect(unsigned int *face, float (*cos)[3], cons { /* needs work */ -#if 0 - if (isect_point_quad_v2(xy, cos[face[0]], cos[face[1]], cos[face[2]], cos[face[3]])) { +#if 1 + /* quad check fails for bowtie, so keep using 2 tri checks */ + //if (isect_point_quad_v2(xy, cos[face[0]], cos[face[1]], cos[face[2]], cos[face[3]])) + if (isect_point_tri_v2(xy, cos[face[0]], cos[face[1]], cos[face[2]]) || + isect_point_tri_v2(xy, cos[face[0]], cos[face[2]], cos[face[3]])) + { return maskrasterize_layer_z_depth_quad(xy, cos[face[0]], cos[face[1]], cos[face[2]], cos[face[3]]); } #elif 1 From f6b3a6e6f380df6ebcf405eb53f6c22dbd51f8f6 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 16 Jul 2012 12:49:01 +0000 Subject: [PATCH 044/108] fix for occasional crash with splines a lot larger then the view --- .../blender/blenkernel/intern/mask_rasterize.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/source/blender/blenkernel/intern/mask_rasterize.c b/source/blender/blenkernel/intern/mask_rasterize.c index ef87f47993c..29e7c94f431 100644 --- a/source/blender/blenkernel/intern/mask_rasterize.c +++ b/source/blender/blenkernel/intern/mask_rasterize.c @@ -383,14 +383,21 @@ static void layer_bucket_init(MaskRasterLayer *layer, const float pixel_size) CLAMP(ymax, 0.0f, 1.0f); { - const unsigned int xi_min = (unsigned int) ((xmin - layer->bounds.xmin) * layer->buckets_xy_scalar[0]); - 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]); + unsigned int xi_min = (unsigned int) ((xmin - layer->bounds.xmin) * layer->buckets_xy_scalar[0]); + unsigned int xi_max = (unsigned int) ((xmax - layer->bounds.xmin) * layer->buckets_xy_scalar[0]); + unsigned int yi_min = (unsigned int) ((ymin - layer->bounds.ymin) * layer->buckets_xy_scalar[1]); + 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; + /* this should _almost_ never happen but since it can in extreme cases, + * we have to clamp the values or we overrun the buffer and crash */ + CLAMP(xi_min, 0, layer->buckets_x - 1); + CLAMP(xi_max, 0, layer->buckets_x - 1); + CLAMP(yi_min, 0, layer->buckets_y - 1); + CLAMP(yi_max, 0, layer->buckets_y - 1); + 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++) { @@ -866,7 +873,7 @@ static float maskrasterize_layer_z_depth_quad(const float pt[2], float w[4]; barycentric_weights_v2_quad(v1, v2, v3, v4, pt, w); //return (v1[2] * w[0]) + (v2[2] * w[1]) + (v3[2] * w[2]) + (v4[2] * w[3]); - return (1.0f * w[2]) + (1.0f * w[3]); /* we can make this assumption for small speedup */ + return w[2] + w[3]; /* we can make this assumption for small speedup */ } #endif From 9362a01ff39494e33fd002f3e5561d7e7a8c7408 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 16 Jul 2012 13:00:54 +0000 Subject: [PATCH 045/108] fix for crash & leak when layer render option is disabled. --- .../blenkernel/intern/mask_rasterize.c | 28 +++++++++++++------ 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/source/blender/blenkernel/intern/mask_rasterize.c b/source/blender/blenkernel/intern/mask_rasterize.c index 29e7c94f431..bcc25028ba4 100644 --- a/source/blender/blenkernel/intern/mask_rasterize.c +++ b/source/blender/blenkernel/intern/mask_rasterize.c @@ -302,6 +302,10 @@ static int layer_bucket_isect_test(MaskRasterLayer *layer, unsigned int face_ind static void layer_bucket_init_dummy(MaskRasterLayer *layer) { + layer->face_tot = 0; + layer->face_coords = NULL; + layer->face_array = NULL; + layer->buckets_x = 0; layer->buckets_y = 0; @@ -309,6 +313,8 @@ static void layer_bucket_init_dummy(MaskRasterLayer *layer) layer->buckets_xy_scalar[1] = 0.0f; layer->buckets_face = NULL; + + BLI_rctf_init(&layer->bounds, -1.0f, -1.0f, -1.0f, -1.0f); } static void layer_bucket_init(MaskRasterLayer *layer, const float pixel_size) @@ -478,9 +484,9 @@ void BKE_maskrasterize_handle_init(MaskRasterHandle *mr_handle, struct Mask *mas for (masklay = mask->masklayers.first, masklay_index = 0; masklay; masklay = masklay->next, masklay_index++) { - const unsigned int tot_splines = BLI_countlist(&masklay->splines); /* we need to store vertex ranges for open splines for filling */ - MaskRasterSplineInfo *open_spline_ranges = MEM_callocN(sizeof(*open_spline_ranges) * tot_splines, __func__); + unsigned int tot_splines; + MaskRasterSplineInfo *open_spline_ranges; unsigned int open_spline_index = 0; MaskSpline *spline; @@ -494,10 +500,16 @@ void BKE_maskrasterize_handle_init(MaskRasterHandle *mr_handle, struct Mask *mas unsigned int sf_vert_tot = 0; unsigned int tot_feather_quads = 0; - if (masklay->restrictflag & MASK_RESTRICT_RENDER) { + if (masklay->restrictflag & MASK_RESTRICT_RENDER || masklay->alpha == 0.0f) { + MaskRasterLayer *layer = &mr_handle->layers[masklay_index]; + layer_bucket_init_dummy(layer); + layer->alpha = 0.0f; /* signal to skip this layer */ continue; } + tot_splines = BLI_countlist(&masklay->splines); + open_spline_ranges = MEM_callocN(sizeof(*open_spline_ranges) * tot_splines, __func__); + BLI_scanfill_begin(&sf_ctx); for (spline = masklay->splines.first; spline; spline = spline->next) { @@ -826,13 +838,7 @@ void BKE_maskrasterize_handle_init(MaskRasterHandle *mr_handle, struct Mask *mas MEM_freeN(face_coords); MEM_freeN(face_array); - layer->face_tot = 0; - layer->face_coords = NULL; - layer->face_array = NULL; - layer_bucket_init_dummy(layer); - - BLI_rctf_init(&layer->bounds, -1.0f, -1.0f, -1.0f, -1.0f); } /* copy as-is */ @@ -992,6 +998,10 @@ float BKE_maskrasterize_handle_sample(MaskRasterHandle *mr_handle, const float x for (i = 0; i < layers_tot; i++, layer++) { float value_layer; + if (layer->alpha == 0.0f) { + continue; + } + if (BLI_in_rctf_v(&layer->bounds, xy)) { value_layer = 1.0f - layer_bucket_depth_from_xy(layer, xy); From 5b4a455569aab9557edff112ea1ffadc10a6738a Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 16 Jul 2012 13:12:52 +0000 Subject: [PATCH 046/108] defailt to ease weight interpolation --- source/blender/blenkernel/intern/mask.c | 2 +- source/blender/blenkernel/intern/mask_rasterize.c | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/source/blender/blenkernel/intern/mask.c b/source/blender/blenkernel/intern/mask.c index 4e683d1618f..1efa62efa13 100644 --- a/source/blender/blenkernel/intern/mask.c +++ b/source/blender/blenkernel/intern/mask.c @@ -239,7 +239,7 @@ MaskSpline *BKE_mask_spline_add(MaskLayer *masklay) /* cyclic shapes are more usually used */ // spline->flag |= MASK_SPLINE_CYCLIC; // disable because its not so nice for drawing. could be done differently - spline->weight_interp = MASK_SPLINE_INTERP_LINEAR; + spline->weight_interp = MASK_SPLINE_INTERP_EASE; BKE_mask_parent_init(&spline->parent); diff --git a/source/blender/blenkernel/intern/mask_rasterize.c b/source/blender/blenkernel/intern/mask_rasterize.c index bcc25028ba4..c3d67a24c3b 100644 --- a/source/blender/blenkernel/intern/mask_rasterize.c +++ b/source/blender/blenkernel/intern/mask_rasterize.c @@ -998,6 +998,7 @@ float BKE_maskrasterize_handle_sample(MaskRasterHandle *mr_handle, const float x for (i = 0; i < layers_tot; i++, layer++) { float value_layer; + /* also used as signal for unused layer (when render is disabled) */ if (layer->alpha == 0.0f) { continue; } From f9e63430ac38f806ac9e69b57f37cd07111f1970 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 16 Jul 2012 14:17:01 +0000 Subject: [PATCH 047/108] use calculated spline resoltion rather then fixed at 32. --- source/blender/blenkernel/BKE_mask.h | 3 +++ source/blender/blenkernel/intern/mask.c | 4 ++-- source/blender/blenkernel/intern/mask_rasterize.c | 5 ++++- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/source/blender/blenkernel/BKE_mask.h b/source/blender/blenkernel/BKE_mask.h index 411350764b3..a293e4a784b 100644 --- a/source/blender/blenkernel/BKE_mask.h +++ b/source/blender/blenkernel/BKE_mask.h @@ -64,6 +64,9 @@ void BKE_mask_layer_copy_list(struct ListBase *masklayers_new, struct ListBase * /* splines */ struct MaskSpline *BKE_mask_spline_add(struct MaskLayer *masklay); +int BKE_mask_spline_resolution(struct MaskSpline *spline, int width, int height); +int BKE_mask_spline_feather_resolution(struct MaskSpline *spline, int width, int height); + int BKE_mask_spline_differentiate_calc_total(const struct MaskSpline *spline, const int resol); float (*BKE_mask_spline_differentiate(struct MaskSpline *spline, int *tot_diff_point))[2]; diff --git a/source/blender/blenkernel/intern/mask.c b/source/blender/blenkernel/intern/mask.c index 1efa62efa13..9374b5dc1d9 100644 --- a/source/blender/blenkernel/intern/mask.c +++ b/source/blender/blenkernel/intern/mask.c @@ -246,7 +246,7 @@ MaskSpline *BKE_mask_spline_add(MaskLayer *masklay) return spline; } -static int BKE_mask_spline_resolution(MaskSpline *spline, int width, int height) +int BKE_mask_spline_resolution(MaskSpline *spline, int width, int height) { float max_segment = 0.01f; int i, resol = 1; @@ -284,7 +284,7 @@ static int BKE_mask_spline_resolution(MaskSpline *spline, int width, int height) return resol; } -static int BKE_mask_spline_feather_resolution(MaskSpline *spline, int width, int height) +int BKE_mask_spline_feather_resolution(MaskSpline *spline, int width, int height) { const float max_segment = 0.005; int resol = BKE_mask_spline_resolution(spline, width, height); diff --git a/source/blender/blenkernel/intern/mask_rasterize.c b/source/blender/blenkernel/intern/mask_rasterize.c index c3d67a24c3b..7b84abc3d36 100644 --- a/source/blender/blenkernel/intern/mask_rasterize.c +++ b/source/blender/blenkernel/intern/mask_rasterize.c @@ -471,7 +471,6 @@ void BKE_maskrasterize_handle_init(MaskRasterHandle *mr_handle, struct Mask *mas const short do_feather) { const rctf default_bounds = {0.0f, 1.0f, 0.0f, 1.0f}; - 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}; @@ -522,6 +521,10 @@ void BKE_maskrasterize_handle_init(MaskRasterHandle *mr_handle, struct Mask *mas float (*diff_feather_points)[2]; int tot_diff_feather_points; + const int resol_a = BKE_mask_spline_resolution(spline, width, height) / 4; + const int resol_b = BKE_mask_spline_feather_resolution(spline, width, height) / 4; + const int resol = CLAMPIS(MAX2(resol_a, resol_b), 4, 512); + diff_points = BKE_mask_spline_differentiate_with_resolution_ex( spline, resol, &tot_diff_point); From 13b56dec782e7b492fed2107eb4db0736e93d10f Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 16 Jul 2012 14:27:45 +0000 Subject: [PATCH 048/108] show alpha in the mask buttons item list --- source/blender/editors/interface/interface_templates.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/blender/editors/interface/interface_templates.c b/source/blender/editors/interface/interface_templates.c index 49e3818fe08..8832f32f43d 100644 --- a/source/blender/editors/interface/interface_templates.c +++ b/source/blender/editors/interface/interface_templates.c @@ -2242,13 +2242,13 @@ static void list_item_row(bContext *C, uiLayout *layout, PointerRNA *ptr, Pointe } } else if (itemptr->type == &RNA_MaskLayer) { - split = uiLayoutSplit(sub, 0.5f, FALSE); + split = uiLayoutRow(sub, FALSE); uiItemL(split, name, icon); uiBlockSetEmboss(block, UI_EMBOSSN); row = uiLayoutRow(split, TRUE); - // uiItemR(row, itemptr, "alpha", 0, "", ICON_NONE); // enable when used + uiItemR(row, itemptr, "alpha", 0, "", ICON_NONE); // enable when used uiItemR(row, itemptr, "hide", 0, "", 0); uiItemR(row, itemptr, "hide_select", 0, "", 0); uiItemR(row, itemptr, "hide_render", 0, "", 0); From 7881d2c1a879702223f742b7d39b620914d2263f Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 16 Jul 2012 15:40:47 +0000 Subject: [PATCH 049/108] correct own error in logic for skipping mask layers, inverted mask layers with zero alpha still need to be evaluated. --- source/blender/blenkernel/intern/mask_rasterize.c | 14 +++++--------- .../editors/interface/interface_templates.c | 2 +- 2 files changed, 6 insertions(+), 10 deletions(-) diff --git a/source/blender/blenkernel/intern/mask_rasterize.c b/source/blender/blenkernel/intern/mask_rasterize.c index 7b84abc3d36..2fe1ffaae9e 100644 --- a/source/blender/blenkernel/intern/mask_rasterize.c +++ b/source/blender/blenkernel/intern/mask_rasterize.c @@ -499,10 +499,10 @@ void BKE_maskrasterize_handle_init(MaskRasterHandle *mr_handle, struct Mask *mas unsigned int sf_vert_tot = 0; unsigned int tot_feather_quads = 0; - if (masklay->restrictflag & MASK_RESTRICT_RENDER || masklay->alpha == 0.0f) { - MaskRasterLayer *layer = &mr_handle->layers[masklay_index]; - layer_bucket_init_dummy(layer); - layer->alpha = 0.0f; /* signal to skip this layer */ + if (masklay->restrictflag & MASK_RESTRICT_RENDER) { + /* skip the layer */ + mr_handle->layers_tot--; + masklay_index--; continue; } @@ -1002,11 +1002,7 @@ float BKE_maskrasterize_handle_sample(MaskRasterHandle *mr_handle, const float x float value_layer; /* also used as signal for unused layer (when render is disabled) */ - if (layer->alpha == 0.0f) { - continue; - } - - if (BLI_in_rctf_v(&layer->bounds, xy)) { + if (layer->alpha != 0.0f && BLI_in_rctf_v(&layer->bounds, xy)) { value_layer = 1.0f - layer_bucket_depth_from_xy(layer, xy); switch (layer->falloff) { diff --git a/source/blender/editors/interface/interface_templates.c b/source/blender/editors/interface/interface_templates.c index 8832f32f43d..4702253140a 100644 --- a/source/blender/editors/interface/interface_templates.c +++ b/source/blender/editors/interface/interface_templates.c @@ -2248,7 +2248,7 @@ static void list_item_row(bContext *C, uiLayout *layout, PointerRNA *ptr, Pointe uiBlockSetEmboss(block, UI_EMBOSSN); row = uiLayoutRow(split, TRUE); - uiItemR(row, itemptr, "alpha", 0, "", ICON_NONE); // enable when used + uiItemR(row, itemptr, "alpha", 0, "", ICON_NONE); uiItemR(row, itemptr, "hide", 0, "", 0); uiItemR(row, itemptr, "hide_select", 0, "", 0); uiItemR(row, itemptr, "hide_render", 0, "", 0); From 54bfdb9296fa1dd8612181d82f4f925111db782f Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 16 Jul 2012 16:16:05 +0000 Subject: [PATCH 050/108] toggling node hide/sockets/options was triggering a re-render. --- source/blender/editors/space_node/node_edit.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/source/blender/editors/space_node/node_edit.c b/source/blender/editors/space_node/node_edit.c index 5e5ffe2049c..8b7251c2018 100644 --- a/source/blender/editors/space_node/node_edit.c +++ b/source/blender/editors/space_node/node_edit.c @@ -3986,9 +3986,9 @@ static int node_hide_toggle_exec(bContext *C, wmOperator *UNUSED(op)) return OPERATOR_CANCELLED; node_flag_toggle_exec(snode, NODE_HIDDEN); - - snode_notify(C, snode); - + + WM_event_add_notifier(C, NC_NODE | ND_DISPLAY, NULL); + return OPERATOR_FINISHED; } @@ -4049,7 +4049,7 @@ static int node_options_toggle_exec(bContext *C, wmOperator *UNUSED(op)) node_flag_toggle_exec(snode, NODE_OPTIONS); - snode_notify(C, snode); + WM_event_add_notifier(C, NC_NODE | ND_DISPLAY, NULL); return OPERATOR_FINISHED; } @@ -4100,7 +4100,7 @@ static int node_socket_toggle_exec(bContext *C, wmOperator *UNUSED(op)) ntreeUpdateTree(snode->edittree); - snode_notify(C, snode); + WM_event_add_notifier(C, NC_NODE | ND_DISPLAY, NULL); return OPERATOR_FINISHED; } From 3a039d0e101b2379a64d584bf3f77f2380fd0120 Mon Sep 17 00:00:00 2001 From: Nicholas Bishop Date: Mon, 16 Jul 2012 16:55:58 +0000 Subject: [PATCH 051/108] Put paint mask grid allocation in a critical section When OpenMP is enabled, memory allocation needs to be protected. Fixes bug [#32111] Memory management regression from svn_46520 projects.blender.org/tracker/index.php?func=detail&aid=32111&group_id=9&atid=498 --- source/blender/blenkernel/intern/multires.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/source/blender/blenkernel/intern/multires.c b/source/blender/blenkernel/intern/multires.c index db39bf74e48..a75d890dcb4 100644 --- a/source/blender/blenkernel/intern/multires.c +++ b/source/blender/blenkernel/intern/multires.c @@ -1067,9 +1067,12 @@ static void multiresModifier_disp_run(DerivedMesh *dm, Mesh *me, DerivedMesh *dm /* if needed, reallocate multires paint mask */ if (gpm && gpm->level < key.level) { gpm->level = key.level; - if (gpm->data) - MEM_freeN(gpm->data); - gpm->data = MEM_callocN(sizeof(float) * key.grid_area, "gpm.data"); + #pragma omp critical + { + if (gpm->data) + MEM_freeN(gpm->data); + gpm->data = MEM_callocN(sizeof(float) * key.grid_area, "gpm.data"); + } } for (y = 0; y < gridSize; y++) { From 92205486e7d773928e1a09283f0e741fc2e9d24a Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Mon, 16 Jul 2012 17:54:28 +0000 Subject: [PATCH 052/108] Masks: feather self-intersection collapse function This implements simple function which collapses internal loops caused by self-intersections into a singularity. This loops can't be removed because rasterizer expects points of feather be aligned with points from spline itself. --- source/blender/blenkernel/intern/mask.c | 136 ++++++++++++++++++++++ source/blender/blenlib/BLI_math_geom.h | 1 + source/blender/blenlib/intern/math_geom.c | 9 ++ 3 files changed, 146 insertions(+) diff --git a/source/blender/blenkernel/intern/mask.c b/source/blender/blenkernel/intern/mask.c index 9374b5dc1d9..d1610cda7d0 100644 --- a/source/blender/blenkernel/intern/mask.c +++ b/source/blender/blenkernel/intern/mask.c @@ -401,6 +401,140 @@ float (*BKE_mask_spline_differentiate(MaskSpline *spline, int *tot_diff_point))[ return BKE_mask_spline_differentiate_with_resolution(spline, 0, 0, tot_diff_point); } +/* ** feather points self-intersection collapse routine ** */ + +typedef struct FeatherEdgesBucket { + int tot_segment; + int (*segments)[2]; + int alloc_segment; +} FeatherEdgesBucket; + +static void feather_bucket_add_edge(FeatherEdgesBucket *bucket, int start, int end) +{ + const int alloc_delta = 20; + + if (bucket->tot_segment >= bucket->alloc_segment) { + if (!bucket->segments) { + bucket->segments = MEM_callocN(alloc_delta * sizeof(*bucket->segments), "feather bucket segments"); + } + else { + bucket->segments = MEM_reallocN(bucket->segments, + (alloc_delta + bucket->tot_segment) * sizeof(*bucket->segments)); + } + + bucket->alloc_segment += alloc_delta; + } + + bucket->segments[bucket->tot_segment][0] = start; + bucket->segments[bucket->tot_segment][1] = end; + + bucket->tot_segment++; +} + +static void feather_bucket_check_intersect(float (*feather_points)[2], FeatherEdgesBucket *bucket, int cur_a, int cur_b) +{ + int i; + + float *v1 = (float *) feather_points[cur_a]; + float *v2 = (float *) feather_points[cur_b]; + + for (i = 0; i< bucket->tot_segment; i++) { + int check_a = bucket->segments[i][0]; + int check_b = bucket->segments[i][1]; + + float *v3 = (float *) feather_points[check_a]; + float *v4 = (float *) feather_points[check_b]; + + if (check_a >= cur_a - 1 || cur_b == check_a) + continue; + + if (isect_seg_seg_v2(v1, v2, v3, v4)) { + int k; + float p[2]; + + isect_seg_seg_v2_point(v1, v2, v3, v4, p); + + for (k = check_b; k <= cur_a; k++) { + copy_v2_v2(feather_points[k], p); + } + + break; + } + } +} + +static void spline_feather_collapse_inner_loops(float (*feather_points)[2], int tot_feather_point) +{ +#define BUCKET_SIDE_INDEX(co, min, max) ((int) ((co - min) / (max - min + FLT_EPSILON) / bucket_size)) + +#define BUCKET_INDEX_DELTA(co, dx, dy) \ + BUCKET_SIDE_INDEX(co[1] + dy, min[1], max[1]) * buckets_per_side + \ + BUCKET_SIDE_INDEX(co[0] + dx, min[0], max[0]) + +#define BUCKET_INDEX(co) BUCKET_INDEX_DELTA(co, 0, 0) + + const int buckets_per_side = 10; + const int tot_bucket = buckets_per_side * buckets_per_side; + const float bucket_size = 1.0f / buckets_per_side; + + FeatherEdgesBucket *buckets; + + int i; + float min[2], max[2]; + + /* find min/max corners of mask to build buckets in that space */ + INIT_MINMAX2(min, max); + + for (i = 0; i < tot_feather_point; i++) { + DO_MINMAX2(feather_points[i], min, max); + } + + /* fill in buckets' edges */ + buckets = MEM_callocN(sizeof(FeatherEdgesBucket) * tot_bucket, "feather buckets"); + + for (i = 0; i < tot_feather_point; i++) { + int start = i; + int end = (i + 1) % tot_feather_point; + + int start_bucket_index = BUCKET_INDEX(feather_points[start]); + int end_bucket_index = BUCKET_INDEX(feather_points[end]); + + feather_bucket_add_edge(&buckets[start_bucket_index], start, end); + + if (start_bucket_index != end_bucket_index) { + feather_bucket_add_edge(&buckets[end_bucket_index], start, end); + } + } + + /* check all edges for intersection with edges from their buckets */ + for (i = 0; i < tot_feather_point; i++) { + int cur_a = i; + int cur_b = (i + 1) % tot_feather_point; + + int start_bucket_index = BUCKET_INDEX(feather_points[cur_a]); + int end_bucket_index = BUCKET_INDEX(feather_points[cur_b]); + + FeatherEdgesBucket *start_bucket = &buckets[start_bucket_index]; + FeatherEdgesBucket *end_bucket = &buckets[end_bucket_index]; + + feather_bucket_check_intersect(feather_points, start_bucket, cur_a, cur_b); + + if (start_bucket != end_bucket) + feather_bucket_check_intersect(feather_points, end_bucket, cur_a, cur_b); + } + + /* free buckets */ + for (i = 0; i < tot_bucket; i++) { + if (buckets[i].segments) + MEM_freeN(buckets[i].segments); + } + + MEM_freeN(buckets); + +#undef BUCKET_INDEX +#undef BUCKET_SIZE_INDEX +} + /** * values align with #BKE_mask_spline_differentiate_with_resolution_ex * when \a resol arguments match. @@ -467,6 +601,8 @@ float (*BKE_mask_spline_feather_differentiated_points_with_resolution_ex(MaskSpl *tot_feather_point = tot; + spline_feather_collapse_inner_loops(feather, tot); + return feather; } diff --git a/source/blender/blenlib/BLI_math_geom.h b/source/blender/blenlib/BLI_math_geom.h index 4c037b6e73c..107b688b36a 100644 --- a/source/blender/blenlib/BLI_math_geom.h +++ b/source/blender/blenlib/BLI_math_geom.h @@ -93,6 +93,7 @@ int isect_line_line_v2_int(const int a1[2], const int a2[2], const int b1[2], co int isect_line_sphere_v3(const float l1[3], const float l2[3], const float sp[3], const float r, float r_p1[3], float r_p2[3]); int isect_line_sphere_v2(const float l1[2], const float l2[2], const float sp[2], const float r, float r_p1[2], float r_p2[2]); int isect_seg_seg_v2_point(const float v1[2], const float v2[2], const float v3[2], const float v4[2], float vi[2]); +int isect_seg_seg_v2(const float v1[2], const float v2[2], const float v3[2], const float v4[2]); /* Returns the number of point of interests * 0 - lines are colinear diff --git a/source/blender/blenlib/intern/math_geom.c b/source/blender/blenlib/intern/math_geom.c index da4846e7af1..cc9cb7a876b 100644 --- a/source/blender/blenlib/intern/math_geom.c +++ b/source/blender/blenlib/intern/math_geom.c @@ -426,6 +426,15 @@ int isect_seg_seg_v2_point(const float v1[2], const float v2[2], const float v3[ return -1; } +int isect_seg_seg_v2(const float v1[2], const float v2[2], const float v3[2], const float v4[2]) +{ +#define CCW(A, B, C) ((C[1] - A[1]) * (B[0] - A[0]) > (B[1]-A[1]) * (C[0]-A[0])) + + return CCW(v1, v3, v4) != CCW(v2, v3, v4) && CCW(v1, v2, v3) != CCW(v1, v2, v4); + +#undef CCW +} + int isect_line_sphere_v3(const float l1[3], const float l2[3], const float sp[3], const float r, float r_p1[3], float r_p2[3]) From 5915b533508d4414b1f8f2351d85f6a87b3c14f8 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Mon, 16 Jul 2012 18:34:57 +0000 Subject: [PATCH 053/108] Fixed crash caused by recent feather collapse commit --- source/blender/blenkernel/intern/mask.c | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/source/blender/blenkernel/intern/mask.c b/source/blender/blenkernel/intern/mask.c index d1610cda7d0..a5ec9743ae6 100644 --- a/source/blender/blenkernel/intern/mask.c +++ b/source/blender/blenkernel/intern/mask.c @@ -463,15 +463,24 @@ static void feather_bucket_check_intersect(float (*feather_points)[2], FeatherEd } } +static int feather_bucket_index_from_coord(float co[2], float min[2], float max[2], const int buckets_per_side, const float bucket_size) +{ +#define BUCKET_SIDE_INDEX(co, min, max) ((int) ((co - min) / (max - min) / bucket_size)) + + int x = BUCKET_SIDE_INDEX(co[0], min[0], max[0]); + int y = BUCKET_SIDE_INDEX(co[1], min[1], max[1]); + + x = MIN2(x, buckets_per_side - 1); + y = MIN2(y, buckets_per_side - 1); + + return y * buckets_per_side + x; +#undef BUCKET_SIDE_INDEX +} + static void spline_feather_collapse_inner_loops(float (*feather_points)[2], int tot_feather_point) { -#define BUCKET_SIDE_INDEX(co, min, max) ((int) ((co - min) / (max - min + FLT_EPSILON) / bucket_size)) - -#define BUCKET_INDEX_DELTA(co, dx, dy) \ - BUCKET_SIDE_INDEX(co[1] + dy, min[1], max[1]) * buckets_per_side + \ - BUCKET_SIDE_INDEX(co[0] + dx, min[0], max[0]) - -#define BUCKET_INDEX(co) BUCKET_INDEX_DELTA(co, 0, 0) +#define BUCKET_INDEX(co) \ + feather_bucket_index_from_coord(co, min, max, buckets_per_side, bucket_size) const int buckets_per_side = 10; const int tot_bucket = buckets_per_side * buckets_per_side; @@ -532,7 +541,6 @@ static void spline_feather_collapse_inner_loops(float (*feather_points)[2], int MEM_freeN(buckets); #undef BUCKET_INDEX -#undef BUCKET_SIZE_INDEX } /** From 1f96470b5d80f05aef1dc1c262ba1a0a56a1d1fb Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Mon, 16 Jul 2012 19:23:15 +0000 Subject: [PATCH 054/108] Fixed disappearing in some circumstances feather Real fix would be to find a point which is definitely now on loop to be collapsed, but that's for a bit later. This commit should remove possible stoppers. --- source/blender/blenkernel/intern/mask.c | 33 ++++++++++++++++++------- 1 file changed, 24 insertions(+), 9 deletions(-) diff --git a/source/blender/blenkernel/intern/mask.c b/source/blender/blenkernel/intern/mask.c index a5ec9743ae6..7eb06a1b9ca 100644 --- a/source/blender/blenkernel/intern/mask.c +++ b/source/blender/blenkernel/intern/mask.c @@ -411,7 +411,7 @@ typedef struct FeatherEdgesBucket { static void feather_bucket_add_edge(FeatherEdgesBucket *bucket, int start, int end) { - const int alloc_delta = 20; + const int alloc_delta = 32; if (bucket->tot_segment >= bucket->alloc_segment) { if (!bucket->segments) { @@ -431,7 +431,8 @@ static void feather_bucket_add_edge(FeatherEdgesBucket *bucket, int start, int e bucket->tot_segment++; } -static void feather_bucket_check_intersect(float (*feather_points)[2], FeatherEdgesBucket *bucket, int cur_a, int cur_b) +static void feather_bucket_check_intersect(float (*feather_points)[2], int tot_feather_point, FeatherEdgesBucket *bucket, + int cur_a, int cur_b) { int i; @@ -449,21 +450,35 @@ static void feather_bucket_check_intersect(float (*feather_points)[2], FeatherEd continue; if (isect_seg_seg_v2(v1, v2, v3, v4)) { - int k; + int k, len; float p[2]; isect_seg_seg_v2_point(v1, v2, v3, v4, p); - for (k = check_b; k <= cur_a; k++) { - copy_v2_v2(feather_points[k], p); + /* TODO: for now simply choose the shortest loop, could be made smarter in some way */ + len = cur_a - check_b; + if (len < tot_feather_point - len) { + for (k = check_b; k <= cur_a; k++) { + copy_v2_v2(feather_points[k], p); + } } + else { + for (k = 0; k <= check_a; k++) { + copy_v2_v2(feather_points[k], p); + } - break; + if (cur_b != 0) { + for (k = cur_b; k < tot_feather_point; k++) { + copy_v2_v2(feather_points[k], p); + } + } + } } } } -static int feather_bucket_index_from_coord(float co[2], float min[2], float max[2], const int buckets_per_side, const float bucket_size) +static int feather_bucket_index_from_coord(float co[2], float min[2], float max[2], + const int buckets_per_side, const float bucket_size) { #define BUCKET_SIDE_INDEX(co, min, max) ((int) ((co - min) / (max - min) / bucket_size)) @@ -526,10 +541,10 @@ static void spline_feather_collapse_inner_loops(float (*feather_points)[2], int FeatherEdgesBucket *start_bucket = &buckets[start_bucket_index]; FeatherEdgesBucket *end_bucket = &buckets[end_bucket_index]; - feather_bucket_check_intersect(feather_points, start_bucket, cur_a, cur_b); + feather_bucket_check_intersect(feather_points, tot_feather_point, start_bucket, cur_a, cur_b); if (start_bucket != end_bucket) - feather_bucket_check_intersect(feather_points, end_bucket, cur_a, cur_b); + feather_bucket_check_intersect(feather_points, tot_feather_point, end_bucket, cur_a, cur_b); } /* free buckets */ From 32cf7fcdb147d4f467279109db384b9a9d3c6708 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 16 Jul 2012 23:23:33 +0000 Subject: [PATCH 055/108] code cleanup: spelling --- intern/bsp/intern/BSP_CSGMesh.cpp | 2 +- intern/cycles/kernel/kernel_differential.h | 2 +- intern/dualcon/intern/octree.cpp | 2 +- intern/itasc/Scene.cpp | 2 +- intern/raskter/raskter.c | 4 +-- intern/smoke/intern/FLUID_3D.h | 2 +- source/blender/blenkernel/intern/curve.c | 2 +- source/blender/blenkernel/intern/fmodifier.c | 2 +- source/blender/blenkernel/intern/group.c | 2 +- source/blender/blenkernel/intern/implicit.c | 4 +-- .../blenkernel/intern/mask_rasterize.c | 3 +- source/blender/blenkernel/intern/mball.c | 2 +- source/blender/blenkernel/intern/multires.c | 4 +-- source/blender/blenkernel/intern/pointcache.c | 2 +- source/blender/blenkernel/intern/seqeffects.c | 4 +-- source/blender/blenkernel/intern/sequencer.c | 2 +- source/blender/blenkernel/intern/softbody.c | 6 ++-- source/blender/blenlib/intern/BLI_kdopbvh.c | 8 ++--- source/blender/blenlib/intern/DLRB_tree.c | 2 +- source/blender/blenlib/intern/math_geom.c | 10 +++---- .../blenlib/intern/math_vector_inline.c | 2 +- source/blender/blenlib/intern/path_util.c | 2 +- source/blender/blenloader/intern/readfile.c | 8 ++--- source/blender/bmesh/intern/bmesh_core.c | 2 +- source/blender/bmesh/intern/bmesh_marking.c | 2 +- .../blender/bmesh/intern/bmesh_operator_api.h | 2 +- source/blender/bmesh/intern/bmesh_polygon.c | 2 +- source/blender/bmesh/intern/bmesh_queries.c | 10 +++---- source/blender/bmesh/intern/bmesh_structure.h | 2 +- source/blender/bmesh/operators/bmo_bevel.c | 2 +- source/blender/bmesh/operators/bmo_dissolve.c | 4 +-- source/blender/bmesh/operators/bmo_hull.c | 2 +- source/blender/bmesh/operators/bmo_inset.c | 2 +- source/blender/bmesh/operators/bmo_utils.c | 2 +- source/blender/bmesh/tools/BME_bevel.c | 2 +- source/blender/compositor/COM_compositor.h | 30 +++++++++---------- .../compositor/intern/COM_ExecutionGroup.h | 4 +-- .../compositor/intern/COM_ExecutionSystem.h | 4 +-- .../compositor/intern/COM_MemoryBuffer.h | 4 +-- .../compositor/intern/COM_MemoryProxy.h | 2 +- source/blender/compositor/intern/COM_Node.h | 2 +- .../compositor/intern/COM_NodeOperation.h | 2 +- .../COM_DoubleEdgeMaskOperation.cpp | 8 ++--- .../operations/COM_KeyingBlurOperation.h | 2 +- .../editors/animation/anim_channels_defines.c | 4 +-- source/blender/editors/interface/view2d.c | 2 +- source/blender/editors/object/object_group.c | 2 +- .../blender/editors/physics/physics_fluid.c | 2 +- source/blender/editors/screen/screen_ops.c | 2 +- .../blender/editors/sculpt_paint/paint_ops.c | 2 +- .../blender/editors/space_view3d/drawobject.c | 4 +-- source/blender/gpu/intern/gpu_buffers.c | 2 +- source/blender/imbuf/IMB_moviecache.h | 2 +- source/blender/imbuf/intern/imageprocess.c | 6 ---- source/blender/imbuf/intern/jp2.c | 2 +- source/blender/imbuf/intern/jpeg.c | 4 +-- source/blender/imbuf/intern/scaling.c | 4 +-- source/blender/makesdna/DNA_anim_types.h | 2 +- source/blender/makesdna/DNA_texture_types.h | 2 +- source/blender/makesdna/intern/dna_genfile.c | 6 ++-- source/blender/makesrna/RNA_types.h | 2 +- .../blender/makesrna/intern/rna_scene_api.c | 2 +- .../blender/makesrna/intern/rna_sequencer.c | 2 +- source/blender/modifiers/intern/MOD_array.c | 2 +- .../blender/modifiers/intern/MOD_solidify.c | 2 +- .../modifiers/intern/MOD_weightvgproximity.c | 2 +- .../nodes/node_composite_doubleEdgeMask.c | 8 ++--- .../blender/nodes/shader/node_shader_util.c | 2 +- source/blender/python/bmesh/bmesh_py_types.c | 4 +-- .../python/bmesh/bmesh_py_types_meshdata.c | 2 +- .../python/bmesh/bmesh_py_types_select.c | 2 +- .../python/generic/bpy_internal_import.c | 2 +- source/blender/python/generic/idprop_py_api.c | 2 +- source/blender/python/generic/py_capi_utils.c | 2 +- source/blender/python/intern/bpy_operator.c | 2 +- source/blender/python/intern/bpy_props.c | 2 +- source/blender/python/intern/bpy_rna.c | 2 +- source/blender/python/intern/bpy_rna_array.c | 2 +- .../python/mathutils/mathutils_Color.c | 2 +- .../python/mathutils/mathutils_Matrix.c | 2 +- .../python/mathutils/mathutils_Vector.c | 4 +-- source/blender/quicktime/apple/qtkit_export.m | 4 +-- source/blender/quicktime/apple/qtkit_import.m | 2 +- .../quicktime/apple/quicktime_import.c | 2 +- source/blender/render/intern/include/zbuf.h | 4 +-- .../render/intern/raytrace/reorganize.h | 2 +- .../render/intern/source/convertblender.c | 4 +-- .../render/intern/source/imagetexture.c | 2 +- .../blender/render/intern/source/rayshade.c | 2 +- .../render/intern/source/render_texture.c | 2 +- .../render/intern/source/renderdatabase.c | 2 +- source/blender/render/intern/source/sunsky.c | 2 +- .../blender/render/intern/source/volumetric.c | 2 +- source/blender/render/intern/source/zbuf.c | 2 +- .../windowmanager/intern/wm_event_system.c | 2 +- .../gameengine/GameLogic/SCA_KeyboardSensor.h | 2 +- 96 files changed, 150 insertions(+), 157 deletions(-) diff --git a/intern/bsp/intern/BSP_CSGMesh.cpp b/intern/bsp/intern/BSP_CSGMesh.cpp index 82919688a38..4dda7741f67 100644 --- a/intern/bsp/intern/BSP_CSGMesh.cpp +++ b/intern/bsp/intern/BSP_CSGMesh.cpp @@ -486,7 +486,7 @@ VertexFaces( BSP_MEdge &e = edges[*e_it]; // iterate through the faces of this edge - push unselected - // edges to ouput and then select the edge + // edges to output and then select the edge vector::const_iterator e_faces_end = e.m_faces.end(); vector::iterator e_faces_it = e.m_faces.begin(); diff --git a/intern/cycles/kernel/kernel_differential.h b/intern/cycles/kernel/kernel_differential.h index 04027523ea5..2190e04e231 100644 --- a/intern/cycles/kernel/kernel_differential.h +++ b/intern/cycles/kernel/kernel_differential.h @@ -22,7 +22,7 @@ CCL_NAMESPACE_BEGIN __device void differential_transfer(differential3 *dP_, const differential3 dP, float3 D, const differential3 dD, float3 Ng, float t) { - /* ray differential transfer through homogenous medium, to + /* ray differential transfer through homogeneous medium, to * compute dPdx/dy at a shading point from the incoming ray */ float3 tmp = D/dot(D, Ng); diff --git a/intern/dualcon/intern/octree.cpp b/intern/dualcon/intern/octree.cpp index 1ad502b018d..9f44e7bbfdf 100644 --- a/intern/dualcon/intern/octree.cpp +++ b/intern/dualcon/intern/octree.cpp @@ -54,7 +54,7 @@ Octree::Octree(ModelReader *mr, After playing around with this option, the only case I could find where this option gives different results is on relatively thin corners. Sometimes along these corners two - vertices from seperate sides will be placed in the same + vertices from separate sides will be placed in the same position, so hole gets filled with a 5-sided face, where two of those vertices are in the same 3D location. If `use_manifold' is disabled, then the modifier doesn't diff --git a/intern/itasc/Scene.cpp b/intern/itasc/Scene.cpp index 877cd883208..7a83f821bf0 100644 --- a/intern/itasc/Scene.cpp +++ b/intern/itasc/Scene.cpp @@ -40,7 +40,7 @@ public: { q_nr += m_qrange.start; project(m_scene->m_Wq, Range(q_nr, ndof), m_qrange).setZero(); - // update the ouput vector so that the movement of this joint will be + // update the ouput vector so that the movement of this joint will be // taken into account and we can put the joint back in its initial position // which means that the jacobian doesn't need to be changed for (unsigned int i=0 ;ilayers; - /* raycast vars */ for (i = 0; i < layers_tot; i++, layer++) { if (layer->face_array) { @@ -225,7 +224,7 @@ void maskrasterize_spline_differentiate_point_outset(float (*diff_feather_points } } -/* this function is not exact, sometimes it retuns false positives, +/* this function is not exact, sometimes it returns false positives, * the main point of it is to clear out _almost_ all bucket/face non-intersections, * returning TRUE in corner cases is ok but missing an intersection is NOT. * diff --git a/source/blender/blenkernel/intern/mball.c b/source/blender/blenkernel/intern/mball.c index b5b03a8924f..f897543db18 100644 --- a/source/blender/blenkernel/intern/mball.c +++ b/source/blender/blenkernel/intern/mball.c @@ -2307,7 +2307,7 @@ void BKE_mball_polygonize(Scene *scene, Object *ob, ListBase *dispbase) metaball_tree = NULL; } - /* if scene includes more then one MetaElem, then octal tree optimalisation is used */ + /* if scene includes more then one MetaElem, then octal tree optimization is used */ if ((totelem > 1) && (totelem <= 64)) init_metaball_octal_tree(1); if ((totelem > 64) && (totelem <= 128)) init_metaball_octal_tree(2); if ((totelem > 128) && (totelem <= 512)) init_metaball_octal_tree(3); diff --git a/source/blender/blenkernel/intern/multires.c b/source/blender/blenkernel/intern/multires.c index a75d890dcb4..866194eea0e 100644 --- a/source/blender/blenkernel/intern/multires.c +++ b/source/blender/blenkernel/intern/multires.c @@ -2105,7 +2105,7 @@ void multires_load_old(Object *ob, Mesh *me) /* XXX We *must* alloc paint mask here, else we have some kind of mismatch in * multires_modifier_update_mdisps() (called by dm->release(dm)), which always creates the * reference subsurfed dm with this option, before calling multiresModifier_disp_run(), - * which implitely expects both subsurfs from its first dm and oldGridData parameters to + * which implicitly expects both subsurfs from its first dm and oldGridData parameters to * be of the same "format"! */ dm = multires_make_derived_from_derived(orig, mmd, ob, MULTIRES_ALLOC_PAINT_MASK); @@ -2120,7 +2120,7 @@ void multires_load_old(Object *ob, Mesh *me) me->mr = NULL; } -/* If 'ob' and 'to_ob' both have multires modifiers, syncronize them +/* If 'ob' and 'to_ob' both have multires modifiers, synchronize them * such that 'ob' has the same total number of levels as 'to_ob'. */ static void multires_sync_levels(Scene *scene, Object *ob, Object *to_ob) { diff --git a/source/blender/blenkernel/intern/pointcache.c b/source/blender/blenkernel/intern/pointcache.c index a3fa8f8be89..90e76e049bd 100644 --- a/source/blender/blenkernel/intern/pointcache.c +++ b/source/blender/blenkernel/intern/pointcache.c @@ -2320,7 +2320,7 @@ void BKE_ptcache_id_time(PTCacheID *pid, Scene *scene, float cfra, int *startfra * - simulation time is scaled by result of bsystem_time * - for offsetting time only time offset is taken into account, since * that's always the same and can't be animated. a timeoffset which - * varies over time is not simpe to support. + * varies over time is not simple to support. * - field and motion blur offsets are currently ignored, proper solution * is probably to interpolate results from two frames for that .. */ diff --git a/source/blender/blenkernel/intern/seqeffects.c b/source/blender/blenkernel/intern/seqeffects.c index 2e2f0e54792..0532a019ecc 100644 --- a/source/blender/blenkernel/intern/seqeffects.c +++ b/source/blender/blenkernel/intern/seqeffects.c @@ -310,7 +310,7 @@ static void do_alphaunder_effect_byte( /* rt = rt1 under rt2 (alpha from rt2) */ - /* this complex optimalisation is because the + /* this complex optimization is because the * 'skybuf' can be crossed in */ if (rt2[3] == 0 && fac2 == 256) *( (unsigned int *)rt) = *( (unsigned int *)rt1); @@ -379,7 +379,7 @@ static void do_alphaunder_effect_float(float facf0, float facf1, int x, int y, /* rt = rt1 under rt2 (alpha from rt2) */ - /* this complex optimalisation is because the + /* this complex optimization is because the * 'skybuf' can be crossed in */ if (rt2[3] <= 0 && fac2 >= 1.0f) { diff --git a/source/blender/blenkernel/intern/sequencer.c b/source/blender/blenkernel/intern/sequencer.c index 902eeefd934..b7f72ff86e2 100644 --- a/source/blender/blenkernel/intern/sequencer.c +++ b/source/blender/blenkernel/intern/sequencer.c @@ -464,7 +464,7 @@ void seq_end(SeqIterator *iter) * ********************************************************************** * build_seqar * ********************************************************************* - * Build a complete array of _all_ sequencies (including those + * Build a complete array of _all_ sequences (including those * in metastrips!) * ********************************************************************* */ diff --git a/source/blender/blenkernel/intern/softbody.c b/source/blender/blenkernel/intern/softbody.c index 1d6895a8c71..ed7fb39a015 100644 --- a/source/blender/blenkernel/intern/softbody.c +++ b/source/blender/blenkernel/intern/softbody.c @@ -2914,7 +2914,7 @@ static void softbody_apply_forces(Object *ob, float forcetime, int mode, float * aabbmin[0]=aabbmin[1]=aabbmin[2] = 1e20f; aabbmax[0]=aabbmax[1]=aabbmax[2] = -1e20f; - /* old one with homogenous masses */ + /* old one with homogeneous masses */ /* claim a minimum mass for vertex */ /* if (sb->nodemass > 0.009999f) timeovermass = forcetime/sb->nodemass; @@ -3297,7 +3297,7 @@ static void mesh_to_softbody(Scene *scene, Object *ob) /* I'd like to have it .. if (sb->namedVG_Goal[0]) */ get_scalar_from_vertexgroup(ob, a, (short) (sb->vertgroup-1), &bp->goal); - /* do this always, regardless successfull read from vertex group */ + /* do this always, regardless successful read from vertex group */ /* this is where '2.5 every thing is animatable' goes wrong in the first place jow_go_for2_5 */ /* 1st coding action to take : move this to frame level */ /* reads: leave the bp->goal as it was read from vertex group / or default .. we will need it at per frame call */ @@ -3811,7 +3811,7 @@ static void softbody_update_positions(Object *ob, SoftBody *sb, float (*vertexCo * that is: * a precise position vector denoting the motion of the center of mass * give a rotation/scale matrix using averaging method, that's why estimate and not calculate - * see: this is kind of reverse engeneering: having to states of a point cloud and recover what happend + * see: this is kind of reverse engineering: having to states of a point cloud and recover what happend * our advantage here we know the identity of the vertex * there are others methods giving other results. * lloc, lrot, lscale are allowed to be NULL, just in case you don't need it. diff --git a/source/blender/blenlib/intern/BLI_kdopbvh.c b/source/blender/blenlib/intern/BLI_kdopbvh.c index a5b5065e023..9a2b94b2c7e 100644 --- a/source/blender/blenlib/intern/BLI_kdopbvh.c +++ b/source/blender/blenlib/intern/BLI_kdopbvh.c @@ -687,7 +687,7 @@ static void split_leafs(BVHNode **leafs_array, int *nth, int partitions, int spl * The reason is that we can build level N+1 from level N without any data dependencies.. thus it allows * to use multithread building. * - * To archieve this is necessary to find how much leafs are accessible from a certain branch, BVHBuildHelper + * To archive this is necessary to find how much leafs are accessible from a certain branch, BVHBuildHelper * implicit_needed_branches and implicit_leafs_index are auxiliary functions to solve that "optimal-split". */ static void non_recursive_bvh_div_nodes(BVHTree *tree, BVHNode *branches_array, BVHNode **leafs_array, int num_leafs) @@ -748,7 +748,7 @@ static void non_recursive_bvh_div_nodes(BVHTree *tree, BVHNode *branches_array, parent->main_axis = split_axis / 2; /* Split the childs along the split_axis, note: its not needed to sort the whole leafs array - * Only to assure that the elements are partioned on a way that each child takes the elements + * Only to assure that the elements are partitioned on a way that each child takes the elements * it would take in case the whole array was sorted. * Split_leafs takes care of that "sort" problem. */ nth_positions[0] = parent_leafs_begin; @@ -982,7 +982,7 @@ void BLI_bvhtree_update_tree(BVHTree *tree) { /* Update bottom=>top * TRICKY: the way we build the tree all the childs have an index greater than the parent - * This allows us todo a bottom up update by starting on the biger numbered branch */ + * This allows us todo a bottom up update by starting on the bigger numbered branch */ BVHNode **root = tree->nodes + tree->totleaf; BVHNode **index = tree->nodes + tree->totleaf + tree->totbranch - 1; @@ -1000,7 +1000,7 @@ float BLI_bvhtree_getepsilon(BVHTree *tree) /* * BLI_bvhtree_overlap * - * overlap - is it possbile for 2 bv's to collide ? */ + * overlap - is it possible for 2 bv's to collide ? */ static int tree_overlap(BVHNode *node1, BVHNode *node2, int start_axis, int stop_axis) { float *bv1 = node1->bv; diff --git a/source/blender/blenlib/intern/DLRB_tree.c b/source/blender/blenlib/intern/DLRB_tree.c index c8c2ad35380..53ae086782b 100644 --- a/source/blender/blenlib/intern/DLRB_tree.c +++ b/source/blender/blenlib/intern/DLRB_tree.c @@ -423,7 +423,7 @@ static void insert_check_2(DLRBT_Tree *tree, DLRBT_Node *node) /* - make the grandparent red, so that we maintain alternating red/black property * (it must exist, so no need to check for NULL here), * - as the grandparent may now cause inconsistencies with the rest of the tree, - * we must flush up the tree and perform checks/rebalancing/repainting, using the + * we must flush up the tree and perform checks/re-balancing/re-painting, using the * grandparent as the node of interest */ gp->tree_col = DLRBT_RED; diff --git a/source/blender/blenlib/intern/math_geom.c b/source/blender/blenlib/intern/math_geom.c index cc9cb7a876b..f2ea93282c9 100644 --- a/source/blender/blenlib/intern/math_geom.c +++ b/source/blender/blenlib/intern/math_geom.c @@ -352,7 +352,7 @@ int isect_line_line_v2(const float v1[2], const float v2[2], const float v3[2], } /* get intersection point of two 2D segments and return intersection type: - * -1: colliniar + * -1: collinear * 1: intersection */ int isect_seg_seg_v2_point(const float v1[2], const float v2[2], const float v3[2], const float v4[2], float vi[2]) @@ -410,7 +410,7 @@ int isect_seg_seg_v2_point(const float v1[2], const float v2[2], const float v3[ } } - /* lines are colliniar */ + /* lines are collinear */ return -1; } @@ -561,7 +561,7 @@ int isect_line_sphere_v2(const float l1[2], const float l2[2], } /* - * -1: colliniar + * -1: collinear * 1: intersection */ static short IsectLLPt2Df(const float x0, const float y0, const float x1, const float y1, @@ -1669,7 +1669,7 @@ static int point_in_slice(const float p[3], const float v1[3], const float l1[3] * a line including l1,l2 and a point not on the line * define a subset of R3 delimited by planes parallel to the line and orthogonal * to the (point --> line) distance vector,one plane on the line one on the point, - * the room inside usually is rather small compared to R3 though still infinte + * the room inside usually is rather small compared to R3 though still infinite * useful for restricting (speeding up) searches * e.g. all points of triangular prism are within the intersection of 3 'slices' * onother trivial case : cube @@ -2843,7 +2843,7 @@ void vcloud_estimate_transform(int list_size, float (*pos)[3], float *weight, fl if (lloc) copy_v3_v3(lloc, accu_com); if (rloc) copy_v3_v3(rloc, accu_rcom); if (lrot || lscale) { /* caller does not want rot nor scale, strange but legal */ - /*so now do some reverse engeneering and see if we can split rotation from scale ->Polardecompose*/ + /*so now do some reverse engineering and see if we can split rotation from scale ->Polardecompose*/ /* build 'projection' matrix */ float m[3][3], mr[3][3], q[3][3], qi[3][3]; float va[3], vb[3], stunt[3]; diff --git a/source/blender/blenlib/intern/math_vector_inline.c b/source/blender/blenlib/intern/math_vector_inline.c index e89b2ece467..177c099d647 100644 --- a/source/blender/blenlib/intern/math_vector_inline.c +++ b/source/blender/blenlib/intern/math_vector_inline.c @@ -521,7 +521,7 @@ MINLINE void cross_v3_v3v3(float r[3], const float a[3], const float b[3]) } /* Newell's Method */ -/* excuse this fairly spesific function, +/* excuse this fairly specific function, * its used for polygon normals all over the place * could use a better name */ MINLINE void add_newell_cross_v3_v3v3(float n[3], const float v_prev[3], const float v_curr[3]) diff --git a/source/blender/blenlib/intern/path_util.c b/source/blender/blenlib/intern/path_util.c index c85efc1fd9a..22b160ad0b4 100644 --- a/source/blender/blenlib/intern/path_util.c +++ b/source/blender/blenlib/intern/path_util.c @@ -1552,7 +1552,7 @@ char *BLI_path_basename(char *path) * 0 if image filename is empty or if destination path * matches image path (i.e. both are the same file). * 2 if source is identical to destination. - * 1 if rebase was successfull + * 1 if rebase was successful * ------------------------------------------------------------- * Hint: Trailing slash in dest_dir is optional. * diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index bfa73c5f7dd..35b1b84bba6 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -255,7 +255,7 @@ static void convert_tface_mt(FileData *fd, Main *main); * in the case of libraray linking errors this is important! * * bit kludge but better then doubling up on prints, - * we could alternatively have a versions of a report function which foces printing - campbell + * we could alternatively have a versions of a report function which forces printing - campbell */ static void BKE_reportf_wrap(ReportList *reports, ReportType type, const char *format, ...) { @@ -5919,7 +5919,7 @@ static void direct_link_screen(FileData *fd, bScreen *sc) } else if (sl->spacetype == SPACE_SEQ) { /* grease pencil data is not a direct data and can't be linked from direct_link* - * functions, it should be linked from lib_link* funcrions instead + * functions, it should be linked from lib_link* functions instead * * otherwise it'll lead to lost grease data on open because it'll likely be * read from file after all other users of grease pencil and newdataadr would @@ -5948,7 +5948,7 @@ static void direct_link_screen(FileData *fd, bScreen *sc) //for (cl= sconsole->scrollback.first; cl; cl= cl->next) // cl->line= newdataadr(fd, cl->line); - /* comma expressions, (e.g. expr1, expr2, expr3) evalutate each expression, + /* comma expressions, (e.g. expr1, expr2, expr3) evaluate each expression, * from left to right. the right-most expression sets the result of the comma * expression as a whole*/ for (cl = sconsole->history.first; cl; cl = cl_next) { @@ -8174,7 +8174,7 @@ static void expand_doit(FileData *fd, Main *mainvar, void *old) * This line is NEEDED, the case is that you have 3 blend files... * user.blend, lib.blend and lib_indirect.blend - if user.blend already references a "tree" from * lib_indirect.blend but lib.blend does too, linking in a Scene or Group from lib.blend can result in an - * empty without the dupli group referenced. Once you save and reload the group would appier. - Campbell */ + * empty without the dupli group referenced. Once you save and reload the group would appear. - Campbell */ /* This crashes files, must look further into it */ /* Update: the issue is that in file reading, the oldnewmap is OK, but for existing data, it has to be diff --git a/source/blender/bmesh/intern/bmesh_core.c b/source/blender/bmesh/intern/bmesh_core.c index a51d6bd2940..8c5adb3cceb 100644 --- a/source/blender/bmesh/intern/bmesh_core.c +++ b/source/blender/bmesh/intern/bmesh_core.c @@ -92,7 +92,7 @@ BMVert *BM_vert_create(BMesh *bm, const float co[3], const BMVert *example) * \brief Main function for creating a new edge. * * \note Duplicate edges are supported by the API however users should _never_ see them. - * so unless you need a unique edge or know the edge won't exist, you should call wih \a nodouble = TRUE + * so unless you need a unique edge or know the edge won't exist, you should call with \a nodouble = TRUE */ BMEdge *BM_edge_create(BMesh *bm, BMVert *v1, BMVert *v2, const BMEdge *example, int nodouble) { diff --git a/source/blender/bmesh/intern/bmesh_marking.c b/source/blender/bmesh/intern/bmesh_marking.c index 59817043eed..4588fbae383 100644 --- a/source/blender/bmesh/intern/bmesh_marking.c +++ b/source/blender/bmesh/intern/bmesh_marking.c @@ -880,7 +880,7 @@ void BM_mesh_elem_hflag_enable_test(BMesh *bm, const char htype, const char hfla /* note, better not attempt a fast path for selection as done with de-select * because hidden geometry and different selection modes can give different results, - * we could of course check for no hiddent faces and then use quicker method but its not worth it. */ + * we could of course check for no hidden faces and then use quicker method but its not worth it. */ for (i = 0; i < 3; i++) { if (htype & flag_types[i]) { diff --git a/source/blender/bmesh/intern/bmesh_operator_api.h b/source/blender/bmesh/intern/bmesh_operator_api.h index 74087c00940..c4ebd4a6204 100644 --- a/source/blender/bmesh/intern/bmesh_operator_api.h +++ b/source/blender/bmesh/intern/bmesh_operator_api.h @@ -235,7 +235,7 @@ int BMO_op_callf(BMesh *bm, const char *fmt, ...); /* initializes, but doesn't execute an operator. this is so you can * gain access to the outputs of the operator. note that you have - * to execute/finitsh (BMO_op_exec and BMO_op_finish) yourself. */ + * to execute/finish (BMO_op_exec and BMO_op_finish) yourself. */ int BMO_op_initf(BMesh *bm, BMOperator *op, const char *fmt, ...); /* va_list version, used to implement the above two functions, diff --git a/source/blender/bmesh/intern/bmesh_polygon.c b/source/blender/bmesh/intern/bmesh_polygon.c index 6b9abfb3e20..03b72aefee6 100644 --- a/source/blender/bmesh/intern/bmesh_polygon.c +++ b/source/blender/bmesh/intern/bmesh_polygon.c @@ -712,7 +712,7 @@ static BMLoop *find_ear(BMFace *f, float (*verts)[3], const int use_beauty, floa } } /* Last check we do not get overlapping triangles - * (as much as possible, ther are some cases with no good solution!) */ + * (as much as possible, there are some cases with no good solution!) */ i4 = (i + 3) % 4; if (!bm_face_goodline((float const (*)[3])verts, f, BM_elem_index_get(larr[i4]->v), BM_elem_index_get(larr[i]->v), BM_elem_index_get(larr[i + 1]->v))) diff --git a/source/blender/bmesh/intern/bmesh_queries.c b/source/blender/bmesh/intern/bmesh_queries.c index f22c25766df..10ea21291db 100644 --- a/source/blender/bmesh/intern/bmesh_queries.c +++ b/source/blender/bmesh/intern/bmesh_queries.c @@ -712,7 +712,7 @@ BMVert *BM_edge_share_vert(BMEdge *e1, BMEdge *e2) * * Finds the loop used which uses \a v in face loop \a l * - * \note currenly this just uses simple loop in future may be speeded up + * \note currently this just uses simple loop in future may be sped up * using radial vars */ BMLoop *BM_face_vert_share_loop(BMFace *f, BMVert *v) @@ -735,7 +735,7 @@ BMLoop *BM_face_vert_share_loop(BMFace *f, BMVert *v) * * Finds the loop used which uses \a e in face loop \a l * - * \note currenly this just uses simple loop in future may be speeded up + * \note currently this just uses simple loop in future may be sped up * using radial vars */ BMLoop *BM_face_edge_share_loop(BMFace *f, BMEdge *e) @@ -794,7 +794,7 @@ float BM_loop_calc_face_angle(BMLoop *l) /** * \brief BM_loop_calc_face_normal * - * Calculate the normal at this loop corner or fallback to the face normal on straignt lines. + * Calculate the normal at this loop corner or fallback to the face normal on straight lines. * * \param bm The BMesh * \param l The loop to calculate the normal at @@ -817,7 +817,7 @@ void BM_loop_calc_face_normal(BMLoop *l, float r_normal[3]) /** * \brief BM_loop_calc_face_tangent * - * Calculate the tangent at this loop corner or fallback to the face normal on straignt lines. + * Calculate the tangent at this loop corner or fallback to the face normal on straight lines. * This vector always points inward into the face. * * \param bm The BMesh @@ -873,7 +873,7 @@ float BM_edge_calc_face_angle(BMEdge *e) /** * \brief BMESH EDGE/FACE TANGENT * - * Calculate the tangent at this loop corner or fallback to the face normal on straignt lines. + * Calculate the tangent at this loop corner or fallback to the face normal on straight lines. * This vector always points inward into the face. * * \brief BM_edge_calc_face_tangent diff --git a/source/blender/bmesh/intern/bmesh_structure.h b/source/blender/bmesh/intern/bmesh_structure.h index 8b43f72c725..b19df4660b8 100644 --- a/source/blender/bmesh/intern/bmesh_structure.h +++ b/source/blender/bmesh/intern/bmesh_structure.h @@ -34,7 +34,7 @@ * The lowest level of functionality for manipulating bmesh structures. * None of these functions should ever be exported to the rest of Blender. * - * in the vast majority of cases thes should not be used directly. + * in the vast majority of cases there shouldn't be used directly. * if absolutely necessary, see function definitions in code for * descriptive comments. but seriously, don't use this stuff. */ diff --git a/source/blender/bmesh/operators/bmo_bevel.c b/source/blender/bmesh/operators/bmo_bevel.c index 0b036c6ff2b..ef4a2a215d6 100644 --- a/source/blender/bmesh/operators/bmo_bevel.c +++ b/source/blender/bmesh/operators/bmo_bevel.c @@ -106,7 +106,7 @@ static void calc_corner_co(BMLoop *l, const float fac, float r_co[3], normalize_v3(l_vec_next); add_v3_v3v3(co_ofs, l_vec_prev, l_vec_next); - if (UNLIKELY(normalize_v3(co_ofs) == 0.0f)) { /* edges form a straignt line */ + if (UNLIKELY(normalize_v3(co_ofs) == 0.0f)) { /* edges form a straight line */ cross_v3_v3v3(co_ofs, l_vec_prev, l->f->no); } diff --git a/source/blender/bmesh/operators/bmo_dissolve.c b/source/blender/bmesh/operators/bmo_dissolve.c index 8e69696f771..f932b8c0766 100644 --- a/source/blender/bmesh/operators/bmo_dissolve.c +++ b/source/blender/bmesh/operators/bmo_dissolve.c @@ -214,7 +214,7 @@ void bmo_dissolve_edgeloop_exec(BMesh *bm, BMOperator *op) BMO_elem_flag_enable(bm, e->v2, VERT_MARK); /* BMESH_TODO - check on delaying edge removal since we may end up removing more then - * one edge, and later referene a removed edge */ + * one edge, and later reference a removed edge */ BM_faces_join_pair(bm, fa, fb, e, TRUE); } } @@ -270,7 +270,7 @@ void bmo_dissolve_edges_exec(BMesh *bm, BMOperator *op) /* join faces */ /* BMESH_TODO - check on delaying edge removal since we may end up removing more then - * one edge, and later referene a removed edge */ + * one edge, and later reference a removed edge */ BM_faces_join_pair(bm, fa, fb, e, TRUE); } } diff --git a/source/blender/bmesh/operators/bmo_hull.c b/source/blender/bmesh/operators/bmo_hull.c index b22bdf60210..87ba216d5cf 100644 --- a/source/blender/bmesh/operators/bmo_hull.c +++ b/source/blender/bmesh/operators/bmo_hull.c @@ -61,7 +61,7 @@ typedef enum { HULL_FLAG_HOLE = (1 << 5) } HullFlags; -/* Store hull triangles seperate from BMesh faces until the end; this +/* Store hull triangles separate from BMesh faces until the end; this * way we don't have to worry about cleaning up extraneous edges or * incorrectly deleting existing geometry. */ typedef struct HullTriangle { diff --git a/source/blender/bmesh/operators/bmo_inset.c b/source/blender/bmesh/operators/bmo_inset.c index 26197c43bd0..3aa6e6dbe49 100644 --- a/source/blender/bmesh/operators/bmo_inset.c +++ b/source/blender/bmesh/operators/bmo_inset.c @@ -280,7 +280,7 @@ void bmo_inset_exec(BMesh *bm, BMOperator *op) BMFace *f_b = e_info_b->l->f; /* we use this as either the normal OR to find the right direction for the - * crpss product between both face normals */ + * cross product between both face normals */ add_v3_v3v3(tvec, e_info_a->no, e_info_b->no); if ((f_a == f_b) || compare_v3v3(f_a->no, f_b->no, 0.00001f)) { diff --git a/source/blender/bmesh/operators/bmo_utils.c b/source/blender/bmesh/operators/bmo_utils.c index 7d6e34b3a05..ccab6c26a5e 100644 --- a/source/blender/bmesh/operators/bmo_utils.c +++ b/source/blender/bmesh/operators/bmo_utils.c @@ -530,7 +530,7 @@ void bmo_similar_faces_exec(BMesh *bm, BMOperator *op) /* * The first thing to do is to iterate through all the the selected items and mark them since * they will be in the selection anyway. - * This will increase performance, (especially when the number of originaly selected faces is high) + * This will increase performance, (especially when the number of originally selected faces is high) * so the overall complexity will be less than $O(mn)$ where is the total number of selected faces, * and n is the total number of faces */ diff --git a/source/blender/bmesh/tools/BME_bevel.c b/source/blender/bmesh/tools/BME_bevel.c index 07e413985bf..eb498ebf9ab 100644 --- a/source/blender/bmesh/tools/BME_bevel.c +++ b/source/blender/bmesh/tools/BME_bevel.c @@ -1129,7 +1129,7 @@ BMesh *BME_bevel(BMEditMesh *em, float value, int res, int options, int defgrp_i } /* possibly needed when running as a tool (which is no longer functional) - * but keep as an optioin for now */ + * but keep as an option for now */ if (do_tessface) { BMEdit_RecalcTessellation(em); } diff --git a/source/blender/compositor/COM_compositor.h b/source/blender/compositor/COM_compositor.h index c65ea771477..cd1615c9094 100644 --- a/source/blender/compositor/COM_compositor.h +++ b/source/blender/compositor/COM_compositor.h @@ -37,9 +37,9 @@ extern "C" { * @mainpage Introduction of the Blender Compositor * * @section bcomp Blender compositor - * This project redesigns the interals of Blender's compositor. The project has been executed in 2011 by At Mind. + * This project redesigns the internals of Blender's compositor. The project has been executed in 2011 by At Mind. * At Mind is a technology company located in Amsterdam, The Netherlands. - * The project has been crowdfunded. This code has been released under GPL2 to be used in Blender. + * The project has been crowd-funded. This code has been released under GPL2 to be used in Blender. * * @section goals The goals of the project * the new compositor has 2 goals. @@ -58,7 +58,7 @@ extern "C" { * @section workflow Work faster * The previous compositor only showed the final image. The compositor could wait a long time before seeing the result * of his work. The new compositor will work in a way that it will focus on getting information back to the user. - * It will prioritise its work to get earlier user feedback. + * It will prioritize its work to get earlier user feedback. * * @page memory Memory model * The main issue is the type of memory model to use. Blender is used by consumers and professionals. @@ -79,7 +79,7 @@ extern "C" { * Render priority is an priority of an output node. A user has a different need of Render priorities of output nodes * than during editing. * for example. the Active ViewerNode has top priority during editing, but during rendering a CompositeNode has. - * All NodeOperation has a setting for their renderpriority, but only for output NodeOperation these have effect. + * All NodeOperation has a setting for their render-priority, but only for output NodeOperation these have effect. * In ExecutionSystem.execute all priorities are checked. For every priority the ExecutionGroup's are check if the * priority do match. * When match the ExecutionGroup will be executed (this happens in serial) @@ -91,18 +91,18 @@ extern "C" { * @section order Chunk order * * When a ExecutionGroup is executed, first the order of chunks are determined. - * The settings are stored in the ViewerNode inside the ExecutionGroup. ExecutionGroups that have no viewernode, + * The settings are stored in the ViewerNode inside the ExecutionGroup. ExecutionGroups that have no viewer-node, * will use a default one. * There are several possible chunk orders * - [@ref OrderOfChunks.COM_TO_CENTER_OUT]: Start calculating from a configurable point and order by nearest chunk * - [@ref OrderOfChunks.COM_TO_RANDOM]: Randomize all chunks. * - [@ref OrderOfChunks.COM_TO_TOP_DOWN]: Start calculation from the bottom to the top of the image - * - [@ref OrderOfChunks.COM_TO_RULE_OF_THIRDS]: Experimental order based on 9 hotspots in the image + * - [@ref OrderOfChunks.COM_TO_RULE_OF_THIRDS]: Experimental order based on 9 hot-spots in the image * - * When the chunkorder is determined, the first few chunks will be checked if they can be scheduled. + * When the chunk-order is determined, the first few chunks will be checked if they can be scheduled. * Chunks can have three states: - * - [@ref ChunkExecutionState.COM_ES_NOT_SCHEDULED]: Chunk is not yet scheduled, or dependacies are not met - * - [@ref ChunkExecutionState.COM_ES_SCHEDULED]: All dependacies are met, chunk is scheduled, but not finished + * - [@ref ChunkExecutionState.COM_ES_NOT_SCHEDULED]: Chunk is not yet scheduled, or dependencies are not met + * - [@ref ChunkExecutionState.COM_ES_SCHEDULED]: All dependencies are met, chunk is scheduled, but not finished * - [@ref ChunkExecutionState.COM_ES_EXECUTED]: Chunk is finished * * @see ExecutionGroup.execute @@ -110,7 +110,7 @@ extern "C" { * @see OrderOfChunks * * @section interest Area of interest - * An ExecutionGroup can have dependancies to other ExecutionGroup's. Data passing from one ExecutionGroup to another + * An ExecutionGroup can have dependencies to other ExecutionGroup's. Data passing from one ExecutionGroup to another * one are stored in 'chunks'. * If not all input chunks are available the chunk execution will not be scheduled. *
@@ -217,22 +217,22 @@ extern "C" {
  * @section workscheduler WorkScheduler
  * the WorkScheduler is implemented as a static class. the responsibility of the WorkScheduler is to balance
  * WorkPackages to the available and free devices.
- * the workscheduler can work in 2 states. For witching these between the state you need to recompile blender
+ * the work-scheduler can work in 2 states. For witching these between the state you need to recompile blender
  *
  * @subsection multithread Multi threaded
- * Default the workscheduler will place all work as WorkPackage in a queue.
+ * Default the work-scheduler will place all work as WorkPackage in a queue.
  * For every CPUcore a working thread is created. These working threads will ask the WorkScheduler if there is work
  * for a specific Device.
- * the workscheduler will find work for the device and the device will be asked to execute the WorkPackage
+ * the work-scheduler will find work for the device and the device will be asked to execute the WorkPackage
  *
  * @subsection singlethread Single threaded
  * For debugging reasons the multi-threading can be disabled. This is done by changing the COM_CURRENT_THREADING_MODEL
- * to COM_TM_NOTHREAD. When compiling the workscheduler
+ * to COM_TM_NOTHREAD. When compiling the work-scheduler
  * will be changes to support no threading and run everything on the CPU.
  *
  * @section devices Devices
  * A Device within the compositor context is a Hardware component that can used to calculate chunks.
- * This chunk is encapseled in a WorkPackage.
+ * This chunk is encapsulated in a WorkPackage.
  * the WorkScheduler controls the devices and selects the device where a WorkPackage will be calculated.
  *
  * @subsection WS_Devices Workscheduler
diff --git a/source/blender/compositor/intern/COM_ExecutionGroup.h b/source/blender/compositor/intern/COM_ExecutionGroup.h
index 43c2bfac52e..e890715cafe 100644
--- a/source/blender/compositor/intern/COM_ExecutionGroup.h
+++ b/source/blender/compositor/intern/COM_ExecutionGroup.h
@@ -180,7 +180,7 @@ private:
 	
 	/**
 	 * @brief Determine the rect (minx, maxx, miny, maxy) of a chunk at a position.
-	 * @note Only gives usefull results ater the determination of the chunksize
+	 * @note Only gives useful results ater the determination of the chunksize
 	 * @see determineChunkSize()
 	 */
 	void determineChunkRect(rcti *rect, const unsigned int xChunk, const unsigned int yChunk) const;
@@ -376,7 +376,7 @@ public:
 	
 	/**
 	 * @brief Determine the rect (minx, maxx, miny, maxy) of a chunk.
-	 * @note Only gives usefull results ater the determination of the chunksize
+	 * @note Only gives useful results ater the determination of the chunksize
 	 * @see determineChunkSize()
 	 */
 	void determineChunkRect(rcti *rect, const unsigned int chunkNumber) const;
diff --git a/source/blender/compositor/intern/COM_ExecutionSystem.h b/source/blender/compositor/intern/COM_ExecutionSystem.h
index 209358ec786..4f6780c8d0b 100644
--- a/source/blender/compositor/intern/COM_ExecutionSystem.h
+++ b/source/blender/compositor/intern/COM_ExecutionSystem.h
@@ -37,7 +37,7 @@ using namespace std;
 
 /**
  * @page execution Execution model
- * In order to get to an efficient model for execution, serveral steps are being done. these steps are explained below.
+ * In order to get to an efficient model for execution, several steps are being done. these steps are explained below.
  *
  * @section EM_Step1 Step 1: translating blender node system to the new compsitor system
  * Blenders node structure is based on C structs (DNA). These structs are not efficient in the new architecture. We want to use classes in order to simplify the system.
@@ -64,7 +64,7 @@ using namespace std;
  * @section EM_Step3 Step3: add additional conversions to the operation system
  *   - Data type conversions: the system has 3 data types COM_DT_VALUE, COM_DT_VECTOR, COM_DT_COLOR. The user can connect a Value socket to a color socket. As values are ordered differently than colors a conversion happens.
  *
- *   - Image size conversions: the system can automatically convert when resolutions do not match. An InputSocket has a resize mode. This can be any of the folowing settings.
+ *   - Image size conversions: the system can automatically convert when resolutions do not match. An InputSocket has a resize mode. This can be any of the following settings.
  *     - [@ref InputSocketResizeMode.COM_SC_CENTER]: The center of both images are aligned
  *     - [@ref InputSocketResizeMode.COM_SC_FIT_WIDTH]: The width of both images are aligned
  *     - [@ref InputSocketResizeMode.COM_SC_FIT_HEIGHT]: the height of both images are aligned
diff --git a/source/blender/compositor/intern/COM_MemoryBuffer.h b/source/blender/compositor/intern/COM_MemoryBuffer.h
index eed0c796cd8..5077a9e3228 100644
--- a/source/blender/compositor/intern/COM_MemoryBuffer.h
+++ b/source/blender/compositor/intern/COM_MemoryBuffer.h
@@ -67,7 +67,7 @@ private:
 	
 	
 	/**
-	 * @brief region of this buffer inside reative to the MemoryProxy
+	 * @brief region of this buffer inside relative to the MemoryProxy
 	 */
 	rcti m_rect;
 	
@@ -218,7 +218,7 @@ public:
 	int getHeight() const;
 	
 	/**
-	 * @brief clear the buffer. Make all pixels black transparant.
+	 * @brief clear the buffer. Make all pixels black transparent.
 	 */
 	void clear();
 	
diff --git a/source/blender/compositor/intern/COM_MemoryProxy.h b/source/blender/compositor/intern/COM_MemoryProxy.h
index 130c5f5057a..696c843e7c4 100644
--- a/source/blender/compositor/intern/COM_MemoryProxy.h
+++ b/source/blender/compositor/intern/COM_MemoryProxy.h
@@ -89,7 +89,7 @@ public:
 	WriteBufferOperation *getWriteBufferOperation() { return this->m_writeBufferOperation; }
 
 	/**
-	 * @brief allocate memory of size widht x height
+	 * @brief allocate memory of size width x height
 	 */
 	void allocate(unsigned int width, unsigned int height);
 
diff --git a/source/blender/compositor/intern/COM_Node.h b/source/blender/compositor/intern/COM_Node.h
index bc4a25db605..e19b1d774c9 100644
--- a/source/blender/compositor/intern/COM_Node.h
+++ b/source/blender/compositor/intern/COM_Node.h
@@ -74,7 +74,7 @@ public:
 	/**
 	 * @brief convert node to operation
 	 *
-	 * @todo this must be described furter
+	 * @todo this must be described further
 	 *
 	 * @param system the ExecutionSystem where the operations need to be added
 	 * @param context reference to the CompositorContext
diff --git a/source/blender/compositor/intern/COM_NodeOperation.h b/source/blender/compositor/intern/COM_NodeOperation.h
index 0de2f6aef5d..9b6d574e321 100644
--- a/source/blender/compositor/intern/COM_NodeOperation.h
+++ b/source/blender/compositor/intern/COM_NodeOperation.h
@@ -101,7 +101,7 @@ public:
 	/**
 	 * @brief isOutputOperation determines whether this operation is an output of the ExecutionSystem during rendering or editing.
 	 *
-	 * Default behaviour if not overriden, this operation will not be evaluated as being an output of the ExecutionSystem.
+	 * Default behaviour if not overridden, this operation will not be evaluated as being an output of the ExecutionSystem.
 	 *
 	 * @see ExecutionSystem
 	 * @group check
diff --git a/source/blender/compositor/operations/COM_DoubleEdgeMaskOperation.cpp b/source/blender/compositor/operations/COM_DoubleEdgeMaskOperation.cpp
index bcad974da70..f647629815b 100644
--- a/source/blender/compositor/operations/COM_DoubleEdgeMaskOperation.cpp
+++ b/source/blender/compositor/operations/COM_DoubleEdgeMaskOperation.cpp
@@ -894,7 +894,7 @@ static void do_createEdgeLocationBuffer(unsigned int t, unsigned int rw, unsigne
 	int x;                             // x = pixel loop counter
 	int a;                             // a = temporary pixel index buffer loop counter
 	unsigned int ud;                   // ud = unscaled edge distance
-	unsigned int dmin;                 // dmin = minimun edge distance
+	unsigned int dmin;                 // dmin = minimum edge distance
 	
 	unsigned int rsl;                  // long used for finding fast 1.0/sqrt
 	unsigned int gradientFillOffset;
@@ -1012,7 +1012,7 @@ static void do_fillGradientBuffer(unsigned int rw, float *res, unsigned short *g
 	unsigned int gradientFillOffset;
 	unsigned int t;
 	unsigned int ud;                   // ud = unscaled edge distance
-	unsigned int dmin;                 // dmin = minimun edge distance
+	unsigned int dmin;                 // dmin = minimum edge distance
 	float odist;                       // odist = current outer edge distance
 	float idist;                       // idist = current inner edge distance
 	int dx;                            // dx = X-delta (used for distance proportion calculation)
@@ -1070,7 +1070,7 @@ static void do_fillGradientBuffer(unsigned int rw, float *res, unsigned short *g
 	 * pixel color as |GI| / (|GI| + |GO|). Since these are reciprocals, GI serves the
 	 * purpose of GO for the proportion calculation.
 	 *
-	 * For the purposes of the minimun distance comparisons, we only check
+	 * For the purposes of the minimum distance comparisons, we only check
 	 * the sums-of-squares against eachother, since they are in the same
 	 * mathematical sort-order as if we did go ahead and take square roots
 	 *
@@ -1116,7 +1116,7 @@ static void do_fillGradientBuffer(unsigned int rw, float *res, unsigned short *g
 		/*
 		 * Note once again that since we are using reciprocals of distance values our
 		 * proportion is already the correct intensity, and does not need to be
-		 * subracted from 1.0 like it would have if we used real distances.
+		 * subtracted from 1.0 like it would have if we used real distances.
 		 */
 		
 		/*
diff --git a/source/blender/compositor/operations/COM_KeyingBlurOperation.h b/source/blender/compositor/operations/COM_KeyingBlurOperation.h
index 84406c33c28..aaacf66a656 100644
--- a/source/blender/compositor/operations/COM_KeyingBlurOperation.h
+++ b/source/blender/compositor/operations/COM_KeyingBlurOperation.h
@@ -27,7 +27,7 @@
 #include "COM_NodeOperation.h"
 
 /**
- * Class with implementation of bluring for keying node
+ * Class with implementation of blurring for keying node
  */
 class KeyingBlurOperation : public NodeOperation {
 protected:
diff --git a/source/blender/editors/animation/anim_channels_defines.c b/source/blender/editors/animation/anim_channels_defines.c
index a21154bde1b..fe5558c6f53 100644
--- a/source/blender/editors/animation/anim_channels_defines.c
+++ b/source/blender/editors/animation/anim_channels_defines.c
@@ -851,7 +851,7 @@ static int acf_group_setting_flag(bAnimContext *ac, int setting, short *neg)
 			// *neg = 1; - if we change this to edtiability
 			return AGRP_PROTECTED;
 			
-		case ACHANNEL_SETTING_VISIBLE: /* visiblity - graph editor */
+		case ACHANNEL_SETTING_VISIBLE: /* visibility - graph editor */
 			*neg = 1;
 			return AGRP_NOTVISIBLE;
 	}
@@ -939,7 +939,7 @@ static int acf_fcurve_setting_flag(bAnimContext *UNUSED(ac), int setting, short
 			// *neg = 1; - if we change this to edtiability
 			return FCURVE_PROTECTED;
 			
-		case ACHANNEL_SETTING_VISIBLE: /* visiblity - graph editor */
+		case ACHANNEL_SETTING_VISIBLE: /* visibility - graph editor */
 			return FCURVE_VISIBLE;
 			
 		default: /* unsupported */
diff --git a/source/blender/editors/interface/view2d.c b/source/blender/editors/interface/view2d.c
index 47e91f4c659..a693e9eb627 100644
--- a/source/blender/editors/interface/view2d.c
+++ b/source/blender/editors/interface/view2d.c
@@ -1818,7 +1818,7 @@ void UI_view2d_scrollers_free(View2DScrollers *scrollers)
  *							  This should be (0,0) for most views. However, for those where the starting row was offsetted
  *							  (like for Animation Editor channel lists, to make the first entry more visible), these will be 
  *							  the min-coordinates of the first item.
- *	- column, row				= the 2d-corodinates (in 2D-view / 'tot' rect space) the cell exists at
+ *	- column, row				= the 2d-coordinates (in 2D-view / 'tot' rect space) the cell exists at
  *	- rect					= coordinates of the cell (passed as single var instead of 4 separate, as it's more useful this way)
  */
 void UI_view2d_listview_cell_to_view(View2D *v2d, short columnwidth, short rowheight, float startx, float starty, int column, int row, rctf *rect)
diff --git a/source/blender/editors/object/object_group.c b/source/blender/editors/object/object_group.c
index c9851c6a0db..7328cdbf9f2 100644
--- a/source/blender/editors/object/object_group.c
+++ b/source/blender/editors/object/object_group.c
@@ -202,7 +202,7 @@ static int group_objects_remove_exec(bContext *C, wmOperator *op)
 	Scene *scene = CTX_data_scene(C);
 	int group_object_index = RNA_enum_get(op->ptr, "group");
 
-	/* first get the group back from the enum index, quite awkward and UI spesific */
+	/* first get the group back from the enum index, quite awkward and UI specific */
 	if (ob) {
 		Group *group = NULL;
 		int i = 0;
diff --git a/source/blender/editors/physics/physics_fluid.c b/source/blender/editors/physics/physics_fluid.c
index 1fe533eb23f..dc2f70189e7 100644
--- a/source/blender/editors/physics/physics_fluid.c
+++ b/source/blender/editors/physics/physics_fluid.c
@@ -913,7 +913,7 @@ static int fluidsimBake(bContext *C, ReportList *reports, Object *fsDomain, shor
 		return 0;
 	}
 	
-	/* these both have to be valid, otherwise we wouldnt be here */
+	/* these both have to be valid, otherwise we wouldn't be here */
 	fluidmd = (FluidsimModifierData *)modifiers_findByType(fsDomain, eModifierType_Fluidsim);
 	domainSettings = fluidmd->fss;
 	mesh = fsDomain->data;
diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c
index c97e91f74b6..2391d6c909e 100644
--- a/source/blender/editors/screen/screen_ops.c
+++ b/source/blender/editors/screen/screen_ops.c
@@ -3017,7 +3017,7 @@ static int screen_animation_step(bContext *C, wmOperator *UNUSED(op), wmEvent *e
 			}
 		}
 
-		/* next frame overriden by user action (pressed jump to first/last frame) */
+		/* next frame overridden by user action (pressed jump to first/last frame) */
 		if (sad->flag & ANIMPLAY_FLAG_USE_NEXT_FRAME) {
 			scene->r.cfra = sad->nextfra;
 			sad->flag &= ~ANIMPLAY_FLAG_USE_NEXT_FRAME;
diff --git a/source/blender/editors/sculpt_paint/paint_ops.c b/source/blender/editors/sculpt_paint/paint_ops.c
index 7df6a893b5c..560174e73ae 100644
--- a/source/blender/editors/sculpt_paint/paint_ops.c
+++ b/source/blender/editors/sculpt_paint/paint_ops.c
@@ -604,7 +604,7 @@ void paint_partial_visibility_keys(wmKeyMap *keymap)
 {
 	wmKeyMapItem *kmi;
 	
-	/* Partial visiblity */
+	/* Partial visibility */
 	kmi = WM_keymap_add_item(keymap, "PAINT_OT_hide_show", HKEY, KM_PRESS, KM_SHIFT, 0);
 	RNA_enum_set(kmi->ptr, "action", PARTIALVIS_SHOW);
 	RNA_enum_set(kmi->ptr, "area", PARTIALVIS_INSIDE);
diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c
index c1b2e2f07e2..8d5dbb51be7 100644
--- a/source/blender/editors/space_view3d/drawobject.c
+++ b/source/blender/editors/space_view3d/drawobject.c
@@ -2843,7 +2843,7 @@ static void draw_em_fancy_edges(BMEditMesh *em, Scene *scene, View3D *v3d,
 	int pass;
 	unsigned char wireCol[4], selCol[4], actCol[4];
 
-	/* since this function does transparant... */
+	/* since this function does transparent... */
 	UI_GetThemeColor4ubv(TH_EDGE_SELECT, selCol);
 	UI_GetThemeColor4ubv(TH_WIRE, wireCol);
 	UI_GetThemeColor4ubv(TH_EDITMESH_ACTIVE, actCol);
@@ -2854,7 +2854,7 @@ static void draw_em_fancy_edges(BMEditMesh *em, Scene *scene, View3D *v3d,
 		wireCol[3] = 0;
 
 	for (pass = 0; pass < 2; pass++) {
-		/* show wires in transparant when no zbuf clipping for select */
+		/* show wires in transparent when no zbuf clipping for select */
 		if (pass == 0) {
 			if (v3d->zbuf && (v3d->flag & V3D_ZBUF_SELECT) == 0) {
 				glEnable(GL_BLEND);
diff --git a/source/blender/gpu/intern/gpu_buffers.c b/source/blender/gpu/intern/gpu_buffers.c
index 75ed7d7eb19..c44a181841e 100644
--- a/source/blender/gpu/intern/gpu_buffers.c
+++ b/source/blender/gpu/intern/gpu_buffers.c
@@ -1595,7 +1595,7 @@ static int gpu_count_grid_quads(BLI_bitmap *grid_hidden,
 	int i, x, y, totquad;
 
 	/* grid hidden layer is present, so have to check each grid for
-	 * visiblity */
+	 * visibility */
 
 	for (i = 0, totquad = 0; i < totgrid; i++) {
 		const BLI_bitmap gh = grid_hidden[grid_indices[i]];
diff --git a/source/blender/imbuf/IMB_moviecache.h b/source/blender/imbuf/IMB_moviecache.h
index d1d34a01433..5e52563a89e 100644
--- a/source/blender/imbuf/IMB_moviecache.h
+++ b/source/blender/imbuf/IMB_moviecache.h
@@ -35,7 +35,7 @@
 #include "BLI_utildefines.h"
 #include "BLI_ghash.h"
 
-/* Cache system for movie data - now supports stoting ImBufs only
+/* Cache system for movie data - now supports storing ImBufs only
  * Supposed to provide unified cache system for movie clips, sequencer and
  * other movie-related areas */
 
diff --git a/source/blender/imbuf/intern/imageprocess.c b/source/blender/imbuf/intern/imageprocess.c
index 5114fcb3ae0..5c389925274 100644
--- a/source/blender/imbuf/intern/imageprocess.c
+++ b/source/blender/imbuf/intern/imageprocess.c
@@ -36,12 +36,6 @@
  *
  */
 
-/*  imageprocess.c        MIXED MODEL
- * 
- *  april 95
- * 
- */
-
 #include 
 
 #include "BLI_utildefines.h"
diff --git a/source/blender/imbuf/intern/jp2.c b/source/blender/imbuf/intern/jp2.c
index 6477d40d695..9fb4cbae383 100644
--- a/source/blender/imbuf/intern/jp2.c
+++ b/source/blender/imbuf/intern/jp2.c
@@ -864,7 +864,7 @@ int imb_savejp2(struct ImBuf *ibuf, const char *name, int flags)
 	
 	/*
 	 * configure the event callbacks (not required)
-	 * setting of each callback is optionnal
+	 * setting of each callback is optional
 	 */
 	memset(&event_mgr, 0, sizeof(opj_event_mgr_t));
 	event_mgr.error_handler = error_callback;
diff --git a/source/blender/imbuf/intern/jpeg.c b/source/blender/imbuf/intern/jpeg.c
index 03c949bc3d1..aea120cd841 100644
--- a/source/blender/imbuf/intern/jpeg.c
+++ b/source/blender/imbuf/intern/jpeg.c
@@ -67,8 +67,8 @@ static ImBuf *ibJpegImageFromCinfo(struct jpeg_decompress_struct *cinfo, int fla
 /*
  * In principle there are 4 jpeg formats.
  *
- * 1. jpeg - standard printing, u & v at quarter of resulution
- * 2. jvid - standaard video, u & v half resolution, frame not interlaced
+ * 1. jpeg - standard printing, u & v at quarter of resolution
+ * 2. jvid - standard video, u & v half resolution, frame not interlaced
  *
  * type 3 is unsupported as of jul 05 2000 Frank.
  *
diff --git a/source/blender/imbuf/intern/scaling.c b/source/blender/imbuf/intern/scaling.c
index 27034317396..810cb88c06e 100644
--- a/source/blender/imbuf/intern/scaling.c
+++ b/source/blender/imbuf/intern/scaling.c
@@ -774,7 +774,7 @@ static void q_scale_float(float *in, float *out, int in_width,
  * Should be comparable in speed to the ImBuf ..._fast functions at least
  * for byte-buffers.
  *
- * NOTE: disabled, due to inacceptable inaccuracy and quality loss, see bug #18609 (ton)
+ * NOTE: disabled, due to unacceptable inaccuracy and quality loss, see bug #18609 (ton)
  */
 static int q_scale_linear_interpolation(
         struct ImBuf *ibuf, int newx, int newy)
@@ -1460,7 +1460,7 @@ struct ImBuf *IMB_scaleImBuf(struct ImBuf *ibuf, unsigned int newx, unsigned int
 	scalefast_Z_ImBuf(ibuf, newx, newy);
 
 	/* try to scale common cases in a fast way */
-	/* disabled, quality loss is inacceptable, see report #18609  (ton) */
+	/* disabled, quality loss is unacceptable, see report #18609  (ton) */
 	if (0 && q_scale_linear_interpolation(ibuf, newx, newy)) {
 		return ibuf;
 	}
diff --git a/source/blender/makesdna/DNA_anim_types.h b/source/blender/makesdna/DNA_anim_types.h
index 17ee8723e53..7cf0d588710 100644
--- a/source/blender/makesdna/DNA_anim_types.h
+++ b/source/blender/makesdna/DNA_anim_types.h
@@ -628,7 +628,7 @@ typedef enum eNlaStrip_Flag {
 		/* NLA strip length is synced to the length of the referenced action */
 	NLASTRIP_FLAG_SYNC_LENGTH	= (1<<9),
 	
-	/* playback flags (may be overriden by F-Curves) */
+	/* playback flags (may be overridden by F-Curves) */
 		/* NLA strip blendin/out values are set automatically based on overlaps */
 	NLASTRIP_FLAG_AUTO_BLENDS	= (1<<10),
 		/* NLA strip is played back in reverse order */
diff --git a/source/blender/makesdna/DNA_texture_types.h b/source/blender/makesdna/DNA_texture_types.h
index 606c466ac74..5257fb6e2cf 100644
--- a/source/blender/makesdna/DNA_texture_types.h
+++ b/source/blender/makesdna/DNA_texture_types.h
@@ -204,7 +204,7 @@ typedef struct Tex {
 	/* newnoise: musgrave parameters */
 	float mg_H, mg_lacunarity, mg_octaves, mg_offset, mg_gain;
 
-	/* newnoise: distorted noise amount, musgrave & voronoi ouput scale */
+	/* newnoise: distorted noise amount, musgrave & voronoi output scale */
 	float dist_amount, ns_outscale;
 
 	/* newnoise: voronoi nearest neighbor weights, minkovsky exponent, distance metric & color type */
diff --git a/source/blender/makesdna/intern/dna_genfile.c b/source/blender/makesdna/intern/dna_genfile.c
index 8be743335cc..f5cf7e3ea3b 100644
--- a/source/blender/makesdna/intern/dna_genfile.c
+++ b/source/blender/makesdna/intern/dna_genfile.c
@@ -105,7 +105,7 @@ typedef long long __int64;
  *  - location within a struct (everthing can be randomly mixed up)
  *  - struct within struct (within struct etc), this is recursive
  *  - adding new elements, will be default initialized zero
- *  - remving elements
+ *  - removing elements
  *  - change of array sizes
  *  - change of a pointer type: when the name doesn't change the contents is copied
  *
@@ -122,7 +122,7 @@ typedef long long __int64;
  *  - only use a long in Blender if you want this to be the size of a pointer. so it is
  *    32 bits or 64 bits, dependent at the cpu architecture
  *  - chars are always unsigned
- *  - aligment of variables has to be done in such a way, that any system does
+ *  - alignment of variables has to be done in such a way, that any system does
  *    not create 'padding' (gaps) in structures. So make sure that:
  *    - short: 2 aligned
  *    - int: 4 aligned
@@ -556,7 +556,7 @@ static void recurs_test_compflags(SDNA *sdna, char *compflags, int structnr)
 
 /* Unsure of exact function - compares the sdna argument to
  * newsdna and sets up the information necessary to convert
- * data written with a dna of oldsdna to inmemory data with a
+ * data written with a dna of oldsdna to in-memory data with a
  * structure defined by the newsdna sdna (I think). -zr
  */
 
diff --git a/source/blender/makesrna/RNA_types.h b/source/blender/makesrna/RNA_types.h
index 348efaed8c6..511999dfa37 100644
--- a/source/blender/makesrna/RNA_types.h
+++ b/source/blender/makesrna/RNA_types.h
@@ -203,7 +203,7 @@ typedef enum PropertyFlag {
 	PROP_CONTEXT_UPDATE = (1 << 22),
 	PROP_CONTEXT_PROPERTY_UPDATE = (1 << 22) | (1 << 27),
 
-	/* Use for arrays or for any data that should not have a referene kept
+	/* Use for arrays or for any data that should not have a reference kept
 	 * most common case is functions that return arrays where the array */
 	PROP_THICK_WRAP = (1 << 23),
 
diff --git a/source/blender/makesrna/intern/rna_scene_api.c b/source/blender/makesrna/intern/rna_scene_api.c
index 13b60498900..61be48f3f02 100644
--- a/source/blender/makesrna/intern/rna_scene_api.c
+++ b/source/blender/makesrna/intern/rna_scene_api.c
@@ -60,7 +60,7 @@ void rna_Scene_frame_set(Scene *scene, int frame, float subframe)
 	BKE_scene_update_for_newframe(G.main, scene, (1 << 20) - 1);
 	BKE_scene_camera_switch_update(scene);
 
-	/* cant use NC_SCENE|ND_FRAME because this casues wm_event_do_notifiers to call
+	/* cant use NC_SCENE|ND_FRAME because this causes wm_event_do_notifiers to call
 	 * BKE_scene_update_for_newframe which will loose any un-keyed changes [#24690] */
 	/* WM_main_add_notifier(NC_SCENE|ND_FRAME, scene); */
 	
diff --git a/source/blender/makesrna/intern/rna_sequencer.c b/source/blender/makesrna/intern/rna_sequencer.c
index fb8ba2f863e..5c851550cc6 100644
--- a/source/blender/makesrna/intern/rna_sequencer.c
+++ b/source/blender/makesrna/intern/rna_sequencer.c
@@ -59,7 +59,7 @@ typedef struct EffectInfo {
 
 #ifdef RNA_RUNTIME
 
-/* build a temp referene to the parent */
+/* build a temp reference to the parent */
 static void meta_tmp_ref(Sequence *seq_par, Sequence *seq)
 {
 	for (; seq; seq = seq->next) {
diff --git a/source/blender/modifiers/intern/MOD_array.c b/source/blender/modifiers/intern/MOD_array.c
index a4ba9ba35bb..57c230fcde6 100644
--- a/source/blender/modifiers/intern/MOD_array.c
+++ b/source/blender/modifiers/intern/MOD_array.c
@@ -189,7 +189,7 @@ static int *find_doubles_index_map(BMesh *bm, BMOperator *dupe_op,
 		i++;
 	}
 	/* above loops over all, so set all to dirty, if this is somehow
-	 * setting valid values, this line can be remvoed - campbell */
+	 * setting valid values, this line can be removed - campbell */
 	bm->elem_index_dirty |= BM_VERT | BM_EDGE | BM_FACE;
 
 	(*index_map_length) = i;
diff --git a/source/blender/modifiers/intern/MOD_solidify.c b/source/blender/modifiers/intern/MOD_solidify.c
index 6f8e65a6e8e..fc74b446762 100644
--- a/source/blender/modifiers/intern/MOD_solidify.c
+++ b/source/blender/modifiers/intern/MOD_solidify.c
@@ -199,7 +199,7 @@ static CustomDataMask requiredDataMask(Object *UNUSED(ob), ModifierData *md)
 	return dataMask;
 }
 
-/* spesific function for solidify - define locally */
+/* specific function for solidify - define locally */
 BLI_INLINE void madd_v3v3short_fl(float r[3], const short a[3], const float f)
 {
 	r[0] += (float)a[0] * f;
diff --git a/source/blender/modifiers/intern/MOD_weightvgproximity.c b/source/blender/modifiers/intern/MOD_weightvgproximity.c
index 70b9eafdac5..d5deb50e1f9 100644
--- a/source/blender/modifiers/intern/MOD_weightvgproximity.c
+++ b/source/blender/modifiers/intern/MOD_weightvgproximity.c
@@ -183,7 +183,7 @@ static float get_ob2ob_distance(const Object *ob, const Object *obr)
 }
 
 /**
- * Maps distances to weights, with an optionnal "smoothing" mapping.
+ * Maps distances to weights, with an optional "smoothing" mapping.
  */
 void do_map(float *weights, const int nidx, const float min_d, const float max_d, short mode)
 {
diff --git a/source/blender/nodes/composite/nodes/node_composite_doubleEdgeMask.c b/source/blender/nodes/composite/nodes/node_composite_doubleEdgeMask.c
index 6eb70636efa..c206b9a1a5d 100644
--- a/source/blender/nodes/composite/nodes/node_composite_doubleEdgeMask.c
+++ b/source/blender/nodes/composite/nodes/node_composite_doubleEdgeMask.c
@@ -909,7 +909,7 @@ static void do_createEdgeLocationBuffer(unsigned int t, unsigned int rw, unsigne
 	int x;							// x = pixel loop counter
 	int a;							// a = temporary pixel index buffer loop counter
 	unsigned int ud;				// ud = unscaled edge distance
-	unsigned int dmin;				// dmin = minimun edge distance
+	unsigned int dmin;				// dmin = minimum edge distance
 
 	unsigned int rsl;				// long used for finding fast 1.0/sqrt
 	unsigned int gradientFillOffset;
@@ -1027,7 +1027,7 @@ static void do_fillGradientBuffer(unsigned int rw, float *res, unsigned short *g
 	unsigned int gradientFillOffset;
 	unsigned int t;
 	unsigned int ud;				// ud = unscaled edge distance
-	unsigned int dmin;				// dmin = minimun edge distance
+	unsigned int dmin;				// dmin = minimum edge distance
 	float odist;					// odist = current outer edge distance
 	float idist;					// idist = current inner edge distance
 	int dx;							// dx = X-delta (used for distance proportion calculation)
@@ -1084,7 +1084,7 @@ static void do_fillGradientBuffer(unsigned int rw, float *res, unsigned short *g
 	 * pixel color as |GI| / (|GI| + |GO|). Since these are reciprocals, GI serves the
 	 * purpose of GO for the proportion calculation.
 	 *
-	 * For the purposes of the minimun distance comparisons, we only check
+	 * For the purposes of the minimum distance comparisons, we only check
 	 * the sums-of-squares against each other, since they are in the same
 	 * mathematical sort-order as if we did go ahead and take square roots
 	 *
@@ -1130,7 +1130,7 @@ static void do_fillGradientBuffer(unsigned int rw, float *res, unsigned short *g
 		/*
 		 * Note once again that since we are using reciprocals of distance values our
 		 * proportion is already the correct intensity, and does not need to be
-		 * subracted from 1.0 like it would have if we used real distances.
+		 * subtracted from 1.0 like it would have if we used real distances.
 		 */
 
 		/*
diff --git a/source/blender/nodes/shader/node_shader_util.c b/source/blender/nodes/shader/node_shader_util.c
index 9aa3c76e0a5..56704b981be 100644
--- a/source/blender/nodes/shader/node_shader_util.c
+++ b/source/blender/nodes/shader/node_shader_util.c
@@ -211,7 +211,7 @@ void node_gpu_stack_from_data(struct GPUNodeStack *gs, int type, bNodeStack *ns)
 	
 	gs->name = "";
 	gs->hasinput= ns->hasinput && ns->data;
-	/* XXX Commented out the ns->data check here, as it seems it's not alwas set,
+	/* XXX Commented out the ns->data check here, as it seems it's not always set,
 	 *     even though there *is* a valid connection/output... But that might need
 	 *     further investigation.
 	 */
diff --git a/source/blender/python/bmesh/bmesh_py_types.c b/source/blender/python/bmesh/bmesh_py_types.c
index 65bff1db7f6..a82562d4445 100644
--- a/source/blender/python/bmesh/bmesh_py_types.c
+++ b/source/blender/python/bmesh/bmesh_py_types.c
@@ -1578,7 +1578,7 @@ PyDoc_STRVAR(bpy_bmloop_calc_normal_doc,
 ".. method:: calc_normal()\n"
 "\n"
 "   Return normal at this loops corner of the face.\n"
-"   Falls back to the face normal for straignt lines.\n"
+"   Falls back to the face normal for straight lines.\n"
 "\n"
 "   :return: a normalized vector.\n"
 "   :rtype: :class:`mathutils.Vector`\n"
@@ -1595,7 +1595,7 @@ PyDoc_STRVAR(bpy_bmloop_calc_tangent_doc,
 ".. method:: calc_tangent()\n"
 "\n"
 "   Return the tangent at this loops corner of the face (pointing inward into the face).\n"
-"   Falls back to the face normal for straignt lines.\n"
+"   Falls back to the face normal for straight lines.\n"
 "\n"
 "   :return: a normalized vector.\n"
 "   :rtype: :class:`mathutils.Vector`\n"
diff --git a/source/blender/python/bmesh/bmesh_py_types_meshdata.c b/source/blender/python/bmesh/bmesh_py_types_meshdata.c
index b2cc0d73481..1b21f62a115 100644
--- a/source/blender/python/bmesh/bmesh_py_types_meshdata.c
+++ b/source/blender/python/bmesh/bmesh_py_types_meshdata.c
@@ -363,7 +363,7 @@ PyObject *BPy_BMLoopColor_CreatePyObject(struct MLoopCol *data)
  *     weight = dv[group_nr]
  *     del dv[group_nr]
  *
- * \note: there is nothing BMesh spesific here,
+ * \note: there is nothing BMesh specific here,
  * its only that BMesh is the only part of blender that uses a hand written api like this.
  * This type could eventually be used to access lattice weights.
  *
diff --git a/source/blender/python/bmesh/bmesh_py_types_select.c b/source/blender/python/bmesh/bmesh_py_types_select.c
index c76c7d975e4..40d39539894 100644
--- a/source/blender/python/bmesh/bmesh_py_types_select.c
+++ b/source/blender/python/bmesh/bmesh_py_types_select.c
@@ -29,7 +29,7 @@
  * This file defines the types for 'BMesh.select_history'
  * sequence and iterator.
  *
- * select_history is very loosely based on pytons set() type,
+ * select_history is very loosely based on pythons set() type,
  * since items can only exist once. however they do have an order.
  */
 
diff --git a/source/blender/python/generic/bpy_internal_import.c b/source/blender/python/generic/bpy_internal_import.c
index 3a46c6971cf..5852a68e7b7 100644
--- a/source/blender/python/generic/bpy_internal_import.c
+++ b/source/blender/python/generic/bpy_internal_import.c
@@ -287,7 +287,7 @@ static PyObject *blender_import(PyObject *UNUSED(self), PyObject *args, PyObject
 	}
 	else {
 		/* no blender text was found that could import the module
-		 * rause the original error from PyImport_ImportModuleEx */
+		 * reuse the original error from PyImport_ImportModuleEx */
 		PyErr_Restore(exception, err, tb);
 	}
 	return newmodule;
diff --git a/source/blender/python/generic/idprop_py_api.c b/source/blender/python/generic/idprop_py_api.c
index 15eeb5934d8..06b6192a091 100644
--- a/source/blender/python/generic/idprop_py_api.c
+++ b/source/blender/python/generic/idprop_py_api.c
@@ -152,7 +152,7 @@ PyObject *BPy_IDGroup_WrapData(ID *id, IDProperty *prop, IDProperty *parent)
 	}
 }
 
-#if 0 /* UNUSED, currenly assignment overwrites into new properties, rather than setting in-place */
+#if 0 /* UNUSED, currently assignment overwrites into new properties, rather than setting in-place */
 static int BPy_IDGroup_SetData(BPy_IDProperty *self, IDProperty *prop, PyObject *value)
 {
 	switch (prop->type) {
diff --git a/source/blender/python/generic/py_capi_utils.c b/source/blender/python/generic/py_capi_utils.c
index fd12f7f483d..a9b9a5d6cf6 100644
--- a/source/blender/python/generic/py_capi_utils.c
+++ b/source/blender/python/generic/py_capi_utils.c
@@ -229,7 +229,7 @@ PyObject *PyC_Object_GetAttrStringArgs(PyObject *o, Py_ssize_t n, ...)
 /* similar to PyErr_Format(),
  *
  * implementation - we cant actually preprend the existing exception,
- * because it could have _any_ argiments given to it, so instead we get its
+ * because it could have _any_ arguments given to it, so instead we get its
  * __str__ output and raise our own exception including it.
  */
 PyObject *PyC_Err_Format_Prefix(PyObject *exception_type_prefix, const char *format, ...)
diff --git a/source/blender/python/intern/bpy_operator.c b/source/blender/python/intern/bpy_operator.c
index 7375ad454a0..90ea589fde4 100644
--- a/source/blender/python/intern/bpy_operator.c
+++ b/source/blender/python/intern/bpy_operator.c
@@ -232,7 +232,7 @@ static PyObject *pyop_call(PyObject *UNUSED(self), PyObject *args)
 #ifdef BPY_RELEASE_GIL
 			/* release GIL, since a thread could be started from an operator
 			 * that updates a driver */
-			/* note: I havve not seen any examples of code that does this
+			/* note: I have not seen any examples of code that does this
 			 * so it may not be officially supported but seems to work ok. */
 			{
 				PyThreadState *ts = PyEval_SaveThread();
diff --git a/source/blender/python/intern/bpy_props.c b/source/blender/python/intern/bpy_props.c
index f8609859251..a781dbb33b5 100644
--- a/source/blender/python/intern/bpy_props.c
+++ b/source/blender/python/intern/bpy_props.c
@@ -307,7 +307,7 @@ static int py_long_as_int(PyObject *py_long, int *r_int)
 	} (void)0
 
 /* terse macros for error checks shared between all funcs cant use function
- * calls because of static strins passed to pyrna_set_to_enum_bitfield */
+ * calls because of static strings passed to pyrna_set_to_enum_bitfield */
 #define BPY_PROPDEF_CHECK(_func, _property_flag_items)                        \
 	if (id_len >= MAX_IDPROP_NAME) {                                          \
 		PyErr_Format(PyExc_TypeError,                                         \
diff --git a/source/blender/python/intern/bpy_rna.c b/source/blender/python/intern/bpy_rna.c
index e85adf21477..609c549dfcb 100644
--- a/source/blender/python/intern/bpy_rna.c
+++ b/source/blender/python/intern/bpy_rna.c
@@ -7000,7 +7000,7 @@ static int bpy_class_call(bContext *C, PointerRNA *ptr, FunctionRNA *func, Param
 			Py_INCREF(py_class_instance);
 #endif
 			/*
-			 * This would work fine but means __init__ functions wouldnt run.
+			 * This would work fine but means __init__ functions wouldn't run.
 			 * none of blenders default scripts use __init__ but its nice to call it
 			 * for general correctness. just to note why this is here when it could be safely removed.
 			 */
diff --git a/source/blender/python/intern/bpy_rna_array.c b/source/blender/python/intern/bpy_rna_array.c
index 5c59c1e620a..70815d9f8bf 100644
--- a/source/blender/python/intern/bpy_rna_array.c
+++ b/source/blender/python/intern/bpy_rna_array.c
@@ -342,7 +342,7 @@ static char *copy_values(PyObject *seq, PointerRNA *ptr, PropertyRNA *prop,
 
 	/* Regarding PySequence_GetItem() failing.
 	 *
-	 * This should never be NULL since we validated it, _but_ some triky python
+	 * This should never be NULL since we validated it, _but_ some tricky python
 	 * developer could write their own sequence type which succeeds on
 	 * validating but fails later somehow, so include checks for safety.
 	 */
diff --git a/source/blender/python/mathutils/mathutils_Color.c b/source/blender/python/mathutils/mathutils_Color.c
index 59c57e916d4..8a87938d825 100644
--- a/source/blender/python/mathutils/mathutils_Color.c
+++ b/source/blender/python/mathutils/mathutils_Color.c
@@ -147,7 +147,7 @@ static PyObject *Color_str(ColorObject *self)
 }
 
 //------------------------tp_richcmpr
-//returns -1 execption, 0 false, 1 true
+//returns -1 exception, 0 false, 1 true
 static PyObject *Color_richcmpr(PyObject *a, PyObject *b, int op)
 {
 	PyObject *res;
diff --git a/source/blender/python/mathutils/mathutils_Matrix.c b/source/blender/python/mathutils/mathutils_Matrix.c
index 895352ccf93..d98c6e9d2fd 100644
--- a/source/blender/python/mathutils/mathutils_Matrix.c
+++ b/source/blender/python/mathutils/mathutils_Matrix.c
@@ -2443,7 +2443,7 @@ PyObject *Matrix_CreatePyObject_cb(PyObject *cb_user,
 
 
 /* ----------------------------------------------------------------------------
- * special type for alaternate access */
+ * special type for alternate access */
 
 typedef struct {
 	PyObject_HEAD /* required python macro   */
diff --git a/source/blender/python/mathutils/mathutils_Vector.c b/source/blender/python/mathutils/mathutils_Vector.c
index 79285b7778d..c7911cb1572 100644
--- a/source/blender/python/mathutils/mathutils_Vector.c
+++ b/source/blender/python/mathutils/mathutils_Vector.c
@@ -1864,7 +1864,7 @@ static double vec_magnitude_nosqrt(float *data, int size)
 
 
 /*------------------------tp_richcmpr
- * returns -1 execption, 0 false, 1 true */
+ * returns -1 exception, 0 false, 1 true */
 static PyObject *Vector_richcmpr(PyObject *objectA, PyObject *objectB, int comparison_type)
 {
 	VectorObject *vecA = NULL, *vecB = NULL;
@@ -2908,7 +2908,7 @@ PyObject *Vector_CreatePyObject(float *vec, const int size, const int type, PyTy
 			}
 			else { /* new empty */
 				fill_vn_fl(self->vec, size, 0.0f);
-				if (size == 4) { /* do the homogenous thing */
+				if (size == 4) {  /* do the homogeneous thing */
 					self->vec[3] = 1.0f;
 				}
 			}
diff --git a/source/blender/quicktime/apple/qtkit_export.m b/source/blender/quicktime/apple/qtkit_export.m
index b4a89eae89e..f8b09ae8b1b 100644
--- a/source/blender/quicktime/apple/qtkit_export.m
+++ b/source/blender/quicktime/apple/qtkit_export.m
@@ -400,13 +400,13 @@ int start_qt(struct Scene *scene, struct RenderData *rd, int rectx, int recty, R
 				qtexport->audioInputFormat.mFormatFlags |= kLinearPCMFormatFlagIsPacked;
 				
 				
-				/*Ouput format*/
+				/*Output format*/
 				qtexport->audioOutputFormat.mFormatID = rd->qtcodecsettings.audiocodecType;
 				//TODO: set audio channels
 				qtexport->audioOutputFormat.mChannelsPerFrame = 2;
 				qtexport->audioOutputFormat.mSampleRate = rd->qtcodecsettings.audioSampleRate;
 				
-				/* Default value for compressed formats, overriden after if not the case */
+				/* Default value for compressed formats, overridden after if not the case */
 				qtexport->audioOutputFormat.mFramesPerPacket = 0;
 				qtexport->audioOutputFormat.mBytesPerFrame = 0;
 				qtexport->audioOutputFormat.mBytesPerPacket = 0;
diff --git a/source/blender/quicktime/apple/qtkit_import.m b/source/blender/quicktime/apple/qtkit_import.m
index 197cbdc2f0b..073fb31ff96 100644
--- a/source/blender/quicktime/apple/qtkit_import.m
+++ b/source/blender/quicktime/apple/qtkit_import.m
@@ -85,7 +85,7 @@ int anim_is_quicktime (const char *name)
 	if( BLI_testextensie(name, ".swf") ||
 		BLI_testextensie(name, ".txt") ||
 		BLI_testextensie(name, ".mpg") ||
-		BLI_testextensie(name, ".avi") ||	// wouldnt be appropriate ;)
+		BLI_testextensie(name, ".avi") ||	// wouldn't be appropriate ;)
 		BLI_testextensie(name, ".mov") ||	// disabled, suboptimal decoding speed   
 		BLI_testextensie(name, ".mp4") ||	// disabled, suboptimal decoding speed
 		BLI_testextensie(name, ".m4v") ||	// disabled, suboptimal decoding speed
diff --git a/source/blender/quicktime/apple/quicktime_import.c b/source/blender/quicktime/apple/quicktime_import.c
index f3e71feec58..5b13d77a030 100644
--- a/source/blender/quicktime/apple/quicktime_import.c
+++ b/source/blender/quicktime/apple/quicktime_import.c
@@ -195,7 +195,7 @@ int anim_is_quicktime(const char *name)
 	if (BLI_testextensie(name, ".swf") ||
 	    BLI_testextensie(name, ".txt") ||
 	    BLI_testextensie(name, ".mpg") ||
-	    BLI_testextensie(name, ".avi") ||  /* wouldnt be appropriate ;) */
+	    BLI_testextensie(name, ".avi") ||  /* wouldn't be appropriate ;) */
 	    BLI_testextensie(name, ".tga") ||
 	    BLI_testextensie(name, ".png") ||
 	    BLI_testextensie(name, ".bmp") ||
diff --git a/source/blender/render/intern/include/zbuf.h b/source/blender/render/intern/include/zbuf.h
index cdf171443d7..99bde3fe02b 100644
--- a/source/blender/render/intern/include/zbuf.h
+++ b/source/blender/render/intern/include/zbuf.h
@@ -46,7 +46,7 @@ struct StrandShadeCache;
 void fillrect(int *rect, int x, int y, int val);
 
 /**
- * Converts a world coordinate into a homogenous coordinate in view
+ * Converts a world coordinate into a homogeneous coordinate in view
  * coordinates. 
  */
 void projectvert(const float v1[3], float winmat[][4], float adr[4]);
@@ -95,7 +95,7 @@ typedef struct ZSpan {
 	
 	float zmulx, zmuly, zofsx, zofsy;		/* transform from hoco to zbuf co */
 	
-	int *rectz, *arectz;					/* zbuffers, arectz is for transparant */
+	int *rectz, *arectz;					/* zbuffers, arectz is for transparent */
 	int *rectz1;							/* seconday z buffer for shadowbuffer (2nd closest z) */
 	int *rectp;								/* polygon index buffer */
 	int *recto;								/* object buffer */
diff --git a/source/blender/render/intern/raytrace/reorganize.h b/source/blender/render/intern/raytrace/reorganize.h
index 1e9a0319b2f..a9ed71a76bc 100644
--- a/source/blender/render/intern/raytrace/reorganize.h
+++ b/source/blender/render/intern/raytrace/reorganize.h
@@ -421,7 +421,7 @@ struct VBVH_optimalPackSIMD {
 				}
 			}
 			
-			//Save the ways to archieve the minimum cost with a given cutsize
+			/* Save the ways to archive the minimum cost with a given cutsize */
 			for (int i = nchilds; i <= MAX_CUT_SIZE; i++) {
 				node->cut_cost[i - 1] = cost[nchilds][i];
 				if (cost[nchilds][i] < INFINITY) {
diff --git a/source/blender/render/intern/source/convertblender.c b/source/blender/render/intern/source/convertblender.c
index 803a9a95571..eaab1b988ae 100644
--- a/source/blender/render/intern/source/convertblender.c
+++ b/source/blender/render/intern/source/convertblender.c
@@ -3391,7 +3391,7 @@ static void init_render_mesh(Render *re, ObjectRen *obr, int timeoffset)
 
 				ma= give_render_material(re, ob, a1+1);
 				
-				/* test for 100% transparant */
+				/* test for 100% transparent */
 				ok= 1;
 				if (ma->alpha==0.0f && ma->spectra==0.0f && ma->filter==0.0f && (ma->mode & MA_TRANSP) && (ma->mode & MA_RAYMIRROR)==0) {
 					ok= 0;
@@ -5495,7 +5495,7 @@ static int load_fluidsimspeedvectors(Render *re, ObjectInstanceRen *obi, float *
 		camco[1] = dot_v3v3(imat[1], fsvec);
 		camco[2] = dot_v3v3(imat[2], fsvec);
 
-		/* get homogenous coordinates */
+		/* get homogeneous coordinates */
 		projectvert(camco, winmat, hoco);
 		projectvert(ver->co, winmat, ho);
 		
diff --git a/source/blender/render/intern/source/imagetexture.c b/source/blender/render/intern/source/imagetexture.c
index a0ba2a82ead..3e6d0f281fd 100644
--- a/source/blender/render/intern/source/imagetexture.c
+++ b/source/blender/render/intern/source/imagetexture.c
@@ -539,7 +539,7 @@ static void boxsample(ImBuf *ibuf, float minx, float miny, float maxx, float max
 	 */
 	/* note: actually minx etc isn't in the proper range... this due to filter size and offset vectors for bump */
 	/* note: talpha must be initialized */
-	/* note: even when 'imaprepeat' is set, this can only repeate once in any direction.
+	/* note: even when 'imaprepeat' is set, this can only repeat once in any direction.
 	 * the point which min/max is derived from is assumed to be wrapped */
 	TexResult texr;
 	rctf *rf, stack[8];
diff --git a/source/blender/render/intern/source/rayshade.c b/source/blender/render/intern/source/rayshade.c
index 8a936545903..cb7122c834c 100644
--- a/source/blender/render/intern/source/rayshade.c
+++ b/source/blender/render/intern/source/rayshade.c
@@ -1043,7 +1043,7 @@ static void QMC_initPixel(QMCSampler *qsa, int thread)
 	}
 	else { 	/* SAMP_TYPE_HALTON */
 		
-		/* generate a new randomised halton sequence per pixel
+		/* generate a new randomized halton sequence per pixel
 		 * to alleviate qmc artifacts and make it reproducible 
 		 * between threads/frames */
 		double ht_invprimes[2], ht_nums[2];
diff --git a/source/blender/render/intern/source/render_texture.c b/source/blender/render/intern/source/render_texture.c
index c8ef3e4a8dd..74e2c094850 100644
--- a/source/blender/render/intern/source/render_texture.c
+++ b/source/blender/render/intern/source/render_texture.c
@@ -2985,7 +2985,7 @@ void do_sky_tex(const float rco[3], float lo[3], const float dxyview[2], float h
 				}
 				else {
 					/* this value has no angle, the vector is directly along the view.
-					 * avoide divide by zero and use a dummy value. */
+					 * avoid divide by zero and use a dummy value. */
 					tempvec[0]= 1.0f;
 					tempvec[1]= 0.0;
 					tempvec[2]= 0.0;
diff --git a/source/blender/render/intern/source/renderdatabase.c b/source/blender/render/intern/source/renderdatabase.c
index 85d0c36be1a..b12753543e9 100644
--- a/source/blender/render/intern/source/renderdatabase.c
+++ b/source/blender/render/intern/source/renderdatabase.c
@@ -49,7 +49,7 @@
  * - If the entry has no block allocated for it yet, memory is
  * allocated.
  *
- * The pointer to the correct entry is returned. Memory is guarateed
+ * The pointer to the correct entry is returned. Memory is guaranteed
  * to exist (as long as the malloc does not break). Since guarded
  * allocation is used, memory _must_ be available. Otherwise, an
  * exit(0) would occur.
diff --git a/source/blender/render/intern/source/sunsky.c b/source/blender/render/intern/source/sunsky.c
index ddc7dff7b06..6a1517e19fb 100644
--- a/source/blender/render/intern/source/sunsky.c
+++ b/source/blender/render/intern/source/sunsky.c
@@ -360,7 +360,7 @@ static void ComputeAttenuatedSunlight(float theta, int turbidity, float fTau[3])
  * rayf, Rayleigh scattering factor, this factor currently call with 1.0
  * inscattf, inscatter light factor that range from 0.0 to 1.0, 0.0 means no inscatter light and 1.0 means full inscatter light
  * extincf, extinction light factor that range from 0.0 to 1.0, 0.0 means no extinction and 1.0 means full extinction
- * disf, is distance factor, multiplyed to pixle's z value to compute each pixle's distance to camera, 
+ * disf, is distance factor, multiplied to pixle's z value to compute each pixle's distance to camera,
  * */
 void InitAtmosphere(struct SunSky *sunSky, float sun_intens, float mief, float rayf,
                     float inscattf, float extincf, float disf)
diff --git a/source/blender/render/intern/source/volumetric.c b/source/blender/render/intern/source/volumetric.c
index 67e453577e4..220fcd3e986 100644
--- a/source/blender/render/intern/source/volumetric.c
+++ b/source/blender/render/intern/source/volumetric.c
@@ -415,7 +415,7 @@ static void vol_get_transmittance_seg(ShadeInput *shi, float tr[3], float stepsi
 	
 	vol_get_sigma_t(shi, sigma_t, co);
 	
-	/* homogenous volume within the sampled distance */
+	/* homogeneous volume within the sampled distance */
 	tau[0] += stepd * sigma_t[0];
 	tau[1] += stepd * sigma_t[1];
 	tau[2] += stepd * sigma_t[2];
diff --git a/source/blender/render/intern/source/zbuf.c b/source/blender/render/intern/source/zbuf.c
index 1ebb963a790..fde25865577 100644
--- a/source/blender/render/intern/source/zbuf.c
+++ b/source/blender/render/intern/source/zbuf.c
@@ -1626,7 +1626,7 @@ static void clippyra(float *labda, float *v1, float *v2, int *b2, int *b3, int a
 		v13= clipcrop*v1[3];
 	}	
 	/* according the original article by Liang&Barsky, for clipping of
-	 * homogenous coordinates with viewplane, the value of "0" is used instead of "-w" .
+	 * homogeneous coordinates with viewplane, the value of "0" is used instead of "-w" .
 	 * This differs from the other clipping cases (like left or top) and I considered
 	 * it to be not so 'homogenic'. But later it has proven to be an error,
 	 * who would have thought that of L&B!
diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c
index b591805f288..202a9d46f33 100644
--- a/source/blender/windowmanager/intern/wm_event_system.c
+++ b/source/blender/windowmanager/intern/wm_event_system.c
@@ -628,7 +628,7 @@ int WM_operator_call(bContext *C, wmOperator *op)
 
 /* this is intended to be used when an invoke operator wants to call exec on its self
  * and is basically like running op->type->exec() directly, no poll checks no freeing,
- * since we assume whoever called invokle will take care of that */
+ * since we assume whoever called invoke will take care of that */
 int WM_operator_call_notest(bContext *C, wmOperator *op)
 {
 	return wm_operator_exec_notest(C, op);
diff --git a/source/gameengine/GameLogic/SCA_KeyboardSensor.h b/source/gameengine/GameLogic/SCA_KeyboardSensor.h
index 778929a2551..c059aba305b 100644
--- a/source/gameengine/GameLogic/SCA_KeyboardSensor.h
+++ b/source/gameengine/GameLogic/SCA_KeyboardSensor.h
@@ -65,7 +65,7 @@ class SCA_KeyboardSensor : public SCA_ISensor
 	STR_String	m_targetprop;
 	/**
 	 * The property that indicates whether or not to log text when in
-	 * loggin mode. If the property equals 0, no loggin is done. For
+	 * logging mode. If the property equals 0, no logging is done. For
 	 * all other values, logging is active. Logging can only become
 	 * active if there is a property to log to. Logging is independent
 	 * from hotkey settings. */

From f4cff34392a8efe7cc7be448ccd9fa2386597772 Mon Sep 17 00:00:00 2001
From: Campbell Barton 
Date: Tue, 17 Jul 2012 09:56:10 +0000
Subject: [PATCH 056/108] disable feather collapse during drawing, its very
 slow.

---
 source/blender/blenkernel/BKE_mask.h          |  6 +++--
 source/blender/blenkernel/intern/mask.c       | 25 +++++++++++++------
 .../blenkernel/intern/mask_rasterize.c        |  4 +--
 3 files changed, 23 insertions(+), 12 deletions(-)

diff --git a/source/blender/blenkernel/BKE_mask.h b/source/blender/blenkernel/BKE_mask.h
index a293e4a784b..9a4f30c853f 100644
--- a/source/blender/blenkernel/BKE_mask.h
+++ b/source/blender/blenkernel/BKE_mask.h
@@ -72,9 +72,11 @@ int BKE_mask_spline_differentiate_calc_total(const struct MaskSpline *spline, co
 float (*BKE_mask_spline_differentiate(struct MaskSpline *spline, int *tot_diff_point))[2];
 float (*BKE_mask_spline_feather_differentiated_points(struct MaskSpline *spline, int *tot_feather_point))[2];
 
-float (*BKE_mask_spline_differentiate_with_resolution_ex(struct MaskSpline *spline, const int resol, int *tot_diff_point))[2];
+float (*BKE_mask_spline_differentiate_with_resolution_ex(struct MaskSpline *spline, int *tot_diff_point,
+                                                         const int resol))[2];
 float (*BKE_mask_spline_differentiate_with_resolution(struct MaskSpline *spline, int width, int height, int *tot_diff_point))[2];
-float (*BKE_mask_spline_feather_differentiated_points_with_resolution_ex(struct MaskSpline *spline, const int resol, int *tot_feather_point))[2];
+float (*BKE_mask_spline_feather_differentiated_points_with_resolution_ex(struct MaskSpline *spline, int *tot_feather_point,
+                                                                         const int resol, const int do_collapse))[2];
 float (*BKE_mask_spline_feather_differentiated_points_with_resolution(struct MaskSpline *spline, int width, int height, int *tot_feather_point))[2];
 
 float (*BKE_mask_spline_feather_points(struct MaskSpline *spline, int *tot_feather_point))[2];
diff --git a/source/blender/blenkernel/intern/mask.c b/source/blender/blenkernel/intern/mask.c
index 7eb06a1b9ca..4b2f4947a71 100644
--- a/source/blender/blenkernel/intern/mask.c
+++ b/source/blender/blenkernel/intern/mask.c
@@ -331,8 +331,10 @@ int BKE_mask_spline_differentiate_calc_total(const MaskSpline *spline, const int
 	return len;
 }
 
-float (*BKE_mask_spline_differentiate_with_resolution_ex(MaskSpline *spline, const int resol,
-                                                         int *tot_diff_point))[2]
+float (*BKE_mask_spline_differentiate_with_resolution_ex(MaskSpline *spline,
+                                                         int *tot_diff_point,
+                                                         const int resol
+                                                         ))[2]
 {
 	MaskSplinePoint *points_array = BKE_mask_spline_point_array(spline);
 
@@ -389,11 +391,12 @@ float (*BKE_mask_spline_differentiate_with_resolution_ex(MaskSpline *spline, con
 }
 
 float (*BKE_mask_spline_differentiate_with_resolution(MaskSpline *spline, int width, int height,
-                                                      int *tot_diff_point))[2]
+                                                      int *tot_diff_point
+                                                      ))[2]
 {
 	int resol = BKE_mask_spline_resolution(spline, width, height);
 
-	return BKE_mask_spline_differentiate_with_resolution_ex(spline, resol, tot_diff_point);
+	return BKE_mask_spline_differentiate_with_resolution_ex(spline, tot_diff_point, resol);
 }
 
 float (*BKE_mask_spline_differentiate(MaskSpline *spline, int *tot_diff_point))[2]
@@ -562,8 +565,11 @@ static void spline_feather_collapse_inner_loops(float (*feather_points)[2], int
  * values align with #BKE_mask_spline_differentiate_with_resolution_ex
  * when \a resol arguments match.
  */
-float (*BKE_mask_spline_feather_differentiated_points_with_resolution_ex(MaskSpline *spline, const int resol,
-                                                                         int *tot_feather_point))[2]
+float (*BKE_mask_spline_feather_differentiated_points_with_resolution_ex(MaskSpline *spline,
+                                                                         int *tot_feather_point,
+                                                                         const int resol,
+                                                                         const int do_collapse
+                                                                         ))[2]
 {
 	MaskSplinePoint *points_array = BKE_mask_spline_point_array(spline);
 	MaskSplinePoint *point, *prev;
@@ -624,7 +630,10 @@ float (*BKE_mask_spline_feather_differentiated_points_with_resolution_ex(MaskSpl
 
 	*tot_feather_point = tot;
 
-	spline_feather_collapse_inner_loops(feather, tot);
+	/* this is slow! - don't do on draw */
+	if (do_collapse) {
+		spline_feather_collapse_inner_loops(feather, tot);
+	}
 
 	return feather;
 }
@@ -634,7 +643,7 @@ float (*BKE_mask_spline_feather_differentiated_points_with_resolution(MaskSpline
 {
 	int resol = BKE_mask_spline_feather_resolution(spline, width, height);
 
-	return BKE_mask_spline_feather_differentiated_points_with_resolution_ex(spline, resol, tot_feather_point);
+	return BKE_mask_spline_feather_differentiated_points_with_resolution_ex(spline, tot_feather_point, resol, FALSE);
 }
 
 float (*BKE_mask_spline_feather_differentiated_points(MaskSpline *spline, int *tot_feather_point))[2]
diff --git a/source/blender/blenkernel/intern/mask_rasterize.c b/source/blender/blenkernel/intern/mask_rasterize.c
index a4fd5c3509b..69bc092a613 100644
--- a/source/blender/blenkernel/intern/mask_rasterize.c
+++ b/source/blender/blenkernel/intern/mask_rasterize.c
@@ -525,11 +525,11 @@ void BKE_maskrasterize_handle_init(MaskRasterHandle *mr_handle, struct Mask *mas
 			const int resol = CLAMPIS(MAX2(resol_a, resol_b), 4, 512);
 
 			diff_points = BKE_mask_spline_differentiate_with_resolution_ex(
-			                  spline, resol, &tot_diff_point);
+			                  spline, &tot_diff_point, resol);
 
 			if (do_feather) {
 				diff_feather_points = BKE_mask_spline_feather_differentiated_points_with_resolution_ex(
-				                          spline, resol, &tot_diff_feather_points);
+				                          spline, &tot_diff_feather_points, resol, TRUE);
 			}
 			else {
 				tot_diff_feather_points = 0;

From f9795b353e65b3f4ba382dd05621479e7e5a9597 Mon Sep 17 00:00:00 2001
From: Campbell Barton 
Date: Tue, 17 Jul 2012 10:19:47 +0000
Subject: [PATCH 057/108] fix for building without the compositor

---
 source/blender/editors/space_node/CMakeLists.txt   |  4 ++++
 source/blender/editors/space_node/node_draw.c      | 11 +++++++++++
 source/blender/windowmanager/CMakeLists.txt        |  4 ++++
 source/blender/windowmanager/intern/wm_init_exit.c |  2 ++
 4 files changed, 21 insertions(+)

diff --git a/source/blender/editors/space_node/CMakeLists.txt b/source/blender/editors/space_node/CMakeLists.txt
index 9c48ce4034d..2d926a50f98 100644
--- a/source/blender/editors/space_node/CMakeLists.txt
+++ b/source/blender/editors/space_node/CMakeLists.txt
@@ -59,4 +59,8 @@ if(WITH_INTERNATIONAL)
 	add_definitions(-DWITH_INTERNATIONAL)
 endif()
 
+if(WITH_COMPOSITOR)
+	add_definitions(-DWITH_COMPOSITOR)
+endif()
+
 blender_add_lib(bf_editor_space_node "${SRC}" "${INC}" "${INC_SYS}")
diff --git a/source/blender/editors/space_node/node_draw.c b/source/blender/editors/space_node/node_draw.c
index 708d7e0b5e6..8c9f057efc1 100644
--- a/source/blender/editors/space_node/node_draw.c
+++ b/source/blender/editors/space_node/node_draw.c
@@ -721,11 +721,14 @@ static void node_draw_basis(const bContext *C, ARegion *ar, SpaceNode *snode, bN
 	if (node->flag & NODE_MUTED)
 		UI_ThemeColorBlend(color_id, TH_REDALERT, 0.5f);
 
+#ifdef WITH_COMPOSITOR
 	if (ntree->type == NTREE_COMPOSIT && (snode->flag & SNODE_SHOW_HIGHLIGHT)) {
 		if (COM_isHighlightedbNode(node)) {
 			UI_ThemeColorBlend(color_id, TH_ACTIVE, 0.5f);
 		}
 	}
+#endif
+
 	uiSetRoundBox(UI_CNR_TOP_LEFT | UI_CNR_TOP_RIGHT);
 	uiRoundBox(rct->xmin, rct->ymax - NODE_DY, rct->xmax, rct->ymax, BASIS_RAD);
 	
@@ -885,11 +888,15 @@ static void node_draw_hidden(const bContext *C, ARegion *ar, SpaceNode *snode, b
 	if (node->flag & NODE_MUTED)
 		UI_ThemeColorBlend(color_id, TH_REDALERT, 0.5f);
 
+#ifdef WITH_COMPOSITOR
 	if (ntree->type == NTREE_COMPOSIT && (snode->flag & SNODE_SHOW_HIGHLIGHT)) {
 		if (COM_isHighlightedbNode(node)) {
 			UI_ThemeColorBlend(color_id, TH_ACTIVE, 0.5f);
 		}
 	}
+#else
+	(void)ntree;
+#endif
 	
 	uiRoundBox(rct->xmin, rct->ymin, rct->xmax, rct->ymax, hiddenrad);
 	
@@ -1138,9 +1145,13 @@ void drawnodespace(const bContext *C, ARegion *ar, View2D *v2d)
 		}
 		
 		node_update_nodetree(C, snode->nodetree, 0.0f, 0.0f);
+
+#ifdef WITH_COMPOSITOR
 		if (snode->nodetree->type == NTREE_COMPOSIT) {
 			COM_startReadHighlights();
 		} 
+#endif
+
 		node_draw_nodetree(C, ar, snode, snode->nodetree);
 		
 		#if 0
diff --git a/source/blender/windowmanager/CMakeLists.txt b/source/blender/windowmanager/CMakeLists.txt
index 275aeb3317c..c5aaeeb8171 100644
--- a/source/blender/windowmanager/CMakeLists.txt
+++ b/source/blender/windowmanager/CMakeLists.txt
@@ -143,4 +143,8 @@ if(WIN322)
 	)
 endif()
 
+if(WITH_COMPOSITOR)
+	add_definitions(-DWITH_COMPOSITOR)
+endif()
+
 blender_add_lib_nolist(bf_windowmanager "${SRC}" "${INC}" "${INC_SYS}")
diff --git a/source/blender/windowmanager/intern/wm_init_exit.c b/source/blender/windowmanager/intern/wm_init_exit.c
index b9170d703aa..2098d872357 100644
--- a/source/blender/windowmanager/intern/wm_init_exit.c
+++ b/source/blender/windowmanager/intern/wm_init_exit.c
@@ -200,11 +200,13 @@ void WM_init(bContext *C, int argc, const char **argv)
 
 	BLI_strncpy(G.lib, G.main->name, FILE_MAX);
 
+#ifdef WITH_COMPOSITOR
 	if (1) {
 		extern void *COM_linker_hack;
 		extern void *COM_execute;
 		COM_linker_hack = COM_execute;
 	}
+#endif
 }
 
 void WM_init_splash(bContext *C)

From 29bc3d70246b6686cd7c9df5a2b6ab9d8e42c3b3 Mon Sep 17 00:00:00 2001
From: Campbell Barton 
Date: Tue, 17 Jul 2012 10:38:22 +0000
Subject: [PATCH 058/108] fix for scons building with compositor

---
 source/blender/editors/space_node/SConscript | 3 +++
 source/blender/windowmanager/SConscript      | 3 +++
 2 files changed, 6 insertions(+)

diff --git a/source/blender/editors/space_node/SConscript b/source/blender/editors/space_node/SConscript
index 4c6e94484e4..7e311b1329d 100644
--- a/source/blender/editors/space_node/SConscript
+++ b/source/blender/editors/space_node/SConscript
@@ -25,4 +25,7 @@ if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'linuxcross', 'win64-vc', '
 if env['WITH_BF_INTERNATIONAL']:
     defs.append('WITH_INTERNATIONAL')
 
+if env['WITH_BF_COMPOSITOR']:
+    defs.append("WITH_COMPOSITOR")
+
 env.BlenderLib ( 'bf_editors_space_node', sources, Split(incs), defs, libtype=['core'], priority=[55], compileflags=cf )
diff --git a/source/blender/windowmanager/SConscript b/source/blender/windowmanager/SConscript
index 57d632c7d04..bf219bb9c06 100644
--- a/source/blender/windowmanager/SConscript
+++ b/source/blender/windowmanager/SConscript
@@ -43,4 +43,7 @@ if env['BF_BUILDINFO']:
 if env['WITH_BF_INTERNATIONAL']:
     defs.append('WITH_INTERNATIONAL')
 
+if env['WITH_BF_COMPOSITOR']:
+    defs.append("WITH_COMPOSITOR")
+
 env.BlenderLib ( 'bf_windowmanager', sources, Split(incs), defines=defs, libtype=['core'], priority=[5] )

From e35d3083ecce72ad01fa63977355beb0c7a5ff68 Mon Sep 17 00:00:00 2001
From: Sergey Sharybin 
Date: Tue, 17 Jul 2012 10:43:57 +0000
Subject: [PATCH 059/108] Fixed crash when rasterizing spline with only one
 point

It was an issue in new feather self-intersection test code.
---
 source/blender/blenkernel/intern/mask.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/source/blender/blenkernel/intern/mask.c b/source/blender/blenkernel/intern/mask.c
index 4b2f4947a71..64902f0ee3e 100644
--- a/source/blender/blenkernel/intern/mask.c
+++ b/source/blender/blenkernel/intern/mask.c
@@ -509,6 +509,14 @@ static void spline_feather_collapse_inner_loops(float (*feather_points)[2], int
 	int i;
 	float min[2], max[2];
 
+	if (tot_feather_point < 4) {
+		/* self-intersection works only for quads at least,
+		 * in other cases polygon can't be self-intersecting anyway
+		 */
+
+		return;
+	}
+
 	/* find min/max corners of mask to build buckets in that space */
 	INIT_MINMAX2(min, max);
 

From 6f0950a1f4abd884234c4e5f980e21ef3915eaff Mon Sep 17 00:00:00 2001
From: Campbell Barton 
Date: Tue, 17 Jul 2012 12:05:15 +0000
Subject: [PATCH 060/108] use math vector init functions

---
 .../blenkernel/intern/particle_system.c       | 29 ++++++++++---------
 source/blender/blenkernel/intern/pointcache.c |  3 +-
 .../modifiers/intern/MOD_particleinstance.c   |  4 +--
 3 files changed, 17 insertions(+), 19 deletions(-)

diff --git a/source/blender/blenkernel/intern/particle_system.c b/source/blender/blenkernel/intern/particle_system.c
index aa798f59482..457903a4d09 100644
--- a/source/blender/blenkernel/intern/particle_system.c
+++ b/source/blender/blenkernel/intern/particle_system.c
@@ -2441,7 +2441,8 @@ static void sph_particle_courant(SPHData *sphdata, SPHRangeData *pfr)
 	int i;
 	float flow[3], offset[3], dist;
 
-	flow[0] = flow[1] = flow[2] = 0.0f;
+	zero_v3(flow);
+
 	dist = 0.0f;
 	if (pfr->tot_neighbors > 0) {
 		pa = pfr->pa;
@@ -2733,9 +2734,8 @@ static void basic_rotate(ParticleSettings *part, ParticleData *pa, float dfra, f
 {
 	float rotfac, rot1[4], rot2[4]={1.0,0.0,0.0,0.0}, dtime=dfra*timestep, extrotfac;
 
-	if ((part->flag & PART_ROTATIONS)==0) {
-		pa->state.rot[0]=1.0f;
-		pa->state.rot[1]=pa->state.rot[2]=pa->state.rot[3]=0;
+	if ((part->flag & PART_ROTATIONS) == 0) {
+		unit_qt(pa->state.rot);
 		return;
 	}
 
@@ -2747,8 +2747,9 @@ static void basic_rotate(ParticleSettings *part, ParticleData *pa, float dfra, f
 		float len2 = len_v3(pa->state.vel);
 		float vec[3];
 
-		if (len1==0.0f || len2==0.0f)
-			pa->state.ave[0] = pa->state.ave[1] = pa->state.ave[2] = 0.0f;
+		if (len1 == 0.0f || len2 == 0.0f) {
+			zero_v3(pa->state.ave);
+		}
 		else {
 			cross_v3_v3v3(pa->state.ave, pa->prev_state.vel, pa->state.vel);
 			normalize_v3(pa->state.ave);
@@ -2761,9 +2762,8 @@ static void basic_rotate(ParticleSettings *part, ParticleData *pa, float dfra, f
 	}
 
 	rotfac = len_v3(pa->state.ave);
-	if (rotfac == 0.0f || (part->flag & PART_ROT_DYN)==0 || extrotfac == 0.0f) { /* unit_qt(in VecRotToQuat) doesn't give unit quat [1,0,0,0]?? */
-		rot1[0]=1.0f;
-		rot1[1]=rot1[2]=rot1[3]=0;
+	if (rotfac == 0.0f || (part->flag & PART_ROT_DYN)==0 || extrotfac == 0.0f) {
+		unit_qt(rot1);
 	}
 	else {
 		axis_angle_to_quat(rot1,pa->state.ave,rotfac*dtime);
@@ -3750,8 +3750,10 @@ static void save_hair(ParticleSimulationData *sim, float UNUSED(cfra))
 		pa->totkey++;
 
 		/* root is always in the origin of hair space so we set it to be so after the last key is saved*/
-		if (pa->totkey == psys->part->hair_step + 1)
-			root->co[0] = root->co[1] = root->co[2] = 0.0f;
+		if (pa->totkey == psys->part->hair_step + 1) {
+			zero_v3(root->co);
+		}
+
 	}
 }
 
@@ -4130,9 +4132,8 @@ static void particles_fluid_step(ParticleSimulationData *sim, int UNUSED(cfra))
 						pa->state.vel[j] = wrf;
 					}
 	
-					pa->state.ave[0] = pa->state.ave[1] = pa->state.ave[2] = 0.0f;
-					pa->state.rot[0] = 1.0;
-					pa->state.rot[1] = pa->state.rot[2] = pa->state.rot[3] = 0.0;
+					zero_v3(pa->state.ave);
+					unit_qt(pa->state.rot);
 	
 					pa->time = 1.f;
 					pa->dietime = sim->scene->r.efra + 1;
diff --git a/source/blender/blenkernel/intern/pointcache.c b/source/blender/blenkernel/intern/pointcache.c
index 90e76e049bd..101f53fe94f 100644
--- a/source/blender/blenkernel/intern/pointcache.c
+++ b/source/blender/blenkernel/intern/pointcache.c
@@ -326,8 +326,7 @@ static void ptcache_particle_read(int index, void *psys_v, void **data, float cf
 
 	/* default to no rotation */
 	if (data[BPHYS_DATA_LOCATION] && !data[BPHYS_DATA_ROTATION]) {
-		pa->state.rot[0]=1.0f;
-		pa->state.rot[1]=pa->state.rot[2]=pa->state.rot[3]=0;
+		unit_qt(pa->state.rot);
 	}
 }
 static void ptcache_particle_interpolate(int index, void *psys_v, void **data, float cfra, float cfra1, float cfra2, float *old_data)
diff --git a/source/blender/modifiers/intern/MOD_particleinstance.c b/source/blender/modifiers/intern/MOD_particleinstance.c
index 74026efecc5..c034832bfb4 100644
--- a/source/blender/modifiers/intern/MOD_particleinstance.c
+++ b/source/blender/modifiers/intern/MOD_particleinstance.c
@@ -238,8 +238,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob,
 
 			/* TODO: incremental rotations somehow */
 			if (state.vel[axis] < -0.9999f || state.vel[axis] > 0.9999f) {
-				state.rot[0] = 1;
-				state.rot[1] = state.rot[2] = state.rot[3] = 0.0f;
+				unit_qt(state.rot);
 			}
 			else {
 				float temp[3] = {0.0f, 0.0f, 0.0f};
@@ -250,7 +249,6 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob,
 				/* state.vel[axis] is the only component surviving from a dot product with the axis */
 				axis_angle_to_quat(state.rot, cross, saacos(state.vel[axis]));
 			}
-
 		}
 		else {
 			state.time = -1.0;

From 9c714f695ae3156519b6e8f4abd0d82f171ba541 Mon Sep 17 00:00:00 2001
From: Campbell Barton 
Date: Tue, 17 Jul 2012 13:28:30 +0000
Subject: [PATCH 061/108] fix for particle system using uninitialized stack
 memory with midpoint of rk4 integrators.

---
 source/blender/blenkernel/intern/particle_system.c | 11 +++++++++--
 1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/source/blender/blenkernel/intern/particle_system.c b/source/blender/blenkernel/intern/particle_system.c
index 457903a4d09..0b3131f0a1c 100644
--- a/source/blender/blenkernel/intern/particle_system.c
+++ b/source/blender/blenkernel/intern/particle_system.c
@@ -2159,7 +2159,9 @@ static void integrate_particle(ParticleSettings *part, ParticleData *pa, float d
 			break;
 	}
 
-	copy_particle_key(states, &pa->state, 1);
+	for (i=0; istate, 1);
+	}
 
 	states->time = 0.f;
 
@@ -2739,7 +2741,12 @@ static void basic_rotate(ParticleSettings *part, ParticleData *pa, float dfra, f
 		return;
 	}
 
-	extrotfac = len_v3(pa->state.ave);
+	if (part->flag & PART_ROT_DYN) {
+		extrotfac = len_v3(pa->state.ave);
+	}
+	else {
+		extrotfac = 0.0f;
+	}
 
 	if ((part->flag & PART_ROT_DYN) && ELEM3(part->avemode, PART_AVE_VELOCITY, PART_AVE_HORIZONTAL, PART_AVE_VERTICAL)) {
 		float angle;

From 46bec423333d3cee3401bf967c6adff257f8b310 Mon Sep 17 00:00:00 2001
From: Campbell Barton 
Date: Tue, 17 Jul 2012 15:16:44 +0000
Subject: [PATCH 062/108] option to clear all keys from a button, so you dont
 have to hunt about for the keys inserted.

---
 .../blender/editors/animation/anim_intern.h   |   1 +
 source/blender/editors/animation/anim_ops.c   |   1 +
 source/blender/editors/animation/keyframing.c | 157 ++++++++++++++++++
 .../editors/interface/interface_anim.c        |   6 +
 .../editors/interface/interface_handlers.c    |  28 +++-
 .../editors/interface/interface_intern.h      |   1 +
 6 files changed, 190 insertions(+), 4 deletions(-)

diff --git a/source/blender/editors/animation/anim_intern.h b/source/blender/editors/animation/anim_intern.h
index 7d1209a3033..cf84eb04b10 100644
--- a/source/blender/editors/animation/anim_intern.h
+++ b/source/blender/editors/animation/anim_intern.h
@@ -55,6 +55,7 @@ void ANIM_OT_keyframe_delete_v3d(struct wmOperatorType *ot);
 /* Keyframe managment operators for UI buttons (RMB menu). */
 void ANIM_OT_keyframe_insert_button(struct wmOperatorType *ot);
 void ANIM_OT_keyframe_delete_button(struct wmOperatorType *ot);
+void ANIM_OT_keyframe_clear_button(struct wmOperatorType *ot);
 
 /* .......... */
 
diff --git a/source/blender/editors/animation/anim_ops.c b/source/blender/editors/animation/anim_ops.c
index 119df33dd91..13741a99d99 100644
--- a/source/blender/editors/animation/anim_ops.c
+++ b/source/blender/editors/animation/anim_ops.c
@@ -294,6 +294,7 @@ void ED_operatortypes_anim(void)
 	WM_operatortype_append(ANIM_OT_keyframe_delete_v3d);
 	WM_operatortype_append(ANIM_OT_keyframe_insert_button);
 	WM_operatortype_append(ANIM_OT_keyframe_delete_button);
+	WM_operatortype_append(ANIM_OT_keyframe_clear_button);
 	
 	
 	WM_operatortype_append(ANIM_OT_driver_button_add);
diff --git a/source/blender/editors/animation/keyframing.c b/source/blender/editors/animation/keyframing.c
index 7600e1d4690..3ef686910e6 100644
--- a/source/blender/editors/animation/keyframing.c
+++ b/source/blender/editors/animation/keyframing.c
@@ -1079,6 +1079,91 @@ short delete_keyframe(ReportList *reports, ID *id, bAction *act, const char grou
 	return ret;
 }
 
+/* ************************************************** */
+/* KEYFRAME CLEAR */
+
+/* Main Keyframing API call:
+ *	Use this when validation of necessary animation data isn't necessary as it
+ *	already exists. It will clear the current buttons fcurve(s).
+ *
+ *	The flag argument is used for special settings that alter the behavior of
+ *	the keyframe deletion. These include the quick refresh options.
+ */
+short clear_keyframe(ReportList *reports, ID *id, bAction *act, const char group[], const char rna_path[], int array_index, short UNUSED(flag))
+{
+	AnimData *adt = BKE_animdata_from_id(id);
+	PointerRNA id_ptr, ptr;
+	PropertyRNA *prop;
+	int array_index_max = array_index + 1;
+	int ret = 0;
+
+	/* sanity checks */
+	if (ELEM(NULL, id, adt)) {
+		BKE_report(reports, RPT_ERROR, "No ID-Block and/Or AnimData to delete keyframe from");
+		return 0;
+	}
+
+	/* validate pointer first - exit if failure */
+	RNA_id_pointer_create(id, &id_ptr);
+	if ((RNA_path_resolve(&id_ptr, rna_path, &ptr, &prop) == 0) || (prop == NULL)) {
+		BKE_reportf(reports, RPT_ERROR, "Could not clear keyframe, as RNA Path is invalid for the given ID (ID = %s, Path = %s)", id->name, rna_path);
+		return 0;
+	}
+
+	/* get F-Curve
+	 * Note: here is one of the places where we don't want new Action + F-Curve added!
+	 *      so 'add' var must be 0
+	 */
+	if (act == NULL) {
+		/* if no action is provided, use the default one attached to this ID-block
+		 *  - if it doesn't exist, then we're out of options...
+		 */
+		if (adt->action) {
+			act = adt->action;
+		}
+		else {
+			BKE_reportf(reports, RPT_ERROR, "No Action to delete keyframes from for ID = %s\n", id->name);
+			return 0;
+		}
+	}
+
+	/* key entire array convenience method */
+	if (array_index == -1) {
+		array_index = 0;
+		array_index_max = RNA_property_array_length(&ptr, prop);
+
+		/* for single properties, increase max_index so that the property itself gets included,
+		 * but don't do this for standard arrays since that can cause corruption issues
+		 * (extra unused curves)
+		 */
+		if (array_index_max == array_index)
+			array_index_max++;
+	}
+
+	/* will only loop once unless the array index was -1 */
+	for (; array_index < array_index_max; array_index++) {
+		FCurve *fcu = verify_fcurve(act, group, &ptr, rna_path, array_index, 0);
+
+		/* check if F-Curve exists and/or whether it can be edited */
+		if (fcu == NULL)
+			continue;
+
+		if ( (fcu->flag & FCURVE_PROTECTED) || ((fcu->grp) && (fcu->grp->flag & AGRP_PROTECTED)) ) {
+			if (G.debug & G_DEBUG)
+				printf("WARNING: not deleting keyframe for locked F-Curve\n");
+			continue;
+		}
+
+		ANIM_fcurve_delete_from_animdata(NULL, adt, fcu);
+
+		/* return success */
+		ret++;
+	}
+
+	/* return success/failure */
+	return ret;
+}
+
 /* ******************************************* */
 /* KEYFRAME MODIFICATION */
 
@@ -1584,6 +1669,78 @@ void ANIM_OT_keyframe_delete_button(wmOperatorType *ot)
 	RNA_def_boolean(ot->srna, "all", 1, "All", "Delete keyframes from all elements of the array");
 }
 
+
+/* Clear Key Button Operator ------------------------ */
+
+static int clear_key_button_exec(bContext *C, wmOperator *op)
+{
+	Main *bmain = CTX_data_main(C);
+	PointerRNA ptr = {{NULL}};
+	PropertyRNA *prop = NULL;
+	char *path;
+	short success = 0;
+	int a, index, length, all = RNA_boolean_get(op->ptr, "all");
+
+	/* try to insert keyframe using property retrieved from UI */
+	uiContextActiveProperty(C, &ptr, &prop, &index);
+
+	if (ptr.id.data && ptr.data && prop) {
+		path = RNA_path_from_ID_to_property(&ptr, prop);
+
+		if (path) {
+			if (all) {
+				length = RNA_property_array_length(&ptr, prop);
+
+				if (length) index = 0;
+				else length = 1;
+			}
+			else
+				length = 1;
+
+			for (a = 0; a < length; a++)
+				success += clear_keyframe(op->reports, ptr.id.data, NULL, NULL, path, index + a, 0);
+
+			MEM_freeN(path);
+		}
+		else if (G.debug & G_DEBUG)
+			printf("Button Clear-Key: no path to property\n");
+	}
+	else if (G.debug & G_DEBUG) {
+		printf("ptr.data = %p, prop = %p\n", (void *)ptr.data, (void *)prop);
+	}
+
+
+	if (success) {
+		/* send updates */
+		uiContextAnimUpdate(C);
+
+		DAG_ids_flush_update(bmain, 0);
+
+		/* send notifiers that keyframes have been changed */
+		WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, NULL);
+	}
+
+	return (success) ? OPERATOR_FINISHED : OPERATOR_CANCELLED;
+}
+
+void ANIM_OT_keyframe_clear_button(wmOperatorType *ot)
+{
+	/* identifiers */
+	ot->name = "Clear Keyframe (Buttons)";
+	ot->idname = "ANIM_OT_keyframe_clear_button";
+	ot->description = "Clear all keyframes on the currently active property";
+
+	/* callbacks */
+	ot->exec = clear_key_button_exec;
+	ot->poll = modify_key_op_poll;
+
+	/* flags */
+	ot->flag = OPTYPE_UNDO;
+
+	/* properties */
+	RNA_def_boolean(ot->srna, "all", 1, "All", "Clear keyframes from all elements of the array");
+}
+
 /* ******************************************* */
 /* AUTO KEYFRAME */
 
diff --git a/source/blender/editors/interface/interface_anim.c b/source/blender/editors/interface/interface_anim.c
index 3099fcb2b40..5d62ef768d2 100644
--- a/source/blender/editors/interface/interface_anim.c
+++ b/source/blender/editors/interface/interface_anim.c
@@ -212,6 +212,12 @@ void ui_but_anim_delete_keyframe(bContext *C)
 	WM_operator_name_call(C, "ANIM_OT_keyframe_delete_button", WM_OP_INVOKE_DEFAULT, NULL);
 }
 
+void ui_but_anim_clear_keyframe(bContext *C)
+{
+	/* this operator calls uiContextActiveProperty */
+	WM_operator_name_call(C, "ANIM_OT_keyframe_clear_button", WM_OP_INVOKE_DEFAULT, NULL);
+}
+
 void ui_but_anim_add_driver(bContext *C)
 {
 	/* this operator calls uiContextActiveProperty */
diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c
index 0a9665ffc15..91b3b3ea622 100644
--- a/source/blender/editors/interface/interface_handlers.c
+++ b/source/blender/editors/interface/interface_handlers.c
@@ -4474,6 +4474,19 @@ static int ui_but_menu(bContext *C, uiBut *but)
 				               ICON_NONE, "ANIM_OT_keyframe_insert_button", "all", 0);
 		}
 		
+		if (but->flag & UI_BUT_ANIMATED) {
+			if (length) {
+				uiItemBooleanO(layout, CTX_IFACE_(BLF_I18NCONTEXT_OPERATOR_DEFAULT, "Clear Keyframes"),
+				               ICON_NONE, "ANIM_OT_keyframe_clear_button", "all", 1);
+				uiItemBooleanO(layout, CTX_IFACE_(BLF_I18NCONTEXT_OPERATOR_DEFAULT, "Clear Single Keyframes"),
+				               ICON_NONE, "ANIM_OT_keyframe_clear_button", "all", 0);
+			}
+			else {
+				uiItemBooleanO(layout, CTX_IFACE_(BLF_I18NCONTEXT_OPERATOR_DEFAULT, "Clear Keyframes"),
+				               ICON_NONE, "ANIM_OT_keyframe_clear_button", "all", 0);
+			}
+		}
+
 		/* Drivers */
 		if (but->flag & UI_BUT_DRIVEN) {
 			uiItemS(layout);
@@ -4687,11 +4700,18 @@ static int ui_do_button(bContext *C, uiBlock *block, uiBut *but, wmEvent *event)
 			ui_but_drop(C, event, but, data);
 		}
 		/* handle keyframing */
-		else if (event->type == IKEY && !ELEM3(KM_MOD_FIRST, event->ctrl, event->oskey, event->shift) && event->val == KM_PRESS) {
-			if (event->alt)
-				ui_but_anim_delete_keyframe(C);
-			else
+		else if (event->type == IKEY && !ELEM(KM_MOD_FIRST, event->ctrl, event->oskey) && event->val == KM_PRESS) {
+			if (event->alt) {
+				if (event->shift) {
+					ui_but_anim_clear_keyframe(C);
+				}
+				else {
+					ui_but_anim_delete_keyframe(C);
+				}
+			}
+			else {
 				ui_but_anim_insert_keyframe(C);
+			}
 			
 			ED_region_tag_redraw(CTX_wm_region(C));
 			
diff --git a/source/blender/editors/interface/interface_intern.h b/source/blender/editors/interface/interface_intern.h
index 1f88db033a4..c6787b4c554 100644
--- a/source/blender/editors/interface/interface_intern.h
+++ b/source/blender/editors/interface/interface_intern.h
@@ -508,6 +508,7 @@ void ui_but_add_shortcut(uiBut *but, const char *key_str, const short do_strip);
 void ui_but_anim_flag(uiBut *but, float cfra);
 void ui_but_anim_insert_keyframe(struct bContext *C);
 void ui_but_anim_delete_keyframe(struct bContext *C);
+void ui_but_anim_clear_keyframe(struct bContext *C);
 void ui_but_anim_add_driver(struct bContext *C);
 void ui_but_anim_remove_driver(struct bContext *C);
 void ui_but_anim_copy_driver(struct bContext *C);

From 2945ba9e5edb8da2258585ae40e845d763b78d5d Mon Sep 17 00:00:00 2001
From: Campbell Barton 
Date: Tue, 17 Jul 2012 15:44:33 +0000
Subject: [PATCH 063/108] holding shift with cont. grab now works on the hsv
 cube and the value slider.

---
 .../editors/interface/interface_anim.c        |  3 +-
 .../editors/interface/interface_handlers.c    | 30 ++++++++++++-------
 2 files changed, 21 insertions(+), 12 deletions(-)

diff --git a/source/blender/editors/interface/interface_anim.c b/source/blender/editors/interface/interface_anim.c
index 5d62ef768d2..28d18f6a3dd 100644
--- a/source/blender/editors/interface/interface_anim.c
+++ b/source/blender/editors/interface/interface_anim.c
@@ -217,8 +217,7 @@ void ui_but_anim_clear_keyframe(bContext *C)
 	/* this operator calls uiContextActiveProperty */
 	WM_operator_name_call(C, "ANIM_OT_keyframe_clear_button", WM_OP_INVOKE_DEFAULT, NULL);
 }
-
-void ui_but_anim_add_driver(bContext *C)
+ void ui_but_anim_add_driver(bContext *C)
 {
 	/* this operator calls uiContextActiveProperty */
 	WM_operator_name_call(C, "ANIM_OT_driver_button_add", WM_OP_INVOKE_DEFAULT, NULL);
diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c
index 91b3b3ea622..c5575639169 100644
--- a/source/blender/editors/interface/interface_handlers.c
+++ b/source/blender/editors/interface/interface_handlers.c
@@ -256,9 +256,11 @@ static uiBut *ui_but_last(uiBlock *block)
 
 static int ui_is_a_warp_but(uiBut *but)
 {
-	if (U.uiflag & USER_CONTINUOUS_MOUSE)
-		if (ELEM4(but->type, NUM, NUMABS, HSVCIRCLE, TRACKPREVIEW))
+	if (U.uiflag & USER_CONTINUOUS_MOUSE) {
+		if (ELEM5(but->type, NUM, NUMABS, HSVCIRCLE, TRACKPREVIEW, HSVCUBE)) {
 			return TRUE;
+		}
+	}
 
 	return FALSE;
 }
@@ -2636,7 +2638,7 @@ static int ui_do_but_NUM(bContext *C, uiBlock *block, uiBut *but, uiHandleButton
 	return retval;
 }
 
-static int ui_numedit_but_SLI(uiBut *but, uiHandleButtonData *data, int shift, int ctrl, int mx)
+static int ui_numedit_but_SLI(uiBut *but, uiHandleButtonData *data, const short shift, const short ctrl, int mx)
 {
 	float deler, f, tempf, softmin, softmax, softrange;
 	int temp, lvalue, changed = 0;
@@ -3091,7 +3093,7 @@ static int ui_do_but_NORMAL(bContext *C, uiBlock *block, uiBut *but, uiHandleBut
 	return WM_UI_HANDLER_CONTINUE;
 }
 
-static int ui_numedit_but_HSVCUBE(uiBut *but, uiHandleButtonData *data, int mx, int my)
+static int ui_numedit_but_HSVCUBE(uiBut *but, uiHandleButtonData *data, float mx, float my, const short shift)
 {
 	float rgb[3];
 	float *hsv = ui_block_hsv_get(but->block);
@@ -3108,6 +3110,13 @@ static int ui_numedit_but_HSVCUBE(uiBut *but, uiHandleButtonData *data, int mx,
 
 	rgb_to_hsv_compat_v(rgb, hsv);
 
+	if (U.uiflag & USER_CONTINUOUS_MOUSE) {
+		float fac = shift ? 0.05f : 1.0f;
+		/* slow down the mouse, this is fairly picky */
+		mx = (data->dragstartx * (1.0f - fac) + mx * fac);
+		my = (data->dragstarty * (1.0f - fac) + my * fac);
+	}
+
 	/* relative position within box */
 	x = ((float)mx - but->x1) / (but->x2 - but->x1);
 	y = ((float)my - but->y1) / (but->y2 - but->y1);
@@ -3161,7 +3170,7 @@ static int ui_numedit_but_HSVCUBE(uiBut *but, uiHandleButtonData *data, int mx,
 	return changed;
 }
 
-static void ui_ndofedit_but_HSVCUBE(uiBut *but, uiHandleButtonData *data, wmNDOFMotionData *ndof, int shift)
+static void ui_ndofedit_but_HSVCUBE(uiBut *but, uiHandleButtonData *data, wmNDOFMotionData *ndof, const short shift)
 {
 	float *hsv = ui_block_hsv_get(but->block);
 	float rgb[3];
@@ -3235,7 +3244,7 @@ static int ui_do_but_HSVCUBE(bContext *C, uiBlock *block, uiBut *but, uiHandleBu
 			button_activate_state(C, but, BUTTON_STATE_NUM_EDITING);
 
 			/* also do drag the first time */
-			if (ui_numedit_but_HSVCUBE(but, data, mx, my))
+			if (ui_numedit_but_HSVCUBE(but, data, mx, my, event->shift))
 				ui_numedit_apply(C, block, but, data);
 			
 			return WM_UI_HANDLER_BREAK;
@@ -3292,7 +3301,7 @@ static int ui_do_but_HSVCUBE(bContext *C, uiBlock *block, uiBut *but, uiHandleBu
 		}
 		else if (event->type == MOUSEMOVE) {
 			if (mx != data->draglastx || my != data->draglasty) {
-				if (ui_numedit_but_HSVCUBE(but, data, mx, my))
+				if (ui_numedit_but_HSVCUBE(but, data, mx, my, event->shift))
 					ui_numedit_apply(C, block, but, data);
 			}
 		}
@@ -3305,7 +3314,7 @@ static int ui_do_but_HSVCUBE(bContext *C, uiBlock *block, uiBut *but, uiHandleBu
 	return WM_UI_HANDLER_CONTINUE;
 }
 
-static int ui_numedit_but_HSVCIRCLE(uiBut *but, uiHandleButtonData *data, int mx, int my, int shift)
+static int ui_numedit_but_HSVCIRCLE(uiBut *but, uiHandleButtonData *data, float mx, float my, int shift)
 {
 	rcti rect;
 	int changed = 1;
@@ -3352,7 +3361,7 @@ static int ui_numedit_but_HSVCIRCLE(uiBut *but, uiHandleButtonData *data, int mx
 	return changed;
 }
 
-static void ui_ndofedit_but_HSVCIRCLE(uiBut *but, uiHandleButtonData *data, wmNDOFMotionData *ndof, int shift)
+static void ui_ndofedit_but_HSVCIRCLE(uiBut *but, uiHandleButtonData *data, wmNDOFMotionData *ndof, const short shift)
 {
 	float *hsv = ui_block_hsv_get(but->block);
 	float rgb[3];
@@ -4182,7 +4191,8 @@ static int ui_do_but_LINK(bContext *C, uiBut *but, uiHandleButtonData *data, wmE
 	return WM_UI_HANDLER_CONTINUE;
 }
 
-static int ui_numedit_but_TRACKPREVIEW(bContext *C, uiBut *but, uiHandleButtonData *data, int mx, int my, int shift)
+static int ui_numedit_but_TRACKPREVIEW(bContext *C, uiBut *but, uiHandleButtonData *data,
+                                       int mx, int my, const short shift)
 {
 	MovieClipScopes *scopes = (MovieClipScopes *)but->poin;
 	int changed = 1;

From 2c2e1775f9dffac928503ba6fa4307dd726f1d23 Mon Sep 17 00:00:00 2001
From: Sergey Sharybin 
Date: Tue, 17 Jul 2012 16:22:18 +0000
Subject: [PATCH 064/108] Feather self-intersection test speed up

Made some minor optimization such as:

- Avoid using "%" operation in loops, replace with a check
  for index "overflow".
- Use pre-computed values for scaling feather coordinates
  to 0 .. 1 space.

This allowed to reach couple of milliseconds of boost.

Another change is to use higher number of buckets (up to 512).
This doesn't took significantly more memory (like uses only 10MB
of memory for average splines) and allows to have 30-50x boost
for average splines.

Use dynamically calculated number of buckets for this, to be
sure segments would fit two buckets.

Also fixed intersection detection in some cases when edge is
shared between two buckets -- it is possible that such edge
would cross third bucket and intersect edge from there.
---
 source/blender/blenkernel/intern/mask.c | 123 +++++++++++++++++++-----
 1 file changed, 97 insertions(+), 26 deletions(-)

diff --git a/source/blender/blenkernel/intern/mask.c b/source/blender/blenkernel/intern/mask.c
index 64902f0ee3e..027d5ba4826 100644
--- a/source/blender/blenkernel/intern/mask.c
+++ b/source/blender/blenkernel/intern/mask.c
@@ -414,7 +414,7 @@ typedef struct FeatherEdgesBucket {
 
 static void feather_bucket_add_edge(FeatherEdgesBucket *bucket, int start, int end)
 {
-	const int alloc_delta = 32;
+	const int alloc_delta = 256;
 
 	if (bucket->tot_segment >= bucket->alloc_segment) {
 		if (!bucket->segments) {
@@ -442,7 +442,7 @@ static void feather_bucket_check_intersect(float (*feather_points)[2], int tot_f
 	float *v1 = (float *) feather_points[cur_a];
 	float *v2 = (float *) feather_points[cur_b];
 
-	for (i = 0; i< bucket->tot_segment; i++) {
+	for (i = 0; i < bucket->tot_segment; i++) {
 		int check_a = bucket->segments[i][0];
 		int check_b = bucket->segments[i][1];
 
@@ -480,34 +480,51 @@ static void feather_bucket_check_intersect(float (*feather_points)[2], int tot_f
 	}
 }
 
-static int feather_bucket_index_from_coord(float co[2], float min[2], float max[2],
-                                           const int buckets_per_side, const float bucket_size)
+static int feather_bucket_index_from_coord(float co[2], const float min[2], const float bucket_scale[2],
+                                           const int buckets_per_side)
 {
-#define BUCKET_SIDE_INDEX(co, min, max) ((int) ((co - min) / (max - min) / bucket_size))
+	int x = (int) ((co[0] - min[0]) * bucket_scale[0]);
+	int y = (int) ((co[1] - min[1]) * bucket_scale[1]);
 
-	int x = BUCKET_SIDE_INDEX(co[0], min[0], max[0]);
-	int y = BUCKET_SIDE_INDEX(co[1], min[1], max[1]);
+	if (x == buckets_per_side)
+		x--;
 
-	x = MIN2(x, buckets_per_side - 1);
-	y = MIN2(y, buckets_per_side - 1);
+	if (y == buckets_per_side)
+		y--;
 
 	return y * buckets_per_side + x;
-#undef BUCKET_SIDE_INDEX
+}
+
+static void feather_bucket_get_diagonal(FeatherEdgesBucket *buckets, int start_bucket_index, int end_bucket_index,
+                                        int buckets_per_side, FeatherEdgesBucket **diagonal_bucket_a_r,
+                                        FeatherEdgesBucket **diagonal_bucket_b_r)
+{
+	int start_bucket_x = start_bucket_index % buckets_per_side;
+	int start_bucket_y = start_bucket_index / buckets_per_side;
+
+	int end_bucket_x = end_bucket_index % buckets_per_side;
+	int end_bucket_y = end_bucket_index / buckets_per_side;
+
+	int diagonal_bucket_a_index = start_bucket_y * buckets_per_side + end_bucket_x;
+	int diagonal_bucket_b_index = end_bucket_y * buckets_per_side + start_bucket_x;
+
+	*diagonal_bucket_a_r = &buckets[diagonal_bucket_a_index];
+	*diagonal_bucket_b_r = &buckets[diagonal_bucket_b_index];
 }
 
 static void spline_feather_collapse_inner_loops(float (*feather_points)[2], int tot_feather_point)
 {
 #define BUCKET_INDEX(co) \
-	feather_bucket_index_from_coord(co, min, max, buckets_per_side, bucket_size)
+	feather_bucket_index_from_coord(co, min, bucket_scale, buckets_per_side)
 
-	const int buckets_per_side = 10;
-	const int tot_bucket = buckets_per_side * buckets_per_side;
-	const float bucket_size = 1.0f / buckets_per_side;
+	int buckets_per_side, tot_bucket;
+	float bucket_size, bucket_scale[2];
 
 	FeatherEdgesBucket *buckets;
 
 	int i;
 	float min[2], max[2];
+	float max_delta_x = -1.0f, max_delta_y = -1.0f, max_delta;
 
 	if (tot_feather_point < 4) {
 		/* self-intersection works only for quads at least,
@@ -521,41 +538,95 @@ static void spline_feather_collapse_inner_loops(float (*feather_points)[2], int
 	INIT_MINMAX2(min, max);
 
 	for (i = 0; i < tot_feather_point; i++) {
+		int next = i + 1;
+		float delta;
+
+		if (next == tot_feather_point)
+			next = 0;
+
+		delta = fabsf(feather_points[i][0] - feather_points[next][0]);
+		if (delta > max_delta_x)
+			max_delta_x = delta;
+
+		delta = fabsf(feather_points[i][1] - feather_points[next][1]);
+		if (delta > max_delta_y)
+			max_delta_y = delta;
+
 		DO_MINMAX2(feather_points[i], min, max);
 	}
 
+	/* use dynamically calculated buckets per side, so we likely wouldn't
+	 * run into a situation when segment doesn't fit two buckets which is
+	 * pain collecting candidates for intersection
+	 */
+	max_delta_x /= max[0] - min[0];
+	max_delta_y /= max[1] - min[1];
+	max_delta = MAX2(max_delta_x, max_delta_y);
+
+	buckets_per_side = MIN2(512, 0.9f / max_delta);
+	tot_bucket = buckets_per_side * buckets_per_side;
+	bucket_size = 1.0f / buckets_per_side;
+
+	/* pre-compute multipliers, to save mathematical operations in loops */
+	bucket_scale[0] = 1.0f / ((max[0] - min[0]) * bucket_size);
+	bucket_scale[1] = 1.0f / ((max[1] - min[1]) * bucket_size);
+
 	/* fill in buckets' edges */
 	buckets = MEM_callocN(sizeof(FeatherEdgesBucket) * tot_bucket, "feather buckets");
 
 	for (i = 0; i < tot_feather_point; i++) {
-		int start = i;
-		int end = (i + 1) % tot_feather_point;
+		int start = i, end = i + 1;
+		int start_bucket_index, end_bucket_index;
 
-		int start_bucket_index = BUCKET_INDEX(feather_points[start]);
-		int end_bucket_index = BUCKET_INDEX(feather_points[end]);
+		if (end == tot_feather_point)
+			end = 0;
+
+		start_bucket_index = BUCKET_INDEX(feather_points[start]);
+		end_bucket_index = BUCKET_INDEX(feather_points[end]);
 
 		feather_bucket_add_edge(&buckets[start_bucket_index], start, end);
 
 		if (start_bucket_index != end_bucket_index) {
-			feather_bucket_add_edge(&buckets[end_bucket_index], start, end);
+			FeatherEdgesBucket *end_bucket = &buckets[end_bucket_index];
+			FeatherEdgesBucket *diagonal_bucket_a, *diagonal_bucket_b;
+
+			feather_bucket_get_diagonal(buckets, start_bucket_index, end_bucket_index, buckets_per_side,
+			                            &diagonal_bucket_a, &diagonal_bucket_b);
+
+			feather_bucket_add_edge(end_bucket, start, end);
+			feather_bucket_add_edge(diagonal_bucket_a, start, end);
+			feather_bucket_add_edge(diagonal_bucket_a, start, end);
 		}
 	}
 
 	/* check all edges for intersection with edges from their buckets */
 	for (i = 0; i < tot_feather_point; i++) {
-		int cur_a = i;
-		int cur_b = (i + 1) % tot_feather_point;
+		int cur_a = i, cur_b = i + 1;
+		int start_bucket_index, end_bucket_index;
 
-		int start_bucket_index = BUCKET_INDEX(feather_points[cur_a]);
-		int end_bucket_index = BUCKET_INDEX(feather_points[cur_b]);
+		FeatherEdgesBucket *start_bucket;
 
-		FeatherEdgesBucket *start_bucket = &buckets[start_bucket_index];
-		FeatherEdgesBucket *end_bucket = &buckets[end_bucket_index];
+		if (cur_b == tot_feather_point)
+			cur_b = 0;
+
+		start_bucket_index = BUCKET_INDEX(feather_points[cur_a]);
+		end_bucket_index = BUCKET_INDEX(feather_points[cur_b]);
+
+		start_bucket = &buckets[start_bucket_index];
 
 		feather_bucket_check_intersect(feather_points, tot_feather_point, start_bucket, cur_a, cur_b);
 
-		if (start_bucket != end_bucket)
+		if (start_bucket_index != end_bucket_index) {
+			FeatherEdgesBucket *end_bucket = &buckets[end_bucket_index];
+			FeatherEdgesBucket *diagonal_bucket_a, *diagonal_bucket_b;
+
+			feather_bucket_get_diagonal(buckets, start_bucket_index, end_bucket_index, buckets_per_side,
+			                            &diagonal_bucket_a, &diagonal_bucket_b);
+
 			feather_bucket_check_intersect(feather_points, tot_feather_point, end_bucket, cur_a, cur_b);
+			feather_bucket_check_intersect(feather_points, tot_feather_point, diagonal_bucket_a, cur_a, cur_b);
+			feather_bucket_check_intersect(feather_points, tot_feather_point, diagonal_bucket_b, cur_a, cur_b);
+		}
 	}
 
 	/* free buckets */

From 3d9637f60aa70b8e5b1633161f572715aaed9bc4 Mon Sep 17 00:00:00 2001
From: Bastien Montagne 
Date: Tue, 17 Jul 2012 17:55:23 +0000
Subject: [PATCH 065/108] Fix [#32133] Numpad Enter key doesnt work with
 Loopcut (worked in 2.49b)

Adding PADENTER to the "OK" keys...
---
 source/blender/editors/mesh/editmesh_loopcut.c  | 1 +
 source/blender/modifiers/intern/MOD_edgesplit.c | 2 +-
 2 files changed, 2 insertions(+), 1 deletion(-)

diff --git a/source/blender/editors/mesh/editmesh_loopcut.c b/source/blender/editors/mesh/editmesh_loopcut.c
index eb2aabd88b8..60c5244ddbc 100644
--- a/source/blender/editors/mesh/editmesh_loopcut.c
+++ b/source/blender/editors/mesh/editmesh_loopcut.c
@@ -447,6 +447,7 @@ static int loopcut_modal(bContext *C, wmOperator *op, wmEvent *event)
 
 	switch (event->type) {
 		case RETKEY:
+		case PADENTER:
 		case LEFTMOUSE: /* confirm */ // XXX hardcoded
 			if (event->val == KM_PRESS) {
 				/* finish */
diff --git a/source/blender/modifiers/intern/MOD_edgesplit.c b/source/blender/modifiers/intern/MOD_edgesplit.c
index 39d78f777a0..471317a279c 100644
--- a/source/blender/modifiers/intern/MOD_edgesplit.c
+++ b/source/blender/modifiers/intern/MOD_edgesplit.c
@@ -79,7 +79,7 @@ static DerivedMesh *doEdgeSplit(DerivedMesh *dm, EdgeSplitModifierData *emd, Obj
 			if ((l1 = e->l) &&
 			    (l2 = e->l->radial_next) != l1)
 			{
-				if (/* 3+ faces on thsi edge, always split */
+				if (/* 3+ faces on this edge, always split */
 				    UNLIKELY(l1 != l2->radial_next) ||
 				    /* 2 face edge - check angle*/
 				    (dot_v3v3(l1->f->no, l2->f->no) < threshold))

From 382ded688a31065b456ee213dc8756be6225b732 Mon Sep 17 00:00:00 2001
From: Bastien Montagne 
Date: Tue, 17 Jul 2012 18:14:59 +0000
Subject: [PATCH 066/108] Spellcheck: minkovsky -> minkowski! (Only in
 comments/UI messages :/ ).

---
 source/blender/blenlib/intern/noise.c             |  8 ++++----
 source/blender/makesrna/intern/rna_texture.c      | 14 +++++++-------
 source/blender/python/mathutils/mathutils_noise.c |  4 ++--
 3 files changed, 13 insertions(+), 13 deletions(-)

diff --git a/source/blender/blenlib/intern/noise.c b/source/blender/blenlib/intern/noise.c
index 859bb66073c..bd83c5e018c 100644
--- a/source/blender/blenlib/intern/noise.c
+++ b/source/blender/blenlib/intern/noise.c
@@ -1130,7 +1130,7 @@ static float turbulencep(float noisesize, float x, float y, float z, int nr)
 /* VORONOI/WORLEY */
 /******************/
 
-/* distance metrics for voronoi, e parameter only used in Minkovsky */
+/* distance metrics for voronoi, e parameter only used in Minkowski */
 /* Camberra omitted, didn't seem useful */
 
 /* distance squared */
@@ -1161,7 +1161,7 @@ static float dist_Chebychev(float x, float y, float z, float e)
 	return ((z > t) ? z : t);
 }
 
-/* minkovsky preset exponent 0.5 */
+/* minkowski preset exponent 0.5 */
 static float dist_MinkovskyH(float x, float y, float z, float e)
 {
 	float d = sqrtf(fabsf(x)) + sqrtf(fabsf(y)) + sqrtf(fabsf(z));
@@ -1169,7 +1169,7 @@ static float dist_MinkovskyH(float x, float y, float z, float e)
 	return (d * d);
 }
 
-/* minkovsky preset exponent 4 */
+/* minkowski preset exponent 4 */
 static float dist_Minkovsky4(float x, float y, float z, float e)
 {
 	(void)e;
@@ -1179,7 +1179,7 @@ static float dist_Minkovsky4(float x, float y, float z, float e)
 	return sqrtf(sqrtf(x * x + y * y + z * z));
 }
 
-/* Minkovsky, general case, slow, maybe too slow to be useful */
+/* Minkowski, general case, slow, maybe too slow to be useful */
 static float dist_Minkovsky(float x, float y, float z, float e)
 {
 	return powf(powf(fabsf(x), e) + powf(fabsf(y), e) + powf(fabsf(z), e), 1.0f / e);
diff --git a/source/blender/makesrna/intern/rna_texture.c b/source/blender/makesrna/intern/rna_texture.c
index 0270a7643a6..483e3ab7f8a 100644
--- a/source/blender/makesrna/intern/rna_texture.c
+++ b/source/blender/makesrna/intern/rna_texture.c
@@ -1443,12 +1443,12 @@ static void rna_def_texture_voronoi(BlenderRNA *brna)
 		                "The length of the distance in axial directions"},
 		{TEX_CHEBYCHEV, "CHEBYCHEV", 0, "Chebychev",
 		                "The length of the longest Axial journey"},
-		{TEX_MINKOVSKY_HALF, "MINKOVSKY_HALF", 0, "Minkovsky 1/2",
-		                     "Set Minkovsky variable to 0.5"},
-		{TEX_MINKOVSKY_FOUR, "MINKOVSKY_FOUR", 0, "Minkovsky 4",
-		                     "Set Minkovsky variable to 4"},
-		{TEX_MINKOVSKY, "MINKOVSKY", 0, "Minkovsky",
-		                "Use the Minkowsky function to calculate distance "
+		{TEX_MINKOVSKY_HALF, "MINKOVSKY_HALF", 0, "Minkowski 1/2",
+		                     "Set Minkowski variable to 0.5"},
+		{TEX_MINKOVSKY_FOUR, "MINKOVSKY_FOUR", 0, "Minkowski 4",
+		                     "Set Minkowski variable to 4"},
+		{TEX_MINKOVSKY, "MINKOVSKY", 0, "Minkowski",
+		                "Use the Minkowski function to calculate distance "
 		                "(exponent value determines the shape of the boundaries)"},
 		{0, NULL, 0, NULL, NULL}
 	};
@@ -1494,7 +1494,7 @@ static void rna_def_texture_voronoi(BlenderRNA *brna)
 	prop = RNA_def_property(srna, "minkovsky_exponent", PROP_FLOAT, PROP_NONE);
 	RNA_def_property_float_sdna(prop, NULL, "vn_mexp");
 	RNA_def_property_range(prop, 0.01, 10);
-	RNA_def_property_ui_text(prop, "Minkovsky Exponent", "Minkovsky exponent");
+	RNA_def_property_ui_text(prop, "Minkowski Exponent", "Minkowski exponent");
 	RNA_def_property_update(prop, 0, "rna_Texture_update");
 
 	prop = RNA_def_property(srna, "distance_metric", PROP_ENUM, PROP_NONE);
diff --git a/source/blender/python/mathutils/mathutils_noise.c b/source/blender/python/mathutils/mathutils_noise.c
index 9460c4d0b36..da32e36dc02 100644
--- a/source/blender/python/mathutils/mathutils_noise.c
+++ b/source/blender/python/mathutils/mathutils_noise.c
@@ -717,7 +717,7 @@ PyDoc_STRVAR(M_Noise_voronoi_doc,
 "   :type position: :class:`mathutils.Vector`\n"
 "   :arg distance_metric: Method of measuring distance.\n"
 "   :type distance_metric: Value in noise.distance_metrics or int\n"
-"   :arg exponent: The exponent for Minkovsky distance metric.\n"
+"   :arg exponent: The exponent for Minkowski distance metric.\n"
 "   :type exponent: float\n"
 "   :return: A list of distances to the four closest features and their locations.\n"
 "   :rtype: list of four floats, list of four :class:`mathutils.Vector` types\n"
@@ -729,7 +729,7 @@ static PyObject *M_Noise_voronoi(PyObject *UNUSED(self), PyObject *args)
 	float vec[3];
 	float da[4], pa[12];
 	int dtype = 0;
-	float me = 2.5f;  /* default minkovsky exponent */
+	float me = 2.5f;  /* default minkowski exponent */
 
 	int i;
 

From b6a9ffffedb9204edcaa4081f4ab8fb2b722ef9f Mon Sep 17 00:00:00 2001
From: Campbell Barton 
Date: Tue, 17 Jul 2012 20:01:01 +0000
Subject: [PATCH 067/108] wip mask capping - works but needs aspect correction
 and to be faded out.

---
 .../blenkernel/intern/mask_rasterize.c        | 154 ++++++++++++++++--
 1 file changed, 143 insertions(+), 11 deletions(-)

diff --git a/source/blender/blenkernel/intern/mask_rasterize.c b/source/blender/blenkernel/intern/mask_rasterize.c
index 69bc092a613..4de39816e2d 100644
--- a/source/blender/blenkernel/intern/mask_rasterize.c
+++ b/source/blender/blenkernel/intern/mask_rasterize.c
@@ -47,7 +47,7 @@
 
 #ifndef USE_RASKTER
 
-#define SPLINE_RESOL_CAP 32
+#define SPLINE_RESOL_CAP 4
 #define SPLINE_RESOL 32
 #define BUCKET_PIXELS_PER_CELL 8
 
@@ -57,6 +57,34 @@
 #define TRI_TERMINATOR_ID   ((unsigned int) -1)
 #define TRI_VERT            ((unsigned int) -1)
 
+/* for debugging add... */
+/* 	printf("%u %u %u %u\n", _t[0], _t[1], _t[2], _t[3]); \ */
+#define FACE_ASSERT(face, vert_max)                      \
+{                                                        \
+	unsigned int *_t = face;                             \
+	BLI_assert(_t[0] < vert_max);                        \
+	BLI_assert(_t[1] < vert_max);                        \
+	BLI_assert(_t[2] < vert_max || _t[2] == TRI_VERT);   \
+} (void)0
+
+void rotate_point(const float cent[2], const float angle, float p[2])
+{
+  const float s = sinf(angle);
+  const float c = cosf(angle);
+  float p_new[2];
+
+  /* translate point back to origin */
+  p[0] -= cent[0];
+  p[1] -= cent[1];
+
+  /* rotate point */
+  p_new[0] = p[0] * c - p[1] * s;
+  p_new[1] = p[0] * s + p[1] * c;
+
+  /* translate point back */
+  p[0] = p_new[0] + cent[0];
+  p[1] = p_new[1] + cent[1];
+}
 
 /* --------------------------------------------------------------------- */
 /* local structs for mask rasterizeing                                   */
@@ -690,10 +718,41 @@ void BKE_maskrasterize_handle_init(MaskRasterHandle *mr_handle, struct Mask *mas
 							tot_feather_quads -= 2;
 						}
 
-						/* ack these are infact tris, but they are extra faces so no matter,
-						 * +1 becausing adding one vert results in 2 tris (joining the existing endpoints)
-						 */
-						// tot_feather_quads + ((SPLINE_RESOL_CAP + 1) * 2);
+						/*cap ends */
+						if (!is_cyclic) {
+
+							unsigned int k;
+
+							for (k = 1; k < SPLINE_RESOL_CAP; k++) {
+								const float angle = (float)k * (1.0f / SPLINE_RESOL_CAP) * (float)M_PI;
+								copy_v2_v2(co_feather, diff_feather_points[0]);
+								rotate_point(diff_points[0], angle, co_feather);
+
+								sf_vert = BLI_scanfill_vert_add(&sf_ctx, co_feather);
+								sf_vert->tmp.u = sf_vert_tot;
+								sf_vert->keyindex = SF_KEYINDEX_TEMP_ID;
+								sf_vert_tot++;
+							}
+
+							tot_feather_quads += SPLINE_RESOL_CAP;
+
+							for (k = 1; k < SPLINE_RESOL_CAP; k++) {
+								const float angle = (float)k * (1.0f / SPLINE_RESOL_CAP) * (float)M_PI;
+								copy_v2_v2(co_feather, diff_feather_points[tot_diff_point - 1]);
+								rotate_point(diff_points[tot_diff_point - 1], -angle, co_feather);
+
+								sf_vert = BLI_scanfill_vert_add(&sf_ctx, co_feather);
+								sf_vert->tmp.u = sf_vert_tot;
+								sf_vert->keyindex = SF_KEYINDEX_TEMP_ID;
+								sf_vert_tot++;
+							}
+
+							tot_feather_quads += SPLINE_RESOL_CAP;
+
+
+						}
+
+						/* end capping */
 
 					}
 				}
@@ -742,14 +801,17 @@ void BKE_maskrasterize_handle_init(MaskRasterHandle *mr_handle, struct Mask *mas
 			sf_tri_tot = BLI_scanfill_calc_ex(&sf_ctx, FALSE, zvec);
 
 			face_array = MEM_mallocN(sizeof(*face_array) * (sf_tri_tot + tot_feather_quads), "maskrast_face_index");
+			face_index = 0;
 
 			/* tri's */
 			face = (unsigned int *)face_array;
-			for (sf_tri = sf_ctx.fillfacebase.first, face_index = 0; sf_tri; sf_tri = sf_tri->next, face_index++) {
+			for (sf_tri = sf_ctx.fillfacebase.first; sf_tri; sf_tri = sf_tri->next) {
 				*(face++) = sf_tri->v3->tmp.u;
 				*(face++) = sf_tri->v2->tmp.u;
 				*(face++) = sf_tri->v1->tmp.u;
 				*(face++) = TRI_VERT;
+				face_index++;
+				FACE_ASSERT(face - 4, sf_vert_tot);
 			}
 
 			/* start of feather faces... if we have this set,
@@ -766,8 +828,8 @@ void BKE_maskrasterize_handle_init(MaskRasterHandle *mr_handle, struct Mask *mas
 						*(face++) = sf_edge->v2->tmp.u;
 						*(face++) = sf_edge->v2->keyindex;
 						*(face++) = sf_edge->v1->keyindex;
-
 						face_index++;
+						FACE_ASSERT(face - 4, sf_vert_tot);
 					}
 				}
 			}
@@ -789,15 +851,15 @@ void BKE_maskrasterize_handle_init(MaskRasterHandle *mr_handle, struct Mask *mas
 					*(face++) = j + 0;                 /* z 1 */
 					*(face++) = j + 1;                 /* z 0 */
 					*(face++) = j + 4; /* next span */ /* z 0 */
-
 					face_index++;
+					FACE_ASSERT(face - 4, sf_vert_tot);
 
 					*(face++) = j + 0;                 /* z 1 */
 					*(face++) = j + 3; /* next span */ /* z 1 */
 					*(face++) = j + 5; /* next span */ /* z 0 */
 					*(face++) = j + 2;                 /* z 0 */
-
 					face_index++;
+					FACE_ASSERT(face - 4, sf_vert_tot);
 				}
 
 				if (open_spline_ranges[open_spline_index].is_cyclic) {
@@ -805,15 +867,85 @@ void BKE_maskrasterize_handle_init(MaskRasterHandle *mr_handle, struct Mask *mas
 					*(face++) = j          + 0;                 /* z 1 */
 					*(face++) = j          + 1;                 /* z 0 */
 					*(face++) = start_vidx + 1; /* next span */ /* z 0 */
-
 					face_index++;
+					FACE_ASSERT(face - 4, sf_vert_tot);
 
 					*(face++) = j          + 0;                 /* z 1 */
 					*(face++) = start_vidx + 0; /* next span */ /* z 1 */
 					*(face++) = start_vidx + 2; /* next span */ /* z 0 */
 					*(face++) = j          + 2;                 /* z 0 */
-
 					face_index++;
+					FACE_ASSERT(face - 4, sf_vert_tot);
+				}
+				else {
+					unsigned int midvidx = start_vidx;
+					// unsigned int repvidx;  /* repeat vertex index, ugh */
+
+					/***************
+					 * cap end 'a' */
+					j = midvidx + (open_spline_ranges[open_spline_index].vertex_total * 3);
+
+					for (k = 0; k < SPLINE_RESOL_CAP - 2; k++, j++) {
+						*(face++) = midvidx + 0;  /* z 1 */
+						*(face++) = j + 0;        /* z 0 */
+						*(face++) = j + 1;        /* z 0 */
+						*(face++) = TRI_VERT;
+						face_index++;
+						FACE_ASSERT(face - 4, sf_vert_tot);
+					}
+
+					j = start_vidx + (open_spline_ranges[open_spline_index].vertex_total * 3);
+
+					/* 2 tris that join the original */
+					*(face++) = midvidx + 0;  /* z 1 */
+					*(face++) = midvidx + 1;  /* z 0 */
+					*(face++) = j + 0;        /* z 0 */
+					*(face++) = TRI_VERT;
+					face_index++;
+					FACE_ASSERT(face - 4, sf_vert_tot);
+
+					*(face++) = midvidx + 0;               /* z 1 */
+					*(face++) = j + SPLINE_RESOL_CAP - 2;  /* z 0 */
+					*(face++) = midvidx + 2;               /* z 0 */
+					*(face++) = TRI_VERT;
+					face_index++;
+					FACE_ASSERT(face - 4, sf_vert_tot);
+
+
+					/***************
+					 * cap end 'b' */
+					/* ... same as previous but v 2-3 flipped, and different initial offsets */
+
+					j = start_vidx + (open_spline_ranges[open_spline_index].vertex_total * 3) + (SPLINE_RESOL_CAP - 1);
+
+					midvidx = start_vidx + (open_spline_ranges[open_spline_index].vertex_total * 3) - 3;
+
+					for (k = 0; k < SPLINE_RESOL_CAP - 2; k++, j++) {
+						*(face++) = midvidx;  /* z 1 */
+						*(face++) = j + 1;    /* z 0 */
+						*(face++) = j + 0;    /* z 0 */
+						*(face++) = TRI_VERT;
+						face_index++;
+						FACE_ASSERT(face - 4, sf_vert_tot);
+					}
+
+					j = start_vidx + (open_spline_ranges[open_spline_index].vertex_total * 3) + (SPLINE_RESOL_CAP - 1);
+
+					/* 2 tris that join the original */
+					*(face++) = midvidx + 0;  /* z 1 */
+					*(face++) = j + 0;        /* z 0 */
+					*(face++) = midvidx + 1;  /* z 0 */
+					*(face++) = TRI_VERT;
+					face_index++;
+					FACE_ASSERT(face - 4, sf_vert_tot);
+
+					*(face++) = midvidx + 0;               /* z 1 */
+					*(face++) = midvidx + 2;               /* z 0 */
+					*(face++) = j + SPLINE_RESOL_CAP - 2;  /* z 0 */
+					*(face++) = TRI_VERT;
+					face_index++;
+					FACE_ASSERT(face - 4, sf_vert_tot);
+
 				}
 			}
 

From 7baa8d520318479037e2032df6de83b4ed3015a7 Mon Sep 17 00:00:00 2001
From: Campbell Barton 
Date: Tue, 17 Jul 2012 20:40:12 +0000
Subject: [PATCH 068/108] mask rasterizer unfilled line end capping now works
 with aspect and blending.

---
 .../blenkernel/intern/mask_rasterize.c        | 62 ++++++++++++-------
 1 file changed, 38 insertions(+), 24 deletions(-)

diff --git a/source/blender/blenkernel/intern/mask_rasterize.c b/source/blender/blenkernel/intern/mask_rasterize.c
index 4de39816e2d..9ee10186861 100644
--- a/source/blender/blenkernel/intern/mask_rasterize.c
+++ b/source/blender/blenkernel/intern/mask_rasterize.c
@@ -47,7 +47,7 @@
 
 #ifndef USE_RASKTER
 
-#define SPLINE_RESOL_CAP 4
+#define SPLINE_RESOL_CAP 32
 #define SPLINE_RESOL 32
 #define BUCKET_PIXELS_PER_CELL 8
 
@@ -67,23 +67,26 @@
 	BLI_assert(_t[2] < vert_max || _t[2] == TRI_VERT);   \
 } (void)0
 
-void rotate_point(const float cent[2], const float angle, float p[2])
+void rotate_point(const float cent[2], const float angle, float p[2], const float asp[2])
 {
-  const float s = sinf(angle);
-  const float c = cosf(angle);
-  float p_new[2];
+	const float s = sinf(angle);
+	const float c = cosf(angle);
+	float p_new[2];
 
-  /* translate point back to origin */
-  p[0] -= cent[0];
-  p[1] -= cent[1];
+	/* translate point back to origin */
+	p[0] -= cent[0];
+	p[1] -= cent[1];
 
-  /* rotate point */
-  p_new[0] = p[0] * c - p[1] * s;
-  p_new[1] = p[0] * s + p[1] * c;
+	p[0] /= asp[0];
+	p[1] /= asp[1];
 
-  /* translate point back */
-  p[0] = p_new[0] + cent[0];
-  p[1] = p_new[1] + cent[1];
+	/* rotate point */
+	p_new[0] = ((p[0] * c) - (p[1] * s)) * asp[0];
+	p_new[1] = ((p[0] * s) + (p[1] * c)) * asp[1];
+
+	/* translate point back */
+	p[0] = p_new[0] + cent[0];
+	p[1] = p_new[1] + cent[1];
 }
 
 /* --------------------------------------------------------------------- */
@@ -720,13 +723,25 @@ void BKE_maskrasterize_handle_init(MaskRasterHandle *mr_handle, struct Mask *mas
 
 						/*cap ends */
 						if (!is_cyclic) {
-
 							unsigned int k;
 
+							float asp[2] = {1.0f, 1.0f};
+
+							if (do_aspect_correct) {
+								if (width != height) {
+									if (width < height) {
+										asp[1] = (float)width / (float)height;
+									}
+									else {
+										asp[0] = (float)height / (float)width;
+									}
+								}
+							}
+
 							for (k = 1; k < SPLINE_RESOL_CAP; k++) {
 								const float angle = (float)k * (1.0f / SPLINE_RESOL_CAP) * (float)M_PI;
 								copy_v2_v2(co_feather, diff_feather_points[0]);
-								rotate_point(diff_points[0], angle, co_feather);
+								rotate_point(diff_points[0], angle, co_feather, asp);
 
 								sf_vert = BLI_scanfill_vert_add(&sf_ctx, co_feather);
 								sf_vert->tmp.u = sf_vert_tot;
@@ -739,7 +754,7 @@ void BKE_maskrasterize_handle_init(MaskRasterHandle *mr_handle, struct Mask *mas
 							for (k = 1; k < SPLINE_RESOL_CAP; k++) {
 								const float angle = (float)k * (1.0f / SPLINE_RESOL_CAP) * (float)M_PI;
 								copy_v2_v2(co_feather, diff_feather_points[tot_diff_point - 1]);
-								rotate_point(diff_points[tot_diff_point - 1], -angle, co_feather);
+								rotate_point(diff_points[tot_diff_point - 1], -angle, co_feather, asp);
 
 								sf_vert = BLI_scanfill_vert_add(&sf_ctx, co_feather);
 								sf_vert->tmp.u = sf_vert_tot;
@@ -879,17 +894,16 @@ void BKE_maskrasterize_handle_init(MaskRasterHandle *mr_handle, struct Mask *mas
 				}
 				else {
 					unsigned int midvidx = start_vidx;
-					// unsigned int repvidx;  /* repeat vertex index, ugh */
 
 					/***************
 					 * cap end 'a' */
 					j = midvidx + (open_spline_ranges[open_spline_index].vertex_total * 3);
 
 					for (k = 0; k < SPLINE_RESOL_CAP - 2; k++, j++) {
+						*(face++) = midvidx + 0;  /* z 1 */
 						*(face++) = midvidx + 0;  /* z 1 */
 						*(face++) = j + 0;        /* z 0 */
 						*(face++) = j + 1;        /* z 0 */
-						*(face++) = TRI_VERT;
 						face_index++;
 						FACE_ASSERT(face - 4, sf_vert_tot);
 					}
@@ -898,16 +912,16 @@ void BKE_maskrasterize_handle_init(MaskRasterHandle *mr_handle, struct Mask *mas
 
 					/* 2 tris that join the original */
 					*(face++) = midvidx + 0;  /* z 1 */
+					*(face++) = midvidx + 0;  /* z 1 */
 					*(face++) = midvidx + 1;  /* z 0 */
 					*(face++) = j + 0;        /* z 0 */
-					*(face++) = TRI_VERT;
 					face_index++;
 					FACE_ASSERT(face - 4, sf_vert_tot);
 
+					*(face++) = midvidx + 0;               /* z 1 */
 					*(face++) = midvidx + 0;               /* z 1 */
 					*(face++) = j + SPLINE_RESOL_CAP - 2;  /* z 0 */
 					*(face++) = midvidx + 2;               /* z 0 */
-					*(face++) = TRI_VERT;
 					face_index++;
 					FACE_ASSERT(face - 4, sf_vert_tot);
 
@@ -921,10 +935,10 @@ void BKE_maskrasterize_handle_init(MaskRasterHandle *mr_handle, struct Mask *mas
 					midvidx = start_vidx + (open_spline_ranges[open_spline_index].vertex_total * 3) - 3;
 
 					for (k = 0; k < SPLINE_RESOL_CAP - 2; k++, j++) {
+						*(face++) = midvidx;  /* z 1 */
 						*(face++) = midvidx;  /* z 1 */
 						*(face++) = j + 1;    /* z 0 */
 						*(face++) = j + 0;    /* z 0 */
-						*(face++) = TRI_VERT;
 						face_index++;
 						FACE_ASSERT(face - 4, sf_vert_tot);
 					}
@@ -933,16 +947,16 @@ void BKE_maskrasterize_handle_init(MaskRasterHandle *mr_handle, struct Mask *mas
 
 					/* 2 tris that join the original */
 					*(face++) = midvidx + 0;  /* z 1 */
+					*(face++) = midvidx + 0;  /* z 1 */
 					*(face++) = j + 0;        /* z 0 */
 					*(face++) = midvidx + 1;  /* z 0 */
-					*(face++) = TRI_VERT;
 					face_index++;
 					FACE_ASSERT(face - 4, sf_vert_tot);
 
+					*(face++) = midvidx + 0;               /* z 1 */
 					*(face++) = midvidx + 0;               /* z 1 */
 					*(face++) = midvidx + 2;               /* z 0 */
 					*(face++) = j + SPLINE_RESOL_CAP - 2;  /* z 0 */
-					*(face++) = TRI_VERT;
 					face_index++;
 					FACE_ASSERT(face - 4, sf_vert_tot);
 

From 52d2bae2bfb40831590a1b2ff2050fc6f8414481 Mon Sep 17 00:00:00 2001
From: Mitchell Stokes 
Date: Wed, 18 Jul 2012 05:51:44 +0000
Subject: [PATCH 069/108] Fix for [#32129] "2D filter texture width off by
 one?" reported by Alex Fraser (z0r).

The GetWidth() and GetHeight() functions of the canvas' display area seem to give values that are both off by one for what OpenGL wants. Adding 1 to both values seems to fix the problem.
---
 .../gameengine/Rasterizer/RAS_2DFilterManager.cpp   | 13 +++++++------
 1 file changed, 7 insertions(+), 6 deletions(-)

diff --git a/source/gameengine/Rasterizer/RAS_2DFilterManager.cpp b/source/gameengine/Rasterizer/RAS_2DFilterManager.cpp
index cf6ea653402..097c2a9c824 100644
--- a/source/gameengine/Rasterizer/RAS_2DFilterManager.cpp
+++ b/source/gameengine/Rasterizer/RAS_2DFilterManager.cpp
@@ -324,8 +324,8 @@ void RAS_2DFilterManager::SetupTextures(bool depth, bool luminance)
 void RAS_2DFilterManager::UpdateOffsetMatrix(RAS_ICanvas* canvas)
 {
 	/* RAS_Rect canvas_rect = canvas->GetWindowArea(); */ /* UNUSED */
-	texturewidth = canvas->GetWidth();
-	textureheight = canvas->GetHeight();
+	texturewidth = canvas->GetWidth()+1;
+	textureheight = canvas->GetHeight()+1;
 	GLint i,j;
 
 	if (!GL_ARB_texture_non_power_of_two)
@@ -402,6 +402,7 @@ void RAS_2DFilterManager::RenderFilters(RAS_ICanvas* canvas)
 	GLuint	viewport[4]={0};
 	glGetIntegerv(GL_VIEWPORT,(GLint *)viewport);
 	RAS_Rect rect = canvas->GetWindowArea();
+	int rect_width = rect.GetWidth()+1, rect_height = rect.GetHeight()+1;
 
 	if (canvaswidth != canvas->GetWidth() || canvasheight != canvas->GetHeight())
 	{
@@ -419,19 +420,19 @@ void RAS_2DFilterManager::RenderFilters(RAS_ICanvas* canvas)
 	if (need_depth) {
 		glActiveTextureARB(GL_TEXTURE1);
 		glBindTexture(GL_TEXTURE_2D, texname[1]);
-		glCopyTexImage2D(GL_TEXTURE_2D,0,GL_DEPTH_COMPONENT, rect.GetLeft(), rect.GetBottom(), rect.GetWidth(), rect.GetHeight(), 0);
+		glCopyTexImage2D(GL_TEXTURE_2D,0,GL_DEPTH_COMPONENT, rect.GetLeft(), rect.GetBottom(), rect_width, rect_height, 0);
 	}
 	
 	if (need_luminance) {
 		glActiveTextureARB(GL_TEXTURE2);
 		glBindTexture(GL_TEXTURE_2D, texname[2]);
-		glCopyTexImage2D(GL_TEXTURE_2D,0,GL_LUMINANCE16, rect.GetLeft(), rect.GetBottom(), rect.GetWidth(), rect.GetHeight(), 0);
+		glCopyTexImage2D(GL_TEXTURE_2D,0,GL_LUMINANCE16, rect.GetLeft(), rect.GetBottom(), rect_width, rect_height, 0);
 	}
 
 	// reverting to texunit 0, without this we get bug [#28462]
 	glActiveTextureARB(GL_TEXTURE0);
 
-	glViewport(rect.GetLeft(), rect.GetBottom(), rect.GetWidth()+1, rect.GetHeight()+1);
+	glViewport(rect.GetLeft(), rect.GetBottom(), rect_width, rect.GetHeight()+1);
 
 	glDisable(GL_DEPTH_TEST);
 	// in case the previous material was wire
@@ -454,7 +455,7 @@ void RAS_2DFilterManager::RenderFilters(RAS_ICanvas* canvas)
 
 			glActiveTextureARB(GL_TEXTURE0);
 			glBindTexture(GL_TEXTURE_2D, texname[0]);
-			glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, rect.GetLeft(), rect.GetBottom(), rect.GetWidth(), rect.GetHeight(), 0); // Don't use texturewidth and textureheight in case we don't have NPOT support
+			glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, rect.GetLeft(), rect.GetBottom(), rect_width, rect_height, 0); // Don't use texturewidth and textureheight in case we don't have NPOT support
 			glClear(GL_COLOR_BUFFER_BIT);
 
 			glBegin(GL_QUADS);

From 64cc69cafc2fda9b70c40a1806abd371c7e80df1 Mon Sep 17 00:00:00 2001
From: Campbell Barton 
Date: Wed, 18 Jul 2012 08:13:30 +0000
Subject: [PATCH 070/108] adding objects active groups now gives menu of which
 group to add to.

---
 source/blender/editors/object/object_group.c | 165 ++++++++++---------
 1 file changed, 89 insertions(+), 76 deletions(-)

diff --git a/source/blender/editors/object/object_group.c b/source/blender/editors/object/object_group.c
index 7328cdbf9f2..3b9d54d76d6 100644
--- a/source/blender/editors/object/object_group.c
+++ b/source/blender/editors/object/object_group.c
@@ -59,57 +59,113 @@
 
 /********************* 3d view operators ***********************/
 
-static int objects_add_active_exec(bContext *C, wmOperator *op)
+/* can be called with C == NULL */
+static EnumPropertyItem *group_object_active_itemf(bContext *C, PointerRNA *UNUSED(ptr), PropertyRNA *UNUSED(prop), int *free)
 {
-	Main *bmain = CTX_data_main(C);
-	Scene *scene = CTX_data_scene(C);
-	Object *ob = OBACT;
-	Group *group;
-	int ok = 0, cycle = 0;
-	
-	if (!ob) return OPERATOR_CANCELLED;
-	
-	/* linking to same group requires its own loop so we can avoid
-	 * looking up the active objects groups each time */
+	Object *ob;
+	EnumPropertyItem *item = NULL, item_tmp = {0};
+	int totitem = 0;
 
-	for (group = bmain->group.first; group; group = group->id.next) {
-		if (object_in_group(ob, group)) {
-			/* Assign groups to selected objects */
-			CTX_DATA_BEGIN (C, Base *, base, selected_editable_bases)
-			{
-				if (base->object->dup_group != group)
-					add_to_group(group, base->object, scene, base);
-				else
-					cycle = 1;
-				ok = 1;
-			}
-			CTX_DATA_END;
+	if (C == NULL) {
+		return DummyRNA_NULL_items;
+	}
+
+	ob = ED_object_context(C);
+
+	/* check that the action exists */
+	if (ob) {
+		Group *group = NULL;
+		int i = 0;
+
+		while ((group = find_group(ob, group))) {
+			item_tmp.identifier = item_tmp.name = group->id.name + 2;
+			/* item_tmp.icon = ICON_ARMATURE_DATA; */
+			item_tmp.value = i;
+			RNA_enum_item_add(&item, &totitem, &item_tmp);
+			i++;
 		}
 	}
-	
-	if (!ok) BKE_report(op->reports, RPT_ERROR, "Active Object contains no groups");
+
+	RNA_enum_item_end(&item, &totitem);
+	*free = 1;
+
+	return item;
+}
+
+/* get the group back from the enum index, quite awkward and UI specific */
+static Group *group_object_active_find_index(Object *ob, const int group_object_index)
+{
+	Group *group = NULL;
+	int i = 0;
+	while ((group = find_group(ob, group))) {
+		if (i == group_object_index) {
+			break;
+		}
+		i++;
+	}
+
+	return group;
+}
+
+static int objects_add_active_exec(bContext *C, wmOperator *op)
+{
+	Object *ob = ED_object_context(C);
+	Main *bmain = CTX_data_main(C);
+	Scene *scene = CTX_data_scene(C);
+	int group_object_index = RNA_enum_get(op->ptr, "group");
+	int cycle = FALSE;
+
+	if (ob) {
+		Group *group = group_object_active_find_index(ob, group_object_index);
+
+		/* now add all selected objects from the group */
+		if (group) {
+
+			CTX_DATA_BEGIN (C, Base *, base, selected_editable_bases)
+			{
+				if (base->object->dup_group != group) {
+					add_to_group(group, base->object, scene, base);
+				}
+				else {
+					cycle = TRUE;
+				}
+			}
+			CTX_DATA_END;
+
+			DAG_scene_sort(bmain, scene);
+			WM_event_add_notifier(C, NC_GROUP | NA_EDITED, NULL);
+
+			return OPERATOR_FINISHED;
+		}
+	}
+
 	if (cycle)
 		BKE_report(op->reports, RPT_WARNING, "Skipped some groups because of cycle detected");
-	
-	DAG_scene_sort(bmain, scene);
-	WM_event_add_notifier(C, NC_GROUP | NA_EDITED, NULL);
-	
-	return OPERATOR_FINISHED;
+
+	return OPERATOR_CANCELLED;
 }
 
 void GROUP_OT_objects_add_active(wmOperatorType *ot)
 {
+	PropertyRNA *prop;
+
 	/* identifiers */
 	ot->name = "Add Selected To Active Group";
 	ot->description = "Add the object to an object group that contains the active object";
 	ot->idname = "GROUP_OT_objects_add_active";
 	
 	/* api callbacks */
-	ot->exec = objects_add_active_exec;	
+	ot->exec = objects_add_active_exec;
+	ot->invoke = WM_menu_invoke;
 	ot->poll = ED_operator_objectmode;
 
 	/* flags */
 	ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+
+	/* properties */
+	prop = RNA_def_enum(ot->srna, "group", DummyRNA_NULL_items, 0, "Group", "The group to add other selected objects to");
+	RNA_def_enum_funcs(prop, group_object_active_itemf);
+	ot->prop = prop;
 }
 
 static int objects_remove_active_exec(bContext *C, wmOperator *op)
@@ -202,17 +258,8 @@ static int group_objects_remove_exec(bContext *C, wmOperator *op)
 	Scene *scene = CTX_data_scene(C);
 	int group_object_index = RNA_enum_get(op->ptr, "group");
 
-	/* first get the group back from the enum index, quite awkward and UI specific */
 	if (ob) {
-		Group *group = NULL;
-		int i = 0;
-
-		while ((group = find_group(ob, group))) {
-			if (i == group_object_index) {
-				break;
-			}
-			i++;
-		}
+		Group *group = group_object_active_find_index(ob, group_object_index);
 
 		/* now remove all selected objects from the group */
 		if (group) {
@@ -233,40 +280,6 @@ static int group_objects_remove_exec(bContext *C, wmOperator *op)
 	return OPERATOR_CANCELLED;
 }
 
-
-/* can be called with C == NULL */
-static EnumPropertyItem *group_objects_remove_itemf(bContext *C, PointerRNA *UNUSED(ptr), PropertyRNA *UNUSED(prop), int *free)
-{
-	Object *ob;
-	EnumPropertyItem *item = NULL, item_tmp = {0};
-	int totitem = 0;
-
-	if (C == NULL) {
-		return DummyRNA_NULL_items;
-	}
-
-	ob = ED_object_context(C);
-
-	/* check that the action exists */
-	if (ob) {
-		Group *group = NULL;
-		int i = 0;
-
-		while ((group = find_group(ob, group))) {
-			item_tmp.identifier = item_tmp.name = group->id.name + 2;
-			/* item_tmp.icon = ICON_ARMATURE_DATA; */
-			item_tmp.value = i;
-			RNA_enum_item_add(&item, &totitem, &item_tmp);
-			i++;
-		}
-	}
-
-	RNA_enum_item_end(&item, &totitem);
-	*free = 1;
-
-	return item;
-}
-
 void GROUP_OT_objects_remove(wmOperatorType *ot)
 {
 	PropertyRNA *prop;
@@ -286,7 +299,7 @@ void GROUP_OT_objects_remove(wmOperatorType *ot)
 
 	/* properties */
 	prop = RNA_def_enum(ot->srna, "group", DummyRNA_NULL_items, 0, "Group", "The group to remove this object from");
-	RNA_def_enum_funcs(prop, group_objects_remove_itemf);
+	RNA_def_enum_funcs(prop, group_object_active_itemf);
 	ot->prop = prop;
 }
 

From e204d67cc79f2a7851611a4558ad95bb1b624859 Mon Sep 17 00:00:00 2001
From: Bastien Montagne 
Date: Wed, 18 Jul 2012 08:51:19 +0000
Subject: [PATCH 071/108] Fix [#32135] FRAMERATE: Framerate display is
 truncated in selection box.

Filename extension was striped twice...
---
 release/scripts/modules/bpy/path.py | 4 ----
 1 file changed, 4 deletions(-)

diff --git a/release/scripts/modules/bpy/path.py b/release/scripts/modules/bpy/path.py
index 7b54af944ad..f1313b583f7 100644
--- a/release/scripts/modules/bpy/path.py
+++ b/release/scripts/modules/bpy/path.py
@@ -133,9 +133,6 @@ def display_name(name):
     mixed case names are kept as is. Intended for use with
     filenames and module names.
     """
-
-    name = _os.path.splitext(name)[0]
-
     # string replacements
     name = name.replace("_colon_", ":")
 
@@ -154,7 +151,6 @@ def display_name_from_filepath(name):
     ensured to be utf8 compatible.
     """
 
-    name = _os.path.splitext(basename(name))[0]
     name = _clean_utf8(name)
     return name
 

From 88fddb3cc34e0e1fe8da6f038f2ed377684b2ea9 Mon Sep 17 00:00:00 2001
From: Campbell Barton 
Date: Wed, 18 Jul 2012 09:45:50 +0000
Subject: [PATCH 072/108] make links now allows groups - this means you can
 make objects have matching groups to the active more easily.

---
 source/blender/blenkernel/BKE_object.h        |  2 +
 source/blender/blenkernel/intern/object.c     | 31 +++++-
 source/blender/editors/object/object_group.c  | 13 ++-
 .../blender/editors/object/object_relations.c | 96 ++++++++++++++-----
 4 files changed, 108 insertions(+), 34 deletions(-)

diff --git a/source/blender/blenkernel/BKE_object.h b/source/blender/blenkernel/BKE_object.h
index b8ba3095905..3aa7148d821 100644
--- a/source/blender/blenkernel/BKE_object.h
+++ b/source/blender/blenkernel/BKE_object.h
@@ -177,6 +177,8 @@ typedef enum eObjectSet {
 } eObjectSet;
 
 struct LinkNode *BKE_object_relational_superset(struct Scene *scene, eObjectSet objectSet, eObRelationTypes includeFilter);
+struct LinkNode *BKE_object_groups(struct Object *ob);
+void             BKE_object_groups_clear(struct Scene *scene, struct Base *base, struct Object *object);
 
 #ifdef __cplusplus
 }
diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c
index a3145ddeedd..048560f3a83 100644
--- a/source/blender/blenkernel/intern/object.c
+++ b/source/blender/blenkernel/intern/object.c
@@ -3156,7 +3156,7 @@ static void obrel_list_add(LinkNode **links, Object *ob)
  * If OB_SET_VISIBLE or OB_SET_SELECTED are collected, 
  * then also add related objects according to the given includeFilters.
  */
-struct LinkNode *BKE_object_relational_superset(struct Scene *scene, eObjectSet objectSet, eObRelationTypes includeFilter)
+LinkNode *BKE_object_relational_superset(struct Scene *scene, eObjectSet objectSet, eObRelationTypes includeFilter)
 {
 	LinkNode *links = NULL;
 
@@ -3235,3 +3235,32 @@ struct LinkNode *BKE_object_relational_superset(struct Scene *scene, eObjectSet
 
 	return links;
 }
+
+/**
+ * return all groups this object is apart of, caller must free.
+ */
+struct LinkNode *BKE_object_groups(Object *ob)
+{
+	LinkNode *group_linknode = NULL;
+	Group *group = NULL;
+	while ((group = find_group(ob, group))) {
+		BLI_linklist_prepend(&group_linknode, group);
+	}
+
+	return group_linknode;
+}
+
+void BKE_object_groups_clear(Scene *scene, Base *base, Object *object)
+{
+	Group *group = NULL;
+
+	BLI_assert(base->object == object);
+
+	if (scene && base == NULL) {
+		base = BKE_scene_base_find(scene, object);
+	}
+
+	while ((group = find_group(base->object, group))) {
+		rem_from_group(group, object, scene, base);
+	}
+}
diff --git a/source/blender/editors/object/object_group.c b/source/blender/editors/object/object_group.c
index 3b9d54d76d6..e86a62f0dca 100644
--- a/source/blender/editors/object/object_group.c
+++ b/source/blender/editors/object/object_group.c
@@ -44,6 +44,7 @@
 #include "BKE_group.h"
 #include "BKE_main.h"
 #include "BKE_report.h"
+#include "BKE_object.h"
 
 #include "ED_screen.h"
 #include "ED_object.h"
@@ -113,7 +114,7 @@ static int objects_add_active_exec(bContext *C, wmOperator *op)
 	Main *bmain = CTX_data_main(C);
 	Scene *scene = CTX_data_scene(C);
 	int group_object_index = RNA_enum_get(op->ptr, "group");
-	int cycle = FALSE;
+	int is_cycle = FALSE;
 
 	if (ob) {
 		Group *group = group_object_active_find_index(ob, group_object_index);
@@ -127,7 +128,7 @@ static int objects_add_active_exec(bContext *C, wmOperator *op)
 					add_to_group(group, base->object, scene, base);
 				}
 				else {
-					cycle = TRUE;
+					is_cycle = TRUE;
 				}
 			}
 			CTX_DATA_END;
@@ -139,8 +140,9 @@ static int objects_add_active_exec(bContext *C, wmOperator *op)
 		}
 	}
 
-	if (cycle)
+	if (is_cycle) {
 		BKE_report(op->reports, RPT_WARNING, "Skipped some groups because of cycle detected");
+	}
 
 	return OPERATOR_CANCELLED;
 }
@@ -220,13 +222,10 @@ static int group_objects_remove_all_exec(bContext *C, wmOperator *UNUSED(op))
 {
 	Main *bmain = CTX_data_main(C);
 	Scene *scene = CTX_data_scene(C);
-	Group *group = NULL;
 
 	CTX_DATA_BEGIN (C, Base *, base, selected_editable_bases)
 	{
-		group = NULL;
-		while ((group = find_group(base->object, group)))
-			rem_from_group(group, base->object, scene, base);
+		BKE_object_groups_clear(scene, base, base->object);
 	}
 	CTX_DATA_END;
 
diff --git a/source/blender/editors/object/object_relations.c b/source/blender/editors/object/object_relations.c
index 860ff24cafd..d25e41898ea 100644
--- a/source/blender/editors/object/object_relations.c
+++ b/source/blender/editors/object/object_relations.c
@@ -50,6 +50,7 @@
 
 #include "BLI_math.h"
 #include "BLI_listbase.h"
+#include "BLI_linklist.h"
 #include "BLI_string.h"
 #include "BLI_utildefines.h"
 
@@ -64,6 +65,7 @@
 #include "BKE_DerivedMesh.h"
 #include "BKE_displist.h"
 #include "BKE_global.h"
+#include "BKE_group.h"
 #include "BKE_fcurve.h"
 #include "BKE_lamp.h"
 #include "BKE_lattice.h"
@@ -1277,14 +1279,15 @@ enum {
 	MAKE_LINKS_OBDATA = 1,
 	MAKE_LINKS_MATERIALS,
 	MAKE_LINKS_ANIMDATA,
+	MAKE_LINKS_GROUP,
 	MAKE_LINKS_DUPLIGROUP,
 	MAKE_LINKS_MODIFIERS
 };
 
 /* Return 1 if make link data is allow, zero otherwise */
-static int allow_make_links_data(int ev, Object *ob, Object *obt)
+static int allow_make_links_data(const int type, Object *ob, Object *obt)
 {
-	switch (ev) {
+	switch (type) {
 		case MAKE_LINKS_OBDATA:
 			if (ob->type == obt->type && ob->type != OB_EMPTY)
 				return 1;
@@ -1297,6 +1300,7 @@ static int allow_make_links_data(int ev, Object *ob, Object *obt)
 			}
 			break;
 		case MAKE_LINKS_ANIMDATA:
+		case MAKE_LINKS_GROUP:
 		case MAKE_LINKS_DUPLIGROUP:
 			return 1;
 		case MAKE_LINKS_MODIFIERS:
@@ -1310,52 +1314,81 @@ static int allow_make_links_data(int ev, Object *ob, Object *obt)
 static int make_links_data_exec(bContext *C, wmOperator *op)
 {
 	Main *bmain = CTX_data_main(C);
-	int event = RNA_enum_get(op->ptr, "type");
-	Object *ob;
+	Scene *scene = CTX_data_scene(C);
+	const int type = RNA_enum_get(op->ptr, "type");
+	Object *ob_src;
 	ID *id;
 	int a;
 
-	ob = ED_object_active_context(C);
+	/* group */
+	LinkNode *ob_groups = NULL;
+	int is_cycle = FALSE;
 
-	CTX_DATA_BEGIN (C, Object *, obt, selected_editable_objects)
+	ob_src = ED_object_active_context(C);
+
+	/* avoid searching all groups in source object each time */
+	if (type == MAKE_LINKS_GROUP) {
+		ob_groups = BKE_object_groups(ob_src);
+	}
+
+	CTX_DATA_BEGIN (C, Base *, base_dst, selected_editable_bases)
 	{
-		if (ob != obt) {
-			if (allow_make_links_data(event, ob, obt)) {
-				switch (event) {
+		Object *ob_dst = base_dst->object;
+
+		if (ob_src != ob_dst) {
+			if (allow_make_links_data(type, ob_src, ob_dst)) {
+				switch (type) {
 					case MAKE_LINKS_OBDATA: /* obdata */
-						id = obt->data;
+						id = ob_dst->data;
 						id->us--;
 
-						id = ob->data;
+						id = ob_src->data;
 						id_us_plus(id);
-						obt->data = id;
+						ob_dst->data = id;
 
 						/* if amount of material indices changed: */
-						test_object_materials(obt->data);
+						test_object_materials(ob_dst->data);
 
-						obt->recalc |= OB_RECALC_DATA;
+						ob_dst->recalc |= OB_RECALC_DATA;
 						break;
 					case MAKE_LINKS_MATERIALS:
 						/* new approach, using functions from kernel */
-						for (a = 0; a < ob->totcol; a++) {
-							Material *ma = give_current_material(ob, a + 1);
-							assign_material(obt, ma, a + 1); /* also works with ma==NULL */
+						for (a = 0; a < ob_src->totcol; a++) {
+							Material *ma = give_current_material(ob_src, a + 1);
+							assign_material(ob_dst, ma, a + 1); /* also works with ma==NULL */
 						}
 						break;
 					case MAKE_LINKS_ANIMDATA:
-						BKE_copy_animdata_id((ID *)obt, (ID *)ob, FALSE);
-						BKE_copy_animdata_id((ID *)obt->data, (ID *)ob->data, FALSE);
+						BKE_copy_animdata_id((ID *)ob_dst, (ID *)ob_src, FALSE);
+						BKE_copy_animdata_id((ID *)ob_dst->data, (ID *)ob_src->data, FALSE);
 						break;
+					case MAKE_LINKS_GROUP:
+					{
+						LinkNode *group_node;
+
+						/* first clear groups */
+						BKE_object_groups_clear(scene, base_dst, ob_dst);
+
+						/* now add in the groups from the link nodes */
+						for (group_node = ob_groups; group_node; group_node = group_node->next) {
+							if (ob_dst->dup_group != group_node->link) {
+								add_to_group(group_node->link, ob_dst, scene, base_dst);
+							}
+							else {
+								is_cycle = TRUE;
+							}
+						}
+					}
 					case MAKE_LINKS_DUPLIGROUP:
-						obt->dup_group = ob->dup_group;
-						if (obt->dup_group) {
-							id_lib_extern(&obt->dup_group->id);
-							obt->transflag |= OB_DUPLIGROUP;
+						ob_dst->dup_group = ob_src->dup_group;
+						if (ob_dst->dup_group) {
+							id_lib_extern(&ob_dst->dup_group->id);
+							ob_dst->transflag |= OB_DUPLIGROUP;
 						}
 						break;
 					case MAKE_LINKS_MODIFIERS:
-						BKE_object_link_modifiers(obt, ob);
-						obt->recalc |= OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME;
+						BKE_object_link_modifiers(ob_dst, ob_src);
+						ob_dst->recalc |= OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME;
 						break;
 				}
 			}
@@ -1363,7 +1396,17 @@ static int make_links_data_exec(bContext *C, wmOperator *op)
 	}
 	CTX_DATA_END;
 
-	DAG_scene_sort(bmain, CTX_data_scene(C));
+	if (type == MAKE_LINKS_GROUP) {
+		if (ob_groups) {
+			BLI_linklist_free(ob_groups, NULL);
+		}
+
+		if (is_cycle) {
+			BKE_report(op->reports, RPT_WARNING, "Skipped some groups because of cycle detected");
+		}
+	}
+
+	DAG_scene_sort(bmain, scene);
 	
 	DAG_ids_flush_update(bmain, 0);
 	WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, CTX_wm_view3d(C));
@@ -1400,6 +1443,7 @@ void OBJECT_OT_make_links_data(wmOperatorType *ot)
 		{MAKE_LINKS_OBDATA,     "OBDATA", 0, "Object Data", ""},
 		{MAKE_LINKS_MATERIALS,  "MATERIAL", 0, "Materials", ""},
 		{MAKE_LINKS_ANIMDATA,   "ANIMATION", 0, "Animation Data", ""},
+		{MAKE_LINKS_GROUP,      "GROUPS", 0, "Group", ""},
 		{MAKE_LINKS_DUPLIGROUP, "DUPLIGROUP", 0, "DupliGroup", ""},
 		{MAKE_LINKS_MODIFIERS,  "MODIFIERS", 0, "Modifiers", ""},
 		{0, NULL, 0, NULL, NULL}};

From 997850aeccb1f2c9f83c592ca41793908e050202 Mon Sep 17 00:00:00 2001
From: Sergey Sharybin 
Date: Wed, 18 Jul 2012 09:56:10 +0000
Subject: [PATCH 073/108] Fix #32132: Uniformly moving custom feather points
 does not work

---
 source/blender/editors/mask/mask_ops.c | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/source/blender/editors/mask/mask_ops.c b/source/blender/editors/mask/mask_ops.c
index 902d065e87b..c8246fd53bc 100644
--- a/source/blender/editors/mask/mask_ops.c
+++ b/source/blender/editors/mask/mask_ops.c
@@ -375,7 +375,7 @@ typedef struct SlidePointData {
 	MaskSplinePointUW *uw;
 	float handle[2], no[2], feather[2];
 	int width, height;
-	float weight;
+	float weight, weight_scalar;
 
 	short curvature_only, accurate;
 	short initial_feather, overall_feather;
@@ -460,6 +460,7 @@ static void *slide_point_customdata(bContext *C, wmOperator *op, wmEvent *event)
 			float weight_scalar = BKE_mask_point_weight_scalar(spline, point, uw->u);
 
 			customdata->weight = uw->w;
+			customdata->weight_scalar = weight_scalar;
 			BKE_mask_point_segment_co(spline, point, uw->u, co);
 			BKE_mask_point_normal(spline, point, uw->u, customdata->no);
 
@@ -469,6 +470,7 @@ static void *slide_point_customdata(bContext *C, wmOperator *op, wmEvent *event)
 			BezTriple *bezt = &point->bezt;
 
 			customdata->weight = bezt->weight;
+			customdata->weight_scalar = 1.0f;
 			BKE_mask_point_normal(spline, point, 0.0f, customdata->no);
 
 			madd_v2_v2v2fl(customdata->feather, bezt->vec[1], customdata->no, bezt->weight);
@@ -710,13 +712,13 @@ static int slide_point_modal(bContext *C, wmOperator *op, wmEvent *event)
 						if (dot_v2v2(no, vec) <= 0.0f)
 							w = -w;
 
-						delta = w - data->weight;
+						delta = w - data->weight * data->weight_scalar;
 
 						if (data->orig_spline == NULL) {
 							/* restore weight for currently sliding point, so orig_spline would be created
 							 * with original weights used
 							 */
-							*weight = data->weight * weight_scalar;
+							*weight = data->weight;
 
 							data->orig_spline = BKE_mask_spline_copy(data->spline);
 						}

From c05af6210e557f3868d3769d1a633d1bbbd63e54 Mon Sep 17 00:00:00 2001
From: Sergey Sharybin 
Date: Wed, 18 Jul 2012 10:22:56 +0000
Subject: [PATCH 074/108] Fixed crash of self-intersection loop in special
 cases

It was wrongly calculated bucket number per side in cases when some
of segments is filling the whole bounding box across some of dimension.

Solved by limiting buckets at least to 1 in such cases.
---
 source/blender/blenkernel/intern/mask.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/source/blender/blenkernel/intern/mask.c b/source/blender/blenkernel/intern/mask.c
index 027d5ba4826..77b404e627a 100644
--- a/source/blender/blenkernel/intern/mask.c
+++ b/source/blender/blenkernel/intern/mask.c
@@ -564,6 +564,13 @@ static void spline_feather_collapse_inner_loops(float (*feather_points)[2], int
 	max_delta = MAX2(max_delta_x, max_delta_y);
 
 	buckets_per_side = MIN2(512, 0.9f / max_delta);
+
+	if (buckets_per_side == 0) {
+		/* happens when some segment fills the whole bounding box across some of dimension */
+
+		buckets_per_side = 1;
+	}
+
 	tot_bucket = buckets_per_side * buckets_per_side;
 	bucket_size = 1.0f / buckets_per_side;
 

From 8f32070e9d29501853e7a4a11efea79005f8e4ec Mon Sep 17 00:00:00 2001
From: Campbell Barton 
Date: Wed, 18 Jul 2012 11:01:23 +0000
Subject: [PATCH 075/108] fix incorrect assert for mask face checking, also
 correct own bad spelling

---
 source/blender/blenkernel/intern/cdderivedmesh.c   |  2 +-
 source/blender/blenkernel/intern/mask_rasterize.c  | 11 ++++++-----
 source/blender/blenlib/intern/math_matrix.c        |  2 +-
 source/blender/editors/sculpt_paint/paint_image.c  |  4 ++--
 source/blender/windowmanager/intern/wm_operators.c |  2 +-
 5 files changed, 11 insertions(+), 10 deletions(-)

diff --git a/source/blender/blenkernel/intern/cdderivedmesh.c b/source/blender/blenkernel/intern/cdderivedmesh.c
index e5afc852846..b19b9db8749 100644
--- a/source/blender/blenkernel/intern/cdderivedmesh.c
+++ b/source/blender/blenkernel/intern/cdderivedmesh.c
@@ -2110,7 +2110,7 @@ void CDDM_calc_normals_mapping_ex(DerivedMesh *dm, const short only_face_normals
 		/* No tessellation on this mesh yet, need to calculate one.
 		 *
 		 * Important not to update face normals from polys since it
-		 * interfears with assigning the new normal layer in the following code.
+		 * interferes with assigning the new normal layer in the following code.
 		 */
 		CDDM_recalc_tessellation_ex(dm, FALSE);
 	}
diff --git a/source/blender/blenkernel/intern/mask_rasterize.c b/source/blender/blenkernel/intern/mask_rasterize.c
index 9ee10186861..9cdbc4205a3 100644
--- a/source/blender/blenkernel/intern/mask_rasterize.c
+++ b/source/blender/blenkernel/intern/mask_rasterize.c
@@ -64,7 +64,8 @@
 	unsigned int *_t = face;                             \
 	BLI_assert(_t[0] < vert_max);                        \
 	BLI_assert(_t[1] < vert_max);                        \
-	BLI_assert(_t[2] < vert_max || _t[2] == TRI_VERT);   \
+	BLI_assert(_t[2] < vert_max);                        \
+	BLI_assert(_t[3] < vert_max || _t[3] == TRI_VERT);   \
 } (void)0
 
 void rotate_point(const float cent[2], const float angle, float p[2], const float asp[2])
@@ -94,7 +95,7 @@ void rotate_point(const float cent[2], const float angle, float p[2], const floa
 /* --------------------------------------------------------------------- */
 
 /**
- * A single #MaskRasterHandle contains multile #MaskRasterLayer's,
+ * A single #MaskRasterHandle contains multiple #MaskRasterLayer's,
  * each #MaskRasterLayer does its own lookup which contributes to
  * the final pixel with its own blending mode and the final pixel
  * is blended between these.
@@ -801,7 +802,7 @@ void BKE_maskrasterize_handle_init(MaskRasterHandle *mr_handle, struct Mask *mas
 				sf_vert_next = sf_vert->next;
 				copy_v3_v3(cos, sf_vert->co);
 
-				/* remove so as not to interfear with fill (called after) */
+				/* remove so as not to interfere with fill (called after) */
 				if (sf_vert->keyindex == SF_KEYINDEX_TEMP_ID) {
 					BLI_remlink(&sf_ctx.fillvertbase, sf_vert);
 				}
@@ -812,13 +813,13 @@ void BKE_maskrasterize_handle_init(MaskRasterHandle *mr_handle, struct Mask *mas
 				cos += 3;
 			}
 
-			/* main scanfill */
+			/* main scan-fill */
 			sf_tri_tot = BLI_scanfill_calc_ex(&sf_ctx, FALSE, zvec);
 
 			face_array = MEM_mallocN(sizeof(*face_array) * (sf_tri_tot + tot_feather_quads), "maskrast_face_index");
 			face_index = 0;
 
-			/* tri's */
+			/* faces */
 			face = (unsigned int *)face_array;
 			for (sf_tri = sf_ctx.fillfacebase.first; sf_tri; sf_tri = sf_tri->next) {
 				*(face++) = sf_tri->v3->tmp.u;
diff --git a/source/blender/blenlib/intern/math_matrix.c b/source/blender/blenlib/intern/math_matrix.c
index f159a6b9d17..3fb3d2b58ff 100644
--- a/source/blender/blenlib/intern/math_matrix.c
+++ b/source/blender/blenlib/intern/math_matrix.c
@@ -1111,7 +1111,7 @@ void mat3_to_rot_size(float rot[3][3], float size[3], float mat3[3][3])
 	/* rotation & scale are linked, we need to create the mat's
 	 * for these together since they are related. */
 
-	/* so scale doesnt interfear with rotation [#24291] */
+	/* so scale doesn't interfere with rotation [#24291] */
 	/* note: this is a workaround for negative matrix not working for rotation conversion, FIXME */
 	normalize_m3_m3(mat3_n, mat3);
 	if (is_negative_m3(mat3)) {
diff --git a/source/blender/editors/sculpt_paint/paint_image.c b/source/blender/editors/sculpt_paint/paint_image.c
index 9746ba6dfa1..073e60ca87c 100644
--- a/source/blender/editors/sculpt_paint/paint_image.c
+++ b/source/blender/editors/sculpt_paint/paint_image.c
@@ -5241,7 +5241,7 @@ static void brush_drawcursor(bContext *C, int x, int y, void *UNUSED(customdata)
 			pixel_size = size;
 		}
 
-		/* fade out the brush (cheap trick to work around brush interfearing with sampling [#])*/
+		/* fade out the brush (cheap trick to work around brush interfering with sampling [#])*/
 		if (pixel_size < PX_SIZE_FADE_MIN) {
 			return;
 		}
@@ -5253,7 +5253,7 @@ static void brush_drawcursor(bContext *C, int x, int y, void *UNUSED(customdata)
 
 		glTranslatef((float)x, (float)y, 0.0f);
 
-		/* No need to scale for uv sculpting, on the contrary it might be useful to keep unscaled */
+		/* No need to scale for uv sculpting, on the contrary it might be useful to keep un-scaled */
 		if (use_zoom)
 			glScalef(zoomx, zoomy, 1.0f);
 
diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c
index d905d981134..a55efc0b216 100644
--- a/source/blender/windowmanager/intern/wm_operators.c
+++ b/source/blender/windowmanager/intern/wm_operators.c
@@ -1066,7 +1066,7 @@ static uiBlock *wm_block_dialog_create(bContext *C, ARegion *ar, void *userData)
 	/* clear so the OK button is left alone */
 	uiBlockSetFunc(block, NULL, NULL, NULL);
 
-	/* new column so as not to interfear with custom layouts [#26436] */
+	/* new column so as not to interfere with custom layouts [#26436] */
 	{
 		uiBlock *col_block;
 		uiLayout *col;

From e80918604a3dc4a0f2ad0ee91f5570ddb51c9cbb Mon Sep 17 00:00:00 2001
From: Sergey Sharybin 
Date: Wed, 18 Jul 2012 11:48:13 +0000
Subject: [PATCH 076/108] Fixed wrong self-intersection check for non-closed
 splines

---
 source/blender/blenkernel/intern/mask.c | 20 ++++++++++++++------
 1 file changed, 14 insertions(+), 6 deletions(-)

diff --git a/source/blender/blenkernel/intern/mask.c b/source/blender/blenkernel/intern/mask.c
index 77b404e627a..fa11721a944 100644
--- a/source/blender/blenkernel/intern/mask.c
+++ b/source/blender/blenkernel/intern/mask.c
@@ -512,7 +512,7 @@ static void feather_bucket_get_diagonal(FeatherEdgesBucket *buckets, int start_b
 	*diagonal_bucket_b_r = &buckets[diagonal_bucket_b_index];
 }
 
-static void spline_feather_collapse_inner_loops(float (*feather_points)[2], int tot_feather_point)
+static void spline_feather_collapse_inner_loops(MaskSpline *spline, float (*feather_points)[2], int tot_feather_point)
 {
 #define BUCKET_INDEX(co) \
 	feather_bucket_index_from_coord(co, min, bucket_scale, buckets_per_side)
@@ -541,8 +541,12 @@ static void spline_feather_collapse_inner_loops(float (*feather_points)[2], int
 		int next = i + 1;
 		float delta;
 
-		if (next == tot_feather_point)
-			next = 0;
+		if (next == tot_feather_point) {
+			if (spline->flag & MASK_SPLINE_CYCLIC)
+				next = 0;
+			else
+				break;
+		}
 
 		delta = fabsf(feather_points[i][0] - feather_points[next][0]);
 		if (delta > max_delta_x)
@@ -585,8 +589,12 @@ static void spline_feather_collapse_inner_loops(float (*feather_points)[2], int
 		int start = i, end = i + 1;
 		int start_bucket_index, end_bucket_index;
 
-		if (end == tot_feather_point)
-			end = 0;
+		if (end == tot_feather_point) {
+			if (spline->flag & MASK_SPLINE_CYCLIC)
+				end = 0;
+			else
+				break;
+		}
 
 		start_bucket_index = BUCKET_INDEX(feather_points[start]);
 		end_bucket_index = BUCKET_INDEX(feather_points[end]);
@@ -718,7 +726,7 @@ float (*BKE_mask_spline_feather_differentiated_points_with_resolution_ex(MaskSpl
 
 	/* this is slow! - don't do on draw */
 	if (do_collapse) {
-		spline_feather_collapse_inner_loops(feather, tot);
+		spline_feather_collapse_inner_loops(spline, feather, tot);
 	}
 
 	return feather;

From eceec8856d6b28c48022a927d6281dd583bb7880 Mon Sep 17 00:00:00 2001
From: Campbell Barton 
Date: Wed, 18 Jul 2012 12:17:12 +0000
Subject: [PATCH 077/108] minor edits to mask rasterizer.

---
 .../blenkernel/intern/mask_rasterize.c        | 116 ++++++++++--------
 1 file changed, 68 insertions(+), 48 deletions(-)

diff --git a/source/blender/blenkernel/intern/mask_rasterize.c b/source/blender/blenkernel/intern/mask_rasterize.c
index 9cdbc4205a3..d6c82017dd9 100644
--- a/source/blender/blenkernel/intern/mask_rasterize.c
+++ b/source/blender/blenkernel/intern/mask_rasterize.c
@@ -48,6 +48,7 @@
 #ifndef USE_RASKTER
 
 #define SPLINE_RESOL_CAP 32
+#define SPLINE_RESOL_CAP_PER_PIXEL 10
 #define SPLINE_RESOL 32
 #define BUCKET_PIXELS_PER_CELL 8
 
@@ -68,26 +69,28 @@
 	BLI_assert(_t[3] < vert_max || _t[3] == TRI_VERT);   \
 } (void)0
 
-void rotate_point(const float cent[2], const float angle, float p[2], const float asp[2])
+static void rotate_point_v2(float r_p[2], const float p[2], const float cent[2], const float angle, const float asp[2])
 {
 	const float s = sinf(angle);
 	const float c = cosf(angle);
 	float p_new[2];
 
 	/* translate point back to origin */
-	p[0] -= cent[0];
-	p[1] -= cent[1];
-
-	p[0] /= asp[0];
-	p[1] /= asp[1];
+	r_p[0] = (p[0] - cent[0]) / asp[0];
+	r_p[1] = (p[1] - cent[1]) / asp[1];
 
 	/* rotate point */
-	p_new[0] = ((p[0] * c) - (p[1] * s)) * asp[0];
-	p_new[1] = ((p[0] * s) + (p[1] * c)) * asp[1];
+	p_new[0] = ((r_p[0] * c) - (r_p[1] * s)) * asp[0];
+	p_new[1] = ((r_p[0] * s) + (r_p[1] * c)) * asp[1];
 
 	/* translate point back */
-	p[0] = p_new[0] + cent[0];
-	p[1] = p_new[1] + cent[1];
+	r_p[0] = p_new[0] + cent[0];
+	r_p[1] = p_new[1] + cent[1];
+}
+
+BLI_INLINE unsigned int clampis_uint(const unsigned int v, const unsigned int min, const unsigned int max)
+{
+	return v < min ? min : (v > max ? max : v);
 }
 
 /* --------------------------------------------------------------------- */
@@ -131,8 +134,14 @@ typedef struct MaskRasterLayer {
 } MaskRasterLayer;
 
 typedef struct MaskRasterSplineInfo {
+	/* body of the spline */
 	unsigned int vertex_offset;
 	unsigned int vertex_total;
+
+	/* capping for non-filled, non cyclic splines */
+	unsigned int vertex_total_cap_head;
+	unsigned int vertex_total_cap_tail;
+
 	unsigned int is_cyclic;
 } MaskRasterSplineInfo;
 
@@ -503,6 +512,8 @@ void BKE_maskrasterize_handle_init(MaskRasterHandle *mr_handle, struct Mask *mas
 {
 	const rctf default_bounds = {0.0f, 1.0f, 0.0f, 1.0f};
 	const float pixel_size = 1.0f / MIN2(width, height);
+	const float asp_xy[2] = {(do_aspect_correct && width > height) ? (float)height / (float)width  : 1.0f,
+	                         (do_aspect_correct && width < height) ? (float)width  / (float)height : 1.0f};
 
 	const float zvec[3] = {0.0f, 0.0f, 1.0f};
 	MaskLayer *masklay;
@@ -684,9 +695,6 @@ void BKE_maskrasterize_handle_init(MaskRasterHandle *mr_handle, struct Mask *mas
 
 						open_spline_ranges[open_spline_index].vertex_offset = sf_vert_tot;
 						open_spline_ranges[open_spline_index].vertex_total = tot_diff_point;
-						open_spline_ranges[open_spline_index].is_cyclic = is_cyclic;
-						open_spline_index++;
-
 
 						/* TODO, an alternate functions so we can avoid double vector copy! */
 						for (j = 0; j < tot_diff_point; j++) {
@@ -722,52 +730,64 @@ void BKE_maskrasterize_handle_init(MaskRasterHandle *mr_handle, struct Mask *mas
 							tot_feather_quads -= 2;
 						}
 
-						/*cap ends */
+						/* cap ends */
+
+						/* dummy init value */
+						open_spline_ranges[open_spline_index].vertex_total_cap_head = 0;
+						open_spline_ranges[open_spline_index].vertex_total_cap_tail = 0;
+
 						if (!is_cyclic) {
+							float *fp_cent;
+							float *fp_turn;
+
 							unsigned int k;
 
-							float asp[2] = {1.0f, 1.0f};
+							fp_cent = diff_points[0];
+							fp_turn = diff_feather_points[0];
 
-							if (do_aspect_correct) {
-								if (width != height) {
-									if (width < height) {
-										asp[1] = (float)width / (float)height;
-									}
-									else {
-										asp[0] = (float)height / (float)width;
-									}
+							{
+								unsigned int vertex_total_cap = clampis_uint(SPLINE_RESOL_CAP_PER_PIXEL * (len_v2v2(fp_cent, fp_turn) * pixel_size), 8, 128);
+								vertex_total_cap = 32;
+
+								for (k = 1; k < vertex_total_cap; k++) {
+									const float angle = (float)k * (1.0f / vertex_total_cap) * (float)M_PI;
+									rotate_point_v2(co_feather, fp_turn, fp_cent, angle, asp_xy);
+
+									sf_vert = BLI_scanfill_vert_add(&sf_ctx, co_feather);
+									sf_vert->tmp.u = sf_vert_tot;
+									sf_vert->keyindex = SF_KEYINDEX_TEMP_ID;
+									sf_vert_tot++;
 								}
+								tot_feather_quads += vertex_total_cap;
+
+								open_spline_ranges[open_spline_index].vertex_total_cap_head = vertex_total_cap;
 							}
 
-							for (k = 1; k < SPLINE_RESOL_CAP; k++) {
-								const float angle = (float)k * (1.0f / SPLINE_RESOL_CAP) * (float)M_PI;
-								copy_v2_v2(co_feather, diff_feather_points[0]);
-								rotate_point(diff_points[0], angle, co_feather, asp);
+							fp_cent = diff_points[tot_diff_point - 1];
+							fp_turn = diff_feather_points[tot_diff_point - 1];
 
-								sf_vert = BLI_scanfill_vert_add(&sf_ctx, co_feather);
-								sf_vert->tmp.u = sf_vert_tot;
-								sf_vert->keyindex = SF_KEYINDEX_TEMP_ID;
-								sf_vert_tot++;
+							{
+								unsigned int vertex_total_cap = clampis_uint(SPLINE_RESOL_CAP_PER_PIXEL * (len_v2v2(fp_cent, fp_turn) * pixel_size), 8, 128);
+								vertex_total_cap = 32;
+
+								for (k = 1; k < vertex_total_cap; k++) {
+									const float angle = (float)k * (1.0f / vertex_total_cap) * (float)M_PI;
+									rotate_point_v2(co_feather, fp_turn, fp_cent, angle, asp_xy);
+
+									sf_vert = BLI_scanfill_vert_add(&sf_ctx, co_feather);
+									sf_vert->tmp.u = sf_vert_tot;
+									sf_vert->keyindex = SF_KEYINDEX_TEMP_ID;
+									sf_vert_tot++;
+								}
+								tot_feather_quads += vertex_total_cap;
+
+								open_spline_ranges[open_spline_index].vertex_total_cap_tail = vertex_total_cap;
 							}
-
-							tot_feather_quads += SPLINE_RESOL_CAP;
-
-							for (k = 1; k < SPLINE_RESOL_CAP; k++) {
-								const float angle = (float)k * (1.0f / SPLINE_RESOL_CAP) * (float)M_PI;
-								copy_v2_v2(co_feather, diff_feather_points[tot_diff_point - 1]);
-								rotate_point(diff_points[tot_diff_point - 1], -angle, co_feather, asp);
-
-								sf_vert = BLI_scanfill_vert_add(&sf_ctx, co_feather);
-								sf_vert->tmp.u = sf_vert_tot;
-								sf_vert->keyindex = SF_KEYINDEX_TEMP_ID;
-								sf_vert_tot++;
-							}
-
-							tot_feather_quads += SPLINE_RESOL_CAP;
-
-
 						}
 
+						open_spline_ranges[open_spline_index].is_cyclic = is_cyclic;
+						open_spline_index++;
+
 						/* end capping */
 
 					}

From e1449e3626e7b7ede2f0a1c3288e3e66cfff200b Mon Sep 17 00:00:00 2001
From: Bastien Montagne 
Date: Wed, 18 Jul 2012 12:23:18 +0000
Subject: [PATCH 078/108] Fix [#32068] Edge slide not working in certain
 circumstance from Front / Side views

Only visible edges are used to create the "sliding vector". The test used to detect whether edges were visible or not was working for solid shading, but useless in wire draw mode (as all edges are visible in this mode!)...
---
 source/blender/editors/transform/transform.c | 17 ++++++++++-------
 1 file changed, 10 insertions(+), 7 deletions(-)

diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c
index e2752f5e828..8eb2371a598 100644
--- a/source/blender/editors/transform/transform.c
+++ b/source/blender/editors/transform/transform.c
@@ -4706,7 +4706,7 @@ static int createSlideVerts(TransInfo *t)
 	float projectMat[4][4];
 	float mval[2] = {(float)t->mval[0], (float)t->mval[1]};
 	float start[3] = {0.0f, 0.0f, 0.0f}, dir[3], end[3] = {0.0f, 0.0f, 0.0f};
-	float vec[3], vec2[3], lastvec[3] /*, size, dis=0.0, z */ /* UNUSED */;
+	float vec[3], vec2[3] /*, lastvec[3], size, dis=0.0, z */ /* UNUSED */;
 	int numsel, i, j;
 
 	if (t->spacetype == SPACE_VIEW3D) {
@@ -4894,7 +4894,7 @@ static int createSlideVerts(TransInfo *t)
 		} while (e != first->e && l1);
 	}
 
-	//EDBM_flag_disable_all(em, BM_ELEM_SELECT);
+	/* EDBM_flag_disable_all(em, BM_ELEM_SELECT); */
 
 	sld->sv = sv_array;
 	sld->totsv = j;
@@ -4902,14 +4902,15 @@ static int createSlideVerts(TransInfo *t)
 	/*find mouse vector*/
 	/* dis = z = -1.0f; */ /* UNUSED */
 	/* size = 50.0; */ /* UNUSED */
-	zero_v3(lastvec); zero_v3(dir);
+	/* zero_v3(lastvec); */ /* UNUSED */
+	zero_v3(dir);
 	/* ee = le = NULL; */ /* UNUSED */
 	BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) {
 		if (BM_elem_flag_test(e, BM_ELEM_SELECT)) {
 			BMIter iter2;
 			BMEdge *e2;
 			float vec1[3], dis2, mval[2] = {t->mval[0], t->mval[1]}, d;
-						
+
 			/* search cross edges for visible edge to the mouse cursor,
 			 * then use the shared vertex to calculate screen vector*/
 			dis2 = -1.0f;
@@ -4918,10 +4919,12 @@ static int createSlideVerts(TransInfo *t)
 				BM_ITER_ELEM (e2, &iter2, v, BM_EDGES_OF_VERT) {
 					if (BM_elem_flag_test(e2, BM_ELEM_SELECT))
 						continue;
-					
-					if (v3d && !BMBVH_EdgeVisible(btree, e2, ar, v3d, t->obedit))
+
+					/* This test is only relevant if object is not wire-dranw! See [#32068]. */
+					if (v3d && t->obedit->dt > OB_WIRE && v3d->drawtype > OB_WIRE &&
+					    !BMBVH_EdgeVisible(btree, e2, ar, v3d, t->obedit))
 						continue;
-					
+
 					j = GET_INT_FROM_POINTER(BLI_smallhash_lookup(&table, (uintptr_t)v));
 
 					if (sv_array[j].down) {

From 61ef13752dc012db45b60606a4c04fbde8839ac0 Mon Sep 17 00:00:00 2001
From: Campbell Barton 
Date: Wed, 18 Jul 2012 12:45:20 +0000
Subject: [PATCH 079/108] chance semi-circle mask capping resolution based on
 size.

---
 .../blenkernel/intern/mask_rasterize.c        | 32 +++++++++++--------
 1 file changed, 19 insertions(+), 13 deletions(-)

diff --git a/source/blender/blenkernel/intern/mask_rasterize.c b/source/blender/blenkernel/intern/mask_rasterize.c
index d6c82017dd9..94d6ad0ab6e 100644
--- a/source/blender/blenkernel/intern/mask_rasterize.c
+++ b/source/blender/blenkernel/intern/mask_rasterize.c
@@ -47,8 +47,10 @@
 
 #ifndef USE_RASKTER
 
-#define SPLINE_RESOL_CAP 32
-#define SPLINE_RESOL_CAP_PER_PIXEL 10
+//#define SPLINE_RESOL_CAP 32
+#define SPLINE_RESOL_CAP_PER_PIXEL 2
+#define SPLINE_RESOL_CAP_MIN 8
+#define SPLINE_RESOL_CAP_MAX 64
 #define SPLINE_RESOL 32
 #define BUCKET_PIXELS_PER_CELL 8
 
@@ -745,9 +747,13 @@ void BKE_maskrasterize_handle_init(MaskRasterHandle *mr_handle, struct Mask *mas
 							fp_cent = diff_points[0];
 							fp_turn = diff_feather_points[0];
 
+#define CALC_CAP_RESOL                                                                      \
+	clampis_uint((len_v2v2(fp_cent, fp_turn) / (pixel_size * SPLINE_RESOL_CAP_PER_PIXEL)),  \
+	             SPLINE_RESOL_CAP_MIN,                                                      \
+	             SPLINE_RESOL_CAP_MAX)
+
 							{
-								unsigned int vertex_total_cap = clampis_uint(SPLINE_RESOL_CAP_PER_PIXEL * (len_v2v2(fp_cent, fp_turn) * pixel_size), 8, 128);
-								vertex_total_cap = 32;
+								const unsigned int vertex_total_cap = CALC_CAP_RESOL;
 
 								for (k = 1; k < vertex_total_cap; k++) {
 									const float angle = (float)k * (1.0f / vertex_total_cap) * (float)M_PI;
@@ -767,12 +773,11 @@ void BKE_maskrasterize_handle_init(MaskRasterHandle *mr_handle, struct Mask *mas
 							fp_turn = diff_feather_points[tot_diff_point - 1];
 
 							{
-								unsigned int vertex_total_cap = clampis_uint(SPLINE_RESOL_CAP_PER_PIXEL * (len_v2v2(fp_cent, fp_turn) * pixel_size), 8, 128);
-								vertex_total_cap = 32;
+								const unsigned int vertex_total_cap = CALC_CAP_RESOL;
 
 								for (k = 1; k < vertex_total_cap; k++) {
 									const float angle = (float)k * (1.0f / vertex_total_cap) * (float)M_PI;
-									rotate_point_v2(co_feather, fp_turn, fp_cent, angle, asp_xy);
+									rotate_point_v2(co_feather, fp_turn, fp_cent, -angle, asp_xy);
 
 									sf_vert = BLI_scanfill_vert_add(&sf_ctx, co_feather);
 									sf_vert->tmp.u = sf_vert_tot;
@@ -788,6 +793,7 @@ void BKE_maskrasterize_handle_init(MaskRasterHandle *mr_handle, struct Mask *mas
 						open_spline_ranges[open_spline_index].is_cyclic = is_cyclic;
 						open_spline_index++;
 
+#undef CALC_CAP_RESOL
 						/* end capping */
 
 					}
@@ -920,7 +926,7 @@ void BKE_maskrasterize_handle_init(MaskRasterHandle *mr_handle, struct Mask *mas
 					 * cap end 'a' */
 					j = midvidx + (open_spline_ranges[open_spline_index].vertex_total * 3);
 
-					for (k = 0; k < SPLINE_RESOL_CAP - 2; k++, j++) {
+					for (k = 0; k < open_spline_ranges[open_spline_index].vertex_total_cap_head - 2; k++, j++) {
 						*(face++) = midvidx + 0;  /* z 1 */
 						*(face++) = midvidx + 0;  /* z 1 */
 						*(face++) = j + 0;        /* z 0 */
@@ -941,7 +947,7 @@ void BKE_maskrasterize_handle_init(MaskRasterHandle *mr_handle, struct Mask *mas
 
 					*(face++) = midvidx + 0;               /* z 1 */
 					*(face++) = midvidx + 0;               /* z 1 */
-					*(face++) = j + SPLINE_RESOL_CAP - 2;  /* z 0 */
+					*(face++) = j + open_spline_ranges[open_spline_index].vertex_total_cap_head - 2;  /* z 0 */
 					*(face++) = midvidx + 2;               /* z 0 */
 					face_index++;
 					FACE_ASSERT(face - 4, sf_vert_tot);
@@ -951,11 +957,11 @@ void BKE_maskrasterize_handle_init(MaskRasterHandle *mr_handle, struct Mask *mas
 					 * cap end 'b' */
 					/* ... same as previous but v 2-3 flipped, and different initial offsets */
 
-					j = start_vidx + (open_spline_ranges[open_spline_index].vertex_total * 3) + (SPLINE_RESOL_CAP - 1);
+					j = start_vidx + (open_spline_ranges[open_spline_index].vertex_total * 3) + (open_spline_ranges[open_spline_index].vertex_total_cap_head - 1);
 
 					midvidx = start_vidx + (open_spline_ranges[open_spline_index].vertex_total * 3) - 3;
 
-					for (k = 0; k < SPLINE_RESOL_CAP - 2; k++, j++) {
+					for (k = 0; k < open_spline_ranges[open_spline_index].vertex_total_cap_tail - 2; k++, j++) {
 						*(face++) = midvidx;  /* z 1 */
 						*(face++) = midvidx;  /* z 1 */
 						*(face++) = j + 1;    /* z 0 */
@@ -964,7 +970,7 @@ void BKE_maskrasterize_handle_init(MaskRasterHandle *mr_handle, struct Mask *mas
 						FACE_ASSERT(face - 4, sf_vert_tot);
 					}
 
-					j = start_vidx + (open_spline_ranges[open_spline_index].vertex_total * 3) + (SPLINE_RESOL_CAP - 1);
+					j = start_vidx + (open_spline_ranges[open_spline_index].vertex_total * 3) + (open_spline_ranges[open_spline_index].vertex_total_cap_head - 1);
 
 					/* 2 tris that join the original */
 					*(face++) = midvidx + 0;  /* z 1 */
@@ -977,7 +983,7 @@ void BKE_maskrasterize_handle_init(MaskRasterHandle *mr_handle, struct Mask *mas
 					*(face++) = midvidx + 0;               /* z 1 */
 					*(face++) = midvidx + 0;               /* z 1 */
 					*(face++) = midvidx + 2;               /* z 0 */
-					*(face++) = j + SPLINE_RESOL_CAP - 2;  /* z 0 */
+					*(face++) = j + open_spline_ranges[open_spline_index].vertex_total_cap_tail - 2;  /* z 0 */
 					face_index++;
 					FACE_ASSERT(face - 4, sf_vert_tot);
 

From cfb3194945ee9c8bde2a5ce11c1dc05ae944920f Mon Sep 17 00:00:00 2001
From: Campbell Barton 
Date: Wed, 18 Jul 2012 12:54:13 +0000
Subject: [PATCH 080/108] code cleanup for mask capping

---
 .../blenkernel/intern/mask_rasterize.c        | 63 ++++++++++---------
 1 file changed, 32 insertions(+), 31 deletions(-)

diff --git a/source/blender/blenkernel/intern/mask_rasterize.c b/source/blender/blenkernel/intern/mask_rasterize.c
index 94d6ad0ab6e..deac66e6154 100644
--- a/source/blender/blenkernel/intern/mask_rasterize.c
+++ b/source/blender/blenkernel/intern/mask_rasterize.c
@@ -47,11 +47,10 @@
 
 #ifndef USE_RASKTER
 
-//#define SPLINE_RESOL_CAP 32
 #define SPLINE_RESOL_CAP_PER_PIXEL 2
 #define SPLINE_RESOL_CAP_MIN 8
 #define SPLINE_RESOL_CAP_MAX 64
-#define SPLINE_RESOL 32
+
 #define BUCKET_PIXELS_PER_CELL 8
 
 #define SF_EDGE_IS_BOUNDARY 0xff
@@ -878,16 +877,18 @@ void BKE_maskrasterize_handle_init(MaskRasterHandle *mr_handle, struct Mask *mas
 
 			/* feather only splines */
 			while (open_spline_index > 0) {
-				unsigned int start_vidx          = open_spline_ranges[--open_spline_index].vertex_offset;
-				unsigned int tot_diff_point_sub1 = open_spline_ranges[  open_spline_index].vertex_total - 1;
+				const unsigned int vertex_offset         = open_spline_ranges[--open_spline_index].vertex_offset;
+				unsigned int       vertex_total          = open_spline_ranges[  open_spline_index].vertex_total;
+				unsigned int       vertex_total_cap_head = open_spline_ranges[  open_spline_index].vertex_total_cap_head;
+				unsigned int       vertex_total_cap_tail = open_spline_ranges[  open_spline_index].vertex_total_cap_tail;
 				unsigned int k, j;
 
-				j = start_vidx;
+				j = vertex_offset;
 
 				/* subtract one since we reference next vertex triple */
-				for (k = 0; k < tot_diff_point_sub1; k++, j += 3) {
+				for (k = 0; k < vertex_total - 1; k++, j += 3) {
 
-					BLI_assert(j == start_vidx + (k * 3));
+					BLI_assert(j == vertex_offset + (k * 3));
 
 					*(face++) = j + 3; /* next span */ /* z 1 */
 					*(face++) = j + 0;                 /* z 1 */
@@ -905,28 +906,28 @@ void BKE_maskrasterize_handle_init(MaskRasterHandle *mr_handle, struct Mask *mas
 				}
 
 				if (open_spline_ranges[open_spline_index].is_cyclic) {
-					*(face++) = start_vidx + 0; /* next span */ /* z 1 */
-					*(face++) = j          + 0;                 /* z 1 */
-					*(face++) = j          + 1;                 /* z 0 */
-					*(face++) = start_vidx + 1; /* next span */ /* z 0 */
+					*(face++) = vertex_offset + 0; /* next span */ /* z 1 */
+					*(face++) = j             + 0;                 /* z 1 */
+					*(face++) = j             + 1;                 /* z 0 */
+					*(face++) = vertex_offset + 1; /* next span */ /* z 0 */
 					face_index++;
 					FACE_ASSERT(face - 4, sf_vert_tot);
 
-					*(face++) = j          + 0;                 /* z 1 */
-					*(face++) = start_vidx + 0; /* next span */ /* z 1 */
-					*(face++) = start_vidx + 2; /* next span */ /* z 0 */
-					*(face++) = j          + 2;                 /* z 0 */
+					*(face++) = j          + 0;                    /* z 1 */
+					*(face++) = vertex_offset + 0; /* next span */ /* z 1 */
+					*(face++) = vertex_offset + 2; /* next span */ /* z 0 */
+					*(face++) = j          + 2;                    /* z 0 */
 					face_index++;
 					FACE_ASSERT(face - 4, sf_vert_tot);
 				}
 				else {
-					unsigned int midvidx = start_vidx;
+					unsigned int midvidx = vertex_offset;
 
 					/***************
 					 * cap end 'a' */
-					j = midvidx + (open_spline_ranges[open_spline_index].vertex_total * 3);
+					j = midvidx + (vertex_total * 3);
 
-					for (k = 0; k < open_spline_ranges[open_spline_index].vertex_total_cap_head - 2; k++, j++) {
+					for (k = 0; k < vertex_total_cap_head - 2; k++, j++) {
 						*(face++) = midvidx + 0;  /* z 1 */
 						*(face++) = midvidx + 0;  /* z 1 */
 						*(face++) = j + 0;        /* z 0 */
@@ -935,7 +936,7 @@ void BKE_maskrasterize_handle_init(MaskRasterHandle *mr_handle, struct Mask *mas
 						FACE_ASSERT(face - 4, sf_vert_tot);
 					}
 
-					j = start_vidx + (open_spline_ranges[open_spline_index].vertex_total * 3);
+					j = vertex_offset + (vertex_total * 3);
 
 					/* 2 tris that join the original */
 					*(face++) = midvidx + 0;  /* z 1 */
@@ -945,10 +946,10 @@ void BKE_maskrasterize_handle_init(MaskRasterHandle *mr_handle, struct Mask *mas
 					face_index++;
 					FACE_ASSERT(face - 4, sf_vert_tot);
 
-					*(face++) = midvidx + 0;               /* z 1 */
-					*(face++) = midvidx + 0;               /* z 1 */
-					*(face++) = j + open_spline_ranges[open_spline_index].vertex_total_cap_head - 2;  /* z 0 */
-					*(face++) = midvidx + 2;               /* z 0 */
+					*(face++) = midvidx + 0;                    /* z 1 */
+					*(face++) = midvidx + 0;                    /* z 1 */
+					*(face++) = j + vertex_total_cap_head - 2;  /* z 0 */
+					*(face++) = midvidx + 2;                    /* z 0 */
 					face_index++;
 					FACE_ASSERT(face - 4, sf_vert_tot);
 
@@ -957,11 +958,11 @@ void BKE_maskrasterize_handle_init(MaskRasterHandle *mr_handle, struct Mask *mas
 					 * cap end 'b' */
 					/* ... same as previous but v 2-3 flipped, and different initial offsets */
 
-					j = start_vidx + (open_spline_ranges[open_spline_index].vertex_total * 3) + (open_spline_ranges[open_spline_index].vertex_total_cap_head - 1);
+					j = vertex_offset + (vertex_total * 3) + (vertex_total_cap_head - 1);
 
-					midvidx = start_vidx + (open_spline_ranges[open_spline_index].vertex_total * 3) - 3;
+					midvidx = vertex_offset + (vertex_total * 3) - 3;
 
-					for (k = 0; k < open_spline_ranges[open_spline_index].vertex_total_cap_tail - 2; k++, j++) {
+					for (k = 0; k < vertex_total_cap_tail - 2; k++, j++) {
 						*(face++) = midvidx;  /* z 1 */
 						*(face++) = midvidx;  /* z 1 */
 						*(face++) = j + 1;    /* z 0 */
@@ -970,7 +971,7 @@ void BKE_maskrasterize_handle_init(MaskRasterHandle *mr_handle, struct Mask *mas
 						FACE_ASSERT(face - 4, sf_vert_tot);
 					}
 
-					j = start_vidx + (open_spline_ranges[open_spline_index].vertex_total * 3) + (open_spline_ranges[open_spline_index].vertex_total_cap_head - 1);
+					j = vertex_offset + (vertex_total * 3) + (vertex_total_cap_head - 1);
 
 					/* 2 tris that join the original */
 					*(face++) = midvidx + 0;  /* z 1 */
@@ -980,10 +981,10 @@ void BKE_maskrasterize_handle_init(MaskRasterHandle *mr_handle, struct Mask *mas
 					face_index++;
 					FACE_ASSERT(face - 4, sf_vert_tot);
 
-					*(face++) = midvidx + 0;               /* z 1 */
-					*(face++) = midvidx + 0;               /* z 1 */
-					*(face++) = midvidx + 2;               /* z 0 */
-					*(face++) = j + open_spline_ranges[open_spline_index].vertex_total_cap_tail - 2;  /* z 0 */
+					*(face++) = midvidx + 0;                    /* z 1 */
+					*(face++) = midvidx + 0;                    /* z 1 */
+					*(face++) = midvidx + 2;                    /* z 0 */
+					*(face++) = j + vertex_total_cap_tail - 2;  /* z 0 */
 					face_index++;
 					FACE_ASSERT(face - 4, sf_vert_tot);
 

From 73a778a4d020cdafc9855a41a2c9bff421aed0d7 Mon Sep 17 00:00:00 2001
From: Campbell Barton 
Date: Wed, 18 Jul 2012 13:34:14 +0000
Subject: [PATCH 081/108] change bucket size to give better performance for
 high detail 4k masks, also clamp from 0-1 for each layer when accumulating.

---
 .../blender/blenkernel/intern/mask_rasterize.c   | 16 +++++++++++++---
 1 file changed, 13 insertions(+), 3 deletions(-)

diff --git a/source/blender/blenkernel/intern/mask_rasterize.c b/source/blender/blenkernel/intern/mask_rasterize.c
index deac66e6154..f0fc1e9fbd2 100644
--- a/source/blender/blenkernel/intern/mask_rasterize.c
+++ b/source/blender/blenkernel/intern/mask_rasterize.c
@@ -51,7 +51,8 @@
 #define SPLINE_RESOL_CAP_MIN 8
 #define SPLINE_RESOL_CAP_MAX 64
 
-#define BUCKET_PIXELS_PER_CELL 8
+/* found this gives best performance for high detail masks, values between 2 and 8 work best */
+#define BUCKET_PIXELS_PER_CELL 4
 
 #define SF_EDGE_IS_BOUNDARY 0xff
 #define SF_KEYINDEX_TEMP_ID ((unsigned int) -1)
@@ -60,8 +61,9 @@
 #define TRI_VERT            ((unsigned int) -1)
 
 /* for debugging add... */
+#ifndef NDEBUG
 /* 	printf("%u %u %u %u\n", _t[0], _t[1], _t[2], _t[3]); \ */
-#define FACE_ASSERT(face, vert_max)                      \
+#  define FACE_ASSERT(face, vert_max)                    \
 {                                                        \
 	unsigned int *_t = face;                             \
 	BLI_assert(_t[0] < vert_max);                        \
@@ -69,6 +71,10 @@
 	BLI_assert(_t[2] < vert_max);                        \
 	BLI_assert(_t[3] < vert_max || _t[3] == TRI_VERT);   \
 } (void)0
+#else
+   /* do nothing */
+#  define FACE_ASSERT(face, vert_max)
+#endif
 
 static void rotate_point_v2(float r_p[2], const float p[2], const float cent[2], const float angle, const float asp[2])
 {
@@ -1234,9 +1240,13 @@ float BKE_maskrasterize_handle_sample(MaskRasterHandle *mr_handle, const float x
 				value += value_layer;
 				break;
 		}
+
+		/* clamp after applying each layer so we don't get
+		 * issues subtracting after accumulating over 1.0f */
+		return CLAMPIS(value, 0.0f, 1.0f);
 	}
 
-	return CLAMPIS(value, 0.0f, 1.0f);
+	return value;
 }
 
 #endif /* USE_RASKTER */

From c0e004bd61c45811f99a886d8818a7764109c5ec Mon Sep 17 00:00:00 2001
From: Campbell Barton 
Date: Wed, 18 Jul 2012 13:44:48 +0000
Subject: [PATCH 082/108] add difference blending mode, also fix error in last
 commit

---
 source/blender/blenkernel/intern/mask_rasterize.c |  5 ++++-
 source/blender/makesdna/DNA_mask_types.h          | 13 +++++++------
 source/blender/makesrna/intern/rna_mask.c         |  1 +
 3 files changed, 12 insertions(+), 7 deletions(-)

diff --git a/source/blender/blenkernel/intern/mask_rasterize.c b/source/blender/blenkernel/intern/mask_rasterize.c
index f0fc1e9fbd2..8a5f225bed6 100644
--- a/source/blender/blenkernel/intern/mask_rasterize.c
+++ b/source/blender/blenkernel/intern/mask_rasterize.c
@@ -1235,6 +1235,9 @@ float BKE_maskrasterize_handle_sample(MaskRasterHandle *mr_handle, const float x
 			case MASK_BLEND_REPLACE:
 				value = (value * (1.0f - layer->alpha)) + (value_layer * layer->alpha);
 				break;
+			case MASK_BLEND_DIFFERENCE:
+				value = fabsf(value - value_layer);
+				break;
 			default: /* same as add */
 				BLI_assert(0);
 				value += value_layer;
@@ -1243,7 +1246,7 @@ float BKE_maskrasterize_handle_sample(MaskRasterHandle *mr_handle, const float x
 
 		/* clamp after applying each layer so we don't get
 		 * issues subtracting after accumulating over 1.0f */
-		return CLAMPIS(value, 0.0f, 1.0f);
+		CLAMP(value, 0.0f, 1.0f);
 	}
 
 	return value;
diff --git a/source/blender/makesdna/DNA_mask_types.h b/source/blender/makesdna/DNA_mask_types.h
index f231cba0df7..60bc3ee0ffc 100644
--- a/source/blender/makesdna/DNA_mask_types.h
+++ b/source/blender/makesdna/DNA_mask_types.h
@@ -167,12 +167,13 @@ enum {
 
 /* masklay->blend */
 enum {
-	MASK_BLEND_ADD      = 0,
-	MASK_BLEND_SUBTRACT = 1,
-	MASK_BLEND_LIGHTEN  = 2,
-	MASK_BLEND_DARKEN   = 3,
-	MASK_BLEND_MUL      = 4,
-	MASK_BLEND_REPLACE  = 5,
+	MASK_BLEND_ADD         = 0,
+	MASK_BLEND_SUBTRACT    = 1,
+	MASK_BLEND_LIGHTEN     = 2,
+	MASK_BLEND_DARKEN      = 3,
+	MASK_BLEND_MUL         = 4,
+	MASK_BLEND_REPLACE     = 5,
+	MASK_BLEND_DIFFERENCE  = 6
 };
 
 /* masklay->blend_flag */
diff --git a/source/blender/makesrna/intern/rna_mask.c b/source/blender/makesrna/intern/rna_mask.c
index f417458212d..f06855e7344 100644
--- a/source/blender/makesrna/intern/rna_mask.c
+++ b/source/blender/makesrna/intern/rna_mask.c
@@ -585,6 +585,7 @@ static void rna_def_mask_layer(BlenderRNA *brna)
 		{MASK_BLEND_DARKEN, "DARKEN", 0, "Darken", ""},
 		{MASK_BLEND_MUL, "MUL", 0, "Multiply", ""},
 		{MASK_BLEND_REPLACE, "REPLACE", 0, "Replace", ""},
+		{MASK_BLEND_DIFFERENCE, "DIFFERENCE", 0, "Difference", ""},
 		{0, NULL, 0, NULL, NULL}
 	};
 

From 1fc3f91016003fa5856bf987e7f2f8340def6c7a Mon Sep 17 00:00:00 2001
From: Bastien Montagne 
Date: Wed, 18 Jul 2012 14:03:10 +0000
Subject: [PATCH 083/108] Some small fixes (grrr, python imports...).

---
 release/scripts/modules/bl_i18n_utils/merge_po.py | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/release/scripts/modules/bl_i18n_utils/merge_po.py b/release/scripts/modules/bl_i18n_utils/merge_po.py
index b09e4daefbc..51e587ca4c8 100755
--- a/release/scripts/modules/bl_i18n_utils/merge_po.py
+++ b/release/scripts/modules/bl_i18n_utils/merge_po.py
@@ -31,16 +31,17 @@
 import sys
 
 try:
+    import settings
     import utils
 except:
-    from . import utils
+    from . import (settings, utils)
 
 
 def main():
     import argparse
     parser = argparse.ArgumentParser(description="" \
                     "Merge one or more .po files into the first dest one.\n" \
-                    "If a msgkey (msgid, msgctxt) is present in more than " \
+                    "If a msgkey (msgctxt, msgid) is present in more than " \
                     "one merged po, the one in the first file wins, unless " \
                     "it’s marked as fuzzy and one later is not.\n" \
                     "The fuzzy flag is removed if necessary.\n" \

From 45738ef8dc81d86e6f323a4a7eccc38a5f42a5a0 Mon Sep 17 00:00:00 2001
From: Bastien Montagne 
Date: Wed, 18 Jul 2012 14:30:31 +0000
Subject: [PATCH 084/108] Add Skin modifier's radius values to Transform panel
 (in 3D views).

---
 .../editors/space_view3d/view3d_buttons.c     | 90 +++++++++++++++++--
 source/blender/editors/transform/transform.c  |  2 +-
 2 files changed, 86 insertions(+), 6 deletions(-)

diff --git a/source/blender/editors/space_view3d/view3d_buttons.c b/source/blender/editors/space_view3d/view3d_buttons.c
index 6cfa828024d..c819637fd04 100644
--- a/source/blender/editors/space_view3d/view3d_buttons.c
+++ b/source/blender/editors/space_view3d/view3d_buttons.c
@@ -93,7 +93,7 @@ typedef struct {
 	float ob_scale[3]; /* need temp space due to linked values */
 	float ob_dims[3];
 	short link_scale;
-	float ve_median[7];
+	float ve_median[9];
 	int curdef;
 	float *defweightp;
 } TransformProperties;
@@ -135,13 +135,13 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float
 	uiBlock *block = (layout) ? uiLayoutAbsoluteBlock(layout) : NULL;
 	MDeformVert *dvert = NULL;
 	TransformProperties *tfp;
-	float median[7], ve_median[7];
-	int tot, totw, totweight, totedge, totradius;
+	float median[9], ve_median[9];
+	int tot, totw, totweight, totedge, totradius, totskinradius;
 	char defstr[320];
 	PointerRNA radius_ptr;
 
-	median[0] = median[1] = median[2] = median[3] = median[4] = median[5] = median[6] = 0.0;
-	tot = totw = totweight = totedge = totradius = 0;
+	median[0] = median[1] = median[2] = median[3] = median[4] = median[5] = median[6] = median[7] = median[8] = 0.0;
+	tot = totw = totweight = totedge = totradius = totskinradius = 0;
 	defstr[0] = 0;
 
 	/* make sure we got storage */
@@ -159,9 +159,17 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float
 
 		BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) {
 			if (BM_elem_flag_test(eve, BM_ELEM_SELECT)) {
+				MVertSkin *vs;
+
 				evedef = eve;
 				tot++;
 				add_v3_v3(median, eve->co);
+
+				vs = (MVertSkin *)CustomData_bmesh_get(&bm->vdata, eve->head.data, CD_MVERT_SKIN);
+				if (vs) {
+					add_v2_v2(median + 7, vs->radius); /* Third val not used currently. */
+					totskinradius++;
+				}
 			}
 		}
 
@@ -304,6 +312,10 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float
 		median[4] /= (float)totweight;
 	if (totradius)
 		median[5] /= (float)totradius;
+	if (totskinradius) {
+		median[7] /= (float)totskinradius;
+		median[8] /= (float)totskinradius;
+	}
 
 	if (v3d->flag & V3D_GLOBAL_STATS)
 		mul_m4_v3(ob->obmat, median);
@@ -373,6 +385,23 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float
 			          &(tfp->ve_median[5]), 0.0, 100.0, 1, 3, TIP_("Radius of curve control points"));
 		}
 
+		if (totskinradius == 1) {
+			uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, IFACE_("Radius X:"),
+			          0, yi -= buth + but_margin, 200, buth,
+			          &(tfp->ve_median[7]), 0.0, 100.0, 1, 3, TIP_("X radius used by Skin modifier"));
+			uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, IFACE_("Radius Y:"),
+			          0, yi -= buth + but_margin, 200, buth,
+			          &(tfp->ve_median[8]), 0.0, 100.0, 1, 3, TIP_("Y radius used by Skin modifier"));
+		}
+		else if (totskinradius > 1) {
+			uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, IFACE_("Mean Radius X:"),
+			          0, yi -= buth + but_margin, 200, buth,
+			          &(tfp->ve_median[7]), 0.0, 100.0, 1, 3, TIP_("Median X radius used by Skin modifier"));
+			uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, IFACE_("Mean Radius Y:"),
+			          0, yi -= buth + but_margin, 200, buth,
+			          &(tfp->ve_median[8]), 0.0, 100.0, 1, 3, TIP_("Median Y radius used by Skin modifier"));
+		}
+
 		if (totedge == 1) {
 			uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, IFACE_("Crease:"),
 			          0, yi -= buth + but_margin, 200, buth,
@@ -407,6 +436,8 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float
 		median[4] = ve_median[4] - median[4];
 		median[5] = ve_median[5] - median[5];
 		median[6] = ve_median[6] - median[6];
+		median[7] = ve_median[7] - median[7];
+		median[8] = ve_median[8] - median[8];
 
 		if (ob->type == OB_MESH) {
 			Mesh *me = ob->data;
@@ -501,6 +532,55 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float
 					}
 				}
 			}
+
+			if (median[7] != 0.0f) {
+				BMVert *eve;
+				/* That one is not clamped to [0.0, 1.0]. */
+				float sca = ve_median[7];
+				if (ve_median[7] - median[7] == 0.0f) {
+					BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) {
+						if (BM_elem_flag_test(eve, BM_ELEM_SELECT)) {
+							MVertSkin *vs = (MVertSkin *)CustomData_bmesh_get(&bm->vdata, eve->head.data, CD_MVERT_SKIN);
+							if (vs)
+								vs->radius[0] = sca;
+						}
+					}
+				}
+				else {
+					sca /= (ve_median[7] - median[7]);
+					BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) {
+						if (BM_elem_flag_test(eve, BM_ELEM_SELECT)) {
+							MVertSkin *vs = (MVertSkin *)CustomData_bmesh_get(&bm->vdata, eve->head.data, CD_MVERT_SKIN);
+							if (vs)
+								vs->radius[0] *= sca;
+						}
+					}
+				}
+			}
+			if (median[8] != 0.0f) {
+				BMVert *eve;
+				/* That one is not clamped to [0.0, 1.0]. */
+				float sca = ve_median[8];
+				if (ve_median[8] - median[8] == 0.0f) {
+					BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) {
+						if (BM_elem_flag_test(eve, BM_ELEM_SELECT)) {
+							MVertSkin *vs = (MVertSkin *)CustomData_bmesh_get(&bm->vdata, eve->head.data, CD_MVERT_SKIN);
+							if (vs)
+								vs->radius[1] = sca;
+						}
+					}
+				}
+				else {
+					sca /= (ve_median[8] - median[8]);
+					BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) {
+						if (BM_elem_flag_test(eve, BM_ELEM_SELECT)) {
+							MVertSkin *vs = (MVertSkin *)CustomData_bmesh_get(&bm->vdata, eve->head.data, CD_MVERT_SKIN);
+							if (vs)
+								vs->radius[1] *= sca;
+						}
+					}
+				}
+			}
 			EDBM_mesh_normals_update(em);
 		}
 		else if (ELEM(ob->type, OB_CURVE, OB_SURF)) {
diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c
index 8eb2371a598..0be871add75 100644
--- a/source/blender/editors/transform/transform.c
+++ b/source/blender/editors/transform/transform.c
@@ -4920,7 +4920,7 @@ static int createSlideVerts(TransInfo *t)
 					if (BM_elem_flag_test(e2, BM_ELEM_SELECT))
 						continue;
 
-					/* This test is only relevant if object is not wire-dranw! See [#32068]. */
+					/* This test is only relevant if object is not wire-drawn! See [#32068]. */
 					if (v3d && t->obedit->dt > OB_WIRE && v3d->drawtype > OB_WIRE &&
 					    !BMBVH_EdgeVisible(btree, e2, ar, v3d, t->obedit))
 						continue;

From c8029bffd94dc9706b66d9a52626737a971423df Mon Sep 17 00:00:00 2001
From: Campbell Barton 
Date: Wed, 18 Jul 2012 16:24:13 +0000
Subject: [PATCH 085/108] workaround for a bug with zero edges getting removed
 got feather faces out of sync and crashed

---
 .../blenkernel/intern/mask_rasterize.c        | 42 +++++++++++++++++--
 .../compositor/intern/COM_WorkScheduler.cpp   |  7 +++-
 source/blender/makesrna/intern/rna_mask.c     |  2 +-
 3 files changed, 44 insertions(+), 7 deletions(-)

diff --git a/source/blender/blenkernel/intern/mask_rasterize.c b/source/blender/blenkernel/intern/mask_rasterize.c
index 8a5f225bed6..b05c1ad4eaa 100644
--- a/source/blender/blenkernel/intern/mask_rasterize.c
+++ b/source/blender/blenkernel/intern/mask_rasterize.c
@@ -47,6 +47,10 @@
 
 #ifndef USE_RASKTER
 
+/* this is rather and annoying hack, use define to isolate it.
+ * problem is caused by scanfill removing edges on us. */
+#define USE_SCANFILL_EDGE_WORKAROUND
+
 #define SPLINE_RESOL_CAP_PER_PIXEL 2
 #define SPLINE_RESOL_CAP_MIN 8
 #define SPLINE_RESOL_CAP_MAX 64
@@ -548,6 +552,11 @@ void BKE_maskrasterize_handle_init(MaskRasterHandle *mr_handle, struct Mask *mas
 		unsigned int sf_vert_tot = 0;
 		unsigned int tot_feather_quads = 0;
 
+#ifdef USE_SCANFILL_EDGE_WORKAROUND
+		unsigned int tot_boundary_used = 0;
+		unsigned int tot_boundary_found = 0;
+#endif
+
 		if (masklay->restrictflag & MASK_RESTRICT_RENDER) {
 			/* skip the layer */
 			mr_handle->layers_tot--;
@@ -580,6 +589,7 @@ void BKE_maskrasterize_handle_init(MaskRasterHandle *mr_handle, struct Mask *mas
 			if (do_feather) {
 				diff_feather_points = BKE_mask_spline_feather_differentiated_points_with_resolution_ex(
 				                          spline, &tot_diff_feather_points, resol, TRUE);
+				BLI_assert(diff_feather_points);
 			}
 			else {
 				tot_diff_feather_points = 0;
@@ -661,8 +671,15 @@ void BKE_maskrasterize_handle_init(MaskRasterHandle *mr_handle, struct Mask *mas
 
 					for (j = 0; j < tot_diff_point; j++) {
 						ScanFillEdge *sf_edge = BLI_scanfill_edge_add(&sf_ctx, sf_vert_prev, sf_vert);
-						sf_edge->tmp.c = SF_EDGE_IS_BOUNDARY;
 
+#ifdef USE_SCANFILL_EDGE_WORKAROUND
+						if (diff_feather_points) {
+							sf_edge->tmp.c = SF_EDGE_IS_BOUNDARY;
+							tot_boundary_used++;
+						}
+#else
+						(void)sf_edge;
+#endif
 						sf_vert_prev = sf_vert;
 						sf_vert = sf_vert->next;
 					}
@@ -877,10 +894,20 @@ void BKE_maskrasterize_handle_init(MaskRasterHandle *mr_handle, struct Mask *mas
 						*(face++) = sf_edge->v1->keyindex;
 						face_index++;
 						FACE_ASSERT(face - 4, sf_vert_tot);
+
+#ifdef USE_SCANFILL_EDGE_WORKAROUND
+						tot_boundary_found++;
+#endif
 					}
 				}
 			}
 
+#ifdef USE_SCANFILL_EDGE_WORKAROUND
+			if (tot_boundary_found != tot_boundary_used) {
+				BLI_assert(tot_boundary_found < tot_boundary_used);
+			}
+#endif
+
 			/* feather only splines */
 			while (open_spline_index > 0) {
 				const unsigned int vertex_offset         = open_spline_ranges[--open_spline_index].vertex_offset;
@@ -999,15 +1026,22 @@ void BKE_maskrasterize_handle_init(MaskRasterHandle *mr_handle, struct Mask *mas
 
 			MEM_freeN(open_spline_ranges);
 
-			// fprintf(stderr, "%d %d\n", face_index, sf_face_tot + tot_feather_quads);
+//			fprintf(stderr, "%u %u (%u %u), %u\n", face_index, sf_tri_tot + tot_feather_quads, sf_tri_tot, tot_feather_quads, tot_boundary_used - tot_boundary_found);
 
+#ifdef USE_SCANFILL_EDGE_WORKAROUND
+			BLI_assert(face_index + (tot_boundary_used - tot_boundary_found) == sf_tri_tot + tot_feather_quads);
+#else
 			BLI_assert(face_index == sf_tri_tot + tot_feather_quads);
-
+#endif
 			{
 				MaskRasterLayer *layer = &mr_handle->layers[masklay_index];
 
 				if (BLI_rctf_isect(&default_bounds, &bounds, &bounds)) {
-					layer->face_tot = sf_tri_tot + tot_feather_quads;
+#ifdef USE_SCANFILL_EDGE_WORKAROUND
+					layer->face_tot = (sf_tri_tot + tot_feather_quads) - (tot_boundary_used - tot_boundary_found);
+#else
+					layer->face_tot = (sf_tri_tot + tot_feather_quads);
+#endif
 					layer->face_coords = face_coords;
 					layer->face_array  = face_array;
 					layer->bounds = bounds;
diff --git a/source/blender/compositor/intern/COM_WorkScheduler.cpp b/source/blender/compositor/intern/COM_WorkScheduler.cpp
index b10e99697e4..753940cd4f2 100644
--- a/source/blender/compositor/intern/COM_WorkScheduler.cpp
+++ b/source/blender/compositor/intern/COM_WorkScheduler.cpp
@@ -36,10 +36,13 @@
 #include "BLI_threads.h"
 
 #if COM_CURRENT_THREADING_MODEL == COM_TM_NOTHREAD
-#warning COM_CURRENT_THREADING_MODEL COM_TM_NOTHREAD is activated. Use only for debugging.
+#  ifndef DEBUG  /* test this so we dont get warnings in debug builds */
+#    warning COM_CURRENT_THREADING_MODEL COM_TM_NOTHREAD is activated. Use only for debugging.
+#  endif
 #elif COM_CURRENT_THREADING_MODEL == COM_TM_QUEUE
+   /* do nothing - default */
 #else
-#error COM_CURRENT_THREADING_MODEL No threading model selected
+#  error COM_CURRENT_THREADING_MODEL No threading model selected
 #endif
 
 
diff --git a/source/blender/makesrna/intern/rna_mask.c b/source/blender/makesrna/intern/rna_mask.c
index f06855e7344..2987057aeb6 100644
--- a/source/blender/makesrna/intern/rna_mask.c
+++ b/source/blender/makesrna/intern/rna_mask.c
@@ -642,7 +642,7 @@ static void rna_def_mask_layer(BlenderRNA *brna)
 	/* render settings */
 	prop = RNA_def_property(srna, "alpha", PROP_FLOAT, PROP_NONE);
 	RNA_def_property_float_sdna(prop, NULL, "alpha");
-	RNA_def_property_range(prop, 0.0, 1.0f);
+	RNA_def_property_ui_range(prop, 0.0f, 1.0f, 0.1, 3);
 	RNA_def_property_ui_text(prop, "Opacity", "Render Opacity");
 	RNA_def_property_update(prop, NC_MASK | NA_EDITED, NULL);
 

From 64234612479f02ed38deca2395a4c0ba4a2ee94a Mon Sep 17 00:00:00 2001
From: Campbell Barton 
Date: Wed, 18 Jul 2012 17:29:15 +0000
Subject: [PATCH 086/108] shift help with continuous grab on a curve point now
 does scaled motion.

---
 source/blender/editors/include/UI_interface.h |  1 +
 .../editors/interface/interface_handlers.c    | 65 +++++++++++++------
 2 files changed, 47 insertions(+), 19 deletions(-)

diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h
index 9715fb93c27..0b0ad83ab21 100644
--- a/source/blender/editors/include/UI_interface.h
+++ b/source/blender/editors/include/UI_interface.h
@@ -198,6 +198,7 @@ typedef struct uiLayout uiLayout;
 /* button reqyires a pointer */
 #define BUTPOIN (FLO | SHO | CHA)
 
+/* assigned to but->type, OR'd with the flags above when passing args */
 #define BUT (1 << 9)
 #define ROW (2 << 9)
 #define TOG (3 << 9)
diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c
index c5575639169..2a93ab794af 100644
--- a/source/blender/editors/interface/interface_handlers.c
+++ b/source/blender/editors/interface/interface_handlers.c
@@ -257,7 +257,7 @@ static uiBut *ui_but_last(uiBlock *block)
 static int ui_is_a_warp_but(uiBut *but)
 {
 	if (U.uiflag & USER_CONTINUOUS_MOUSE) {
-		if (ELEM5(but->type, NUM, NUMABS, HSVCIRCLE, TRACKPREVIEW, HSVCUBE)) {
+		if (ELEM6(but->type, NUM, NUMABS, HSVCIRCLE, TRACKPREVIEW, HSVCUBE, BUT_CURVE)) {
 			return TRUE;
 		}
 	}
@@ -265,6 +265,33 @@ static int ui_is_a_warp_but(uiBut *but)
 	return FALSE;
 }
 
+static float ui_mouse_scale_warp_factor(const short shift)
+{
+	if (U.uiflag & USER_CONTINUOUS_MOUSE) {
+		return shift ? 0.05f : 1.0f;
+	}
+	else {
+		return 1.0f;
+	}
+}
+
+static void ui_mouse_scale_warp(uiHandleButtonData *data,
+                                const float mx, const float my,
+                                float *r_mx, float *r_my,
+                                const short shift)
+{
+	if (U.uiflag & USER_CONTINUOUS_MOUSE) {
+		const float fac = ui_mouse_scale_warp_factor(shift);
+		/* slow down the mouse, this is fairly picky */
+		*r_mx = (data->dragstartx * (1.0f - fac) + mx * fac);
+		*r_my = (data->dragstarty * (1.0f - fac) + my * fac);
+	}
+	else {
+		*r_mx = mx;
+		*r_my = my;
+	}
+}
+
 /* file selectors are exempt from utf-8 checks */
 int ui_is_but_utf8(uiBut *but)
 {
@@ -3093,14 +3120,17 @@ static int ui_do_but_NORMAL(bContext *C, uiBlock *block, uiBut *but, uiHandleBut
 	return WM_UI_HANDLER_CONTINUE;
 }
 
-static int ui_numedit_but_HSVCUBE(uiBut *but, uiHandleButtonData *data, float mx, float my, const short shift)
+static int ui_numedit_but_HSVCUBE(uiBut *but, uiHandleButtonData *data, int mx, int my, const short shift)
 {
 	float rgb[3];
 	float *hsv = ui_block_hsv_get(but->block);
 	float x, y;
+	float mx_fl, my_fl;
 	int changed = 1;
 	int color_profile = but->block->color_profile;
 	
+	ui_mouse_scale_warp(data, mx, my, &mx_fl, &my_fl, shift);
+
 	if (but->rnaprop) {
 		if (RNA_property_subtype(but->rnaprop) == PROP_COLOR_GAMMA)
 			color_profile = BLI_PR_NONE;
@@ -3110,16 +3140,10 @@ static int ui_numedit_but_HSVCUBE(uiBut *but, uiHandleButtonData *data, float mx
 
 	rgb_to_hsv_compat_v(rgb, hsv);
 
-	if (U.uiflag & USER_CONTINUOUS_MOUSE) {
-		float fac = shift ? 0.05f : 1.0f;
-		/* slow down the mouse, this is fairly picky */
-		mx = (data->dragstartx * (1.0f - fac) + mx * fac);
-		my = (data->dragstarty * (1.0f - fac) + my * fac);
-	}
 
 	/* relative position within box */
-	x = ((float)mx - but->x1) / (but->x2 - but->x1);
-	y = ((float)my - but->y1) / (but->y2 - but->y1);
+	x = ((float)mx_fl - but->x1) / (but->x2 - but->x1);
+	y = ((float)my_fl - but->y1) / (but->y2 - but->y1);
 	CLAMP(x, 0.0f, 1.0f);
 	CLAMP(y, 0.0f, 1.0f);
 
@@ -3318,9 +3342,12 @@ static int ui_numedit_but_HSVCIRCLE(uiBut *but, uiHandleButtonData *data, float
 {
 	rcti rect;
 	int changed = 1;
+	float mx_fl, my_fl;
 	float rgb[3];
 	float hsv[3];
 	
+	ui_mouse_scale_warp(data, mx, my, &mx_fl, &my_fl, shift);
+
 	rect.xmin = but->x1; rect.xmax = but->x2;
 	rect.ymin = but->y1; rect.ymax = but->y2;
 	
@@ -3334,14 +3361,8 @@ static int ui_numedit_but_HSVCIRCLE(uiBut *but, uiHandleButtonData *data, float
 		if (hsv[2] == 0.f) hsv[2] = 0.0001f;
 	}
 
-	if (U.uiflag & USER_CONTINUOUS_MOUSE) {
-		float fac = shift ? 0.05f : 1.0f;
-		/* slow down the mouse, this is fairly picky */
-		mx = (data->dragstartx * (1.0f - fac) + mx * fac);
-		my = (data->dragstarty * (1.0f - fac) + my * fac);
-	}
 
-	ui_hsvcircle_vals_from_pos(hsv, hsv + 1, &rect, (float)mx, (float)my);
+	ui_hsvcircle_vals_from_pos(hsv, hsv + 1, &rect, mx_fl, my_fl);
 
 	if (but->flag & UI_BUT_COLOR_CUBIC)
 		hsv[1] = 1.0f - sqrt3f(1.0f - hsv[1]);
@@ -3593,7 +3614,8 @@ static int ui_do_but_COLORBAND(bContext *C, uiBlock *block, uiBut *but, uiHandle
 	return WM_UI_HANDLER_CONTINUE;
 }
 
-static int ui_numedit_but_CURVE(uiBut *but, uiHandleButtonData *data, int snap, int mx, int my)
+static int ui_numedit_but_CURVE(uiBut *but, uiHandleButtonData *data, int snap,
+                                float mx, float my, const short shift)
 {
 	CurveMapping *cumap = (CurveMapping *)but->poin;
 	CurveMap *cuma = cumap->cm + cumap->cur;
@@ -3617,10 +3639,15 @@ static int ui_numedit_but_CURVE(uiBut *but, uiHandleButtonData *data, int snap,
 	}
 
 	if (data->dragsel != -1) {
+		const float mval_factor = ui_mouse_scale_warp_factor(shift);
 		int moved_point = 0;     /* for ctrl grid, can't use orig coords because of sorting */
 		
 		fx = (mx - data->draglastx) / zoomx;
 		fy = (my - data->draglasty) / zoomy;
+
+		fx *= mval_factor;
+		fy *= mval_factor;
+
 		for (a = 0; a < cuma->totpoint; a++) {
 			if (cmp[a].flag & SELECT) {
 				float origx = cmp[a].x, origy = cmp[a].y;
@@ -3783,7 +3810,7 @@ static int ui_do_but_CURVE(bContext *C, uiBlock *block, uiBut *but, uiHandleButt
 	else if (data->state == BUTTON_STATE_NUM_EDITING) {
 		if (event->type == MOUSEMOVE) {
 			if (mx != data->draglastx || my != data->draglasty) {
-				if (ui_numedit_but_CURVE(but, data, event->ctrl, mx, my))
+				if (ui_numedit_but_CURVE(but, data, event->ctrl, mx, my, event->shift))
 					ui_numedit_apply(C, block, but, data);
 			}
 		}

From db14b97be6917d961c893ba6e0188c927ffa67b0 Mon Sep 17 00:00:00 2001
From: Campbell Barton 
Date: Wed, 18 Jul 2012 20:32:31 +0000
Subject: [PATCH 087/108] mask transform aspect correction wasn't working
 properly, also fix for own recent commit which made cyclic report not show

---
 source/blender/editors/object/object_group.c |  8 ++++----
 source/blender/editors/transform/transform.c | 10 ++++++++--
 2 files changed, 12 insertions(+), 6 deletions(-)

diff --git a/source/blender/editors/object/object_group.c b/source/blender/editors/object/object_group.c
index e86a62f0dca..53bfddee740 100644
--- a/source/blender/editors/object/object_group.c
+++ b/source/blender/editors/object/object_group.c
@@ -133,6 +133,10 @@ static int objects_add_active_exec(bContext *C, wmOperator *op)
 			}
 			CTX_DATA_END;
 
+			if (is_cycle) {
+				BKE_report(op->reports, RPT_WARNING, "Skipped some groups because of cycle detected");
+			}
+
 			DAG_scene_sort(bmain, scene);
 			WM_event_add_notifier(C, NC_GROUP | NA_EDITED, NULL);
 
@@ -140,10 +144,6 @@ static int objects_add_active_exec(bContext *C, wmOperator *op)
 		}
 	}
 
-	if (is_cycle) {
-		BKE_report(op->reports, RPT_WARNING, "Skipped some groups because of cycle detected");
-	}
-
 	return OPERATOR_CANCELLED;
 }
 
diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c
index 0be871add75..5232371fcaf 100644
--- a/source/blender/editors/transform/transform.c
+++ b/source/blender/editors/transform/transform.c
@@ -174,8 +174,14 @@ void convertViewVec(TransInfo *t, float r_vec[3], int dx, int dy)
 
 		if (t->options & CTX_MASK) {
 			/* clamp w/h, mask only */
-			divx = divy = maxf(divx, divy);
-			mulx = muly = minf(mulx, muly);
+			if (mulx / divx < muly / divy) {
+				divx = divy = divx;
+				mulx = muly = mulx;
+			}
+			else {
+				divx = divy = divy;
+				mulx = muly = muly;
+			}
 		}
 
 		r_vec[0] = mulx * (dx) / divx;

From d0e892a7286791a4b2d1c5d7321fe8fe040819dd Mon Sep 17 00:00:00 2001
From: Campbell Barton 
Date: Wed, 18 Jul 2012 23:03:27 +0000
Subject: [PATCH 088/108] quiet double promotion warnings for the game engine.

---
 .../BlenderRoutines/BL_KetsjiEmbedStart.cpp   |   5 -
 .../BlenderRoutines/KX_BlenderRenderTools.cpp |   3 +-
 .../Converter/BL_ArmatureChannel.cpp          |   4 +-
 .../Converter/BL_ArmatureConstraint.cpp       |  10 +-
 .../Converter/BL_BlenderDataConversion.cpp    |  53 ++++-----
 .../Converter/KX_ConvertActuators.cpp         |  10 +-
 .../Converter/KX_ConvertSensors.cpp           |   8 +-
 .../gameengine/Ketsji/KX_CameraActuator.cpp   |  32 ++---
 source/gameengine/Ketsji/KX_GameActuator.h    |  52 ++++----
 .../Ketsji/KX_SCA_AddObjectActuator.cpp       |  65 +++++-----
 .../Ketsji/KX_SCA_AddObjectActuator.h         |  52 ++++----
 .../Ketsji/KX_SCA_DynamicActuator.cpp         |  65 +++++-----
 .../Ketsji/KX_SCA_DynamicActuator.h           |  52 ++++----
 .../Ketsji/KX_SCA_EndObjectActuator.h         |  52 ++++----
 .../Ketsji/KX_SCA_ReplaceMeshActuator.cpp     |  57 ++++-----
 .../Ketsji/KX_SCA_ReplaceMeshActuator.h       |  52 ++++----
 source/gameengine/Ketsji/KX_SceneActuator.h   |  52 ++++----
 .../gameengine/Ketsji/KX_TrackToActuator.cpp  | 112 +++++++++---------
 source/gameengine/Ketsji/KX_TrackToActuator.h |  52 ++++----
 source/gameengine/VideoTexture/VideoBase.h    |   2 +-
 20 files changed, 388 insertions(+), 402 deletions(-)

diff --git a/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp b/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp
index 8b211385928..8e2ff06a55c 100644
--- a/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp
+++ b/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp
@@ -82,10 +82,6 @@ extern "C" {
 /* #include "BKE_screen.h" */ /* cant include this because of 'new' function name */
 extern float BKE_screen_view3d_zoom_to_fac(float camzoom);
 
-
-//XXX #include "BIF_screen.h"
-//XXX #include "BIF_scrarea.h"
-
 #include "BKE_main.h"
 #include "BLI_blenlib.h"
 #include "BLO_readfile.h"
@@ -93,7 +89,6 @@ extern float BKE_screen_view3d_zoom_to_fac(float camzoom);
 #include "BKE_ipo.h"
 	/***/
 
-//XXX #include "BSE_headerbuttons.h"
 #include "BKE_context.h"
 #include "../../blender/windowmanager/WM_types.h"
 #include "../../blender/windowmanager/wm_window.h"
diff --git a/source/gameengine/BlenderRoutines/KX_BlenderRenderTools.cpp b/source/gameengine/BlenderRoutines/KX_BlenderRenderTools.cpp
index 9156102ab0d..1266250e942 100644
--- a/source/gameengine/BlenderRoutines/KX_BlenderRenderTools.cpp
+++ b/source/gameengine/BlenderRoutines/KX_BlenderRenderTools.cpp
@@ -383,8 +383,7 @@ void KX_BlenderRenderTools::MotionBlur(RAS_IRasterizer* rasterizer)
 			glAccum(GL_LOAD, 1.0);
 			rasterizer->SetMotionBlurState(2);
 		}
-		else if (motionblurvalue>=0.0 && motionblurvalue<=1.0)
-		{
+		else if (motionblurvalue >= 0.0f && motionblurvalue <= 1.0f) {
 			glAccum(GL_MULT, motionblurvalue);
 			glAccum(GL_ACCUM, 1-motionblurvalue);
 			glAccum(GL_RETURN, 1.0);
diff --git a/source/gameengine/Converter/BL_ArmatureChannel.cpp b/source/gameengine/Converter/BL_ArmatureChannel.cpp
index f464d6c4b59..7344aa9378e 100644
--- a/source/gameengine/Converter/BL_ArmatureChannel.cpp
+++ b/source/gameengine/Converter/BL_ArmatureChannel.cpp
@@ -258,7 +258,7 @@ PyObject* BL_ArmatureChannel::py_attr_get_joint_rotation(void *self_v, const str
 		joints[2] = -joint_mat[1][0];
 		norm = normalize_v3(joints);
 		if (norm < FLT_EPSILON) {
-			norm = (joint_mat[1][1] < 0.f) ? M_PI : 0.f;
+			norm = (joint_mat[1][1] < 0.0f) ? (float)M_PI : 0.0f;
 		} else {
 			norm = acos(joint_mat[1][1]);
 		}
@@ -275,7 +275,7 @@ PyObject* BL_ArmatureChannel::py_attr_get_joint_rotation(void *self_v, const str
 		joints[2] = (joint_mat[0][1]-joint_mat[1][0])*0.5f;
 		sa = len_v3(joints);
 		ca = (joint_mat[0][0]+joint_mat[1][1]+joint_mat[1][1]-1.0f)*0.5f;
-		if (sa > FLT_EPSILON) {
+		if (sa > (double)FLT_EPSILON) {
 			norm = atan2(sa,ca)/sa;
 		} else {
 			if (ca < 0.0) {
diff --git a/source/gameengine/Converter/BL_ArmatureConstraint.cpp b/source/gameengine/Converter/BL_ArmatureConstraint.cpp
index ee78c4deed9..7939d6e9235 100644
--- a/source/gameengine/Converter/BL_ArmatureConstraint.cpp
+++ b/source/gameengine/Converter/BL_ArmatureConstraint.cpp
@@ -334,7 +334,7 @@ PyObject* BL_ArmatureConstraint::py_attr_getattr(void *self_v, const struct KX_P
 		}
 		switch (attr_order) {
 		case BCA_IKWEIGHT:
-			return PyFloat_FromDouble((ikconstraint)?ikconstraint->weight:0.0);
+			return PyFloat_FromDouble((ikconstraint)?ikconstraint->weight : 0.0f);
 		case BCA_IKTYPE:
 			return PyLong_FromLong(ikconstraint->type);
 		case BCA_IKFLAG:
@@ -370,7 +370,7 @@ int BL_ArmatureConstraint::py_attr_setattr(void *self_v, const struct KX_PYATTRI
 	switch (attr_order) {
 	case BCA_ENFORCE:
 		dval = PyFloat_AsDouble(value);
-		if (dval < 0.0f || dval > 1.0f) { /* also accounts for non float */
+		if (dval < 0.0 || dval > 1.0) { /* also accounts for non float */
 			PyErr_SetString(PyExc_AttributeError, "constraint.enforce = float: BL_ArmatureConstraint, expected a float between 0 and 1");
 			return PY_SET_ATTR_FAIL;
 		}
@@ -379,7 +379,7 @@ int BL_ArmatureConstraint::py_attr_setattr(void *self_v, const struct KX_PYATTRI
 
 	case BCA_HEADTAIL:
 		dval = PyFloat_AsDouble(value);
-		if (dval < 0.0f || dval > 1.0f) { /* also accounts for non float */
+		if (dval < 0.0 || dval > 1.0) { /* also accounts for non float */
 			PyErr_SetString(PyExc_AttributeError, "constraint.headtail = float: BL_ArmatureConstraint, expected a float between 0 and 1");
 			return PY_SET_ATTR_FAIL;
 		}
@@ -417,7 +417,7 @@ int BL_ArmatureConstraint::py_attr_setattr(void *self_v, const struct KX_PYATTRI
 		switch (attr_order) {
 		case BCA_IKWEIGHT:
 			dval = PyFloat_AsDouble(value);
-			if (dval < 0.0f || dval > 1.0f) { /* also accounts for non float */
+			if (dval < 0.0 || dval > 1.0) { /* also accounts for non float */
 				PyErr_SetString(PyExc_AttributeError, "constraint.weight = float: BL_ArmatureConstraint, expected a float between 0 and 1");
 				return PY_SET_ATTR_FAIL;
 			}
@@ -426,7 +426,7 @@ int BL_ArmatureConstraint::py_attr_setattr(void *self_v, const struct KX_PYATTRI
 
 		case BCA_IKDIST:
 			dval = PyFloat_AsDouble(value);
-			if (dval < 0.0f) { /* also accounts for non float */
+			if (dval < 0.0) {  /* also accounts for non float */
 				PyErr_SetString(PyExc_AttributeError, "constraint.ik_dist = float: BL_ArmatureConstraint, expected a positive float");
 				return PY_SET_ATTR_FAIL;
 			}
diff --git a/source/gameengine/Converter/BL_BlenderDataConversion.cpp b/source/gameengine/Converter/BL_BlenderDataConversion.cpp
index 3c9ca77b37e..84ad12477d0 100644
--- a/source/gameengine/Converter/BL_BlenderDataConversion.cpp
+++ b/source/gameengine/Converter/BL_BlenderDataConversion.cpp
@@ -30,7 +30,6 @@
  *  \ingroup bgeconv
  */
 
-
 #if defined(WIN32) && !defined(FREE_WINDOWS)
 #pragma warning (disable : 4786)
 #endif
@@ -186,10 +185,8 @@ extern Material defmaterial;	/* material.c */
 #ifdef __cplusplus
 extern "C" {
 #endif
-//XXX #include "BSE_headerbuttons.h"
 //XXX void update_for_newframe();
 //void BKE_scene_update_for_newframe(struct Scene *sce, unsigned int lay);
-//#include "BKE_ipo.h"
 //void do_all_data_ipos(void);
 #ifdef __cplusplus
 }
@@ -464,10 +461,10 @@ static void GetRGB(short type,
 					unsigned char cp[4];
 					unsigned int integer;
 				} col_converter;
-				col_converter.cp[3] = (unsigned char) (mat->r*255.0);
-				col_converter.cp[2] = (unsigned char) (mat->g*255.0);
-				col_converter.cp[1] = (unsigned char) (mat->b*255.0);
-				col_converter.cp[0] = (unsigned char) (mat->alpha*255.0);
+				col_converter.cp[3] = (unsigned char) (mat->r     * 255.0f);
+				col_converter.cp[2] = (unsigned char) (mat->g     * 255.0f);
+				col_converter.cp[1] = (unsigned char) (mat->b     * 255.0f);
+				col_converter.cp[0] = (unsigned char) (mat->alpha * 255.0f);
 				color = col_converter.integer;
 			}
 			c0 = KX_rgbaint2uint_new(color);
@@ -1143,10 +1140,10 @@ RAS_MeshObject* BL_ConvertMesh(Mesh* mesh, Object* blenderobj, KX_Scene* scene,
 							unsigned int integer;
 						} col_converter;
 						
-						col_converter.cp[3] = (unsigned char) (ma->r*255.0);
-						col_converter.cp[2] = (unsigned char) (ma->g*255.0);
-						col_converter.cp[1] = (unsigned char) (ma->b*255.0);
-						col_converter.cp[0] = (unsigned char) (ma->alpha*255.0);
+						col_converter.cp[3] = (unsigned char) (ma->r     * 255.0f);
+						col_converter.cp[2] = (unsigned char) (ma->g     * 255.0f);
+						col_converter.cp[1] = (unsigned char) (ma->b     * 255.0f);
+						col_converter.cp[0] = (unsigned char) (ma->alpha * 255.0f);
 						
 						color = col_converter.integer;
 					}
@@ -1330,8 +1327,8 @@ static PHY_ShapeProps *CreateShapePropsFromBlenderObject(struct Object* blendero
 	MT_assert(0.0f <= blenderobject->damping && blenderobject->damping <= 1.0f);
 	MT_assert(0.0f <= blenderobject->rdamping && blenderobject->rdamping <= 1.0f);
 	
-	shapeProps->m_lin_drag = 1.0 - blenderobject->damping;
-	shapeProps->m_ang_drag = 1.0 - blenderobject->rdamping;
+	shapeProps->m_lin_drag = 1.0f - blenderobject->damping;
+	shapeProps->m_ang_drag = 1.0f - blenderobject->rdamping;
 	
 	shapeProps->m_friction_scaling[0] = blenderobject->anisotropicFriction[0]; 
 	shapeProps->m_friction_scaling[1] = blenderobject->anisotropicFriction[1];
@@ -1456,17 +1453,17 @@ static void my_tex_space_mesh(Mesh *me)
 		copy_v3_v3(me->size, size);
 		me->rot[0]= me->rot[1]= me->rot[2]= 0.0f;
 
-		if (me->size[0]==0.0) me->size[0]= 1.0f;
-		else if (me->size[0]>0.0 && me->size[0]< 0.00001f) me->size[0]= 0.00001f;
-		else if (me->size[0]<0.0 && me->size[0]> -0.00001f) me->size[0]= -0.00001f;
+		if (me->size[0] == 0.0f) me->size[0] = 1.0f;
+		else if (me->size[0] > 0.0f && me->size[0]< 0.00001f) me->size[0]= 0.00001f;
+		else if (me->size[0] < 0.0f && me->size[0]> -0.00001f) me->size[0]= -0.00001f;
 
-		if (me->size[1]==0.0) me->size[1]= 1.0f;
-		else if (me->size[1]>0.0 && me->size[1]< 0.00001f) me->size[1]= 0.00001f;
-		else if (me->size[1]<0.0 && me->size[1]> -0.00001f) me->size[1]= -0.00001f;
+		if (me->size[1] == 0.0f) me->size[1]= 1.0f;
+		else if (me->size[1] > 0.0f && me->size[1]< 0.00001f) me->size[1]= 0.00001f;
+		else if (me->size[1] < 0.0f && me->size[1]> -0.00001f) me->size[1]= -0.00001f;
 
-		if (me->size[2]==0.0) me->size[2]= 1.0f;
-		else if (me->size[2]>0.0 && me->size[2]< 0.00001f) me->size[2]= 0.00001f;
-		else if (me->size[2]<0.0 && me->size[2]> -0.00001f) me->size[2]= -0.00001f;
+		if (me->size[2] == 0.0f) me->size[2]= 1.0f;
+		else if (me->size[2] > 0.0f && me->size[2]< 0.00001f) me->size[2]= 0.00001f;
+		else if (me->size[2] < 0.0f && me->size[2]> -0.00001f) me->size[2]= -0.00001f;
 	}
 	
 }
@@ -1522,13 +1519,13 @@ static void my_get_local_bounds(Object *ob, DerivedMesh *dm, float *center, floa
 	}
 	else 
 	{
-		size[0]= 0.5f*fabs(bb->vec[0][0] - bb->vec[4][0]);
-		size[1]= 0.5f*fabs(bb->vec[0][1] - bb->vec[2][1]);
-		size[2]= 0.5f*fabs(bb->vec[0][2] - bb->vec[1][2]);
+		size[0] = 0.5f * fabsf(bb->vec[0][0] - bb->vec[4][0]);
+		size[1] = 0.5f * fabsf(bb->vec[0][1] - bb->vec[2][1]);
+		size[2] = 0.5f * fabsf(bb->vec[0][2] - bb->vec[1][2]);
 					
-		center[0]= 0.5f*(bb->vec[0][0] + bb->vec[4][0]);
-		center[1]= 0.5f*(bb->vec[0][1] + bb->vec[2][1]);
-		center[2]= 0.5f*(bb->vec[0][2] + bb->vec[1][2]);
+		center[0] = 0.5f * (bb->vec[0][0] + bb->vec[4][0]);
+		center[1] = 0.5f * (bb->vec[0][1] + bb->vec[2][1]);
+		center[2] = 0.5f * (bb->vec[0][2] + bb->vec[1][2]);
 	}
 }
 	
diff --git a/source/gameengine/Converter/KX_ConvertActuators.cpp b/source/gameengine/Converter/KX_ConvertActuators.cpp
index 28e34769ab8..89a3f365140 100644
--- a/source/gameengine/Converter/KX_ConvertActuators.cpp
+++ b/source/gameengine/Converter/KX_ConvertActuators.cpp
@@ -109,7 +109,7 @@
  * KX_BLENDERTRUNC needed to round 'almost' zero values to zero, else velocities etc. are incorrectly set
  */
 
-#define KX_BLENDERTRUNC(x)  (( x < 0.0001 && x > -0.0001 )  ? 0.0 : x)
+#define KX_BLENDERTRUNC(x)  (( x < 0.0001f && x > -0.0001f ) ? 0.0f : x)
 
 void BL_ConvertActuators(const char* maggiename,
 						 struct Object* blenderobject,
@@ -162,7 +162,7 @@ void BL_ConvertActuators(const char* maggiename,
 					KX_BLENDERTRUNC(obact->angularvelocity[1]),
 					KX_BLENDERTRUNC(obact->angularvelocity[2]));
 				short damping = obact->damping;
-				
+
 				/* Blender uses a bit vector internally for the local-flags. In */
 				/* KX, we have four bools. The compiler should be smart enough  */
 				/* to do the right thing. We need to explicitly convert here!   */
@@ -431,7 +431,7 @@ void BL_ConvertActuators(const char* maggiename,
 						new KX_SoundActuator(gameobj,
 						snd_sound,
 						soundact->volume,
-						(float)(exp((soundact->pitch / 12.0) * M_LN2)),
+						(float)(expf((soundact->pitch / 12.0f) * (float)M_LN2)),
 						is3d,
 						settings,
 						soundActuatorType);
@@ -578,8 +578,8 @@ void BL_ConvertActuators(const char* maggiename,
 				/* convert settings... degrees in the ui become radians  */ 
 				/* internally                                            */ 
 				if (conact->type == ACT_CONST_TYPE_ORI) {
-					min = (float)((MT_2_PI * conact->minloc[0])/360.0);
-					max = (float)((MT_2_PI * conact->maxloc[0])/360.0);
+					min = (float)(((float)MT_2_PI * conact->minloc[0]) / 360.0f);
+					max = (float)(((float)MT_2_PI * conact->maxloc[0]) / 360.0f);
 					switch (conact->mode) {
 					case ACT_CONST_DIRPX:
 						locrot = KX_ConstraintActuator::KX_ACT_CONSTRAINT_ORIX;
diff --git a/source/gameengine/Converter/KX_ConvertSensors.cpp b/source/gameengine/Converter/KX_ConvertSensors.cpp
index 2bd1688ca6d..93eeaaf05fb 100644
--- a/source/gameengine/Converter/KX_ConvertSensors.cpp
+++ b/source/gameengine/Converter/KX_ConvertSensors.cpp
@@ -23,14 +23,14 @@
  * Contributor(s): none yet.
  *
  * ***** END GPL LICENSE BLOCK *****
- * Conversion of Blender data blocks to KX sensor system
  */
 
 /** \file gameengine/Converter/KX_ConvertSensors.cpp
  *  \ingroup bgeconv
+ *
+ * Conversion of Blender data blocks to KX sensor system
  */
 
-
 #include 
 
 #if defined(WIN32) && !defined(FREE_WINDOWS)
@@ -476,7 +476,7 @@ void BL_ConvertSensors(struct Object* blenderobject,
 					// or the blenderradarsensor->angle?
 					// nzc: the angle is the opening angle. We need to init with 
 					// the axis-hull angle,so /2.0.
-					MT_Scalar factor = tan(MT_radians((blenderradarsensor->angle)/2.0));
+					MT_Scalar factor = tan(MT_radians((blenderradarsensor->angle) / 2.0f));
 					//MT_Scalar coneradius = coneheight * (factor / 2);
 					MT_Scalar coneradius = coneheight * factor;
 					
@@ -519,7 +519,7 @@ void BL_ConvertSensors(struct Object* blenderobject,
 					STR_String checkname = (bFindMaterial? blenderraysensor->matname : blenderraysensor->propname);
 
 					// don't want to get rays of length 0.0 or so
-					double distance = (blenderraysensor->range < 0.01 ? 0.01 : blenderraysensor->range );
+					double distance = (blenderraysensor->range < 0.01f ? 0.01f : blenderraysensor->range);
 					int axis = blenderraysensor->axisflag;
 
 					
diff --git a/source/gameengine/Ketsji/KX_CameraActuator.cpp b/source/gameengine/Ketsji/KX_CameraActuator.cpp
index dfe45b8cfcd..e009478c803 100644
--- a/source/gameengine/Ketsji/KX_CameraActuator.cpp
+++ b/source/gameengine/Ketsji/KX_CameraActuator.cpp
@@ -192,10 +192,10 @@ static void Kx_VecUpMat3(float vec[3], float mat[][3], short axis)
 		mat[coz][2] = 0.0f;
 	}
 	
-	inp= mat[coz][2];
-	mat[coy][0]= - inp*mat[coz][0];
-	mat[coy][1]= - inp*mat[coz][1];
-	mat[coy][2]= 1.0 - inp*mat[coz][2];
+	inp = mat[coz][2];
+	mat[coy][0] =      - inp * mat[coz][0];
+	mat[coy][1] =      - inp * mat[coz][1];
+	mat[coy][2] = 1.0f - inp * mat[coz][2];
 
 	if (Kx_Normalize((float *)mat[coy]) == 0.f) {
 		/* the camera is vertical, chose the y axis arbitrary */
@@ -260,7 +260,7 @@ bool KX_CameraActuator::Update(double curtime, bool frame)
 	/* C2: blender test_visibility function. Can this be a ray-test?         */
 
 	/* C3: fixed height  */
-	from[2] = (15.0*from[2] + lookat[2] + m_height)/16.0;
+	from[2] = (15.0f * from[2] + lookat[2] + m_height) / 16.0f;
 
 
 	/* C4: camera behind actor   */
@@ -310,22 +310,22 @@ bool KX_CameraActuator::Update(double curtime, bool frame)
 			break;
 	}
 	
-	inp= fp1[0]*fp2[0] + fp1[1]*fp2[1] + fp1[2]*fp2[2];
-	fac= (-1.0 + inp) * m_damping;
+	inp = fp1[0]*fp2[0] + fp1[1]*fp2[1] + fp1[2]*fp2[2];
+	fac = (-1.0f + inp) * m_damping;
 
 	from[0]+= fac*fp1[0];
 	from[1]+= fac*fp1[1];
 	from[2]+= fac*fp1[2];
 	
 	/* alleen alstie ervoor ligt: cross testen en loodrechte bijtellen */
-	if (inp<0.0) {
-		if (fp1[0]*fp2[1] - fp1[1]*fp2[0] > 0.0) {
-			from[0]-= fac*fp1[1];
-			from[1]+= fac*fp1[0];
+	if (inp < 0.0f) {
+		if (fp1[0] * fp2[1] - fp1[1] * fp2[0] > 0.0f) {
+			from[0] -= fac * fp1[1];
+			from[1] += fac * fp1[0];
 		}
 		else {
-			from[0]+= fac*fp1[1];
-			from[1]-= fac*fp1[0];
+			from[0] += fac * fp1[1];
+			from[1] -= fac * fp1[0];
 		}
 	}
 
@@ -334,17 +334,17 @@ bool KX_CameraActuator::Update(double curtime, bool frame)
 	rc[0]= (lookat[0]-from[0]);
 	rc[1]= (lookat[1]-from[1]);
 	rc[2]= (lookat[2]-from[2]);
-	distsq= rc[0]*rc[0] + rc[1]*rc[1] + rc[2]*rc[2];
+	distsq = rc[0]*rc[0] + rc[1]*rc[1] + rc[2]*rc[2];
 
 	if (distsq > maxdistsq) {
-		distsq = 0.15*(distsq-maxdistsq)/distsq;
+		distsq = 0.15f * (distsq - maxdistsq) / distsq;
 		
 		from[0] += distsq*rc[0];
 		from[1] += distsq*rc[1];
 		from[2] += distsq*rc[2];
 	}
 	else if (distsq < mindistsq) {
-		distsq = 0.15*(mindistsq-distsq)/mindistsq;
+		distsq = 0.15f * (mindistsq - distsq) / mindistsq;
 		
 		from[0] -= distsq*rc[0];
 		from[1] -= distsq*rc[1];
diff --git a/source/gameengine/Ketsji/KX_GameActuator.h b/source/gameengine/Ketsji/KX_GameActuator.h
index 8356bc1068b..0c1c4f0c277 100644
--- a/source/gameengine/Ketsji/KX_GameActuator.h
+++ b/source/gameengine/Ketsji/KX_GameActuator.h
@@ -1,29 +1,29 @@
-//
-// ***** BEGIN GPL LICENSE BLOCK *****
-//
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software Foundation,
-// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-//
-// The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
-// All rights reserved.
-//
-// The Original Code is: all of this file.
-//
-// Contributor(s): none yet.
-//
-// ***** END GPL LICENSE BLOCK *****
-//
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
 
 /** \file KX_GameActuator.h
  *  \ingroup ketsji
diff --git a/source/gameengine/Ketsji/KX_SCA_AddObjectActuator.cpp b/source/gameengine/Ketsji/KX_SCA_AddObjectActuator.cpp
index 39b7c44eda9..841feda5237 100644
--- a/source/gameengine/Ketsji/KX_SCA_AddObjectActuator.cpp
+++ b/source/gameengine/Ketsji/KX_SCA_AddObjectActuator.cpp
@@ -1,40 +1,39 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
 /** \file gameengine/Ketsji/KX_SCA_AddObjectActuator.cpp
  *  \ingroup ketsji
+ *
+ * Add an object when this actuator is triggered
  */
-//
-// Add an object when this actuator is triggered
-//
-//
-// ***** BEGIN GPL LICENSE BLOCK *****
-//
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software Foundation,
-// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-//
-// The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
-// All rights reserved.
-//
-// The Original Code is: all of this file.
-//
-// Contributor(s): none yet.
-//
-// ***** END GPL LICENSE BLOCK *****
-// Previously existed as:
-
-// \source\gameengine\GameLogic\SCA_AddObjectActuator.cpp
-
-// Please look here for revision history.
 
+/* Previously existed as:
+ * \source\gameengine\GameLogic\SCA_AddObjectActuator.cpp
+ * Please look here for revision history. */
 
 #include "KX_SCA_AddObjectActuator.h"
 #include "SCA_IScene.h"
diff --git a/source/gameengine/Ketsji/KX_SCA_AddObjectActuator.h b/source/gameengine/Ketsji/KX_SCA_AddObjectActuator.h
index 40136f429a2..e0aba795e01 100644
--- a/source/gameengine/Ketsji/KX_SCA_AddObjectActuator.h
+++ b/source/gameengine/Ketsji/KX_SCA_AddObjectActuator.h
@@ -1,28 +1,29 @@
-//
-// ***** BEGIN GPL LICENSE BLOCK *****
-//
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software Foundation,
-// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-//
-// The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
-// All rights reserved.
-//
-// The Original Code is: all of this file.
-//
-// Contributor(s): none yet.
-//
-// ***** END GPL LICENSE BLOCK *****
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
 
 /** \file KX_SCA_AddObjectActuator.h
  *  \ingroup ketsji
@@ -40,7 +41,6 @@
 #include "MT_Vector3.h"
 
 
-
 class SCA_IScene;
 
 class KX_SCA_AddObjectActuator : public SCA_IActuator
diff --git a/source/gameengine/Ketsji/KX_SCA_DynamicActuator.cpp b/source/gameengine/Ketsji/KX_SCA_DynamicActuator.cpp
index ff44fad1f3f..35c791e427d 100644
--- a/source/gameengine/Ketsji/KX_SCA_DynamicActuator.cpp
+++ b/source/gameengine/Ketsji/KX_SCA_DynamicActuator.cpp
@@ -1,41 +1,38 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
 /** \file gameengine/Ketsji/KX_SCA_DynamicActuator.cpp
  *  \ingroup ketsji
+ * Adjust dynamics settins for this object
  */
-//
-// Adjust dynamics settins for this object
-//
-//
-// ***** BEGIN GPL LICENSE BLOCK *****
-//
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software Foundation,
-// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-//
-// The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
-// All rights reserved.
-//
-// The Original Code is: all of this file.
-//
-// Contributor(s): none yet.
-//
-// ***** END GPL LICENSE BLOCK *****
 
-//
-// Previously existed as:
-
-// \source\gameengine\GameLogic\SCA_DynamicActuator.cpp
-
-// Please look here for revision history.
+/* Previously existed as:
+ * \source\gameengine\GameLogic\SCA_DynamicActuator.cpp
+ * Please look here for revision history. */
 
 #include "KX_SCA_DynamicActuator.h"
 
diff --git a/source/gameengine/Ketsji/KX_SCA_DynamicActuator.h b/source/gameengine/Ketsji/KX_SCA_DynamicActuator.h
index 885c7a0297f..01a91624c41 100644
--- a/source/gameengine/Ketsji/KX_SCA_DynamicActuator.h
+++ b/source/gameengine/Ketsji/KX_SCA_DynamicActuator.h
@@ -1,29 +1,29 @@
-//
-// ***** BEGIN GPL LICENSE BLOCK *****
-//
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software Foundation,
-// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-//
-// The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
-// All rights reserved.
-//
-// The Original Code is: all of this file.
-//
-// Contributor(s): Campbell Barton
-//
-// ***** END GPL LICENSE BLOCK *****
-//
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): Campbell Barton
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
 
 /** \file KX_SCA_DynamicActuator.h
  *  \ingroup ketsji
diff --git a/source/gameengine/Ketsji/KX_SCA_EndObjectActuator.h b/source/gameengine/Ketsji/KX_SCA_EndObjectActuator.h
index 374d5f2f211..1a503c074ed 100644
--- a/source/gameengine/Ketsji/KX_SCA_EndObjectActuator.h
+++ b/source/gameengine/Ketsji/KX_SCA_EndObjectActuator.h
@@ -1,29 +1,29 @@
-//
-// ***** BEGIN GPL LICENSE BLOCK *****
-//
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software Foundation,
-// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-//
-// The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
-// All rights reserved.
-//
-// The Original Code is: all of this file.
-//
-// Contributor(s): none yet.
-//
-// ***** END GPL LICENSE BLOCK *****
-//
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
 
 /** \file KX_SCA_EndObjectActuator.h
  *  \ingroup ketsji
diff --git a/source/gameengine/Ketsji/KX_SCA_ReplaceMeshActuator.cpp b/source/gameengine/Ketsji/KX_SCA_ReplaceMeshActuator.cpp
index 00a6e9e63d5..ffe5556cfe6 100644
--- a/source/gameengine/Ketsji/KX_SCA_ReplaceMeshActuator.cpp
+++ b/source/gameengine/Ketsji/KX_SCA_ReplaceMeshActuator.cpp
@@ -1,34 +1,35 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
 /** \file gameengine/Ketsji/KX_SCA_ReplaceMeshActuator.cpp
  *  \ingroup ketsji
+ *
+ * Replace the mesh for this actuator's parent
  */
-//
-// Replace the mesh for this actuator's parent
-//
-//
-// ***** BEGIN GPL LICENSE BLOCK *****
-//
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software Foundation,
-// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-//
-// The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
-// All rights reserved.
-//
-// The Original Code is: all of this file.
-//
-// Contributor(s): none yet.
-//
-// ***** END GPL LICENSE BLOCK *****
 
 //
 // Previously existed as:
diff --git a/source/gameengine/Ketsji/KX_SCA_ReplaceMeshActuator.h b/source/gameengine/Ketsji/KX_SCA_ReplaceMeshActuator.h
index c8e6123024d..d756c48f0f9 100644
--- a/source/gameengine/Ketsji/KX_SCA_ReplaceMeshActuator.h
+++ b/source/gameengine/Ketsji/KX_SCA_ReplaceMeshActuator.h
@@ -1,29 +1,29 @@
-//
-// ***** BEGIN GPL LICENSE BLOCK *****
-//
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software Foundation,
-// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-//
-// The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
-// All rights reserved.
-//
-// The Original Code is: all of this file.
-//
-// Contributor(s): none yet.
-//
-// ***** END GPL LICENSE BLOCK *****
-//
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
 
 /** \file KX_SCA_ReplaceMeshActuator.h
  *  \ingroup ketsji
diff --git a/source/gameengine/Ketsji/KX_SceneActuator.h b/source/gameengine/Ketsji/KX_SceneActuator.h
index 774f740dd00..8e157544e2e 100644
--- a/source/gameengine/Ketsji/KX_SceneActuator.h
+++ b/source/gameengine/Ketsji/KX_SceneActuator.h
@@ -1,29 +1,29 @@
-//
-// ***** BEGIN GPL LICENSE BLOCK *****
-//
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software Foundation,
-// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-//
-// The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
-// All rights reserved.
-//
-// The Original Code is: all of this file.
-//
-// Contributor(s): none yet.
-//
-// ***** END GPL LICENSE BLOCK *****
-//
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
 
 /** \file KX_SceneActuator.h
  *  \ingroup ketsji
diff --git a/source/gameengine/Ketsji/KX_TrackToActuator.cpp b/source/gameengine/Ketsji/KX_TrackToActuator.cpp
index af93121b50e..99732130f83 100644
--- a/source/gameengine/Ketsji/KX_TrackToActuator.cpp
+++ b/source/gameengine/Ketsji/KX_TrackToActuator.cpp
@@ -1,39 +1,40 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
 /** \file gameengine/Ketsji/KX_TrackToActuator.cpp
  *  \ingroup ketsji
+ *
+ * Replace the mesh for this actuator's parent
  */
-//
-// Replace the mesh for this actuator's parent
-//
-//
-// ***** BEGIN GPL LICENSE BLOCK *****
-//
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software Foundation,
-// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-//
-// The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
-// All rights reserved.
-//
-// The Original Code is: all of this file.
-//
-// Contributor(s): none yet.
-//
-// ***** END GPL LICENSE BLOCK *****
 
-// todo: not all trackflags / upflags are implemented/tested !
-// m_trackflag is used to determine the forward tracking direction
-// m_upflag for the up direction
-// normal situation is +y for forward, +z for up
+/* todo: not all trackflags / upflags are implemented/tested !
+ * m_trackflag is used to determine the forward tracking direction
+ * m_upflag for the up direction
+ * normal situation is +y for forward, +z for up */
 
 #include "MT_Scalar.h"
 #include "SCA_IActuator.h"
@@ -50,8 +51,6 @@
 /* Native functions                                                          */
 /* ------------------------------------------------------------------------- */
 
-
-
 KX_TrackToActuator::KX_TrackToActuator(SCA_IObject *gameobj, 
                                        SCA_IObject *ob,
                                        int time,
@@ -123,19 +122,18 @@ MT_Matrix3x3 EulToMat3(float *eul)
 
 
 /* old function from Blender */
-void Mat3ToEulOld(MT_Matrix3x3 mat, float *eul)
+void Mat3ToEulOld(MT_Matrix3x3 mat, float eul[3])
 {
-	MT_Scalar cy;
-	
-	cy = sqrt(mat[0][0]*mat[0][0] + mat[0][1]*mat[0][1]);
+	const float cy = sqrtf(mat[0][0] * mat[0][0] + mat[0][1] * mat[0][1]);
 
-	if (cy > 16.0*FLT_EPSILON) {
-		eul[0] = atan2(mat[1][2], mat[2][2]);
-		eul[1] = atan2(-mat[0][2], cy);
-		eul[2] = atan2(mat[0][1], mat[0][0]);
-	} else {
-		eul[0] = atan2(-mat[2][1], mat[1][1]);
-		eul[1] = atan2(-mat[0][2], cy);
+	if (cy > (float)(16.0f * FLT_EPSILON)) {
+		eul[0] = atan2f( mat[1][2], mat[2][2]);
+		eul[1] = atan2f(-mat[0][2], cy);
+		eul[2] = atan2f( mat[0][1], mat[0][0]);
+	}
+	else {
+		eul[0] = atan2f(-mat[2][1], mat[1][1]);
+		eul[1] = atan2f(-mat[0][2], cy);
 		eul[2] = 0.0;
 	}
 }
@@ -149,18 +147,18 @@ void compatible_eulFast(float *eul, float *oldrot)
 	
 	/* angular difference of 360 degrees */
 
-	dx= eul[0] - oldrot[0];
-	dy= eul[1] - oldrot[1];
-	dz= eul[2] - oldrot[2];
+	dx = eul[0] - oldrot[0];
+	dy = eul[1] - oldrot[1];
+	dz = eul[2] - oldrot[2];
 
-	if ( fabs(dx) > MT_PI) {
-		if (dx > 0.0) eul[0] -= MT_2_PI; else eul[0]+= MT_2_PI;
+	if (fabsf(dx) > (float)MT_PI) {
+		if (dx > 0.0f) eul[0] -= (float)MT_2_PI; else eul[0] += (float)MT_2_PI;
 	}
-	if ( fabs(dy) > MT_PI) {
-		if (dy > 0.0) eul[1] -= MT_2_PI; else eul[1]+= MT_2_PI;
+	if (fabsf(dy) > (float)MT_PI) {
+		if (dy > 0.0f) eul[1] -= (float)MT_2_PI; else eul[1] += (float)MT_2_PI;
 	}
-	if ( fabs(dz) > MT_PI ) {
-		if (dz > 0.0) eul[2] -= MT_2_PI; else eul[2]+= MT_2_PI;
+	if (fabsf(dz) > (float)MT_PI) {
+		if (dz > 0.0f) eul[2] -= (float)MT_2_PI; else eul[2] += (float)MT_2_PI;
 	}
 }
 
@@ -174,9 +172,9 @@ MT_Matrix3x3 matrix3x3_interpol(MT_Matrix3x3 oldmat, MT_Matrix3x3 mat, int m_tim
 	Mat3ToEulOld(mat, eul);
 	compatible_eulFast(eul, oldeul);
 	
-	eul[0]= (m_time*oldeul[0] + eul[0])/(1.0+m_time);
-	eul[1]= (m_time*oldeul[1] + eul[1])/(1.0+m_time);
-	eul[2]= (m_time*oldeul[2] + eul[2])/(1.0+m_time);
+	eul[0] = (m_time * oldeul[0] + eul[0]) / (1.0f + m_time);
+	eul[1] = (m_time * oldeul[1] + eul[1]) / (1.0f + m_time);
+	eul[2] = (m_time * oldeul[2] + eul[2]) / (1.0f + m_time);
 	
 	return EulToMat3(eul);
 }
diff --git a/source/gameengine/Ketsji/KX_TrackToActuator.h b/source/gameengine/Ketsji/KX_TrackToActuator.h
index 8eb69b1ad08..fb2ced2a415 100644
--- a/source/gameengine/Ketsji/KX_TrackToActuator.h
+++ b/source/gameengine/Ketsji/KX_TrackToActuator.h
@@ -1,29 +1,29 @@
-//
-// ***** BEGIN GPL LICENSE BLOCK *****
-//
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software Foundation,
-// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-//
-// The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
-// All rights reserved.
-//
-// The Original Code is: all of this file.
-//
-// Contributor(s): none yet.
-//
-// ***** END GPL LICENSE BLOCK *****
-//
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
 
 /** \file KX_TrackToActuator.h
  *  \ingroup ketsji
diff --git a/source/gameengine/VideoTexture/VideoBase.h b/source/gameengine/VideoTexture/VideoBase.h
index 3657a20b841..e221d876358 100644
--- a/source/gameengine/VideoTexture/VideoBase.h
+++ b/source/gameengine/VideoTexture/VideoBase.h
@@ -130,7 +130,7 @@ public:
 	float getFrameRate (void) { return m_frameRate; }
 	/// set frame rate
 	virtual void setFrameRate (float rate)
-	{ if (m_isFile) m_frameRate = rate > 0.0 ? rate : 1.0f; }
+	{ if (m_isFile) m_frameRate = rate > 0.0f ? rate : 1.0f; }
 
 protected:
 	/// video format

From 250cdd5e52dcb46c681fa5fe7935c670d5969977 Mon Sep 17 00:00:00 2001
From: Campbell Barton 
Date: Wed, 18 Jul 2012 23:07:07 +0000
Subject: [PATCH 089/108] code cleanup: remove commented includes - mostly from
 2.4x

---
 source/blender/blenkernel/intern/effect.c        |  3 ---
 source/blender/blenkernel/intern/lattice.c       |  3 ---
 source/blender/blenkernel/intern/softbody.c      |  5 ++---
 source/blender/blenlib/intern/freetypefont.c     |  3 ---
 .../compositor/intern/COM_WorkScheduler.cpp      |  7 +++++--
 .../editors/armature/editarmature_retarget.c     |  8 +-------
 .../editors/armature/editarmature_sketch.c       | 10 ----------
 source/blender/editors/armature/reeb.c           | 13 ++-----------
 source/blender/editors/transform/transform.c     |  9 ++-------
 .../editors/transform/transform_constraints.c    |  6 ------
 .../editors/transform/transform_generics.c       | 15 +--------------
 .../editors/transform/transform_orientations.c   |  5 -----
 .../blender/editors/transform/transform_snap.c   | 16 ++--------------
 .../render/intern/source/convertblender.c        |  1 -
 source/blender/render/intern/source/initrender.c |  2 --
 .../blender/windowmanager/intern/wm_init_exit.c  |  4 +---
 16 files changed, 16 insertions(+), 94 deletions(-)

diff --git a/source/blender/blenkernel/intern/effect.c b/source/blender/blenkernel/intern/effect.c
index a4e7676c602..4f4bafd00b4 100644
--- a/source/blender/blenkernel/intern/effect.c
+++ b/source/blender/blenkernel/intern/effect.c
@@ -29,7 +29,6 @@
  *  \ingroup bke
  */
 
-
 #include 
 
 #include 
@@ -98,8 +97,6 @@
 #include 
 #endif // WITH_MOD_FLUID
 
-//XXX #include "BIF_screen.h"
-
 EffectorWeights *BKE_add_effector_weights(Group *group)
 {
 	EffectorWeights *weights = MEM_callocN(sizeof(EffectorWeights), "EffectorWeights");
diff --git a/source/blender/blenkernel/intern/lattice.c b/source/blender/blenkernel/intern/lattice.c
index d5b1d3c98c8..0e73d10fa5f 100644
--- a/source/blender/blenkernel/intern/lattice.c
+++ b/source/blender/blenkernel/intern/lattice.c
@@ -29,8 +29,6 @@
  *  \ingroup bke
  */
 
-
-
 #include 
 #include 
 #include 
@@ -65,7 +63,6 @@
 
 #include "BKE_deform.h"
 
-//XXX #include "BIF_editdeform.h"
 
 void calc_lat_fudu(int flag, int res, float *fu, float *du)
 {
diff --git a/source/blender/blenkernel/intern/softbody.c b/source/blender/blenkernel/intern/softbody.c
index ed7fb39a015..2c105e4940d 100644
--- a/source/blender/blenkernel/intern/softbody.c
+++ b/source/blender/blenkernel/intern/softbody.c
@@ -78,9 +78,8 @@ variables on the UI for now
 #include "BKE_DerivedMesh.h"
 #include "BKE_pointcache.h"
 #include "BKE_deform.h"
-#include "BKE_mesh.h" 
-//XXX #include  "BIF_editdeform.h"
-//XXX #include  "BIF_graphics.h"
+#include "BKE_mesh.h"
+
 #include  "PIL_time.h"
 // #include  "ONL_opennl.h" remove linking to ONL for now
 
diff --git a/source/blender/blenlib/intern/freetypefont.c b/source/blender/blenlib/intern/freetypefont.c
index a499f9a81ea..6ce8b9ecf91 100644
--- a/source/blender/blenlib/intern/freetypefont.c
+++ b/source/blender/blenlib/intern/freetypefont.c
@@ -52,11 +52,8 @@
 #include "BLI_math.h"
 #include "BLI_utildefines.h"
 
-//XXX #include "BIF_toolbox.h"
-
 #include "BKE_font.h"
 
-
 #include "DNA_vfont_types.h"
 #include "DNA_packedFile_types.h"
 #include "DNA_curve_types.h"
diff --git a/source/blender/compositor/intern/COM_WorkScheduler.cpp b/source/blender/compositor/intern/COM_WorkScheduler.cpp
index 753940cd4f2..7d4134aca13 100644
--- a/source/blender/compositor/intern/COM_WorkScheduler.cpp
+++ b/source/blender/compositor/intern/COM_WorkScheduler.cpp
@@ -95,7 +95,9 @@ void ** g_highlightedNodesRead;
 		} \
 	} \
 }
-void COM_startReadHighlights() {
+
+void COM_startReadHighlights()
+{
 	if (g_highlightedNodesRead) {
 		delete [] g_highlightedNodesRead;
 	}
@@ -108,7 +110,8 @@ void COM_startReadHighlights() {
 	}
 }
 
-int COM_isHighlightedbNode(bNode* bnode) {
+int COM_isHighlightedbNode(bNode* bnode)
+{
 	if (!g_highlightedNodesRead) return false;
 	for (int i = 0 ; i < MAX_HIGHLIGHT; i++) {
 		void* p = g_highlightedNodesRead[i];
diff --git a/source/blender/editors/armature/editarmature_retarget.c b/source/blender/editors/armature/editarmature_retarget.c
index 91c342ec070..caadee5f941 100644
--- a/source/blender/editors/armature/editarmature_retarget.c
+++ b/source/blender/editors/armature/editarmature_retarget.c
@@ -25,7 +25,6 @@
  *  \ingroup edarmature
  */
 
-
 #include 
 #include 
 #include 
@@ -49,8 +48,6 @@
 #include "BLI_rand.h"
 #include "BLI_threads.h"
 
-//#include "BDR_editobject.h"
-
 #include "BKE_constraint.h"
 #include "BKE_armature.h"
 #include "BKE_context.h"
@@ -60,10 +57,7 @@
 
 #include "BIF_retarget.h"
 
-
-//#include "mydevice.h"
-#include "reeb.h" // FIX ME
-//#include "blendef.h"
+#include "reeb.h" /* FIX ME */
 
 #include "armature_intern.h"
 
diff --git a/source/blender/editors/armature/editarmature_sketch.c b/source/blender/editors/armature/editarmature_sketch.c
index 06ecf76ba3e..78d3d8dc64d 100644
--- a/source/blender/editors/armature/editarmature_sketch.c
+++ b/source/blender/editors/armature/editarmature_sketch.c
@@ -22,7 +22,6 @@
  *  \ingroup edarmature
  */
 
-
 #include 
 #include 
 #include 
@@ -49,27 +48,18 @@
 #include "ED_screen.h"
 
 #include "BIF_gl.h"
-//#include "BIF_screen.h"
-//#include "BIF_space.h"
-//#include "BIF_mywindow.h"
 #include "ED_armature.h"
 #include "armature_intern.h"
-//#include "BIF_sketch.h"
 #include "BIF_retarget.h"
 #include "BIF_generate.h"
-//#include "BIF_interface.h"
 
 #include "ED_transform.h"
 
 #include "WM_api.h"
 #include "WM_types.h"
 
-//#include "blendef.h"
-//#include "mydevice.h"
 #include "reeb.h"
 
-
-
 typedef int (*GestureDetectFct)(bContext *, SK_Gesture *, SK_Sketch *);
 typedef void (*GestureApplyFct)(bContext *, SK_Gesture *, SK_Sketch *);
 
diff --git a/source/blender/editors/armature/reeb.c b/source/blender/editors/armature/reeb.c
index af252ffe60c..ce4e1db23b5 100644
--- a/source/blender/editors/armature/reeb.c
+++ b/source/blender/editors/armature/reeb.c
@@ -24,11 +24,10 @@
  *  \ingroup edarmature
  */
 
- 
 #include 
-#include  // for memcpy
+#include  /* for memcpy */
 #include 
-#include  // for qsort
+#include  /* for qsort */
 #include 
 
 #include "DNA_scene_types.h"
@@ -45,16 +44,8 @@
 #include "BLI_ghash.h"
 #include "BLI_heap.h"
 
-//#include "BDR_editobject.h"
-
-//#include "BIF_interface.h"
-//#include "BIF_toolbox.h"
-//#include "BIF_graphics.h"
-
 #include "BKE_mesh.h"
 
-//#include "blendef.h"
-
 #include "ONL_opennl.h"
 
 #include "reeb.h"
diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c
index 5232371fcaf..7bcf6ba58f1 100644
--- a/source/blender/editors/transform/transform.c
+++ b/source/blender/editors/transform/transform.c
@@ -29,7 +29,6 @@
  *  \ingroup edtransform
  */
 
-
 #include 
 #include 
 #include 
@@ -37,9 +36,9 @@
 #include 
 
 #ifndef WIN32
-#include 
+#  include 
 #else
-#include 
+#  include 
 #endif
 
 #include "MEM_guardedalloc.h"
@@ -90,10 +89,6 @@
 
 #include "UI_resources.h"
 
-//#include "blendef.h"
-//
-//#include "mydevice.h"
-
 #include "transform.h"
 
 #include 
diff --git a/source/blender/editors/transform/transform_constraints.c b/source/blender/editors/transform/transform_constraints.c
index 034ea3eb704..7c0d4f10186 100644
--- a/source/blender/editors/transform/transform_constraints.c
+++ b/source/blender/editors/transform/transform_constraints.c
@@ -53,7 +53,6 @@
 
 #include "BKE_context.h"
 
-
 #include "ED_image.h"
 #include "ED_view3d.h"
 
@@ -61,13 +60,8 @@
 #include "BLI_utildefines.h"
 #include "BLI_string.h"
 
-//#include "blendef.h"
-//
-//#include "mydevice.h"
-
 #include "UI_resources.h"
 
-
 #include "transform.h"
 
 static void drawObjectConstraint(TransInfo *t);
diff --git a/source/blender/editors/transform/transform_generics.c b/source/blender/editors/transform/transform_generics.c
index 9f335b4afe7..dba597d316d 100644
--- a/source/blender/editors/transform/transform_generics.c
+++ b/source/blender/editors/transform/transform_generics.c
@@ -29,13 +29,12 @@
  *  \ingroup edtransform
  */
 
-
 #include 
 #include 
 
 #include "MEM_guardedalloc.h"
 
-#include "BLO_sys_types.h" // for intptr_t support
+#include "BLO_sys_types.h" /* for intptr_t support */
 
 #include "DNA_anim_types.h"
 #include "DNA_armature_types.h"
@@ -58,14 +57,8 @@
 
 #include "RNA_access.h"
 
-//#include "BIF_screen.h"
-//#include "BIF_mywindow.h"
 #include "BIF_gl.h"
 #include "BIF_glutil.h"
-//#include "BIF_editmesh.h"
-//#include "BIF_editsima.h"
-//#include "BIF_editparticle.h"
-//#include "BIF_meshtools.h"
 
 #include "BKE_animsys.h"
 #include "BKE_action.h"
@@ -96,17 +89,11 @@
 #include "ED_clip.h"
 #include "ED_screen.h"
 
-//#include "BDR_unwrapper.h"
-
 #include "WM_types.h"
 #include "WM_api.h"
 
 #include "UI_resources.h"
 
-//#include "blendef.h"
-//
-//#include "mydevice.h"
-
 #include "transform.h"
 
 /* ************************** Functions *************************** */
diff --git a/source/blender/editors/transform/transform_orientations.c b/source/blender/editors/transform/transform_orientations.c
index 97fc173f9a1..b9583fc21e1 100644
--- a/source/blender/editors/transform/transform_orientations.c
+++ b/source/blender/editors/transform/transform_orientations.c
@@ -50,11 +50,6 @@
 
 #include "BLF_translation.h"
 
-//#include "BIF_editmesh.h"
-//#include "BIF_interface.h"
-//#include "BIF_space.h"
-//#include "BIF_toolbox.h"
-
 #include "ED_armature.h"
 #include "ED_mesh.h"
 
diff --git a/source/blender/editors/transform/transform_snap.c b/source/blender/editors/transform/transform_snap.c
index 3847087111e..1286a520bb9 100644
--- a/source/blender/editors/transform/transform_snap.c
+++ b/source/blender/editors/transform/transform_snap.c
@@ -29,7 +29,6 @@
  *  \ingroup edtransform
  */
 
- 
 #include 
 #include 
 #include 
@@ -41,7 +40,7 @@
 #include "DNA_scene_types.h"
 #include "DNA_object_types.h"
 #include "DNA_mesh_types.h"
-#include "DNA_meshdata_types.h" // Temporary, for snapping to other unselected meshes
+#include "DNA_meshdata_types.h"  /* Temporary, for snapping to other unselected meshes */
 #include "DNA_node_types.h"
 #include "DNA_space_types.h"
 #include "DNA_screen_types.h"
@@ -54,20 +53,11 @@
 #include "BLI_blenlib.h"
 #include "BLI_utildefines.h"
 
-//#include "BDR_drawobject.h"
-//
-//#include "editmesh.h"
-//#include "BIF_editsima.h"
 #include "BIF_gl.h"
-//#include "BIF_mywindow.h"
-//#include "BIF_screen.h"
-//#include "BIF_editsima.h"
-//#include "BIF_drawimage.h"
-//#include "BIF_editmesh.h"
 
 #include "BKE_DerivedMesh.h"
 #include "BKE_object.h"
-#include "BKE_anim.h" /* for duplis */
+#include "BKE_anim.h"  /* for duplis */
 #include "BKE_context.h"
 #include "BKE_tessmesh.h"
 #include "BKE_mesh.h"
@@ -88,8 +78,6 @@
 
 #include "transform.h"
 
-//#include "blendef.h" /* for selection modes */
-
 #define USE_BVH_FACE_SNAP
 
 /********************* PROTOTYPES ***********************/
diff --git a/source/blender/render/intern/source/convertblender.c b/source/blender/render/intern/source/convertblender.c
index eaab1b988ae..3408eb74b58 100644
--- a/source/blender/render/intern/source/convertblender.c
+++ b/source/blender/render/intern/source/convertblender.c
@@ -27,7 +27,6 @@
  *  \ingroup render
  */
 
-
 #include 
 #include 
 #include 
diff --git a/source/blender/render/intern/source/initrender.c b/source/blender/render/intern/source/initrender.c
index 33a777381aa..cc8f6682781 100644
--- a/source/blender/render/intern/source/initrender.c
+++ b/source/blender/render/intern/source/initrender.c
@@ -27,8 +27,6 @@
  *  \ingroup render
  */
 
-
-
 /* Global includes */
 
 #include 
diff --git a/source/blender/windowmanager/intern/wm_init_exit.c b/source/blender/windowmanager/intern/wm_init_exit.c
index 2098d872357..7a885d60bff 100644
--- a/source/blender/windowmanager/intern/wm_init_exit.c
+++ b/source/blender/windowmanager/intern/wm_init_exit.c
@@ -28,7 +28,6 @@
  *  \ingroup wm
  */
 
-
 #include 
 #include 
 #include 
@@ -63,7 +62,6 @@
 #include "BKE_tracking.h" /* free tracking clipboard */
 
 #include "BLI_listbase.h"
-// #include "BLI_scanfill.h"
 #include "BLI_string.h"
 #include "BLI_utildefines.h"
 
@@ -75,7 +73,7 @@
 #endif
 
 #ifdef WITH_GAMEENGINE
-#include "BL_System.h"
+#  include "BL_System.h"
 #endif
 #include "GHOST_Path-api.h"
 #include "GHOST_C-api.h"

From 21c08954668d0acf26db26e66777b84f6c6c17d1 Mon Sep 17 00:00:00 2001
From: Campbell Barton 
Date: Thu, 19 Jul 2012 08:04:12 +0000
Subject: [PATCH 090/108] poll function for edge loop delete.

---
 release/scripts/startup/bl_operators/wm.py | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/release/scripts/startup/bl_operators/wm.py b/release/scripts/startup/bl_operators/wm.py
index 75c5ef849ad..18450ebe316 100644
--- a/release/scripts/startup/bl_operators/wm.py
+++ b/release/scripts/startup/bl_operators/wm.py
@@ -36,6 +36,10 @@ class MESH_OT_delete_edgeloop(Operator):
     bl_idname = "mesh.delete_edgeloop"
     bl_label = "Delete Edge Loop"
 
+    @classmethod
+    def poll(cls, context):
+        return bpy.ops.transform.edge_slide.poll()
+
     def execute(self, context):
         if 'FINISHED' in bpy.ops.transform.edge_slide(value=1.0):
             bpy.ops.mesh.select_more()

From 2721a17a31e780b70cc0421c552217134320da80 Mon Sep 17 00:00:00 2001
From: Lukas Toenne 
Date: Thu, 19 Jul 2012 08:23:56 +0000
Subject: [PATCH 091/108] Fix #32118, Reroute nodes inside groups get created
 in wonky places. The operator needs to take into account the potential offset
 from the group node (most operators use the node_add_node helper function
 which does this).

---
 source/blender/editors/space_node/node_edit.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/source/blender/editors/space_node/node_edit.c b/source/blender/editors/space_node/node_edit.c
index 8b7251c2018..512781f9b77 100644
--- a/source/blender/editors/space_node/node_edit.c
+++ b/source/blender/editors/space_node/node_edit.c
@@ -3142,6 +3142,7 @@ static int add_reroute_exec(bContext *C, wmOperator *op)
 {
 	SpaceNode *snode = CTX_wm_space_node(C);
 	ARegion *ar = CTX_wm_region(C);
+	bNode *gnode = node_tree_get_editgroup(snode->nodetree);
 	float mcoords[256][2];
 	int i = 0;
 
@@ -3174,6 +3175,10 @@ static int add_reroute_exec(bContext *C, wmOperator *op)
 				rerouteNode = nodeAddNode(snode->edittree, &ntemp);
 				rerouteNode->locx = insertPoint[0];
 				rerouteNode->locy = insertPoint[1];
+				if (gnode) {
+					rerouteNode->locx -= gnode->locx;
+					rerouteNode->locy -= gnode->locy;
+				}
 				
 				nodeAddLink(snode->edittree, link->fromnode, link->fromsock, rerouteNode, rerouteNode->inputs.first);
 				link->fromnode = rerouteNode;

From 4408a4aeffaa48a4346d03d758dce2fb5043b8d3 Mon Sep 17 00:00:00 2001
From: Campbell Barton 
Date: Thu, 19 Jul 2012 09:23:31 +0000
Subject: [PATCH 092/108] remove unneeded externs

---
 source/blender/python/generic/bpy_internal_import.c | 9 ++++++---
 source/blender/python/generic/bpy_internal_import.h | 3 ---
 2 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/source/blender/python/generic/bpy_internal_import.c b/source/blender/python/generic/bpy_internal_import.c
index 5852a68e7b7..d4158210cc8 100644
--- a/source/blender/python/generic/bpy_internal_import.c
+++ b/source/blender/python/generic/bpy_internal_import.c
@@ -48,12 +48,15 @@
 #include "BLI_utildefines.h"
 
 /* UNUSED */
-#include "BKE_text.h" /* txt_to_buf */	
+#include "BKE_text.h"  /* txt_to_buf */
 #include "BKE_main.h"
 
 static Main *bpy_import_main = NULL;
 static ListBase bpy_import_main_list;
 
+static PyMethodDef bpy_import_meth;
+static PyMethodDef bpy_reload_meth;
+
 /* 'builtins' is most likely PyEval_GetBuiltins() */
 void bpy_import_init(PyObject *builtins)
 {
@@ -335,5 +338,5 @@ static PyObject *blender_reload(PyObject *UNUSED(self), PyObject *module)
 	return newmodule;
 }
 
-PyMethodDef bpy_import_meth = {"bpy_import_meth", (PyCFunction)blender_import, METH_VARARGS | METH_KEYWORDS, "blenders import"};
-PyMethodDef bpy_reload_meth = {"bpy_reload_meth", (PyCFunction)blender_reload, METH_O, "blenders reload"};
+static PyMethodDef bpy_import_meth = {"bpy_import_meth", (PyCFunction)blender_import, METH_VARARGS | METH_KEYWORDS, "blenders import"};
+static PyMethodDef bpy_reload_meth = {"bpy_reload_meth", (PyCFunction)blender_reload, METH_O, "blenders reload"};
diff --git a/source/blender/python/generic/bpy_internal_import.h b/source/blender/python/generic/bpy_internal_import.h
index 980e6edca03..1592ec52b4c 100644
--- a/source/blender/python/generic/bpy_internal_import.h
+++ b/source/blender/python/generic/bpy_internal_import.h
@@ -55,9 +55,6 @@ PyObject*	bpy_text_reimport(PyObject *module, int *found);
 
 void bpy_text_filename_get(char *fn, size_t fn_len, struct Text *text);
 
-extern PyMethodDef bpy_import_meth;
-extern PyMethodDef bpy_reload_meth;
-
 /* The game engine has its own Main struct, if this is set search this rather than G.main */
 struct Main *bpy_import_main_get(void);
 void bpy_import_main_set(struct Main *maggie);

From 4bc46b18d1e3d3e72a27e7f721cd0800b8ff3a4f Mon Sep 17 00:00:00 2001
From: Campbell Barton 
Date: Thu, 19 Jul 2012 09:55:49 +0000
Subject: [PATCH 093/108] handy function for getting a python stacktrace while
 debugging in gdb

---
 source/blender/python/generic/py_capi_utils.c | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/source/blender/python/generic/py_capi_utils.c b/source/blender/python/generic/py_capi_utils.c
index a9b9a5d6cf6..657844ebfff 100644
--- a/source/blender/python/generic/py_capi_utils.c
+++ b/source/blender/python/generic/py_capi_utils.c
@@ -152,6 +152,21 @@ void PyC_LineSpit(void)
 	fprintf(stderr, "%s:%d\n", filename, lineno);
 }
 
+void PyC_StackSpit(void)
+{
+	/* Note, allow calling from outside python (RNA) */
+	if (!PYC_INTERPRETER_ACTIVE) {
+		fprintf(stderr, "python line lookup failed, interpreter inactive\n");
+		return;
+	}
+	else {
+		/* lame but handy */
+		PyGILState_STATE gilstate = PyGILState_Ensure();
+		PyRun_SimpleString("__import__('traceback').print_stack()");
+		PyGILState_Release(gilstate);
+	}
+}
+
 void PyC_FileAndNum(const char **filename, int *lineno)
 {
 	PyFrameObject *frame;

From 9c8edae7d4ef799b19f6487feb21ce7fbcf5ee07 Mon Sep 17 00:00:00 2001
From: Campbell Barton 
Date: Thu, 19 Jul 2012 10:23:25 +0000
Subject: [PATCH 094/108] fix for separate loose parts doing full depsgraph
 rebuild for every object split off.

---
 source/blender/editors/armature/editarmature.c | 2 ++
 source/blender/editors/curve/editcurve.c       | 2 ++
 source/blender/editors/mesh/editmesh_tools.c   | 7 ++++++-
 source/blender/editors/object/object_add.c     | 7 +++++--
 source/blender/python/generic/py_capi_utils.h  | 3 ++-
 5 files changed, 17 insertions(+), 4 deletions(-)

diff --git a/source/blender/editors/armature/editarmature.c b/source/blender/editors/armature/editarmature.c
index 2a3f2182fdf..e0aa33d0207 100644
--- a/source/blender/editors/armature/editarmature.c
+++ b/source/blender/editors/armature/editarmature.c
@@ -1213,6 +1213,8 @@ static int separate_armature_exec(bContext *C, wmOperator *UNUSED(op))
 	
 	/* 2) duplicate base */
 	newbase = ED_object_add_duplicate(bmain, scene, oldbase, USER_DUP_ARM); /* only duplicate linked armature */
+	DAG_scene_sort(bmain, scene);
+
 	newob = newbase->object;
 	newbase->flag &= ~SELECT;
 	
diff --git a/source/blender/editors/curve/editcurve.c b/source/blender/editors/curve/editcurve.c
index e8a71a35576..a9646aaabf4 100644
--- a/source/blender/editors/curve/editcurve.c
+++ b/source/blender/editors/curve/editcurve.c
@@ -1369,6 +1369,8 @@ static int separate_exec(bContext *C, wmOperator *op)
 	
 	/* 1. duplicate the object and data */
 	newbase = ED_object_add_duplicate(bmain, scene, oldbase, 0); /* 0 = fully linked */
+	DAG_scene_sort(bmain, scene);
+
 	ED_base_object_select(newbase, BA_DESELECT);
 	newob = newbase->object;
 
diff --git a/source/blender/editors/mesh/editmesh_tools.c b/source/blender/editors/mesh/editmesh_tools.c
index 29f38342dd2..5657cef4fd2 100644
--- a/source/blender/editors/mesh/editmesh_tools.c
+++ b/source/blender/editors/mesh/editmesh_tools.c
@@ -2815,7 +2815,8 @@ static int mesh_separate_selected(Main *bmain, Scene *scene, Base *editbase, wmO
 	CustomData_bmesh_init_pool(&bm_new->ldata, bm_mesh_allocsize_default.totloop, BM_LOOP);
 	CustomData_bmesh_init_pool(&bm_new->pdata, bm_mesh_allocsize_default.totface, BM_FACE);
 		
-	basenew = ED_object_add_duplicate(bmain, scene, editbase, USER_DUP_MESH);   /* 0 = fully linked */
+	basenew = ED_object_add_duplicate(bmain, scene, editbase, USER_DUP_MESH);
+	/* DAG_scene_sort(bmain, scene); */ /* normally would call directly after but in this case delay recalc */
 	assign_matarar(basenew->object, give_matarar(obedit), *give_totcolp(obedit)); /* new in 2.5 */
 
 	ED_base_object_select(basenew, BA_DESELECT);
@@ -2968,6 +2969,10 @@ static int edbm_separate_exec(bContext *C, wmOperator *op)
 
 	if (retval) {
 		BMEditMesh *em = BMEdit_FromObject(base->object);
+
+		/* delay depsgraph recalc until all objects are duplicated */
+		DAG_scene_sort(bmain, scene);
+
 		EDBM_update_generic(C, em, TRUE);
 
 		return OPERATOR_FINISHED;
diff --git a/source/blender/editors/object/object_add.c b/source/blender/editors/object/object_add.c
index 7ab20033239..21eab5bd4dc 100644
--- a/source/blender/editors/object/object_add.c
+++ b/source/blender/editors/object/object_add.c
@@ -1854,7 +1854,9 @@ static Base *object_add_duplicate_internal(Main *bmain, Scene *scene, Base *base
 
 /* single object duplicate, if dupflag==0, fully linked, else it uses the flags given */
 /* leaves selection of base/object unaltered.
- * note: don't call this within a loop since clear_* funcs loop over the entire database. */
+ * note: don't call this within a loop since clear_* funcs loop over the entire database.
+ * note: caller must do DAG_scene_sort(bmain, scene);
+ *       this is not done automatic since we may duplicate many objects in a batch */
 Base *ED_object_add_duplicate(Main *bmain, Scene *scene, Base *base, int dupflag)
 {
 	Base *basen;
@@ -1874,7 +1876,8 @@ Base *ED_object_add_duplicate(Main *bmain, Scene *scene, Base *base, int dupflag
 	BKE_object_relink(ob);
 	set_sca_new_poins_ob(ob);
 
-	DAG_scene_sort(bmain, scene);
+	/* DAG_scene_sort(bmain, scene); */ /* caller must do */
+
 	if (ob->data) {
 		ED_render_id_flush_update(bmain, ob->data);
 	}
diff --git a/source/blender/python/generic/py_capi_utils.h b/source/blender/python/generic/py_capi_utils.h
index 9ef171256aa..481cfb17c7a 100644
--- a/source/blender/python/generic/py_capi_utils.h
+++ b/source/blender/python/generic/py_capi_utils.h
@@ -24,12 +24,13 @@
  *  \ingroup pygen
  */
 
- 
+
 #ifndef __PY_CAPI_UTILS_H__
 #define __PY_CAPI_UTILS_H__
 
 void			PyC_ObSpit(const char *name, PyObject *var);
 void			PyC_LineSpit(void);
+void			PyC_StackSpit(void);
 PyObject *		PyC_ExceptionBuffer(void);
 PyObject *		PyC_Object_GetAttrStringArgs(PyObject *o, Py_ssize_t n, ...);
 PyObject *		PyC_Err_Format_Prefix(PyObject *exception_type_prefix, const char *format, ...);

From a56f4fee38e17d05964941a5edc2850c217309d7 Mon Sep 17 00:00:00 2001
From: Jeroen Bakker 
Date: Thu, 19 Jul 2012 11:05:18 +0000
Subject: [PATCH 095/108] Fix for  * [#32040] size-input of a blur-node is
 uniform for the whole picture  * [#32062] Blur node Size input is not working
 with  * [#32140] Blur Node using a greyscale input as size multiplier fails
 to work

Node now has a new option (new compositor cannot detect if the connected
part is a single value, or an image connected).

With this option the use of a reference image to multiply the size of
the blur per pixel can be enabled/disabled.

Regards,
Jeroen
 - At Mind -
---
 .../blender/compositor/nodes/COM_BlurNode.cpp |  40 ++++
 .../COM_GaussianBokehBlurOperation.cpp        | 173 +++++++++---------
 .../COM_GaussianBokehBlurOperation.h          |  20 +-
 source/blender/editors/space_node/drawnode.c  |  13 +-
 source/blender/makesdna/DNA_node_types.h      |   4 +
 source/blender/makesrna/intern/rna_nodetree.c |   6 +-
 6 files changed, 153 insertions(+), 103 deletions(-)

diff --git a/source/blender/compositor/nodes/COM_BlurNode.cpp b/source/blender/compositor/nodes/COM_BlurNode.cpp
index 5447652c238..9b945887ec2 100644
--- a/source/blender/compositor/nodes/COM_BlurNode.cpp
+++ b/source/blender/compositor/nodes/COM_BlurNode.cpp
@@ -25,9 +25,13 @@
 #include "DNA_node_types.h"
 #include "COM_GaussianXBlurOperation.h"
 #include "COM_GaussianYBlurOperation.h"
+#include "COM_GaussianAlphaXBlurOperation.h"
+#include "COM_GaussianAlphaYBlurOperation.h"
 #include "COM_ExecutionSystem.h"
 #include "COM_GaussianBokehBlurOperation.h"
 #include "COM_FastGaussianBlurOperation.h"
+#include "COM_MathBaseOperation.h"
+#include "COM_SetValueOperation.h"
 
 BlurNode::BlurNode(bNode *editorNode) : Node(editorNode)
 {
@@ -56,6 +60,42 @@ void BlurNode::convertToOperations(ExecutionSystem *graph, CompositorContext *co
 		graph->addOperation(operationfgb);
 		addPreviewOperation(graph, operationfgb->getOutputSocket());
 	}
+	else if (editorNode->custom1 & CMP_NODEFLAG_BLUR_REFERENCE) {
+		MathAddOperation *clamp = new MathAddOperation();
+		SetValueOperation *zero = new SetValueOperation();
+		addLink(graph, zero->getOutputSocket(), clamp->getInputSocket(1));
+		this->getInputSocket(1)->relinkConnections(clamp->getInputSocket(0), 1, graph);
+		zero->setValue(0.0f);
+		clamp->setUseClamp(true);
+		graph->addOperation(clamp);
+		graph->addOperation(zero);
+	
+		GaussianAlphaXBlurOperation *operationx = new GaussianAlphaXBlurOperation();
+		operationx->setData(data);
+		operationx->setbNode(editorNode);
+		operationx->setQuality(quality);
+		operationx->setSize(1.0f);
+		addLink(graph, clamp->getOutputSocket(), operationx->getInputSocket(0));
+		graph->addOperation(operationx);
+
+		GaussianYBlurOperation *operationy = new GaussianYBlurOperation();
+		operationy->setData(data);
+		operationy->setbNode(editorNode);
+		operationy->setQuality(quality);
+		operationy->setSize(1.0f);
+		addLink(graph, operationx->getOutputSocket(), operationy->getInputSocket(0));
+		graph->addOperation(operationy);
+
+		GaussianBlurReferenceOperation *operation = new GaussianBlurReferenceOperation();
+		operation->setData(data);
+		operation->setbNode(editorNode);
+		operation->setQuality(quality);
+		this->getInputSocket(0)->relinkConnections(operation->getInputSocket(0), 0, graph);
+		addLink(graph, operationy->getOutputSocket(), operation->getInputSocket(1));
+		graph->addOperation(operation);
+		this->getOutputSocket(0)->relinkConnections(operation->getOutputSocket());
+		addPreviewOperation(graph, operation->getOutputSocket());
+	}
 	else if (!data->bokeh) {
 		GaussianXBlurOperation *operationx = new GaussianXBlurOperation();
 		operationx->setData(data);
diff --git a/source/blender/compositor/operations/COM_GaussianBokehBlurOperation.cpp b/source/blender/compositor/operations/COM_GaussianBokehBlurOperation.cpp
index 93cc39849a2..fd70d0d329a 100644
--- a/source/blender/compositor/operations/COM_GaussianBokehBlurOperation.cpp
+++ b/source/blender/compositor/operations/COM_GaussianBokehBlurOperation.cpp
@@ -22,7 +22,7 @@
 
 #include "COM_GaussianBokehBlurOperation.h"
 #include "BLI_math.h"
-
+#include "MEM_guardedalloc.h"
 extern "C" {
 	#include "RE_pipeline.h"
 }
@@ -198,25 +198,20 @@ bool GaussianBokehBlurOperation::determineDependingAreaOfInterest(rcti *input, R
 }
 
 // reference image
-GaussianBokehBlurReferenceOperation::GaussianBokehBlurReferenceOperation() : NodeOperation()
+GaussianBlurReferenceOperation::GaussianBlurReferenceOperation() : BlurBaseOperation(COM_DT_COLOR)
 {
-	this->addInputSocket(COM_DT_COLOR);
-	this->addInputSocket(COM_DT_VALUE);
-	this->addOutputSocket(COM_DT_COLOR);
-	this->setComplex(true);
-	this->m_gausstab = NULL;
-	this->m_inputImage = NULL;
-	this->m_inputSize = NULL;
+	this->m_maintabs = NULL;
 }
 
-void *GaussianBokehBlurReferenceOperation::initializeTileData(rcti *rect)
+void *GaussianBlurReferenceOperation::initializeTileData(rcti *rect)
 {
 	void *buffer = getInputOperation(0)->initializeTileData(NULL);
 	return buffer;
 }
 
-void GaussianBokehBlurReferenceOperation::initExecution()
+void GaussianBlurReferenceOperation::initExecution()
 {
+	BlurBaseOperation::initExecution();
 	// setup gaustab
 	this->m_data->image_in_width = this->getWidth();
 	this->m_data->image_in_height = this->getHeight();
@@ -237,100 +232,106 @@ void GaussianBokehBlurReferenceOperation::initExecution()
 		}
 	}
 	
+	
+	/* horizontal */
+	m_radx = (float)this->m_data->sizex;
+	int imgx = getWidth()/2;
+	if (m_radx > imgx)
+		m_radx = imgx;
+	else if (m_radx < 1)
+		m_radx = 1;
+	m_radxf = (float)m_radx;
+
+	/* vertical */
+	m_rady = (float)this->m_data->sizey;
+	int imgy = getHeight()/2;
+	if (m_rady > imgy)
+		m_rady = imgy;
+	else if (m_rady < 1)
+		m_rady = 1;
+	m_radyf = (float)m_rady;
 	updateGauss();
-	this->m_inputImage = this->getInputSocketReader(0);
-	this->m_inputSize = this->getInputSocketReader(1);
 }
 
-void GaussianBokehBlurReferenceOperation::updateGauss()
+void GaussianBlurReferenceOperation::updateGauss()
 {
-	int n;
-	float *dgauss;
-	float *ddgauss;
-	int j, i;
-
-	n = (2 * radx + 1) * (2 * rady + 1);
-
-	/* create a full filter image */
-	ddgauss = new float[n];
-	dgauss = ddgauss;
-	for (j = -rady; j <= rady; j++) {
-		for (i = -radx; i <= radx; i++, dgauss++) {
-			float fj = (float)j / radyf;
-			float fi = (float)i / radxf;
-			float dist = sqrt(fj * fj + fi * fi);
-			*dgauss = RE_filter_value(this->m_data->filtertype, dist);
-		}
-	}
-	this->m_gausstab = ddgauss;
+	int i;
+	int x = MAX2(m_radx, m_rady);
+	this->m_maintabs = (float**)MEM_mallocN(x * sizeof(float *), "gauss array");
+	for (i = 0; i < x; i++)
+		m_maintabs[i] = make_gausstab(i + 1);
 }
 
-void GaussianBokehBlurReferenceOperation::executePixel(float *color, int x, int y, void *data)
+void GaussianBlurReferenceOperation::executePixel(float *color, int x, int y, void *data)
 {
-	float tempColor[4];
+	MemoryBuffer *memorybuffer = (MemoryBuffer*)data;
+	float *buffer = memorybuffer->getBuffer();
+	float *gausstabx, *gausstabcenty;
+	float *gausstaby, *gausstabcentx;
+	int i, j;
+	float *src;
+	register float sum, val;
+	float rval, gval, bval, aval;
+	int imgx = getWidth();
+	int imgy = getHeight();
 	float tempSize[4];
-	tempColor[0] = 0;
-	tempColor[1] = 0;
-	tempColor[2] = 0;
-	tempColor[3] = 0;
-	float multiplier_accum = 0;
-	MemoryBuffer *inputBuffer = (MemoryBuffer *)data;
-	float *buffer = inputBuffer->getBuffer();
-	int bufferwidth = inputBuffer->getWidth();
-	int bufferstartx = inputBuffer->getRect()->xmin;
-	int bufferstarty = inputBuffer->getRect()->ymin;
 	this->m_inputSize->read(tempSize, x, y, data);
-	float size = tempSize[0];
-	CLAMP(size, 0.0f, 1.0f);
-	float sizeX = ceil(this->m_data->sizex * size);
-	float sizeY = ceil(this->m_data->sizey * size);
+	float refSize = tempSize[0];
+	int refradx = (int)(refSize * m_radxf);
+	int refrady = (int)(refSize * m_radyf);
+	if (refradx > m_radx) refradx = m_radx;
+	else if (refradx < 1) refradx = 1;
+	if (refrady > m_rady) refrady = m_rady;
+	else if (refrady < 1) refrady = 1;
 
-	if (sizeX <= 0.5f && sizeY <= 0.5f) {
-		this->m_inputImage->read(color, x, y, data);
-		return;
-	}
-	
-	int miny = y - sizeY;
-	int maxy = y + sizeY;
-	int minx = x - sizeX;
-	int maxx = x + sizeX;
-	miny = max(miny, inputBuffer->getRect()->ymin);
-	minx = max(minx, inputBuffer->getRect()->xmin);
-	maxy = min(maxy, inputBuffer->getRect()->ymax);
-	maxx = min(maxx, inputBuffer->getRect()->xmax);
+	if (refradx == 1 && refrady == 1) {
+		memorybuffer->readNoCheck(color, x, y);
+	} else {
+		int minxr = x - refradx < 0 ? -x : -refradx;
+		int maxxr = x + refradx > imgx ? imgx - x : refradx;
+		int minyr = y - refrady < 0 ? -y : -refrady;
+		int maxyr = y + refrady > imgy ? imgy - y : refrady;
 
-	int step = QualityStepHelper::getStep();
-	int offsetadd = QualityStepHelper::getOffsetAdd();
-	for (int ny = miny; ny < maxy; ny += step) {
-		int u = ny - y;
-		float uf = ((u/sizeY)*radyf)+radyf;
-		int indexu = uf * (radx*2+1);
-		int bufferindex = ((minx - bufferstartx) * 4) + ((ny - bufferstarty) * 4 * bufferwidth);
-		for (int nx = minx; nx < maxx; nx += step) {
-			int v = nx - x;
-			float vf = ((v/sizeX)*radxf)+radxf;
-			int index = indexu + vf;
-			const float multiplier = this->m_gausstab[index];
-			madd_v4_v4fl(tempColor, &buffer[bufferindex], multiplier);
-			multiplier_accum += multiplier;
-			index += step;
-			bufferindex += offsetadd;
+		float *srcd = buffer + COM_NUMBER_OF_CHANNELS * ( (y + minyr) * imgx + x + minxr);
+
+		gausstabx = m_maintabs[refradx - 1];
+		gausstabcentx = gausstabx + refradx;
+		gausstaby = m_maintabs[refrady - 1];
+		gausstabcenty = gausstaby + refrady;
+
+		sum = gval = rval = bval = aval = 0.0f;
+		for (i = minyr; i < maxyr; i++, srcd += COM_NUMBER_OF_CHANNELS * imgx) {
+			src = srcd;
+			for (j = minxr; j < maxxr; j++, src += COM_NUMBER_OF_CHANNELS) {
+			
+				val = gausstabcenty[i] * gausstabcentx[j];
+				sum += val;
+				rval += val * src[0];
+				gval += val * src[1];
+				bval += val * src[2];
+				aval += val * src[3];
+			}
 		}
+		sum = 1.0f / sum;
+		color[0] = rval * sum;
+		color[1] = gval * sum;
+		color[2] = bval * sum;
+		color[3] = aval * sum;
 	}
 
-	mul_v4_v4fl(color, tempColor, 1.0f / multiplier_accum);
 }
 
-void GaussianBokehBlurReferenceOperation::deinitExecution()
+void GaussianBlurReferenceOperation::deinitExecution()
 {
-	delete [] this->m_gausstab;
-	this->m_gausstab = NULL;
-	this->m_inputImage = NULL;
-	this->m_inputSize = NULL;
-	
+	int x, i;
+	x = MAX2(m_radx, m_rady);
+	for (i = 0; i < x; i++)
+		delete []m_maintabs[i];
+	MEM_freeN(m_maintabs);
+	BlurBaseOperation::deinitExecution();
 }
 
-bool GaussianBokehBlurReferenceOperation::determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output)
+bool GaussianBlurReferenceOperation::determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output)
 {
 	rcti newInput;
 	NodeOperation *operation = this->getInputOperation(1);
diff --git a/source/blender/compositor/operations/COM_GaussianBokehBlurOperation.h b/source/blender/compositor/operations/COM_GaussianBokehBlurOperation.h
index 1a134c20e63..45140855464 100644
--- a/source/blender/compositor/operations/COM_GaussianBokehBlurOperation.h
+++ b/source/blender/compositor/operations/COM_GaussianBokehBlurOperation.h
@@ -49,22 +49,18 @@ public:
 	bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output);
 };
 
-class GaussianBokehBlurReferenceOperation : public NodeOperation, public QualityStepHelper {
+class GaussianBlurReferenceOperation : public BlurBaseOperation {
 private:
-	SocketReader * m_inputImage;
-	SocketReader * m_inputSize;
-	float *m_gausstab;
-	NodeBlurData *m_data;
+	float **m_maintabs;
 	
 	void updateGauss();
+	int m_radx;
+	int m_rady;
+	float m_radxf;
+	float m_radyf;
 
-	static const int radxf = 256.0f;
-	static const int radyf = 256.0f;
-	static const int radx = 256;
-	static const int rady = 256;
-	
 public:
-	GaussianBokehBlurReferenceOperation();
+	GaussianBlurReferenceOperation();
 	void initExecution();
 	void *initializeTileData(rcti *rect);
 	/**
@@ -78,8 +74,6 @@ public:
 	void deinitExecution();
 	
 	bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output);
-
-	void setData(NodeBlurData *data) { this->m_data = data; }
 };
 
 #endif
diff --git a/source/blender/editors/space_node/drawnode.c b/source/blender/editors/space_node/drawnode.c
index 87a07407ee6..134b2d6fd99 100644
--- a/source/blender/editors/space_node/drawnode.c
+++ b/source/blender/editors/space_node/drawnode.c
@@ -1528,12 +1528,19 @@ static void node_composit_buts_renderlayers(uiLayout *layout, bContext *C, Point
 static void node_composit_buts_blur(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
 {
 	uiLayout *col, *row;
+	int reference;
+	int filter;
 	
 	col = uiLayoutColumn(layout, FALSE);
-	
+	filter = RNA_enum_get(ptr, "filter_type");
+	reference = RNA_boolean_get(ptr, "use_reference");
+
 	uiItemR(col, ptr, "filter_type", 0, "", ICON_NONE);
-	if (RNA_enum_get(ptr, "filter_type") != R_FILTER_FAST_GAUSS) {
-		uiItemR(col, ptr, "use_bokeh", 0, NULL, ICON_NONE);
+	if (filter != R_FILTER_FAST_GAUSS) {
+		uiItemR(col, ptr, "use_reference", 0, NULL, ICON_NONE);
+		if (!reference) {
+			uiItemR(col, ptr, "use_bokeh", 0, NULL, ICON_NONE);
+		}
 		uiItemR(col, ptr, "use_gamma_correction", 0, NULL, ICON_NONE);
 	}
 	
diff --git a/source/blender/makesdna/DNA_node_types.h b/source/blender/makesdna/DNA_node_types.h
index 1e2f6eabce6..a7f854f603c 100644
--- a/source/blender/makesdna/DNA_node_types.h
+++ b/source/blender/makesdna/DNA_node_types.h
@@ -374,6 +374,10 @@ enum {
 	CMP_NODEFLAG_MASK_NO_FEATHER = (1 << 1)
 };
 
+enum {
+	CMP_NODEFLAG_BLUR_REFERENCE = (1 << 0),
+};
+
 typedef struct NodeFrame {
 	short flag;
 	short label_size;
diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c
index a72059063fd..055c8dcbebb 100644
--- a/source/blender/makesrna/intern/rna_nodetree.c
+++ b/source/blender/makesrna/intern/rna_nodetree.c
@@ -1713,6 +1713,11 @@ static void def_cmp_blur(StructRNA *srna)
 		{0, NULL, 0, NULL, NULL}
 	};
 
+	prop = RNA_def_property(srna, "use_reference", PROP_BOOLEAN, PROP_NONE);
+	RNA_def_property_boolean_sdna(prop, NULL, "custom1", CMP_NODEFLAG_BLUR_REFERENCE);
+	RNA_def_property_ui_text(prop, "Reference", "Use size socket as a reference image");
+	RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
+
 	RNA_def_struct_sdna_from(srna, "NodeBlurData", "storage");
 	
 	prop = RNA_def_property(srna, "size_x", PROP_INT, PROP_NONE);
@@ -1771,7 +1776,6 @@ static void def_cmp_blur(StructRNA *srna)
 	RNA_def_property_boolean_sdna(prop, NULL, "gamma", 1);
 	RNA_def_property_ui_text(prop, "Gamma", "Apply filter on gamma corrected values");
 	RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
-	
 }
 
 static void def_cmp_filter(StructRNA *srna)

From 776c6e66b2064f2a6934a726f4fcc317b709d6fd Mon Sep 17 00:00:00 2001
From: Campbell Barton 
Date: Thu, 19 Jul 2012 11:40:25 +0000
Subject: [PATCH 096/108] add lattice selection to rna

---
 source/blender/editors/object/object_lattice.c | 4 ++--
 source/blender/makesrna/intern/rna_lattice.c   | 4 ++++
 2 files changed, 6 insertions(+), 2 deletions(-)

diff --git a/source/blender/editors/object/object_lattice.c b/source/blender/editors/object/object_lattice.c
index e85f47837ef..89f9f5de311 100644
--- a/source/blender/editors/object/object_lattice.c
+++ b/source/blender/editors/object/object_lattice.c
@@ -203,7 +203,7 @@ static int lattice_select_all_exec(bContext *C, wmOperator *op)
 
 		while (a--) {
 			if (bp->hide == 0) {
-				if (bp->f1) {
+				if (bp->f1 & SELECT) {
 					action = SEL_DESELECT;
 					break;
 				}
@@ -225,7 +225,7 @@ static int lattice_select_all_exec(bContext *C, wmOperator *op)
 
 			while (a--) {
 				if (bp->hide == 0) {
-					bp->f1 ^= 1;
+					bp->f1 ^= SELECT;
 				}
 				bp++;
 			}
diff --git a/source/blender/makesrna/intern/rna_lattice.c b/source/blender/makesrna/intern/rna_lattice.c
index 6e42b47afce..d4082cf3d9f 100644
--- a/source/blender/makesrna/intern/rna_lattice.c
+++ b/source/blender/makesrna/intern/rna_lattice.c
@@ -224,6 +224,10 @@ static void rna_def_latticepoint(BlenderRNA *brna)
 	RNA_def_struct_ui_text(srna, "LatticePoint", "Point in the lattice grid");
 	RNA_def_struct_path_func(srna, "rna_LatticePoint_path");
 
+	prop = RNA_def_property(srna, "select", PROP_BOOLEAN, PROP_NONE);
+	RNA_def_property_boolean_sdna(prop, NULL, "f1", 0);
+	RNA_def_property_ui_text(prop, "Point selected", "Selection status");
+
 	prop = RNA_def_property(srna, "co", PROP_FLOAT, PROP_TRANSLATION);
 	RNA_def_property_array(prop, 3);
 	RNA_def_property_clear_flag(prop, PROP_EDITABLE);

From 2557eaf0dd33e3139cc6188b97029207686360bf Mon Sep 17 00:00:00 2001
From: Campbell Barton 
Date: Thu, 19 Jul 2012 13:04:43 +0000
Subject: [PATCH 097/108] print names of nodes/sockets when cycles complains
 about only being able to connect a closure to another closure.

---
 doc/manpage/blender.1          | 54 +++++++++++++++-------------------
 intern/cycles/render/graph.cpp |  5 +++-
 2 files changed, 27 insertions(+), 32 deletions(-)

diff --git a/doc/manpage/blender.1 b/doc/manpage/blender.1
index 6257a78171b..c7a762f08c7 100644
--- a/doc/manpage/blender.1
+++ b/doc/manpage/blender.1
@@ -1,13 +1,4 @@
-.TH "BLENDER" "1" "April 26, 2012" "Blender Blender 2\&.63 (sub 0)
-	build date: 2012-04-26
-	build time: 19:38:31
-	build revision: 45987
-	build platform: Linux
-	build type: Debug
-	build c flags:  -fopenmp  -msse2  -msse -pipe -fPIC -funsigned-char -fno-strict-aliasing  -Wall -Wcast-align -Werror=declaration-after-statement -Werror=implicit-function-declaration -Werror=return-type -Wstrict-prototypes -Wno-char-subscripts -Wno-unknown-pragmas -Wpointer-arith -Wunused-parameter -Wwrite-strings
-	build c++ flags:  -D__STDC_CONSTANT_MACROS -fopenmp  -msse2  -msse -pipe -fPIC -funsigned-char -fno-strict-aliasing  -Wall -Wno-invalid-offsetof -Wno-sign-compare
-	build link flags: -pthread
-	build system: CMake"
+.TH "BLENDER" "1" "July 19, 2012" "Blender Blender 2\&.63 (sub 14)"
 
 .SH NAME
 blender \- a 3D modelling and rendering package
@@ -24,7 +15,7 @@ Use Blender to create TV commercials, to make technical visualizations, business
 http://www.blender.org
 .SH OPTIONS
 
-Blender 2.63 (sub 0)
+Blender 2.63 (sub 14)
 Usage: blender [args ...] [file] [args ...]
 .br
 .SS "Render Options:"
@@ -223,18 +214,6 @@ Turn debugging on
 Enable floating point exceptions
 .br
 
-.TP
-.B \-\-debug\-ffmpeg
-.br
-Enable debug messages from FFmpeg library
-.br
-
-.TP
-.B \-\-debug\-libmv
-.br
-Enable debug messages from libmv library
-.br
-
 .IP
 
 .TP
@@ -257,12 +236,6 @@ Set the BLENDER_SYSTEM_DATAFILES environment variable
 Set the BLENDER_SYSTEM_SCRIPTS environment variable
 .br
 
-.TP
-.B \-\-env\-system\-plugins
-.br
-Set the BLENDER_SYSTEM_PLUGINS environment variable
-.br
-
 .TP
 .B \-\-env\-system\-python
 .br
@@ -316,7 +289,7 @@ Enable automatic python script execution, (default)
 .TP
 .B \-Y or \-\-disable\-autoexec
 .br
-Disable automatic python script execution (pydrivers, pyconstraints, pynodes)
+Disable automatic python script execution (pydrivers & startup scripts)
 .br
 
 .IP
@@ -383,6 +356,26 @@ Enable debug messages for the window manager
 Enable all debug messages (excludes libmv)
 .br
 
+.TP
+.B \-\-debug\-value 
+.br
+Set debug value of  on startup
+.br
+
+.IP
+
+.TP
+.B \-\-debug\-jobs
+.br
+Enable time profiling for background jobs.
+.br
+
+.TP
+.B \-\-verbose 
+.br
+Set logging verbosity level.
+.br
+
 .TP
 .B \-R
 .br
@@ -421,7 +414,6 @@ Arguments are executed in the order they are given. eg
   \fIBLENDER_SYSTEM_DATAFILES\fR Directory for system wide data files.
   \fIBLENDER_SYSTEM_PYTHON\fR Directory for system python libraries.
   \fITMP\fR or \fITMPDIR\fR Store temporary files here.
-  \fISDL_AUDIODRIVER\fR LibSDL audio driver \- alsa, esd, dma.
   \fIPYTHONHOME\fR Path to the python directory, eg. /usr/lib/python.
 .br
 .br
diff --git a/intern/cycles/render/graph.cpp b/intern/cycles/render/graph.cpp
index 34c8879aa1f..18e802b610d 100644
--- a/intern/cycles/render/graph.cpp
+++ b/intern/cycles/render/graph.cpp
@@ -187,7 +187,10 @@ void ShaderGraph::connect(ShaderOutput *from, ShaderInput *to)
 	if(from->type != to->type) {
 		/* for closures we can't do automatic conversion */
 		if(from->type == SHADER_SOCKET_CLOSURE || to->type == SHADER_SOCKET_CLOSURE) {
-			fprintf(stderr, "ShaderGraph connect: can only connect closure to closure.\n");
+			fprintf(stderr, "ShaderGraph connect: can only connect closure to closure "
+			        "(ShaderNode:%s, ShaderOutput:%s , type:%d -> to ShaderNode:%s, ShaderInput:%s, type:%d).\n",
+			        from->parent->name.c_str(), from->name, (int)from->type,
+			        to->parent->name.c_str(),   to->name,   (int)to->type);
 			return;
 		}
 

From 579a4a02a54da01a4af98e831f4feb87fba72392 Mon Sep 17 00:00:00 2001
From: Jeroen Bakker 
Date: Thu, 19 Jul 2012 17:28:37 +0000
Subject: [PATCH 098/108] Possible fix for [#32141] Crash when using a mask as
 the factor input for a color combine (mix) node with render resolution at
 100%

Seems to be that the MaskNode has been created as a complex node. But no
complex features were used. Converted the execute pixel to simple
execution. And it sees that the crash does not happen.

Not sure if it is the issue is solved. I am going to let the user retest
with this revision.
---
 .../compositor/operations/COM_MaskOperation.cpp    | 14 +-------------
 .../compositor/operations/COM_MaskOperation.h      |  6 +++++-
 2 files changed, 6 insertions(+), 14 deletions(-)

diff --git a/source/blender/compositor/operations/COM_MaskOperation.cpp b/source/blender/compositor/operations/COM_MaskOperation.cpp
index 057a749080a..c648f3e6f08 100644
--- a/source/blender/compositor/operations/COM_MaskOperation.cpp
+++ b/source/blender/compositor/operations/COM_MaskOperation.cpp
@@ -30,7 +30,6 @@
 
 #include "DNA_scene_types.h"
 
-
 #ifdef USE_RASKTER
 
 extern "C" {
@@ -140,13 +139,10 @@ MaskOperation::MaskOperation() : NodeOperation()
 	this->m_maskHeight = 0;
 	this->m_framenumber = 0;
 	this->m_rasterMaskHandle = NULL;
-	setComplex(true);
 }
 
 void MaskOperation::initExecution()
 {
-	initMutex();
-
 	if (this->m_mask) {
 		if (this->m_rasterMaskHandle == NULL) {
 			const int width = this->getWidth();
@@ -165,14 +161,6 @@ void MaskOperation::deinitExecution()
 		BKE_maskrasterize_handle_free(this->m_rasterMaskHandle);
 		this->m_rasterMaskHandle = NULL;
 	}
-
-	deinitMutex();
-}
-
-void *MaskOperation::initializeTileData(rcti *rect)
-{
-	/* pass */
-	return NULL;
 }
 
 void MaskOperation::determineResolution(unsigned int resolution[], unsigned int preferredResolution[])
@@ -193,7 +181,7 @@ void MaskOperation::determineResolution(unsigned int resolution[], unsigned int
 	}
 }
 
-void MaskOperation::executePixel(float *color, int x, int y, void *data)
+void MaskOperation::executePixel(float *color, float x, float y, PixelSampler sampler)
 {
 	const float xy[2] = {x / (float)this->m_maskWidth, y / (float)this->m_maskHeight};
 	if (this->m_rasterMaskHandle) {
diff --git a/source/blender/compositor/operations/COM_MaskOperation.h b/source/blender/compositor/operations/COM_MaskOperation.h
index d761ee58cb9..f367298b3d6 100644
--- a/source/blender/compositor/operations/COM_MaskOperation.h
+++ b/source/blender/compositor/operations/COM_MaskOperation.h
@@ -72,7 +72,6 @@ public:
 	void initExecution();
 	void deinitExecution();
 
-	void *initializeTileData(rcti *rect);
 
 	void setMask(Mask *mask) { this->m_mask = mask; }
 	void setMaskWidth(int width) { this->m_maskWidth = width; }
@@ -81,7 +80,12 @@ public:
 	void setSmooth(bool smooth) { this->m_do_smooth = smooth; }
 	void setFeather(bool feather) { this->m_do_feather = feather; }
 
+#ifdef USE_RASKTER
+	void *initializeTileData(rcti *rect);
 	void executePixel(float *color, int x, int y, void *data);
+#else /* USE_RASKTER */
+	void executePixel(float *color, float x, float y, PixelSampler sampler);
+#endif /* USE_RASKTER */
 };
 
 #endif

From 88cf37e9bcb576c7192ec9e0f52caf7fda81d2d4 Mon Sep 17 00:00:00 2001
From: Campbell Barton 
Date: Thu, 19 Jul 2012 21:55:16 +0000
Subject: [PATCH 099/108] quiet formatting warnings when international was
 enabled.

---
 .../editors/space_image/image_buttons.c       | 26 +++++++++----------
 1 file changed, 13 insertions(+), 13 deletions(-)

diff --git a/source/blender/editors/space_image/image_buttons.c b/source/blender/editors/space_image/image_buttons.c
index 7989a8e1b34..7d358bcfb8b 100644
--- a/source/blender/editors/space_image/image_buttons.c
+++ b/source/blender/editors/space_image/image_buttons.c
@@ -106,36 +106,36 @@ static void image_info(Scene *scene, ImageUser *iuser, Image *ima, ImBuf *ibuf,
 	if (ima == NULL) return;
 
 	if (ibuf == NULL) {
-		ofs += sprintf(str, IFACE_("Can't Load Image"));
+		ofs += sprintf(str, "%s", IFACE_("Can't Load Image"));
 	}
 	else {
 		if (ima->source == IMA_SRC_MOVIE) {
-			ofs += sprintf(str, IFACE_("Movie"));
+			ofs += sprintf(str, "%s", IFACE_("Movie"));
 			if (ima->anim)
 				ofs += sprintf(str + ofs, IFACE_("%d frs"), IMB_anim_get_duration(ima->anim, IMB_TC_RECORD_RUN));
 		}
 		else
-			ofs += sprintf(str, IFACE_("Image"));
+			ofs += sprintf(str, "%s", IFACE_("Image"));
 
-		ofs += sprintf(str + ofs, IFACE_(": size %d x %d,"), ibuf->x, ibuf->y);
+		ofs += sprintf(str + ofs, ": %s %d x %d,", IFACE_("size"), ibuf->x, ibuf->y);
 
 		if (ibuf->rect_float) {
 			if (ibuf->channels != 4) {
-				ofs += sprintf(str + ofs, IFACE_("%d float channel(s)"), ibuf->channels);
+				ofs += sprintf(str + ofs, "%d %s", ibuf->channels, IFACE_("float channel(s)"));
 			}
 			else if (ibuf->planes == R_IMF_PLANES_RGBA)
-				ofs += sprintf(str + ofs, IFACE_(" RGBA float"));
+				ofs += sprintf(str + ofs, "%s", IFACE_(" RGBA float"));
 			else
-				ofs += sprintf(str + ofs, IFACE_(" RGB float"));
+				ofs += sprintf(str + ofs, "%s", IFACE_(" RGB float"));
 		}
 		else {
 			if (ibuf->planes == R_IMF_PLANES_RGBA)
-				ofs += sprintf(str + ofs, IFACE_(" RGBA byte"));
+				ofs += sprintf(str + ofs, "%s", IFACE_(" RGBA byte"));
 			else
-				ofs += sprintf(str + ofs, IFACE_(" RGB byte"));
+				ofs += sprintf(str + ofs, "%s", IFACE_(" RGB byte"));
 		}
 		if (ibuf->zbuf || ibuf->zbuf_float)
-			ofs += sprintf(str + ofs, IFACE_(" + Z"));
+			ofs += sprintf(str + ofs, "%s", IFACE_(" + Z"));
 
 		if (ima->source == IMA_SRC_SEQUENCE) {
 			char *file = BLI_last_slash(ibuf->name);
@@ -381,11 +381,11 @@ static char *layer_menu(RenderResult *rr, short *UNUSED(curlay))
 	
 	/* compo result */
 	if (rr->rectf) {
-		a += sprintf(str + a, IFACE_("|Composite %%x0"));
+		a += sprintf(str + a, "|%s %%x0", IFACE_("Composite"));
 		nr = 1;
 	}
 	else if (rr->rect32) {
-		a += sprintf(str + a, IFACE_("|Sequence %%x0"));
+		a += sprintf(str + a, "|%s %%x0", IFACE_("Sequence"));
 		nr = 1;
 	}
 	for (rl = rr->layers.first; rl; rl = rl->next, nr++) {
@@ -410,7 +410,7 @@ static char *pass_menu(RenderLayer *rl, short *curpass)
 	
 	/* rendered results don't have a Combined pass */
 	if (rl == NULL || rl->rectf) {
-		a += sprintf(str + a, IFACE_("|Combined %%x0"));
+		a += sprintf(str + a, "|%s %%x0", IFACE_("Combined"));
 		nr = 1;
 	}
 	

From c8db1e832d26e7b34ace2f36ff66b40d1195cb7c Mon Sep 17 00:00:00 2001
From: Campbell Barton 
Date: Fri, 20 Jul 2012 09:49:54 +0000
Subject: [PATCH 100/108] minor edits for bmesh api

---
 source/blender/bmesh/intern/bmesh_marking.c   | 11 ++++++++---
 source/blender/bmesh/intern/bmesh_marking.h   |  1 +
 source/blender/editors/include/ED_mesh.h      |  4 ++--
 source/blender/editors/mesh/editmesh_select.c | 13 ++++++-------
 source/blender/editors/mesh/editmesh_utils.c  |  6 ++----
 source/blender/editors/transform/transform.c  |  8 ++++----
 6 files changed, 23 insertions(+), 20 deletions(-)

diff --git a/source/blender/bmesh/intern/bmesh_marking.c b/source/blender/bmesh/intern/bmesh_marking.c
index 4588fbae383..d16dacaf5cf 100644
--- a/source/blender/bmesh/intern/bmesh_marking.c
+++ b/source/blender/bmesh/intern/bmesh_marking.c
@@ -71,7 +71,7 @@ static void recount_totsels(BMesh *bm)
  * (ie: all verts of an edge selects the edge and so on).
  * This should only be called by system and not tool authors.
  */
-void BM_mesh_select_mode_flush(BMesh *bm)
+void BM_mesh_select_mode_flush_ex(BMesh *bm, const short selectmode)
 {
 	BMEdge *e;
 	BMLoop *l_iter;
@@ -83,7 +83,7 @@ void BM_mesh_select_mode_flush(BMesh *bm)
 
 	int ok;
 
-	if (bm->selectmode & SCE_SELECT_VERTEX) {
+	if (selectmode & SCE_SELECT_VERTEX) {
 		BM_ITER_MESH (e, &eiter, bm, BM_EDGES_OF_MESH) {
 			if (BM_elem_flag_test(e->v1, BM_ELEM_SELECT) &&
 			    BM_elem_flag_test(e->v2, BM_ELEM_SELECT) &&
@@ -113,7 +113,7 @@ void BM_mesh_select_mode_flush(BMesh *bm)
 			BM_elem_flag_set(f, BM_ELEM_SELECT, ok);
 		}
 	}
-	else if (bm->selectmode & SCE_SELECT_EDGE) {
+	else if (selectmode & SCE_SELECT_EDGE) {
 		BM_ITER_MESH (f, &fiter, bm, BM_FACES_OF_MESH) {
 			ok = TRUE;
 			if (!BM_elem_flag_test(f, BM_ELEM_HIDDEN)) {
@@ -139,6 +139,11 @@ void BM_mesh_select_mode_flush(BMesh *bm)
 	recount_totsels(bm);
 }
 
+void BM_mesh_select_mode_flush(BMesh *bm)
+{
+	BM_mesh_select_mode_flush_ex(bm, bm->selectmode);
+}
+
 /**
  * mode independent flushing up/down
  */
diff --git a/source/blender/bmesh/intern/bmesh_marking.h b/source/blender/bmesh/intern/bmesh_marking.h
index 406971652dc..9b73ed2c390 100644
--- a/source/blender/bmesh/intern/bmesh_marking.h
+++ b/source/blender/bmesh/intern/bmesh_marking.h
@@ -60,6 +60,7 @@ void BM_edge_select_set(BMesh *bm, BMEdge *e, int select);
 void BM_face_select_set(BMesh *bm, BMFace *f, int select);
 
 void BM_mesh_select_mode_set(BMesh *bm, int selectmode);
+void BM_mesh_select_mode_flush_ex(BMesh *bm, const short selectmode);
 void BM_mesh_select_mode_flush(BMesh *bm);
 
 void BM_mesh_deselect_flush(BMesh *bm);
diff --git a/source/blender/editors/include/ED_mesh.h b/source/blender/editors/include/ED_mesh.h
index b2e8ecd09c9..35284b26d29 100644
--- a/source/blender/editors/include/ED_mesh.h
+++ b/source/blender/editors/include/ED_mesh.h
@@ -104,14 +104,14 @@ struct BMFace *EDBM_face_at_index(struct BMEditMesh *em, int index);
 void EDBM_select_more(struct BMEditMesh *em);
 void EDBM_select_less(struct BMEditMesh *em);
 
-void EDBM_selectmode_flush_ex(struct BMEditMesh *em, int selectmode);
+void EDBM_selectmode_flush_ex(struct BMEditMesh *em, const short selectmode);
 void EDBM_selectmode_flush(struct BMEditMesh *em);
 
 void EDBM_deselect_flush(struct BMEditMesh *em);
 void EDBM_select_flush(struct BMEditMesh *em);
 
 void EDBM_selectmode_set(struct BMEditMesh *em);
-void EDBM_selectmode_convert(struct BMEditMesh *em, short oldmode, short selectmode);
+void EDBM_selectmode_convert(struct BMEditMesh *em, short oldmode, const short selectmode);
 void undo_push_mesh(struct bContext *C, const char *name);
 
 int  EDBM_vert_color_check(struct BMEditMesh *em);
diff --git a/source/blender/editors/mesh/editmesh_select.c b/source/blender/editors/mesh/editmesh_select.c
index a9912b90aef..61d12b751e0 100644
--- a/source/blender/editors/mesh/editmesh_select.c
+++ b/source/blender/editors/mesh/editmesh_select.c
@@ -1682,15 +1682,15 @@ void EDBM_selectmode_set(BMEditMesh *em)
 	}
 }
 
-void EDBM_selectmode_convert(BMEditMesh *em, short oldmode, short selectmode)
+void EDBM_selectmode_convert(BMEditMesh *em, const short selectmode_old, const short selectmode_new)
 {
 	BMEdge *eed;
 	BMFace *efa;
 	BMIter iter;
 
 	/* have to find out what the selectionmode was previously */
-	if (oldmode == SCE_SELECT_VERTEX) {
-		if (selectmode == SCE_SELECT_EDGE) {
+	if (selectmode_old == SCE_SELECT_VERTEX) {
+		if (selectmode_new == SCE_SELECT_EDGE) {
 			/* select all edges associated with every selected vertex */
 			eed = BM_iter_new(&iter, em->bm, BM_EDGES_OF_MESH, NULL);
 			for (; eed; eed = BM_iter_step(&iter)) {
@@ -1701,7 +1701,7 @@ void EDBM_selectmode_convert(BMEditMesh *em, short oldmode, short selectmode)
 				}
 			}
 		}		
-		else if (selectmode == SCE_SELECT_FACE) {
+		else if (selectmode_new == SCE_SELECT_FACE) {
 			BMIter liter;
 			BMLoop *l;
 
@@ -1718,9 +1718,8 @@ void EDBM_selectmode_convert(BMEditMesh *em, short oldmode, short selectmode)
 			}
 		}
 	}
-	
-	if (oldmode == SCE_SELECT_EDGE) {
-		if (selectmode == SCE_SELECT_FACE) {
+	else if (selectmode_old == SCE_SELECT_EDGE) {
+		if (selectmode_new == SCE_SELECT_FACE) {
 			BMIter liter;
 			BMLoop *l;
 
diff --git a/source/blender/editors/mesh/editmesh_utils.c b/source/blender/editors/mesh/editmesh_utils.c
index 4952dd3f09a..274789a7b96 100644
--- a/source/blender/editors/mesh/editmesh_utils.c
+++ b/source/blender/editors/mesh/editmesh_utils.c
@@ -452,11 +452,9 @@ BMFace *EDBM_face_at_index(BMEditMesh *tm, int index)
 	return (tm->face_index && index < tm->bm->totface && index >= 0) ? tm->face_index[index] : NULL;
 }
 
-void EDBM_selectmode_flush_ex(BMEditMesh *em, int selectmode)
+void EDBM_selectmode_flush_ex(BMEditMesh *em, const short selectmode)
 {
-	em->bm->selectmode = selectmode;
-	BM_mesh_select_mode_flush(em->bm);
-	em->bm->selectmode = em->selectmode;
+	BM_mesh_select_mode_flush_ex(em->bm, selectmode);
 }
 
 void EDBM_selectmode_flush(BMEditMesh *em)
diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c
index 7bcf6ba58f1..6aee12c4b41 100644
--- a/source/blender/editors/transform/transform.c
+++ b/source/blender/editors/transform/transform.c
@@ -170,12 +170,12 @@ void convertViewVec(TransInfo *t, float r_vec[3], int dx, int dy)
 		if (t->options & CTX_MASK) {
 			/* clamp w/h, mask only */
 			if (mulx / divx < muly / divy) {
-				divx = divy = divx;
-				mulx = muly = mulx;
+				divy = divx;
+				muly = mulx;
 			}
 			else {
-				divx = divy = divy;
-				mulx = muly = muly;
+				divx = divy;
+				mulx = muly;
 			}
 		}
 

From 3b26b46631eefe5a38b54c6465dc5dd82f2c6294 Mon Sep 17 00:00:00 2001
From: Campbell Barton 
Date: Fri, 20 Jul 2012 10:33:15 +0000
Subject: [PATCH 101/108] Separate meshes by loose parts and materials now
 works in object mode as well as editmode.

---
 source/blender/editors/mesh/editmesh_tools.c | 167 +++++++++++--------
 1 file changed, 99 insertions(+), 68 deletions(-)

diff --git a/source/blender/editors/mesh/editmesh_tools.c b/source/blender/editors/mesh/editmesh_tools.c
index 5657cef4fd2..53744a01b8c 100644
--- a/source/blender/editors/mesh/editmesh_tools.c
+++ b/source/blender/editors/mesh/editmesh_tools.c
@@ -2790,121 +2790,110 @@ void MESH_OT_knife_cut(wmOperatorType *ot)
 	RNA_def_int(ot->srna, "cursor", BC_KNIFECURSOR, 0, INT_MAX, "Cursor", "", 0, INT_MAX);
 }
 
-static int mesh_separate_selected(Main *bmain, Scene *scene, Base *editbase, wmOperator *wmop)
+static int mesh_separate_selected(Main *bmain, Scene *scene, Base *base_old, BMesh *bm_old)
 {
-	Base *basenew;
+	Base *base_new;
 	BMIter iter;
 	BMVert *v;
 	BMEdge *e;
-	Object *obedit = editbase->object;
-	Mesh *me = obedit->data;
-	BMEditMesh *em = me->edit_btmesh;
+	Object *obedit = base_old->object;
 	BMesh *bm_new;
-	
-	if (!em)
-		return FALSE;
-		
+
 	bm_new = BM_mesh_create(&bm_mesh_allocsize_default);
-	CustomData_copy(&em->bm->vdata, &bm_new->vdata, CD_MASK_BMESH, CD_CALLOC, 0);
-	CustomData_copy(&em->bm->edata, &bm_new->edata, CD_MASK_BMESH, CD_CALLOC, 0);
-	CustomData_copy(&em->bm->ldata, &bm_new->ldata, CD_MASK_BMESH, CD_CALLOC, 0);
-	CustomData_copy(&em->bm->pdata, &bm_new->pdata, CD_MASK_BMESH, CD_CALLOC, 0);
+	CustomData_copy(&bm_old->vdata, &bm_new->vdata, CD_MASK_BMESH, CD_CALLOC, 0);
+	CustomData_copy(&bm_old->edata, &bm_new->edata, CD_MASK_BMESH, CD_CALLOC, 0);
+	CustomData_copy(&bm_old->ldata, &bm_new->ldata, CD_MASK_BMESH, CD_CALLOC, 0);
+	CustomData_copy(&bm_old->pdata, &bm_new->pdata, CD_MASK_BMESH, CD_CALLOC, 0);
 
 	CustomData_bmesh_init_pool(&bm_new->vdata, bm_mesh_allocsize_default.totvert, BM_VERT);
 	CustomData_bmesh_init_pool(&bm_new->edata, bm_mesh_allocsize_default.totedge, BM_EDGE);
 	CustomData_bmesh_init_pool(&bm_new->ldata, bm_mesh_allocsize_default.totloop, BM_LOOP);
 	CustomData_bmesh_init_pool(&bm_new->pdata, bm_mesh_allocsize_default.totface, BM_FACE);
-		
-	basenew = ED_object_add_duplicate(bmain, scene, editbase, USER_DUP_MESH);
-	/* DAG_scene_sort(bmain, scene); */ /* normally would call directly after but in this case delay recalc */
-	assign_matarar(basenew->object, give_matarar(obedit), *give_totcolp(obedit)); /* new in 2.5 */
 
-	ED_base_object_select(basenew, BA_DESELECT);
-	
-	EDBM_op_callf(em, wmop, "duplicate geom=%hvef dest=%p", BM_ELEM_SELECT, bm_new);
-	EDBM_op_callf(em, wmop, "delete geom=%hvef context=%i", BM_ELEM_SELECT, DEL_FACES);
+	base_new = ED_object_add_duplicate(bmain, scene, base_old, USER_DUP_MESH);
+	/* DAG_scene_sort(bmain, scene); */ /* normally would call directly after but in this case delay recalc */
+	assign_matarar(base_new->object, give_matarar(obedit), *give_totcolp(obedit)); /* new in 2.5 */
+
+	ED_base_object_select(base_new, BA_SELECT);
+
+	BMO_op_callf(bm_old, "duplicate geom=%hvef dest=%p", BM_ELEM_SELECT, bm_new);
+	BMO_op_callf(bm_old, "delete geom=%hvef context=%i", BM_ELEM_SELECT, DEL_FACES);
 
 	/* clean up any loose edges */
-	BM_ITER_MESH (e, &iter, em->bm, BM_EDGES_OF_MESH) {
+	BM_ITER_MESH (e, &iter, bm_old, BM_EDGES_OF_MESH) {
 		if (BM_elem_flag_test(e, BM_ELEM_HIDDEN))
 			continue;
 
 		if (!BM_edge_is_wire(e)) {
-			BM_edge_select_set(em->bm, e, FALSE);
+			BM_edge_select_set(bm_old, e, FALSE);
 		}
 	}
-	EDBM_op_callf(em, wmop, "delete geom=%hvef context=%i", BM_ELEM_SELECT, DEL_EDGES);
+	BMO_op_callf(bm_old, "delete geom=%hvef context=%i", BM_ELEM_SELECT, DEL_EDGES);
 
 	/* clean up any loose verts */
-	BM_ITER_MESH (v, &iter, em->bm, BM_VERTS_OF_MESH) {
+	BM_ITER_MESH (v, &iter, bm_old, BM_VERTS_OF_MESH) {
 		if (BM_elem_flag_test(v, BM_ELEM_HIDDEN))
 			continue;
 
 		if (BM_vert_edge_count(v) != 0) {
-			BM_vert_select_set(em->bm, v, FALSE);
+			BM_vert_select_set(bm_old, v, FALSE);
 		}
 	}
 
-	EDBM_op_callf(em, wmop, "delete geom=%hvef context=%i", BM_ELEM_SELECT, DEL_VERTS);
+	BMO_op_callf(bm_old, "delete geom=%hvef context=%i", BM_ELEM_SELECT, DEL_VERTS);
 
 	BM_mesh_normals_update(bm_new, TRUE);
 
-	BM_mesh_bm_to_me(bm_new, basenew->object->data, FALSE);
-		
+	BM_mesh_bm_to_me(bm_new, base_new->object->data, FALSE);
+
 	BM_mesh_free(bm_new);
-	((Mesh *)basenew->object->data)->edit_btmesh = NULL;
+	((Mesh *)base_new->object->data)->edit_btmesh = NULL;
 	
 	return TRUE;
 }
 
-static int mesh_separate_material(Main *bmain, Scene *scene, Base *editbase, wmOperator *wmop)
+static int mesh_separate_material(Main *bmain, Scene *scene, Base *base_old, BMesh *bm_old)
 {
 	BMFace *f_cmp, *f;
 	BMIter iter;
 	int result = FALSE;
-	Object *obedit = editbase->object;
-	BMEditMesh *em = BMEdit_FromObject(obedit);
-	BMesh *bm = em->bm;
 
-	EDBM_flag_disable_all(em, BM_ELEM_SELECT);
+	BM_mesh_elem_hflag_disable_all(bm_old, BM_VERT | BM_EDGE | BM_FACE, BM_ELEM_SELECT, FALSE);
 
-	while ((f_cmp = BM_iter_at_index(bm, BM_FACES_OF_MESH, NULL, 0))) {
+	while ((f_cmp = BM_iter_at_index(bm_old, BM_FACES_OF_MESH, NULL, 0))) {
 		const short mat_nr = f_cmp->mat_nr;
 		int tot = 0;
 
-		BM_ITER_MESH (f, &iter, bm, BM_FACES_OF_MESH) {
+		BM_ITER_MESH (f, &iter, bm_old, BM_FACES_OF_MESH) {
 			if (f->mat_nr == mat_nr) {
-				BM_face_select_set(bm, f, TRUE);
+				BM_face_select_set(bm_old, f, TRUE);
 				tot++;
 			}
 		}
 
 		/* leave the current object with some materials */
-		if (tot == bm->totface) {
+		if (tot == bm_old->totface) {
 			break;
 		}
 
 		/* Move selection into a separate object */
-		result |= mesh_separate_selected(bmain, scene, editbase, wmop);
+		result |= mesh_separate_selected(bmain, scene, base_old, bm_old);
 	}
 
 	return result;
 }
 
-static int mesh_separate_loose(Main *bmain, Scene *scene, Base *editbase, wmOperator *wmop)
+static int mesh_separate_loose(Main *bmain, Scene *scene, Base *base_old, BMesh *bm_old)
 {
 	int i;
 	BMEdge *e;
 	BMVert *v_seed;
 	BMWalker walker;
 	int result = FALSE;
-	Object *obedit = editbase->object;
-	BMEditMesh *em = BMEdit_FromObject(obedit);
-	BMesh *bm = em->bm;
-	int max_iter = bm->totvert;
+	int max_iter = bm_old->totvert;
 
 	/* Clear all selected vertices */
-	EDBM_flag_disable_all(em, BM_ELEM_SELECT);
+	BM_mesh_elem_hflag_disable_all(bm_old, BM_VERT | BM_EDGE | BM_FACE, BM_ELEM_SELECT, FALSE);
 
 	/* A "while (true)" loop should work here as each iteration should
 	 * select and remove at least one vertex and when all vertices
@@ -2913,7 +2902,7 @@ static int mesh_separate_loose(Main *bmain, Scene *scene, Base *editbase, wmOper
 	 * original mesh.*/
 	for (i = 0; i < max_iter; i++) {
 		/* Get a seed vertex to start the walk */
-		v_seed = BM_iter_at_index(bm, BM_VERTS_OF_MESH, NULL, 0);
+		v_seed = BM_iter_at_index(bm_old, BM_VERTS_OF_MESH, NULL, 0);
 
 		/* No vertices available, can't do anything */
 		if (v_seed == NULL) {
@@ -2921,33 +2910,33 @@ static int mesh_separate_loose(Main *bmain, Scene *scene, Base *editbase, wmOper
 		}
 
 		/* Select the seed explicitly, in case it has no edges */
-		BM_vert_select_set(bm, v_seed, TRUE);
+		BM_vert_select_set(bm_old, v_seed, TRUE);
 
 		/* Walk from the single vertex, selecting everything connected
 		 * to it */
-		BMW_init(&walker, bm, BMW_SHELL,
+		BMW_init(&walker, bm_old, BMW_SHELL,
 		         BMW_MASK_NOP, BMW_MASK_NOP, BMW_MASK_NOP,
 		         BMW_FLAG_NOP, /* BMESH_TODO - should be BMW_FLAG_TEST_HIDDEN ? */
 		         BMW_NIL_LAY);
 
 		e = BMW_begin(&walker, v_seed);
 		for (; e; e = BMW_step(&walker)) {
-			BM_vert_select_set(bm, e->v1, TRUE);
-			BM_vert_select_set(bm, e->v2, TRUE);
+			BM_vert_select_set(bm_old, e->v1, TRUE);
+			BM_vert_select_set(bm_old, e->v2, TRUE);
 		}
 		BMW_end(&walker);
-				
+
 		/* Flush the selection to get edge/face selections matching
 		 * the vertex selection */
-		EDBM_selectmode_flush_ex(em, SCE_SELECT_VERTEX);
+		BM_mesh_select_mode_flush_ex(bm_old, SCE_SELECT_VERTEX);
 
-		if (bm->totvert == bm->totvertsel) {
+		if (bm_old->totvert == bm_old->totvertsel) {
 			/* Every vertex selected, nothing to separate, work is done */
 			break;
 		}
 
 		/* Move selection into a separate object */
-		result |= mesh_separate_selected(bmain, scene, editbase, wmop);
+		result |= mesh_separate_selected(bmain, scene, base_old, bm_old);
 	}
 
 	return result;
@@ -2957,24 +2946,66 @@ static int edbm_separate_exec(bContext *C, wmOperator *op)
 {
 	Main *bmain = CTX_data_main(C);
 	Scene *scene = CTX_data_scene(C);
-	Base *base = CTX_data_active_base(C);
 	int retval = 0, type = RNA_enum_get(op->ptr, "type");
 	
-	if (type == 0)
-		retval = mesh_separate_selected(bmain, scene, base, op);
-	else if (type == 1)
-		retval = mesh_separate_material(bmain, scene, base, op);
-	else if (type == 2)
-		retval = mesh_separate_loose(bmain, scene, base, op);
-
-	if (retval) {
+	if (ED_operator_editmesh(C)) {
+		Base *base = CTX_data_active_base(C);
 		BMEditMesh *em = BMEdit_FromObject(base->object);
 
+		/* editmode separate */
+		if      (type == 0) retval = mesh_separate_selected(bmain, scene, base, em->bm);
+		else if (type == 1) retval = mesh_separate_material(bmain, scene, base, em->bm);
+		else if (type == 2) retval = mesh_separate_loose(bmain, scene, base, em->bm);
+		else                BLI_assert(0);
+
+		if (retval) {
+			EDBM_update_generic(C, em, TRUE);
+		}
+	}
+	else {
+		if (type == 0) {
+			BKE_report(op->reports, RPT_ERROR, "Selecton not supported in object mode");
+			return OPERATOR_CANCELLED;
+		}
+
+		/* object mode separate */
+		CTX_DATA_BEGIN(C, Base *, base_iter, selected_editable_bases)
+		{
+			Object *ob = base_iter->object;
+			if (ob->type == OB_MESH) {
+				Mesh *me = ob->data;
+				if (me->id.lib == NULL) {
+					BMesh *bm_old = NULL;
+					int retval_iter = 0;
+
+					bm_old = BM_mesh_create(&bm_mesh_allocsize_default);
+
+					BM_mesh_bm_from_me(bm_old, me, FALSE, 0);
+
+					if      (type == 1) retval_iter = mesh_separate_material(bmain, scene, base_iter, bm_old);
+					else if (type == 2) retval_iter = mesh_separate_loose(bmain, scene, base_iter, bm_old);
+					else                BLI_assert(0);
+
+					if (retval_iter) {
+						BM_mesh_bm_to_me(bm_old, me, FALSE);
+
+						DAG_id_tag_update(&me->id, OB_RECALC_DATA);
+						WM_event_add_notifier(C, NC_GEOM | ND_DATA, me);
+					}
+
+					BM_mesh_free(bm_old);
+
+					retval |= retval_iter;
+				}
+			}
+		}
+		CTX_DATA_END;
+	}
+
+	if (retval) {
 		/* delay depsgraph recalc until all objects are duplicated */
 		DAG_scene_sort(bmain, scene);
 
-		EDBM_update_generic(C, em, TRUE);
-
 		return OPERATOR_FINISHED;
 	}
 
@@ -3000,7 +3031,7 @@ void MESH_OT_separate(wmOperatorType *ot)
 	/* api callbacks */
 	ot->invoke = WM_menu_invoke;
 	ot->exec = edbm_separate_exec;
-	ot->poll = ED_operator_editmesh;
+	ot->poll = ED_operator_scene_editable; /* object and editmode */
 	
 	/* flags */
 	ot->flag = OPTYPE_UNDO;
@@ -5106,7 +5137,7 @@ static int edbm_convex_hull_exec(bContext *C, wmOperator *op)
 	Object *obedit = CTX_data_edit_object(C);
 	BMEditMesh *em = BMEdit_FromObject(obedit);
 	BMOperator bmop;
-		
+
 	EDBM_op_init(em, &bmop, op, "convex_hull input=%hvef "
 	             "use_existing_faces=%b",
 	             BM_ELEM_SELECT,

From 54d29215085c687b59272dedf27ce573da62b9b3 Mon Sep 17 00:00:00 2001
From: Joshua Leung 
Date: Fri, 20 Jul 2012 12:18:45 +0000
Subject: [PATCH 102/108] Keyframes from lib-linked actions are now drawn
 ghosted (just like those of protected/unmodifiable channels),

---
 .../editors/animation/keyframes_draw.c        | 21 +++++++++++++------
 1 file changed, 15 insertions(+), 6 deletions(-)

diff --git a/source/blender/editors/animation/keyframes_draw.c b/source/blender/editors/animation/keyframes_draw.c
index 84711b97729..85731933168 100644
--- a/source/blender/editors/animation/keyframes_draw.c
+++ b/source/blender/editors/animation/keyframes_draw.c
@@ -674,15 +674,15 @@ static void draw_keylist(View2D *v2d, DLRBT_Tree *keys, DLRBT_Tree *blocks, floa
 	if (keys) {
 		/* locked channels are less strongly shown, as feedback for locked channels in DopeSheet */
 		/* TODO: allow this opacity factor to be themed? */
-		float kalpha = (channelLocked) ? 0.35f : 1.0f;
-
+		float kalpha = (channelLocked) ? 0.25f : 1.0f;
+		
 		for (ak = keys->first; ak; ak = ak->next) {
 			/* optimization: if keyframe doesn't appear within 5 units (screenspace) in visible area, don't draw
 			 *	- this might give some improvements, since we current have to flip between view/region matrices
 			 */
 			if (IN_RANGE_INCL(ak->cfra, v2d->cur.xmin, v2d->cur.xmax) == 0)
 				continue;
-
+			
 			/* draw using OpenGL - uglier but faster */
 			/* NOTE1: a previous version of this didn't work nice for some intel cards
 			 * NOTE2: if we wanted to go back to icons, these are  icon = (ak->sel & SELECT) ? ICON_SPACE2 : ICON_SPACE3; */
@@ -753,6 +753,10 @@ void draw_fcurve_channel(View2D *v2d, AnimData *adt, FCurve *fcu, float ypos)
 {
 	DLRBT_Tree keys, blocks;
 	
+	short locked = (fcu->flag & FCURVE_PROTECTED) ||
+	               ((fcu->grp) && (fcu->grp->flag & AGRP_PROTECTED)) ||
+	               ((adt && adt->action) && (adt->action->id.lib));
+	
 	BLI_dlrbTree_init(&keys);
 	BLI_dlrbTree_init(&blocks);
 	
@@ -761,7 +765,7 @@ void draw_fcurve_channel(View2D *v2d, AnimData *adt, FCurve *fcu, float ypos)
 	BLI_dlrbTree_linkedlist_sync(&keys);
 	BLI_dlrbTree_linkedlist_sync(&blocks);
 	
-	draw_keylist(v2d, &keys, &blocks, ypos, (fcu->flag & FCURVE_PROTECTED));
+	draw_keylist(v2d, &keys, &blocks, ypos, locked);
 	
 	BLI_dlrbTree_free(&keys);
 	BLI_dlrbTree_free(&blocks);
@@ -771,6 +775,9 @@ void draw_agroup_channel(View2D *v2d, AnimData *adt, bActionGroup *agrp, float y
 {
 	DLRBT_Tree keys, blocks;
 	
+	short locked = (agrp->flag & AGRP_PROTECTED) ||
+	               ((adt && adt->action) && (adt->action->id.lib));
+	
 	BLI_dlrbTree_init(&keys);
 	BLI_dlrbTree_init(&blocks);
 	
@@ -779,7 +786,7 @@ void draw_agroup_channel(View2D *v2d, AnimData *adt, bActionGroup *agrp, float y
 	BLI_dlrbTree_linkedlist_sync(&keys);
 	BLI_dlrbTree_linkedlist_sync(&blocks);
 	
-	draw_keylist(v2d, &keys, &blocks, ypos, (agrp->flag & AGRP_PROTECTED));
+	draw_keylist(v2d, &keys, &blocks, ypos, locked);
 	
 	BLI_dlrbTree_free(&keys);
 	BLI_dlrbTree_free(&blocks);
@@ -789,6 +796,8 @@ void draw_action_channel(View2D *v2d, AnimData *adt, bAction *act, float ypos)
 {
 	DLRBT_Tree keys, blocks;
 	
+	short locked = (act->id.lib != 0);
+	
 	BLI_dlrbTree_init(&keys);
 	BLI_dlrbTree_init(&blocks);
 	
@@ -797,7 +806,7 @@ void draw_action_channel(View2D *v2d, AnimData *adt, bAction *act, float ypos)
 	BLI_dlrbTree_linkedlist_sync(&keys);
 	BLI_dlrbTree_linkedlist_sync(&blocks);
 	
-	draw_keylist(v2d, &keys, &blocks, ypos, 0);
+	draw_keylist(v2d, &keys, &blocks, ypos, locked);
 	
 	BLI_dlrbTree_free(&keys);
 	BLI_dlrbTree_free(&blocks);

From 684affe5497793cd3154cf4e2b24a2daf14e9b53 Mon Sep 17 00:00:00 2001
From: Joshua Leung 
Date: Fri, 20 Jul 2012 12:29:56 +0000
Subject: [PATCH 103/108] Code cleanup - missing indention be gone!

(And fixed some incorrect comments)
---
 .../editors/animation/anim_channels_defines.c | 50 ++++++++---------
 .../blender/editors/animation/anim_filter.c   | 53 ++++++++-----------
 2 files changed, 47 insertions(+), 56 deletions(-)

diff --git a/source/blender/editors/animation/anim_channels_defines.c b/source/blender/editors/animation/anim_channels_defines.c
index fe5558c6f53..d4b30814403 100644
--- a/source/blender/editors/animation/anim_channels_defines.c
+++ b/source/blender/editors/animation/anim_channels_defines.c
@@ -2507,11 +2507,11 @@ static bAnimChannelType ACF_GPL =
 	acf_generic_channel_backdrop,   /* backdrop */
 	acf_generic_indention_flexible, /* indent level */
 	acf_generic_group_offset,       /* offset */
-
+	
 	acf_gpl_name,                   /* name */
 	acf_gpl_name_prop,              /* name prop */
 	NULL,                           /* icon */
-
+	
 	acf_gpl_setting_valid,          /* has setting */
 	acf_gpl_setting_flag,           /* flag for setting */
 	acf_gpl_setting_ptr             /* pointer for setting */
@@ -2541,7 +2541,7 @@ static short acf_mask_setting_valid(bAnimContext *UNUSED(ac), bAnimListElem *UNU
 		case ACHANNEL_SETTING_SELECT:
 		case ACHANNEL_SETTING_EXPAND:
 			return 1;
-
+		
 		default:
 			return 0;
 	}
@@ -2552,15 +2552,15 @@ static int acf_mask_setting_flag(bAnimContext *UNUSED(ac), int setting, short *n
 {
 	/* clear extra return data first */
 	*neg = 0;
-
+	
 	switch (setting) {
 		case ACHANNEL_SETTING_SELECT: /* selected */
 			return AGRP_SELECTED;
-
+		
 		case ACHANNEL_SETTING_EXPAND: /* expanded */
 			return MASK_ANIMF_EXPAND;
 	}
-
+	
 	/* this shouldn't happen */
 	return 0;
 }
@@ -2569,7 +2569,7 @@ static int acf_mask_setting_flag(bAnimContext *UNUSED(ac), int setting, short *n
 static void *acf_mask_setting_ptr(bAnimListElem *ale, int UNUSED(setting), short *type)
 {
 	Mask *mask = (Mask *)ale->data;
-
+	
 	/* all flags are just in mask->flag for now... */
 	return GET_ACF_FLAG_PTR(mask->flag, type);
 }
@@ -2578,16 +2578,16 @@ static void *acf_mask_setting_ptr(bAnimListElem *ale, int UNUSED(setting), short
 static bAnimChannelType ACF_MASKDATA =
 {
 	"Mask Datablock",            /* type name */
-
+	
 	acf_mask_color,                  /* backdrop color */
 	acf_group_backdrop,             /* backdrop */
 	acf_generic_indention_0,        /* indent level */
 	acf_generic_group_offset,       /* offset */
-
+	
 	acf_generic_idblock_name,       /* name */
 	acf_generic_idfill_nameprop,    /* name prop */
 	acf_mask_icon,                   /* icon */
-
+	
 	acf_mask_setting_valid,          /* has setting */
 	acf_mask_setting_flag,           /* flag for setting */
 	acf_mask_setting_ptr             /* pointer for setting */
@@ -2599,7 +2599,7 @@ static bAnimChannelType ACF_MASKDATA =
 static void acf_masklay_name(bAnimListElem *ale, char *name)
 {
 	MaskLayer *masklay = (MaskLayer *)ale->data;
-
+	
 	if (masklay && name)
 		BLI_strncpy(name, masklay->name, ANIM_CHAN_NAME_SIZE);
 }
@@ -2610,7 +2610,7 @@ static short acf_masklay_name_prop(bAnimListElem *ale, PointerRNA *ptr, Property
 	if (ale->data) {
 		RNA_pointer_create(ale->id, &RNA_MaskLayer, ale->data, ptr);
 		*prop = RNA_struct_name_property(ptr->type);
-
+		
 		return (*prop != NULL);
 	}
 
@@ -2625,7 +2625,7 @@ static short acf_masklay_setting_valid(bAnimContext *UNUSED(ac), bAnimListElem *
 		case ACHANNEL_SETTING_EXPAND: /* mask layers are more like F-Curves than groups */
 		case ACHANNEL_SETTING_VISIBLE: /* graph editor only */
 			return 0;
-
+		
 		/* always available */
 		default:
 			return 1;
@@ -2637,18 +2637,18 @@ static int acf_masklay_setting_flag(bAnimContext *UNUSED(ac), int setting, short
 {
 	/* clear extra return data first */
 	*neg = 0;
-
+	
 	switch (setting) {
 		case ACHANNEL_SETTING_SELECT: /* selected */
 			return MASK_LAYERFLAG_SELECT;
-
+		
 //		case ACHANNEL_SETTING_MUTE: /* muted */
 //			return GP_LAYER_HIDE;
-
+		
 		case ACHANNEL_SETTING_PROTECT: /* protected */
 			// *neg = 1; - if we change this to edtiability
 			return MASK_LAYERFLAG_LOCKED;
-
+		
 		default: /* unsupported */
 			return 0;
 	}
@@ -2702,17 +2702,17 @@ static void ANIM_init_channel_typeinfo_data(void)
 		animchannelTypeInfo[type++] = NULL;              /* None */
 		animchannelTypeInfo[type++] = NULL;              /* AnimData */
 		animchannelTypeInfo[type++] = NULL;              /* Special */
-
+		
 		animchannelTypeInfo[type++] = &ACF_SUMMARY;      /* Motion Summary */
-
+		
 		animchannelTypeInfo[type++] = &ACF_SCENE;        /* Scene */
 		animchannelTypeInfo[type++] = &ACF_OBJECT;       /* Object */
 		animchannelTypeInfo[type++] = &ACF_GROUP;        /* Group */
 		animchannelTypeInfo[type++] = &ACF_FCURVE;       /* F-Curve */
-
+		
 		animchannelTypeInfo[type++] = &ACF_FILLACTD;     /* Object Action Expander */
 		animchannelTypeInfo[type++] = &ACF_FILLDRIVERS;  /* Drivers Expander */
-
+		
 		animchannelTypeInfo[type++] = &ACF_DSMAT;        /* Material Channel */
 		animchannelTypeInfo[type++] = &ACF_DSLAM;        /* Lamp Channel */
 		animchannelTypeInfo[type++] = &ACF_DSCAM;        /* Camera Channel */
@@ -2727,15 +2727,15 @@ static void ANIM_init_channel_typeinfo_data(void)
 		animchannelTypeInfo[type++] = &ACF_DSTEX;        /* Texture Channel */
 		animchannelTypeInfo[type++] = &ACF_DSLAT;        /* Lattice Channel */
 		animchannelTypeInfo[type++] = &ACF_DSSPK;        /* Speaker Channel */
-
+		
 		animchannelTypeInfo[type++] = &ACF_SHAPEKEY;     /* ShapeKey */
-
+		
 		animchannelTypeInfo[type++] = &ACF_GPD;          /* Grease Pencil Datablock */
 		animchannelTypeInfo[type++] = &ACF_GPL;          /* Grease Pencil Layer */
-
+		
 		animchannelTypeInfo[type++] = &ACF_MASKDATA;     /* Mask Datablock */
 		animchannelTypeInfo[type++] = &ACF_MASKLAYER;    /* Mask Layer */
-
+		
 		// TODO: these types still need to be implemented!!!
 		// probably need a few extra flags for these special cases...
 		animchannelTypeInfo[type++] = NULL;              /* NLA Track */
diff --git a/source/blender/editors/animation/anim_filter.c b/source/blender/editors/animation/anim_filter.c
index 6144cc4ecc1..1dcb9f79a09 100644
--- a/source/blender/editors/animation/anim_filter.c
+++ b/source/blender/editors/animation/anim_filter.c
@@ -417,16 +417,16 @@ short ANIM_animdata_get_context(const bContext *C, bAnimContext *ac)
  *
  * For this to work correctly, a standard set of data needs to be available within the scope that this
  * gets called in: 
- *	- ListBase anim_data;
- *	- bDopeSheet *ads;
- *	- bAnimListElem *ale;
+ *  - ListBase anim_data;
+ *  - bDopeSheet *ads;
+ *  - bAnimListElem *ale;
  *  - size_t items;
  *
  *  - id: ID block which should have an AnimData pointer following it immediately, to use
- *	- adtOk: line or block of code to execute for AnimData-blocks case (usually ANIMDATA_ADD_ANIMDATA)
- *	- nlaOk: line or block of code to execute for NLA tracks+strips case
- *	- driversOk: line or block of code to execute for Drivers case
- *	- keysOk: line or block of code for Keyframes case
+ *  - adtOk: line or block of code to execute for AnimData-blocks case (usually ANIMDATA_ADD_ANIMDATA)
+ *  - nlaOk: line or block of code to execute for NLA tracks+strips case
+ *  - driversOk: line or block of code to execute for Drivers case
+ *  - keysOk: line or block of code for Keyframes case
  *
  * The checks for the various cases are as follows:
  *	0) top level: checks for animdata and also that all the F-Curves for the block will be visible
@@ -1316,6 +1316,7 @@ static size_t animdata_filter_shapekey(bAnimContext *ac, ListBase *anim_data, Ke
 	return items;
 }
 
+/* Helper for Grease Pencil - layers within a datablock */
 static size_t animdata_filter_gpencil_data(ListBase *anim_data, bGPdata *gpd, int filter_mode)
 {
 	bGPDlayer *gpl;
@@ -1382,6 +1383,7 @@ static size_t animdata_filter_gpencil(ListBase *anim_data, void *UNUSED(data), i
 	return items;
 }
 
+/* Helper for Mask Editing - mask layers */
 static size_t animdata_filter_mask_data(ListBase *anim_data, Mask *mask, const int filter_mode)
 {
 	MaskLayer *masklay_act = BKE_mask_layer_active(mask);
@@ -1398,18 +1400,6 @@ static size_t animdata_filter_mask_data(ListBase *anim_data, Mask *mask, const i
 				if (!(filter_mode & ANIMFILTER_ACTIVE) || (masklay_act == masklay)) {
 					/* add to list */
 					ANIMCHANNEL_NEW_CHANNEL(masklay, ANIMTYPE_MASKLAYER, mask);
-
-
-//					if (filter_mode & ANIMFILTER_TMP_PEEK)
-//						return 1;
-//					else {
-//						bAnimListElem *ale = make_new_animlistelem(masklay, channel_type, (ID *)owner_id);
-//						if (ale) {
-//							BLI_addtail(anim_data, ale);
-//							items ++;
-//						}
-//					}
-
 				}
 //			}
 		}
@@ -1418,28 +1408,29 @@ static size_t animdata_filter_mask_data(ListBase *anim_data, Mask *mask, const i
 	return items;
 }
 
+/* Grab all mask data */
 static size_t animdata_filter_mask(ListBase *anim_data, void *UNUSED(data), int filter_mode)
 {
 	Mask *mask;
 	size_t items = 0;
-
-	/* for now, grab grease pencil datablocks directly from main */
+	
+	/* for now, grab mask datablocks directly from main */
 	// XXX: this is not good...
 	for (mask = G.main->mask.first; mask; mask = mask->id.next) {
 		ListBase tmp_data = {NULL, NULL};
 		size_t tmp_items = 0;
-
-		/* only show if gpd is used by something... */
+		
+		/* only show if mask is used by something... */
 		if (ID_REAL_USERS(mask) < 1)
 			continue;
-
-		/* add gpencil animation channels */
+		
+		/* add mask animation channels */
 		BEGIN_ANIMFILTER_SUBCHANNELS(EXPANDED_MASK(mask))
 		{
 			tmp_items += animdata_filter_mask_data(&tmp_data, mask, filter_mode);
 		}
 		END_ANIMFILTER_SUBCHANNELS;
-
+		
 		/* did we find anything? */
 		if (tmp_items) {
 			/* include data-expand widget first */
@@ -1447,14 +1438,14 @@ static size_t animdata_filter_mask(ListBase *anim_data, void *UNUSED(data), int
 				/* add gpd as channel too (if for drawing, and it has layers) */
 				ANIMCHANNEL_NEW_CHANNEL(mask, ANIMTYPE_MASKDATABLOCK, NULL);
 			}
-
+			
 			/* now add the list of collected channels */
 			BLI_movelisttolist(anim_data, &tmp_data);
 			BLI_assert((tmp_data.first == tmp_data.last) && (tmp_data.first == NULL));
 			items += tmp_items;
 		}
 	}
-
+	
 	/* return the number of items added to the list */
 	return items;
 }
@@ -2386,7 +2377,7 @@ size_t ANIM_animdata_filter(bAnimContext *ac, ListBase *anim_data, int filter_mo
 					items += animfilter_action(ac, anim_data, ads, data, filter_mode, (ID *)obact);
 			}
 			break;
-
+			
 			case ANIMCONT_SHAPEKEY: /* 'ShapeKey Editor' */
 			{
 				/* the check for the DopeSheet summary is included here since the summary works here too */
@@ -2401,14 +2392,14 @@ size_t ANIM_animdata_filter(bAnimContext *ac, ListBase *anim_data, int filter_mo
 					items = animdata_filter_gpencil(anim_data, data, filter_mode);
 			}
 			break;
-
+			
 			case ANIMCONT_MASK:
 			{
 				if (animdata_filter_dopesheet_summary(ac, anim_data, filter_mode, &items))
 					items = animdata_filter_mask(anim_data, data, filter_mode);
 			}
 			break;
-
+			
 			case ANIMCONT_DOPESHEET: /* 'DopeSheet Editor' */
 			{
 				/* the DopeSheet editor is the primary place where the DopeSheet summaries are useful */

From 054b78d74bac1fa057d7a4ee22f5cae2db7d26cc Mon Sep 17 00:00:00 2001
From: Joshua Leung 
Date: Fri, 20 Jul 2012 12:33:35 +0000
Subject: [PATCH 104/108] Commented out "Filter" FModifier type entry in type
 enum. This doesn't exist yet, and likely won't exist for a while.

---
 source/blender/makesrna/intern/rna_fcurve.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/source/blender/makesrna/intern/rna_fcurve.c b/source/blender/makesrna/intern/rna_fcurve.c
index 5eb15cf31b6..a0d64723a5c 100644
--- a/source/blender/makesrna/intern/rna_fcurve.c
+++ b/source/blender/makesrna/intern/rna_fcurve.c
@@ -55,7 +55,7 @@ EnumPropertyItem fmodifier_type_items[] = {
 	{FMODIFIER_TYPE_ENVELOPE, "ENVELOPE", 0, "Envelope", ""},
 	{FMODIFIER_TYPE_CYCLES, "CYCLES", 0, "Cycles", ""},
 	{FMODIFIER_TYPE_NOISE, "NOISE", 0, "Noise", ""},
-	{FMODIFIER_TYPE_FILTER, "FILTER", 0, "Filter", ""},
+	/*{FMODIFIER_TYPE_FILTER, "FILTER", 0, "Filter", ""},*/ /* FIXME: not implemented yet! */
 	/*{FMODIFIER_TYPE_PYTHON, "PYTHON", 0, "Python", ""},	 *//* FIXME: not implemented yet! */
 	{FMODIFIER_TYPE_LIMITS, "LIMITS", 0, "Limits", ""},
 	{FMODIFIER_TYPE_STEPPED, "STEPPED", 0, "Stepped Interpolation", ""},

From e94ef6ca6ced8976203c160056983672c5c465b6 Mon Sep 17 00:00:00 2001
From: Campbell Barton 
Date: Fri, 20 Jul 2012 13:54:05 +0000
Subject: [PATCH 105/108] ignore hidden faces when splitting by loose parts of
 materials.

---
 source/blender/editors/mesh/editmesh_tools.c | 103 ++++++++++++++-----
 1 file changed, 76 insertions(+), 27 deletions(-)

diff --git a/source/blender/editors/mesh/editmesh_tools.c b/source/blender/editors/mesh/editmesh_tools.c
index 53744a01b8c..08f70f984a8 100644
--- a/source/blender/editors/mesh/editmesh_tools.c
+++ b/source/blender/editors/mesh/editmesh_tools.c
@@ -2790,7 +2790,7 @@ void MESH_OT_knife_cut(wmOperatorType *ot)
 	RNA_def_int(ot->srna, "cursor", BC_KNIFECURSOR, 0, INT_MAX, "Cursor", "", 0, INT_MAX);
 }
 
-static int mesh_separate_selected(Main *bmain, Scene *scene, Base *base_old, BMesh *bm_old)
+static int mesh_separate_tagged(Main *bmain, Scene *scene, Base *base_old, BMesh *bm_old)
 {
 	Base *base_new;
 	BMIter iter;
@@ -2816,33 +2816,27 @@ static int mesh_separate_selected(Main *bmain, Scene *scene, Base *base_old, BMe
 
 	ED_base_object_select(base_new, BA_SELECT);
 
-	BMO_op_callf(bm_old, "duplicate geom=%hvef dest=%p", BM_ELEM_SELECT, bm_new);
-	BMO_op_callf(bm_old, "delete geom=%hvef context=%i", BM_ELEM_SELECT, DEL_FACES);
+	BMO_op_callf(bm_old, "duplicate geom=%hvef dest=%p", BM_ELEM_TAG, bm_new);
+	BMO_op_callf(bm_old, "delete geom=%hvef context=%i", BM_ELEM_TAG, DEL_FACES);
 
 	/* clean up any loose edges */
 	BM_ITER_MESH (e, &iter, bm_old, BM_EDGES_OF_MESH) {
-		if (BM_elem_flag_test(e, BM_ELEM_HIDDEN))
-			continue;
-
 		if (!BM_edge_is_wire(e)) {
-			BM_edge_select_set(bm_old, e, FALSE);
+			BM_elem_flag_disable(e, BM_ELEM_TAG);
 		}
 	}
-	BMO_op_callf(bm_old, "delete geom=%hvef context=%i", BM_ELEM_SELECT, DEL_EDGES);
+	BMO_op_callf(bm_old, "delete geom=%hvef context=%i", BM_ELEM_TAG, DEL_EDGES);
 
 	/* clean up any loose verts */
 	BM_ITER_MESH (v, &iter, bm_old, BM_VERTS_OF_MESH) {
-		if (BM_elem_flag_test(v, BM_ELEM_HIDDEN))
-			continue;
-
 		if (BM_vert_edge_count(v) != 0) {
-			BM_vert_select_set(bm_old, v, FALSE);
+			BM_elem_flag_disable(v, BM_ELEM_TAG);
 		}
 	}
 
-	BMO_op_callf(bm_old, "delete geom=%hvef context=%i", BM_ELEM_SELECT, DEL_VERTS);
+	BMO_op_callf(bm_old, "delete geom=%hvef context=%i", BM_ELEM_TAG, DEL_VERTS);
 
-	BM_mesh_normals_update(bm_new, TRUE);
+	BM_mesh_normals_update(bm_new, FALSE);
 
 	BM_mesh_bm_to_me(bm_new, base_new->object->data, FALSE);
 
@@ -2852,13 +2846,58 @@ static int mesh_separate_selected(Main *bmain, Scene *scene, Base *base_old, BMe
 	return TRUE;
 }
 
+static int mesh_separate_selected(Main *bmain, Scene *scene, Base *base_old, BMesh *bm_old)
+{
+	/* tag -> select */
+	BM_mesh_elem_hflag_enable_test(bm_old, BM_FACE | BM_EDGE | BM_VERT, BM_ELEM_TAG, TRUE, BM_ELEM_SELECT);
+
+	return mesh_separate_tagged(bmain, scene, base_old, bm_old);
+}
+
+/* flush a hflag to from verts to edges/faces */
+static void bm_mesh_hflag_flush_vert(BMesh *bm, const char hflag)
+{
+	BMEdge *e;
+	BMLoop *l_iter;
+	BMLoop *l_first;
+	BMFace *f;
+
+	BMIter eiter;
+	BMIter fiter;
+
+	int ok;
+
+	BM_ITER_MESH (e, &eiter, bm, BM_EDGES_OF_MESH) {
+		if (BM_elem_flag_test(e->v1, hflag) &&
+		    BM_elem_flag_test(e->v2, hflag))
+		{
+			BM_elem_flag_enable(e, hflag);
+		}
+		else {
+			BM_elem_flag_disable(e, hflag);
+		}
+	}
+	BM_ITER_MESH (f, &fiter, bm, BM_FACES_OF_MESH) {
+		ok = TRUE;
+		l_iter = l_first = BM_FACE_FIRST_LOOP(f);
+		do {
+			if (!BM_elem_flag_test(l_iter->v, hflag)) {
+				ok = FALSE;
+				break;
+			}
+		} while ((l_iter = l_iter->next) != l_first);
+
+		BM_elem_flag_set(f, hflag, ok);
+	}
+}
+
 static int mesh_separate_material(Main *bmain, Scene *scene, Base *base_old, BMesh *bm_old)
 {
 	BMFace *f_cmp, *f;
 	BMIter iter;
 	int result = FALSE;
 
-	BM_mesh_elem_hflag_disable_all(bm_old, BM_VERT | BM_EDGE | BM_FACE, BM_ELEM_SELECT, FALSE);
+	BM_mesh_elem_hflag_disable_all(bm_old, BM_VERT | BM_EDGE | BM_FACE, BM_ELEM_TAG, FALSE);
 
 	while ((f_cmp = BM_iter_at_index(bm_old, BM_FACES_OF_MESH, NULL, 0))) {
 		const short mat_nr = f_cmp->mat_nr;
@@ -2866,7 +2905,16 @@ static int mesh_separate_material(Main *bmain, Scene *scene, Base *base_old, BMe
 
 		BM_ITER_MESH (f, &iter, bm_old, BM_FACES_OF_MESH) {
 			if (f->mat_nr == mat_nr) {
-				BM_face_select_set(bm_old, f, TRUE);
+				BMLoop *l_iter;
+				BMLoop *l_first;
+
+				BM_elem_flag_enable(f, BM_ELEM_TAG);
+				l_iter = l_first = BM_FACE_FIRST_LOOP(f);
+				do {
+					BM_elem_flag_enable(l_iter->v, BM_ELEM_TAG);
+					BM_elem_flag_enable(l_iter->e, BM_ELEM_TAG);
+				} while ((l_iter = l_iter->next) != l_first);
+
 				tot++;
 			}
 		}
@@ -2877,7 +2925,7 @@ static int mesh_separate_material(Main *bmain, Scene *scene, Base *base_old, BMe
 		}
 
 		/* Move selection into a separate object */
-		result |= mesh_separate_selected(bmain, scene, base_old, bm_old);
+		result |= mesh_separate_tagged(bmain, scene, base_old, bm_old);
 	}
 
 	return result;
@@ -2893,7 +2941,7 @@ static int mesh_separate_loose(Main *bmain, Scene *scene, Base *base_old, BMesh
 	int max_iter = bm_old->totvert;
 
 	/* Clear all selected vertices */
-	BM_mesh_elem_hflag_disable_all(bm_old, BM_VERT | BM_EDGE | BM_FACE, BM_ELEM_SELECT, FALSE);
+	BM_mesh_elem_hflag_disable_all(bm_old, BM_VERT | BM_EDGE | BM_FACE, BM_ELEM_TAG, FALSE);
 
 	/* A "while (true)" loop should work here as each iteration should
 	 * select and remove at least one vertex and when all vertices
@@ -2901,6 +2949,7 @@ static int mesh_separate_loose(Main *bmain, Scene *scene, Base *base_old, BMesh
 	 * behavior by limiting iterations to the number of vertices in the
 	 * original mesh.*/
 	for (i = 0; i < max_iter; i++) {
+		int tot = 0;
 		/* Get a seed vertex to start the walk */
 		v_seed = BM_iter_at_index(bm_old, BM_VERTS_OF_MESH, NULL, 0);
 
@@ -2910,7 +2959,7 @@ static int mesh_separate_loose(Main *bmain, Scene *scene, Base *base_old, BMesh
 		}
 
 		/* Select the seed explicitly, in case it has no edges */
-		BM_vert_select_set(bm_old, v_seed, TRUE);
+		BM_elem_flag_enable(v_seed, BM_ELEM_TAG);
 
 		/* Walk from the single vertex, selecting everything connected
 		 * to it */
@@ -2921,22 +2970,22 @@ static int mesh_separate_loose(Main *bmain, Scene *scene, Base *base_old, BMesh
 
 		e = BMW_begin(&walker, v_seed);
 		for (; e; e = BMW_step(&walker)) {
-			BM_vert_select_set(bm_old, e->v1, TRUE);
-			BM_vert_select_set(bm_old, e->v2, TRUE);
+			if (!BM_elem_flag_test(e->v1, BM_ELEM_TAG)) { BM_elem_flag_enable(e->v1, BM_ELEM_TAG); tot++; }
+			if (!BM_elem_flag_test(e->v2, BM_ELEM_TAG)) { BM_elem_flag_enable(e->v2, BM_ELEM_TAG); tot++; }
 		}
 		BMW_end(&walker);
 
-		/* Flush the selection to get edge/face selections matching
-		 * the vertex selection */
-		BM_mesh_select_mode_flush_ex(bm_old, SCE_SELECT_VERTEX);
-
-		if (bm_old->totvert == bm_old->totvertsel) {
+		if (bm_old->totvert == tot) {
 			/* Every vertex selected, nothing to separate, work is done */
 			break;
 		}
 
+		/* Flush the selection to get edge/face selections matching
+		 * the vertex selection */
+		bm_mesh_hflag_flush_vert(bm_old, BM_ELEM_TAG);
+
 		/* Move selection into a separate object */
-		result |= mesh_separate_selected(bmain, scene, base_old, bm_old);
+		result |= mesh_separate_tagged(bmain, scene, base_old, bm_old);
 	}
 
 	return result;

From 80a24a2ff55935296ccd2699091411bdb987dfb1 Mon Sep 17 00:00:00 2001
From: Campbell Barton 
Date: Fri, 20 Jul 2012 14:01:43 +0000
Subject: [PATCH 106/108] fix for compositor bug, mix node operation `clamp`
 was uninitialized.

made HSV node randomly clamp values from 0-1.
---
 source/blender/compositor/operations/COM_MixBaseOperation.cpp | 1 +
 1 file changed, 1 insertion(+)

diff --git a/source/blender/compositor/operations/COM_MixBaseOperation.cpp b/source/blender/compositor/operations/COM_MixBaseOperation.cpp
index e9dd7078f83..9f9c432895e 100644
--- a/source/blender/compositor/operations/COM_MixBaseOperation.cpp
+++ b/source/blender/compositor/operations/COM_MixBaseOperation.cpp
@@ -32,6 +32,7 @@ MixBaseOperation::MixBaseOperation() : NodeOperation()
 	this->m_inputColor1Operation = NULL;
 	this->m_inputColor2Operation = NULL;
 	this->setUseValueAlphaMultiply(false);
+	this->setUseClamp(false);
 }
 
 void MixBaseOperation::initExecution()

From f883337ba3ad23370ca23f0601f231883ac3c021 Mon Sep 17 00:00:00 2001
From: Lukas Toenne 
Date: Fri, 20 Jul 2012 15:07:06 +0000
Subject: [PATCH 107/108] Fix #32118, Reroute nodes inside groups get created
 in wonky places.

Previous attempt was not taking into account parent nodes of the group nodes (i.e. frames). The nodeFromView function should be used to convert between relative node location to absolute view space. Also added this in the node_add_node helper function, which is used in a number of operators for adding nodes in a specific location.
---
 source/blender/editors/space_node/node_edit.c | 19 +++++++++++--------
 1 file changed, 11 insertions(+), 8 deletions(-)

diff --git a/source/blender/editors/space_node/node_edit.c b/source/blender/editors/space_node/node_edit.c
index 512781f9b77..a0df2aefab1 100644
--- a/source/blender/editors/space_node/node_edit.c
+++ b/source/blender/editors/space_node/node_edit.c
@@ -2549,14 +2549,16 @@ bNode *node_add_node(SpaceNode *snode, Main *bmain, Scene *scene, bNodeTemplate
 	
 	/* generics */
 	if (node) {
-		node->locx = locx;
-		node->locy = locy + 60.0f;       // arbitrary.. so its visible, (0,0) is top of node
 		node_select(node);
 		
 		gnode = node_tree_get_editgroup(snode->nodetree);
+		// arbitrary y offset of 60 so its visible
 		if (gnode) {
-			node->locx -= gnode->locx;
-			node->locy -= gnode->locy;
+			nodeFromView(gnode, locx, locy + 60.0f, &node->locx, &node->locy);
+		}
+		else {
+			node->locx = locx;
+			node->locy = locy + 60.0f;
 		}
 
 		ntreeUpdateTree(snode->edittree);
@@ -3173,11 +3175,12 @@ static int add_reroute_exec(bContext *C, wmOperator *op)
 				
 				ntemp.type = NODE_REROUTE;
 				rerouteNode = nodeAddNode(snode->edittree, &ntemp);
-				rerouteNode->locx = insertPoint[0];
-				rerouteNode->locy = insertPoint[1];
 				if (gnode) {
-					rerouteNode->locx -= gnode->locx;
-					rerouteNode->locy -= gnode->locy;
+					nodeFromView(gnode, insertPoint[0], insertPoint[1], &rerouteNode->locx, &rerouteNode->locy);
+				}
+				else {
+					rerouteNode->locx = insertPoint[0];
+					rerouteNode->locy = insertPoint[1];
 				}
 				
 				nodeAddLink(snode->edittree, link->fromnode, link->fromsock, rerouteNode, rerouteNode->inputs.first);

From 16516238e2b25ce53144c2dcea5323dc7313b724 Mon Sep 17 00:00:00 2001
From: Campbell Barton 
Date: Fri, 20 Jul 2012 19:11:47 +0000
Subject: [PATCH 108/108] patch [#32152] Make NlaTrack.is_solo settable from
 Peter Amstutz (tetron)

---
 source/blender/makesrna/intern/rna_nla.c | 41 ++++++++++++++++++++++--
 1 file changed, 39 insertions(+), 2 deletions(-)

diff --git a/source/blender/makesrna/intern/rna_nla.c b/source/blender/makesrna/intern/rna_nla.c
index edfbf0f2efd..b47f957ac76 100644
--- a/source/blender/makesrna/intern/rna_nla.c
+++ b/source/blender/makesrna/intern/rna_nla.c
@@ -357,6 +357,43 @@ static void rna_NlaStrip_remove(NlaTrack *track, bContext *C, ReportList *report
 	}
 }
 
+/* Set the 'solo' setting for the given NLA-track, making sure that it is the only one
+ * that has this status in its AnimData block.
+ */
+void rna_NlaTrack_solo_set(PointerRNA *ptr, int value)
+{
+	NlaTrack *data = (NlaTrack*)ptr->data;
+	AnimData *adt = BKE_animdata_from_id(ptr->id.data);
+	NlaTrack *nt;
+
+	if (data == NULL) {
+		return;
+	}
+	
+	/* firstly, make sure 'solo' flag for all tracks is disabled */
+	for (nt = data; nt; nt = nt->next) {
+		nt->flag &= ~NLATRACK_SOLO;
+	}
+	for (nt = data; nt; nt = nt->prev) {
+		nt->flag &= ~NLATRACK_SOLO;
+	}
+		
+	/* now, enable 'solo' for the given track if appropriate */
+	if (value) {
+		/* set solo status */
+		data->flag |= NLATRACK_SOLO;
+		
+		/* set solo-status on AnimData */
+		adt->flag |= ADT_NLA_SOLO_TRACK;
+	}
+	else {
+		/* solo status was already cleared on track */
+
+		/* clear solo-status on AnimData */
+		adt->flag &= ~ADT_NLA_SOLO_TRACK;
+	}
+}
+
 #else
 
 /* enum defines exported for rna_animation.c */
@@ -637,13 +674,13 @@ static void rna_def_nlatrack(BlenderRNA *brna)
 	
 	prop = RNA_def_property(srna, "is_solo", PROP_BOOLEAN, PROP_NONE);
 	/* can be made editable by hooking it up to the necessary NLA API methods */
-	RNA_def_property_clear_flag(prop, PROP_EDITABLE);
 	RNA_def_property_boolean_sdna(prop, NULL, "flag", NLATRACK_SOLO);
 	RNA_def_property_ui_text(prop, "Solo",
 	                         "NLA Track is evaluated itself (i.e. active Action and all other NLA Tracks in the "
 	                         "same AnimData block are disabled)");
 	RNA_def_property_update(prop, NC_ANIMATION | ND_NLA, NULL); /* this will do? */
-	
+	RNA_def_property_boolean_funcs(prop, NULL, "rna_NlaTrack_solo_set");
+
 	prop = RNA_def_property(srna, "select", PROP_BOOLEAN, PROP_NONE);
 	RNA_def_property_boolean_sdna(prop, NULL, "flag", NLATRACK_SELECTED);
 	RNA_def_property_ui_text(prop, "Select", "NLA Track is selected");