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/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 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/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/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; } 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/guardedalloc/MEM_guardedalloc.h b/intern/guardedalloc/MEM_guardedalloc.h index 7fcfba5afec..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 @@ -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,32 +111,34 @@ 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 ; - - /** 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) + 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 ; - - /** 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) + 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 ; @@ -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); @@ -213,11 +216,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..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 ***** */ @@ -222,10 +223,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; @@ -904,6 +905,4 @@ const char *MEM_name_ptr(void *vmemh) return "MEM_name_ptr(NULL)"; } } -#endif - -/* eof */ +#endif /* NDEBUG */ 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 ;ibezt.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 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/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/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/cdderivedmesh.c b/source/blender/blenkernel/intern/cdderivedmesh.c index e5e73061d52..b19b9db8749 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 */ @@ -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/curve.c b/source/blender/blenkernel/intern/curve.c index 674a2d98d07..31491a80f2b 100644 --- a/source/blender/blenkernel/intern/curve.c +++ b/source/blender/blenkernel/intern/curve.c @@ -1588,7 +1588,7 @@ static int cu_isectLL(const float v1[3], const float v2[3], const float v3[3], c float *labda, float *mu, float vec[3]) { /* return: - * -1: colliniar + * -1: collinear * 0: no intersection of segments * 1: exact intersection of segments * 2: cross-intersection of segments 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/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/fmodifier.c b/source/blender/blenkernel/intern/fmodifier.c index cefcbdd2762..438188b1e2a 100644 --- a/source/blender/blenkernel/intern/fmodifier.c +++ b/source/blender/blenkernel/intern/fmodifier.c @@ -1298,7 +1298,7 @@ float evaluate_time_fmodifiers(ListBase *modifiers, FCurve *fcu, float cvalue, f return evaltime; } -/* Evalautes the given set of F-Curve Modifiers using the given data +/* Evaluates the given set of F-Curve Modifiers using the given data * Should only be called after evaluate_time_fmodifiers() has been called... */ void evaluate_value_fmodifiers(ListBase *modifiers, FCurve *fcu, float *cvalue, float evaltime) diff --git a/source/blender/blenkernel/intern/group.c b/source/blender/blenkernel/intern/group.c index 95e659e9a2c..b615f8c0d9f 100644 --- a/source/blender/blenkernel/intern/group.c +++ b/source/blender/blenkernel/intern/group.c @@ -351,7 +351,7 @@ void group_handle_recalc_and_update(Scene *scene, Object *UNUSED(parent), Group #if 0 /* warning, isn't clearing the recalc flag on the object which causes it to run all the time, * not just on frame change. - * This isn't working because the animation data is only re-evalyated on frame change so commenting for now + * This isn't working because the animation data is only re-evaluated on frame change so commenting for now * but when its enabled at some point it will need to be changed so as not to update so much - campbell */ /* if animated group... */ diff --git a/source/blender/blenkernel/intern/implicit.c b/source/blender/blenkernel/intern/implicit.c index 5b3e823f050..8a573aaa676 100644 --- a/source/blender/blenkernel/intern/implicit.c +++ b/source/blender/blenkernel/intern/implicit.c @@ -185,7 +185,7 @@ DO_INLINE void print_lfvector(float (*fLongVector)[3], unsigned int verts) /* create long vector */ DO_INLINE lfVector *create_lfvector(unsigned int verts) { - /* TODO: check if memory allocation was successfull */ + /* TODO: check if memory allocation was successful */ return (lfVector *)MEM_callocN(verts * sizeof(lfVector), "cloth_implicit_alloc_vector"); // return (lfVector *)cloth_aligned_malloc(&MEMORY_BASE, verts * sizeof(lfVector)); } @@ -513,7 +513,7 @@ static void print_bfmatrix(fmatrix3x3 *m3) /* create big matrix */ DO_INLINE fmatrix3x3 *create_bfmatrix(unsigned int verts, unsigned int springs) { - // TODO: check if memory allocation was successfull */ + // TODO: check if memory allocation was successful */ fmatrix3x3 *temp = (fmatrix3x3 *)MEM_callocN(sizeof(fmatrix3x3) * (verts + springs), "cloth_implicit_alloc_matrix"); temp[0].vcount = verts; temp[0].scount = springs; 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/mask.c b/source/blender/blenkernel/intern/mask.c index 4e683d1618f..fa11721a944 100644 --- a/source/blender/blenkernel/intern/mask.c +++ b/source/blender/blenkernel/intern/mask.c @@ -239,14 +239,14 @@ 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); 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); @@ -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] @@ -401,12 +404,266 @@ 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 = 256; + + 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], int tot_feather_point, 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, len; + float p[2]; + + isect_seg_seg_v2_point(v1, v2, v3, v4, 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); + } + + 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], const float min[2], const float bucket_scale[2], + const int buckets_per_side) +{ + int x = (int) ((co[0] - min[0]) * bucket_scale[0]); + int y = (int) ((co[1] - min[1]) * bucket_scale[1]); + + if (x == buckets_per_side) + x--; + + if (y == buckets_per_side) + y--; + + return y * buckets_per_side + x; +} + +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(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) + + 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, + * 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); + + for (i = 0; i < tot_feather_point; i++) { + int next = i + 1; + float delta; + + 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) + 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); + + 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; + + /* 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, end = i + 1; + int start_bucket_index, end_bucket_index; + + 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]); + + feather_bucket_add_edge(&buckets[start_bucket_index], start, end); + + 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_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, cur_b = i + 1; + int start_bucket_index, end_bucket_index; + + FeatherEdgesBucket *start_bucket; + + 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_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 */ + for (i = 0; i < tot_bucket; i++) { + if (buckets[i].segments) + MEM_freeN(buckets[i].segments); + } + + MEM_freeN(buckets); + +#undef BUCKET_INDEX +} + /** * 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; @@ -467,6 +724,11 @@ float (*BKE_mask_spline_feather_differentiated_points_with_resolution_ex(MaskSpl *tot_feather_point = tot; + /* this is slow! - don't do on draw */ + if (do_collapse) { + spline_feather_collapse_inner_loops(spline, feather, tot); + } + return feather; } @@ -475,7 +737,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 bb18166ba6d..b05c1ad4eaa 100644 --- a/source/blender/blenkernel/intern/mask_rasterize.c +++ b/source/blender/blenkernel/intern/mask_rasterize.c @@ -32,39 +32,107 @@ #include "DNA_vec_types.h" #include "DNA_mask_types.h" +#include "DNA_scene_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 +/* 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 + +/* 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) + +#define TRI_TERMINATOR_ID ((unsigned int) -1) +#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) \ +{ \ + unsigned int *_t = face; \ + BLI_assert(_t[0] < vert_max); \ + BLI_assert(_t[1] < vert_max); \ + 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]) +{ + const float s = sinf(angle); + const float c = cosf(angle); + float p_new[2]; + + /* translate point back to origin */ + r_p[0] = (p[0] - cent[0]) / asp[0]; + r_p[1] = (p[1] - cent[1]) / asp[1]; + + /* rotate point */ + 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 */ + 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); +} + +/* --------------------------------------------------------------------- */ +/* local structs for mask rasterizeing */ +/* --------------------------------------------------------------------- */ /** - * 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. + * the final pixel with its own blending mode and the final pixel + * is blended between these. */ /* internal use only */ typedef struct MaskRasterLayer { - /* xy raytree */ - BVHTree *bvhtree; + /* geometry */ + 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; - /* 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_face; + /* cache divide and subtract */ + float buckets_xy_scalar[2]; /* (1.0 / (buckets_width + FLT_EPSILON)) * buckets_x */ + unsigned int buckets_x; + unsigned int buckets_y; /* copied direct from #MaskLayer.--- */ @@ -72,9 +140,21 @@ typedef struct MaskRasterLayer { float alpha; char blend; char blend_flag; + char falloff; } 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; /** * opaque local struct for mask pixel lookup, each MaskLayer needs one of these @@ -83,11 +163,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; }; -MaskRasterHandle *BLI_maskrasterize_handle_new(void) +/* --------------------------------------------------------------------- */ +/* alloc / free functions */ +/* --------------------------------------------------------------------- */ + +MaskRasterHandle *BKE_maskrasterize_handle_new(void) { MaskRasterHandle *mr_handle; @@ -96,22 +180,33 @@ 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; - MaskRasterLayer *raslayers = mr_handle->layers; + MaskRasterLayer *layer = mr_handle->layers; - /* raycast vars */ - for (i = 0; i < layers_tot; i++, raslayers++) { - BLI_bvhtree_free(raslayers->bvhtree); + for (i = 0; i < layers_tot; i++, layer++) { - if (raslayers->tri_array) { - MEM_freeN(raslayers->tri_array); + if (layer->face_array) { + MEM_freeN(layer->face_array); } - if (raslayers->tri_coords) { - MEM_freeN(raslayers->tri_coords); + if (layer->face_coords) { + MEM_freeN(layer->face_coords); + } + + 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 = layer->buckets_face[bucket_index]; + if (face_index) { + MEM_freeN(face_index); + } + } + + MEM_freeN(layer->buckets_face); } } @@ -119,21 +214,16 @@ void BLI_maskrasterize_handle_free(MaskRasterHandle *mr_handle) MEM_freeN(mr_handle); } -#define PRINT_MASK_DEBUG printf -#define SF_EDGE_IS_BOUNDARY 0xff - -#define SF_KEYINDEX_TEMP_ID ((unsigned int) -1) - - -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) +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) { - 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]; @@ -153,12 +243,9 @@ 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]; + /* co_prev = diff_points[k_prev]; */ /* precalc */ co_curr = diff_points[k_curr]; co_next = diff_points[k_next]; @@ -183,26 +270,265 @@ 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++; } } -#define TRI_VERT ((unsigned int) -1) +/* 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. + * + * 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_size_x, const float bucket_size_y, + const float bucket_max_rad_squared) +{ + unsigned int *face = layer->face_array[face_index]; + float (*cos)[3] = layer->face_coords; -void BLI_maskrasterize_handle_init(MaskRasterHandle *mr_handle, struct Mask *mask, + 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; + + const 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]]; + + if (isect_point_tri_v2(cent, v1, v2, v3)) { + 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; + } + } + + } + 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]]; + + if (isect_point_tri_v2(cent, v1, v2, v3)) { + return TRUE; + } + else if (isect_point_tri_v2(cent, v1, v3, v4)) { + 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; + } + } + } +} + +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; + + layer->buckets_xy_scalar[0] = 0.0f; + 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) +{ + MemArena *arena = BLI_memarena_new(1 << 16, __func__); + + 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 = (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); + + 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 + 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; + + 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 face_index; + + for (face_index = 0; face_index < layer->face_tot; face_index++, face += 4) { + float xmin; + float xmax; + float ymin; + float ymax; + + if (face[3] == TRI_VERT) { + const float *v1 = cos[face[0]]; + const float *v2 = cos[face[1]]; + const float *v3 = cos[face[2]]; + + 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]]; + const float *v2 = cos[face[1]]; + const float *v3 = cos[face[2]]; + const float *v4 = cos[face[3]]; + + 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]))); + } + + + /* 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))) { + + CLAMP(xmin, 0.0f, 1.0f); + CLAMP(ymin, 0.0f, 1.0f); + CLAMP(xmax, 0.0f, 1.0f); + CLAMP(ymax, 0.0f, 1.0f); + + { + 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++) { + // 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]++; + } + } + } + } + } + } + + if (1) { + /* now convert linknodes into arrays for faster per pixel access */ + 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++) { + if (bucketstore_tot[bucket_index]) { + unsigned int *bucket = MEM_mallocN((bucketstore_tot[bucket_index] + 1) * sizeof(unsigned int), + __func__); + LinkNode *bucket_node; + + 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); + bucket++; + } + *bucket = TRI_TERMINATOR_ID; + } + else { + buckets_face[bucket_index] = NULL; + } + } + + layer->buckets_face = buckets_face; + } + + MEM_freeN(bucketstore); + MEM_freeN(bucketstore_tot); + } + + BLI_memarena_free(arena); +} + +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) { - /* TODO: real size */ - const int resol = RESOL; - const float aa_filter_size = 1.0f / MIN2(width, height); + 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; - 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)); @@ -210,6 +536,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++) { + /* we need to store vertex ranges for open splines for filling */ + unsigned int tot_splines; + MaskRasterSplineInfo *open_spline_ranges; + unsigned int open_spline_index = 0; + MaskSpline *spline; /* scanfill */ @@ -221,13 +552,26 @@ void BLI_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--; + masklay_index--; 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) { + 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; @@ -235,11 +579,17 @@ 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); + 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, &tot_diff_point, resol); - /* 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, &tot_diff_feather_points, resol, TRUE); + BLI_assert(diff_feather_points); } else { tot_diff_feather_points = 0; @@ -287,101 +637,220 @@ 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); + 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, - tot_diff_point, aa_filter_size, TRUE); + maskrasterize_spline_differentiate_point_outset(diff_feather_points, diff_points, + tot_diff_point, pixel_size, TRUE); } } - 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_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; + 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 dont 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); + +#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; } - 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++; + } + + tot_feather_quads += tot_diff_point; + } + } + else { + /* unfilled spline */ + if (diff_feather_points) { + + float co_diff[3]; + + float co_feather[3]; + co_feather[2] = 1.0f; + + open_spline_ranges[open_spline_index].vertex_offset = sf_vert_tot; + open_spline_ranges[open_spline_index].vertex_total = tot_diff_point; + + /* 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; + } + + if (!is_cyclic) { + tot_feather_quads -= 2; + } + + /* 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; + + 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) + + { + 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); + + 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; + } + + fp_cent = diff_points[tot_diff_point - 1]; + fp_turn = diff_feather_points[tot_diff_point - 1]; + + { + 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); + + 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; + } + } + + open_spline_ranges[open_spline_index].is_cyclic = is_cyclic; + open_spline_index++; + +#undef CALC_CAP_RESOL + /* end capping */ + + } } } if (diff_points) { MEM_freeN(diff_points); } + + if (diff_feather_points) { + MEM_freeN(diff_feather_points); + } } - 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; - - BVHTree *bvhtree; - float bvhcos[4][3]; + int face_index; /* 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); - /* 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); } @@ -392,78 +861,210 @@ void BLI_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); - 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"); + face_index = 0; - /* */ - 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++) { - *(tri++) = sf_tri->v1->tmp.u; - *(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); + /* 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; + *(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, - * '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; + face_index++; + FACE_ASSERT(face - 4, sf_vert_tot); - 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)]); - - BLI_bvhtree_insert(bvhtree, tri_index++, (const float *)bvhcos, 4); +#ifdef USE_SCANFILL_EDGE_WORKAROUND + tot_boundary_found++; +#endif } } } - fprintf(stderr, "%d %d\n", tri_index, sf_tri_tot + tot_feather_quads); +#ifdef USE_SCANFILL_EDGE_WORKAROUND + if (tot_boundary_found != tot_boundary_used) { + BLI_assert(tot_boundary_found < tot_boundary_used); + } +#endif - BLI_assert(tri_index == sf_tri_tot + tot_feather_quads); + /* feather only splines */ + while (open_spline_index > 0) { + 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; - BLI_bvhtree_balance(bvhtree); + j = vertex_offset; - { - MaskRasterLayer *raslayer = &mr_handle->layers[masklay_index]; + /* subtract one since we reference next vertex triple */ + for (k = 0; k < vertex_total - 1; k++, j += 3) { - raslayer->tri_coords = tri_coords; - raslayer->tri_array = tri_array; - raslayer->bounds = bounds; - raslayer->bvhtree = bvhtree; + BLI_assert(j == vertex_offset + (k * 3)); - /* copy as-is */ - raslayer->alpha = masklay->alpha; - raslayer->blend = masklay->blend; - raslayer->blend_flag = masklay->blend_flag; + *(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_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) { + *(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++) = 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 = vertex_offset; + + /*************** + * cap end 'a' */ + j = midvidx + (vertex_total * 3); + + 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 */ + *(face++) = j + 1; /* z 0 */ + face_index++; + FACE_ASSERT(face - 4, sf_vert_tot); + } + + j = vertex_offset + (vertex_total * 3); + + /* 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_index++; + FACE_ASSERT(face - 4, sf_vert_tot); + + *(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); - BLI_union_rctf(&mr_handle->bounds, &bounds); + /*************** + * cap end 'b' */ + /* ... same as previous but v 2-3 flipped, and different initial offsets */ + + j = vertex_offset + (vertex_total * 3) + (vertex_total_cap_head - 1); + + midvidx = vertex_offset + (vertex_total * 3) - 3; + + for (k = 0; k < vertex_total_cap_tail - 2; k++, j++) { + *(face++) = midvidx; /* z 1 */ + *(face++) = midvidx; /* z 1 */ + *(face++) = j + 1; /* z 0 */ + *(face++) = j + 0; /* z 0 */ + face_index++; + FACE_ASSERT(face - 4, sf_vert_tot); + } + + j = vertex_offset + (vertex_total * 3) + (vertex_total_cap_head - 1); + + /* 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_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 + vertex_total_cap_tail - 2; /* z 0 */ + face_index++; + FACE_ASSERT(face - 4, sf_vert_tot); + + } } - PRINT_MASK_DEBUG("tris %d, feather tris %d\n", sf_tri_tot, tot_feather_quads); + MEM_freeN(open_spline_ranges); + +// 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)) { +#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; + + layer_bucket_init(layer, pixel_size); + + BLI_rctf_union(&mr_handle->bounds, &bounds); + } + else { + MEM_freeN(face_coords); + MEM_freeN(face_array); + + layer_bucket_init_dummy(layer); + } + + /* copy as-is */ + 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); */ } /* add trianges */ @@ -471,12 +1072,13 @@ void BLI_maskrasterize_handle_init(MaskRasterHandle *mr_handle, struct Mask *mas } } -//static void tri_flip_tri(unsigned int tri[3]) -//{ -//} +/* --------------------------------------------------------------------- */ +/* functions that run inside the sampling thread (keep fast!) */ +/* --------------------------------------------------------------------- */ /* 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]) { @@ -484,47 +1086,44 @@ 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 w[2] + w[3]; /* we can make this assumption for small speedup */ } #endif -static void maskrasterize_layer_bvh_cb(void *userdata, int index, const BVHTreeRay *ray, BVHTreeRayHit *hit) +static float maskrasterize_layer_isect(unsigned int *face, 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) { + if (face[3] == TRI_VERT) { /* --- tri --- */ +#if 0 /* not essential but avoids unneeded extra lookups */ if ((cos[0][2] < dist_orig) || (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_cw(xy, cos[face[0]], cos[face[1]], cos[face[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; - } -#else - hit->index = index; - hit->dist = 0.0f; -#endif + 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_cw(xy, cos[face[0]], cos[face[1]], cos[face[2]])) { + return 0.0f; + } + } +#endif } else { /* --- quad --- */ @@ -537,28 +1136,22 @@ 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 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 - 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; - } + /* 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]]); } - 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[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 */ @@ -566,73 +1159,131 @@ static void maskrasterize_layer_bvh_cb(void *userdata, int index, const BVHTreeR #endif } } + + return 1.0f; } -float BLI_maskrasterize_handle_sample(MaskRasterHandle *mr_handle, const float xy[2]) +BLI_INLINE unsigned int layer_bucket_index_from_xy(MaskRasterLayer *layer, const float xy[2]) { - /* TODO - AA jitter */ + BLI_assert(BLI_in_rctf_v(&layer->bounds, xy)); - 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; + 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); +} - /* 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}; +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 *face_index = layer->buckets_face[index]; - /* return */ - float value = 0.0f; - - for (i = 0; i < layers_tot; i++, layer++) { - - if (BLI_in_rctf_v(&layer->bounds, xy)) { - - hit.dist = FLT_MAX; - hit.index = -1; - - /* 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); - - /* --- 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; - } - } + if (face_index) { + unsigned int (*face_array)[4] = layer->face_array; + float (*cos)[3] = layer->face_coords; + float best_dist = 1.0f; + 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 */ + return 0.0f; } - /* --- hit (end) --- */ - } + face_index++; } - - return CLAMPIS(value, 0.0f, 1.0f); + return best_dist; } else { - return 0.0f; + return 1.0f; } } +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)) */ + + const unsigned int layers_tot = mr_handle->layers_tot; + unsigned int i; + MaskRasterLayer *layer = mr_handle->layers; + + /* return value */ + float value = 0.0f; + + 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 && BLI_in_rctf_v(&layer->bounds, 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 */ + value_layer = (3.0f * value_layer * value_layer - 2.0f * value_layer * value_layer * value_layer); + break; + case PROP_SPHERE: + value_layer = sqrtf(2.0f * value_layer - value_layer * value_layer); + break; + case PROP_ROOT: + value_layer = sqrtf(value_layer); + break; + case PROP_SHARP: + value_layer = value_layer * value_layer; + break; + case PROP_LIN: + default: + /* nothing */ + break; + } + + if (layer->blend != MASK_BLEND_REPLACE) { + value_layer *= layer->alpha; + } + } + else { + value_layer = 0.0f; + } + + if (layer->blend_flag & MASK_BLENDFLAG_INVERT) { + value_layer = 1.0f - value_layer; + } + + switch (layer->blend) { + case MASK_BLEND_ADD: + 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; + case MASK_BLEND_DIFFERENCE: + value = fabsf(value - value_layer); + break; + default: /* same as add */ + BLI_assert(0); + value += value_layer; + break; + } + + /* clamp after applying each layer so we don't get + * issues subtracting after accumulating over 1.0f */ + CLAMP(value, 0.0f, 1.0f); + } + + return value; +} + #endif /* USE_RASKTER */ 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/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/blenkernel/intern/multires.c b/source/blender/blenkernel/intern/multires.c index 2bc5c37b41b..866194eea0e 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; @@ -1064,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++) { @@ -2069,6 +2075,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,31 +2102,25 @@ 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 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); + 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; } -/* 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/object.c b/source/blender/blenkernel/intern/object.c index f471ffef0f6..2692e2a2929 100644 --- a/source/blender/blenkernel/intern/object.c +++ b/source/blender/blenkernel/intern/object.c @@ -3166,7 +3166,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; @@ -3245,3 +3245,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/blenkernel/intern/particle_system.c b/source/blender/blenkernel/intern/particle_system.c index aa798f59482..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; @@ -2441,7 +2443,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,13 +2736,17 @@ 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; } - 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; @@ -2747,8 +2754,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 +2769,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 +3757,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 +4139,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 a3fa8f8be89..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) @@ -2320,7 +2319,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..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 @@ -2914,7 +2913,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 +3296,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 +3810,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/BLI_math_geom.h b/source/blender/blenlib/BLI_math_geom.h index 50345237a9f..107b688b36a 100644 --- a/source/blender/blenlib/BLI_math_geom.h +++ b/source/blender/blenlib/BLI_math_geom.h @@ -55,11 +55,13 @@ 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 **********************************/ 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]); @@ -85,11 +87,13 @@ 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]); 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 @@ -151,6 +155,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]); @@ -187,7 +192,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/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..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 @@ -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__ */ 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/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/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/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/blenlib/intern/math_geom.c b/source/blender/blenlib/intern/math_geom.c index f9acb6ae1dd..f2ea93282c9 100644 --- a/source/blender/blenlib/intern/math_geom.c +++ b/source/blender/blenlib/intern/math_geom.c @@ -162,52 +162,57 @@ 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_squared_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]; - return sqrtf(rc[0] * rc[0] + rc[1] * rc[1]); + rc[0] = pt[0] - p[0]; + rc[1] = pt[1] - p[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 */ @@ -312,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]) { @@ -332,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]) @@ -390,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; } @@ -406,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]) @@ -532,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, @@ -586,6 +615,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) { @@ -1626,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 @@ -1943,34 +1986,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]; @@ -2114,7 +2167,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; @@ -2126,14 +2179,37 @@ 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]) { + /* 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; @@ -2144,17 +2220,47 @@ 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]) +{ + /* 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; + + 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) */ @@ -2737,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]; @@ -3278,3 +3384,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/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/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/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/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/blenlib/intern/rct.c b/source/blender/blenlib/intern/rct.c index c1ef3e27291..658d45ad171 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)); @@ -108,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; @@ -143,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; @@ -151,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; @@ -227,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; @@ -243,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; @@ -253,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; @@ -263,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; @@ -293,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; @@ -323,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/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 53b9f8064c4..29e3f418dd3 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -256,7 +256,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, ...) { @@ -5933,7 +5933,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 @@ -5962,7 +5962,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) { @@ -8394,7 +8394,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..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 */ @@ -880,7 +885,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_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/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 f47781241e8..916ae6ac785 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/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/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/intern/COM_WorkScheduler.cpp b/source/blender/compositor/intern/COM_WorkScheduler.cpp
index b10e99697e4..7d4134aca13 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
 
 
@@ -92,7 +95,9 @@ void ** g_highlightedNodesRead;
 		} \
 	} \
 }
