diff options
author | Jeroen Bakker <jeroen@blender.org> | 2022-02-22 15:42:44 +0300 |
---|---|---|
committer | Jeroen Bakker <jeroen@blender.org> | 2022-02-22 15:42:44 +0300 |
commit | 0b4c56b01078b70b294208932d1e1d37a1ab3bd2 (patch) | |
tree | 1d43b9c0eaf1040404f14aacd6bb4098af56b887 /source/blender/editors/sculpt_paint/paint_image.cc | |
parent | 683a77256dc8845955a8592a730457e0bdc3c10c (diff) |
Cleanup: Replace eTexPaintMode with classes.
For an upcoming prototype we would introduced a new eTexPaintMode
option. That would add more cases and if statements. This change migrate
the eTexPaintMode to 3 classes. AbstractPaintMode contains a shared interface.
ImagePaintMode for 2d painting and ProjectionPaintMode for 3d painting.
Diffstat (limited to 'source/blender/editors/sculpt_paint/paint_image.cc')
-rw-r--r-- | source/blender/editors/sculpt_paint/paint_image.cc | 380 |
1 files changed, 1 insertions, 379 deletions
diff --git a/source/blender/editors/sculpt_paint/paint_image.cc b/source/blender/editors/sculpt_paint/paint_image.cc index eda686d808d..9413f872c3a 100644 --- a/source/blender/editors/sculpt_paint/paint_image.cc +++ b/source/blender/editors/sculpt_paint/paint_image.cc @@ -286,7 +286,7 @@ static bool image_paint_poll_ex(bContext *C, bool check_tool) return false; } -static bool image_paint_poll(bContext *C) +bool image_paint_poll(bContext *C) { return image_paint_poll_ex(C, true); } @@ -312,24 +312,6 @@ static bool image_paint_2d_clone_poll(bContext *C) } /************************ paint operator ************************/ -enum class eTexPaintMode { - _2D, - _3D_PROJECT, -}; - -struct PaintOperation { - eTexPaintMode mode; - - void *stroke_handle; - - float prevmouse[2]; - float startmouse[2]; - double starttime; - - wmPaintCursor *cursor; - ViewContext vc; -}; - bool paint_use_opacity_masking(Brush *brush) { return ((brush->flag & BRUSH_AIRBRUSH) || (brush->flag & BRUSH_DRAG_DOT) || @@ -419,366 +401,6 @@ void paint_brush_exit_tex(Brush *brush) } } -static void gradient_draw_line(bContext *UNUSED(C), int x, int y, void *customdata) -{ - PaintOperation *pop = (PaintOperation *)customdata; - - if (pop) { - GPU_line_smooth(true); - GPU_blend(GPU_BLEND_ALPHA); - - GPUVertFormat *format = immVertexFormat(); - uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_I32, 2, GPU_FETCH_INT_TO_FLOAT); - - ARegion *region = pop->vc.region; - - immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); - - GPU_line_width(4.0); - immUniformColor4ub(0, 0, 0, 255); - - immBegin(GPU_PRIM_LINES, 2); - immVertex2i(pos, x, y); - immVertex2i( - pos, pop->startmouse[0] + region->winrct.xmin, pop->startmouse[1] + region->winrct.ymin); - immEnd(); - - GPU_line_width(2.0); - immUniformColor4ub(255, 255, 255, 255); - - immBegin(GPU_PRIM_LINES, 2); - immVertex2i(pos, x, y); - immVertex2i( - pos, pop->startmouse[0] + region->winrct.xmin, pop->startmouse[1] + region->winrct.ymin); - immEnd(); - - immUnbindProgram(); - - GPU_blend(GPU_BLEND_NONE); - GPU_line_smooth(false); - } -} - -static PaintOperation *texture_paint_init(bContext *C, wmOperator *op, const float mouse[2]) -{ - Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C); - Scene *scene = CTX_data_scene(C); - ToolSettings *settings = scene->toolsettings; - PaintOperation *pop = MEM_cnew<PaintOperation>("PaintOperation"); /* caller frees */ - Brush *brush = BKE_paint_brush(&settings->imapaint.paint); - int mode = RNA_enum_get(op->ptr, "mode"); - ED_view3d_viewcontext_init(C, &pop->vc, depsgraph); - - copy_v2_v2(pop->prevmouse, mouse); - copy_v2_v2(pop->startmouse, mouse); - - /* initialize from context */ - if (CTX_wm_region_view3d(C)) { - ViewLayer *view_layer = CTX_data_view_layer(C); - Object *ob = OBACT(view_layer); - bool uvs, mat, tex, stencil; - if (!ED_paint_proj_mesh_data_check(scene, ob, &uvs, &mat, &tex, &stencil)) { - ED_paint_data_warning(op->reports, uvs, mat, tex, stencil); - MEM_delete(pop); - WM_event_add_notifier(C, NC_SCENE | ND_TOOLSETTINGS, nullptr); - return nullptr; - } - pop->mode = eTexPaintMode::_3D_PROJECT; - pop->stroke_handle = paint_proj_new_stroke(C, ob, mouse, mode); - } - else { - pop->mode = eTexPaintMode::_2D; - pop->stroke_handle = paint_2d_new_stroke(C, op, mode); - } - - if (!pop->stroke_handle) { - MEM_delete(pop); - return nullptr; - } - - if ((brush->imagepaint_tool == PAINT_TOOL_FILL) && (brush->flag & BRUSH_USE_GRADIENT)) { - pop->cursor = WM_paint_cursor_activate( - SPACE_TYPE_ANY, RGN_TYPE_ANY, image_paint_poll, gradient_draw_line, pop); - } - - settings->imapaint.flag |= IMAGEPAINT_DRAWING; - ED_image_undo_push_begin(op->type->name, PAINT_MODE_TEXTURE_2D); - - return pop; -} - -static void paint_stroke_update_step(bContext *C, - wmOperator *UNUSED(op), - struct PaintStroke *stroke, - PointerRNA *itemptr) -{ - PaintOperation *pop = static_cast<PaintOperation *>(paint_stroke_mode_data(stroke)); - Scene *scene = CTX_data_scene(C); - ToolSettings *toolsettings = CTX_data_tool_settings(C); - UnifiedPaintSettings *ups = &toolsettings->unified_paint_settings; - Brush *brush = BKE_paint_brush(&toolsettings->imapaint.paint); - - float alphafac = (brush->flag & BRUSH_ACCUMULATE) ? ups->overlap_factor : 1.0f; - - /* initial brush values. Maybe it should be considered moving these to stroke system */ - float startalpha = BKE_brush_alpha_get(scene, brush); - - float mouse[2]; - float pressure; - float size; - float distance = paint_stroke_distance_get(stroke); - int eraser; - - RNA_float_get_array(itemptr, "mouse", mouse); - pressure = RNA_float_get(itemptr, "pressure"); - eraser = RNA_boolean_get(itemptr, "pen_flip"); - size = RNA_float_get(itemptr, "size"); - - /* stroking with fill tool only acts on stroke end */ - if (brush->imagepaint_tool == PAINT_TOOL_FILL) { - copy_v2_v2(pop->prevmouse, mouse); - return; - } - - if (BKE_brush_use_alpha_pressure(brush)) { - BKE_brush_alpha_set(scene, brush, max_ff(0.0f, startalpha * pressure * alphafac)); - } - else { - BKE_brush_alpha_set(scene, brush, max_ff(0.0f, startalpha * alphafac)); - } - - if ((brush->flag & BRUSH_DRAG_DOT) || (brush->flag & BRUSH_ANCHORED)) { - UndoStack *ustack = CTX_wm_manager(C)->undo_stack; - ED_image_undo_restore(ustack->step_init); - } - - switch (pop->mode) { - case eTexPaintMode::_2D: - paint_2d_stroke(pop->stroke_handle, pop->prevmouse, mouse, eraser, pressure, distance, size); - break; - - case eTexPaintMode::_3D_PROJECT: - paint_proj_stroke( - C, pop->stroke_handle, pop->prevmouse, mouse, eraser, pressure, distance, size); - break; - } - - copy_v2_v2(pop->prevmouse, mouse); - - /* restore brush values */ - BKE_brush_alpha_set(scene, brush, startalpha); -} - -static void paint_stroke_redraw(const bContext *C, struct PaintStroke *stroke, bool final) -{ - PaintOperation *pop = static_cast<PaintOperation *>(paint_stroke_mode_data(stroke)); - - switch (pop->mode) { - case eTexPaintMode::_2D: - paint_2d_redraw(C, pop->stroke_handle, final); - break; - - case eTexPaintMode::_3D_PROJECT: - paint_proj_redraw(C, pop->stroke_handle, final); - break; - } -} - -static void paint_stroke_done(const bContext *C, struct PaintStroke *stroke) -{ - Scene *scene = CTX_data_scene(C); - ToolSettings *toolsettings = scene->toolsettings; - PaintOperation *pop = static_cast<PaintOperation *>(paint_stroke_mode_data(stroke)); - Brush *brush = BKE_paint_brush(&toolsettings->imapaint.paint); - - toolsettings->imapaint.flag &= ~IMAGEPAINT_DRAWING; - - if (brush->imagepaint_tool == PAINT_TOOL_FILL) { - if (brush->flag & BRUSH_USE_GRADIENT) { - switch (pop->mode) { - case eTexPaintMode::_2D: - paint_2d_gradient_fill(C, brush, pop->startmouse, pop->prevmouse, pop->stroke_handle); - break; - - case eTexPaintMode::_3D_PROJECT: - paint_proj_stroke(C, - pop->stroke_handle, - pop->startmouse, - pop->prevmouse, - paint_stroke_flipped(stroke), - 1.0, - 0.0, - BKE_brush_size_get(scene, brush)); - /* two redraws, one for GPU update, one for notification */ - paint_proj_redraw(C, pop->stroke_handle, false); - paint_proj_redraw(C, pop->stroke_handle, true); - break; - } - } - else { - switch (pop->mode) { - case eTexPaintMode::_2D: { - float color[3]; - if (paint_stroke_inverted(stroke)) { - srgb_to_linearrgb_v3_v3(color, BKE_brush_secondary_color_get(scene, brush)); - } - else { - srgb_to_linearrgb_v3_v3(color, BKE_brush_color_get(scene, brush)); - } - paint_2d_bucket_fill( - C, color, brush, pop->startmouse, pop->prevmouse, pop->stroke_handle); - break; - } - - case eTexPaintMode::_3D_PROJECT: - paint_proj_stroke(C, - pop->stroke_handle, - pop->startmouse, - pop->prevmouse, - paint_stroke_flipped(stroke), - 1.0, - 0.0, - BKE_brush_size_get(scene, brush)); - /* two redraws, one for GPU update, one for notification */ - paint_proj_redraw(C, pop->stroke_handle, false); - paint_proj_redraw(C, pop->stroke_handle, true); - break; - } - } - } - - switch (pop->mode) { - case eTexPaintMode::_2D: - paint_2d_stroke_done(pop->stroke_handle); - break; - - case eTexPaintMode::_3D_PROJECT: - paint_proj_stroke_done(pop->stroke_handle); - break; - } - - if (pop->cursor) { - WM_paint_cursor_end(pop->cursor); - } - - ED_image_undo_push_end(); - - /* duplicate warning, see texpaint_init */ -#if 0 - if (pop->s.warnmultifile) { - BKE_reportf(op->reports, - RPT_WARNING, - "Image requires 4 color channels to paint: %s", - pop->s.warnmultifile); - } - if (pop->s.warnpackedfile) { - BKE_reportf(op->reports, - RPT_WARNING, - "Packed MultiLayer files cannot be painted: %s", - pop->s.warnpackedfile); - } -#endif - MEM_delete(pop); -} - -static bool paint_stroke_test_start(bContext *C, wmOperator *op, const float mouse[2]) -{ - PaintOperation *pop; - - /* TODO: Should avoid putting this here. Instead, last position should be requested - * from stroke system. */ - - if (!(pop = texture_paint_init(C, op, mouse))) { - return false; - } - - paint_stroke_set_mode_data(static_cast<PaintStroke *>(op->customdata), pop); - - return true; -} - -static int paint_invoke(bContext *C, wmOperator *op, const wmEvent *event) -{ - int retval; - - op->customdata = paint_stroke_new(C, - op, - nullptr, - paint_stroke_test_start, - paint_stroke_update_step, - paint_stroke_redraw, - paint_stroke_done, - event->type); - - if ((retval = op->type->modal(C, op, event)) == OPERATOR_FINISHED) { - paint_stroke_free(C, op, static_cast<PaintStroke *>(op->customdata)); - return OPERATOR_FINISHED; - } - /* add modal handler */ - WM_event_add_modal_handler(C, op); - - OPERATOR_RETVAL_CHECK(retval); - BLI_assert(retval == OPERATOR_RUNNING_MODAL); - - return OPERATOR_RUNNING_MODAL; -} - -static int paint_exec(bContext *C, wmOperator *op) -{ - PropertyRNA *strokeprop; - PointerRNA firstpoint; - float mouse[2]; - - strokeprop = RNA_struct_find_property(op->ptr, "stroke"); - - if (!RNA_property_collection_lookup_int(op->ptr, strokeprop, 0, &firstpoint)) { - return OPERATOR_CANCELLED; - } - - RNA_float_get_array(&firstpoint, "mouse", mouse); - - op->customdata = paint_stroke_new(C, - op, - nullptr, - paint_stroke_test_start, - paint_stroke_update_step, - paint_stroke_redraw, - paint_stroke_done, - 0); - /* frees op->customdata */ - return paint_stroke_exec(C, op, static_cast<PaintStroke *>(op->customdata)); -} - -static int paint_modal(bContext *C, wmOperator *op, const wmEvent *event) -{ - return paint_stroke_modal(C, op, event, static_cast<PaintStroke *>(op->customdata)); -} - -static void paint_cancel(bContext *C, wmOperator *op) -{ - paint_stroke_cancel(C, op, static_cast<PaintStroke *>(op->customdata)); -} - -void PAINT_OT_image_paint(wmOperatorType *ot) -{ - /* identifiers */ - ot->name = "Image Paint"; - ot->idname = "PAINT_OT_image_paint"; - ot->description = "Paint a stroke into the image"; - - /* api callbacks */ - ot->invoke = paint_invoke; - ot->modal = paint_modal; - ot->exec = paint_exec; - ot->poll = image_paint_poll; - ot->cancel = paint_cancel; - - /* flags */ - ot->flag = OPTYPE_BLOCKING; - - paint_stroke_operator_properties(ot); -} - bool get_imapaint_zoom(bContext *C, float *zoomx, float *zoomy) { ScrArea *area = CTX_wm_area(C); |