diff options
Diffstat (limited to 'source/blender/editors/sculpt_paint')
-rw-r--r-- | source/blender/editors/sculpt_paint/paint_cursor.c | 115 | ||||
-rw-r--r-- | source/blender/editors/sculpt_paint/paint_intern.h | 6 | ||||
-rw-r--r-- | source/blender/editors/sculpt_paint/paint_ops.c | 179 | ||||
-rw-r--r-- | source/blender/editors/sculpt_paint/paint_utils.c | 22 | ||||
-rw-r--r-- | source/blender/editors/sculpt_paint/paint_vertex.c | 4 | ||||
-rw-r--r-- | source/blender/editors/sculpt_paint/sculpt.c | 2 |
6 files changed, 289 insertions, 39 deletions
diff --git a/source/blender/editors/sculpt_paint/paint_cursor.c b/source/blender/editors/sculpt_paint/paint_cursor.c index 38660e371be..1616b3026bd 100644 --- a/source/blender/editors/sculpt_paint/paint_cursor.c +++ b/source/blender/editors/sculpt_paint/paint_cursor.c @@ -117,7 +117,7 @@ static void make_snap(Snapshot *snap, Brush *brush, ViewContext *vc) snap->winy = vc->ar->winy; } -static int load_tex(Brush *br, ViewContext *vc, float zoom) +static int load_tex(Brush *br, ViewContext *vc, float zoom, bool col) { static GLuint overlay_texture = 0; static int init = 0; @@ -126,12 +126,14 @@ static int load_tex(Brush *br, ViewContext *vc, float zoom) static Snapshot snap; static int old_size = -1; static int old_zoom = -1; + static bool old_col = -1; GLubyte *buffer = NULL; int size; int j; int refresh; + int format = col? GL_RGBA : GL_ALPHA; if (br->mtex.brush_map_mode == MTEX_MAP_MODE_TILED && !br->mtex.tex) return 0; @@ -143,11 +145,15 @@ static int load_tex(Brush *br, ViewContext *vc, float zoom) !br->curve || br->curve->changed_timestamp != curve_changed_timestamp || old_zoom != zoom || + old_col != col || !same_snap(&snap, br, vc); if (refresh) { struct ImagePool *pool = NULL; - const float rotation = -br->mtex.rot; + /* stencil is rotated later */ + const float rotation = (br->mtex.brush_map_mode != MTEX_MAP_MODE_STENCIL)? + -br->mtex.rot : 0; + float radius = BKE_brush_size_get(vc->scene, br) * zoom; if (br->mtex.tex && br->mtex.tex->preview) @@ -187,8 +193,10 @@ static int load_tex(Brush *br, ViewContext *vc, float zoom) old_size = size; } - - buffer = MEM_mallocN(sizeof(GLubyte) * size * size, "load_tex"); + if (col) + buffer = MEM_mallocN(sizeof(GLubyte) * size * size * 4, "load_tex"); + else + buffer = MEM_mallocN(sizeof(GLubyte) * size * size, "load_tex"); if (br->mtex.tex) pool = BKE_image_pool_new(); @@ -205,7 +213,6 @@ static int load_tex(Brush *br, ViewContext *vc, float zoom) int index = j * size + i; float x; - float avg; x = (float)i / size; y = (float)j / size; @@ -224,7 +231,7 @@ static int load_tex(Brush *br, ViewContext *vc, float zoom) len = sqrtf(x * x + y * y); - if ((br->mtex.brush_map_mode == MTEX_MAP_MODE_TILED) || len <= 1) { + if (ELEM(br->mtex.brush_map_mode, MTEX_MAP_MODE_TILED, MTEX_MAP_MODE_STENCIL) || len <= 1) { /* it is probably worth optimizing for those cases where * the texture is not rotated by skipping the calls to * atan2, sqrtf, sin, and cos. */ @@ -241,17 +248,40 @@ static int load_tex(Brush *br, ViewContext *vc, float zoom) x += br->mtex.ofs[0]; y += br->mtex.ofs[1]; - avg = br->mtex.tex ? paint_get_tex_pixel(br, x, y, pool) : 1; + if (col) { + float rgba[4]; - avg += br->texture_sample_bias; + if (br->mtex.tex) + paint_get_tex_pixel_col(&br->mtex, x, y, rgba, pool); - if (br->mtex.brush_map_mode == MTEX_MAP_MODE_VIEW) - avg *= BKE_brush_curve_strength(br, len, 1); /* Falloff curve */ + if (br->mtex.brush_map_mode == MTEX_MAP_MODE_VIEW) + mul_v4_fl(rgba, BKE_brush_curve_strength(br, len, 1)); /* Falloff curve */ + + buffer[index*4] = rgba[0]*255; + buffer[index*4 + 1] = rgba[1]*255; + buffer[index*4 + 2] = rgba[2]*255; + buffer[index*4 + 3] = rgba[3]*255; + } + else { + float avg = br->mtex.tex ? paint_get_tex_pixel(&br->mtex, x, y, pool) : 1; - buffer[index] = 255 - (GLubyte)(255 * avg); + avg += br->texture_sample_bias; + + if (br->mtex.brush_map_mode == MTEX_MAP_MODE_VIEW) + avg *= BKE_brush_curve_strength(br, len, 1); /* Falloff curve */ + + buffer[index] = 255 - (GLubyte)(255 * avg); + } } else { - buffer[index] = 0; + if (col) { + buffer[index*4] = 0; + buffer[index*4 + 1] = 0; + buffer[index*4 + 2] = 0; + buffer[index*4 + 3] = 0; + } + else + buffer[index] = 0; } } } @@ -269,16 +299,18 @@ static int load_tex(Brush *br, ViewContext *vc, float zoom) glBindTexture(GL_TEXTURE_2D, overlay_texture); if (refresh) { - if (!init) { - glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, size, size, 0, GL_ALPHA, GL_UNSIGNED_BYTE, buffer); + if (!init || (old_col != col)) { + glTexImage2D(GL_TEXTURE_2D, 0, format, size, size, 0, format, GL_UNSIGNED_BYTE, buffer); init = 1; } else { - glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, size, size, GL_ALPHA, GL_UNSIGNED_BYTE, buffer); + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, size, size, format, GL_UNSIGNED_BYTE, buffer); } if (buffer) MEM_freeN(buffer); + + old_col = col; } glEnable(GL_TEXTURE_2D); @@ -385,17 +417,21 @@ static int sculpt_get_brush_geometry(bContext *C, ViewContext *vc, * have on brush strength */ /* TODO: sculpt only for now */ static void paint_draw_alpha_overlay(UnifiedPaintSettings *ups, Brush *brush, - ViewContext *vc, int x, int y, float zoom) + ViewContext *vc, int x, int y, float zoom, PaintMode mode) { rctf quad; - + bool col; /* check for overlay mode */ - if (!(brush->flag & BRUSH_TEXTURE_OVERLAY) || - !(ELEM(brush->mtex.brush_map_mode, MTEX_MAP_MODE_VIEW, MTEX_MAP_MODE_TILED))) + + if (brush->mtex.brush_map_mode != MTEX_MAP_MODE_STENCIL && + (!(brush->flag & BRUSH_TEXTURE_OVERLAY) || + !ELEM(brush->mtex.brush_map_mode, MTEX_MAP_MODE_VIEW, MTEX_MAP_MODE_TILED))) { return; } + col = ELEM3(mode, PAINT_TEXTURE_PROJECTIVE, PAINT_TEXTURE_2D, PAINT_VERTEX)? + true: false; /* save lots of GL state * TODO: check on whether all of these are needed? */ glPushAttrib(GL_COLOR_BUFFER_BIT | @@ -409,7 +445,7 @@ static void paint_draw_alpha_overlay(UnifiedPaintSettings *ups, Brush *brush, GL_VIEWPORT_BIT | GL_TEXTURE_BIT); - if (load_tex(brush, vc, zoom)) { + if (load_tex(brush, vc, zoom, col)) { glEnable(GL_BLEND); glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); @@ -449,18 +485,36 @@ static void paint_draw_alpha_overlay(UnifiedPaintSettings *ups, Brush *brush, quad.ymax = y + radius; } } - else { + else if (brush->mtex.brush_map_mode == MTEX_MAP_MODE_TILED){ quad.xmin = 0; quad.ymin = 0; quad.xmax = BLI_rcti_size_x(&vc->ar->winrct); quad.ymax = BLI_rcti_size_y(&vc->ar->winrct); } + else if (brush->mtex.brush_map_mode == MTEX_MAP_MODE_STENCIL) { + quad.xmin = -brush->stencil_dimension[0]; + quad.ymin = -brush->stencil_dimension[1]; + quad.xmax = brush->stencil_dimension[0]; + quad.ymax = brush->stencil_dimension[1]; + + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + glTranslatef(brush->stencil_pos[0], brush->stencil_pos[1], 0); + glRotatef(brush->mtex.rot/M_PI*180, 0, 0, 1); + glMatrixMode(GL_TEXTURE); + } - /* set quad color */ - glColor4f(U.sculpt_paint_overlay_col[0], - U.sculpt_paint_overlay_col[1], - U.sculpt_paint_overlay_col[2], - brush->texture_overlay_alpha / 100.0f); + /* set quad color. Colored overlay does not get blending */ + if (col) + glColor4f(1.0, + 1.0, + 1.0, + brush->texture_overlay_alpha / 100.0f); + else + glColor4f(U.sculpt_paint_overlay_col[0], + U.sculpt_paint_overlay_col[1], + U.sculpt_paint_overlay_col[2], + brush->texture_overlay_alpha / 100.0f); /* draw textured quad */ glBegin(GL_QUADS); @@ -475,6 +529,11 @@ static void paint_draw_alpha_overlay(UnifiedPaintSettings *ups, Brush *brush, glEnd(); glPopMatrix(); + + if (brush->mtex.brush_map_mode == MTEX_MAP_MODE_STENCIL) { + glMatrixMode(GL_MODELVIEW); + glPopMatrix(); + } } glPopAttrib(); @@ -519,6 +578,7 @@ static void paint_draw_cursor(bContext *C, int x, int y, void *UNUSED(unused)) Paint *paint = paint_get_active_from_context(C); Brush *brush = paint_brush(paint); ViewContext vc; + PaintMode mode; float final_radius; float translation[2]; float outline_alpha, *outline_col; @@ -534,6 +594,7 @@ static void paint_draw_cursor(bContext *C, int x, int y, void *UNUSED(unused)) get_imapaint_zoom(C, &zoomx, &zoomy); zoomx = max_ff(zoomx, zoomy); + mode = paintmode_get_active_from_context(C); /* set various defaults */ translation[0] = x; @@ -549,7 +610,7 @@ static void paint_draw_cursor(bContext *C, int x, int y, void *UNUSED(unused)) ups->brush_rotation = 0.0; /* draw overlay */ - paint_draw_alpha_overlay(ups, brush, &vc, x, y, zoomx); + paint_draw_alpha_overlay(ups, brush, &vc, x, y, zoomx, mode); /* TODO: as sculpt and other paint modes are unified, this * special mode of drawing will go away */ diff --git a/source/blender/editors/sculpt_paint/paint_intern.h b/source/blender/editors/sculpt_paint/paint_intern.h index cfc40a826dd..8b1de32f1ea 100644 --- a/source/blender/editors/sculpt_paint/paint_intern.h +++ b/source/blender/editors/sculpt_paint/paint_intern.h @@ -39,6 +39,7 @@ struct Brush; struct ImagePool; struct ListBase; struct Mesh; +struct MTex; struct Object; struct PaintStroke; struct Paint; @@ -179,7 +180,8 @@ void paint_calc_redraw_planes(float planes[4][4], void projectf(struct bglMats *mats, const float v[3], float p[2]); float paint_calc_object_space_radius(struct ViewContext *vc, const float center[3], float pixel_radius); -float paint_get_tex_pixel(struct Brush *br, float u, float v, struct ImagePool *pool); +float paint_get_tex_pixel(struct MTex *mtex, float u, float v, struct ImagePool *pool); +void paint_get_tex_pixel_col(struct MTex *mtex, float u, float v, float rgba[4], struct ImagePool *pool); int imapaint_pick_face(struct ViewContext *vc, const int mval[2], unsigned int *index, unsigned int totface); void imapaint_pick_uv(struct Scene *scene, struct Object *ob, unsigned int faceindex, const int xy[2], float uv[2]); void brush_drawcursor_texpaint_uvsculpt(struct bContext *C, int x, int y, void *customdata); @@ -204,7 +206,7 @@ int facemask_paint_poll(struct bContext *C); typedef enum BrushStrokeMode { BRUSH_STROKE_NORMAL, BRUSH_STROKE_INVERT, - BRUSH_STROKE_SMOOTH, + BRUSH_STROKE_SMOOTH } BrushStrokeMode; /* paint_undo.c */ diff --git a/source/blender/editors/sculpt_paint/paint_ops.c b/source/blender/editors/sculpt_paint/paint_ops.c index 120d0a3b10a..7ea11cc464a 100644 --- a/source/blender/editors/sculpt_paint/paint_ops.c +++ b/source/blender/editors/sculpt_paint/paint_ops.c @@ -28,6 +28,7 @@ #include "BLI_listbase.h" #include "BLI_string.h" #include "BLI_utildefines.h" +#include "BLI_math_vector.h" #include "DNA_object_types.h" #include "DNA_scene_types.h" @@ -307,11 +308,7 @@ static int brush_select_exec(bContext *C, wmOperator *op) Object *ob = CTX_data_active_object(C); if (ob) { /* select current paint mode */ - paint_mode = ob->mode & - (OB_MODE_SCULPT | - OB_MODE_VERTEX_PAINT | - OB_MODE_WEIGHT_PAINT | - OB_MODE_TEXTURE_PAINT); + paint_mode = ob->mode & OB_MODE_ALL_PAINT; } else { return OPERATOR_CANCELLED; @@ -448,6 +445,158 @@ static void BRUSH_OT_uv_sculpt_tool_set(wmOperatorType *ot) ot->prop = RNA_def_enum(ot->srna, "tool", uv_sculpt_tool_items, 0, "Tool", ""); } +/***** Stencil Control *****/ + +enum { +STENCIL_TRANSLATE, +STENCIL_SCALE, +STENCIL_ROTATE +} StencilControlMode; + +typedef struct { + int init_mouse[2]; + int init_spos[2]; + int init_sdim[2]; + float init_rot; + float init_angle; + float lenorig; + int mode; + Brush *br; +} StencilControlData; + +static int stencil_control_invoke(bContext *C, wmOperator *op, const wmEvent *event) +{ + Paint *paint = paint_get_active_from_context(C); + Brush *br = paint->brush; + int mdiff[2]; + + StencilControlData *scd = MEM_mallocN(sizeof(StencilControlData), "stencil_control"); + + copy_v2_v2_int(scd->init_mouse, event->mval); + copy_v2_v2_int(scd->init_sdim, br->stencil_dimension); + copy_v2_v2_int(scd->init_spos, br->stencil_pos); + sub_v2_v2v2_int(mdiff, event->mval, br->stencil_pos); + scd->lenorig = sqrtf(mdiff[0]*mdiff[0] + mdiff[1]*mdiff[1]); + scd->br = br; + scd->init_rot = br->mtex.rot; + scd->init_angle = atan2(mdiff[1], mdiff[0]); + scd->mode = RNA_enum_get(op->ptr, "mode"); + + op->customdata = scd; + WM_event_add_modal_handler(C, op); + + return OPERATOR_RUNNING_MODAL; +} + + +static int stencil_control_cancel(bContext *UNUSED(C), wmOperator *op) +{ + StencilControlData *scd = op->customdata; + Brush *br = scd->br; + + copy_v2_v2_int(br->stencil_dimension, scd->init_sdim); + copy_v2_v2_int(br->stencil_pos, scd->init_spos); + br->mtex.rot = scd->init_rot; + MEM_freeN(op->customdata); + return OPERATOR_CANCELLED; +} + +static int stencil_control_modal(bContext *C, wmOperator *op, const wmEvent *event) +{ + StencilControlData *scd = op->customdata; + + switch (event->type) { + case MOUSEMOVE: + { + int mdiff[2]; + switch (scd->mode) { + case STENCIL_TRANSLATE: + sub_v2_v2v2_int(mdiff, event->mval, scd->init_mouse); + add_v2_v2v2_int(scd->br->stencil_pos, scd->init_spos, + mdiff); + break; + case STENCIL_SCALE: + { + float len, factor; + sub_v2_v2v2_int(mdiff, event->mval, scd->br->stencil_pos); + len = sqrtf(mdiff[0]*mdiff[0] + mdiff[1]*mdiff[1]); + factor = len/scd->lenorig; + mdiff[0] = factor*scd->init_sdim[0]; + mdiff[1] = factor*scd->init_sdim[1]; + copy_v2_v2_int(scd->br->stencil_dimension, mdiff); + break; + } + case STENCIL_ROTATE: + { + float angle; + sub_v2_v2v2_int(mdiff, event->mval, scd->br->stencil_pos); + angle = atan2(mdiff[1], mdiff[0]); + angle = scd->init_rot + angle - scd->init_angle; + if (angle < 0) + angle += 2*M_PI; + if (angle > 2*M_PI) + angle -= 2*M_PI; + scd->br->mtex.rot = angle; + break; + } + } + } + break; + case LEFTMOUSE: + if(event->val == KM_PRESS) { + MEM_freeN(op->customdata); + return OPERATOR_FINISHED; + } + case RIGHTMOUSE: + if(event->val == KM_PRESS) { + return stencil_control_cancel(C, op); + } + default: + break; + } + + ED_region_tag_redraw(CTX_wm_region(C)); + + return OPERATOR_RUNNING_MODAL; +} + +static void BRUSH_OT_stencil_control(wmOperatorType *ot) +{ + static EnumPropertyItem stencil_control_items[] = { + {STENCIL_TRANSLATE, "TRANSLATION", 0, "Transation", ""}, + {STENCIL_SCALE, "SCALE", 0, "Scale", ""}, + {STENCIL_ROTATE, "ROTATION", 0, "Rotation", ""}, + {0, NULL, 0, NULL, NULL} + }; + /* identifiers */ + ot->name = "Stencil Brush Control"; + ot->description = "Control the stencil brush"; + ot->idname = "BRUSH_OT_stencil_control"; + + /* api callbacks */ + ot->invoke = stencil_control_invoke; + ot->modal = stencil_control_modal; + ot->cancel = stencil_control_cancel; + + /* flags */ + ot->flag = 0; + + RNA_def_enum(ot->srna, "mode", stencil_control_items, 0, "Tool", ""); +} + +static void ed_keymap_stencil(wmKeyMap *keymap) +{ + wmKeyMapItem *kmi; + + kmi = WM_keymap_add_item(keymap, "BRUSH_OT_stencil_control", QKEY, KM_PRESS, 0, 0); + RNA_enum_set(kmi->ptr, "mode", STENCIL_TRANSLATE); + kmi = WM_keymap_add_item(keymap, "BRUSH_OT_stencil_control", QKEY, KM_PRESS, KM_SHIFT, 0); + RNA_enum_set(kmi->ptr, "mode", STENCIL_SCALE); + kmi = WM_keymap_add_item(keymap, "BRUSH_OT_stencil_control", QKEY, KM_PRESS, KM_CTRL, 0); + RNA_enum_set(kmi->ptr, "mode", STENCIL_ROTATE); + +} + /**************************** registration **********************************/ void ED_operatortypes_paint(void) @@ -457,6 +606,7 @@ void ED_operatortypes_paint(void) WM_operatortype_append(BRUSH_OT_scale_size); WM_operatortype_append(BRUSH_OT_curve_preset); WM_operatortype_append(BRUSH_OT_reset); + WM_operatortype_append(BRUSH_OT_stencil_control); /* note, particle uses a different system, can be added with existing operators in wm.py */ WM_operatortype_append(PAINT_OT_brush_select); @@ -671,6 +821,8 @@ void ED_keymap_paint(wmKeyConfig *keyconf) ed_keymap_paint_brush_size(keymap, "tool_settings.sculpt.brush.size"); ed_keymap_paint_brush_radial_control(keymap, "sculpt", RC_ROTATION); + ed_keymap_stencil(keymap); + keymap_brush_select(keymap, OB_MODE_SCULPT, SCULPT_TOOL_DRAW, DKEY, 0); keymap_brush_select(keymap, OB_MODE_SCULPT, SCULPT_TOOL_SMOOTH, SKEY, 0); keymap_brush_select(keymap, OB_MODE_SCULPT, SCULPT_TOOL_PINCH, PKEY, 0); @@ -687,7 +839,7 @@ void ED_keymap_paint(wmKeyConfig *keyconf) /* */ kmi = WM_keymap_add_item(keymap, "WM_OT_context_menu_enum", AKEY, KM_PRESS, 0, 0); - RNA_string_set(kmi->ptr, "data_path", "tool_settings.sculpt.brush.stroke_method"); + RNA_string_set(kmi->ptr, "data_path", "tool_settings.sculpt.brush.sculpt_stroke_method"); kmi = WM_keymap_add_item(keymap, "WM_OT_context_toggle", SKEY, KM_PRESS, KM_SHIFT, 0); RNA_string_set(kmi->ptr, "data_path", "tool_settings.sculpt.brush.use_smooth_stroke"); @@ -709,6 +861,8 @@ void ED_keymap_paint(wmKeyConfig *keyconf) ed_keymap_paint_brush_size(keymap, "tool_settings.vertex_paint.brush.size"); ed_keymap_paint_brush_radial_control(keymap, "vertex_paint", RC_COLOR | RC_ROTATION); + ed_keymap_stencil(keymap); + kmi = WM_keymap_add_item(keymap, "WM_OT_context_toggle", MKEY, KM_PRESS, 0, 0); /* mask toggle */ RNA_string_set(kmi->ptr, "data_path", "vertex_paint_object.data.use_paint_mask"); @@ -718,6 +872,9 @@ void ED_keymap_paint(wmKeyConfig *keyconf) kmi = WM_keymap_add_item(keymap, "WM_OT_context_menu_enum", RKEY, KM_PRESS, 0, 0); RNA_string_set(kmi->ptr, "data_path", "tool_settings.vertex_paint.brush.texture_angle_source_random"); + kmi = WM_keymap_add_item(keymap, "WM_OT_context_menu_enum", AKEY, KM_PRESS, 0, 0); + RNA_string_set(kmi->ptr, "data_path", "tool_settings.vertex_paint.brush.stroke_method"); + /* Weight Paint mode */ keymap = WM_keymap_find(keyconf, "Weight Paint", 0, 0); keymap->poll = weight_paint_mode_poll; @@ -738,6 +895,11 @@ void ED_keymap_paint(wmKeyConfig *keyconf) ed_keymap_paint_brush_size(keymap, "tool_settings.weight_paint.brush.size"); ed_keymap_paint_brush_radial_control(keymap, "weight_paint", 0); + ed_keymap_stencil(keymap); + + kmi = WM_keymap_add_item(keymap, "WM_OT_context_menu_enum", AKEY, KM_PRESS, 0, 0); + RNA_string_set(kmi->ptr, "data_path", "tool_settings.vertex_paint.brush.stroke_method"); + kmi = WM_keymap_add_item(keymap, "WM_OT_context_toggle", MKEY, KM_PRESS, 0, 0); /* face mask toggle */ RNA_string_set(kmi->ptr, "data_path", "weight_paint_object.data.use_paint_mask"); @@ -776,6 +938,8 @@ void ED_keymap_paint(wmKeyConfig *keyconf) ed_keymap_paint_brush_size(keymap, "tool_settings.image_paint.brush.size"); ed_keymap_paint_brush_radial_control(keymap, "image_paint", RC_COLOR | RC_ZOOM | RC_ROTATION); + ed_keymap_stencil(keymap); + kmi = WM_keymap_add_item(keymap, "WM_OT_context_toggle", MKEY, KM_PRESS, 0, 0); /* mask toggle */ RNA_string_set(kmi->ptr, "data_path", "image_paint_object.data.use_paint_mask"); @@ -785,6 +949,9 @@ void ED_keymap_paint(wmKeyConfig *keyconf) kmi = WM_keymap_add_item(keymap, "WM_OT_context_menu_enum", RKEY, KM_PRESS, 0, 0); RNA_string_set(kmi->ptr, "data_path", "tool_settings.image_paint.brush.texture_angle_source_random"); + kmi = WM_keymap_add_item(keymap, "WM_OT_context_menu_enum", AKEY, KM_PRESS, 0, 0); + RNA_string_set(kmi->ptr, "data_path", "tool_settings.image_paint.brush.stroke_method"); + /* face-mask mode */ keymap = WM_keymap_find(keyconf, "Face Mask", 0, 0); keymap->poll = facemask_paint_poll; diff --git a/source/blender/editors/sculpt_paint/paint_utils.c b/source/blender/editors/sculpt_paint/paint_utils.c index 1dadef1e0a4..47e20bcc5fb 100644 --- a/source/blender/editors/sculpt_paint/paint_utils.c +++ b/source/blender/editors/sculpt_paint/paint_utils.c @@ -59,6 +59,7 @@ #include "BIF_glutil.h" #include "RE_shader_ext.h" +#include "RE_render_ext.h" #include "ED_view3d.h" #include "ED_screen.h" @@ -176,13 +177,13 @@ float paint_calc_object_space_radius(ViewContext *vc, const float center[3], return len_v3(delta) / scale; } -float paint_get_tex_pixel(Brush *br, float u, float v, struct ImagePool *pool) +float paint_get_tex_pixel(MTex *mtex, float u, float v, struct ImagePool *pool) { TexResult texres = {0}; float co[3] = {u, v, 0.0f}; int hasrgb; - hasrgb = multitex_ext(br->mtex.tex, co, NULL, NULL, 0, &texres, pool); + hasrgb = multitex_ext(mtex->tex, co, NULL, NULL, 0, &texres, pool); if (hasrgb & TEX_RGB) texres.tin = rgb_to_grayscale(&texres.tr) * texres.ta; @@ -190,6 +191,23 @@ float paint_get_tex_pixel(Brush *br, float u, float v, struct ImagePool *pool) return texres.tin; } +void paint_get_tex_pixel_col(MTex *mtex, float u, float v, float rgba[4], struct ImagePool *pool) +{ + float co[3] = {u, v, 0.0f}; + int hasrgb; + float intensity; + + hasrgb = externtex(mtex, co, &intensity, + rgba, rgba + 1, rgba + 2, rgba + 3, 0, pool); + + if (!hasrgb) { + rgba[0] = intensity; + rgba[1] = intensity; + rgba[2] = intensity; + rgba[3] = 1.0f; + } +} + /* 3D Paint */ static void imapaint_project(Object *ob, float model[4][4], float proj[4][4], const float co[3], float pco[4]) diff --git a/source/blender/editors/sculpt_paint/paint_vertex.c b/source/blender/editors/sculpt_paint/paint_vertex.c index 197231124fc..061f073b287 100644 --- a/source/blender/editors/sculpt_paint/paint_vertex.c +++ b/source/blender/editors/sculpt_paint/paint_vertex.c @@ -866,6 +866,7 @@ static float calc_vp_strength_col_dl(VPaint *vp, ViewContext *vc, const float co { float delta[2]; float dist_squared; + float factor = 1.0; sub_v2_v2v2(delta, mval, co_ss); dist_squared = dot_v2v2(delta, delta); /* len squared */ @@ -880,8 +881,9 @@ static float calc_vp_strength_col_dl(VPaint *vp, ViewContext *vc, const float co const float co_ss_3d[3] = {co_ss[0], co_ss[1], 0.0f}; /* we need a 3rd empty value */ BKE_brush_sample_tex_3D(vc->scene, brush, co_ss_3d, rgba, 0, NULL); } + factor = rgba[3]; } - return BKE_brush_curve_strength_clamp(brush, dist, brush_size_pressure); + return factor*BKE_brush_curve_strength_clamp(brush, dist, brush_size_pressure); } } if (rgba) diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c index 5a6bc823dc0..9bb7760fcc0 100644 --- a/source/blender/editors/sculpt_paint/sculpt.c +++ b/source/blender/editors/sculpt_paint/sculpt.c @@ -968,7 +968,7 @@ static float tex_strength(SculptSession *ss, Brush *br, x += br->mtex.ofs[0]; y += br->mtex.ofs[1]; - avg = paint_get_tex_pixel(br, x, y, ss->tex_pool); + avg = paint_get_tex_pixel(&br->mtex, x, y, ss->tex_pool); avg += br->texture_sample_bias; } |