-void COM_startReadHighlights() {
+
+void COM_startReadHighlights()
+{
 	if (g_highlightedNodesRead) {
 		delete [] g_highlightedNodesRead;
 	}
@@ -105,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/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_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_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/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/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/compositor/operations/COM_MaskOperation.cpp b/source/blender/compositor/operations/COM_MaskOperation.cpp
index d2a4854efee..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,21 +139,18 @@ 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();
 			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,17 +158,9 @@ 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;
 	}
-
-	deinitMutex();
-}
-
-void *MaskOperation::initializeTileData(rcti *rect)
-{
-	/* pass */
-	return NULL;
 }
 
 void MaskOperation::determineResolution(unsigned int resolution[], unsigned int preferredResolution[])
@@ -193,11 +181,11 @@ 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) {
-		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;
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
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()
diff --git a/source/blender/editors/animation/anim_channels_defines.c b/source/blender/editors/animation/anim_channels_defines.c
index 6331dd51527..e890b8f2aba 100644
--- a/source/blender/editors/animation/anim_channels_defines.c
+++ b/source/blender/editors/animation/anim_channels_defines.c
@@ -852,7 +852,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;
 	}
@@ -940,7 +940,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 */
@@ -2585,11 +2585,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 */
@@ -2619,7 +2619,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;
 	}
