diff options
Diffstat (limited to 'source/blender/editors/sculpt_paint')
23 files changed, 995 insertions, 918 deletions
diff --git a/source/blender/editors/sculpt_paint/CMakeLists.txt b/source/blender/editors/sculpt_paint/CMakeLists.txt index 9527dc4fe83..80c58e5b91d 100644 --- a/source/blender/editors/sculpt_paint/CMakeLists.txt +++ b/source/blender/editors/sculpt_paint/CMakeLists.txt @@ -25,6 +25,7 @@ set(INC ../../blenlib ../../blentranslation ../../bmesh + ../../depsgraph ../../gpu ../../imbuf ../../makesdna diff --git a/source/blender/editors/sculpt_paint/paint_cursor.c b/source/blender/editors/sculpt_paint/paint_cursor.c index 769f6116dc6..94111c9939d 100644 --- a/source/blender/editors/sculpt_paint/paint_cursor.c +++ b/source/blender/editors/sculpt_paint/paint_cursor.c @@ -54,14 +54,15 @@ #include "WM_api.h" -#include "BIF_gl.h" -#include "BIF_glutil.h" - #include "IMB_imbuf_types.h" #include "ED_view3d.h" -#include "GPU_basic_shader.h" +#include "GPU_draw.h" +#include "GPU_immediate.h" +#include "GPU_immediate_util.h" +#include "GPU_matrix.h" +#include "GPU_state.h" #include "UI_resources.h" @@ -338,11 +339,12 @@ static int load_tex(Brush *br, ViewContext *vc, float zoom, bool col, bool prima size = target->old_size; } + glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, target->overlay_texture); if (refresh) { - GLenum format = col ? GL_RGBA : GL_ALPHA; - GLenum internalformat = col ? GL_RGBA8 : GL_ALPHA8; + GLenum format = col ? GL_RGBA : GL_RED; + GLenum internalformat = col ? GL_RGBA8 : GL_R8; if (!init || (target->old_col != col)) { glTexImage2D(GL_TEXTURE_2D, 0, internalformat, size, size, 0, format, GL_UNSIGNED_BYTE, buffer); @@ -357,8 +359,6 @@ static int load_tex(Brush *br, ViewContext *vc, float zoom, bool col, bool prima target->old_col = col; } - GPU_basic_shader_bind(GPU_SHADER_TEXTURE_2D | GPU_SHADER_USE_COLOR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); @@ -466,22 +466,21 @@ static int load_tex_cursor(Brush *br, ViewContext *vc, float zoom) size = cursor_snap.size; } + glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, cursor_snap.overlay_texture); if (refresh) { if (!init) { - glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA8, size, size, 0, GL_ALPHA, GL_UNSIGNED_BYTE, buffer); + glTexImage2D(GL_TEXTURE_2D, 0, GL_R8, size, size, 0, GL_RED, GL_UNSIGNED_BYTE, buffer); } 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, GL_RED, GL_UNSIGNED_BYTE, buffer); } if (buffer) MEM_freeN(buffer); } - GPU_basic_shader_bind(GPU_SHADER_TEXTURE_2D | GPU_SHADER_USE_COLOR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); @@ -609,32 +608,33 @@ static void paint_draw_tex_overlay(UnifiedPaintSettings *ups, Brush *brush, } if (load_tex(brush, vc, zoom, col, primary)) { - glEnable(GL_BLEND); + GPU_blend(true); glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); glDepthMask(GL_FALSE); glDepthFunc(GL_ALWAYS); - glMatrixMode(GL_TEXTURE); - glPushMatrix(); - glLoadIdentity(); - if (mtex->brush_map_mode == MTEX_MAP_MODE_VIEW) { + gpuPushMatrix(); + /* brush rotation */ - glTranslatef(0.5, 0.5, 0); - glRotatef((double)RAD2DEGF((primary) ? ups->brush_rotation : ups->brush_rotation_sec), - 0.0, 0.0, 1.0); - glTranslatef(-0.5f, -0.5f, 0); + gpuTranslate2f(x, y); + gpuRotate2D(-RAD2DEGF(primary ? ups->brush_rotation : ups->brush_rotation_sec)); + gpuTranslate2f(-x, -y); /* scale based on tablet pressure */ if (primary && ups->stroke_active && BKE_brush_use_size_pressure(vc->scene, brush)) { - glTranslatef(0.5f, 0.5f, 0); - glScalef(1.0f / ups->size_pressure_value, 1.0f / ups->size_pressure_value, 1); - glTranslatef(-0.5f, -0.5f, 0); + const float scale = ups->size_pressure_value; + gpuTranslate2f(x, y); + gpuScale2f(scale, scale); + gpuTranslate2f(-x, -y); } if (ups->draw_anchored) { - const float *aim = ups->anchored_initial_mouse; + float aim[2] = { + ups->anchored_initial_mouse[0] + vc->ar->winrct.xmin, + ups->anchored_initial_mouse[1] + vc->ar->winrct.ymin, + }; quad.xmin = aim[0] - ups->anchored_size; quad.ymin = aim[1] - ups->anchored_size; quad.xmax = aim[0] + ups->anchored_size; @@ -668,41 +668,46 @@ static void paint_draw_tex_overlay(UnifiedPaintSettings *ups, Brush *brush, quad.xmax = brush->mask_stencil_dimension[0]; quad.ymax = brush->mask_stencil_dimension[1]; } - glMatrixMode(GL_MODELVIEW); - glPushMatrix(); + gpuPushMatrix(); if (primary) - glTranslate2fv(brush->stencil_pos); + gpuTranslate2fv(brush->stencil_pos); else - glTranslate2fv(brush->mask_stencil_pos); - glRotatef(RAD2DEGF(mtex->rot), 0, 0, 1); - glMatrixMode(GL_TEXTURE); + gpuTranslate2fv(brush->mask_stencil_pos); + gpuRotate2D(RAD2DEGF(mtex->rot)); } /* set quad color. Colored overlay does not get blending */ + Gwn_VertFormat *format = immVertexFormat(); + unsigned int pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + unsigned int texCoord = GWN_vertformat_attr_add(format, "texCoord", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + if (col) { - glColor4f(1.0, 1.0, 1.0, overlay_alpha / 100.0f); + immBindBuiltinProgram(GPU_SHADER_2D_IMAGE_COLOR); + immUniformColor4f(1.0f, 1.0f, 1.0f, overlay_alpha * 0.01f); } else { - glColor4f(UNPACK3(U.sculpt_paint_overlay_col), overlay_alpha / 100.0f); + immBindBuiltinProgram(GPU_SHADER_2D_IMAGE_ALPHA_COLOR); + immUniformColor3fvAlpha(U.sculpt_paint_overlay_col, overlay_alpha * 0.01f); } /* draw textured quad */ - glBegin(GL_QUADS); - glTexCoord2f(0, 0); - glVertex2f(quad.xmin, quad.ymin); - glTexCoord2f(1, 0); - glVertex2f(quad.xmax, quad.ymin); - glTexCoord2f(1, 1); - glVertex2f(quad.xmax, quad.ymax); - glTexCoord2f(0, 1); - glVertex2f(quad.xmin, quad.ymax); - glEnd(); - - glPopMatrix(); - - if (mtex->brush_map_mode == MTEX_MAP_MODE_STENCIL) { - glMatrixMode(GL_MODELVIEW); - glPopMatrix(); + immUniform1i("image", GL_TEXTURE0); + + immBegin(GWN_PRIM_TRI_FAN, 4); + immAttrib2f(texCoord, 0.0f, 0.0f); + immVertex2f(pos, quad.xmin, quad.ymin); + immAttrib2f(texCoord, 1.0f, 0.0f); + immVertex2f(pos, quad.xmax, quad.ymin); + immAttrib2f(texCoord, 1.0f, 1.0f); + immVertex2f(pos, quad.xmax, quad.ymax); + immAttrib2f(texCoord, 0.0f, 1.0f); + immVertex2f(pos, quad.xmin, quad.ymax); + immEnd(); + + immUnbindProgram(); + + if (ELEM(mtex->brush_map_mode, MTEX_MAP_MODE_STENCIL, MTEX_MAP_MODE_VIEW)) { + gpuPopMatrix(); } } } @@ -722,14 +727,17 @@ static void paint_draw_cursor_overlay(UnifiedPaintSettings *ups, Brush *brush, if (load_tex_cursor(brush, vc, zoom)) { bool do_pop = false; float center[2]; - glEnable(GL_BLEND); + GPU_blend(true); glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); glDepthMask(GL_FALSE); glDepthFunc(GL_ALWAYS); if (ups->draw_anchored) { - const float *aim = ups->anchored_initial_mouse; + float aim[2] = { + ups->anchored_initial_mouse[0] + vc->ar->winrct.xmin, + ups->anchored_initial_mouse[1] + vc->ar->winrct.ymin, + }; copy_v2_v2(center, aim); quad.xmin = aim[0] - ups->anchored_size; quad.ymin = aim[1] - ups->anchored_size; @@ -750,32 +758,41 @@ static void paint_draw_cursor_overlay(UnifiedPaintSettings *ups, Brush *brush, /* scale based on tablet pressure */ if (ups->stroke_active && BKE_brush_use_size_pressure(vc->scene, brush)) { do_pop = true; - glPushMatrix(); - glLoadIdentity(); - glTranslate2fv(center); - glScalef(ups->size_pressure_value, ups->size_pressure_value, 1); - glTranslatef(-center[0], -center[1], 0); + gpuPushMatrix(); + gpuLoadIdentity(); + gpuTranslate2fv(center); + gpuScaleUniform(ups->size_pressure_value); + gpuTranslate2f(-center[0], -center[1]); } - glColor4f(U.sculpt_paint_overlay_col[0], - U.sculpt_paint_overlay_col[1], - U.sculpt_paint_overlay_col[2], - brush->cursor_overlay_alpha / 100.0f); + Gwn_VertFormat *format = immVertexFormat(); + unsigned int pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + unsigned int texCoord = GWN_vertformat_attr_add(format, "texCoord", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + + immBindBuiltinProgram(GPU_SHADER_2D_IMAGE_COLOR); + + immUniformColor3fvAlpha(U.sculpt_paint_overlay_col, brush->cursor_overlay_alpha * 0.01f); + + /* draw textured quad */ /* draw textured quad */ - glBegin(GL_QUADS); - glTexCoord2f(0, 0); - glVertex2f(quad.xmin, quad.ymin); - glTexCoord2f(1, 0); - glVertex2f(quad.xmax, quad.ymin); - glTexCoord2f(1, 1); - glVertex2f(quad.xmax, quad.ymax); - glTexCoord2f(0, 1); - glVertex2f(quad.xmin, quad.ymax); - glEnd(); + immUniform1i("image", 0); + + immBegin(GWN_PRIM_TRI_FAN, 4); + immAttrib2f(texCoord, 0.0f, 0.0f); + immVertex2f(pos, quad.xmin, quad.ymin); + immAttrib2f(texCoord, 1.0f, 0.0f); + immVertex2f(pos, quad.xmax, quad.ymin); + immAttrib2f(texCoord, 1.0f, 1.0f); + immVertex2f(pos, quad.xmax, quad.ymax); + immAttrib2f(texCoord, 0.0f, 1.0f); + immVertex2f(pos, quad.xmin, quad.ymax); + immEnd(); + + immUnbindProgram(); if (do_pop) - glPopMatrix(); + gpuPopMatrix(); } } @@ -785,19 +802,7 @@ static void paint_draw_alpha_overlay(UnifiedPaintSettings *ups, Brush *brush, /* color means that primary brush texture is colured and secondary is used for alpha/mask control */ bool col = ELEM(mode, ePaintTextureProjective, ePaintTexture2D, ePaintVertex) ? true : false; eOverlayControlFlags flags = BKE_paint_get_overlay_flags(); - /* save lots of GL state - * TODO: check on whether all of these are needed? */ - glPushAttrib(GL_COLOR_BUFFER_BIT | - GL_CURRENT_BIT | - GL_DEPTH_BUFFER_BIT | - GL_ENABLE_BIT | - GL_LINE_BIT | - GL_POLYGON_BIT | - GL_STENCIL_BUFFER_BIT | - GL_TRANSFORM_BIT | - GL_VIEWPORT_BIT | - GL_TEXTURE_BIT); - + gpuPushAttrib(GPU_DEPTH_BUFFER_BIT | GPU_BLEND_BIT); /* coloured overlay should be drawn separately */ if (col) { @@ -815,86 +820,98 @@ static void paint_draw_alpha_overlay(UnifiedPaintSettings *ups, Brush *brush, paint_draw_cursor_overlay(ups, brush, vc, x, y, zoom); } - glPopAttrib(); - GPU_basic_shader_bind(GPU_SHADER_USE_COLOR); + gpuPopAttrib(); } -BLI_INLINE void draw_tri_point(float *co, float width, bool selected) +BLI_INLINE void draw_tri_point( + unsigned int pos, float sel_col[4], float pivot_col[4], + float *co, float width, bool selected) { + immUniformColor4fv(selected ? sel_col : pivot_col); + + GPU_line_width(3.0f); + float w = width / 2.0f; - if (selected) - UI_ThemeColor4(TH_VERTEX_SELECT); - else - UI_ThemeColor4(TH_PAINT_CURVE_PIVOT); - - glLineWidth(3.0); - - glBegin(GL_LINE_LOOP); - glVertex2f(co[0], co[1] + w); - glVertex2f(co[0] - w, co[1] - w); - glVertex2f(co[0] + w, co[1] - w); - glEnd(); - - glColor4f(1.0, 1.0, 1.0, 0.5); - glLineWidth(1.0); - - glBegin(GL_LINE_LOOP); - glVertex2f(co[0], co[1] + w); - glVertex2f(co[0] - w, co[1] - w); - glVertex2f(co[0] + w, co[1] - w); - glEnd(); + float tri[3][2] = { + {co[0], co[1] + w}, + {co[0] - w, co[1] - w}, + {co[0] + w, co[1] - w}, + }; + + immBegin(GWN_PRIM_LINE_LOOP, 3); + immVertex2fv(pos, tri[0]); + immVertex2fv(pos, tri[1]); + immVertex2fv(pos, tri[2]); + immEnd(); + + immUniformColor4f(1.0f, 1.0f, 1.0f, 0.5f); + GPU_line_width(1.0f); + + immBegin(GWN_PRIM_LINE_LOOP, 3); + immVertex2fv(pos, tri[0]); + immVertex2fv(pos, tri[1]); + immVertex2fv(pos, tri[2]); + immEnd(); } -BLI_INLINE void draw_rect_point(float *co, float width, bool selected) +BLI_INLINE void draw_rect_point( + unsigned int pos, float sel_col[4], float handle_col[4], + float *co, float width, bool selected) { + immUniformColor4fv(selected ? sel_col : handle_col); + + GPU_line_width(3.0f); + float w = width / 2.0f; - if (selected) - UI_ThemeColor4(TH_VERTEX_SELECT); - else - UI_ThemeColor4(TH_PAINT_CURVE_HANDLE); - glLineWidth(3.0); - - glBegin(GL_LINE_LOOP); - glVertex2f(co[0] + w, co[1] + w); - glVertex2f(co[0] - w, co[1] + w); - glVertex2f(co[0] - w, co[1] - w); - glVertex2f(co[0] + w, co[1] - w); - glEnd(); - - glColor4f(1.0, 1.0, 1.0, 0.5); - glLineWidth(1.0); - - glBegin(GL_LINE_LOOP); - glVertex2f(co[0] + w, co[1] + w); - glVertex2f(co[0] - w, co[1] + w); - glVertex2f(co[0] - w, co[1] - w); - glVertex2f(co[0] + w, co[1] - w); - glEnd(); + float minx = co[0] - w; + float miny = co[1] - w; + float maxx = co[0] + w; + float maxy = co[1] + w; + + imm_draw_box_wire_2d(pos, minx, miny, maxx, maxy); + + immUniformColor4f(1.0f, 1.0f, 1.0f, 0.5f); + GPU_line_width(1.0f); + + imm_draw_box_wire_2d(pos, minx, miny, maxx, maxy); } -BLI_INLINE void draw_bezier_handle_lines(BezTriple *bez) +BLI_INLINE void draw_bezier_handle_lines(unsigned int pos, float sel_col[4], BezTriple *bez) { - short line1[] = {0, 1}; - short line2[] = {1, 2}; - - glVertexPointer(2, GL_FLOAT, 3 * sizeof(float), bez->vec); - glColor4f(0.0, 0.0, 0.0, 0.5); - glLineWidth(3.0); - glDrawArrays(GL_LINE_STRIP, 0, 3); - - glLineWidth(1.0); - if (bez->f1 || bez->f2) - UI_ThemeColor4(TH_VERTEX_SELECT); - else - glColor4f(1.0, 1.0, 1.0, 0.5); - glDrawElements(GL_LINES, 2, GL_UNSIGNED_SHORT, line1); - if (bez->f3 || bez->f2) - UI_ThemeColor4(TH_VERTEX_SELECT); - else - glColor4f(1.0, 1.0, 1.0, 0.5); - glDrawElements(GL_LINES, 2, GL_UNSIGNED_SHORT, line2); + immUniformColor4f(0.0f, 0.0f, 0.0f, 0.5f); + GPU_line_width(3.0f); + + immBegin(GWN_PRIM_LINE_STRIP, 3); + immVertex2fv(pos, bez->vec[0]); + immVertex2fv(pos, bez->vec[1]); + immVertex2fv(pos, bez->vec[2]); + immEnd(); + + GPU_line_width(1.0f); + + if (bez->f1 || bez->f2) { + immUniformColor4fv(sel_col); + } + else { + immUniformColor4f(1.0f, 1.0f, 1.0f, 0.5f); + } + immBegin(GWN_PRIM_LINES, 2); + immVertex2fv(pos, bez->vec[0]); + immVertex2fv(pos, bez->vec[1]); + immEnd(); + + if (bez->f3 || bez->f2) { + immUniformColor4fv(sel_col); + } + else { + immUniformColor4f(1.0f, 1.0f, 1.0f, 0.5f); + } + immBegin(GWN_PRIM_LINES, 2); + immVertex2fv(pos, bez->vec[1]); + immVertex2fv(pos, bez->vec[2]); + immEnd(); } static void paint_draw_curve_cursor(Brush *brush) @@ -904,20 +921,28 @@ static void paint_draw_curve_cursor(Brush *brush) PaintCurve *pc = brush->paint_curve; PaintCurvePoint *cp = pc->points; - glEnable(GL_LINE_SMOOTH); - glEnable(GL_BLEND); - glEnableClientState(GL_VERTEX_ARRAY); + GPU_line_smooth(true); + GPU_blend(true); /* draw the bezier handles and the curve segment between the current and next point */ + unsigned int pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + + immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); + + float selec_col[4], handle_col[4], pivot_col[4]; + UI_GetThemeColor4fv(TH_VERTEX_SELECT, selec_col); + UI_GetThemeColor4fv(TH_PAINT_CURVE_HANDLE, handle_col); + UI_GetThemeColor4fv(TH_PAINT_CURVE_PIVOT, pivot_col); + for (i = 0; i < pc->tot_points - 1; i++, cp++) { int j; PaintCurvePoint *cp_next = cp + 1; float data[(PAINT_CURVE_NUM_SEGMENTS + 1) * 2]; /* use color coding to distinguish handles vs curve segments */ - draw_bezier_handle_lines(&cp->bez); - draw_tri_point(&cp->bez.vec[1][0], 10.0, cp->bez.f2); - draw_rect_point(&cp->bez.vec[0][0], 8.0, cp->bez.f1 || cp->bez.f2); - draw_rect_point(&cp->bez.vec[2][0], 8.0, cp->bez.f3 || cp->bez.f2); + draw_bezier_handle_lines(pos, selec_col, &cp->bez); + draw_tri_point(pos, selec_col, pivot_col, &cp->bez.vec[1][0], 10.0f, cp->bez.f2); + draw_rect_point(pos, selec_col, handle_col, &cp->bez.vec[0][0], 8.0f, cp->bez.f1 || cp->bez.f2); + draw_rect_point(pos, selec_col, handle_col, &cp->bez.vec[2][0], 8.0f, cp->bez.f3 || cp->bez.f2); for (j = 0; j < 2; j++) BKE_curve_forward_diff_bezier( @@ -927,25 +952,35 @@ static void paint_draw_curve_cursor(Brush *brush) cp_next->bez.vec[1][j], data + j, PAINT_CURVE_NUM_SEGMENTS, sizeof(float[2])); - glVertexPointer(2, GL_FLOAT, 0, data); - glLineWidth(3.0); - glColor4f(0.0, 0.0, 0.0, 0.5); - glDrawArrays(GL_LINE_STRIP, 0, PAINT_CURVE_NUM_SEGMENTS + 1); + float (*v)[2] = (float(*)[2])data; + + immUniformColor4f(0.0f, 0.0f, 0.0f, 0.5f); + GPU_line_width(3.0f); + immBegin(GWN_PRIM_LINE_STRIP, PAINT_CURVE_NUM_SEGMENTS + 1); + for (j = 0; j <= PAINT_CURVE_NUM_SEGMENTS; j++) { + immVertex2fv(pos, v[j]); + } + immEnd(); - glLineWidth(1.0); - glColor4f(0.9, 0.9, 1.0, 0.5); - glDrawArrays(GL_LINE_STRIP, 0, PAINT_CURVE_NUM_SEGMENTS + 1); + immUniformColor4f(0.9f, 0.9f, 1.0f, 0.5f); + GPU_line_width(1.0f); + immBegin(GWN_PRIM_LINE_STRIP, PAINT_CURVE_NUM_SEGMENTS + 1); + for (j = 0; j <= PAINT_CURVE_NUM_SEGMENTS; j++) { + immVertex2fv(pos, v[j]); + } + immEnd(); } /* draw last line segment */ - draw_bezier_handle_lines(&cp->bez); - draw_tri_point(&cp->bez.vec[1][0], 10.0, cp->bez.f2); - draw_rect_point(&cp->bez.vec[0][0], 8.0, cp->bez.f1 || cp->bez.f2); - draw_rect_point(&cp->bez.vec[2][0], 8.0, cp->bez.f3 || cp->bez.f2); - - glDisable(GL_BLEND); - glDisable(GL_LINE_SMOOTH); - glDisableClientState(GL_VERTEX_ARRAY); + draw_bezier_handle_lines(pos, selec_col, &cp->bez); + draw_tri_point(pos, selec_col, pivot_col, &cp->bez.vec[1][0], 10.0f, cp->bez.f2); + draw_rect_point(pos, selec_col, handle_col, &cp->bez.vec[0][0], 8.0f, cp->bez.f1 || cp->bez.f2); + draw_rect_point(pos, selec_col, handle_col, &cp->bez.vec[2][0], 8.0f, cp->bez.f3 || cp->bez.f2); + + GPU_blend(false); + GPU_line_smooth(false); + + immUnbindProgram(); } } @@ -995,15 +1030,11 @@ static bool ommit_cursor_drawing(Paint *paint, ePaintMode mode, Brush *brush) static void paint_draw_cursor(bContext *C, int x, int y, void *UNUSED(unused)) { Scene *scene = CTX_data_scene(C); + ARegion *ar = CTX_wm_region(C); UnifiedPaintSettings *ups = &scene->toolsettings->unified_paint_settings; Paint *paint = BKE_paint_get_active_from_context(C); Brush *brush = BKE_paint_brush(paint); ePaintMode mode = BKE_paintmode_get_active_from_context(C); - ViewContext vc; - float final_radius; - float translation[2]; - float outline_alpha, *outline_col; - float zoomx, zoomy; /* check that brush drawing is enabled */ if (ommit_cursor_drawing(paint, mode, brush)) @@ -1011,6 +1042,7 @@ static void paint_draw_cursor(bContext *C, int x, int y, void *UNUSED(unused)) /* can't use stroke vc here because this will be called during * mouse over too, not just during a stroke */ + ViewContext vc; ED_view3d_viewcontext_init(C, &vc); if (vc.rv3d && (vc.rv3d->rflag & RV3D_NAVIGATING)) { @@ -1023,15 +1055,15 @@ static void paint_draw_cursor(bContext *C, int x, int y, void *UNUSED(unused)) return; } + float zoomx, zoomy; get_imapaint_zoom(C, &zoomx, &zoomy); zoomx = max_ff(zoomx, zoomy); /* set various defaults */ - translation[0] = x; - translation[1] = y; - outline_alpha = 0.5; - outline_col = brush->add_col; - final_radius = (BKE_brush_size_get(scene, brush) * zoomx); + const float *outline_col = brush->add_col; + const float outline_alpha = 0.5f; + float translation[2] = { x, y }; + float final_radius = (BKE_brush_size_get(scene, brush) * zoomx); /* don't calculate rake angles while a stroke is active because the rake variables are global and * we may get interference with the stroke itself. For line strokes, such interference is visible */ @@ -1047,10 +1079,9 @@ static void paint_draw_cursor(bContext *C, int x, int y, void *UNUSED(unused)) if ((mode == ePaintSculpt) && vc.obact->sculpt) { float location[3]; int pixel_radius; - bool hit; /* test if brush is over the mesh */ - hit = sculpt_get_brush_geometry(C, &vc, x, y, &pixel_radius, location, ups); + bool hit = sculpt_get_brush_geometry(C, &vc, x, y, &pixel_radius, location, ups); if (BKE_brush_use_locked_size(scene, brush)) BKE_brush_size_set(scene, brush, pixel_radius); @@ -1071,34 +1102,36 @@ static void paint_draw_cursor(bContext *C, int x, int y, void *UNUSED(unused)) if (ups->draw_anchored) { final_radius = ups->anchored_size; - translation[0] = ups->anchored_initial_mouse[0]; - translation[1] = ups->anchored_initial_mouse[1]; + copy_v2_fl2(translation, + ups->anchored_initial_mouse[0] + ar->winrct.xmin, + ups->anchored_initial_mouse[1] + ar->winrct.ymin); } /* make lines pretty */ - glLineWidth(1.0f); - glEnable(GL_BLEND); - glEnable(GL_LINE_SMOOTH); + GPU_line_width(1.0f); + GPU_blend(true); /* TODO: also set blend mode? */ + GPU_line_smooth(true); + + unsigned int pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); /* set brush color */ - glColor4f(outline_col[0], outline_col[1], outline_col[2], outline_alpha); + immUniformColor3fvAlpha(outline_col, outline_alpha); /* draw brush outline */ - glTranslate2fv(translation); - - /* draw an inner brush */ if (ups->stroke_active && BKE_brush_use_size_pressure(scene, brush)) { /* inner at full alpha */ - glutil_draw_lined_arc(0.0, M_PI * 2.0, final_radius * ups->size_pressure_value, 40); + imm_draw_circle_wire_2d(pos, translation[0], translation[1], final_radius * ups->size_pressure_value, 40); /* outer at half alpha */ - glColor4f(outline_col[0], outline_col[1], outline_col[2], outline_alpha * 0.5f); + immUniformColor3fvAlpha(outline_col, outline_alpha * 0.5f); } - glutil_draw_lined_arc(0.0, M_PI * 2.0, final_radius, 40); - glTranslatef(-translation[0], -translation[1], 0); + imm_draw_circle_wire_2d(pos, translation[0], translation[1], final_radius, 40); + + immUnbindProgram(); /* restore GL state */ - glDisable(GL_BLEND); - glDisable(GL_LINE_SMOOTH); + GPU_blend(false); + GPU_line_smooth(false); } /* Public API */ diff --git a/source/blender/editors/sculpt_paint/paint_curve.c b/source/blender/editors/sculpt_paint/paint_curve.c index 8d31ad19a99..0c3c6e120ed 100644 --- a/source/blender/editors/sculpt_paint/paint_curve.c +++ b/source/blender/editors/sculpt_paint/paint_curve.c @@ -39,6 +39,8 @@ #include "BKE_main.h" #include "BKE_paint.h" +#include "DEG_depsgraph.h" + #include "ED_view3d.h" #include "ED_paint.h" @@ -712,7 +714,7 @@ static int paintcurve_cursor_invoke(bContext *C, wmOperator *UNUSED(op), const w break; } default: - ED_view3d_cursor3d_update(C, event->mval); + ED_view3d_cursor3d_update(C, event->mval, true, V3D_CURSOR_ORIENT_VIEW); break; } diff --git a/source/blender/editors/sculpt_paint/paint_hide.c b/source/blender/editors/sculpt_paint/paint_hide.c index 0bec71f0566..4deec54a5b3 100644 --- a/source/blender/editors/sculpt_paint/paint_hide.c +++ b/source/blender/editors/sculpt_paint/paint_hide.c @@ -46,13 +46,13 @@ #include "BKE_pbvh.h" #include "BKE_ccg.h" #include "BKE_context.h" -#include "BKE_DerivedMesh.h" #include "BKE_mesh.h" +#include "BKE_mesh_runtime.h" #include "BKE_multires.h" #include "BKE_paint.h" #include "BKE_subsurf.h" -#include "BIF_glutil.h" +#include "DEG_depsgraph.h" #include "WM_api.h" #include "WM_types.h" @@ -323,12 +323,10 @@ static void clip_planes_from_rect(bContext *C, { ViewContext vc; BoundBox bb; - bglMats mats = {{0}}; view3d_operator_needs_opengl(C); ED_view3d_viewcontext_init(C, &vc); - view3d_get_transformation(vc.ar, vc.rv3d, vc.obact, &mats); - ED_view3d_clipping_calc(&bb, clip_planes, &mats, rect); + ED_view3d_clipping_calc(&bb, clip_planes, vc.ar, vc.obact, rect); negate_m4(clip_planes); } @@ -364,12 +362,12 @@ static int hide_show_exec(bContext *C, wmOperator *op) { ARegion *ar = CTX_wm_region(C); Object *ob = CTX_data_active_object(C); + Depsgraph *depsgraph = CTX_data_depsgraph(C); Mesh *me = ob->data; PartialVisAction action; PartialVisArea area; PBVH *pbvh; PBVHNode **nodes; - DerivedMesh *dm; PBVHType pbvh_type; float clip_planes[4][4]; rcti rect; @@ -382,9 +380,9 @@ static int hide_show_exec(bContext *C, wmOperator *op) clip_planes_from_rect(C, clip_planes, &rect); - dm = mesh_get_derived_final(CTX_data_scene(C), ob, CD_MASK_BAREMESH); - pbvh = dm->getPBVH(ob, dm); - ob->sculpt->pbvh = pbvh; + Mesh *me_eval_deform = mesh_get_eval_deform(depsgraph, CTX_data_scene(C), ob, CD_MASK_BAREMESH); + pbvh = BKE_sculpt_object_pbvh_ensure(ob, me_eval_deform); + BLI_assert(ob->sculpt->pbvh == pbvh); get_pbvh_nodes(pbvh, &nodes, &totnode, clip_planes, area); pbvh_type = BKE_pbvh_type(pbvh); diff --git a/source/blender/editors/sculpt_paint/paint_image.c b/source/blender/editors/sculpt_paint/paint_image.c index 3760dec96d0..02fd685719e 100644 --- a/source/blender/editors/sculpt_paint/paint_image.c +++ b/source/blender/editors/sculpt_paint/paint_image.c @@ -46,21 +46,23 @@ #include "IMB_imbuf_types.h" #include "DNA_brush_types.h" +#include "DNA_mesh_types.h" #include "DNA_node_types.h" #include "DNA_object_types.h" #include "BKE_colorband.h" #include "BKE_context.h" -#include "BKE_depsgraph.h" -#include "BKE_DerivedMesh.h" #include "BKE_brush.h" #include "BKE_main.h" #include "BKE_material.h" +#include "BKE_mesh.h" #include "BKE_node.h" #include "BKE_paint.h" #include "BKE_undo_system.h" +#include "DEG_depsgraph.h" + #include "UI_interface.h" #include "UI_view2d.h" @@ -72,15 +74,17 @@ #include "WM_api.h" #include "WM_types.h" +#include "WM_message.h" +#include "WM_toolsystem.h" #include "RNA_access.h" #include "RNA_define.h" #include "GPU_draw.h" -#include "GPU_buffers.h" +#include "GPU_immediate.h" +#include "GPU_state.h" #include "BIF_gl.h" -#include "BIF_glutil.h" #include "IMB_colormanagement.h" @@ -264,7 +268,7 @@ static Brush *image_paint_brush(bContext *C) return BKE_paint_brush(&settings->imapaint.paint); } -static bool image_paint_poll(bContext *C) +static bool image_paint_poll_ex(bContext *C, bool check_tool) { Object *obact; @@ -273,7 +277,9 @@ static bool image_paint_poll(bContext *C) obact = CTX_data_active_object(C); if ((obact && obact->mode & OB_MODE_TEXTURE_PAINT) && CTX_wm_region_view3d(C)) { - return 1; + if (!check_tool || WM_toolsystem_active_tool_is_brush(C)) { + return 1; + } } else { SpaceImage *sima = CTX_wm_space_image(C); @@ -290,6 +296,16 @@ static bool image_paint_poll(bContext *C) return 0; } +static bool image_paint_poll(bContext *C) +{ + return image_paint_poll_ex(C, true); +} + +static bool image_paint_ignore_tool_poll(bContext *C) +{ + return image_paint_poll_ex(C, false); +} + static bool image_paint_2d_clone_poll(bContext *C) { Brush *brush = image_paint_brush(C); @@ -398,18 +414,34 @@ static void gradient_draw_line(bContext *UNUSED(C), int x, int y, void *customda PaintOperation *pop = (PaintOperation *)customdata; if (pop) { - glEnable(GL_LINE_SMOOTH); - glEnable(GL_BLEND); - - glLineWidth(4.0); - glColor4ub(0, 0, 0, 255); - sdrawline(x, y, pop->startmouse[0], pop->startmouse[1]); - glLineWidth(2.0); - glColor4ub(255, 255, 255, 255); - sdrawline(x, y, pop->startmouse[0], pop->startmouse[1]); - - glDisable(GL_BLEND); - glDisable(GL_LINE_SMOOTH); + GPU_line_smooth(true); + GPU_blend(true); + + Gwn_VertFormat *format = immVertexFormat(); + unsigned int pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_I32, 2, GWN_FETCH_INT_TO_FLOAT); + + immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); + + GPU_line_width(4.0); + immUniformColor4ub(0, 0, 0, 255); + + immBegin(GWN_PRIM_LINES, 2); + immVertex2i(pos, x, y); + immVertex2i(pos, pop->startmouse[0], pop->startmouse[1]); + immEnd(); + + GPU_line_width(2.0); + immUniformColor4ub(255, 255, 255, 255); + + immBegin(GWN_PRIM_LINES, 2); + immVertex2i(pos, x, y); + immVertex2i(pos, pop->startmouse[0], pop->startmouse[1]); + immEnd(); + + immUnbindProgram(); + + GPU_blend(false); + GPU_line_smooth(false); } } @@ -428,7 +460,8 @@ static PaintOperation *texture_paint_init(bContext *C, wmOperator *op, const flo /* initialize from context */ if (CTX_wm_region_view3d(C)) { - Object *ob = OBACT; + ViewLayer *view_layer = CTX_data_view_layer(C); + Object *ob = OBACT(view_layer); bool uvs, mat, tex, stencil; if (!BKE_paint_proj_mesh_data_check(scene, ob, &uvs, &mat, &tex, &stencil)) { BKE_paint_data_warning(op->reports, uvs, mat, tex, stencil); @@ -711,16 +744,20 @@ static void toggle_paint_cursor(bContext *C, int enable) void ED_space_image_paint_update(Main *bmain, wmWindowManager *wm, Scene *scene) { ToolSettings *settings = scene->toolsettings; - wmWindow *win; - ScrArea *sa; ImagePaintSettings *imapaint = &settings->imapaint; bool enabled = false; - for (win = wm->windows.first; win; win = win->next) - for (sa = win->screen->areabase.first; sa; sa = sa->next) - if (sa->spacetype == SPACE_IMAGE) - if (((SpaceImage *)sa->spacedata.first)->mode == SI_MODE_PAINT) + for (wmWindow *win = wm->windows.first; win; win = win->next) { + bScreen *screen = WM_window_get_active_screen(win); + + for (ScrArea *sa = screen->areabase.first; sa; sa = sa->next) { + if (sa->spacetype == SPACE_IMAGE) { + if (((SpaceImage *)sa->spacedata.first)->mode == SI_MODE_PAINT) { enabled = true; + } + } + } + } if (enabled) { BKE_paint_init(bmain, scene, ePaintTexture2D, PAINT_CURSOR_TEXTURE_PAINT); @@ -850,7 +887,7 @@ static void sample_color_update_header(SampleColorData *data, bContext *C) !data->sample_palette ? IFACE_("Brush. Use Left Click to sample for palette instead") : IFACE_("Palette. Use Left Click to sample more colors")); - ED_area_headerprint(sa, msg); + ED_workspace_status_text(C, msg); } } @@ -929,8 +966,6 @@ static int sample_color_modal(bContext *C, wmOperator *op, const wmEvent *event) Brush *brush = BKE_paint_brush(paint); if ((event->type == data->event_type) && (event->val == KM_RELEASE)) { - ScrArea *sa = CTX_wm_area(C); - if (data->show_cursor) { paint->flags |= PAINT_SHOW_BRUSH; } @@ -941,7 +976,7 @@ static int sample_color_modal(bContext *C, wmOperator *op, const wmEvent *event) } WM_cursor_modal_restore(CTX_wm_window(C)); MEM_freeN(data); - ED_area_headerprint(sa, NULL); + ED_workspace_status_text(C, NULL); return OPERATOR_FINISHED; } @@ -976,11 +1011,6 @@ static int sample_color_modal(bContext *C, wmOperator *op, const wmEvent *event) return OPERATOR_RUNNING_MODAL; } -static bool sample_color_poll(bContext *C) -{ - return (image_paint_poll(C) || vertex_paint_poll(C)); -} - void PAINT_OT_sample_color(wmOperatorType *ot) { /* identifiers */ @@ -992,7 +1022,7 @@ void PAINT_OT_sample_color(wmOperatorType *ot) ot->exec = sample_color_exec; ot->invoke = sample_color_invoke; ot->modal = sample_color_modal; - ot->poll = sample_color_poll; + ot->poll = image_paint_ignore_tool_poll; /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; @@ -1024,6 +1054,7 @@ static bool texture_paint_toggle_poll(bContext *C) static int texture_paint_toggle_exec(bContext *C, wmOperator *op) { + struct wmMsgBus *mbus = CTX_wm_message_bus(C); Main *bmain = CTX_data_main(C); Scene *scene = CTX_data_scene(C); Object *ob = CTX_data_active_object(C); @@ -1076,8 +1107,10 @@ static int texture_paint_toggle_exec(bContext *C, wmOperator *op) if (sl->spacetype == SPACE_IMAGE) { SpaceImage *sima = (SpaceImage *)sl; - if (!sima->pin) - ED_space_image_set(bmain, sima, scene, scene->obedit, ima); + if (!sima->pin) { + Object *obedit = CTX_data_edit_object(C); + ED_space_image_set(bmain, sima, scene, obedit, ima); + } } } } @@ -1095,9 +1128,16 @@ static int texture_paint_toggle_exec(bContext *C, wmOperator *op) toggle_paint_cursor(C, 1); } - GPU_drawobject_free(ob->derivedFinal); + Mesh *me = BKE_mesh_from_object(ob); + BLI_assert(me != NULL); + DEG_id_tag_update(&me->id, DEG_TAG_COPY_ON_WRITE); + WM_event_add_notifier(C, NC_SCENE | ND_MODE, scene); + WM_msg_publish_rna_prop(mbus, &ob->id, ob, Object, mode); + + WM_toolsystem_update_from_context_view3d(C); + return OPERATOR_FINISHED; } @@ -1121,8 +1161,8 @@ static int brush_colors_flip_exec(bContext *C, wmOperator *UNUSED(op)) { UnifiedPaintSettings *ups = &CTX_data_tool_settings(C)->unified_paint_settings; - Brush *br; Object *ob = CTX_data_active_object(C); + Brush *br; if (!(ob && (ob->mode & OB_MODE_VERTEX_PAINT))) { br = image_paint_brush(C); } @@ -1191,7 +1231,7 @@ void ED_imapaint_bucket_fill(struct bContext *C, float color[3], wmOperator *op) BKE_undosys_step_push(wm->undo_stack, C, op->type->name); - DAG_id_tag_update(&ima->id, 0); + DEG_id_tag_update(&ima->id, 0); } diff --git a/source/blender/editors/sculpt_paint/paint_image_2d.c b/source/blender/editors/sculpt_paint/paint_image_2d.c index ec1a6ebf7ed..a75d6344849 100644 --- a/source/blender/editors/sculpt_paint/paint_image_2d.c +++ b/source/blender/editors/sculpt_paint/paint_image_2d.c @@ -46,12 +46,13 @@ #include "BKE_colorband.h" #include "BKE_context.h" -#include "BKE_depsgraph.h" #include "BKE_brush.h" #include "BKE_image.h" #include "BKE_paint.h" #include "BKE_report.h" +#include "DEG_depsgraph.h" + #include "ED_paint.h" #include "ED_screen.h" @@ -1367,7 +1368,7 @@ void paint_2d_redraw(const bContext *C, void *ps, bool final) /* compositor listener deals with updating */ WM_event_add_notifier(C, NC_IMAGE | NA_EDITED, s->image); - DAG_id_tag_update(&s->image->id, 0); + DEG_id_tag_update(&s->image->id, 0); } else { if (!s->sima || !s->sima->lock) diff --git a/source/blender/editors/sculpt_paint/paint_image_proj.c b/source/blender/editors/sculpt_paint/paint_image_proj.c index e9fdbdb7f26..8c5fdc617c6 100644 --- a/source/blender/editors/sculpt_paint/paint_image_proj.c +++ b/source/blender/editors/sculpt_paint/paint_image_proj.c @@ -58,6 +58,7 @@ #include "DNA_brush_types.h" #include "DNA_material_types.h" #include "DNA_mesh_types.h" +#include "DNA_meshdata_types.h" #include "DNA_node_types.h" #include "DNA_object_types.h" @@ -65,8 +66,6 @@ #include "BKE_colorband.h" #include "BKE_context.h" #include "BKE_colortools.h" -#include "BKE_depsgraph.h" -#include "BKE_DerivedMesh.h" #include "BKE_idprop.h" #include "BKE_brush.h" #include "BKE_image.h" @@ -75,12 +74,16 @@ #include "BKE_material.h" #include "BKE_mesh.h" #include "BKE_mesh_mapping.h" +#include "BKE_mesh_runtime.h" #include "BKE_node.h" #include "BKE_paint.h" #include "BKE_report.h" #include "BKE_scene.h" #include "BKE_texture.h" +#include "DEG_depsgraph.h" +#include "DEG_depsgraph_query.h" + #include "UI_interface.h" #include "ED_object.h" @@ -227,6 +230,7 @@ typedef struct ProjPaintState { View3D *v3d; RegionView3D *rv3d; ARegion *ar; + Depsgraph *depsgraph; Scene *scene; int source; /* PROJ_SRC_**** */ @@ -282,7 +286,6 @@ typedef struct ProjPaintState { bool do_backfacecull; /* ignore faces with normals pointing away, skips a lot of raycasts if your normals are correctly flipped */ bool do_mask_normal; /* mask out pixels based on their normals */ bool do_mask_cavity; /* mask out pixels based on cavity */ - bool do_new_shading_nodes; /* cache BKE_scene_use_new_shading_nodes value */ float normal_angle; /* what angle to mask at */ float normal_angle__cos; /* cos(normal_angle), faster to compare */ float normal_angle_inner; @@ -351,28 +354,30 @@ typedef struct ProjPaintState { SpinLock *tile_lock; - DerivedMesh *dm; - int dm_totlooptri; - int dm_totpoly; - int dm_totedge; - int dm_totvert; - bool dm_release; + Mesh *me_eval; + int totlooptri_eval; + int totpoly_eval; + int totedge_eval; + int totvert_eval; - const MVert *dm_mvert; - const MEdge *dm_medge; - const MPoly *dm_mpoly; - const MLoop *dm_mloop; - const MLoopTri *dm_mlooptri; + const MVert *mvert_eval; + const MEdge *medge_eval; + const MPoly *mpoly_eval; + const MLoop *mloop_eval; + const MLoopTri *mlooptri_eval; - const MLoopUV *dm_mloopuv_stencil; + const MLoopUV *mloopuv_stencil_eval; /** - * \note These UV layers are aligned to \a dm_mpoly + * \note These UV layers are aligned to \a mpoly_eval * but each pointer references the start of the layer, * so a loop indirection is needed as well. */ - const MLoopUV **dm_mloopuv; - const MLoopUV **dm_mloopuv_clone; /* other UV map, use for cloning between layers */ + const MLoopUV **poly_to_loop_uv; + const MLoopUV **poly_to_loop_uv_clone; /* other UV map, use for cloning between layers */ + + /* Actual material for each index, either from object or Mesh datablock... */ + Material **mat_array; bool use_colormanagement; } ProjPaintState; @@ -438,13 +443,13 @@ typedef struct { BLI_INLINE const MPoly *ps_tri_index_to_mpoly(const ProjPaintState *ps, int tri_index) { - return &ps->dm_mpoly[ps->dm_mlooptri[tri_index].poly]; + return &ps->mpoly_eval[ps->mlooptri_eval[tri_index].poly]; } #define PS_LOOPTRI_AS_VERT_INDEX_3(ps, lt) \ - ps->dm_mloop[lt->tri[0]].v, \ - ps->dm_mloop[lt->tri[1]].v, \ - ps->dm_mloop[lt->tri[2]].v, + ps->mloop_eval[lt->tri[0]].v, \ + ps->mloop_eval[lt->tri[1]].v, \ + ps->mloop_eval[lt->tri[2]].v, #define PS_LOOPTRI_AS_UV_3(uvlayer, lt) \ uvlayer[lt->poly][lt->tri[0]].uv, \ @@ -466,7 +471,7 @@ BLI_INLINE const MPoly *ps_tri_index_to_mpoly(const ProjPaintState *ps, int tri_ static TexPaintSlot *project_paint_face_paint_slot(const ProjPaintState *ps, int tri_index) { const MPoly *mp = ps_tri_index_to_mpoly(ps, tri_index); - Material *ma = ps->dm->mat[mp->mat_nr]; + Material *ma = ps->mat_array[mp->mat_nr]; return ma ? ma->texpaintslot + ma->paint_active_slot : NULL; } @@ -477,7 +482,7 @@ static Image *project_paint_face_paint_image(const ProjPaintState *ps, int tri_i } else { const MPoly *mp = ps_tri_index_to_mpoly(ps, tri_index); - Material *ma = ps->dm->mat[mp->mat_nr]; + Material *ma = ps->mat_array[mp->mat_nr]; TexPaintSlot *slot = ma ? ma->texpaintslot + ma->paint_active_slot : NULL; return slot ? slot->ima : ps->canvas_ima; } @@ -486,14 +491,14 @@ static Image *project_paint_face_paint_image(const ProjPaintState *ps, int tri_i static TexPaintSlot *project_paint_face_clone_slot(const ProjPaintState *ps, int tri_index) { const MPoly *mp = ps_tri_index_to_mpoly(ps, tri_index); - Material *ma = ps->dm->mat[mp->mat_nr]; + Material *ma = ps->mat_array[mp->mat_nr]; return ma ? ma->texpaintslot + ma->paint_clone_slot : NULL; } static Image *project_paint_face_clone_image(const ProjPaintState *ps, int tri_index) { const MPoly *mp = ps_tri_index_to_mpoly(ps, tri_index); - Material *ma = ps->dm->mat[mp->mat_nr]; + Material *ma = ps->mat_array[mp->mat_nr]; TexPaintSlot *slot = ma ? ma->texpaintslot + ma->paint_clone_slot : NULL; return slot ? slot->ima : ps->clone_ima; } @@ -594,11 +599,11 @@ static int project_paint_PickFace( for (node = ps->bucketFaces[bucket_index]; node; node = node->next) { const int tri_index = GET_INT_FROM_POINTER(node->link); - const MLoopTri *lt = &ps->dm_mlooptri[tri_index]; + const MLoopTri *lt = &ps->mlooptri_eval[tri_index]; const float *vtri_ss[3] = { - ps->screenCoords[ps->dm_mloop[lt->tri[0]].v], - ps->screenCoords[ps->dm_mloop[lt->tri[1]].v], - ps->screenCoords[ps->dm_mloop[lt->tri[2]].v], + ps->screenCoords[ps->mloop_eval[lt->tri[0]].v], + ps->screenCoords[ps->mloop_eval[lt->tri[1]].v], + ps->screenCoords[ps->mloop_eval[lt->tri[2]].v], }; @@ -653,8 +658,8 @@ static bool project_paint_PickColor( if (tri_index == -1) return 0; - lt = &ps->dm_mlooptri[tri_index]; - PS_LOOPTRI_ASSIGN_UV_3(lt_tri_uv, ps->dm_mloopuv, lt); + lt = &ps->mlooptri_eval[tri_index]; + PS_LOOPTRI_ASSIGN_UV_3(lt_tri_uv, ps->poly_to_loop_uv, lt); interp_v2_v2v2v2(uv, UNPACK3(lt_tri_uv), w); @@ -810,19 +815,19 @@ static bool project_bucket_point_occluded( const int tri_index = GET_INT_FROM_POINTER(bucketFace->link); if (orig_face != tri_index) { - const MLoopTri *lt = &ps->dm_mlooptri[tri_index]; + const MLoopTri *lt = &ps->mlooptri_eval[tri_index]; const float *vtri_ss[3] = { - ps->screenCoords[ps->dm_mloop[lt->tri[0]].v], - ps->screenCoords[ps->dm_mloop[lt->tri[1]].v], - ps->screenCoords[ps->dm_mloop[lt->tri[2]].v], + ps->screenCoords[ps->mloop_eval[lt->tri[0]].v], + ps->screenCoords[ps->mloop_eval[lt->tri[1]].v], + ps->screenCoords[ps->mloop_eval[lt->tri[2]].v], }; float w[3]; if (do_clip) { const float *vtri_co[3] = { - ps->dm_mvert[ps->dm_mloop[lt->tri[0]].v].co, - ps->dm_mvert[ps->dm_mloop[lt->tri[1]].v].co, - ps->dm_mvert[ps->dm_mloop[lt->tri[2]].v].co, + ps->mvert_eval[ps->mloop_eval[lt->tri[0]].v].co, + ps->mvert_eval[ps->mloop_eval[lt->tri[1]].v].co, + ps->mvert_eval[ps->mloop_eval[lt->tri[2]].v].co, }; isect_ret = project_paint_occlude_ptv_clip( pixelScreenCo, UNPACK3(vtri_ss), UNPACK3(vtri_co), @@ -1002,8 +1007,8 @@ static bool pixel_bounds_array(float (*uv)[2], rcti *bounds_px, const int ibuf_x static void project_face_winding_init(const ProjPaintState *ps, const int tri_index) { /* detect the winding of faces in uv space */ - const MLoopTri *lt = &ps->dm_mlooptri[tri_index]; - const float *lt_tri_uv[3] = { PS_LOOPTRI_AS_UV_3(ps->dm_mloopuv, lt) }; + const MLoopTri *lt = &ps->mlooptri_eval[tri_index]; + const float *lt_tri_uv[3] = { PS_LOOPTRI_AS_UV_3(ps->poly_to_loop_uv, lt) }; float winding = cross_tri_v2(lt_tri_uv[0], lt_tri_uv[1], lt_tri_uv[2]); if (winding > 0) @@ -1019,11 +1024,11 @@ static bool check_seam( const int orig_face, const int orig_i1_fidx, const int orig_i2_fidx, int *other_face, int *orig_fidx) { - const MLoopTri *orig_lt = &ps->dm_mlooptri[orig_face]; - const float *orig_lt_tri_uv[3] = { PS_LOOPTRI_AS_UV_3(ps->dm_mloopuv, orig_lt) }; + const MLoopTri *orig_lt = &ps->mlooptri_eval[orig_face]; + const float *orig_lt_tri_uv[3] = { PS_LOOPTRI_AS_UV_3(ps->poly_to_loop_uv, orig_lt) }; /* vert indices from face vert order indices */ - const unsigned int i1 = ps->dm_mloop[orig_lt->tri[orig_i1_fidx]].v; - const unsigned int i2 = ps->dm_mloop[orig_lt->tri[orig_i2_fidx]].v; + const unsigned int i1 = ps->mloop_eval[orig_lt->tri[orig_i1_fidx]].v; + const unsigned int i2 = ps->mloop_eval[orig_lt->tri[orig_i2_fidx]].v; LinkNode *node; int i1_fidx = -1, i2_fidx = -1; /* index in face */ @@ -1031,7 +1036,7 @@ static bool check_seam( const int tri_index = GET_INT_FROM_POINTER(node->link); if (tri_index != orig_face) { - const MLoopTri *lt = &ps->dm_mlooptri[tri_index]; + const MLoopTri *lt = &ps->mlooptri_eval[tri_index]; const int lt_vtri[3] = { PS_LOOPTRI_AS_VERT_INDEX_3(ps, lt) }; /* could check if the 2 faces images match here, * but then there wouldn't be a way to return the opposite face's info */ @@ -1044,7 +1049,7 @@ static bool check_seam( /* Only need to check if 'i2_fidx' is valid because we know i1_fidx is the same vert on both faces */ if (i2_fidx != -1) { - const float *lt_tri_uv[3] = { PS_LOOPTRI_AS_UV_3(ps->dm_mloopuv, lt) }; + const float *lt_tri_uv[3] = { PS_LOOPTRI_AS_UV_3(ps->poly_to_loop_uv, lt) }; Image *tpage = project_paint_face_paint_image(ps, tri_index); Image *orig_tpage = project_paint_face_paint_image(ps, orig_face); @@ -1348,8 +1353,8 @@ static float project_paint_uvpixel_mask( Image *other_tpage = ps->stencil_ima; if (other_tpage && (ibuf_other = BKE_image_acquire_ibuf(other_tpage, NULL, NULL))) { - const MLoopTri *lt_other = &ps->dm_mlooptri[tri_index]; - const float *lt_other_tri_uv[3] = { PS_LOOPTRI_AS_UV_3(ps->dm_mloopuv, lt_other) }; + const MLoopTri *lt_other = &ps->mlooptri_eval[tri_index]; + const float *lt_other_tri_uv[3] = { PS_LOOPTRI_AS_UV_3(ps->poly_to_loop_uv, lt_other) }; /* BKE_image_acquire_ibuf - TODO - this may be slow */ unsigned char rgba_ub[4]; @@ -1382,7 +1387,7 @@ static float project_paint_uvpixel_mask( } if (ps->do_mask_cavity) { - const MLoopTri *lt = &ps->dm_mlooptri[tri_index]; + const MLoopTri *lt = &ps->mlooptri_eval[tri_index]; const int lt_vtri[3] = { PS_LOOPTRI_AS_VERT_INDEX_3(ps, lt) }; float ca1, ca2, ca3, ca_mask; ca1 = ps->cavities[lt_vtri[0]]; @@ -1397,16 +1402,16 @@ static float project_paint_uvpixel_mask( /* calculate mask */ if (ps->do_mask_normal) { - const MLoopTri *lt = &ps->dm_mlooptri[tri_index]; + const MLoopTri *lt = &ps->mlooptri_eval[tri_index]; const int lt_vtri[3] = { PS_LOOPTRI_AS_VERT_INDEX_3(ps, lt) }; - const MPoly *mp = &ps->dm_mpoly[lt->poly]; + const MPoly *mp = &ps->mpoly_eval[lt->poly]; float no[3], angle_cos; if (mp->flag & ME_SMOOTH) { const short *no1, *no2, *no3; - no1 = ps->dm_mvert[lt_vtri[0]].no; - no2 = ps->dm_mvert[lt_vtri[1]].no; - no3 = ps->dm_mvert[lt_vtri[2]].no; + no1 = ps->mvert_eval[lt_vtri[0]].no; + no2 = ps->mvert_eval[lt_vtri[1]].no; + no3 = ps->mvert_eval[lt_vtri[2]].no; no[0] = w[0] * no1[0] + w[1] * no2[0] + w[2] * no3[0]; no[1] = w[0] * no1[1] + w[1] * no2[1] + w[2] * no3[1]; @@ -1418,9 +1423,9 @@ static float project_paint_uvpixel_mask( #if 1 /* normalizing per pixel isn't optimal, we could cache or check ps->*/ normal_tri_v3(no, - ps->dm_mvert[lt_vtri[0]].co, - ps->dm_mvert[lt_vtri[1]].co, - ps->dm_mvert[lt_vtri[2]].co); + ps->mvert_eval[lt_vtri[0]].co, + ps->mvert_eval[lt_vtri[1]].co, + ps->mvert_eval[lt_vtri[2]].co); #else /* don't use because some modifiers dont have normal data (subsurf for eg) */ copy_v3_v3(no, (float *)ps->dm->getTessFaceData(ps->dm, tri_index, CD_NORMAL)); @@ -1439,9 +1444,9 @@ static float project_paint_uvpixel_mask( /* Annoying but for the perspective view we need to get the pixels location in 3D space :/ */ float viewDirPersp[3]; const float *co1, *co2, *co3; - co1 = ps->dm_mvert[lt_vtri[0]].co; - co2 = ps->dm_mvert[lt_vtri[1]].co; - co3 = ps->dm_mvert[lt_vtri[2]].co; + co1 = ps->mvert_eval[lt_vtri[0]].co; + co2 = ps->mvert_eval[lt_vtri[1]].co; + co3 = ps->mvert_eval[lt_vtri[2]].co; /* Get the direction from the viewPoint to the pixel and normalize */ viewDirPersp[0] = (ps->viewPos[0] - (w[0] * co1[0] + w[1] * co2[0] + w[2] * co3[0])); @@ -1610,13 +1615,13 @@ static ProjPixel *project_paint_uvpixel_init( /* done with view3d_project_float inline */ if (ps->tool == PAINT_TOOL_CLONE) { - if (ps->dm_mloopuv_clone) { + if (ps->poly_to_loop_uv_clone) { ImBuf *ibuf_other; Image *other_tpage = project_paint_face_clone_image(ps, tri_index); if (other_tpage && (ibuf_other = BKE_image_acquire_ibuf(other_tpage, NULL, NULL))) { - const MLoopTri *lt_other = &ps->dm_mlooptri[tri_index]; - const float *lt_other_tri_uv[3] = { PS_LOOPTRI_AS_UV_3(ps->dm_mloopuv_clone, lt_other) }; + const MLoopTri *lt_other = &ps->mlooptri_eval[tri_index]; + const float *lt_other_tri_uv[3] = { PS_LOOPTRI_AS_UV_3(ps->poly_to_loop_uv_clone, lt_other) }; /* BKE_image_acquire_ibuf - TODO - this may be slow */ @@ -2491,8 +2496,7 @@ static bool IsectPoly2Df_twoside(const float pt[2], float uv[][2], const int tot static void project_paint_face_init( const ProjPaintState *ps, const int thread_index, const int bucket_index, const int tri_index, const int image_index, - const rctf *clip_rect, const rctf *bucket_bounds, ImBuf *ibuf, ImBuf **tmpibuf, - const bool clamp_u, const bool clamp_v) + const rctf *clip_rect, const rctf *bucket_bounds, ImBuf *ibuf, ImBuf **tmpibuf) { /* Projection vars, to get the 3D locations into screen space */ MemArena *arena = ps->arena_mt[thread_index]; @@ -2508,9 +2512,9 @@ static void project_paint_face_init( ps->projImages + image_index }; - const MLoopTri *lt = &ps->dm_mlooptri[tri_index]; + const MLoopTri *lt = &ps->mlooptri_eval[tri_index]; const int lt_vtri[3] = { PS_LOOPTRI_AS_VERT_INDEX_3(ps, lt) }; - const float *lt_tri_uv[3] = { PS_LOOPTRI_AS_UV_3(ps->dm_mloopuv, lt) }; + const float *lt_tri_uv[3] = { PS_LOOPTRI_AS_UV_3(ps->poly_to_loop_uv, lt) }; /* UV/pixel seeking data */ int x; /* Image X-Pixel */ @@ -2544,9 +2548,9 @@ static void project_paint_face_init( const bool do_backfacecull = ps->do_backfacecull; const bool do_clip = ps->rv3d ? ps->rv3d->rflag & RV3D_CLIPPING : 0; - vCo[0] = ps->dm_mvert[lt_vtri[0]].co; - vCo[1] = ps->dm_mvert[lt_vtri[1]].co; - vCo[2] = ps->dm_mvert[lt_vtri[2]].co; + vCo[0] = ps->mvert_eval[lt_vtri[0]].co; + vCo[1] = ps->mvert_eval[lt_vtri[1]].co; + vCo[2] = ps->mvert_eval[lt_vtri[2]].co; /* Use lt_uv_pxoffset instead of lt_tri_uv so we can offset the UV half a pixel @@ -2599,17 +2603,6 @@ static void project_paint_face_init( #endif if (pixel_bounds_array(uv_clip, &bounds_px, ibuf->x, ibuf->y, uv_clip_tot)) { - - if (clamp_u) { - CLAMP(bounds_px.xmin, 0, ibuf->x); - CLAMP(bounds_px.xmax, 0, ibuf->x); - } - - if (clamp_v) { - CLAMP(bounds_px.ymin, 0, ibuf->y); - CLAMP(bounds_px.ymax, 0, ibuf->y); - } - #if 0 project_paint_undo_tiles_init(&bounds_px, ps->projImages + image_index, tmpibuf, tile_width, threaded, ps->do_masking); @@ -2641,9 +2634,9 @@ static void project_paint_face_init( if (do_clip || do_3d_mapping) { interp_v3_v3v3v3( wco, - ps->dm_mvert[lt_vtri[0]].co, - ps->dm_mvert[lt_vtri[1]].co, - ps->dm_mvert[lt_vtri[2]].co, + ps->mvert_eval[lt_vtri[0]].co, + ps->mvert_eval[lt_vtri[1]].co, + ps->mvert_eval[lt_vtri[2]].co, w); if (do_clip && ED_view3d_clipping_test(ps->rv3d, wco, true)) { continue; /* Watch out that no code below this needs to run */ @@ -2823,7 +2816,7 @@ static void project_paint_face_init( !project_bucket_point_occluded(ps, bucketFaceNodes, tri_index, pixelScreenCo)) { /* Only bother calculating the weights if we intersect */ - if (ps->do_mask_normal || ps->dm_mloopuv_clone) { + if (ps->do_mask_normal || ps->poly_to_loop_uv_clone) { const float uv_fac = fac1 + (fac * (fac2 - fac1)); #if 0 /* get the UV on the line since we want to copy the pixels from there for bleeding */ @@ -2926,19 +2919,16 @@ static void project_bucket_init( int tri_index, image_index = 0; ImBuf *ibuf = NULL; Image *tpage_last = NULL, *tpage; - Image *ima = NULL; ImBuf *tmpibuf = NULL; if (ps->image_tot == 1) { /* Simple loop, no context switching */ ibuf = ps->projImages[0].ibuf; - ima = ps->projImages[0].ima; for (node = ps->bucketFaces[bucket_index]; node; node = node->next) { project_paint_face_init( ps, thread_index, bucket_index, GET_INT_FROM_POINTER(node->link), 0, - clip_rect, bucket_bounds, ibuf, &tmpibuf, - (ima->tpageflag & IMA_CLAMP_U) != 0, (ima->tpageflag & IMA_CLAMP_V) != 0); + clip_rect, bucket_bounds, ibuf, &tmpibuf); } } else { @@ -2955,7 +2945,6 @@ static void project_bucket_init( for (image_index = 0; image_index < ps->image_tot; image_index++) { if (ps->projImages[image_index].ima == tpage_last) { ibuf = ps->projImages[image_index].ibuf; - ima = ps->projImages[image_index].ima; break; } } @@ -2964,8 +2953,7 @@ static void project_bucket_init( project_paint_face_init( ps, thread_index, bucket_index, tri_index, image_index, - clip_rect, bucket_bounds, ibuf, &tmpibuf, - (ima->tpageflag & IMA_CLAMP_U) != 0, (ima->tpageflag & IMA_CLAMP_V) != 0); + clip_rect, bucket_bounds, ibuf, &tmpibuf); } } @@ -3081,26 +3069,8 @@ static void project_paint_delayed_face_init(ProjPaintState *ps, const MLoopTri * #endif } -/** - * \note when using subsurf or multires, some arrays are thrown away, we need to keep a copy - */ -static void proj_paint_state_non_cddm_init(ProjPaintState *ps) -{ - if (ps->dm->type != DM_TYPE_CDDM) { - ps->dm_mvert = MEM_dupallocN(ps->dm_mvert); - ps->dm_mpoly = MEM_dupallocN(ps->dm_mpoly); - ps->dm_mloop = MEM_dupallocN(ps->dm_mloop); - /* looks like these are ok for now.*/ -#if 0 - ps->dm_mloopuv = MEM_dupallocN(ps->dm_mloopuv); - ps->dm_mloopuv_clone = MEM_dupallocN(ps->dm_mloopuv_clone); - ps->dm_mloopuv_stencil = MEM_dupallocN(ps->dm_mloopuv_stencil); -#endif - } -} - static void proj_paint_state_viewport_init( - ProjPaintState *ps, const char symmetry_flag) + ProjPaintState *ps, const Depsgraph *depsgraph, const char symmetry_flag) { float mat[3][3]; float viewmat[4][4]; @@ -3134,7 +3104,7 @@ static void proj_paint_state_viewport_init( ED_view3d_ob_project_mat_get_from_obmat(ps->rv3d, ps->obmat, ps->projectMat); - ps->is_ortho = ED_view3d_clip_range_get(ps->v3d, ps->rv3d, &ps->clipsta, &ps->clipend, true); + ps->is_ortho = ED_view3d_clip_range_get(ps->depsgraph, ps->v3d, ps->rv3d, &ps->clipsta, &ps->clipend, true); } else { /* re-projection */ @@ -3161,17 +3131,17 @@ static void proj_paint_state_viewport_init( invert_m4_m4(viewinv, viewmat); } else if (ps->source == PROJ_SRC_IMAGE_CAM) { - Object *cam_ob = ps->scene->camera; + Object *cam_ob_eval = DEG_get_evaluated_object(depsgraph, ps->scene->camera); CameraParams params; /* viewmat & viewinv */ - copy_m4_m4(viewinv, cam_ob->obmat); + copy_m4_m4(viewinv, cam_ob_eval->obmat); normalize_m4(viewinv); invert_m4_m4(viewmat, viewinv); /* window matrix, clipping and ortho */ BKE_camera_params_init(¶ms); - BKE_camera_params_from_object(¶ms, cam_ob); + BKE_camera_params_from_object(¶ms, cam_ob_eval); BKE_camera_params_compute_viewplane(¶ms, ps->winx, ps->winy, 1.0f, 1.0f); BKE_camera_params_compute_matrix(¶ms); @@ -3218,11 +3188,11 @@ static void proj_paint_state_screen_coords_init(ProjPaintState *ps, const int di INIT_MINMAX2(ps->screenMin, ps->screenMax); - ps->screenCoords = MEM_mallocN(sizeof(float) * ps->dm_totvert * 4, "ProjectPaint ScreenVerts"); + ps->screenCoords = MEM_mallocN(sizeof(float) * ps->totvert_eval * 4, "ProjectPaint ScreenVerts"); projScreenCo = *ps->screenCoords; if (ps->is_ortho) { - for (a = 0, mv = ps->dm_mvert; a < ps->dm_totvert; a++, mv++, projScreenCo += 4) { + for (a = 0, mv = ps->mvert_eval; a < ps->totvert_eval; a++, mv++, projScreenCo += 4) { mul_v3_m4v3(projScreenCo, ps->projectMat, mv->co); /* screen space, not clamped */ @@ -3232,7 +3202,7 @@ static void proj_paint_state_screen_coords_init(ProjPaintState *ps, const int di } } else { - for (a = 0, mv = ps->dm_mvert; a < ps->dm_totvert; a++, mv++, projScreenCo += 4) { + for (a = 0, mv = ps->mvert_eval; a < ps->totvert_eval; a++, mv++, projScreenCo += 4) { copy_v3_v3(projScreenCo, mv->co); projScreenCo[3] = 1.0f; @@ -3293,21 +3263,21 @@ static void proj_paint_state_cavity_init(ProjPaintState *ps) int a; if (ps->do_mask_cavity) { - int *counter = MEM_callocN(sizeof(int) * ps->dm_totvert, "counter"); - float (*edges)[3] = MEM_callocN(sizeof(float) * 3 * ps->dm_totvert, "edges"); - ps->cavities = MEM_mallocN(sizeof(float) * ps->dm_totvert, "ProjectPaint Cavities"); + int *counter = MEM_callocN(sizeof(int) * ps->totvert_eval, "counter"); + float (*edges)[3] = MEM_callocN(sizeof(float) * 3 * ps->totvert_eval, "edges"); + ps->cavities = MEM_mallocN(sizeof(float) * ps->totvert_eval, "ProjectPaint Cavities"); cavities = ps->cavities; - for (a = 0, me = ps->dm_medge; a < ps->dm_totedge; a++, me++) { + for (a = 0, me = ps->medge_eval; a < ps->totedge_eval; a++, me++) { float e[3]; - sub_v3_v3v3(e, ps->dm_mvert[me->v1].co, ps->dm_mvert[me->v2].co); + sub_v3_v3v3(e, ps->mvert_eval[me->v1].co, ps->mvert_eval[me->v2].co); normalize_v3(e); add_v3_v3(edges[me->v2], e); counter[me->v2]++; sub_v3_v3(edges[me->v1], e); counter[me->v1]++; } - for (a = 0, mv = ps->dm_mvert; a < ps->dm_totvert; a++, mv++) { + for (a = 0, mv = ps->mvert_eval; a < ps->totvert_eval; a++, mv++) { if (counter[a] > 0) { float no[3]; mul_v3_fl(edges[a], 1.0f / counter[a]); @@ -3328,10 +3298,10 @@ static void proj_paint_state_cavity_init(ProjPaintState *ps) static void proj_paint_state_seam_bleed_init(ProjPaintState *ps) { if (ps->seam_bleed_px > 0.0f) { - ps->vertFaces = MEM_callocN(sizeof(LinkNode *) * ps->dm_totvert, "paint-vertFaces"); - ps->faceSeamFlags = MEM_callocN(sizeof(char) * ps->dm_totlooptri, "paint-faceSeamFlags"); - ps->faceWindingFlags = MEM_callocN(sizeof(char) * ps->dm_totlooptri, "paint-faceWindindFlags"); - ps->faceSeamUVs = MEM_mallocN(sizeof(float[3][2]) * ps->dm_totlooptri, "paint-faceSeamUVs"); + ps->vertFaces = MEM_callocN(sizeof(LinkNode *) * ps->totvert_eval, "paint-vertFaces"); + ps->faceSeamFlags = MEM_callocN(sizeof(char) * ps->totlooptri_eval, "paint-faceSeamFlags"); + ps->faceWindingFlags = MEM_callocN(sizeof(char) * ps->totlooptri_eval, "paint-faceWindindFlags"); + ps->faceSeamUVs = MEM_mallocN(sizeof(float[3][2]) * ps->totlooptri_eval, "paint-faceSeamUVs"); } } #endif @@ -3375,9 +3345,9 @@ static void proj_paint_state_vert_flags_init(ProjPaintState *ps) float no[3]; int a; - ps->vertFlags = MEM_callocN(sizeof(char) * ps->dm_totvert, "paint-vertFlags"); + ps->vertFlags = MEM_callocN(sizeof(char) * ps->totvert_eval, "paint-vertFlags"); - for (a = 0, mv = ps->dm_mvert; a < ps->dm_totvert; a++, mv++) { + for (a = 0, mv = ps->mvert_eval; a < ps->totvert_eval; a++, mv++) { normal_short_to_float_v3(no, mv->no); if (UNLIKELY(ps->is_flip_object)) { negate_v3(no); @@ -3422,49 +3392,63 @@ static void project_paint_bleed_add_face_user( } #endif -/* Return true if DM can be painted on, false otherwise */ -static bool proj_paint_state_dm_init(ProjPaintState *ps) +/* Return true if evaluated mesh can be painted on, false otherwise */ +static bool proj_paint_state_mesh_eval_init(const bContext *C, ProjPaintState *ps) { + Depsgraph *depsgraph = CTX_data_depsgraph(C); + Scene *sce = ps->scene; + Object *ob = ps->ob; + /* Workaround for subsurf selection, try the display mesh first */ + /* XXX Don't think this is easily doable with new system, and not sure why that was needed in the first place :/ */ +#if 0 if (ps->source == PROJ_SRC_IMAGE_CAM) { /* using render mesh, assume only camera was rendered from */ - ps->dm = mesh_create_derived_render(ps->scene, ps->ob, ps->scene->customdata_mask | CD_MASK_MLOOPUV | CD_MASK_MTFACE); + ps->dm = mesh_create_derived_render( + depsgraph, ps->scene, ps->ob, ps->scene->customdata_mask | CD_MASK_MLOOPUV | CD_MASK_MTFACE); ps->dm_release = true; } else { ps->dm = mesh_get_derived_final( - ps->scene, ps->ob, + depsgraph, ps->scene, ps->ob, ps->scene->customdata_mask | CD_MASK_MLOOPUV | CD_MASK_MTFACE | (ps->do_face_sel ? CD_MASK_ORIGINDEX : 0)); ps->dm_release = false; } - - if (!CustomData_has_layer(&ps->dm->loopData, CD_MLOOPUV)) { - - if (ps->dm_release) - ps->dm->release(ps->dm); - - ps->dm = NULL; +#endif + ps->me_eval = mesh_get_eval_final( + depsgraph, sce, ob, + sce->customdata_mask | CD_MASK_MLOOPUV | CD_MASK_MTFACE | (ps->do_face_sel ? CD_MASK_ORIGINDEX : 0)); + if (!CustomData_has_layer(&ps->me_eval->ldata, CD_MLOOPUV)) { + ps->me_eval = NULL; return false; } - DM_update_materials(ps->dm, ps->ob); - - ps->dm_mvert = ps->dm->getVertArray(ps->dm); - - if (ps->do_mask_cavity) - ps->dm_medge = ps->dm->getEdgeArray(ps->dm); + /* Build final material array, we use this a lot here. */ + const int totmat = ob->totcol + 1; /* materials start from 1, default material is 0 */ + ps->mat_array = MEM_malloc_arrayN(totmat, sizeof(*ps->mat_array), __func__); + /* We leave last material as empty - rationale here is being able to index + * the materials by using the mf->mat_nr directly and leaving the last + * material as NULL in case no materials exist on mesh, so indexing will not fail. */ + for (int i = 0; i < totmat - 1; i++) { + ps->mat_array[i] = give_current_material(ob, i + 1); + } + ps->mat_array[totmat - 1] = NULL; - ps->dm_mloop = ps->dm->getLoopArray(ps->dm); - ps->dm_mpoly = ps->dm->getPolyArray(ps->dm); + ps->mvert_eval = ps->me_eval->mvert; + if (ps->do_mask_cavity) { + ps->medge_eval = ps->me_eval->medge; + } + ps->mloop_eval = ps->me_eval->mloop; + ps->mpoly_eval = ps->me_eval->mpoly; - ps->dm_mlooptri = ps->dm->getLoopTriArray(ps->dm); + ps->totvert_eval = ps->me_eval->totvert; + ps->totedge_eval = ps->me_eval->totedge; + ps->totpoly_eval = ps->me_eval->totpoly; - ps->dm_totvert = ps->dm->getNumVerts(ps->dm); - ps->dm_totedge = ps->dm->getNumEdges(ps->dm); - ps->dm_totpoly = ps->dm->getNumPolys(ps->dm); - ps->dm_totlooptri = ps->dm->getNumLoopTri(ps->dm); + ps->mlooptri_eval = BKE_mesh_runtime_looptri_ensure(ps->me_eval); + ps->totlooptri_eval = ps->me_eval->runtime.looptris.len; - ps->dm_mloopuv = MEM_mallocN(ps->dm_totpoly * sizeof(MLoopUV *), "proj_paint_mtfaces"); + ps->poly_to_loop_uv = MEM_mallocN(ps->totpoly_eval * sizeof(MLoopUV *), "proj_paint_mtfaces"); return true; } @@ -3483,16 +3467,16 @@ static void proj_paint_layer_clone_init( /* use clone mtface? */ if (ps->do_layer_clone) { - const int layer_num = CustomData_get_clone_layer(&((Mesh *)ps->ob->data)->pdata, CD_MTEXPOLY); + const int layer_num = CustomData_get_clone_layer(&((Mesh *)ps->ob->data)->ldata, CD_MLOOPUV); - ps->dm_mloopuv_clone = MEM_mallocN(ps->dm_totpoly * sizeof(MLoopUV *), "proj_paint_mtfaces"); + ps->poly_to_loop_uv_clone = MEM_mallocN(ps->totpoly_eval * sizeof(MLoopUV *), "proj_paint_mtfaces"); if (layer_num != -1) - mloopuv_clone_base = CustomData_get_layer_n(&ps->dm->loopData, CD_MLOOPUV, layer_num); + mloopuv_clone_base = CustomData_get_layer_n(&ps->me_eval->ldata, CD_MLOOPUV, layer_num); if (mloopuv_clone_base == NULL) { /* get active instead */ - mloopuv_clone_base = CustomData_get_layer(&ps->dm->loopData, CD_MLOOPUV); + mloopuv_clone_base = CustomData_get_layer(&ps->me_eval->ldata, CD_MLOOPUV); } } @@ -3522,17 +3506,17 @@ static bool project_paint_clone_face_skip( if (lc->slot_clone != lc->slot_last_clone) { if (!slot->uvname || !(lc->mloopuv_clone_base = CustomData_get_layer_named( - &ps->dm->loopData, CD_MLOOPUV, + &ps->me_eval->ldata, CD_MLOOPUV, lc->slot_clone->uvname))) { - lc->mloopuv_clone_base = CustomData_get_layer(&ps->dm->loopData, CD_MLOOPUV); + lc->mloopuv_clone_base = CustomData_get_layer(&ps->me_eval->ldata, CD_MLOOPUV); } lc->slot_last_clone = lc->slot_clone; } } /* will set multiple times for 4+ sided poly */ - ps->dm_mloopuv_clone[ps->dm_mlooptri[tri_index].poly] = lc->mloopuv_clone_base; + ps->poly_to_loop_uv_clone[ps->mlooptri_eval[tri_index].poly] = lc->mloopuv_clone_base; } return false; } @@ -3549,7 +3533,7 @@ static void proj_paint_face_lookup_init( { memset(face_lookup, 0, sizeof(*face_lookup)); if (ps->do_face_sel) { - face_lookup->index_mp_to_orig = ps->dm->getPolyDataArray(ps->dm, CD_ORIGINDEX); + face_lookup->index_mp_to_orig = CustomData_get_layer(&ps->me_eval->pdata, CD_ORIGINDEX); face_lookup->mpoly_orig = ((Mesh *)ps->ob->data)->mpoly; } } @@ -3570,7 +3554,7 @@ static bool project_paint_check_face_sel( mp = &face_lookup->mpoly_orig[orig_index]; } else { - mp = &ps->dm_mpoly[lt->poly]; + mp = &ps->mpoly_eval[lt->poly]; } return ((mp->flag & ME_FACE_SEL) != 0); @@ -3684,7 +3668,7 @@ static void project_paint_prepare_all_faces( int image_index = -1, tri_index; int prev_poly = -1; - for (tri_index = 0, lt = ps->dm_mlooptri; tri_index < ps->dm_totlooptri; tri_index++, lt++) { + for (tri_index = 0, lt = ps->mlooptri_eval; tri_index < ps->totlooptri_eval; tri_index++, lt++) { bool is_face_sel; #ifndef PROJ_DEBUG_NOSEAMBLEED @@ -3697,13 +3681,13 @@ static void project_paint_prepare_all_faces( slot = project_paint_face_paint_slot(ps, tri_index); /* all faces should have a valid slot, reassert here */ if (slot == NULL) { - mloopuv_base = CustomData_get_layer(&ps->dm->loopData, CD_MLOOPUV); + mloopuv_base = CustomData_get_layer(&ps->me_eval->ldata, CD_MLOOPUV); tpage = ps->canvas_ima; } else { if (slot != slot_last) { - if (!slot->uvname || !(mloopuv_base = CustomData_get_layer_named(&ps->dm->loopData, CD_MLOOPUV, slot->uvname))) - mloopuv_base = CustomData_get_layer(&ps->dm->loopData, CD_MLOOPUV); + if (!slot->uvname || !(mloopuv_base = CustomData_get_layer_named(&ps->me_eval->ldata, CD_MLOOPUV, slot->uvname))) + mloopuv_base = CustomData_get_layer(&ps->me_eval->ldata, CD_MLOOPUV); slot_last = slot; } @@ -3711,7 +3695,7 @@ static void project_paint_prepare_all_faces( if (slot->ima == ps->stencil_ima) { /* While this shouldn't be used, face-winding reads all polys. * It's less trouble to set all faces to valid UV's, avoiding NULL checks all over. */ - ps->dm_mloopuv[lt->poly] = mloopuv_base; + ps->poly_to_loop_uv[lt->poly] = mloopuv_base; continue; } @@ -3722,7 +3706,7 @@ static void project_paint_prepare_all_faces( tpage = ps->stencil_ima; } - ps->dm_mloopuv[lt->poly] = mloopuv_base; + ps->poly_to_loop_uv[lt->poly] = mloopuv_base; if (project_paint_clone_face_skip(ps, layer_clone, slot, tri_index)) { continue; @@ -3753,11 +3737,11 @@ static void project_paint_prepare_all_faces( if (prev_poly != lt->poly) { int iloop; bool culled = true; - const MPoly *poly = ps->dm_mpoly + lt->poly; + const MPoly *poly = ps->mpoly_eval + lt->poly; int poly_loops = poly->totloop; prev_poly = lt->poly; for (iloop = 0; iloop < poly_loops; iloop++) { - if (!(ps->vertFlags[ps->dm_mloop[poly->loopstart + iloop].v] & PROJ_VERT_CULL)) { + if (!(ps->vertFlags[ps->mloop_eval[poly->loopstart + iloop].v] & PROJ_VERT_CULL)) { culled = false; break; } @@ -3813,7 +3797,7 @@ static void project_paint_prepare_all_faces( /* run once per stroke before projection painting */ static void project_paint_begin( - ProjPaintState *ps, + const bContext *C, ProjPaintState *ps, const bool is_multi_view, const char symmetry_flag) { ProjPaintLayerClone layer_clone; @@ -3836,7 +3820,7 @@ static void project_paint_begin( /* paint onto the derived mesh */ if (ps->is_shared_user == false) { - if (!proj_paint_state_dm_init(ps)) { + if (!proj_paint_state_mesh_eval_init(C, ps)) { return; } } @@ -3845,28 +3829,26 @@ static void project_paint_begin( proj_paint_layer_clone_init(ps, &layer_clone); if (ps->do_layer_stencil || ps->do_stencil_brush) { - //int layer_num = CustomData_get_stencil_layer(&ps->dm->loopData, CD_MLOOPUV); - int layer_num = CustomData_get_stencil_layer(&((Mesh *)ps->ob->data)->pdata, CD_MTEXPOLY); + //int layer_num = CustomData_get_stencil_layer(&ps->me_eval->ldata, CD_MLOOPUV); + int layer_num = CustomData_get_stencil_layer(&((Mesh *)ps->ob->data)->ldata, CD_MLOOPUV); if (layer_num != -1) - ps->dm_mloopuv_stencil = CustomData_get_layer_n(&ps->dm->loopData, CD_MLOOPUV, layer_num); + ps->mloopuv_stencil_eval = CustomData_get_layer_n(&ps->me_eval->ldata, CD_MLOOPUV, layer_num); - if (ps->dm_mloopuv_stencil == NULL) { + if (ps->mloopuv_stencil_eval == NULL) { /* get active instead */ - ps->dm_mloopuv_stencil = CustomData_get_layer(&ps->dm->loopData, CD_MLOOPUV); + ps->mloopuv_stencil_eval = CustomData_get_layer(&ps->me_eval->ldata, CD_MLOOPUV); } if (ps->do_stencil_brush) - mloopuv_base = ps->dm_mloopuv_stencil; + mloopuv_base = ps->mloopuv_stencil_eval; } /* when using subsurf or multires, mface arrays are thrown away, we need to keep a copy */ if (ps->is_shared_user == false) { - proj_paint_state_non_cddm_init(ps); - proj_paint_state_cavity_init(ps); } - proj_paint_state_viewport_init(ps, symmetry_flag); + proj_paint_state_viewport_init(ps, CTX_data_depsgraph(C), symmetry_flag); /* calculate vert screen coords * run this early so we can calculate the x/y resolution of our bucket rect */ @@ -3913,7 +3895,7 @@ static void paint_proj_begin_clone(ProjPaintState *ps, const float mouse[2]) /* setup clone offset */ if (ps->tool == PAINT_TOOL_CLONE) { float projCo[4]; - copy_v3_v3(projCo, ED_view3d_cursor3d_get(ps->scene, ps->v3d)); + copy_v3_v3(projCo, ED_view3d_cursor3d_get(ps->scene, ps->v3d)->location); mul_m4_v3(ps->obmat_imat, projCo); projCo[3] = 1.0f; @@ -3934,7 +3916,7 @@ static void project_paint_end(ProjPaintState *ps) ProjPaintImage *projIma; for (a = 0, projIma = ps->projImages; a < ps->image_tot; a++, projIma++) { BKE_image_release_ibuf(projIma->ima, projIma->ibuf, NULL); - DAG_id_tag_update(&projIma->ima->id, 0); + DEG_id_tag_update(&projIma->ima->id, 0); } } @@ -3952,14 +3934,17 @@ static void project_paint_end(ProjPaintState *ps) MEM_freeN(ps->bucketFlags); if (ps->is_shared_user == false) { + if (ps->mat_array != NULL) { + MEM_freeN(ps->mat_array); + } /* must be set for non-shared */ - BLI_assert(ps->dm_mloopuv || ps->is_shared_user); - if (ps->dm_mloopuv) - MEM_freeN((void *)ps->dm_mloopuv); + BLI_assert(ps->poly_to_loop_uv || ps->is_shared_user); + if (ps->poly_to_loop_uv) + MEM_freeN((void *)ps->poly_to_loop_uv); if (ps->do_layer_clone) - MEM_freeN((void *)ps->dm_mloopuv_clone); + MEM_freeN((void *)ps->poly_to_loop_uv_clone); if (ps->thread_tot > 1) { BLI_spin_end(ps->tile_lock); MEM_freeN((void *)ps->tile_lock); @@ -3979,22 +3964,6 @@ static void project_paint_end(ProjPaintState *ps) if (ps->do_mask_cavity) { MEM_freeN(ps->cavities); } - - /* copy for subsurf/multires, so throw away */ - if (ps->dm->type != DM_TYPE_CDDM) { - if (ps->dm_mvert) MEM_freeN((void *)ps->dm_mvert); - if (ps->dm_mpoly) MEM_freeN((void *)ps->dm_mpoly); - if (ps->dm_mloop) MEM_freeN((void *)ps->dm_mloop); - /* looks like these don't need copying */ -#if 0 - if (ps->dm_mloopuv) MEM_freeN(ps->dm_mloopuv); - if (ps->dm_mloopuv_clone) MEM_freeN(ps->dm_mloopuv_clone); - if (ps->dm_mloopuv_stencil) MEM_freeN(ps->dm_mloopuv_stencil); -#endif - } - - if (ps->dm_release) - ps->dm->release(ps->dm); } if (ps->blurkernel) { @@ -4869,7 +4838,7 @@ static bool project_paint_op(void *state, const float lastpos[2], const float po struct ImagePool *pool; if (!project_bucket_iter_init(ps, pos)) { - return 0; + return touch_any; } if (ps->thread_tot > 1) @@ -4935,16 +4904,16 @@ static bool project_paint_op(void *state, const float lastpos[2], const float po tri_index = project_paint_PickFace(ps, pos, w); if (tri_index != -1) { - const MLoopTri *lt = &ps->dm_mlooptri[tri_index]; + const MLoopTri *lt = &ps->mlooptri_eval[tri_index]; const int lt_vtri[3] = { PS_LOOPTRI_AS_VERT_INDEX_3(ps, lt) }; float world[3]; UnifiedPaintSettings *ups = &ps->scene->toolsettings->unified_paint_settings; interp_v3_v3v3v3( world, - ps->dm_mvert[lt_vtri[0]].co, - ps->dm_mvert[lt_vtri[1]].co, - ps->dm_mvert[lt_vtri[2]].co, + ps->mvert_eval[lt_vtri[0]].co, + ps->mvert_eval[lt_vtri[1]].co, + ps->mvert_eval[lt_vtri[2]].co, w); ups->average_stroke_counter++; @@ -5019,17 +4988,18 @@ void paint_proj_stroke( /* clone gets special treatment here to avoid going through image initialization */ if (ps_handle->is_clone_cursor_pick) { - Main *bmain = CTX_data_main(C); Scene *scene = ps_handle->scene; + struct Depsgraph *depsgraph = CTX_data_depsgraph(C); View3D *v3d = CTX_wm_view3d(C); ARegion *ar = CTX_wm_region(C); - float *cursor = ED_view3d_cursor3d_get(scene, v3d); + float *cursor = ED_view3d_cursor3d_get(scene, v3d)->location; int mval_i[2] = {(int)pos[0], (int)pos[1]}; view3d_operator_needs_opengl(C); - if (!ED_view3d_autodist(bmain, scene, ar, v3d, mval_i, cursor, false, NULL)) + if (!ED_view3d_autodist(depsgraph, ar, v3d, mval_i, cursor, false, NULL)) { return; + } ED_region_tag_redraw(ar); @@ -5085,6 +5055,7 @@ static void project_state_init(bContext *C, Object *ob, ProjPaintState *ps, int ps->rv3d = CTX_wm_region_view3d(C); ps->ar = CTX_wm_region(C); + ps->depsgraph = CTX_data_depsgraph(C); ps->scene = scene; ps->ob = ob; /* allow override of active object */ @@ -5107,7 +5078,6 @@ static void project_state_init(bContext *C, Object *ob, ProjPaintState *ps, int else { ps->do_backfacecull = ps->do_occlude = ps->do_mask_normal = 0; } - ps->do_new_shading_nodes = BKE_scene_use_new_shading_nodes(scene); /* only cache the value */ if (ps->tool == PAINT_TOOL_CLONE) ps->do_layer_clone = (settings->imapaint.flag & IMAGEPAINT_PROJECT_LAYER_CLONE) ? 1 : 0; @@ -5207,7 +5177,7 @@ void *paint_proj_new_stroke(bContext *C, Object *ob, const float mouse[2], int m project_state_init(C, ob, ps, mode); - if (ps->ob == NULL || !(ps->ob->lay & ps->v3d->lay)) { + if (ps->ob == NULL) { ps_handle->ps_views_tot = i + 1; goto fail; } @@ -5231,14 +5201,12 @@ void *paint_proj_new_stroke(bContext *C, Object *ob, const float mouse[2], int m PROJ_PAINT_STATE_SHARED_MEMCPY(ps, ps_handle->ps_views[0]); } - project_paint_begin(ps, is_multi_view, symmetry_flag_views[i]); - - paint_proj_begin_clone(ps, mouse); - - if (ps->dm == NULL) { + project_paint_begin(C, ps, is_multi_view, symmetry_flag_views[i]); + if (ps->me_eval == NULL) { goto fail; - return NULL; } + + paint_proj_begin_clone(ps, mouse); } paint_brush_init_tex(ps_handle->brush); @@ -5309,11 +5277,12 @@ static int texture_paint_camera_project_exec(bContext *C, wmOperator *op) { Image *image = BLI_findlink(&CTX_data_main(C)->image, RNA_enum_get(op->ptr, "image")); Scene *scene = CTX_data_scene(C); + ViewLayer *view_layer = CTX_data_view_layer(C); ProjPaintState ps = {NULL}; int orig_brush_size; IDProperty *idgroup; IDProperty *view_data = NULL; - Object *ob = OBACT; + Object *ob = OBACT(view_layer); bool uvs, mat, tex; if (ob == NULL || ob->type != OB_MESH) { @@ -5383,10 +5352,11 @@ static int texture_paint_camera_project_exec(bContext *C, wmOperator *op) ED_image_undo_push_begin(op->type->name); /* allocate and initialize spatial data structures */ - project_paint_begin(&ps, false, 0); + project_paint_begin(C, &ps, false, 0); - if (ps.dm == NULL) { + if (ps.me_eval == NULL) { BKE_brush_size_set(scene, ps.brush, orig_brush_size); + BKE_report(op->reports, RPT_ERROR, "Could not get valid evaluated mesh"); return OPERATOR_CANCELLED; } else { @@ -5441,8 +5411,11 @@ static int texture_paint_image_from_view_exec(bContext *C, wmOperator *op) char filename[FILE_MAX]; Main *bmain = CTX_data_main(C); + Depsgraph *depsgraph = CTX_data_depsgraph(C); Scene *scene = CTX_data_scene(C); ToolSettings *settings = scene->toolsettings; + View3D *v3d = CTX_wm_view3d(C); + RegionView3D *rv3d = CTX_wm_region_view3d(C); int w = settings->imapaint.screen_grab_size[0]; int h = settings->imapaint.screen_grab_size[1]; int maxsize; @@ -5456,9 +5429,10 @@ static int texture_paint_image_from_view_exec(bContext *C, wmOperator *op) if (h > maxsize) h = maxsize; ibuf = ED_view3d_draw_offscreen_imbuf( - bmain, scene, CTX_wm_view3d(C), CTX_wm_region(C), + depsgraph, scene, v3d->drawtype, + v3d, CTX_wm_region(C), w, h, IB_rect, V3D_OFSDRAW_NONE, R_ALPHAPREMUL, 0, NULL, - NULL, NULL, err_out); + NULL, err_out); if (!ibuf) { /* Mostly happens when OpenGL offscreen buffer was failed to create, */ /* but could be other reasons. Should be handled in the future. nazgul */ @@ -5474,9 +5448,6 @@ static int texture_paint_image_from_view_exec(bContext *C, wmOperator *op) if (image) { /* now for the trickiness. store the view projection here! * re-projection will reuse this */ - View3D *v3d = CTX_wm_view3d(C); - RegionView3D *rv3d = CTX_wm_region_view3d(C); - IDPropertyTemplate val; IDProperty *idgroup = IDP_GetProperties(&image->id, 1); IDProperty *view_data; @@ -5490,7 +5461,7 @@ static int texture_paint_image_from_view_exec(bContext *C, wmOperator *op) array = (float *)IDP_Array(view_data); memcpy(array, rv3d->winmat, sizeof(rv3d->winmat)); array += sizeof(rv3d->winmat) / sizeof(float); memcpy(array, rv3d->viewmat, sizeof(rv3d->viewmat)); array += sizeof(rv3d->viewmat) / sizeof(float); - is_ortho = ED_view3d_clip_range_get(v3d, rv3d, &array[0], &array[1], true); + is_ortho = ED_view3d_clip_range_get(CTX_data_depsgraph(C), v3d, rv3d, &array[0], &array[1], true); /* using float for a bool is dodgy but since its an extra member in the array... * easier then adding a single bool prop */ array[2] = is_ortho ? 1.0f : 0.0f; @@ -5590,7 +5561,7 @@ bool BKE_paint_proj_mesh_data_check(Scene *scene, Object *ob, bool *uvs, bool *m } me = BKE_mesh_from_object(ob); - layernum = CustomData_number_of_layers(&me->pdata, CD_MTEXPOLY); + layernum = CustomData_number_of_layers(&me->ldata, CD_MLOOPUV); if (layernum == 0) { hasuvs = false; @@ -5629,20 +5600,11 @@ bool BKE_paint_proj_mesh_data_check(Scene *scene, Object *ob, bool *uvs, bool *m /* Add layer operator */ static const EnumPropertyItem layer_type_items[] = { - {MAP_COL, "DIFFUSE_COLOR", 0, "Diffuse Color", ""}, - {MAP_REF, "DIFFUSE_INTENSITY", 0, "Diffuse Intensity", ""}, - {MAP_ALPHA, "ALPHA", 0, "Alpha", ""}, - {MAP_TRANSLU, "TRANSLUCENCY", 0, "Translucency", ""}, - {MAP_COLSPEC, "SPECULAR_COLOR", 0, "Specular Color", ""}, - {MAP_SPEC, "SPECULAR_INTENSITY", 0, "Specular Intensity", ""}, - {MAP_HAR, "SPECULAR_HARDNESS", 0, "Specular Hardness", ""}, - {MAP_AMB, "AMBIENT", 0, "Ambient", ""}, - {MAP_EMIT, "EMIT", 0, "Emit", ""}, - {MAP_COLMIR, "MIRROR_COLOR", 0, "Mirror Color", ""}, - {MAP_RAYMIRR, "RAYMIRROR", 0, "Ray Mirror", ""}, - {MAP_NORM, "NORMAL", 0, "Normal", ""}, - {MAP_WARP, "WARP", 0, "Warp", ""}, - {MAP_DISPLACE, "DISPLACE", 0, "Displace", ""}, + {0, "BASE_COLOR", 0, "Base Color", ""}, + {1, "EMISSION", 0, "Emission", ""}, + {2, "NORMAL", 0, "Normal", ""}, + {3, "BUMP", 0, "Bump", ""}, + {4, "DISPLACEMENT", 0, "Displacement", ""}, {0, NULL, 0, NULL, NULL} }; @@ -5677,7 +5639,6 @@ static bool proj_paint_add_slot(bContext *C, wmOperator *op) Object *ob = ED_object_active_context(C); Scene *scene = CTX_data_scene(C); Material *ma; - bool is_bi = BKE_scene_uses_blender_internal(scene) || BKE_scene_uses_blender_game(scene); Image *ima = NULL; if (!ob) @@ -5686,60 +5647,34 @@ static bool proj_paint_add_slot(bContext *C, wmOperator *op) ma = give_current_material(ob, ob->actcol); if (ma) { + /* TODO: use type to link to proper socket. */ Main *bmain = CTX_data_main(C); - if (!is_bi && BKE_scene_use_new_shading_nodes(scene)) { - bNode *imanode; - bNodeTree *ntree = ma->nodetree; + bNode *imanode; + bNodeTree *ntree = ma->nodetree; - if (!ntree) { - ED_node_shader_default(C, &ma->id); - ntree = ma->nodetree; - } - - ma->use_nodes = true; + if (!ntree) { + ED_node_shader_default(C, &ma->id); + ntree = ma->nodetree; + } - /* try to add an image node */ - imanode = nodeAddStaticNode(C, ntree, SH_NODE_TEX_IMAGE); + ma->use_nodes = true; - ima = proj_paint_image_create(op, bmain); - imanode->id = &ima->id; + /* try to add an image node */ + imanode = nodeAddStaticNode(C, ntree, SH_NODE_TEX_IMAGE); - nodeSetActive(ntree, imanode); + ima = proj_paint_image_create(op, bmain); + imanode->id = &ima->id; - ntreeUpdateTree(CTX_data_main(C), ntree); - } - else { - MTex *mtex = BKE_texture_mtex_add_id(&ma->id, -1); - - /* successful creation of mtex layer, now create set */ - if (mtex) { - int type = MAP_COL; - char imagename_buff[MAX_ID_NAME - 2]; - const char *imagename = DATA_("Diffuse Color"); - - if (op) { - type = RNA_enum_get(op->ptr, "type"); - RNA_string_get(op->ptr, "name", imagename_buff); - imagename = imagename_buff; - } + nodeSetActive(ntree, imanode); - mtex->tex = BKE_texture_add(bmain, imagename); - mtex->mapto = type; - - if (mtex->tex) { - ima = mtex->tex->ima = proj_paint_image_create(op, bmain); - } - - WM_event_add_notifier(C, NC_TEXTURE | NA_ADDED, mtex->tex); - } - } + ntreeUpdateTree(CTX_data_main(C), ntree); if (ima) { BKE_texpaint_slot_refresh_cache(scene, ma); BKE_image_signal(bmain, ima, NULL, IMA_SIGNAL_USER_NEW_IMAGE); WM_event_add_notifier(C, NC_IMAGE | NA_ADDED, ima); - DAG_id_tag_update(&ma->id, 0); + DEG_id_tag_update(&ma->id, 0); ED_area_tag_redraw(CTX_wm_area(C)); BKE_paint_proj_mesh_data_check(scene, ob, NULL, NULL, NULL, NULL); @@ -5826,59 +5761,6 @@ void PAINT_OT_add_texture_paint_slot(wmOperatorType *ot) RNA_def_boolean(ot->srna, "float", 0, "32 bit Float", "Create image with 32 bit floating point bit depth"); } -static int texture_paint_delete_texture_paint_slot_exec(bContext *C, wmOperator *UNUSED(op)) -{ - Object *ob = CTX_data_active_object(C); - Scene *scene = CTX_data_scene(C); - Material *ma; - bool is_bi = BKE_scene_uses_blender_internal(scene) || BKE_scene_uses_blender_game(scene); - TexPaintSlot *slot; - - /* not supported for node-based engines */ - if (!ob || !is_bi) - return OPERATOR_CANCELLED; - - ma = give_current_material(ob, ob->actcol); - - if (!ma->texpaintslot || ma->use_nodes) - return OPERATOR_CANCELLED; - - slot = ma->texpaintslot + ma->paint_active_slot; - - if (ma->mtex[slot->index]->tex) { - id_us_min(&ma->mtex[slot->index]->tex->id); - - if (ma->mtex[slot->index]->tex->ima) { - id_us_min(&ma->mtex[slot->index]->tex->ima->id); - } - } - MEM_freeN(ma->mtex[slot->index]); - ma->mtex[slot->index] = NULL; - - BKE_texpaint_slot_refresh_cache(scene, ma); - DAG_id_tag_update(&ma->id, 0); - WM_event_add_notifier(C, NC_MATERIAL, ma); - /* we need a notifier for data change since we change the displayed modifier uvs */ - WM_event_add_notifier(C, NC_GEOM | ND_DATA, ob->data); - return OPERATOR_FINISHED; -} - - -void PAINT_OT_delete_texture_paint_slot(wmOperatorType *ot) -{ - /* identifiers */ - ot->name = "Delete Texture Paint Slot"; - ot->description = "Delete selected texture paint slot"; - ot->idname = "PAINT_OT_delete_texture_paint_slot"; - - /* api callbacks */ - ot->exec = texture_paint_delete_texture_paint_slot_exec; - ot->poll = ED_operator_region_view3d_active; - - /* flags */ - ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; -} - static int add_simple_uvs_exec(bContext *C, wmOperator *UNUSED(op)) { /* no checks here, poll function does them for us */ @@ -5915,7 +5797,7 @@ static int add_simple_uvs_exec(bContext *C, wmOperator *UNUSED(op)) BKE_paint_proj_mesh_data_check(scene, ob, NULL, NULL, NULL, NULL); - DAG_id_tag_update(ob->data, 0); + DEG_id_tag_update(ob->data, 0); WM_event_add_notifier(C, NC_GEOM | ND_DATA, ob->data); WM_event_add_notifier(C, NC_SCENE | ND_TOOLSETTINGS, scene); return OPERATOR_FINISHED; @@ -5925,9 +5807,9 @@ static bool add_simple_uvs_poll(bContext *C) { Object *ob = CTX_data_active_object(C); - if (!ob || ob->type != OB_MESH || ob->mode != OB_MODE_TEXTURE_PAINT) + if (!ob || ob->type != OB_MESH || ob->mode != OB_MODE_TEXTURE_PAINT) { return false; - + } return true; } diff --git a/source/blender/editors/sculpt_paint/paint_image_undo.c b/source/blender/editors/sculpt_paint/paint_image_undo.c index ef28dafa8c9..ade775d14e6 100644 --- a/source/blender/editors/sculpt_paint/paint_image_undo.c +++ b/source/blender/editors/sculpt_paint/paint_image_undo.c @@ -33,16 +33,18 @@ #include "DNA_object_types.h" #include "DNA_screen_types.h" #include "DNA_space_types.h" +#include "DNA_workspace_types.h" #include "IMB_imbuf.h" #include "IMB_imbuf_types.h" #include "BKE_context.h" -#include "BKE_depsgraph.h" #include "BKE_image.h" #include "BKE_main.h" #include "BKE_undo_system.h" +#include "DEG_depsgraph.h" + #include "ED_paint.h" #include "ED_undo.h" @@ -328,7 +330,7 @@ static void image_undo_restore_list(ListBase *lb, struct UndoIDPtrMap *id_map) } ibuf->userflags |= IB_DISPLAY_BUFFER_INVALID; - DAG_id_tag_update(&ima->id, 0); + DEG_id_tag_update(&ima->id, 0); BKE_image_release_ibuf(ima, ibuf, NULL); } diff --git a/source/blender/editors/sculpt_paint/paint_intern.h b/source/blender/editors/sculpt_paint/paint_intern.h index 8ba773a2fc8..a7041a5e9ea 100644 --- a/source/blender/editors/sculpt_paint/paint_intern.h +++ b/source/blender/editors/sculpt_paint/paint_intern.h @@ -94,8 +94,10 @@ void paint_cursor_delete_textures(void); /* paint_vertex.c */ bool weight_paint_poll(struct bContext *C); +bool weight_paint_poll_ignore_tool(bContext *C); bool weight_paint_mode_poll(struct bContext *C); bool vertex_paint_poll(struct bContext *C); +bool vertex_paint_poll_ignore_tool(struct bContext *C); bool vertex_paint_mode_poll(struct bContext *C); typedef void (*VPaintTransform_Callback)(const float col[3], const void *user_data, float r_col[3]); @@ -157,10 +159,10 @@ void PAINT_OT_weight_sample_group(struct wmOperatorType *ot); /* paint_vertex_proj.c */ struct VertProjHandle; struct VertProjHandle *ED_vpaint_proj_handle_create( - struct Scene *scene, struct Object *ob, + struct Depsgraph *depsgraph, struct Scene *scene, struct Object *ob, struct DMCoNo **r_vcosnos); void ED_vpaint_proj_handle_update( - struct VertProjHandle *vp_handle, + struct Depsgraph *depsgraph, struct VertProjHandle *vp_handle, /* runtime vars */ struct ARegion *ar, const float mval_fl[2]); void ED_vpaint_proj_handle_free( @@ -216,7 +218,6 @@ void PAINT_OT_texture_paint_toggle(struct wmOperatorType *ot); void PAINT_OT_project_image(struct wmOperatorType *ot); void PAINT_OT_image_from_view(struct wmOperatorType *ot); void PAINT_OT_add_texture_paint_slot(struct wmOperatorType *ot); -void PAINT_OT_delete_texture_paint_slot(struct wmOperatorType *ot); void PAINT_OT_image_paint(struct wmOperatorType *ot); void PAINT_OT_add_simple_uvs(struct wmOperatorType *ot); @@ -259,7 +260,6 @@ bool paint_convert_bb_to_rect(struct rcti *rect, * 2D screens-space bounding box into four 3D planes) */ void paint_calc_redraw_planes(float planes[4][4], const struct ARegion *ar, - struct RegionView3D *rv3d, struct Object *ob, const struct rcti *screen_rect); diff --git a/source/blender/editors/sculpt_paint/paint_mask.c b/source/blender/editors/sculpt_paint/paint_mask.c index 76b629395e2..4a338e65d79 100644 --- a/source/blender/editors/sculpt_paint/paint_mask.c +++ b/source/blender/editors/sculpt_paint/paint_mask.c @@ -35,8 +35,6 @@ #include "DNA_meshdata_types.h" #include "DNA_object_types.h" -#include "BIF_glutil.h" - #include "BLI_bitmap_draw_2d.h" #include "BLI_math_matrix.h" #include "BLI_math_geom.h" @@ -47,11 +45,12 @@ #include "BKE_pbvh.h" #include "BKE_ccg.h" #include "BKE_context.h" -#include "BKE_DerivedMesh.h" #include "BKE_multires.h" #include "BKE_paint.h" #include "BKE_subsurf.h" +#include "DEG_depsgraph.h" + #include "RNA_access.h" #include "RNA_define.h" @@ -134,6 +133,7 @@ static int mask_flood_fill_exec(bContext *C, wmOperator *op) ARegion *ar = CTX_wm_region(C); struct Scene *scene = CTX_data_scene(C); Object *ob = CTX_data_active_object(C); + Depsgraph *depsgraph = CTX_data_depsgraph(C); PaintMaskFloodMode mode; float value; PBVH *pbvh; @@ -145,7 +145,7 @@ static int mask_flood_fill_exec(bContext *C, wmOperator *op) mode = RNA_enum_get(op->ptr, "mode"); value = RNA_float_get(op->ptr, "value"); - BKE_sculpt_update_mesh_elements(scene, sd, ob, false, true); + BKE_sculpt_update_mesh_elements(depsgraph, scene, sd, ob, false, true); pbvh = ob->sculpt->pbvh; multires = (BKE_pbvh_type(pbvh) == PBVH_GRIDS); @@ -258,9 +258,9 @@ static void mask_box_select_task_cb( int ED_sculpt_mask_box_select(struct bContext *C, ViewContext *vc, const rcti *rect, bool select, bool UNUSED(extend)) { + Depsgraph *depsgraph = CTX_data_depsgraph(C); Sculpt *sd = vc->scene->toolsettings->sculpt; BoundBox bb; - bglMats mats = {{0}}; float clip_planes[4][4]; float clip_planes_final[4][4]; ARegion *ar = vc->ar; @@ -278,11 +278,10 @@ int ED_sculpt_mask_box_select(struct bContext *C, ViewContext *vc, const rcti *r value = select ? 1.0 : 0.0; /* transform the clip planes in object space */ - view3d_get_transformation(vc->ar, vc->rv3d, vc->obact, &mats); - ED_view3d_clipping_calc(&bb, clip_planes, &mats, rect); + ED_view3d_clipping_calc(&bb, clip_planes, vc->ar, vc->obact, rect); negate_m4(clip_planes); - BKE_sculpt_update_mesh_elements(scene, sd, ob, false, true); + BKE_sculpt_update_mesh_elements(depsgraph, scene, sd, ob, false, true); pbvh = ob->sculpt->pbvh; multires = (BKE_pbvh_type(pbvh) == PBVH_GRIDS); @@ -424,9 +423,9 @@ static int paint_mask_gesture_lasso_exec(bContext *C, wmOperator *op) const int (*mcords)[2] = WM_gesture_lasso_path_to_array(C, op, &mcords_tot); if (mcords) { + Depsgraph *depsgraph = CTX_data_depsgraph(C); float clip_planes[4][4], clip_planes_final[4][4]; BoundBox bb; - bglMats mats = {{0}}; Object *ob; ViewContext vc; LassoMaskData data; @@ -444,7 +443,6 @@ static int paint_mask_gesture_lasso_exec(bContext *C, wmOperator *op) * calculations done. Bounding box PBVH collision is not computed against enclosing rectangle * of lasso */ ED_view3d_viewcontext_init(C, &vc); - view3d_get_transformation(vc.ar, vc.rv3d, vc.obact, &mats); /* lasso data calculations */ data.vc = &vc; @@ -460,10 +458,10 @@ static int paint_mask_gesture_lasso_exec(bContext *C, wmOperator *op) mcords, mcords_tot, mask_lasso_px_cb, &data); - ED_view3d_clipping_calc(&bb, clip_planes, &mats, &data.rect); + ED_view3d_clipping_calc(&bb, clip_planes, vc.ar, vc.obact, &data.rect); negate_m4(clip_planes); - BKE_sculpt_update_mesh_elements(scene, sd, ob, false, true); + BKE_sculpt_update_mesh_elements(depsgraph, scene, sd, ob, false, true); pbvh = ob->sculpt->pbvh; multires = (BKE_pbvh_type(pbvh) == PBVH_GRIDS); diff --git a/source/blender/editors/sculpt_paint/paint_ops.c b/source/blender/editors/sculpt_paint/paint_ops.c index 89475d0de8a..e2c39695380 100644 --- a/source/blender/editors/sculpt_paint/paint_ops.c +++ b/source/blender/editors/sculpt_paint/paint_ops.c @@ -47,6 +47,7 @@ #include "WM_api.h" #include "WM_types.h" +#include "WM_toolsystem.h" #include "RNA_access.h" #include "RNA_define.h" @@ -452,9 +453,23 @@ static int brush_select_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } - return brush_generic_tool_set(bmain, paint, tool, tool_offset, - paint_mode, tool_name, create_missing, - toggle); + /* TODO(campbell): Use the toolsystem for now, ideally the toolsystem will display brushes directly + * so we don't need to sync between tools and brushes. */ + if (false) { + return brush_generic_tool_set( + bmain, paint, tool, tool_offset, + paint_mode, tool_name, create_missing, + toggle); + } + else { + WorkSpace *workspace = CTX_wm_workspace(C); + if (WM_toolsystem_ref_set_by_name(C, workspace, NULL, tool_name, true)) { + return OPERATOR_FINISHED; + } + else { + return OPERATOR_CANCELLED; + } + } } static void PAINT_OT_brush_select(wmOperatorType *ot) @@ -493,9 +508,10 @@ static void PAINT_OT_brush_select(wmOperatorType *ot) RNA_def_property_flag(prop, PROP_SKIP_SAVE); } -static wmKeyMapItem *keymap_brush_select(wmKeyMap *keymap, int paint_mode, - int tool, int keymap_type, - int keymap_modifier) +static wmKeyMapItem *keymap_brush_select( + wmKeyMap *keymap, int paint_mode, + int tool, int keymap_type, + int keymap_modifier) { wmKeyMapItem *kmi; kmi = WM_keymap_add_item(keymap, "PAINT_OT_brush_select", @@ -1035,7 +1051,6 @@ void ED_operatortypes_paint(void) WM_operatortype_append(PAINT_OT_image_from_view); WM_operatortype_append(PAINT_OT_brush_colors_flip); WM_operatortype_append(PAINT_OT_add_texture_paint_slot); - WM_operatortype_append(PAINT_OT_delete_texture_paint_slot); WM_operatortype_append(PAINT_OT_add_simple_uvs); /* weight */ @@ -1081,20 +1096,6 @@ void ED_operatortypes_paint(void) WM_operatortype_append(PAINT_OT_mask_lasso_gesture); } - -static void ed_keymap_paint_brush_switch(wmKeyMap *keymap, const char *mode) -{ - wmKeyMapItem *kmi; - int i; - /* index 0-9 (zero key is tenth), shift key for index 10-19 */ - for (i = 0; i < 20; i++) { - kmi = WM_keymap_add_item(keymap, "BRUSH_OT_active_index_set", - ZEROKEY + ((i + 1) % 10), KM_PRESS, i < 10 ? 0 : KM_SHIFT, 0); - RNA_string_set(kmi->ptr, "mode", mode); - RNA_int_set(kmi->ptr, "index", i); - } -} - static void ed_keymap_paint_brush_size(wmKeyMap *keymap, const char *UNUSED(path)) { wmKeyMapItem *kmi; @@ -1229,7 +1230,9 @@ static void paint_keymap_curve(wmKeyMap *keymap) RNA_boolean_set(kmi->ptr, "toggle", true); WM_keymap_add_item(keymap, "PAINTCURVE_OT_cursor", ACTIONMOUSE, KM_PRESS, 0, 0); +#ifdef USE_WM_KEYMAP_27X WM_keymap_add_item(keymap, "PAINTCURVE_OT_delete_point", XKEY, KM_PRESS, 0, 0); +#endif WM_keymap_add_item(keymap, "PAINTCURVE_OT_delete_point", DELKEY, KM_PRESS, 0, 0); WM_keymap_add_item(keymap, "PAINTCURVE_OT_draw", RETKEY, KM_PRESS, 0, 0); @@ -1299,7 +1302,6 @@ void ED_keymap_paint(wmKeyConfig *keyconf) RNA_int_set(kmi->ptr, "level", -1); RNA_boolean_set(kmi->ptr, "relative", true); - ed_keymap_paint_brush_switch(keymap, "sculpt"); ed_keymap_paint_brush_size(keymap, "tool_settings.sculpt.brush.size"); ed_keymap_paint_brush_radial_control(keymap, "sculpt", RC_ROTATION); @@ -1339,7 +1341,6 @@ void ED_keymap_paint(wmKeyConfig *keyconf) WM_keymap_add_item(keymap, "PAINT_OT_vertex_color_set", KKEY, KM_PRESS, KM_SHIFT, 0); - ed_keymap_paint_brush_switch(keymap, "vertex_paint"); ed_keymap_paint_brush_size(keymap, "tool_settings.vertex_paint.brush.size"); ed_keymap_paint_brush_radial_control(keymap, "vertex_paint", RC_COLOR | RC_COLOR_OVERRIDE | RC_ROTATION); @@ -1372,7 +1373,6 @@ void ED_keymap_paint(wmKeyConfig *keyconf) WM_keymap_add_item(keymap, "PAINT_OT_weight_set", KKEY, KM_PRESS, KM_SHIFT, 0); - ed_keymap_paint_brush_switch(keymap, "weight_paint"); ed_keymap_paint_brush_size(keymap, "tool_settings.weight_paint.brush.size"); ed_keymap_paint_brush_radial_control(keymap, "weight_paint", RC_WEIGHT); @@ -1413,7 +1413,6 @@ void ED_keymap_paint(wmKeyConfig *keyconf) WM_keymap_add_item(keymap, "PAINT_OT_grab_clone", RIGHTMOUSE, KM_PRESS, 0, 0); WM_keymap_add_item(keymap, "PAINT_OT_sample_color", SKEY, KM_PRESS, 0, 0); - ed_keymap_paint_brush_switch(keymap, "image_paint"); ed_keymap_paint_brush_size(keymap, "tool_settings.image_paint.brush.size"); ed_keymap_paint_brush_radial_control( keymap, "image_paint", diff --git a/source/blender/editors/sculpt_paint/paint_stroke.c b/source/blender/editors/sculpt_paint/paint_stroke.c index a194b1b3e90..80211c46733 100644 --- a/source/blender/editors/sculpt_paint/paint_stroke.c +++ b/source/blender/editors/sculpt_paint/paint_stroke.c @@ -38,6 +38,8 @@ #include "BLI_rand.h" #include "BLI_listbase.h" +#include "PIL_time.h" + #include "DNA_object_types.h" #include "DNA_scene_types.h" #include "DNA_brush_types.h" @@ -51,6 +53,7 @@ #include "BKE_curve.h" #include "BKE_colortools.h" #include "BKE_image.h" +#include "BKE_mesh.h" #include "WM_api.h" #include "WM_types.h" @@ -58,7 +61,8 @@ #include "BIF_gl.h" #include "BIF_glutil.h" -#include "GPU_basic_shader.h" +#include "GPU_immediate.h" +#include "GPU_state.h" #include "ED_screen.h" #include "ED_view3d.h" @@ -85,6 +89,7 @@ typedef struct PaintStroke { void *mode_data; void *stroke_cursor; wmTimer *timer; + struct RNG *rng; /* Cached values */ ViewContext vc; @@ -145,13 +150,27 @@ static void paint_draw_smooth_cursor(bContext *C, int x, int y, void *customdata PaintStroke *stroke = customdata; if (stroke && brush) { - glEnable(GL_LINE_SMOOTH); - glEnable(GL_BLEND); - glColor4ubv(paint->paint_cursor_col); - sdrawline(x, y, (int)stroke->last_mouse_position[0], - (int)stroke->last_mouse_position[1]); - glDisable(GL_BLEND); - glDisable(GL_LINE_SMOOTH); + GPU_line_smooth(true); + GPU_blend(true); + + ARegion *ar = stroke->vc.ar; + + unsigned int pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); + immUniformColor4ubv(paint->paint_cursor_col); + + immBegin(GWN_PRIM_LINES, 2); + immVertex2f(pos, x, y); + immVertex2f(pos, + stroke->last_mouse_position[0] + ar->winrct.xmin, + stroke->last_mouse_position[1] + ar->winrct.ymin); + + immEnd(); + + immUnbindProgram(); + + GPU_blend(false); + GPU_line_smooth(false); } } @@ -160,38 +179,47 @@ static void paint_draw_line_cursor(bContext *C, int x, int y, void *customdata) Paint *paint = BKE_paint_get_active_from_context(C); PaintStroke *stroke = customdata; - glEnable(GL_LINE_SMOOTH); - glEnable(GL_BLEND); + GPU_line_smooth(true); - GPU_basic_shader_bind_enable(GPU_SHADER_LINE | GPU_SHADER_STIPPLE); - GPU_basic_shader_line_stipple(3, 0xAAAA); - GPU_basic_shader_line_width(3.0); + uint shdr_pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); - glColor4ub(0, 0, 0, paint->paint_cursor_col[3]); - if (stroke->constrain_line) { - sdrawline((int)stroke->last_mouse_position[0], (int)stroke->last_mouse_position[1], - stroke->constrained_pos[0], stroke->constrained_pos[1]); - } - else { - sdrawline((int)stroke->last_mouse_position[0], (int)stroke->last_mouse_position[1], - x, y); - } + immBindBuiltinProgram(GPU_SHADER_2D_LINE_DASHED_UNIFORM_COLOR); + + float viewport_size[4]; + GPU_viewport_size_getf(viewport_size); + immUniform2f("viewport_size", viewport_size[2], viewport_size[3]); + + immUniform1i("colors_len", 2); /* "advanced" mode */ + const float alpha = (float)paint->paint_cursor_col[3] / 255.0f; + immUniformArray4fv("colors", (float *)(float[][4]){{0.0f, 0.0f, 0.0f, alpha}, {1.0f, 1.0f, 1.0f, alpha}}, 2); + immUniform1f("dash_width", 6.0f); + + immBegin(GWN_PRIM_LINES, 2); + + ARegion *ar = stroke->vc.ar; - glColor4ub(255, 255, 255, paint->paint_cursor_col[3]); - GPU_basic_shader_line_width(1.0); if (stroke->constrain_line) { - sdrawline((int)stroke->last_mouse_position[0], (int)stroke->last_mouse_position[1], - stroke->constrained_pos[0], stroke->constrained_pos[1]); + immVertex2f(shdr_pos, + stroke->last_mouse_position[0] + ar->winrct.xmin, + stroke->last_mouse_position[1] + ar->winrct.ymin); + + immVertex2f(shdr_pos, + stroke->constrained_pos[0] + ar->winrct.xmin, + stroke->constrained_pos[1] + ar->winrct.ymin); } else { - sdrawline((int)stroke->last_mouse_position[0], (int)stroke->last_mouse_position[1], - x, y); + immVertex2f(shdr_pos, + stroke->last_mouse_position[0] + ar->winrct.xmin, + stroke->last_mouse_position[1] + ar->winrct.ymin); + + immVertex2f(shdr_pos, x, y); } - GPU_basic_shader_bind_disable(GPU_SHADER_LINE | GPU_SHADER_STIPPLE); + immEnd(); - glDisable(GL_BLEND); - glDisable(GL_LINE_SMOOTH); + immUnbindProgram(); + + GPU_line_smooth(false); } static bool paint_tool_require_location(Brush *brush, ePaintMode mode) @@ -379,17 +407,24 @@ static bool paint_brush_update(bContext *C, } } + if ((do_random || do_random_mask) && stroke->rng == NULL) { + /* Lazy initialization. */ + uint rng_seed = (uint)(PIL_check_seconds_timer_i() & UINT_MAX); + rng_seed ^= (uint)GET_INT_FROM_POINTER(brush); + stroke->rng = BLI_rng_new(rng_seed); + } + if (do_random) { if (brush->mtex.brush_angle_mode & MTEX_ANGLE_RANDOM) { ups->brush_rotation += -brush->mtex.random_angle / 2.0f + - brush->mtex.random_angle * BLI_frand(); + brush->mtex.random_angle * BLI_rng_get_float(stroke->rng); } } if (do_random_mask) { if (brush->mask_mtex.brush_angle_mode & MTEX_ANGLE_RANDOM) { ups->brush_rotation_sec += -brush->mask_mtex.random_angle / 2.0f + - brush->mask_mtex.random_angle * BLI_frand(); + brush->mask_mtex.random_angle * BLI_rng_get_float(stroke->rng); } } @@ -761,6 +796,10 @@ static void stroke_done(struct bContext *C, struct wmOperator *op) stroke->timer); } + if (stroke->rng) { + BLI_rng_free(stroke->rng); + } + if (stroke->stroke_cursor) WM_paint_cursor_end(CTX_wm_manager(C), stroke->stroke_cursor); diff --git a/source/blender/editors/sculpt_paint/paint_utils.c b/source/blender/editors/sculpt_paint/paint_utils.c index f215fdcd579..57306eaff45 100644 --- a/source/blender/editors/sculpt_paint/paint_utils.c +++ b/source/blender/editors/sculpt_paint/paint_utils.c @@ -50,17 +50,22 @@ #include "BKE_brush.h" #include "BKE_context.h" -#include "BKE_DerivedMesh.h" +#include "BKE_customdata.h" #include "BKE_image.h" #include "BKE_material.h" +#include "BKE_object.h" #include "BKE_paint.h" #include "BKE_report.h" +#include "DEG_depsgraph.h" +#include "DEG_depsgraph_query.h" + #include "RNA_access.h" #include "RNA_define.h" -#include "BIF_gl.h" -#include "BIF_glutil.h" +#include "GPU_glew.h" +#include "GPU_matrix.h" +#include "GPU_state.h" #include "IMB_colormanagement.h" #include "IMB_imbuf_types.h" @@ -130,17 +135,12 @@ bool paint_convert_bb_to_rect(rcti *rect, * 2D screens-space bounding box into four 3D planes) */ void paint_calc_redraw_planes(float planes[4][4], const ARegion *ar, - RegionView3D *rv3d, Object *ob, const rcti *screen_rect) { BoundBox bb; - bglMats mats; rcti rect; - memset(&bb, 0, sizeof(BoundBox)); - view3d_get_transformation(ar, rv3d, ob, &mats); - /* use some extra space just in case */ rect = *screen_rect; rect.xmin -= 2; @@ -148,7 +148,7 @@ void paint_calc_redraw_planes(float planes[4][4], rect.ymin -= 2; rect.ymax += 2; - ED_view3d_clipping_calc(&bb, planes, &mats, &rect); + ED_view3d_clipping_calc(&bb, planes, ar, ob, &rect); negate_m4(planes); } @@ -277,26 +277,26 @@ static void imapaint_tri_weights(float matrix[4][4], GLint view[4], } /* compute uv coordinates of mouse in face */ -static void imapaint_pick_uv(Scene *scene, Object *ob, unsigned int faceindex, const int xy[2], float uv[2]) +static void imapaint_pick_uv(Mesh *me_eval, Scene *scene, Object *ob_eval, unsigned int faceindex, const int xy[2], float uv[2]) { - DerivedMesh *dm = mesh_get_derived_final(scene, ob, CD_MASK_BAREMESH); - const int tottri = dm->getNumLoopTri(dm); + const int tottri = me_eval->runtime.looptris.len; int i, findex; float p[2], w[3], absw, minabsw; float matrix[4][4], proj[4][4]; GLint view[4]; const eImagePaintMode mode = scene->toolsettings->imapaint.mode; - const MLoopTri *lt = dm->getLoopTriArray(dm); - const MPoly *mpoly = dm->getPolyArray(dm); - const MLoop *mloop = dm->getLoopArray(dm); - const int *index_mp_to_orig = dm->getPolyDataArray(dm, CD_ORIGINDEX); + const MLoopTri *lt = me_eval->runtime.looptris.array; + const MVert *mvert = me_eval->mvert; + const MPoly *mpoly = me_eval->mpoly; + const MLoop *mloop = me_eval->mloop; + const int *index_mp_to_orig = CustomData_get_layer(&me_eval->pdata, CD_ORIGINDEX); /* get the needed opengl matrices */ - glGetIntegerv(GL_VIEWPORT, view); - glGetFloatv(GL_MODELVIEW_MATRIX, (float *)matrix); - glGetFloatv(GL_PROJECTION_MATRIX, (float *)proj); + GPU_viewport_size_geti(view); + gpuGetModelViewMatrix(matrix); + gpuGetProjectionMatrix(proj); view[0] = view[1] = 0; - mul_m4_m4m4(matrix, matrix, ob->obmat); + mul_m4_m4m4(matrix, matrix, ob_eval->obmat); mul_m4_m4m4(matrix, proj, matrix); minabsw = 1e10; @@ -313,25 +313,25 @@ static void imapaint_pick_uv(Scene *scene, Object *ob, unsigned int faceindex, c const MLoopUV *tri_uv[3]; float tri_co[3][3]; - dm->getVertCo(dm, mloop[lt->tri[0]].v, tri_co[0]); - dm->getVertCo(dm, mloop[lt->tri[1]].v, tri_co[1]); - dm->getVertCo(dm, mloop[lt->tri[2]].v, tri_co[2]); + for (int j = 3; j--; ) { + copy_v3_v3(tri_co[j], mvert[mloop[lt->tri[j]].v].co); + } if (mode == IMAGEPAINT_MODE_MATERIAL) { const Material *ma; const TexPaintSlot *slot; - ma = dm->mat[mp->mat_nr]; + ma = give_current_material(ob_eval, mp->mat_nr); slot = &ma->texpaintslot[ma->paint_active_slot]; if (!(slot && slot->uvname && - (mloopuv = CustomData_get_layer_named(&dm->loopData, CD_MLOOPUV, slot->uvname)))) + (mloopuv = CustomData_get_layer_named(&me_eval->ldata, CD_MLOOPUV, slot->uvname)))) { - mloopuv = CustomData_get_layer(&dm->loopData, CD_MLOOPUV); + mloopuv = CustomData_get_layer(&me_eval->ldata, CD_MLOOPUV); } } else { - mloopuv = CustomData_get_layer(&dm->loopData, CD_MLOOPUV); + mloopuv = CustomData_get_layer(&me_eval->ldata, CD_MLOOPUV); } tri_uv[0] = &mloopuv[lt->tri[0]]; @@ -350,12 +350,12 @@ static void imapaint_pick_uv(Scene *scene, Object *ob, unsigned int faceindex, c } } } - - dm->release(dm); } /* returns 0 if not found, otherwise 1 */ -static int imapaint_pick_face(ViewContext *vc, const int mval[2], unsigned int *r_index, unsigned int totpoly) +static int imapaint_pick_face( + ViewContext *vc, const int mval[2], + unsigned int *r_index, unsigned int totpoly) { if (totpoly == 0) return 0; @@ -427,6 +427,7 @@ void flip_qt_qt(float out[4], const float in[4], const char symm) void paint_sample_color(bContext *C, ARegion *ar, int x, int y, bool texpaint_proj, bool use_palette) { Scene *scene = CTX_data_scene(C); + Depsgraph *depsgraph = CTX_data_depsgraph(C); Paint *paint = BKE_paint_get_active_from_context(C); Palette *palette = BKE_paint_palette(paint); PaletteColor *color = NULL; @@ -450,21 +451,23 @@ void paint_sample_color(bContext *C, ARegion *ar, int x, int y, bool texpaint_pr if (CTX_wm_view3d(C) && texpaint_proj) { /* first try getting a colour directly from the mesh faces if possible */ - Object *ob = OBACT; + ViewLayer *view_layer = CTX_data_view_layer(C); + Object *ob = OBACT(view_layer); + Object *ob_eval = DEG_get_evaluated_object(depsgraph, ob); bool sample_success = false; ImagePaintSettings *imapaint = &scene->toolsettings->imapaint; bool use_material = (imapaint->mode == IMAGEPAINT_MODE_MATERIAL); if (ob) { Mesh *me = (Mesh *)ob->data; - DerivedMesh *dm = mesh_get_derived_final(scene, ob, CD_MASK_BAREMESH); + Mesh *me_eval = BKE_object_get_evaluated_mesh(depsgraph, ob); /* Or shall we just do ob_eval->mesh_eval ? */ ViewContext vc; const int mval[2] = {x, y}; unsigned int faceindex; unsigned int totpoly = me->totpoly; - if (dm->getLoopDataArray(dm, CD_MLOOPUV)) { + if (CustomData_has_layer(&me_eval->ldata, CD_MLOOPUV)) { ED_view3d_viewcontext_init(C, &vc); view3d_operator_needs_opengl(C); @@ -473,7 +476,7 @@ void paint_sample_color(bContext *C, ARegion *ar, int x, int y, bool texpaint_pr Image *image; if (use_material) - image = imapaint_face_image(ob, me, faceindex); + image = imapaint_face_image(ob_eval, me_eval, faceindex); else image = imapaint->canvas; @@ -482,7 +485,7 @@ void paint_sample_color(bContext *C, ARegion *ar, int x, int y, bool texpaint_pr if (ibuf && ibuf->rect) { float uv[2]; float u, v; - imapaint_pick_uv(scene, ob, faceindex, mval, uv); + imapaint_pick_uv(me_eval, scene, ob_eval, faceindex, mval, uv); sample_success = true; u = fmodf(uv[0], 1.0f); @@ -496,10 +499,7 @@ void paint_sample_color(bContext *C, ARegion *ar, int x, int y, bool texpaint_pr if (ibuf->rect_float) { float rgba_f[4]; - if (U.gameflags & USER_DISABLE_MIPMAP) - nearest_interpolation_color_wrap(ibuf, NULL, rgba_f, u, v); - else - bilinear_interpolation_color_wrap(ibuf, NULL, rgba_f, u, v); + bilinear_interpolation_color_wrap(ibuf, NULL, rgba_f, u, v); straight_to_premul_v4(rgba_f); if (use_palette) { linearrgb_to_srgb_v3_v3(color->rgb, rgba_f); @@ -511,10 +511,7 @@ void paint_sample_color(bContext *C, ARegion *ar, int x, int y, bool texpaint_pr } else { unsigned char rgba[4]; - if (U.gameflags & USER_DISABLE_MIPMAP) - nearest_interpolation_color_wrap(ibuf, rgba, NULL, u, v); - else - bilinear_interpolation_color_wrap(ibuf, rgba, NULL, u, v); + bilinear_interpolation_color_wrap(ibuf, rgba, NULL, u, v); if (use_palette) { rgb_uchar_to_float(color->rgb, rgba); } @@ -530,7 +527,6 @@ void paint_sample_color(bContext *C, ARegion *ar, int x, int y, bool texpaint_pr } } } - dm->release(dm); } if (!sample_success) { @@ -564,8 +560,9 @@ static int brush_curve_preset_exec(bContext *C, wmOperator *op) if (br) { Scene *scene = CTX_data_scene(C); + ViewLayer *view_layer = CTX_data_view_layer(C); BKE_brush_curve_preset(br, RNA_enum_get(op->ptr, "shape")); - BKE_paint_invalidate_cursor_overlay(scene, br->curve); + BKE_paint_invalidate_cursor_overlay(scene, view_layer, br->curve); } return OPERATOR_FINISHED; diff --git a/source/blender/editors/sculpt_paint/paint_vertex.c b/source/blender/editors/sculpt_paint/paint_vertex.c index 483c8a77ab5..59a9ee8f0d2 100644 --- a/source/blender/editors/sculpt_paint/paint_vertex.c +++ b/source/blender/editors/sculpt_paint/paint_vertex.c @@ -54,18 +54,22 @@ #include "BKE_brush.h" #include "BKE_context.h" -#include "BKE_depsgraph.h" #include "BKE_deform.h" #include "BKE_main.h" #include "BKE_mesh.h" #include "BKE_mesh_mapping.h" +#include "BKE_object.h" #include "BKE_object_deform.h" #include "BKE_paint.h" #include "BKE_report.h" #include "BKE_subsurf.h" +#include "DEG_depsgraph.h" + #include "WM_api.h" #include "WM_types.h" +#include "WM_message.h" +#include "WM_toolsystem.h" #include "ED_object.h" #include "ED_mesh.h" @@ -204,7 +208,7 @@ bool vertex_paint_mode_poll(bContext *C) return ob && ob->mode == OB_MODE_VERTEX_PAINT && ((Mesh *)ob->data)->totpoly; } -bool vertex_paint_poll(bContext *C) +static bool vertex_paint_poll_ex(bContext *C, bool check_tool) { if (vertex_paint_mode_poll(C) && BKE_paint_brush(&CTX_data_tool_settings(C)->vpaint->paint)) @@ -212,13 +216,26 @@ bool vertex_paint_poll(bContext *C) ScrArea *sa = CTX_wm_area(C); if (sa && sa->spacetype == SPACE_VIEW3D) { ARegion *ar = CTX_wm_region(C); - if (ar->regiontype == RGN_TYPE_WINDOW) - return 1; + if (ar->regiontype == RGN_TYPE_WINDOW) { + if (!check_tool || WM_toolsystem_active_tool_is_brush(C)) { + return 1; + } + } } } return 0; } +bool vertex_paint_poll(bContext *C) +{ + return vertex_paint_poll_ex(C, true); +} + +bool vertex_paint_poll_ignore_tool(bContext *C) +{ + return vertex_paint_poll_ex(C, true); +} + bool weight_paint_mode_poll(bContext *C) { Object *ob = CTX_data_active_object(C); @@ -226,7 +243,7 @@ bool weight_paint_mode_poll(bContext *C) return ob && ob->mode == OB_MODE_WEIGHT_PAINT && ((Mesh *)ob->data)->totpoly; } -bool weight_paint_poll(bContext *C) +static bool weight_paint_poll_ex(bContext *C, bool check_tool) { Object *ob = CTX_data_active_object(C); ScrArea *sa; @@ -239,12 +256,24 @@ bool weight_paint_poll(bContext *C) { ARegion *ar = CTX_wm_region(C); if (ar->regiontype == RGN_TYPE_WINDOW) { - return 1; + if (!check_tool || WM_toolsystem_active_tool_is_brush(C)) { + return 1; + } } } return 0; } +bool weight_paint_poll(bContext *C) +{ + return weight_paint_poll_ex(C, true); +} + +bool weight_paint_poll_ignore_tool(bContext *C) +{ + return weight_paint_poll_ex(C, false); +} + static VPaint *new_vpaint(void) { VPaint *vp = MEM_callocN(sizeof(VPaint), "VPaint"); @@ -938,7 +967,7 @@ static void do_weight_paint_vertex( /* Toggle operator for turning vertex paint mode on or off (copied from sculpt.c) */ -static void vertex_paint_init_session(Scene *scene, Object *ob, eObjectMode object_mode) +static void vertex_paint_init_session(Depsgraph *depsgraph, Scene *scene, Object *ob, eObjectMode object_mode) { /* Create persistent sculpt mode data */ BKE_sculpt_toolsettings_data_ensure(scene); @@ -946,12 +975,12 @@ static void vertex_paint_init_session(Scene *scene, Object *ob, eObjectMode obje BLI_assert(ob->sculpt == NULL); ob->sculpt = MEM_callocN(sizeof(SculptSession), "sculpt session"); ob->sculpt->mode_type = object_mode; - BKE_sculpt_update_mesh_elements(scene, scene->toolsettings->sculpt, ob, false, false); + BKE_sculpt_update_mesh_elements(depsgraph, scene, scene->toolsettings->sculpt, ob, false, false); } -static void vertex_paint_init_stroke(Scene *scene, Object *ob) +static void vertex_paint_init_stroke(Depsgraph *depsgraph, Scene *scene, Object *ob) { - BKE_sculpt_update_mesh_elements(scene, scene->toolsettings->sculpt, ob, false, false); + BKE_sculpt_update_mesh_elements(depsgraph, scene, scene->toolsettings->sculpt, ob, false, false); } static void vertex_paint_init_session_data(const ToolSettings *ts, Object *ob) @@ -1037,14 +1066,18 @@ static void vertex_paint_init_session_data(const ToolSettings *ts, Object *ob) * \{ */ static void ed_vwpaintmode_enter_generic( - Main *bmain, - wmWindowManager *wm, - Scene *scene, + Main *bmain, Depsgraph *depsgraph, + wmWindowManager *wm, Scene *scene, Object *ob, const eObjectMode mode_flag) { ob->mode |= mode_flag; Mesh *me = BKE_mesh_from_object(ob); + /* Same as sculpt mode, make sure we don't have cached derived mesh which + * points to freed arrays. + */ + BKE_object_free_derived_caches(ob); + if (mode_flag == OB_MODE_VERTEX_PAINT) { const ePaintMode paint_mode = ePaintVertex; ED_mesh_color_ensure(me, NULL); @@ -1085,39 +1118,44 @@ static void ed_vwpaintmode_enter_generic( BKE_sculptsession_free(ob); } - vertex_paint_init_session(scene, ob, mode_flag); + vertex_paint_init_session(depsgraph, scene, ob, mode_flag); + + /* Flush object mode. */ + DEG_id_tag_update(&ob->id, DEG_TAG_COPY_ON_WRITE); } void ED_object_vpaintmode_enter_ex( - Main *bmain, wmWindowManager *wm, + Main *bmain, Depsgraph *depsgraph, wmWindowManager *wm, Scene *scene, Object *ob) { ed_vwpaintmode_enter_generic( - bmain, wm, scene, ob, OB_MODE_VERTEX_PAINT); + bmain, depsgraph, wm, scene, ob, OB_MODE_VERTEX_PAINT); } void ED_object_vpaintmode_enter(struct bContext *C) { Main *bmain = CTX_data_main(C); + Depsgraph *depsgraph = CTX_data_depsgraph(C); wmWindowManager *wm = CTX_wm_manager(C); Scene *scene = CTX_data_scene(C); Object *ob = CTX_data_active_object(C); - ED_object_vpaintmode_enter_ex(bmain, wm, scene, ob); + ED_object_vpaintmode_enter_ex(bmain, depsgraph, wm, scene, ob); } void ED_object_wpaintmode_enter_ex( - Main *bmain, wmWindowManager *wm, + Main *bmain, Depsgraph *depsgraph, wmWindowManager *wm, Scene *scene, Object *ob) { ed_vwpaintmode_enter_generic( - bmain, wm, scene, ob, OB_MODE_WEIGHT_PAINT); + bmain, depsgraph, wm, scene, ob, OB_MODE_WEIGHT_PAINT); } void ED_object_wpaintmode_enter(struct bContext *C) { Main *bmain = CTX_data_main(C); + Depsgraph *depsgraph = CTX_data_depsgraph(C); wmWindowManager *wm = CTX_wm_manager(C); Scene *scene = CTX_data_scene(C); Object *ob = CTX_data_active_object(C); - ED_object_wpaintmode_enter_ex(bmain, wm, scene, ob); + ED_object_wpaintmode_enter_ex(bmain, depsgraph, wm, scene, ob); } /** \} */ @@ -1166,6 +1204,12 @@ static void ed_vwpaintmode_exit_generic( ED_mesh_mirror_spatial_table(NULL, NULL, NULL, NULL, 'e'); ED_mesh_mirror_topo_table(NULL, NULL, 'e'); } + + /* Never leave derived meshes behind. */ + BKE_object_free_derived_caches(ob); + + /* Flush object mode. */ + DEG_id_tag_update(&ob->id, DEG_TAG_COPY_ON_WRITE); } void ED_object_vpaintmode_exit_ex(Object *ob) @@ -1198,6 +1242,7 @@ void ED_object_wpaintmode_exit(struct bContext *C) static int wpaint_mode_toggle_exec(bContext *C, wmOperator *op) { Main *bmain = CTX_data_main(C); + struct wmMsgBus *mbus = CTX_wm_message_bus(C); Object *ob = CTX_data_active_object(C); const int mode_flag = OB_MODE_WEIGHT_PAINT; const bool is_mode_set = (ob->mode & mode_flag) != 0; @@ -1215,8 +1260,9 @@ static int wpaint_mode_toggle_exec(bContext *C, wmOperator *op) ED_object_wpaintmode_exit_ex(ob); } else { + Depsgraph *depsgraph = CTX_data_depsgraph_on_load(C); wmWindowManager *wm = CTX_wm_manager(C); - ED_object_wpaintmode_enter_ex(bmain, wm, scene, ob); + ED_object_wpaintmode_enter_ex(bmain, depsgraph, wm, scene, ob); } /* Weightpaint works by overriding colors in mesh, @@ -1224,10 +1270,14 @@ static int wpaint_mode_toggle_exec(bContext *C, wmOperator *op) * exit (exit needs doing regardless because we * should redeform). */ - DAG_id_tag_update(&me->id, 0); + DEG_id_tag_update(&me->id, 0); WM_event_add_notifier(C, NC_SCENE | ND_MODE, scene); + WM_msg_publish_rna_prop(mbus, &ob->id, ob, Object, mode); + + WM_toolsystem_update_from_context_view3d(C); + return OPERATOR_FINISHED; } @@ -1407,6 +1457,7 @@ static bool wpaint_stroke_test_start(bContext *C, wmOperator *op, const float mo bool *defbase_sel; SculptSession *ss = ob->sculpt; VPaint *vp = CTX_data_tool_settings(C)->wpaint; + Depsgraph *depsgraph = CTX_data_depsgraph(C); if (ED_wpaint_ensure_data(C, op->reports, WPAINT_ENSURE_MIRROR, &vgroup_index) == false) { return false; @@ -1510,7 +1561,7 @@ static bool wpaint_stroke_test_start(bContext *C, wmOperator *op, const float mo } /* If not previously created, create vertex/weight paint mode session data */ - vertex_paint_init_stroke(scene, ob); + vertex_paint_init_stroke(depsgraph, scene, ob); vwpaint_update_cache_invariants(C, vp, ss, op, mouse); vertex_paint_init_session_data(ts, ob); @@ -1951,7 +2002,8 @@ static void wpaint_paint_leaves( /* threaded loop over nodes */ SculptThreadedTaskData data = { - .sd = sd, .ob = ob, .brush = brush, .nodes = nodes, .vp = vp, .wpd = wpd, .wpi = wpi, .me = me, .C = C, + .C = C, .sd = sd, .ob = ob, .brush = brush, .nodes = nodes, + .vp = vp, .wpd = wpd, .wpi = wpi, .me = me, }; /* Use this so average can modify its weight without touching the brush. */ @@ -2179,7 +2231,9 @@ static void wpaint_stroke_update_step(bContext *C, struct PaintStroke *stroke, P /* also needed for "View Selected" on last stroke */ paint_last_stroke_update(scene, vc->ar, mval); - DAG_id_tag_update(ob->data, 0); + BKE_mesh_batch_cache_dirty(ob->data, BKE_MESH_BATCH_DIRTY_ALL); + + DEG_id_tag_update(ob->data, 0); WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob); swap_m4m4(wpd->vc.rv3d->persmat, mat); @@ -2243,7 +2297,7 @@ static void wpaint_stroke_done(const bContext *C, struct PaintStroke *stroke) } } - DAG_id_tag_update(ob->data, 0); + DEG_id_tag_update(ob->data, 0); WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob); @@ -2326,6 +2380,7 @@ void PAINT_OT_weight_paint(wmOperatorType *ot) static int vpaint_mode_toggle_exec(bContext *C, wmOperator *op) { Main *bmain = CTX_data_main(C); + struct wmMsgBus *mbus = CTX_wm_message_bus(C); Object *ob = CTX_data_active_object(C); const int mode_flag = OB_MODE_VERTEX_PAINT; const bool is_mode_set = (ob->mode & mode_flag) != 0; @@ -2344,15 +2399,22 @@ static int vpaint_mode_toggle_exec(bContext *C, wmOperator *op) ED_object_vpaintmode_exit_ex(ob); } else { + Depsgraph *depsgraph = CTX_data_depsgraph_on_load(C); wmWindowManager *wm = CTX_wm_manager(C); - ED_object_vpaintmode_enter_ex(bmain, wm, scene, ob); + ED_object_vpaintmode_enter_ex(bmain, depsgraph, wm, scene, ob); } + BKE_mesh_batch_cache_dirty(ob->data, BKE_MESH_BATCH_DIRTY_ALL); + /* update modifier stack for mapping requirements */ - DAG_id_tag_update(&me->id, 0); + DEG_id_tag_update(&me->id, 0); WM_event_add_notifier(C, NC_SCENE | ND_MODE, scene); + WM_msg_publish_rna_prop(mbus, &ob->id, ob, Object, mode); + + WM_toolsystem_update_from_context_view3d(C); + return OPERATOR_FINISHED; } @@ -2435,6 +2497,7 @@ static bool vpaint_stroke_test_start(bContext *C, struct wmOperator *op, const f Object *ob = CTX_data_active_object(C); Mesh *me; SculptSession *ss = ob->sculpt; + Depsgraph *depsgraph = CTX_data_depsgraph(C); /* context checks could be a poll() */ me = BKE_mesh_from_object(ob); @@ -2482,12 +2545,12 @@ static bool vpaint_stroke_test_start(bContext *C, struct wmOperator *op, const f /* Create projection handle */ if (vpd->is_texbrush) { ob->sculpt->building_vp_handle = true; - vpd->vp_handle = ED_vpaint_proj_handle_create(scene, ob, &vpd->vertexcosnos); + vpd->vp_handle = ED_vpaint_proj_handle_create(depsgraph, scene, ob, &vpd->vertexcosnos); ob->sculpt->building_vp_handle = false; } /* If not previously created, create vertex/weight paint mode session data */ - vertex_paint_init_stroke(scene, ob); + vertex_paint_init_stroke(depsgraph, scene, ob); vwpaint_update_cache_invariants(C, vp, ss, op, mouse); vertex_paint_init_session_data(ts, ob); @@ -2943,8 +3006,8 @@ static void vpaint_paint_leaves( const Brush *brush = ob->sculpt->cache->brush; SculptThreadedTaskData data = { - .sd = sd, .ob = ob, .brush = brush, .nodes = nodes, .vp = vp, .vpd = vpd, - .lcol = (uint *)me->mloopcol, .me = me, .C = C, + .C = C, .sd = sd, .ob = ob, .brush = brush, .nodes = nodes, .vp = vp, .vpd = vpd, + .lcol = (uint *)me->mloopcol, .me = me, }; ParallelRangeSettings settings; BLI_parallel_range_settings_defaults(&settings); @@ -3081,6 +3144,8 @@ static void vpaint_stroke_update_step(bContext *C, struct PaintStroke *stroke, P swap_m4m4(vc->rv3d->persmat, mat); + BKE_mesh_batch_cache_dirty(ob->data, BKE_MESH_BATCH_DIRTY_ALL); + if (vp->paint.brush->vertexpaint_tool == PAINT_BLEND_SMEAR) { memcpy(vpd->smear.color_prev, vpd->smear.color_curr, sizeof(uint) * ((Mesh *)ob->data)->totloop); } @@ -3094,11 +3159,11 @@ static void vpaint_stroke_update_step(bContext *C, struct PaintStroke *stroke, P if (vpd->use_fast_update == false) { /* recalculate modifier stack to get new colors, slow, * avoid this if we can! */ - DAG_id_tag_update(ob->data, 0); + DEG_id_tag_update(ob->data, 0); } else { - /* If using new VBO drawing, mark mcol as dirty to force colors gpu buffer refresh! */ - ob->derivedFinal->dirty |= DM_DIRTY_MCOL_UPDATE_DRAW; + /* Flush changes through DEG. */ + DEG_id_tag_update(ob->data, DEG_TAG_COPY_ON_WRITE); } } diff --git a/source/blender/editors/sculpt_paint/paint_vertex_color_ops.c b/source/blender/editors/sculpt_paint/paint_vertex_color_ops.c index 4959c40c65e..4c8ca493cd1 100644 --- a/source/blender/editors/sculpt_paint/paint_vertex_color_ops.c +++ b/source/blender/editors/sculpt_paint/paint_vertex_color_ops.c @@ -33,10 +33,11 @@ #include "BLI_math_color.h" #include "BKE_context.h" -#include "BKE_depsgraph.h" #include "BKE_mesh.h" #include "BKE_deform.h" +#include "DEG_depsgraph.h" + #include "RNA_access.h" #include "RNA_define.h" @@ -97,7 +98,7 @@ static bool vertex_color_set(Object *ob, uint paintcol) /* remove stale me->mcol, will be added later */ BKE_mesh_tessface_clear(me); - DAG_id_tag_update(&me->id, 0); + DEG_id_tag_update(&me->id, 0); return true; } @@ -151,6 +152,7 @@ static bool vertex_paint_from_weight(Object *ob) } /* TODO: respect selection. */ + /* TODO: Do we want to take weights from evaluated mesh instead? 2.7x was not doing it anyway... */ mp = me->mpoly; vgroup_active = ob->actdef - 1; for (int i = 0; i < me->totpoly; i++, mp++) { @@ -168,7 +170,7 @@ static bool vertex_paint_from_weight(Object *ob) } while (j < mp->totloop); } - DAG_id_tag_update(&ob->id, OB_RECALC_DATA); + DEG_id_tag_update(&ob->id, OB_RECALC_DATA); return true; } @@ -304,7 +306,7 @@ static bool vertex_color_smooth(Object *ob) MEM_freeN(mlooptag); - DAG_id_tag_update(&me->id, 0); + DEG_id_tag_update(&me->id, 0); return true; } diff --git a/source/blender/editors/sculpt_paint/paint_vertex_color_utils.c b/source/blender/editors/sculpt_paint/paint_vertex_color_utils.c index a0bd5ea2a2d..481d5e7d5ea 100644 --- a/source/blender/editors/sculpt_paint/paint_vertex_color_utils.c +++ b/source/blender/editors/sculpt_paint/paint_vertex_color_utils.c @@ -38,9 +38,10 @@ #include "IMB_colormanagement.h" #include "BKE_context.h" -#include "BKE_depsgraph.h" #include "BKE_mesh.h" +#include "DEG_depsgraph.h" + #include "ED_mesh.h" #include "paint_intern.h" /* own include */ @@ -87,7 +88,7 @@ bool ED_vpaint_color_transform( /* remove stale me->mcol, will be added later */ BKE_mesh_tessface_clear(me); - DAG_id_tag_update(&me->id, 0); + DEG_id_tag_update(&me->id, 0); return true; } diff --git a/source/blender/editors/sculpt_paint/paint_vertex_proj.c b/source/blender/editors/sculpt_paint/paint_vertex_proj.c index 411a0ca9ec3..602bfe1ab8e 100644 --- a/source/blender/editors/sculpt_paint/paint_vertex_proj.c +++ b/source/blender/editors/sculpt_paint/paint_vertex_proj.c @@ -28,7 +28,7 @@ * \ingroup edsculpt * * Utility functions for getting vertex locations while painting - * (since they may be instanced multiple times in a DerivedMesh) + * (since they may be instanced multiple times in an evaluated mesh) */ #include "MEM_guardedalloc.h" @@ -39,8 +39,12 @@ #include "DNA_mesh_types.h" #include "DNA_object_types.h" -#include "BKE_DerivedMesh.h" +#include "BKE_DerivedMesh.h" /* XXX To be removed, only used for DMCoNo struct */ #include "BKE_context.h" +#include "BKE_mesh_iterators.h" +#include "BKE_mesh_runtime.h" + +#include "DEG_depsgraph.h" #include "ED_screen.h" #include "ED_view3d.h" @@ -100,28 +104,14 @@ static void vpaint_proj_dm_map_cosnos_init__map_cb( } static void vpaint_proj_dm_map_cosnos_init( - Scene *scene, Object *ob, + struct Depsgraph *depsgraph, Scene *scene, Object *ob, struct VertProjHandle *vp_handle) { Mesh *me = ob->data; - DerivedMesh *dm; - - dm = mesh_get_derived_final(scene, ob, CD_MASK_BAREMESH | CD_MASK_ORIGINDEX); + Mesh *me_eval = mesh_get_eval_final(depsgraph, scene, ob, CD_MASK_BAREMESH | CD_MASK_ORIGINDEX); - if (dm->foreachMappedVert) { - memset(vp_handle->vcosnos, 0, sizeof(DMCoNo) * me->totvert); - dm->foreachMappedVert(dm, vpaint_proj_dm_map_cosnos_init__map_cb, vp_handle, DM_FOREACH_USE_NORMAL); - } - else { - DMCoNo *v_co_no = vp_handle->vcosnos; - int a; - for (a = 0; a < me->totvert; a++, v_co_no++) { - dm->getVertCo(dm, a, v_co_no->co); - dm->getVertNo(dm, a, v_co_no->no); - } - } - - dm->release(dm); + memset(vp_handle->vcosnos, 0, sizeof(*vp_handle->vcosnos) * me->totvert); + BKE_mesh_foreach_mapped_vert(me_eval, vpaint_proj_dm_map_cosnos_init__map_cb, vp_handle, MESH_FOREACH_USE_NORMAL); } @@ -174,7 +164,7 @@ static void vpaint_proj_dm_map_cosnos_update__map_cb( } static void vpaint_proj_dm_map_cosnos_update( - struct VertProjHandle *vp_handle, + struct Depsgraph *depsgraph, struct VertProjHandle *vp_handle, ARegion *ar, const float mval_fl[2]) { struct VertProjUpdate vp_update = {vp_handle, ar, mval_fl}; @@ -182,21 +172,13 @@ static void vpaint_proj_dm_map_cosnos_update( Scene *scene = vp_handle->scene; Object *ob = vp_handle->ob; Mesh *me = ob->data; - DerivedMesh *dm; + Mesh *me_eval = mesh_get_eval_final(depsgraph, scene, ob, CD_MASK_BAREMESH | CD_MASK_ORIGINDEX); /* quick sanity check - we shouldn't have to run this if there are no modifiers */ BLI_assert(BLI_listbase_is_empty(&ob->modifiers) == false); - dm = mesh_get_derived_final(scene, ob, CD_MASK_BAREMESH | CD_MASK_ORIGINDEX); - - /* highly unlikely this will become unavailable once painting starts (perhaps with animated modifiers) */ - if (LIKELY(dm->foreachMappedVert)) { - copy_vn_fl(vp_handle->dists_sq, me->totvert, FLT_MAX); - - dm->foreachMappedVert(dm, vpaint_proj_dm_map_cosnos_update__map_cb, &vp_update, DM_FOREACH_USE_NORMAL); - } - - dm->release(dm); + copy_vn_fl(vp_handle->dists_sq, me->totvert, FLT_MAX); + BKE_mesh_foreach_mapped_vert(me_eval, vpaint_proj_dm_map_cosnos_update__map_cb, &vp_update, MESH_FOREACH_USE_NORMAL); } @@ -204,7 +186,7 @@ static void vpaint_proj_dm_map_cosnos_update( /* Public Functions */ struct VertProjHandle *ED_vpaint_proj_handle_create( - Scene *scene, Object *ob, + struct Depsgraph *depsgraph, Scene *scene, Object *ob, DMCoNo **r_vcosnos) { struct VertProjHandle *vp_handle = MEM_mallocN(sizeof(struct VertProjHandle), __func__); @@ -215,7 +197,7 @@ struct VertProjHandle *ED_vpaint_proj_handle_create( vp_handle->use_update = false; /* sets 'use_update' if needed */ - vpaint_proj_dm_map_cosnos_init(scene, ob, vp_handle); + vpaint_proj_dm_map_cosnos_init(depsgraph, scene, ob, vp_handle); if (vp_handle->use_update) { vp_handle->dists_sq = MEM_mallocN(sizeof(float) * me->totvert, __func__); @@ -235,11 +217,11 @@ struct VertProjHandle *ED_vpaint_proj_handle_create( } void ED_vpaint_proj_handle_update( - struct VertProjHandle *vp_handle, + struct Depsgraph *depsgraph, struct VertProjHandle *vp_handle, ARegion *ar, const float mval_fl[2]) { if (vp_handle->use_update) { - vpaint_proj_dm_map_cosnos_update(vp_handle, ar, mval_fl); + vpaint_proj_dm_map_cosnos_update(depsgraph, vp_handle, ar, mval_fl); } } diff --git a/source/blender/editors/sculpt_paint/paint_vertex_weight_ops.c b/source/blender/editors/sculpt_paint/paint_vertex_weight_ops.c index fade31fff0d..d19a1d3a189 100644 --- a/source/blender/editors/sculpt_paint/paint_vertex_weight_ops.c +++ b/source/blender/editors/sculpt_paint/paint_vertex_weight_ops.c @@ -35,8 +35,8 @@ #include "IMB_imbuf_types.h" #include "IMB_colormanagement.h" -//#include "DNA_armature_types.h" #include "DNA_mesh_types.h" +#include "DNA_meshdata_types.h" #include "DNA_particle_types.h" #include "DNA_brush_types.h" #include "DNA_object_types.h" @@ -46,19 +46,21 @@ #include "RNA_define.h" #include "RNA_enum_types.h" -#include "BKE_DerivedMesh.h" #include "BKE_brush.h" #include "BKE_context.h" -#include "BKE_depsgraph.h" #include "BKE_deform.h" #include "BKE_mesh.h" +#include "BKE_mesh_iterators.h" #include "BKE_mesh_mapping.h" +#include "BKE_mesh_runtime.h" #include "BKE_modifier.h" #include "BKE_object_deform.h" #include "BKE_paint.h" #include "BKE_report.h" #include "BKE_colortools.h" +#include "DEG_depsgraph.h" + #include "WM_api.h" #include "WM_types.h" @@ -124,15 +126,16 @@ static bool weight_from_bones_poll(bContext *C) static int weight_from_bones_exec(bContext *C, wmOperator *op) { + Depsgraph *depsgraph = CTX_data_depsgraph(C); Scene *scene = CTX_data_scene(C); Object *ob = CTX_data_active_object(C); Object *armob = modifiers_isDeformedByArmature(ob); Mesh *me = ob->data; int type = RNA_enum_get(op->ptr, "type"); - ED_object_vgroup_calc_from_armature(op->reports, scene, ob, armob, type, (me->editflag & ME_EDIT_MIRROR_X)); + ED_object_vgroup_calc_from_armature(op->reports, depsgraph, scene, ob, armob, type, (me->editflag & ME_EDIT_MIRROR_X)); - DAG_id_tag_update(&me->id, 0); + DEG_id_tag_update(&me->id, 0); WM_event_add_notifier(C, NC_GEOM | ND_DATA, me); return OPERATOR_FINISHED; @@ -366,7 +369,7 @@ static int weight_sample_group_exec(bContext *C, wmOperator *op) BLI_assert(type + 1 >= 0); vc.obact->actdef = type + 1; - DAG_id_tag_update(&vc.obact->id, OB_RECALC_DATA); + DEG_id_tag_update(&vc.obact->id, OB_RECALC_DATA); WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, vc.obact); return OPERATOR_FINISHED; } @@ -482,7 +485,7 @@ static bool weight_paint_set(Object *ob, float paintweight) wpaint_prev_destroy(&wpp); - DAG_id_tag_update(&me->id, 0); + DEG_id_tag_update(&me->id, 0); return true; } @@ -531,21 +534,21 @@ void PAINT_OT_weight_set(wmOperatorType *ot) * \{ */ /* *** VGroups Gradient *** */ -typedef struct DMGradient_vertStore { +typedef struct WPGradient_vertStore { float sco[2]; float weight_orig; enum { VGRAD_STORE_NOP = 0, VGRAD_STORE_DW_EXIST = (1 << 0) } flag; -} DMGradient_vertStore; +} WPGradient_vertStore; -typedef struct DMGradient_vertStoreBase { +typedef struct WPGradient_vertStoreBase { struct WPaintPrev wpp; - DMGradient_vertStore elem[0]; -} DMGradient_vertStoreBase; + WPGradient_vertStore elem[0]; +} WPGradient_vertStoreBase; -typedef struct DMGradient_userData { +typedef struct WPGradient_userData { struct ARegion *ar; Scene *scene; Mesh *me; @@ -555,7 +558,7 @@ typedef struct DMGradient_userData { float sco_line_div; /* store (1.0f / len_v2v2(sco_start, sco_end)) */ int def_nr; bool is_init; - DMGradient_vertStoreBase *vert_cache; + WPGradient_vertStoreBase *vert_cache; /* only for init */ BLI_bitmap *vert_visit; @@ -563,12 +566,12 @@ typedef struct DMGradient_userData { short use_select; short type; float weightpaint; -} DMGradient_userData; +} WPGradient_userData; -static void gradientVert_update(DMGradient_userData *grad_data, int index) +static void gradientVert_update(WPGradient_userData *grad_data, int index) { Mesh *me = grad_data->me; - DMGradient_vertStore *vs = &grad_data->vert_cache->elem[index]; + WPGradient_vertStore *vs = &grad_data->vert_cache->elem[index]; float alpha; if (grad_data->type == WPAINT_GRADIENT_TYPE_LINEAR) { @@ -616,10 +619,10 @@ static void gradientVertUpdate__mapFunc( void *userData, int index, const float UNUSED(co[3]), const float UNUSED(no_f[3]), const short UNUSED(no_s[3])) { - DMGradient_userData *grad_data = userData; + WPGradient_userData *grad_data = userData; Mesh *me = grad_data->me; if ((grad_data->use_select == false) || (me->mvert[index].flag & SELECT)) { - DMGradient_vertStore *vs = &grad_data->vert_cache->elem[index]; + WPGradient_vertStore *vs = &grad_data->vert_cache->elem[index]; if (vs->sco[0] != FLT_MAX) { gradientVert_update(grad_data, index); } @@ -630,7 +633,7 @@ static void gradientVertInit__mapFunc( void *userData, int index, const float co[3], const float UNUSED(no_f[3]), const short UNUSED(no_s[3])) { - DMGradient_userData *grad_data = userData; + WPGradient_userData *grad_data = userData; Mesh *me = grad_data->me; if ((grad_data->use_select == false) || (me->mvert[index].flag & SELECT)) { @@ -639,7 +642,7 @@ static void gradientVertInit__mapFunc( * updating the mesh may move them about (entering feedback loop) */ if (BLI_BITMAP_TEST(grad_data->vert_visit, index) == 0) { - DMGradient_vertStore *vs = &grad_data->vert_cache->elem[index]; + WPGradient_vertStore *vs = &grad_data->vert_cache->elem[index]; if (ED_view3d_project_float_object(grad_data->ar, co, vs->sco, V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_NEAR) == V3D_PROJ_RET_OK) @@ -672,7 +675,7 @@ static void gradientVertInit__mapFunc( static int paint_weight_gradient_modal(bContext *C, wmOperator *op, const wmEvent *event) { wmGesture *gesture = op->customdata; - DMGradient_vertStoreBase *vert_cache = gesture->userdata; + WPGradient_vertStoreBase *vert_cache = gesture->userdata; int ret = WM_gesture_straightline_modal(C, op, event); if (ret & OPERATOR_RUNNING_MODAL) { @@ -694,7 +697,7 @@ static int paint_weight_gradient_modal(bContext *C, wmOperator *op, const wmEven } MEM_freeN(vert_cache); - DAG_id_tag_update(&ob->id, OB_RECALC_DATA); + DEG_id_tag_update(&ob->id, OB_RECALC_DATA); WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob); } else if (ret & OPERATOR_FINISHED) { @@ -708,7 +711,7 @@ static int paint_weight_gradient_modal(bContext *C, wmOperator *op, const wmEven static int paint_weight_gradient_exec(bContext *C, wmOperator *op) { wmGesture *gesture = op->customdata; - DMGradient_vertStoreBase *vert_cache; + WPGradient_vertStoreBase *vert_cache; struct ARegion *ar = CTX_wm_region(C); Scene *scene = CTX_data_scene(C); Object *ob = CTX_data_active_object(C); @@ -720,20 +723,21 @@ static int paint_weight_gradient_exec(bContext *C, wmOperator *op) float sco_start[2] = {x_start, y_start}; float sco_end[2] = {x_end, y_end}; const bool is_interactive = (gesture != NULL); - DerivedMesh *dm = mesh_get_derived_final(scene, ob, scene->customdata_mask); - DMGradient_userData data = {NULL}; + Depsgraph *depsgraph = CTX_data_depsgraph(C); + + WPGradient_userData data = {NULL}; if (is_interactive) { if (gesture->userdata == NULL) { gesture->userdata = MEM_mallocN( - sizeof(DMGradient_vertStoreBase) + - (sizeof(DMGradient_vertStore) * me->totvert), + sizeof(WPGradient_vertStoreBase) + + (sizeof(WPGradient_vertStore) * me->totvert), __func__); gesture->userdata_free = false; data.is_init = true; - wpaint_prev_create(&((DMGradient_vertStoreBase *)gesture->userdata)->wpp, me->dvert, me->totvert); + wpaint_prev_create(&((WPGradient_vertStoreBase *)gesture->userdata)->wpp, me->dvert, me->totvert); /* on init only, convert face -> vert sel */ if (me->editflag & ME_EDIT_PAINT_FACE_SEL) { @@ -750,8 +754,8 @@ static int paint_weight_gradient_exec(bContext *C, wmOperator *op) data.is_init = true; vert_cache = MEM_mallocN( - sizeof(DMGradient_vertStoreBase) + - (sizeof(DMGradient_vertStore) * me->totvert), + sizeof(WPGradient_vertStoreBase) + + (sizeof(WPGradient_vertStore) * me->totvert), __func__); } @@ -780,19 +784,20 @@ static int paint_weight_gradient_exec(bContext *C, wmOperator *op) ED_view3d_init_mats_rv3d(ob, ar->regiondata); + Mesh *me_eval = mesh_get_eval_final(depsgraph, scene, ob, scene->customdata_mask | CD_MASK_ORIGINDEX); if (data.is_init) { data.vert_visit = BLI_BITMAP_NEW(me->totvert, __func__); - dm->foreachMappedVert(dm, gradientVertInit__mapFunc, &data, DM_FOREACH_NOP); + BKE_mesh_foreach_mapped_vert(me_eval, gradientVertInit__mapFunc, &data, MESH_FOREACH_NOP); MEM_freeN(data.vert_visit); data.vert_visit = NULL; } else { - dm->foreachMappedVert(dm, gradientVertUpdate__mapFunc, &data, DM_FOREACH_NOP); + BKE_mesh_foreach_mapped_vert(me_eval, gradientVertUpdate__mapFunc, &data, MESH_FOREACH_NOP); } - DAG_id_tag_update(&ob->id, OB_RECALC_DATA); + DEG_id_tag_update(&ob->id, OB_RECALC_DATA); WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob); if (is_interactive == false) { @@ -844,7 +849,7 @@ void PAINT_OT_weight_gradient(wmOperatorType *ot) ot->invoke = paint_weight_gradient_invoke; ot->modal = paint_weight_gradient_modal; ot->exec = paint_weight_gradient_exec; - ot->poll = weight_paint_poll; + ot->poll = weight_paint_poll_ignore_tool; ot->cancel = WM_gesture_straightline_cancel; /* flags */ diff --git a/source/blender/editors/sculpt_paint/paint_vertex_weight_utils.c b/source/blender/editors/sculpt_paint/paint_vertex_weight_utils.c index 197b16ffe6e..51cd759b260 100644 --- a/source/blender/editors/sculpt_paint/paint_vertex_weight_utils.c +++ b/source/blender/editors/sculpt_paint/paint_vertex_weight_utils.c @@ -43,6 +43,7 @@ #include "BKE_modifier.h" #include "BKE_object_deform.h" #include "BKE_report.h" +#include "BKE_object.h" #include "WM_api.h" #include "WM_types.h" @@ -58,7 +59,6 @@ bool ED_wpaint_ensure_data( bContext *C, struct ReportList *reports, enum eWPaintFlag flag, struct WPaintVGroupIndex *vgroup_index) { - Scene *scene = CTX_data_scene(C); Object *ob = CTX_data_active_object(C); Mesh *me = BKE_mesh_from_object(ob); @@ -67,7 +67,7 @@ bool ED_wpaint_ensure_data( vgroup_index->mirror = -1; } - if (scene->obedit) { + if (BKE_object_is_in_editmode(ob)) { return false; } diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c index 74baa267b69..a5871c90d56 100644 --- a/source/blender/editors/sculpt_paint/sculpt.c +++ b/source/blender/editors/sculpt_paint/sculpt.c @@ -56,7 +56,6 @@ #include "BKE_brush.h" #include "BKE_ccg.h" #include "BKE_context.h" -#include "BKE_depsgraph.h" #include "BKE_global.h" #include "BKE_image.h" #include "BKE_key.h" @@ -73,8 +72,12 @@ #include "BKE_subsurf.h" #include "BKE_colortools.h" +#include "DEG_depsgraph.h" + #include "WM_api.h" #include "WM_types.h" +#include "WM_message.h" +#include "WM_toolsystem.h" #include "ED_sculpt.h" #include "ED_object.h" @@ -86,9 +89,6 @@ #include "RNA_access.h" #include "RNA_define.h" -#include "GPU_buffers.h" -#include "GPU_extensions.h" - #include "UI_interface.h" #include "UI_resources.h" @@ -500,8 +500,7 @@ bool sculpt_get_redraw_rect(ARegion *ar, RegionView3D *rv3d, return 1; } -void ED_sculpt_redraw_planes_get(float planes[4][4], ARegion *ar, - RegionView3D *rv3d, Object *ob) +void ED_sculpt_redraw_planes_get(float planes[4][4], ARegion *ar, Object *ob) { PBVH *pbvh = ob->sculpt->pbvh; /* copy here, original will be used below */ @@ -509,7 +508,7 @@ void ED_sculpt_redraw_planes_get(float planes[4][4], ARegion *ar, sculpt_extend_redraw_rect_previous(ob, &rect); - paint_calc_redraw_planes(planes, ar, rv3d, ob, &rect); + paint_calc_redraw_planes(planes, ar, ob, &rect); /* we will draw this rect, so now we can set it as the previous partial rect. * Note that we don't update with the union of previous/current (rect), only with @@ -2101,6 +2100,10 @@ static void do_draw_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode) mul_v3_v3(offset, ss->cache->scale); mul_v3_fl(offset, bstrength); + /* XXX - this shouldn't be necessary, but sculpting crashes in blender2.8 otherwise + * initialize before threads so they can do curve mapping */ + curvemapping_initialize(brush->curve); + /* threaded loop over nodes */ SculptThreadedTaskData data = { .sd = sd, .ob = ob, .brush = brush, .nodes = nodes, @@ -4600,10 +4603,11 @@ static void sculpt_stroke_modifiers_check(const bContext *C, Object *ob, const B SculptSession *ss = ob->sculpt; if (ss->kb || ss->modifiers_active) { + Depsgraph *depsgraph = CTX_data_depsgraph(C); Scene *scene = CTX_data_scene(C); Sculpt *sd = scene->toolsettings->sculpt; bool need_pmap = sculpt_any_smooth_mode(brush, ss->cache, 0); - BKE_sculpt_update_mesh_elements(scene, sd, ob, need_pmap, false); + BKE_sculpt_update_mesh_elements(depsgraph, scene, sd, ob, need_pmap, false); } } @@ -4688,7 +4692,7 @@ static float sculpt_raycast_init( RegionView3D *rv3d = vc->ar->regiondata; /* TODO: what if the segment is totally clipped? (return == 0) */ - ED_view3d_win_to_segment(vc->ar, vc->v3d, mouse, ray_start, ray_end, true); + ED_view3d_win_to_segment(vc->depsgraph, vc->ar, vc->v3d, mouse, ray_start, ray_end, true); invert_m4_m4(obimat, ob->obmat); mul_m4_v3(obimat, ray_start); @@ -4806,6 +4810,7 @@ static void sculpt_brush_init_tex(const Scene *scene, Sculpt *sd, SculptSession static void sculpt_brush_stroke_init(bContext *C, wmOperator *op) { + Depsgraph *depsgraph = CTX_data_depsgraph(C); Scene *scene = CTX_data_scene(C); Object *ob = CTX_data_active_object(C); Sculpt *sd = CTX_data_tool_settings(C)->sculpt; @@ -4823,7 +4828,7 @@ static void sculpt_brush_stroke_init(bContext *C, wmOperator *op) sculpt_brush_init_tex(scene, sd, ss); is_smooth = sculpt_any_smooth_mode(brush, NULL, mode); - BKE_sculpt_update_mesh_elements(scene, sd, ob, is_smooth, need_mask); + BKE_sculpt_update_mesh_elements(depsgraph, scene, sd, ob, is_smooth, need_mask); } static void sculpt_restore_mesh(Sculpt *sd, Object *ob) @@ -4861,11 +4866,9 @@ static void sculpt_flush_update(bContext *C) if (mmd) multires_mark_as_modified(ob, MULTIRES_COORDS_MODIFIED); - if (ob->derivedFinal) /* VBO no longer valid */ - GPU_drawobject_free(ob->derivedFinal); if (ss->kb || ss->modifiers_active) { - DAG_id_tag_update(&ob->id, OB_RECALC_DATA); + DEG_id_tag_update(&ob->id, OB_RECALC_DATA); ED_region_tag_redraw(ar); } else { @@ -4895,6 +4898,9 @@ static void sculpt_flush_update(bContext *C) ED_region_tag_redraw_partial(ar, &r); } } + + /* 2.8x - avoid full mesh update! */ + BKE_mesh_batch_cache_dirty(ob->data, BKE_MESH_BATCH_DIRTY_SCULPT_COORDS); } /* Returns whether the mouse/stylus is over the mesh (1) @@ -4978,7 +4984,7 @@ static void sculpt_stroke_update_step(bContext *C, struct PaintStroke *UNUSED(st * Could be optimized later, but currently don't think it's so * much common scenario. * - * Same applies to the DAG_id_tag_update() invoked from + * Same applies to the DEG_id_tag_update() invoked from * sculpt_flush_update(). */ if (ss->modifiers_active) { @@ -5053,7 +5059,7 @@ static void sculpt_stroke_done(const bContext *C, struct PaintStroke *UNUSED(str /* try to avoid calling this, only for e.g. linked duplicates now */ if (((Mesh *)ob->data)->id.us > 1) - DAG_id_tag_update(&ob->id, OB_RECALC_DATA); + DEG_id_tag_update(&ob->id, OB_RECALC_DATA); WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob); } @@ -5200,14 +5206,12 @@ static void sculpt_dynamic_topology_triangulate(BMesh *bm) void sculpt_pbvh_clear(Object *ob) { SculptSession *ss = ob->sculpt; - DerivedMesh *dm = ob->derivedFinal; /* Clear out any existing DM and PBVH */ - if (ss->pbvh) + if (ss->pbvh) { BKE_pbvh_free(ss->pbvh); + } ss->pbvh = NULL; - if (dm) - dm->getPBVH(NULL, dm); BKE_object_free_derived_caches(ob); } @@ -5244,16 +5248,18 @@ void sculpt_dyntopo_node_layers_add(SculptSession *ss) void sculpt_update_after_dynamic_topology_toggle( + Depsgraph *depsgraph, Scene *scene, Object *ob) { Sculpt *sd = scene->toolsettings->sculpt; /* Create the PBVH */ - BKE_sculpt_update_mesh_elements(scene, sd, ob, false, false); + BKE_sculpt_update_mesh_elements(depsgraph, scene, sd, ob, false, false); WM_main_add_notifier(NC_OBJECT | ND_DRAW, ob); } void sculpt_dynamic_topology_enable_ex( + Depsgraph *depsgraph, Scene *scene, Object *ob) { SculptSession *ss = ob->sculpt; @@ -5291,7 +5297,7 @@ void sculpt_dynamic_topology_enable_ex( ss->bm_log = BM_log_create(ss->bm); /* Refresh */ - sculpt_update_after_dynamic_topology_toggle(scene, ob); + sculpt_update_after_dynamic_topology_toggle(depsgraph, scene, ob); } /* Free the sculpt BMesh and BMLog @@ -5299,6 +5305,7 @@ void sculpt_dynamic_topology_enable_ex( * If 'unode' is given, the BMesh's data is copied out to the unode * before the BMesh is deleted so that it can be restored from */ void sculpt_dynamic_topology_disable_ex( + Depsgraph *depsgraph, Scene *scene, Object *ob, SculptUndoNode *unode) { SculptSession *ss = ob->sculpt; @@ -5349,35 +5356,37 @@ void sculpt_dynamic_topology_disable_ex( } /* Refresh */ - sculpt_update_after_dynamic_topology_toggle(scene, ob); + sculpt_update_after_dynamic_topology_toggle(depsgraph, scene, ob); } void sculpt_dynamic_topology_disable(bContext *C, SculptUndoNode *unode) { + Depsgraph *depsgraph = CTX_data_depsgraph(C); Scene *scene = CTX_data_scene(C); Object *ob = CTX_data_active_object(C); - sculpt_dynamic_topology_disable_ex(scene, ob, unode); + sculpt_dynamic_topology_disable_ex(depsgraph, scene, ob, unode); } static void sculpt_dynamic_topology_disable_with_undo( - Scene *scene, Object *ob) + Depsgraph *depsgraph, Scene *scene, Object *ob) { SculptSession *ss = ob->sculpt; if (ss->bm) { sculpt_undo_push_begin("Dynamic topology disable"); sculpt_undo_push_node(ob, NULL, SCULPT_UNDO_DYNTOPO_END); - sculpt_dynamic_topology_disable_ex(scene, ob, NULL); + sculpt_dynamic_topology_disable_ex(depsgraph, scene, ob, NULL); sculpt_undo_push_end(); } } static void sculpt_dynamic_topology_enable_with_undo( + Depsgraph *depsgraph, Scene *scene, Object *ob) { SculptSession *ss = ob->sculpt; if (ss->bm == NULL) { sculpt_undo_push_begin("Dynamic topology enable"); - sculpt_dynamic_topology_enable_ex(scene, ob); + sculpt_dynamic_topology_enable_ex(depsgraph, scene, ob); sculpt_undo_push_node(ob, NULL, SCULPT_UNDO_DYNTOPO_BEGIN); sculpt_undo_push_end(); } @@ -5385,6 +5394,7 @@ static void sculpt_dynamic_topology_enable_with_undo( static int sculpt_dynamic_topology_toggle_exec(bContext *C, wmOperator *UNUSED(op)) { + Depsgraph *depsgraph = CTX_data_depsgraph(C); Scene *scene = CTX_data_scene(C); Object *ob = CTX_data_active_object(C); SculptSession *ss = ob->sculpt; @@ -5392,10 +5402,10 @@ static int sculpt_dynamic_topology_toggle_exec(bContext *C, wmOperator *UNUSED(o WM_cursor_wait(1); if (ss->bm) { - sculpt_dynamic_topology_disable_with_undo(scene, ob); + sculpt_dynamic_topology_disable_with_undo(depsgraph, scene, ob); } else { - sculpt_dynamic_topology_enable_with_undo(scene, ob); + sculpt_dynamic_topology_enable_with_undo(depsgraph, scene, ob); } WM_cursor_wait(0); @@ -5606,13 +5616,14 @@ static void SCULPT_OT_symmetrize(wmOperatorType *ot) /**** Toggle operator for turning sculpt mode on or off ****/ -static void sculpt_init_session(Scene *scene, Object *ob) +static void sculpt_init_session(Depsgraph *depsgraph, Scene *scene, Object *ob) { /* Create persistent sculpt mode data */ BKE_sculpt_toolsettings_data_ensure(scene); ob->sculpt = MEM_callocN(sizeof(SculptSession), "sculpt session"); - BKE_sculpt_update_mesh_elements(scene, scene->toolsettings->sculpt, ob, false, false); + ob->sculpt->mode_type = OB_MODE_SCULPT; + BKE_sculpt_update_mesh_elements(depsgraph, scene, scene->toolsettings->sculpt, ob, false, false); } static int ed_object_sculptmode_flush_recalc_flag(Scene *scene, Object *ob, MultiresModifierData *mmd) @@ -5626,7 +5637,8 @@ static int ed_object_sculptmode_flush_recalc_flag(Scene *scene, Object *ob, Mult } void ED_object_sculptmode_enter_ex( - Main *bmain, Scene *scene, Object *ob, + Main *bmain, Depsgraph *depsgraph, + Scene *scene, Object *ob, ReportList *reports) { const int mode_flag = OB_MODE_SCULPT; @@ -5635,21 +5647,24 @@ void ED_object_sculptmode_enter_ex( /* Enter sculptmode */ ob->mode |= mode_flag; - MultiresModifierData *mmd = BKE_sculpt_multires_active(scene, ob); const int flush_recalc = ed_object_sculptmode_flush_recalc_flag(scene, ob, mmd); - if (flush_recalc) { - DAG_id_tag_update(&ob->id, OB_RECALC_DATA); - } + if (flush_recalc) + DEG_id_tag_update(&ob->id, OB_RECALC_DATA); /* Create sculpt mode session data */ if (ob->sculpt) { BKE_sculptsession_free(ob); } - sculpt_init_session(scene, ob); + /* Make sure derived final from original object does not reference possibly + * freed memory. + */ + BKE_object_free_derived_caches(ob); + + sculpt_init_session(depsgraph, scene, ob); /* Mask layer is required */ if (mmd) { @@ -5707,7 +5722,7 @@ void ED_object_sculptmode_enter_ex( if (message_unsupported == NULL) { /* undo push is needed to prevent memory leak */ sculpt_undo_push_begin("Dynamic topology enable"); - sculpt_dynamic_topology_enable_ex(scene, ob); + sculpt_dynamic_topology_enable_ex(depsgraph, scene, ob); sculpt_undo_push_node(ob, NULL, SCULPT_UNDO_DYNTOPO_BEGIN); } else { @@ -5718,10 +5733,10 @@ void ED_object_sculptmode_enter_ex( } } - /* VBO no longer valid */ - if (ob->derivedFinal) { - GPU_drawobject_free(ob->derivedFinal); - } + // ED_workspace_object_mode_sync_from_object(bmain->wm.first, workspace, ob); + + /* Flush object mode. */ + DEG_id_tag_update(&ob->id, DEG_TAG_COPY_ON_WRITE); } void ED_object_sculptmode_enter(struct bContext *C, ReportList *reports) @@ -5729,10 +5744,12 @@ void ED_object_sculptmode_enter(struct bContext *C, ReportList *reports) Main *bmain = CTX_data_main(C); Scene *scene = CTX_data_scene(C); Object *ob = CTX_data_active_object(C); - ED_object_sculptmode_enter_ex(bmain, scene, ob, reports); + Depsgraph *depsgraph = CTX_data_depsgraph(C); + ED_object_sculptmode_enter_ex(bmain, depsgraph, scene, ob, reports); } void ED_object_sculptmode_exit_ex( + Depsgraph *depsgraph, Scene *scene, Object *ob) { const int mode_flag = OB_MODE_SCULPT; @@ -5752,14 +5769,14 @@ void ED_object_sculptmode_exit_ex( * a consistent state. */ if (true || /* flush_recalc || */ (ob->sculpt && ob->sculpt->bm)) { - DAG_id_tag_update(&ob->id, OB_RECALC_DATA); + DEG_id_tag_update(&ob->id, OB_RECALC_DATA); } if (me->flag & ME_SCULPT_DYNAMIC_TOPOLOGY) { /* Dynamic topology must be disabled before exiting sculpt * mode to ensure the undo stack stays in a consistent * state */ - sculpt_dynamic_topology_disable_with_undo(scene, ob); + sculpt_dynamic_topology_disable_with_undo(depsgraph, scene, ob); /* store so we know to re-enable when entering sculpt mode */ me->flag |= ME_SCULPT_DYNAMIC_TOPOLOGY; @@ -5768,26 +5785,32 @@ void ED_object_sculptmode_exit_ex( /* Leave sculptmode */ ob->mode &= ~mode_flag; + // ED_workspace_object_mode_sync_from_object(G_MAIN->wm.first, workspace, ob); + BKE_sculptsession_free(ob); paint_cursor_delete_textures(); - /* VBO no longer valid */ - if (ob->derivedFinal) { - GPU_drawobject_free(ob->derivedFinal); - } + /* Never leave derived meshes behind. */ + BKE_object_free_derived_caches(ob); + + /* Flush object mode. */ + DEG_id_tag_update(&ob->id, DEG_TAG_COPY_ON_WRITE); } void ED_object_sculptmode_exit(bContext *C) { + Depsgraph *depsgraph = CTX_data_depsgraph(C); Scene *scene = CTX_data_scene(C); Object *ob = CTX_data_active_object(C); - ED_object_sculptmode_exit_ex(scene, ob); + ED_object_sculptmode_exit_ex(depsgraph, scene, ob); } static int sculpt_mode_toggle_exec(bContext *C, wmOperator *op) { + struct wmMsgBus *mbus = CTX_wm_message_bus(C); Main *bmain = CTX_data_main(C); + Depsgraph *depsgraph = CTX_data_depsgraph_on_load(C); Scene *scene = CTX_data_scene(C); Object *ob = CTX_data_active_object(C); const int mode_flag = OB_MODE_SCULPT; @@ -5800,14 +5823,18 @@ static int sculpt_mode_toggle_exec(bContext *C, wmOperator *op) } if (is_mode_set) { - ED_object_sculptmode_exit_ex(scene, ob); + ED_object_sculptmode_exit_ex(depsgraph, scene, ob); } else { - ED_object_sculptmode_enter_ex(bmain, scene, ob, op->reports); + ED_object_sculptmode_enter_ex(bmain, depsgraph, scene, ob, op->reports); } WM_event_add_notifier(C, NC_SCENE | ND_MODE, scene); + WM_msg_publish_rna_prop(mbus, &ob->id, ob, Object, mode); + + WM_toolsystem_update_from_context_view3d(C); + return OPERATOR_FINISHED; } @@ -5943,8 +5970,7 @@ static int sculpt_sample_detail_size_exec(bContext *C, wmOperator *op) static int sculpt_sample_detail_size_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(e)) { - ScrArea *sa = CTX_wm_area(C); - ED_area_headerprint(sa, "Click on the mesh to set the detail"); + ED_workspace_status_text(C, "Click on the mesh to set the detail"); WM_cursor_modal_set(CTX_wm_window(C), BC_EYEDROPPER_CURSOR); WM_event_add_modal_handler(C, op); return OPERATOR_RUNNING_MODAL; @@ -5955,14 +5981,13 @@ static int sculpt_sample_detail_size_modal(bContext *C, wmOperator *op, const wm switch (e->type) { case LEFTMOUSE: if (e->val == KM_PRESS) { - ScrArea *sa = CTX_wm_area(C); int ss_co[2] = {e->mval[0], e->mval[1]}; sample_detail(C, ss_co); RNA_int_set_array(op->ptr, "location", ss_co); WM_cursor_modal_restore(CTX_wm_window(C)); - ED_area_headerprint(sa, NULL); + ED_workspace_status_text(C, NULL); WM_main_add_notifier(NC_SCENE | ND_TOOLSETTINGS, NULL); return OPERATOR_FINISHED; @@ -5971,9 +5996,8 @@ static int sculpt_sample_detail_size_modal(bContext *C, wmOperator *op, const wm case RIGHTMOUSE: { - ScrArea *sa = CTX_wm_area(C); WM_cursor_modal_restore(CTX_wm_window(C)); - ED_area_headerprint(sa, NULL); + ED_workspace_status_text(C, NULL); return OPERATOR_CANCELLED; } diff --git a/source/blender/editors/sculpt_paint/sculpt_intern.h b/source/blender/editors/sculpt_paint/sculpt_intern.h index 137e957dce6..2154061da1b 100644 --- a/source/blender/editors/sculpt_paint/sculpt_intern.h +++ b/source/blender/editors/sculpt_paint/sculpt_intern.h @@ -61,12 +61,15 @@ bool sculpt_stroke_get_location(struct bContext *C, float out[3], const float mo void sculpt_pbvh_clear(Object *ob); void sculpt_dyntopo_node_layers_add(struct SculptSession *ss); void sculpt_update_after_dynamic_topology_toggle( + struct Depsgraph *depsgraph, struct Scene *scene, struct Object *ob); void sculpt_dynamic_topology_enable_ex( + struct Depsgraph *depsgraph, struct Scene *scene, struct Object *ob); void sculpt_dynamic_topology_enable(bContext *C); void sculpt_dynamic_topology_disable_ex( + struct Depsgraph *depsgraph, struct Scene *scene, struct Object *ob, struct SculptUndoNode *unode); void sculpt_dynamic_topology_disable(bContext *C, struct SculptUndoNode *unode); diff --git a/source/blender/editors/sculpt_paint/sculpt_undo.c b/source/blender/editors/sculpt_paint/sculpt_undo.c index bf5ddeb71ff..bc22147b15d 100644 --- a/source/blender/editors/sculpt_paint/sculpt_undo.c +++ b/source/blender/editors/sculpt_paint/sculpt_undo.c @@ -50,22 +50,23 @@ #include "DNA_mesh_types.h" #include "DNA_screen_types.h" #include "DNA_space_types.h" +#include "DNA_workspace_types.h" #include "BKE_ccg.h" #include "BKE_context.h" -#include "BKE_depsgraph.h" #include "BKE_multires.h" #include "BKE_paint.h" #include "BKE_key.h" #include "BKE_mesh.h" +#include "BKE_mesh_runtime.h" #include "BKE_subsurf.h" #include "BKE_undo_system.h" +#include "DEG_depsgraph.h" + #include "WM_api.h" #include "WM_types.h" -#include "GPU_buffers.h" - #include "ED_paint.h" #include "ED_object.h" #include "ED_sculpt.h" @@ -140,6 +141,7 @@ static bool sculpt_undo_restore_coords(bContext *C, DerivedMesh *dm, SculptUndoN Scene *scene = CTX_data_scene(C); Sculpt *sd = CTX_data_tool_settings(C)->sculpt; Object *ob = CTX_data_active_object(C); + Depsgraph *depsgraph = CTX_data_depsgraph(C); SculptSession *ss = ob->sculpt; MVert *mvert; int *index; @@ -156,7 +158,7 @@ static bool sculpt_undo_restore_coords(bContext *C, DerivedMesh *dm, SculptUndoN if (kb) { ob->shapenr = BLI_findindex(&key->block, kb) + 1; - BKE_sculpt_update_mesh_elements(scene, sd, ob, false, false); + BKE_sculpt_update_mesh_elements(depsgraph, scene, sd, ob, false, false); WM_event_add_notifier(C, NC_OBJECT | ND_DATA, ob); } else { @@ -196,7 +198,7 @@ static bool sculpt_undo_restore_coords(bContext *C, DerivedMesh *dm, SculptUndoN /* pbvh uses it's own mvert array, so coords should be */ /* propagated to pbvh here */ - BKE_pbvh_apply_vertCos(ss->pbvh, vertCos); + BKE_pbvh_apply_vertCos(ss->pbvh, vertCos, unode->totvert); MEM_freeN(vertCos); } @@ -378,8 +380,8 @@ static void sculpt_undo_bmesh_restore_generic(bContext *C, } /* Create empty sculpt BMesh and enable logging */ -static void sculpt_undo_bmesh_enable(Object *ob, - SculptUndoNode *unode) +static void sculpt_undo_bmesh_enable( + Object *ob, SculptUndoNode *unode) { SculptSession *ss = ob->sculpt; Mesh *me = ob->data; @@ -472,6 +474,7 @@ static void sculpt_undo_restore_list(bContext *C, ListBase *lb) Scene *scene = CTX_data_scene(C); Sculpt *sd = CTX_data_tool_settings(C)->sculpt; Object *ob = CTX_data_active_object(C); + Depsgraph *depsgraph = CTX_data_depsgraph(C); DerivedMesh *dm; SculptSession *ss = ob->sculpt; SculptUndoNode *unode; @@ -490,10 +493,12 @@ static void sculpt_undo_restore_list(bContext *C, ListBase *lb) } } - BKE_sculpt_update_mesh_elements(scene, sd, ob, false, need_mask); + DEG_id_tag_update(&ob->id, DEG_TAG_COPY_ON_WRITE); + + BKE_sculpt_update_mesh_elements(depsgraph, scene, sd, ob, false, need_mask); /* call _after_ sculpt_update_mesh_elements() which may update 'ob->derivedFinal' */ - dm = mesh_get_derived_final(scene, ob, 0); + dm = mesh_get_derived_final(depsgraph, scene, ob, 0); if (lb->first && sculpt_undo_bmesh_restore(C, lb->first, ob, ss)) return; @@ -556,7 +561,7 @@ static void sculpt_undo_restore_list(bContext *C, ListBase *lb) else { BKE_pbvh_search_callback(ss->pbvh, NULL, NULL, update_cb, &rebuild); } - BKE_pbvh_update(ss->pbvh, PBVH_UpdateBB | PBVH_UpdateOriginalBB | PBVH_UpdateRedraw, NULL); + BKE_pbvh_update(ss->pbvh, PBVH_UpdateBB | PBVH_UpdateOriginalBB | PBVH_UpdateRedraw | PBVH_UpdateNormals, NULL); if (BKE_sculpt_multires_active(scene, ob)) { if (rebuild) @@ -576,14 +581,11 @@ static void sculpt_undo_restore_list(bContext *C, ListBase *lb) } if (tag_update) { - DAG_id_tag_update(&ob->id, OB_RECALC_DATA); + DEG_id_tag_update(&ob->id, OB_RECALC_DATA); } else { sculpt_update_object_bounding_box(ob); } - - /* for non-PBVH drawing, need to recreate VBOs */ - GPU_drawobject_free(ob->derivedFinal); } } diff --git a/source/blender/editors/sculpt_paint/sculpt_uv.c b/source/blender/editors/sculpt_paint/sculpt_uv.c index 7e30c8b5b23..29b258fc80d 100644 --- a/source/blender/editors/sculpt_paint/sculpt_uv.c +++ b/source/blender/editors/sculpt_paint/sculpt_uv.c @@ -46,16 +46,21 @@ #include "BKE_colortools.h" #include "BKE_context.h" #include "BKE_customdata.h" -#include "BKE_depsgraph.h" #include "BKE_editmesh.h" #include "BKE_main.h" #include "BKE_mesh_mapping.h" #include "BKE_paint.h" +#include "DEG_depsgraph.h" + #include "ED_screen.h" #include "ED_image.h" #include "ED_mesh.h" +#include "GPU_immediate.h" +#include "GPU_immediate_util.h" +#include "GPU_state.h" + #include "WM_api.h" #include "WM_types.h" @@ -65,9 +70,6 @@ #include "paint_intern.h" #include "uvedit_intern.h" -#include "BIF_gl.h" -#include "BIF_glutil.h" - #include "UI_view2d.h" #define MARK_BOUNDARY 1 @@ -213,18 +215,17 @@ static void brush_drawcursor_uvsculpt(bContext *C, int x, int y, void *UNUSED(cu alpha *= (size - PX_SIZE_FADE_MIN) / (PX_SIZE_FADE_MAX - PX_SIZE_FADE_MIN); } - glPushMatrix(); - - glTranslatef((float)x, (float)y, 0.0f); + unsigned int pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); + immUniformColor3fvAlpha(brush->add_col, alpha); - glColor4f(brush->add_col[0], brush->add_col[1], brush->add_col[2], alpha); - glEnable(GL_LINE_SMOOTH); - glEnable(GL_BLEND); - glutil_draw_lined_arc(0, (float)(M_PI * 2.0), size, 40); - glDisable(GL_BLEND); - glDisable(GL_LINE_SMOOTH); + GPU_line_smooth(true); + GPU_blend(true); + imm_draw_circle_wire_2d(pos, (float)x, (float)y, size, 40); + GPU_blend(false); + GPU_line_smooth(false); - glPopMatrix(); + immUnbindProgram(); } #undef PX_SIZE_FADE_MAX #undef PX_SIZE_FADE_MIN @@ -654,7 +655,7 @@ static UvSculptData *uv_sculpt_stroke_init(bContext *C, wmOperator *op, const wm UvElement *element; UvNearestHit hit = UV_NEAREST_HIT_INIT; Image *ima = CTX_data_edit_image(C); - uv_find_nearest_vert(scene, ima, em, co, 0.0f, &hit); + uv_find_nearest_vert(scene, ima, obedit, co, 0.0f, &hit); element = BM_uv_element_get(data->elementMap, hit.efa, hit.l); island_index = element->island; @@ -901,7 +902,7 @@ static int uv_sculpt_stroke_modal(bContext *C, wmOperator *op, const wmEvent *ev ED_region_tag_redraw(CTX_wm_region(C)); WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data); - DAG_id_tag_update(obedit->data, 0); + DEG_id_tag_update(obedit->data, 0); return OPERATOR_RUNNING_MODAL; } |