diff options
Diffstat (limited to 'source/blender/editors/sculpt_paint/paint_ops.c')
-rw-r--r-- | source/blender/editors/sculpt_paint/paint_ops.c | 179 |
1 files changed, 173 insertions, 6 deletions
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; |