@@ -2630,15 +2630,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;
 }
@@ -2647,7 +2647,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);
 }
@@ -2656,16 +2656,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 */
@@ -2677,7 +2677,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);
 }
@@ -2688,7 +2688,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);
 	}
 
@@ -2703,7 +2703,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;
@@ -2715,18 +2715,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;
 	}
@@ -2780,17 +2780,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 */
@@ -2806,15 +2806,15 @@ static void ANIM_init_channel_typeinfo_data(void)
 		animchannelTypeInfo[type++] = &ACF_DSLAT;        /* Lattice Channel */
 		animchannelTypeInfo[type++] = &ACF_DSSPK;        /* Speaker Channel */
 		animchannelTypeInfo[type++] = &ACF_DSLINESTYLE;  /* LineStyle 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 81b6d77dd82..035641b2888 100644
--- a/source/blender/editors/animation/anim_filter.c
+++ b/source/blender/editors/animation/anim_filter.c
@@ -418,16 +418,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
@@ -1330,6 +1330,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;
@@ -1396,6 +1397,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);
@@ -1412,18 +1414,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 ++;
-//						}
-//					}
-
 				}
 //			}
 		}
@@ -1432,28 +1422,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 */
@@ -1461,14 +1452,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;
 }
@@ -2453,7 +2444,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 */
@@ -2468,14 +2459,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 */
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_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/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/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);
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/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/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/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/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/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/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/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/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_anim.c b/source/blender/editors/interface/interface_anim.c
index 3099fcb2b40..28d18f6a3dd 100644
--- a/source/blender/editors/interface/interface_anim.c
+++ b/source/blender/editors/interface/interface_anim.c
@@ -212,7 +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_add_driver(bContext *C)
+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 */
 	WM_operator_name_call(C, "ANIM_OT_driver_button_add", WM_OP_INVOKE_DEFAULT, NULL);
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/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c
index 613ab2fa6c8..2a93ab794af 100644
--- a/source/blender/editors/interface/interface_handlers.c
+++ b/source/blender/editors/interface/interface_handlers.c
@@ -256,13 +256,42 @@ 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 (ELEM6(but->type, NUM, NUMABS, HSVCIRCLE, TRACKPREVIEW, HSVCUBE, BUT_CURVE)) {
 			return TRUE;
+		}
+	}
 
 	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)
 {
@@ -2636,7 +2665,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,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, int mx, int my)
+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;
@@ -3108,9 +3140,10 @@ static int ui_numedit_but_HSVCUBE(uiBut *but, uiHandleButtonData *data, int mx,
 
 	rgb_to_hsv_compat_v(rgb, hsv);
 
+
 	/* 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);
 
@@ -3161,7 +3194,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 +3268,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 +3325,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,13 +3338,16 @@ 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;
+	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;
 	
@@ -3325,14 +3361,8 @@ static int ui_numedit_but_HSVCIRCLE(uiBut *but, uiHandleButtonData *data, int mx
 		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]);
@@ -3352,7 +3382,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];
@@ -3584,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;
@@ -3608,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;
@@ -3774,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);
 			}
 		}
@@ -4182,7 +4218,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;
@@ -4474,6 +4511,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 +4737,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));
 			
@@ -5937,14 +5994,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;
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);
diff --git a/source/blender/editors/interface/interface_templates.c b/source/blender/editors/interface/interface_templates.c
index cbc76137ae1..5d62b010555 100644
--- a/source/blender/editors/interface/interface_templates.c
+++ b/source/blender/editors/interface/interface_templates.c
@@ -2243,13 +2243,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);
 		uiItemR(row, itemptr, "hide", 0, "", 0);
 		uiItemR(row, itemptr, "hide_select", 0, "", 0);
 		uiItemR(row, itemptr, "hide_render", 0, "", 0);
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/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/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);
 						}
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/editors/mesh/editmesh_select.c b/source/blender/editors/mesh/editmesh_select.c
index cb8b2c076e2..d9f09c0bc65 100644
--- a/source/blender/editors/mesh/editmesh_select.c
+++ b/source/blender/editors/mesh/editmesh_select.c
@@ -1692,15 +1692,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)) {
@@ -1711,7 +1711,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;
 
@@ -1728,9 +1728,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_tools.c b/source/blender/editors/mesh/editmesh_tools.c
index 1432985d290..622e34a1366 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"
@@ -2789,120 +2790,158 @@ 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_tagged(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);   /* 0 = fully linked */
-	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_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, em->bm, BM_EDGES_OF_MESH) {
-		if (BM_elem_flag_test(e, BM_ELEM_HIDDEN))
-			continue;
-
+	BM_ITER_MESH (e, &iter, bm_old, BM_EDGES_OF_MESH) {
 		if (!BM_edge_is_wire(e)) {
-			BM_edge_select_set(em->bm, e, FALSE);
+			BM_elem_flag_disable(e, BM_ELEM_TAG);
 		}
 	}
-	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_TAG, DEL_EDGES);
 
 	/* clean up any loose verts */
