diff options
author | Antony Riakiotakis <kalast@gmail.com> | 2013-04-23 04:06:22 +0400 |
---|---|---|
committer | Antony Riakiotakis <kalast@gmail.com> | 2013-04-23 04:06:22 +0400 |
commit | 157244b13cf61d5889f5714167c6e5468ae35b15 (patch) | |
tree | e59778ab61ab8bf8823d245e96ed99885ed5729b /source/blender/editors/sculpt_paint/paint_ops.c | |
parent | 0d14a1414c1c36f0e887c11de137f8b32a788852 (diff) |
Add stencil control for mask overlay. Key combinations are the same as
regular stencil but use Alt as well, so Alt-Rclick is translation, Alt-
clamping to avoid scaling of stencil to zero.
Diffstat (limited to 'source/blender/editors/sculpt_paint/paint_ops.c')
-rw-r--r-- | source/blender/editors/sculpt_paint/paint_ops.c | 132 |
1 files changed, 101 insertions, 31 deletions
diff --git a/source/blender/editors/sculpt_paint/paint_ops.c b/source/blender/editors/sculpt_paint/paint_ops.c index ae49fbcbc95..f0265fd4e69 100644 --- a/source/blender/editors/sculpt_paint/paint_ops.c +++ b/source/blender/editors/sculpt_paint/paint_ops.c @@ -451,14 +451,20 @@ static void BRUSH_OT_uv_sculpt_tool_set(wmOperatorType *ot) /***** Stencil Control *****/ typedef enum { -STENCIL_TRANSLATE, -STENCIL_SCALE, -STENCIL_ROTATE + STENCIL_TRANSLATE, + STENCIL_SCALE, + STENCIL_ROTATE } StencilControlMode; typedef enum { -STENCIL_CONSTRAINT_X = 1, -STENCIL_CONSTRAINT_Y = 2 + STENCIL_PRIMARY = 0, + STENCIL_SECONDARY = 1 +} StencilTextureMode; + + +typedef enum { + STENCIL_CONSTRAINT_X = 1, + STENCIL_CONSTRAINT_Y = 2 } StencilConstraint; typedef struct { @@ -471,48 +477,92 @@ typedef struct { float area_size[2]; StencilControlMode mode; StencilConstraint constrain_mode; + int mask; /* we are twaking mask or colour stencil */ Brush *br; + float *dim_target; + float *rot_target; + float *pos_target; short event_type; } StencilControlData; +static void stencil_set_target(StencilControlData *scd) +{ + Brush *br = scd->br; + float mdiff[2]; + if (scd->mask) { + copy_v2_v2(scd->init_sdim, br->mask_stencil_dimension); + copy_v2_v2(scd->init_spos, br->mask_stencil_pos); + scd->init_rot = br->mask_mtex.rot; + + scd->dim_target = br->mask_stencil_dimension; + scd->rot_target = &br->mask_mtex.rot; + scd->pos_target = br->mask_stencil_pos; + } else { + copy_v2_v2(scd->init_sdim, br->stencil_dimension); + copy_v2_v2(scd->init_spos, br->stencil_pos); + scd->init_rot = br->mtex.rot; + + scd->dim_target = br->stencil_dimension; + scd->rot_target = &br->mtex.rot; + scd->pos_target = br->stencil_pos; + } + + sub_v2_v2v2(mdiff, scd->init_mouse, br->stencil_pos); + scd->lenorig = len_v2(mdiff); + + scd->init_angle = atan2(mdiff[1], mdiff[0]); +} + static int stencil_control_invoke(bContext *C, wmOperator *op, const wmEvent *event) { Paint *paint = BKE_paint_get_active_from_context(C); Brush *br = BKE_paint_brush(paint); - float mdiff[2]; float mvalf[2] = {event->mval[0], event->mval[1]}; ARegion *ar = CTX_wm_region(C); + StencilControlData *scd; + int mask = RNA_enum_get(op->ptr, "texmode"); + + if (mask) { + if (br->mask_mtex.brush_map_mode != MTEX_MAP_MODE_STENCIL) + return OPERATOR_CANCELLED; + } + else { + if (br->mtex.brush_map_mode != MTEX_MAP_MODE_STENCIL) + return OPERATOR_CANCELLED; + } - StencilControlData *scd = MEM_mallocN(sizeof(StencilControlData), "stencil_control"); + scd = MEM_mallocN(sizeof(StencilControlData), "stencil_control"); + scd->mask = mask; + scd->br = br; copy_v2_v2(scd->init_mouse, mvalf); - copy_v2_v2(scd->init_sdim, br->stencil_dimension); - copy_v2_v2(scd->init_spos, br->stencil_pos); - sub_v2_v2v2(mdiff, mvalf, br->stencil_pos); - scd->lenorig = len_v2(mdiff); - scd->br = br; - scd->init_rot = br->mtex.rot; - scd->init_angle = atan2(mdiff[1], mdiff[0]); + + stencil_set_target(scd); + scd->mode = RNA_enum_get(op->ptr, "mode"); scd->event_type = event->type; scd->area_size[0] = ar->winx; scd->area_size[1] = ar->winy; + op->customdata = scd; WM_event_add_modal_handler(C, op); return OPERATOR_RUNNING_MODAL; } +static void stencil_restore(StencilControlData *scd) +{ + copy_v2_v2(scd->dim_target, scd->init_sdim); + copy_v2_v2(scd->pos_target, scd->init_spos); + *scd->rot_target = scd->init_rot; +} static int stencil_control_cancel(bContext *UNUSED(C), wmOperator *op) { StencilControlData *scd = op->customdata; - Brush *br = scd->br; - copy_v2_v2(br->stencil_dimension, scd->init_sdim); - copy_v2_v2(br->stencil_pos, scd->init_spos); - br->mtex.rot = scd->init_rot; + stencil_restore(scd); MEM_freeN(op->customdata); return OPERATOR_CANCELLED; } @@ -526,21 +576,21 @@ static void stencil_control_calculate(StencilControlData *scd, const int mval[2] switch (scd->mode) { case STENCIL_TRANSLATE: sub_v2_v2v2(mdiff, mvalf, scd->init_mouse); - add_v2_v2v2(scd->br->stencil_pos, scd->init_spos, + add_v2_v2v2(scd->pos_target, scd->init_spos, mdiff); - CLAMP(scd->br->stencil_pos[0], - -scd->br->stencil_dimension[0] + PIXEL_MARGIN, - scd->area_size[0] + scd->br->stencil_dimension[0] - PIXEL_MARGIN); + CLAMP(scd->pos_target[0], + -scd->dim_target[0] + PIXEL_MARGIN, + scd->area_size[0] + scd->dim_target[0] - PIXEL_MARGIN); - CLAMP(scd->br->stencil_pos[1], - -scd->br->stencil_dimension[1] + PIXEL_MARGIN, - scd->area_size[1] + scd->br->stencil_dimension[1] - PIXEL_MARGIN); + CLAMP(scd->pos_target[1], + -scd->dim_target[1] + PIXEL_MARGIN, + scd->area_size[1] + scd->dim_target[1] - PIXEL_MARGIN); break; case STENCIL_SCALE: { float len, factor; - sub_v2_v2v2(mdiff, mvalf, scd->br->stencil_pos); + sub_v2_v2v2(mdiff, mvalf, scd->pos_target); len = len_v2(mdiff); factor = len / scd->lenorig; copy_v2_v2(mdiff, scd->init_sdim); @@ -548,20 +598,22 @@ static void stencil_control_calculate(StencilControlData *scd, const int mval[2] mdiff[0] = factor * scd->init_sdim[0]; if (scd->constrain_mode != STENCIL_CONSTRAINT_X) mdiff[1] = factor * scd->init_sdim[1]; - copy_v2_v2(scd->br->stencil_dimension, mdiff); + CLAMP(mdiff[0], 5.0, 10000); + CLAMP(mdiff[1], 5.0, 10000); + copy_v2_v2(scd->dim_target, mdiff); break; } case STENCIL_ROTATE: { float angle; - sub_v2_v2v2(mdiff, mvalf, scd->br->stencil_pos); + sub_v2_v2v2(mdiff, mvalf, scd->pos_target); angle = atan2(mdiff[1], mdiff[0]); angle = scd->init_rot + angle - scd->init_angle; if (angle < 0.0f) angle += (float)(2 * M_PI); if (angle > (float)(2 * M_PI)) angle -= (float)(2 * M_PI); - scd->br->mtex.rot = angle; + *scd->rot_target = angle; break; } } @@ -623,7 +675,9 @@ static int stencil_control_poll(bContext *C) Paint *paint = BKE_paint_get_active_from_context(C); Brush *br = BKE_paint_brush(paint); - return (br && br->mtex.brush_map_mode == MTEX_MAP_MODE_STENCIL); + return (br && + (br->mtex.brush_map_mode == MTEX_MAP_MODE_STENCIL || + br->mask_mtex.brush_map_mode == MTEX_MAP_MODE_STENCIL)); } static void BRUSH_OT_stencil_control(wmOperatorType *ot) @@ -634,6 +688,12 @@ static void BRUSH_OT_stencil_control(wmOperatorType *ot) {STENCIL_ROTATE, "ROTATION", 0, "Rotation", ""}, {0, NULL, 0, NULL, NULL} }; + + static EnumPropertyItem stencil_texture_items[] = { + {STENCIL_PRIMARY, "PRIMARY", 0, "Primary", ""}, + {STENCIL_SECONDARY, "SECONDARY", 0, "Secondary", ""}, + {0, NULL, 0, NULL, NULL} + }; /* identifiers */ ot->name = "Stencil Brush Control"; ot->description = "Control the stencil brush"; @@ -648,7 +708,8 @@ static void BRUSH_OT_stencil_control(wmOperatorType *ot) /* flags */ ot->flag = 0; - RNA_def_enum(ot->srna, "mode", stencil_control_items, 0, "Tool", ""); + RNA_def_enum(ot->srna, "mode", stencil_control_items, STENCIL_TRANSLATE, "Tool", ""); + RNA_def_enum(ot->srna, "texmode", stencil_texture_items, STENCIL_PRIMARY, "Tool", ""); } @@ -721,6 +782,15 @@ static void ed_keymap_stencil(wmKeyMap *keymap) kmi = WM_keymap_add_item(keymap, "BRUSH_OT_stencil_control", RIGHTMOUSE, KM_PRESS, KM_CTRL, 0); RNA_enum_set(kmi->ptr, "mode", STENCIL_ROTATE); + kmi = WM_keymap_add_item(keymap, "BRUSH_OT_stencil_control", RIGHTMOUSE, KM_PRESS, KM_ALT, 0); + RNA_enum_set(kmi->ptr, "mode", STENCIL_TRANSLATE); + RNA_enum_set(kmi->ptr, "texmode", STENCIL_SECONDARY); + kmi = WM_keymap_add_item(keymap, "BRUSH_OT_stencil_control", RIGHTMOUSE, KM_PRESS, KM_SHIFT | KM_ALT, 0); + RNA_enum_set(kmi->ptr, "texmode", STENCIL_SECONDARY); + RNA_enum_set(kmi->ptr, "mode", STENCIL_SCALE); + kmi = WM_keymap_add_item(keymap, "BRUSH_OT_stencil_control", RIGHTMOUSE, KM_PRESS, KM_CTRL | KM_ALT, 0); + RNA_enum_set(kmi->ptr, "texmode", STENCIL_SECONDARY); + RNA_enum_set(kmi->ptr, "mode", STENCIL_ROTATE); } /**************************** registration **********************************/ |