diff options
author | Campbell Barton <ideasman42@gmail.com> | 2017-09-29 12:55:00 +0300 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2017-09-29 12:55:00 +0300 |
commit | e3fe8128e41bb7c576f02ba234dfabf5c399cb60 (patch) | |
tree | cd148a38fb32cdb1a36fc576b9f36fe864003e40 /source/blender | |
parent | 31be6fccf83095f4245f97730ccc7e61e51cfcec (diff) | |
parent | 5a1954a5cbd7b0b1458fdc80ada5acd036278309 (diff) |
Merge branch 'master' into blender2.8
Diffstat (limited to 'source/blender')
25 files changed, 674 insertions, 108 deletions
diff --git a/source/blender/blenkernel/BKE_paint.h b/source/blender/blenkernel/BKE_paint.h index cf4542e4824..f865a6a7cdd 100644 --- a/source/blender/blenkernel/BKE_paint.h +++ b/source/blender/blenkernel/BKE_paint.h @@ -222,6 +222,7 @@ typedef struct SculptSession { /* For non-airbrush painting to re-apply from the original (MLoop aligned). */ unsigned int *previous_color; + unsigned int *previous_accum; } vpaint; struct { diff --git a/source/blender/blenkernel/intern/cdderivedmesh.c b/source/blender/blenkernel/intern/cdderivedmesh.c index 4b7196165f4..dd43bf8b9d8 100644 --- a/source/blender/blenkernel/intern/cdderivedmesh.c +++ b/source/blender/blenkernel/intern/cdderivedmesh.c @@ -641,8 +641,18 @@ static void cdDM_drawMappedFaces( /* avoid buffer problems in following code */ } else if (setDrawOptions == NULL) { + const bool show_alpha = true; + if (show_alpha) { + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + } + /* just draw the entire face array */ GPU_buffer_draw_elements(dm->drawObject->triangles, GL_TRIANGLES, 0, tot_tri_elem); + + if (show_alpha) { + glDisable(GL_BLEND); + } } else { for (mat_index = 0; mat_index < dm->drawObject->totmaterial; mat_index++) { @@ -1405,8 +1415,8 @@ static void cdDM_buffer_copy_mcol( for (i = 0; i < totpoly; i++, mpoly++) { for (j = 0; j < mpoly->totloop; j++) { - copy_v3_v3_uchar(&varray[start], &mloopcol[mpoly->loopstart + j].r); - start += 3; + copy_v4_v4_uchar(&varray[start], &mloopcol[mpoly->loopstart + j].r); + start += 4; } } } diff --git a/source/blender/blenkernel/intern/paint.c b/source/blender/blenkernel/intern/paint.c index db13c23aa5f..e7ccb819b36 100644 --- a/source/blender/blenkernel/intern/paint.c +++ b/source/blender/blenkernel/intern/paint.c @@ -469,7 +469,7 @@ bool BKE_paint_select_vert_test(Object *ob) (ob->type == OB_MESH) && (ob->data != NULL) && (((Mesh *)ob->data)->editflag & ME_EDIT_PAINT_VERT_SEL) && - (ob->mode & OB_MODE_WEIGHT_PAINT) + (ob->mode & OB_MODE_WEIGHT_PAINT || ob->mode & OB_MODE_VERTEX_PAINT) ); } @@ -683,6 +683,7 @@ void BKE_sculptsession_free_vwpaint_data(struct SculptSession *ss) gmap = &ss->mode.vpaint.gmap; MEM_SAFE_FREE(ss->mode.vpaint.previous_color); + MEM_SAFE_FREE(ss->mode.vpaint.previous_accum); } else if (ss->mode_type == OB_MODE_WEIGHT_PAINT) { gmap = &ss->mode.wpaint.gmap; @@ -740,7 +741,10 @@ void BKE_sculptsession_bm_to_me_for_render(Object *object) */ BKE_object_free_derived_caches(object); - MEM_SAFE_FREE(object->sculpt->pbvh); + if (object->sculpt->pbvh) { + BKE_pbvh_free(object->sculpt->pbvh); + object->sculpt->pbvh = NULL; + } sculptsession_bm_to_me_update_data_only(object, false); diff --git a/source/blender/blenlib/BLI_fnmatch.h b/source/blender/blenlib/BLI_fnmatch.h index f69f5b39869..06fa5048622 100644 --- a/source/blender/blenlib/BLI_fnmatch.h +++ b/source/blender/blenlib/BLI_fnmatch.h @@ -28,7 +28,7 @@ extern "C" { #endif -#if defined WIN32 && !defined _LIBC || defined __sun +#if defined WIN32 && !defined _LIBC #if defined(__cplusplus) || (defined(__STDC__) && __STDC__) #undef __P @@ -53,7 +53,7 @@ extern "C" { #define FNM_NOESCAPE (1 << 1) /* Backslashes don't quote special chars. */ #define FNM_PERIOD (1 << 2) /* Leading `.' is matched only explicitly. */ -#if !defined(_POSIX_C_SOURCE) || _POSIX_C_SOURCE < 2 || defined(_GNU_SOURCE) || defined(__SUNPRO_C) +#if !defined(_POSIX_C_SOURCE) || _POSIX_C_SOURCE < 2 || defined(_GNU_SOURCE) #define FNM_FILE_NAME FNM_PATHNAME /* Preferred GNU name. */ #define FNM_LEADING_DIR (1 << 3) /* Ignore `/...' after a match. */ #define FNM_CASEFOLD (1 << 4) /* Compare without regard to case. */ @@ -72,7 +72,7 @@ extern int fnmatch __P((const char *__pattern, const char *__string, # define _GNU_SOURCE # endif # include <fnmatch.h> -#endif /* defined WIN32 && !defined _LIBC || defined __sun */ +#endif /* defined WIN32 && !defined _LIBC */ #ifdef __cplusplus } diff --git a/source/blender/blenlib/intern/storage.c b/source/blender/blenlib/intern/storage.c index b819c513fbd..a48c8b074dd 100644 --- a/source/blender/blenlib/intern/storage.c +++ b/source/blender/blenlib/intern/storage.c @@ -37,14 +37,10 @@ #include <sys/stat.h> -#if defined(__NetBSD__) || defined(__DragonFly__) || defined(__sun__) || defined(__sun) +#if defined(__NetBSD__) || defined(__DragonFly__) /* Other modern unix os's should probably use this also */ # include <sys/statvfs.h> # define USE_STATFS_STATVFS -#elif (defined(__sparc) || defined(__sparc__)) && !defined(__FreeBSD__) && !defined(__linux__) -# include <sys/statfs.h> - /* 4 argument version (not common) */ -# define USE_STATFS_4ARGS #endif #if defined(__APPLE__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) || defined(__DragonFly__) diff --git a/source/blender/blenloader/intern/versioning_270.c b/source/blender/blenloader/intern/versioning_270.c index 8c414c31b81..afbd84bdb91 100644 --- a/source/blender/blenloader/intern/versioning_270.c +++ b/source/blender/blenloader/intern/versioning_270.c @@ -1653,6 +1653,23 @@ void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *main) } } + { + Brush *br; + br = (Brush *)BKE_libblock_find_name_ex(main, ID_BR, "Average"); + if (!br) { + br = BKE_brush_add(main, "Average", OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT); + br->vertexpaint_tool = PAINT_BLEND_AVERAGE; + br->ob_mode = OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT; + } + + br = (Brush *)BKE_libblock_find_name_ex(main, ID_BR, "Smear"); + if (!br) { + br = BKE_brush_add(main, "Smear", OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT); + br->vertexpaint_tool = PAINT_BLEND_SMEAR; + br->ob_mode = OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT; + } + } + FOREACH_NODETREE(main, ntree, id) { if (ntree->type == NTREE_COMPOSIT) { do_versions_compositor_render_passes(ntree); diff --git a/source/blender/bmesh/intern/bmesh_mesh_validate.c b/source/blender/bmesh/intern/bmesh_mesh_validate.c index 7c9ebc800a3..3a6a3543bc8 100644 --- a/source/blender/bmesh/intern/bmesh_mesh_validate.c +++ b/source/blender/bmesh/intern/bmesh_mesh_validate.c @@ -41,7 +41,7 @@ /* macro which inserts the function name */ -#if defined __GNUC__ || defined __sun +#if defined __GNUC__ # define ERRMSG(format, args...) { fprintf(stderr, "%s: " format ", " AT "\n", __func__, ##args); errtot++; } (void)0 #else # define ERRMSG(format, ...) { fprintf(stderr, "%s: " format ", " AT "\n", __func__, __VA_ARGS__); errtot++; } (void)0 diff --git a/source/blender/collada/GeometryExporter.cpp b/source/blender/collada/GeometryExporter.cpp index 27ff6b5f2b5..587f30b6eb8 100644 --- a/source/blender/collada/GeometryExporter.cpp +++ b/source/blender/collada/GeometryExporter.cpp @@ -480,12 +480,13 @@ void GeometryExporter::createVertexColorSource(std::string geom_id, Mesh *me) source.setArrayId(layer_id + ARRAY_ID_SUFFIX); source.setAccessorCount(me->totloop); - source.setAccessorStride(3); + source.setAccessorStride(4); COLLADASW::SourceBase::ParameterNameList ¶m = source.getParameterNameList(); param.push_back("R"); param.push_back("G"); param.push_back("B"); + param.push_back("A"); source.prepareToAppendValues(); @@ -495,9 +496,10 @@ void GeometryExporter::createVertexColorSource(std::string geom_id, Mesh *me) MLoopCol *mlc = mloopcol + mpoly->loopstart; for (int j = 0; j < mpoly->totloop; j++, mlc++) { source.appendValues( - mlc->r / 255.0f, - mlc->g / 255.0f, - mlc->b / 255.0f + mlc->r / 255.0f, + mlc->g / 255.0f, + mlc->b / 255.0f, + mlc->a / 255.0f ); } } diff --git a/source/blender/editors/include/ED_mesh.h b/source/blender/editors/include/ED_mesh.h index 52edfc22d21..1703ec6194f 100644 --- a/source/blender/editors/include/ED_mesh.h +++ b/source/blender/editors/include/ED_mesh.h @@ -283,6 +283,7 @@ bool ED_mesh_uv_texture_remove_active(struct Mesh *me); bool ED_mesh_uv_texture_remove_named(struct Mesh *me, const char *name); void ED_mesh_uv_loop_reset(struct bContext *C, struct Mesh *me); void ED_mesh_uv_loop_reset_ex(struct Mesh *me, const int layernum); +bool ED_mesh_color_ensure(struct Mesh *me, const char *name); int ED_mesh_color_add(struct Mesh *me, const char *name, const bool active_set); bool ED_mesh_color_remove_index(struct Mesh *me, const int n); bool ED_mesh_color_remove_active(struct Mesh *me); diff --git a/source/blender/editors/mesh/mesh_data.c b/source/blender/editors/mesh/mesh_data.c index 2767ce75a5f..f2e60c55574 100644 --- a/source/blender/editors/mesh/mesh_data.c +++ b/source/blender/editors/mesh/mesh_data.c @@ -440,6 +440,20 @@ int ED_mesh_color_add(Mesh *me, const char *name, const bool active_set) return layernum; } +bool ED_mesh_color_ensure(struct Mesh *me, const char *name) +{ + BLI_assert(me->edit_btmesh == NULL); + + if (!me->mloopcol && me->totloop) { + CustomData_add_layer_named(&me->ldata, CD_MLOOPCOL, CD_DEFAULT, NULL, me->totloop, name); + BKE_mesh_update_customdata_pointers(me, true); + } + + DEG_id_tag_update(&me->id, 0); + + return (me->mloopcol != NULL); +} + bool ED_mesh_color_remove_index(Mesh *me, const int n) { CustomData *ldata = GET_CD_DATA(me, ldata); diff --git a/source/blender/editors/sculpt_paint/CMakeLists.txt b/source/blender/editors/sculpt_paint/CMakeLists.txt index ead420b1faa..bb9ebea6b22 100644 --- a/source/blender/editors/sculpt_paint/CMakeLists.txt +++ b/source/blender/editors/sculpt_paint/CMakeLists.txt @@ -53,6 +53,7 @@ set(SRC paint_undo.c paint_utils.c paint_vertex.c + paint_vertex_color_ops.c paint_vertex_proj.c sculpt.c sculpt_undo.c diff --git a/source/blender/editors/sculpt_paint/paint_intern.h b/source/blender/editors/sculpt_paint/paint_intern.h index 2b866118f19..48f8e789ec3 100644 --- a/source/blender/editors/sculpt_paint/paint_intern.h +++ b/source/blender/editors/sculpt_paint/paint_intern.h @@ -123,6 +123,8 @@ void PAINT_OT_vertex_paint(struct wmOperatorType *ot); unsigned int vpaint_get_current_col(struct Scene *scene, struct VPaint *vp); +/* paint_vertex_color_ops.c */ +void PAINT_OT_vertex_color_from_weight(struct wmOperatorType *ot); /* paint_vertex_proj.c */ struct VertProjHandle; diff --git a/source/blender/editors/sculpt_paint/paint_ops.c b/source/blender/editors/sculpt_paint/paint_ops.c index 4ebf14ed0b9..23231b7ccc7 100644 --- a/source/blender/editors/sculpt_paint/paint_ops.c +++ b/source/blender/editors/sculpt_paint/paint_ops.c @@ -1349,6 +1349,7 @@ void ED_operatortypes_paint(void) WM_operatortype_append(PAINT_OT_vertex_color_hsv); WM_operatortype_append(PAINT_OT_vertex_color_invert); WM_operatortype_append(PAINT_OT_vertex_color_levels); + WM_operatortype_append(PAINT_OT_vertex_color_from_weight); /* face-select */ WM_operatortype_append(PAINT_OT_face_select_linked); diff --git a/source/blender/editors/sculpt_paint/paint_vertex.c b/source/blender/editors/sculpt_paint/paint_vertex.c index 9046a768eaf..c3fb67816da 100644 --- a/source/blender/editors/sculpt_paint/paint_vertex.c +++ b/source/blender/editors/sculpt_paint/paint_vertex.c @@ -84,6 +84,8 @@ #include "sculpt_intern.h" #include "paint_intern.h" /* own include */ +#define EPS_SATURATION 0.0005f + /* Use for 'blur' brush, align with PBVH nodes, created and freed on each update. */ struct VPaintAverageAccum { uint len; @@ -257,29 +259,6 @@ static void do_shared_vertexcol(Mesh *me, bool *mlooptag) MEM_freeN(scol); } -static bool make_vertexcol(Object *ob) /* single ob */ -{ - Mesh *me; - - if (ID_IS_LINKED_DATABLOCK(ob) || - ((me = BKE_mesh_from_object(ob)) == NULL) || - (me->totpoly == 0) || - (me->edit_btmesh)) - { - return false; - } - - /* copies from shadedisplist to mcol */ - if (!me->mloopcol && me->totloop) { - CustomData_add_layer(&me->ldata, CD_MLOOPCOL, CD_DEFAULT, NULL, me->totloop); - BKE_mesh_update_customdata_pointers(me, true); - } - - DEG_id_tag_update(&me->id, 0); - - return (me->mloopcol != NULL); -} - /* mirror_vgroup is set to -1 when invalid */ static int wpaint_mirror_vgroup_ensure(Object *ob, const int vgroup_active) { @@ -343,12 +322,13 @@ bool ED_vpaint_fill(Object *ob, uint paintcol) int i, j; if (((me = BKE_mesh_from_object(ob)) == NULL) || - (me->mloopcol == NULL && (make_vertexcol(ob) == false))) + (ED_mesh_color_ensure(me, NULL) == false)) { return false; } const bool use_face_sel = (me->editflag & ME_EDIT_PAINT_FACE_SEL) != 0; + const bool use_vert_sel = (me->editflag & ME_EDIT_PAINT_VERT_SEL) != 0; mp = me->mpoly; for (i = 0; i < me->totpoly; i++, mp++) { @@ -357,9 +337,16 @@ bool ED_vpaint_fill(Object *ob, uint paintcol) if (use_face_sel && !(mp->flag & ME_FACE_SEL)) continue; - for (j = 0; j < mp->totloop; j++, lcol++) { - *(int *)lcol = paintcol; - } + j = 0; + do { + uint vidx = me->mloop[mp->loopstart + j].v; + if (!(use_vert_sel && !(me->mvert[vidx].flag & SELECT))) { + *(int *)lcol = paintcol; + } + lcol++; + j++; + } while (j < mp->totloop); + } /* remove stale me->mcol, will be added later */ @@ -466,7 +453,7 @@ bool ED_vpaint_smooth(Object *ob) bool *mlooptag; if (((me = BKE_mesh_from_object(ob)) == NULL) || - (me->mloopcol == NULL && (make_vertexcol(ob) == false))) + (ED_mesh_color_ensure(me, NULL) == false)) { return false; } @@ -513,7 +500,7 @@ bool ED_vpaint_color_transform( const MPoly *mp; if (((me = BKE_mesh_from_object(ob)) == NULL) || - (me->mloopcol == NULL && (make_vertexcol(ob) == false))) + (ED_mesh_color_ensure(me, NULL) == false)) { return false; } @@ -613,15 +600,17 @@ BLI_INLINE uint mcol_blend(uint col1, uint col2, int fac) int r1 = cp1[0] * cp1[0]; int g1 = cp1[1] * cp1[1]; int b1 = cp1[2] * cp1[2]; + int a1 = cp1[3] * cp1[3]; int r2 = cp2[0] * cp2[0]; int g2 = cp2[1] * cp2[1]; int b2 = cp2[2] * cp2[2]; + int a2 = cp2[3] * cp2[3]; cp[0] = round_fl_to_uchar(sqrtf(divide_round_i((mfac * r1 + fac * r2), 255))); cp[1] = round_fl_to_uchar(sqrtf(divide_round_i((mfac * g1 + fac * g2), 255))); cp[2] = round_fl_to_uchar(sqrtf(divide_round_i((mfac * b1 + fac * b2), 255))); - cp[3] = 255; + cp[3] = round_fl_to_uchar(sqrtf(divide_round_i((mfac * a1 + fac * a2), 255))); return col; } @@ -646,7 +635,8 @@ BLI_INLINE uint mcol_add(uint col1, uint col2, int fac) cp[1] = (temp > 254) ? 255 : temp; temp = cp1[2] + divide_round_i((fac * cp2[2]), 255); cp[2] = (temp > 254) ? 255 : temp; - cp[3] = 255; + temp = cp1[3] + divide_round_i((fac * cp2[3]), 255); + cp[3] = (temp > 254) ? 255 : temp; return col; } @@ -671,7 +661,8 @@ BLI_INLINE uint mcol_sub(uint col1, uint col2, int fac) cp[1] = (temp < 0) ? 0 : temp; temp = cp1[2] - divide_round_i((fac * cp2[2]), 255); cp[2] = (temp < 0) ? 0 : temp; - cp[3] = 255; + temp = cp1[3] - divide_round_i((fac * cp2[3]), 255); + cp[3] = (temp < 0) ? 0 : temp; return col; } @@ -696,7 +687,7 @@ BLI_INLINE uint mcol_mul(uint col1, uint col2, int fac) cp[0] = divide_round_i(mfac * cp1[0] * 255 + fac * cp2[0] * cp1[0], 255 * 255); cp[1] = divide_round_i(mfac * cp1[1] * 255 + fac * cp2[1] * cp1[1], 255 * 255); cp[2] = divide_round_i(mfac * cp1[2] * 255 + fac * cp2[2] * cp1[2], 255 * 255); - cp[3] = 255; + cp[3] = divide_round_i(mfac * cp1[3] * 255 + fac * cp2[3] * cp1[3], 255 * 255); return col; } @@ -729,7 +720,7 @@ BLI_INLINE uint mcol_lighten(uint col1, uint col2, int fac) cp[0] = divide_round_i(mfac * cp1[0] + fac * cp2[0], 255); cp[1] = divide_round_i(mfac * cp1[1] + fac * cp2[1], 255); cp[2] = divide_round_i(mfac * cp1[2] + fac * cp2[2], 255); - cp[3] = 255; + cp[3] = divide_round_i(mfac * cp1[3] + fac * cp2[3], 255); return col; } @@ -762,24 +753,373 @@ BLI_INLINE uint mcol_darken(uint col1, uint col2, int fac) cp[0] = divide_round_i((mfac * cp1[0] + fac * cp2[0]), 255); cp[1] = divide_round_i((mfac * cp1[1] + fac * cp2[1]), 255); cp[2] = divide_round_i((mfac * cp1[2] + fac * cp2[2]), 255); - cp[3] = 255; + cp[3] = divide_round_i((mfac * cp1[3] + fac * cp2[3]), 255); + return col; +} + +BLI_INLINE uint mcol_colordodge(uint col1, uint col2, int fac) +{ + uchar *cp1, *cp2, *cp; + int mfac,temp; + uint col = 0; + + if (fac == 0) { + return col1; + } + + mfac = 255 - fac; + + cp1 = (uchar *)&col1; + cp2 = (uchar *)&col2; + cp = (uchar *)&col; + + temp = (cp2[0] == 255) ? 255 : min_ii((cp1[0] * 225) / (255 - cp2[0]), 255); + cp[0] = (mfac * cp1[0] + temp * fac) / 255; + temp = (cp2[1] == 255) ? 255 : min_ii((cp1[1] * 225) / (255 - cp2[1]), 255); + cp[1] = (mfac * cp1[1] + temp * fac) / 255; + temp = (cp2[2] == 255) ? 255 : min_ii((cp1[2] * 225 )/ (255 - cp2[2]), 255); + cp[2] = (mfac * cp1[2] + temp * fac) / 255; + temp = (cp2[3] == 255) ? 255 : min_ii((cp1[3] * 225) / (255 - cp2[3]), 255); + cp[3] = (mfac * cp1[3] + temp * fac) / 255; + return col; +} + +BLI_INLINE uint mcol_difference(uint col1, uint col2, int fac) +{ + uchar *cp1, *cp2, *cp; + int mfac, temp; + uint col = 0; + + if (fac == 0) { + return col1; + } + + mfac = 255 - fac; + + cp1 = (uchar *)&col1; + cp2 = (uchar *)&col2; + cp = (uchar *)&col; + + temp = abs(cp1[0] - cp2[0]); + cp[0] = (mfac * cp1[0] + temp * fac) / 255; + temp = abs(cp1[1] - cp2[1]); + cp[1] = (mfac * cp1[1] + temp * fac) / 255; + temp = abs(cp1[2] - cp2[2]); + cp[2] = (mfac * cp1[2] + temp * fac) / 255; + temp = abs(cp1[3] - cp2[3]); + cp[3] = (mfac * cp1[3] + temp * fac) / 255; + return col; +} + +BLI_INLINE uint mcol_screen(uint col1, uint col2, int fac) +{ + uchar *cp1, *cp2, *cp; + int mfac, temp; + uint col = 0; + + if (fac == 0) { + return col1; + } + + mfac = 255 - fac; + + cp1 = (uchar *)&col1; + cp2 = (uchar *)&col2; + cp = (uchar *)&col; + + temp = max_ii(255 - (((255 - cp1[0]) * (255 - cp2[0])) / 255), 0); + cp[0] = (mfac * cp1[0] + temp * fac) / 255; + temp = max_ii(255 - (((255 - cp1[1]) * (255 - cp2[1])) / 255), 0); + cp[1] = (mfac * cp1[1] + temp * fac) / 255; + temp = max_ii(255 - (((255 - cp1[2]) * (255 - cp2[2])) / 255), 0); + cp[2] = (mfac * cp1[2] + temp * fac) / 255; + temp = max_ii(255 - (((255 - cp1[3]) * (255 - cp2[3])) / 255), 0); + cp[3] = (mfac * cp1[3] + temp * fac) / 255; + return col; +} + +BLI_INLINE uint mcol_hardlight(uint col1, uint col2, int fac) +{ + uchar *cp1, *cp2, *cp; + int mfac, temp; + uint col = 0; + + if (fac == 0) { + return col1; + } + + mfac = 255 - fac; + + cp1 = (uchar *)&col1; + cp2 = (uchar *)&col2; + cp = (uchar *)&col; + + int i = 0; + + for (i = 0; i < 4; i++) { + if (cp2[i] > 127) { + temp = 255 - ((255 - 2 * (cp2[i] - 127)) * (255 - cp1[i]) / 255); + } + else { + temp = (2 * cp2[i] * cp1[i]) >> 8; + } + cp[i] = min_ii((mfac * cp1[i] + temp * fac) / 255, 255); + } + return col; +} + +BLI_INLINE uint mcol_overlay(uint col1, uint col2, int fac) +{ + uchar *cp1, *cp2, *cp; + int mfac, temp; + uint col = 0; + + if (fac == 0) { + return col1; + } + + mfac = 255 - fac; + + cp1 = (uchar *)&col1; + cp2 = (uchar *)&col2; + cp = (uchar *)&col; + + int i = 0; + + for (i = 0; i < 4; i++) { + if (cp1[i] > 127) { + temp = 255 - ((255 - 2 * (cp1[i] - 127)) * (255 - cp2[i]) / 255); + } + else { + temp = (2 * cp2[i] * cp1[i]) >> 8; + } + cp[i] = min_ii((mfac * cp1[i] + temp * fac) / 255, 255); + } + return col; +} + +BLI_INLINE uint mcol_softlight(uint col1, uint col2, int fac) +{ + uchar *cp1, *cp2, *cp; + int mfac, temp; + uint col = 0; + + if (fac == 0) { + return col1; + } + + mfac = 255 - fac; + + cp1 = (uchar *)&col1; + cp2 = (uchar *)&col2; + cp = (uchar *)&col; + + int i = 0; + + for (i = 0; i < 4; i++) { + if (cp1[i] < 127) { + temp = ((2 * ((cp2[i] / 2) + 64)) * cp1[i]) / 255; + } + else { + temp = 255 - (2 * (255 - ((cp2[i] / 2) + 64)) * (255 - cp1[i]) / 255); + } + cp[i] = (temp * fac + cp1[i] * mfac) / 255; + } + return col; +} + +BLI_INLINE uint mcol_exclusion(uint col1, uint col2, int fac) +{ + uchar *cp1, *cp2, *cp; + int mfac, temp; + uint col = 0; + + if (fac == 0) { + return col1; + } + + mfac = 255 - fac; + + cp1 = (uchar *)&col1; + cp2 = (uchar *)&col2; + cp = (uchar *)&col; + + int i = 0; + + for (i = 0; i < 4; i++) { + temp = 127 - ((2 * (cp1[i] - 127) * (cp2[i] - 127)) / 255); + cp[i] = (temp * fac + cp1[i] * mfac) / 255; + } + return col; +} + +BLI_INLINE uint mcol_luminosity(uint col1, uint col2, int fac) +{ + uchar *cp1, *cp2, *cp; + int mfac; + uint col = 0; + + if (fac == 0) { + return col1; + } + + mfac = 255 - fac; + + cp1 = (uchar *)&col1; + cp2 = (uchar *)&col2; + cp = (uchar *)&col; + + float h1, s1, v1; + float h2, s2, v2; + float r, g, b; + rgb_to_hsv(cp1[0] / 255.0f, cp1[1] / 255.0f, cp1[2] / 255.0f, &h1, &s1, &v1); + rgb_to_hsv(cp2[0] / 255.0f, cp2[1] / 255.0f, cp2[2] / 255.0f, &h2, &s2, &v2); + + v1 = v2; + + hsv_to_rgb(h1, s1, v1, &r, &g, &b); + + cp[0] = ((int)(r * 255.0f) * fac + mfac * cp1[0]) / 255; + cp[1] = ((int)(g * 255.0f) * fac + mfac * cp1[1]) / 255; + cp[2] = ((int)(b * 255.0f) * fac + mfac * cp1[2]) / 255; + cp[3] = ((int)(cp2[3]) * fac + mfac * cp1[3]) / 255; + return col; +} + +BLI_INLINE uint mcol_saturation(uint col1, uint col2, int fac) +{ + uchar *cp1, *cp2, *cp; + int mfac; + uint col = 0; + + if (fac == 0) { + return col1; + } + + mfac = 255 - fac; + + cp1 = (uchar *)&col1; + cp2 = (uchar *)&col2; + cp = (uchar *)&col; + + float h1, s1, v1; + float h2, s2, v2; + float r, g, b; + rgb_to_hsv(cp1[0] / 255.0f, cp1[1] / 255.0f, cp1[2] / 255.0f, &h1, &s1, &v1); + rgb_to_hsv(cp2[0] / 255.0f, cp2[1] / 255.0f, cp2[2] / 255.0f, &h2, &s2, &v2); + + if (s1 > EPS_SATURATION) { + s1 = s2; + } + + hsv_to_rgb(h1, s1, v1, &r, &g, &b); + + cp[0] = ((int)(r * 255.0f) * fac + mfac * cp1[0]) / 255; + cp[1] = ((int)(g * 255.0f) * fac + mfac * cp1[1]) / 255; + cp[2] = ((int)(b * 255.0f) * fac + mfac * cp1[2]) / 255; + return col; +} + +BLI_INLINE uint mcol_hue(uint col1, uint col2, int fac) +{ + uchar *cp1, *cp2, *cp; + int mfac; + uint col = 0; + + if (fac == 0) { + return col1; + } + + mfac = 255 - fac; + + cp1 = (uchar *)&col1; + cp2 = (uchar *)&col2; + cp = (uchar *)&col; + + float h1, s1, v1; + float h2, s2, v2; + float r, g, b; + rgb_to_hsv(cp1[0] / 255.0f, cp1[1] / 255.0f, cp1[2] / 255.0f, &h1, &s1, &v1); + rgb_to_hsv(cp2[0] / 255.0f, cp2[1] / 255.0f, cp2[2] / 255.0f, &h2, &s2, &v2); + + h1 = h2; + + hsv_to_rgb(h1, s1, v1, &r, &g, &b); + + cp[0] = ((int)(r * 255.0f) * fac + mfac * cp1[0]) / 255; + cp[1] = ((int)(g * 255.0f) * fac + mfac * cp1[1]) / 255; + cp[2] = ((int)(b * 255.0f) * fac + mfac * cp1[2]) / 255; + cp[3] = ((int)(cp2[3]) * fac + mfac * cp1[3]) / 255; + return col; +} + +BLI_INLINE uint mcol_alpha_add(uint col1, int fac) +{ + uchar *cp1, *cp; + int temp; + uint col = 0; + + if (fac == 0) { + return col1; + } + + cp1 = (uchar *)&col1; + cp = (uchar *)&col; + + temp = cp1[3] + fac; + cp[3] = (temp > 254) ? 255 : temp; + return col; } +BLI_INLINE uint mcol_alpha_sub(uint col1, int fac) +{ + uchar *cp1, *cp; + int temp; + uint col = 0; + + if (fac == 0) { + return col1; + } + + cp1 = (uchar *)&col1; + cp = (uchar *)&col; + + temp = cp1[3] - fac; + cp[3] = temp < 0 ? 0 : temp; + + return col; +} + + /* wpaint has 'wpaint_blend_tool' */ -static uint vpaint_blend_tool(const int tool, const uint col, - const uint paintcol, const int alpha_i) +static uint vpaint_blend_tool( + const int tool, const uint col, + const uint paintcol, const int alpha_i) { switch (tool) { case PAINT_BLEND_MIX: - case PAINT_BLEND_BLUR: return mcol_blend(col, paintcol, alpha_i); - case PAINT_BLEND_AVERAGE: return mcol_blend(col, paintcol, alpha_i); - case PAINT_BLEND_SMEAR: return mcol_blend(col, paintcol, alpha_i); - case PAINT_BLEND_ADD: return mcol_add(col, paintcol, alpha_i); - case PAINT_BLEND_SUB: return mcol_sub(col, paintcol, alpha_i); - case PAINT_BLEND_MUL: return mcol_mul(col, paintcol, alpha_i); - case PAINT_BLEND_LIGHTEN: return mcol_lighten(col, paintcol, alpha_i); - case PAINT_BLEND_DARKEN: return mcol_darken(col, paintcol, alpha_i); + case PAINT_BLEND_BLUR: return mcol_blend(col, paintcol, alpha_i); + case PAINT_BLEND_AVERAGE: return mcol_blend(col, paintcol, alpha_i); + case PAINT_BLEND_SMEAR: return mcol_blend(col, paintcol, alpha_i); + case PAINT_BLEND_ADD: return mcol_add(col, paintcol, alpha_i); + case PAINT_BLEND_SUB: return mcol_sub(col, paintcol, alpha_i); + case PAINT_BLEND_MUL: return mcol_mul(col, paintcol, alpha_i); + case PAINT_BLEND_LIGHTEN: return mcol_lighten(col, paintcol, alpha_i); + case PAINT_BLEND_DARKEN: return mcol_darken(col, paintcol, alpha_i); + case PAINT_BLEND_COLORDODGE: return mcol_colordodge(col, paintcol, alpha_i); + case PAINT_BLEND_DIFFERENCE: return mcol_difference(col, paintcol, alpha_i); + case PAINT_BLEND_SCREEN: return mcol_screen(col, paintcol, alpha_i); + case PAINT_BLEND_HARDLIGHT: return mcol_hardlight(col, paintcol, alpha_i); + case PAINT_BLEND_OVERLAY: return mcol_overlay(col, paintcol, alpha_i); + case PAINT_BLEND_SOFTLIGHT: return mcol_softlight(col, paintcol, alpha_i); + case PAINT_BLEND_EXCLUSION: return mcol_exclusion(col, paintcol, alpha_i); + case PAINT_BLEND_LUMINOCITY: return mcol_luminosity(col, paintcol, alpha_i); + case PAINT_BLEND_SATURATION: return mcol_saturation(col, paintcol, alpha_i); + case PAINT_BLEND_HUE: return mcol_hue(col, paintcol, alpha_i); + /* non-color */ + case PAINT_BLEND_ALPHA_SUB: return mcol_alpha_sub(col, alpha_i); + case PAINT_BLEND_ALPHA_ADD: return mcol_alpha_add(col, alpha_i); default: BLI_assert(0); return 0; @@ -788,27 +1128,27 @@ static uint vpaint_blend_tool(const int tool, const uint col, /* wpaint has 'wpaint_blend' */ static uint vpaint_blend( - VPaint *vp, uint col, uint colorig, - const uint paintcol, const int alpha_i, + VPaint *vp, uint color_curr, uint color_orig, + uint color_paint, const int alpha_i, /* pre scaled from [0-1] --> [0-255] */ const int brush_alpha_value_i) { Brush *brush = BKE_paint_brush(&vp->paint); const int tool = brush->vertexpaint_tool; - col = vpaint_blend_tool(tool, col, paintcol, alpha_i); + uint color_blend = vpaint_blend_tool(tool, color_curr, color_paint, alpha_i); /* if no spray, clip color adding with colorig & orig alpha */ if ((vp->flag & VP_SPRAY) == 0) { - uint testcol, a; + uint color_test, a; char *cp, *ct, *co; - - testcol = vpaint_blend_tool(tool, colorig, paintcol, brush_alpha_value_i); - - cp = (char *)&col; - ct = (char *)&testcol; - co = (char *)&colorig; - + + color_test = vpaint_blend_tool(tool, color_orig, color_paint, brush_alpha_value_i); + + cp = (char *)&color_blend; + ct = (char *)&color_test; + co = (char *)&color_orig; + for (a = 0; a < 4; a++) { if (ct[a] < co[a]) { if (cp[a] < ct[a]) cp[a] = ct[a]; @@ -821,7 +1161,16 @@ static uint vpaint_blend( } } - return col; + if ((brush->flag & BRUSH_LOCK_ALPHA) && + !ELEM(tool, PAINT_BLEND_ALPHA_SUB, PAINT_BLEND_ALPHA_ADD)) + { + char *cp, *cc; + cp = (char *)&color_blend; + cc = (char *)&color_curr; + cp[3] = cc[3]; + } + + return color_blend; } @@ -1739,12 +2088,15 @@ static void vertex_paint_init_session_data(const ToolSettings *ts, Object *ob) { /* Create maps */ struct SculptVertexPaintGeomMap *gmap = NULL; + const Brush *brush = NULL; if (ob->mode == OB_MODE_VERTEX_PAINT) { gmap = &ob->sculpt->mode.vpaint.gmap; + brush = BKE_paint_brush(&ts->vpaint->paint); ob->sculpt->mode_type = OB_MODE_VERTEX_PAINT; } else if (ob->mode == OB_MODE_WEIGHT_PAINT) { gmap = &ob->sculpt->mode.wpaint.gmap; + brush = BKE_paint_brush(&ts->wpaint->paint); ob->sculpt->mode_type = OB_MODE_WEIGHT_PAINT; } else { @@ -1781,6 +2133,16 @@ static void vertex_paint_init_session_data(const ToolSettings *ts, Object *ob) else { MEM_SAFE_FREE(ob->sculpt->mode.vpaint.previous_color); } + + if (brush && brush->flag & BRUSH_ACCUMULATE) { + if (ob->sculpt->mode.vpaint.previous_accum == NULL) { + ob->sculpt->mode.vpaint.previous_accum = + MEM_callocN(me->totloop * sizeof(uint), "previous_color"); + } + } + else { + MEM_SAFE_FREE(ob->sculpt->mode.vpaint.previous_accum); + } } else if (ob->mode == OB_MODE_WEIGHT_PAINT) { if ((ts->wpaint->flag & VP_SPRAY) == 0) { @@ -3116,6 +3478,9 @@ static int vpaint_mode_toggle_exec(bContext *C, wmOperator *op) if (me->editflag & ME_EDIT_PAINT_FACE_SEL) { BKE_mesh_flush_select_from_polys(me); } + else if (me->editflag & ME_EDIT_PAINT_VERT_SEL) { + BKE_mesh_flush_select_from_verts(me); + } /* If the cache is not released by a cancel or a done, free it now. */ if (ob->sculpt->cache) { @@ -3134,9 +3499,7 @@ static int vpaint_mode_toggle_exec(bContext *C, wmOperator *op) ob->mode |= mode_flag; - if (me->mloopcol == NULL) { - make_vertexcol(ob); - } + ED_mesh_color_ensure(me, NULL); if (vp == NULL) vp = scene->toolsettings->vpaint = new_vpaint(0); @@ -3250,8 +3613,7 @@ static bool vpaint_stroke_test_start(bContext *C, struct wmOperator *op, const f if (me == NULL || me->totpoly == 0) return false; - if (me->mloopcol == NULL) - make_vertexcol(ob); + ED_mesh_color_ensure(me, NULL); if (me->mloopcol == NULL) return false; @@ -3316,8 +3678,7 @@ static void do_vpaint_brush_calc_average_color_cb_ex( StrokeCache *cache = ss->cache; uint *lcol = data->lcol; char *col; - - const bool use_face_sel = (data->me->editflag & ME_EDIT_PAINT_FACE_SEL) != 0; + const bool use_vert_sel = (data->me->editflag & (ME_EDIT_PAINT_FACE_SEL | ME_EDIT_PAINT_VERT_SEL)) != 0; struct VPaintAverageAccum *accum = (struct VPaintAverageAccum *)data->custom_data + n; accum->len = 0; @@ -3336,7 +3697,7 @@ static void do_vpaint_brush_calc_average_color_cb_ex( if (BKE_brush_curve_strength(data->brush, test.dist, cache->radius) > 0.0) { /* If the vertex is selected for painting. */ const MVert *mv = &data->me->mvert[v_index]; - if (!use_face_sel || mv->flag & SELECT) { + if (!use_vert_sel || mv->flag & SELECT) { accum->len += gmap->vert_to_loop[v_index].count; /* if a vertex is within the brush region, then add it's color to the blend. */ for (int j = 0; j < gmap->vert_to_loop[v_index].count; j++) { @@ -3388,12 +3749,13 @@ static void do_vpaint_brush_draw_task_cb_ex( Scene *scene = CTX_data_scene(data->C); float brush_size_pressure, brush_alpha_value, brush_alpha_pressure; get_brush_alpha_data(scene, ss, brush, &brush_size_pressure, &brush_alpha_value, &brush_alpha_pressure); + const bool use_vert_sel = (data->me->editflag & (ME_EDIT_PAINT_FACE_SEL | ME_EDIT_PAINT_VERT_SEL)) != 0; const bool use_face_sel = (data->me->editflag & ME_EDIT_PAINT_FACE_SEL) != 0; SculptBrushTest test; sculpt_brush_test_init(ss, &test); - /* For each vertex*/ + /* For each vertex */ PBVHVertexIter vd; BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) { @@ -3407,7 +3769,7 @@ static void do_vpaint_brush_draw_task_cb_ex( const MVert *mv = &data->me->mvert[v_index]; /* If the vertex is selected for painting. */ - if (!use_face_sel || mv->flag & SELECT) { + if (!use_vert_sel || mv->flag & SELECT) { /* Calc the dot prod. between ray norm on surf and current vert * (ie splash prevention factor), and only paint front facing verts. */ const float view_dot = (vd.no) ? dot_vf3vs3(cache->sculpt_normal_symm, vd.no) : 1.0; @@ -3437,9 +3799,16 @@ static void do_vpaint_brush_draw_task_cb_ex( } color_orig = ss->mode.vpaint.previous_color[l_index]; } - const float final_alpha = + float final_alpha = 255 * brush_fade * brush_strength * view_dot * tex_alpha * brush_alpha_pressure * grid_alpha; + + if (brush->flag & BRUSH_ACCUMULATE) { + float mask_accum = ss->mode.vpaint.previous_accum[l_index]; + final_alpha = min_ff(final_alpha + mask_accum, 255.0f); + ss->mode.vpaint.previous_accum[l_index] = final_alpha; + } + /* Mix the new color with the original based on final_alpha. */ lcol[l_index] = vpaint_blend( data->vp, lcol[l_index], color_orig, color_final, @@ -3468,6 +3837,7 @@ static void do_vpaint_brush_blur_task_cb_ex( uint *lcol = data->lcol; float brush_size_pressure, brush_alpha_value, brush_alpha_pressure; get_brush_alpha_data(scene, ss, brush, &brush_size_pressure, &brush_alpha_value, &brush_alpha_pressure); + const bool use_vert_sel = (data->me->editflag & (ME_EDIT_PAINT_FACE_SEL | ME_EDIT_PAINT_VERT_SEL)) != 0; const bool use_face_sel = (data->me->editflag & ME_EDIT_PAINT_FACE_SEL) != 0; SculptBrushTest test; @@ -3480,7 +3850,7 @@ static void do_vpaint_brush_blur_task_cb_ex( /* Test to see if the vertex coordinates are within the spherical brush region. */ if (sculpt_brush_test(&test, vd.co)) { /* For grid based pbvh, take the vert whose loop cooresponds to the current grid. - Otherwise, take the current vert. */ + * Otherwise, take the current vert. */ const int v_index = ccgdm ? data->me->mloop[vd.grid_indices[vd.g]].v : vd.vert_indices[vd.i]; const float grid_alpha = ccgdm ? 1.0f / vd.gridsize : 1.0f; const MVert *mv = &data->me->mvert[v_index]; @@ -3490,7 +3860,7 @@ static void do_vpaint_brush_blur_task_cb_ex( const float brush_fade = BKE_brush_curve_strength(brush, test.dist, cache->radius); /* If the vertex is selected for painting. */ - if (!use_face_sel || mv->flag & SELECT) { + if (!use_vert_sel || mv->flag & SELECT) { /* Get the average poly color */ uint color_final = 0; int total_hit_loops = 0; @@ -3568,6 +3938,7 @@ static void do_vpaint_brush_smear_task_cb_ex( float brush_size_pressure, brush_alpha_value, brush_alpha_pressure; get_brush_alpha_data(scene, ss, brush, &brush_size_pressure, &brush_alpha_value, &brush_alpha_pressure); float brush_dir[3]; + const bool use_vert_sel = (data->me->editflag & (ME_EDIT_PAINT_FACE_SEL | ME_EDIT_PAINT_VERT_SEL)) != 0; const bool use_face_sel = (data->me->editflag & ME_EDIT_PAINT_FACE_SEL) != 0; sub_v3_v3v3(brush_dir, cache->location, cache->last_location); @@ -3583,15 +3954,15 @@ static void do_vpaint_brush_smear_task_cb_ex( /* Test to see if the vertex coordinates are within the spherical brush region. */ if (sculpt_brush_test(&test, vd.co)) { /* For grid based pbvh, take the vert whose loop cooresponds to the current grid. - Otherwise, take the current vert. */ + * Otherwise, take the current vert. */ const int v_index = ccgdm ? data->me->mloop[vd.grid_indices[vd.g]].v : vd.vert_indices[vd.i]; const float grid_alpha = ccgdm ? 1.0f / vd.gridsize : 1.0f; const MVert *mv_curr = &data->me->mvert[v_index]; /* if the vertex is selected for painting. */ - if (!use_face_sel || mv_curr->flag & SELECT) { + if (!use_vert_sel || mv_curr->flag & SELECT) { /* Calc the dot prod. between ray norm on surf and current vert - (ie splash prevention factor), and only paint front facing verts. */ + * (ie splash prevention factor), and only paint front facing verts. */ const float view_dot = (vd.no) ? dot_vf3vs3(cache->sculpt_normal_symm, vd.no) : 1.0; if (view_dot > 0.0f) { const float brush_fade = BKE_brush_curve_strength(brush, test.dist, cache->radius); diff --git a/source/blender/editors/sculpt_paint/paint_vertex_color_ops.c b/source/blender/editors/sculpt_paint/paint_vertex_color_ops.c new file mode 100644 index 00000000000..3cec9dfc063 --- /dev/null +++ b/source/blender/editors/sculpt_paint/paint_vertex_color_ops.c @@ -0,0 +1,112 @@ +/* + * ***** 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. + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/editors/sculpt_paint/paint_vertex_color_ops.c + * \ingroup edsculpt + */ + +#include "MEM_guardedalloc.h" + +#include "DNA_mesh_types.h" +#include "DNA_meshdata_types.h" +#include "DNA_object_types.h" + +#include "BKE_context.h" +#include "BKE_mesh.h" +#include "BKE_deform.h" + +#include "DEG_depsgraph.h" + +#include "WM_api.h" +#include "WM_types.h" + +#include "ED_mesh.h" + +#include "paint_intern.h" /* own include */ + + +static int vertex_weight_paint_mode_poll(bContext *C) +{ + Object *ob = CTX_data_active_object(C); + Mesh *me = BKE_mesh_from_object(ob); + return (ob && (ob->mode == OB_MODE_VERTEX_PAINT || ob->mode == OB_MODE_WEIGHT_PAINT)) && + (me && me->totpoly && me->dvert); +} + +static bool vertex_paint_from_weight(bContext *C) +{ + Object *ob = CTX_data_active_object(C); + Mesh *me; + const MPoly *mp; + int vgroup_active; + + if (((me = BKE_mesh_from_object(ob)) == NULL || + (ED_mesh_color_ensure(me, NULL)) == false)) + { + return false; + } + + /* TODO: respect selection. */ + mp = me->mpoly; + vgroup_active = ob->actdef - 1; + for (int i = 0; i < me->totpoly; i++, mp++) { + MLoopCol *lcol = &me->mloopcol[mp->loopstart]; + uint j = 0; + do{ + uint vidx = me->mloop[mp->loopstart + j].v; + const float weight = defvert_find_weight(&me->dvert[vidx], vgroup_active); + const uchar grayscale = weight * 255; + lcol->r = grayscale; + lcol->b = grayscale; + lcol->g = grayscale; + lcol++; + j++; + } while (j < mp->totloop); + } + + DEG_id_tag_update(&ob->id, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob); + return true; +} + +static int vertex_paint_from_weight_exec(bContext *C, wmOperator *UNUSED(op)) +{ + if (vertex_paint_from_weight(C)) { + return OPERATOR_FINISHED; + } + return OPERATOR_CANCELLED; +} + +void PAINT_OT_vertex_color_from_weight(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Vertex Color from Weight"; + ot->idname = "PAINT_OT_vertex_color_from_weight"; + ot->description = "Converts active weight into greyscale vertex colors"; + + /* api callback */ + ot->exec = vertex_paint_from_weight_exec; + ot->poll = vertex_weight_paint_mode_poll; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + /* TODO: invert, alpha */ +} diff --git a/source/blender/editors/sculpt_paint/sculpt_intern.h b/source/blender/editors/sculpt_paint/sculpt_intern.h index 850d4631311..3d1c7e94d17 100644 --- a/source/blender/editors/sculpt_paint/sculpt_intern.h +++ b/source/blender/editors/sculpt_paint/sculpt_intern.h @@ -192,14 +192,14 @@ typedef struct { bool original; } SculptSearchSphereData; -void sculpt_brush_test_init(SculptSession *ss, SculptBrushTest *test); +void sculpt_brush_test_init(struct SculptSession *ss, SculptBrushTest *test); bool sculpt_brush_test(SculptBrushTest *test, const float co[3]); bool sculpt_brush_test_sq(SculptBrushTest *test, const float co[3]); bool sculpt_brush_test_fast(const SculptBrushTest *test, const float co[3]); bool sculpt_brush_test_cube(SculptBrushTest *test, const float co[3], float local[4][4]); bool sculpt_search_sphere_cb(PBVHNode *node, void *data_v); float tex_strength( - SculptSession *ss, struct Brush *br, + struct SculptSession *ss, struct Brush *br, const float point[3], const float len, const short vno[3], diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c index 953eda42373..fa88d63ae1c 100644 --- a/source/blender/editors/space_view3d/drawobject.c +++ b/source/blender/editors/space_view3d/drawobject.c @@ -9792,8 +9792,8 @@ void draw_object_backbufsel( else { Mesh *me = ob->data; if ((me->editflag & ME_EDIT_PAINT_VERT_SEL) && - /* currently vertex select only supports weight paint */ - (ob->mode & OB_MODE_WEIGHT_PAINT)) + /* currently vertex select supports weight paint and vertex paint*/ + ((ob->mode & OB_MODE_WEIGHT_PAINT) || (ob->mode & OB_MODE_VERTEX_PAINT))) { bbs_mesh_solid_verts(eval_ctx, scene, ob); } diff --git a/source/blender/editors/space_view3d/view3d_header.c b/source/blender/editors/space_view3d/view3d_header.c index b6deabdb447..d8599610197 100644 --- a/source/blender/editors/space_view3d/view3d_header.c +++ b/source/blender/editors/space_view3d/view3d_header.c @@ -314,7 +314,7 @@ void uiTemplateHeader3D(uiLayout *layout, struct bContext *C) PointerRNA meshptr; RNA_pointer_create(ob->data, &RNA_Mesh, ob->data, &meshptr); - if (ob->mode & (OB_MODE_TEXTURE_PAINT | OB_MODE_VERTEX_PAINT)) { + if (ob->mode & (OB_MODE_TEXTURE_PAINT)) { uiItemR(layout, &meshptr, "use_paint_mask", UI_ITEM_R_ICON_ONLY, "", ICON_NONE); } else { diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c index 56dbe01aa4b..166a5805fa1 100644 --- a/source/blender/editors/transform/transform_conversions.c +++ b/source/blender/editors/transform/transform_conversions.c @@ -4780,7 +4780,7 @@ void flushTransGraphData(TransInfo *t) /* if int-values only, truncate to integers */ if (td->flag & TD_INTVALUES) - td2d->loc2d[1] = floorf(td2d->loc[1] + 0.5f); + td2d->loc2d[1] = floorf(td2d->loc[1] * inv_unit_scale - tdg->offset + 0.5f); else td2d->loc2d[1] = td2d->loc[1] * inv_unit_scale - tdg->offset; diff --git a/source/blender/gpu/intern/gpu_buffers.c b/source/blender/gpu/intern/gpu_buffers.c index e918b70ec7c..3a6b0a2a72d 100644 --- a/source/blender/gpu/intern/gpu_buffers.c +++ b/source/blender/gpu/intern/gpu_buffers.c @@ -84,7 +84,7 @@ static const GPUBufferTypeSettings gpu_buffer_type_settings[] = { /* normal */ {GL_ARRAY_BUFFER, 4}, /* we copy 3 shorts per normal but we add a fourth for alignment */ /* mcol */ - {GL_ARRAY_BUFFER, 3}, + {GL_ARRAY_BUFFER, 4}, /* uv */ {GL_ARRAY_BUFFER, 2}, /* uv for texpaint */ @@ -691,7 +691,7 @@ void GPU_color_setup(DerivedMesh *dm, int colType) glEnableClientState(GL_COLOR_ARRAY); glBindBuffer(GL_ARRAY_BUFFER, dm->drawObject->colors->id); - glColorPointer(3, GL_UNSIGNED_BYTE, 0, 0); + glColorPointer(4, GL_UNSIGNED_BYTE, 0, 0); GLStates |= GPU_BUFFER_COLOR_STATE; } diff --git a/source/blender/imbuf/intern/moviecache.c b/source/blender/imbuf/intern/moviecache.c index 4b49076dcd6..89955711384 100644 --- a/source/blender/imbuf/intern/moviecache.c +++ b/source/blender/imbuf/intern/moviecache.c @@ -49,7 +49,7 @@ #include "IMB_imbuf.h" #ifdef DEBUG_MESSAGES -# if defined __GNUC__ || defined __sun +# if defined __GNUC__ # define PRINT(format, args ...) printf(format, ##args) # else # define PRINT(format, ...) printf(__VA_ARGS__) diff --git a/source/blender/makesdna/DNA_brush_types.h b/source/blender/makesdna/DNA_brush_types.h index eecfd88606f..67a35d4e207 100644 --- a/source/blender/makesdna/DNA_brush_types.h +++ b/source/blender/makesdna/DNA_brush_types.h @@ -318,6 +318,18 @@ enum { PAINT_BLEND_DARKEN = 6, PAINT_BLEND_AVERAGE = 7, PAINT_BLEND_SMEAR = 8, + PAINT_BLEND_COLORDODGE = 9, + PAINT_BLEND_DIFFERENCE = 10, + PAINT_BLEND_SCREEN = 11, + PAINT_BLEND_HARDLIGHT = 12, + PAINT_BLEND_OVERLAY = 13, + PAINT_BLEND_SOFTLIGHT = 14, + PAINT_BLEND_EXCLUSION = 15, + PAINT_BLEND_LUMINOCITY = 16, + PAINT_BLEND_SATURATION = 17, + PAINT_BLEND_HUE = 18, + PAINT_BLEND_ALPHA_SUB = 19, + PAINT_BLEND_ALPHA_ADD = 20, }; typedef enum { diff --git a/source/blender/makesrna/RNA_access.h b/source/blender/makesrna/RNA_access.h index 9c3e5506143..114b0c32c15 100644 --- a/source/blender/makesrna/RNA_access.h +++ b/source/blender/makesrna/RNA_access.h @@ -1219,7 +1219,7 @@ StructRNA *ID_code_to_RNA_type(short idcode); } (void)0 /* macro which inserts the function name */ -#if defined __GNUC__ || defined __sun +#if defined __GNUC__ # define RNA_warning(format, args ...) _RNA_warning("%s: " format "\n", __func__, ##args) #else # define RNA_warning(format, ...) _RNA_warning("%s: " format "\n", __FUNCTION__, __VA_ARGS__) diff --git a/source/blender/makesrna/intern/rna_brush.c b/source/blender/makesrna/intern/rna_brush.c index b1f69a42dac..352706fd9b8 100644 --- a/source/blender/makesrna/intern/rna_brush.c +++ b/source/blender/makesrna/intern/rna_brush.c @@ -94,8 +94,21 @@ EnumPropertyItem rna_enum_brush_vertex_tool_items[] = { {PAINT_BLEND_BLUR, "BLUR", ICON_BRUSH_BLUR, "Blur", "Blur the color with surrounding values"}, {PAINT_BLEND_LIGHTEN, "LIGHTEN", ICON_BRUSH_LIGHTEN, "Lighten", "Use lighten blending mode while painting"}, {PAINT_BLEND_DARKEN, "DARKEN", ICON_BRUSH_DARKEN, "Darken", "Use darken blending mode while painting"}, - {PAINT_BLEND_AVERAGE, "AVERAGE", ICON_BRUSH_BLUR, "Average", "Use average blending mode while painting" }, - {PAINT_BLEND_SMEAR, "SMEAR", ICON_BRUSH_BLUR, "Smear", "Use smear blending mode while painting" }, + {PAINT_BLEND_AVERAGE, "AVERAGE", ICON_BRUSH_BLUR, "Average", "Use average blending mode while painting"}, + {PAINT_BLEND_SMEAR, "SMEAR", ICON_BRUSH_BLUR, "Smear", "Use smear blending mode while painting"}, + {PAINT_BLEND_COLORDODGE, "COLORDODGE", ICON_BRUSH_BLUR, "Color Dodge", "Use color dodge blending mode while painting" }, + {PAINT_BLEND_DIFFERENCE, "DIFFERENCE", ICON_BRUSH_BLUR, "Difference", "Use difference blending mode while painting"}, + {PAINT_BLEND_SCREEN, "SCREEN", ICON_BRUSH_BLUR, "Screen", "Use screen blending mode while painting"}, + {PAINT_BLEND_HARDLIGHT, "HARDLIGHT", ICON_BRUSH_BLUR, "Hardlight", "Use hardlight blending mode while painting"}, + {PAINT_BLEND_OVERLAY, "OVERLAY", ICON_BRUSH_BLUR, "Overlay", "Use overlay blending mode while painting"}, + {PAINT_BLEND_SOFTLIGHT, "SOFTLIGHT", ICON_BRUSH_BLUR, "Softlight", "Use softlight blending mode while painting"}, + {PAINT_BLEND_EXCLUSION, "EXCLUSION", ICON_BRUSH_BLUR, "Exclusion", "Use exclusion blending mode while painting"}, + {PAINT_BLEND_LUMINOCITY, "LUMINOCITY", ICON_BRUSH_BLUR, "Luminocity", "Use luminocity blending mode while painting"}, + {PAINT_BLEND_SATURATION, "SATURATION", ICON_BRUSH_BLUR, "Saturation", "Use saturation blending mode while painting"}, + {PAINT_BLEND_HUE, "HUE", ICON_BRUSH_BLUR, "Hue", "Use hue blending mode while painting"}, + {PAINT_BLEND_ALPHA_SUB, "ERASE_ALPHA", 0, "Erase Alpha", "Erase alpha while painting"}, + {PAINT_BLEND_ALPHA_ADD, "ADD_ALPHA", 0, "Add Alpha", "Add alpha while painting"}, + {0, NULL, 0, NULL, NULL} }; @@ -1266,7 +1279,7 @@ static void rna_def_brush(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Restore Mesh", "Allow a single dot to be carefully positioned"); RNA_def_property_update(prop, 0, "rna_Brush_update"); - /* only for projection paint, TODO, other paint modes */ + /* only for projection paint & vertex paint, TODO, other paint modes */ prop = RNA_def_property(srna, "use_alpha", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", BRUSH_LOCK_ALPHA); RNA_def_property_ui_text(prop, "Alpha", "When this is disabled, lock alpha while painting"); diff --git a/source/blender/makesrna/intern/rna_mesh.c b/source/blender/makesrna/intern/rna_mesh.c index 524e9935760..beb5430b63b 100644 --- a/source/blender/makesrna/intern/rna_mesh.c +++ b/source/blender/makesrna/intern/rna_mesh.c @@ -608,12 +608,14 @@ static void rna_MeshColor_color1_set(PointerRNA *ptr, const float *values) (&mcol[0].r)[2] = round_fl_to_uchar_clamp(values[0] * 255.0f); (&mcol[0].r)[1] = round_fl_to_uchar_clamp(values[1] * 255.0f); (&mcol[0].r)[0] = round_fl_to_uchar_clamp(values[2] * 255.0f); + (&mcol[0].r)[3] = round_fl_to_uchar_clamp(values[3] * 255.0f); } static void rna_MeshColor_color2_get(PointerRNA *ptr, float *values) { MCol *mcol = (MCol *)ptr->data; + values[3] = (&mcol[1].r)[3] / 255.0f; values[2] = (&mcol[1].r)[0] / 255.0f; values[1] = (&mcol[1].r)[1] / 255.0f; values[0] = (&mcol[1].r)[2] / 255.0f; @@ -626,12 +628,14 @@ static void rna_MeshColor_color2_set(PointerRNA *ptr, const float *values) (&mcol[1].r)[2] = round_fl_to_uchar_clamp(values[0] * 255.0f); (&mcol[1].r)[1] = round_fl_to_uchar_clamp(values[1] * 255.0f); (&mcol[1].r)[0] = round_fl_to_uchar_clamp(values[2] * 255.0f); + (&mcol[1].r)[3] = round_fl_to_uchar_clamp(values[3] * 255.0f); } static void rna_MeshColor_color3_get(PointerRNA *ptr, float *values) { MCol *mcol = (MCol *)ptr->data; + values[3] = (&mcol[2].r)[3] / 255.0f; values[2] = (&mcol[2].r)[0] / 255.0f; values[1] = (&mcol[2].r)[1] / 255.0f; values[0] = (&mcol[2].r)[2] / 255.0f; @@ -644,6 +648,7 @@ static void rna_MeshColor_color3_set(PointerRNA *ptr, const float *values) (&mcol[2].r)[2] = round_fl_to_uchar_clamp(values[0] * 255.0f); (&mcol[2].r)[1] = round_fl_to_uchar_clamp(values[1] * 255.0f); (&mcol[2].r)[0] = round_fl_to_uchar_clamp(values[2] * 255.0f); + (&mcol[2].r)[3] = round_fl_to_uchar_clamp(values[3] * 255.0f); } static void rna_MeshColor_color4_get(PointerRNA *ptr, float *values) @@ -653,6 +658,7 @@ static void rna_MeshColor_color4_get(PointerRNA *ptr, float *values) values[2] = (&mcol[3].r)[0] / 255.0f; values[1] = (&mcol[3].r)[1] / 255.0f; values[0] = (&mcol[3].r)[2] / 255.0f; + values[3] = (&mcol[3].r)[3] / 255.0f; } static void rna_MeshColor_color4_set(PointerRNA *ptr, const float *values) @@ -662,6 +668,7 @@ static void rna_MeshColor_color4_set(PointerRNA *ptr, const float *values) (&mcol[3].r)[2] = round_fl_to_uchar_clamp(values[0] * 255.0f); (&mcol[3].r)[1] = round_fl_to_uchar_clamp(values[1] * 255.0f); (&mcol[3].r)[0] = round_fl_to_uchar_clamp(values[2] * 255.0f); + (&mcol[3].r)[3] = round_fl_to_uchar_clamp(values[3] * 255.0f); } static void rna_MeshLoopColor_color_get(PointerRNA *ptr, float *values) @@ -671,6 +678,7 @@ static void rna_MeshLoopColor_color_get(PointerRNA *ptr, float *values) values[0] = (&mcol->r)[0] / 255.0f; values[1] = (&mcol->r)[1] / 255.0f; values[2] = (&mcol->r)[2] / 255.0f; + values[3] = (&mcol->r)[3] / 255.0f; } static void rna_MeshLoopColor_color_set(PointerRNA *ptr, const float *values) @@ -680,6 +688,7 @@ static void rna_MeshLoopColor_color_set(PointerRNA *ptr, const float *values) (&mcol->r)[0] = round_fl_to_uchar_clamp(values[0] * 255.0f); (&mcol->r)[1] = round_fl_to_uchar_clamp(values[1] * 255.0f); (&mcol->r)[2] = round_fl_to_uchar_clamp(values[2] * 255.0f); + (&mcol->r)[3] = round_fl_to_uchar_clamp(values[3] * 255.0f); } static int rna_Mesh_texspace_editable(PointerRNA *ptr, const char **UNUSED(r_info)) @@ -2454,28 +2463,28 @@ static void rna_def_mcol(BlenderRNA *brna) RNA_def_struct_path_func(srna, "rna_MeshColor_path"); prop = RNA_def_property(srna, "color1", PROP_FLOAT, PROP_COLOR); - RNA_def_property_array(prop, 3); + RNA_def_property_array(prop, 4); RNA_def_property_range(prop, 0.0f, 1.0f); RNA_def_property_float_funcs(prop, "rna_MeshColor_color1_get", "rna_MeshColor_color1_set", NULL); RNA_def_property_ui_text(prop, "Color 1", ""); RNA_def_property_update(prop, 0, "rna_Mesh_update_data"); prop = RNA_def_property(srna, "color2", PROP_FLOAT, PROP_COLOR); - RNA_def_property_array(prop, 3); + RNA_def_property_array(prop, 4); RNA_def_property_range(prop, 0.0f, 1.0f); RNA_def_property_float_funcs(prop, "rna_MeshColor_color2_get", "rna_MeshColor_color2_set", NULL); RNA_def_property_ui_text(prop, "Color 2", ""); RNA_def_property_update(prop, 0, "rna_Mesh_update_data"); prop = RNA_def_property(srna, "color3", PROP_FLOAT, PROP_COLOR); - RNA_def_property_array(prop, 3); + RNA_def_property_array(prop, 4); RNA_def_property_range(prop, 0.0f, 1.0f); RNA_def_property_float_funcs(prop, "rna_MeshColor_color3_get", "rna_MeshColor_color3_set", NULL); RNA_def_property_ui_text(prop, "Color 3", ""); RNA_def_property_update(prop, 0, "rna_Mesh_update_data"); prop = RNA_def_property(srna, "color4", PROP_FLOAT, PROP_COLOR); - RNA_def_property_array(prop, 3); + RNA_def_property_array(prop, 4); RNA_def_property_range(prop, 0.0f, 1.0f); RNA_def_property_float_funcs(prop, "rna_MeshColor_color4_get", "rna_MeshColor_color4_set", NULL); RNA_def_property_ui_text(prop, "Color 4", ""); @@ -2525,7 +2534,7 @@ static void rna_def_mloopcol(BlenderRNA *brna) RNA_def_struct_path_func(srna, "rna_MeshColor_path"); prop = RNA_def_property(srna, "color", PROP_FLOAT, PROP_COLOR); - RNA_def_property_array(prop, 3); + RNA_def_property_array(prop, 4); RNA_def_property_range(prop, 0.0f, 1.0f); RNA_def_property_float_funcs(prop, "rna_MeshLoopColor_color_get", "rna_MeshLoopColor_color_set", NULL); RNA_def_property_ui_text(prop, "Color", ""); |