-	BM_ITER_MESH (v, &iter, em->bm, BM_VERTS_OF_MESH) {
-		if (BM_elem_flag_test(v, BM_ELEM_HIDDEN))
-			continue;
-
+	BM_ITER_MESH (v, &iter, bm_old, BM_VERTS_OF_MESH) {
 		if (BM_vert_edge_count(v) != 0) {
-			BM_vert_select_set(em->bm, v, FALSE);
+			BM_elem_flag_disable(v, BM_ELEM_TAG);
 		}
 	}
 
-	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_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);
 
-	BM_mesh_bm_to_me(bm_new, basenew->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_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;
-	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_TAG, 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);
+				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++;
 			}
 		}
 
 		/* 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_tagged(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_TAG, FALSE);
 
 	/* A "while (true)" loop should work here as each iteration should
 	 * select and remove at least one vertex and when all vertices
@@ -2910,8 +2949,9 @@ static int mesh_separate_loose(Main *bmain, Scene *scene, Base *editbase, wmOper
 	 * 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, 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) {
@@ -2919,33 +2959,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_elem_flag_enable(v_seed, BM_ELEM_TAG);
 
 		/* 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);
+			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 */
-		EDBM_selectmode_flush_ex(em, SCE_SELECT_VERTEX);
 
-		if (bm->totvert == bm->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, editbase, wmop);
+		result |= mesh_separate_tagged(bmain, scene, base_old, bm_old);
 	}
 
 	return result;
@@ -2955,19 +2995,65 @@ 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 (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) {
-		BMEditMesh *em = BMEdit_FromObject(base->object);
-		EDBM_update_generic(C, em, TRUE);
+		/* delay depsgraph recalc until all objects are duplicated */
+		DAG_scene_sort(bmain, scene);
 
 		return OPERATOR_FINISHED;
 	}
@@ -2994,7 +3080,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;
@@ -4305,23 +4391,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 +4478,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 +4621,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 +4643,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 +4719,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 +4764,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 +4811,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 +4950,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 +4971,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 +5018,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 +5043,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);
@@ -5010,7 +5186,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,
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/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/editors/object/object_group.c b/source/blender/editors/object/object_group.c
index c9851c6a0db..53bfddee740 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"
@@ -59,57 +60,114 @@
 
 /********************* 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");
-	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;
+
+	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 is_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 {
+					is_cycle = TRUE;
+				}
+			}
+			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);
+
+			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)
@@ -164,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;
 
@@ -202,17 +257,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 spesific */
 	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 +279,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 +298,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;
 }
 
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/editors/object/object_relations.c b/source/blender/editors/object/object_relations.c
index d7c882ba51e..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"
@@ -518,7 +520,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 +644,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 +677,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 +732,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 +770,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 ******************* */
@@ -1246,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;
@@ -1266,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:
@@ -1279,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;
 				}
 			}
@@ -1332,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));
@@ -1369,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}};
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/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..2391d6c909e 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 */
@@ -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_image.c b/source/blender/editors/sculpt_paint/paint_image.c
index 5e46a28a3b7..073e60ca87c 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])
@@ -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/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/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..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);
@@ -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);
@@ -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;
 	}
 	
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);
 }
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/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/editors/space_node/drawnode.c b/source/blender/editors/space_node/drawnode.c
index c4b9d5989e1..134b2d6fd99 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 
@@ -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 */
@@ -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/editors/space_node/node_draw.c b/source/blender/editors/space_node/node_draw.c
index adf52313307..8c9f057efc1 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 
@@ -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/editors/space_node/node_edit.c b/source/blender/editors/space_node/node_edit.c
index c4e72fa4a51..a0df2aefab1 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;
@@ -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);
 	
@@ -2547,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);
@@ -3140,6 +3144,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;
 
@@ -3170,8 +3175,13 @@ 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) {
+					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);
 				link->fromnode = rerouteNode;
@@ -3984,9 +3994,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;
 }
 
@@ -4047,7 +4057,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;
 }
@@ -4098,7 +4108,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;
 }
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_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);
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 919772bbf46..ad6df39869a 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;
 				}
 			}
@@ -2859,7 +2859,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);
@@ -2870,7 +2870,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/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/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/editors/transform/transform.c b/source/blender/editors/transform/transform.c
index 956c3a16277..b1358c9f275 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 
@@ -174,8 +169,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) {
+				divy = divx;
+				muly = mulx;
+			}
+			else {
+				divx = divy;
+				mulx = muly;
+			}
 		}
 
 		r_vec[0] = mulx * (dx) / divx;
@@ -2455,7 +2456,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 +2585,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 +2671,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 +2688,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 +3048,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 +3394,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 +3493,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 +3578,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 +3598,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 +3632,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 +3804,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 +3873,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 +3945,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 +4013,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 +4079,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 +4215,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 +4282,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 +4355,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 +4415,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 +4430,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 +4548,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);
@@ -4695,7 +4707,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) {
@@ -4883,7 +4895,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;
@@ -4891,14 +4903,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;
@@ -4907,10 +4920,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-drawn! 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) {
@@ -5428,7 +5443,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 +5509,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 +5581,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 +5774,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 +6017,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 +6172,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 +6314,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/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/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);
 			}
 	}
 }
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_mask_types.h b/source/blender/makesdna/DNA_mask_types.h
index 52fedd72e86..60bc3ee0ffc 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  */
@@ -137,7 +139,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
@@ -162,8 +167,13 @@ enum {
 
 /* masklay->blend */
 enum {
-	MASK_BLEND_ADD      = 0,
-	MASK_BLEND_SUBTRACT = 1
+	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/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/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_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", ""},
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);
diff --git a/source/blender/makesrna/intern/rna_mask.c b/source/blender/makesrna/intern/rna_mask.c
index b879d2b19f7..2987057aeb6 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"
 
@@ -565,7 +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, NC_MASK | NA_EDITED, "rna_Mask_update_data");
 }
 
 static void rna_def_mask_layer(BlenderRNA *brna)
@@ -573,6 +581,11 @@ 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", ""},
+		{MASK_BLEND_DIFFERENCE, "DIFFERENCE", 0, "Difference", ""},
 		{0, NULL, 0, NULL, NULL}
 	};
 
@@ -629,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);
 
@@ -646,6 +659,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)
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");
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)
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 */
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/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/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_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))
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;
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/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/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..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)
 {
@@ -287,7 +290,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;
@@ -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);
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..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;
@@ -229,7 +244,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/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, ...);
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/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;
 
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 2dcd0f7c70a..50b7e526cac 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 
@@ -3419,7 +3418,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;
@@ -5555,7 +5554,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/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/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/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/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/CMakeLists.txt b/source/blender/windowmanager/CMakeLists.txt
index a1dd999a921..7f7321f6f29 100644
--- a/source/blender/windowmanager/CMakeLists.txt
+++ b/source/blender/windowmanager/CMakeLists.txt
@@ -144,4 +144,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/SConscript b/source/blender/windowmanager/SConscript
index 65026460740..5819ae2545a 100644
--- a/source/blender/windowmanager/SConscript
+++ b/source/blender/windowmanager/SConscript
@@ -44,4 +44,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] )
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..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);
@@ -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;
diff --git a/source/blender/windowmanager/intern/wm_init_exit.c b/source/blender/windowmanager/intern/wm_init_exit.c
index 3dbb3b7ef66..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"
@@ -199,6 +197,14 @@ void WM_init(bContext *C, int argc, const char **argv)
 #endif
 
 	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)
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;
diff --git a/source/creator/CMakeLists.txt b/source/creator/CMakeLists.txt
index 3b75d7a75a0..245f71ce1ea 100644
--- a/source/creator/CMakeLists.txt
+++ b/source/creator/CMakeLists.txt
@@ -911,10 +911,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)
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_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
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/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. */
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;
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/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);
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