Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/editors/sculpt_paint')
-rw-r--r--source/blender/editors/sculpt_paint/CMakeLists.txt1
-rw-r--r--source/blender/editors/sculpt_paint/paint_cursor.c452
-rw-r--r--source/blender/editors/sculpt_paint/paint_curve.c4
-rw-r--r--source/blender/editors/sculpt_paint/paint_hide.c16
-rw-r--r--source/blender/editors/sculpt_paint/paint_image.c120
-rw-r--r--source/blender/editors/sculpt_paint/paint_image_2d.c10
-rw-r--r--source/blender/editors/sculpt_paint/paint_image_proj.c570
-rw-r--r--source/blender/editors/sculpt_paint/paint_image_undo.c6
-rw-r--r--source/blender/editors/sculpt_paint/paint_intern.h44
-rw-r--r--source/blender/editors/sculpt_paint/paint_mask.c24
-rw-r--r--source/blender/editors/sculpt_paint/paint_ops.c94
-rw-r--r--source/blender/editors/sculpt_paint/paint_stroke.c125
-rw-r--r--source/blender/editors/sculpt_paint/paint_utils.c87
-rw-r--r--source/blender/editors/sculpt_paint/paint_vertex.c135
-rw-r--r--source/blender/editors/sculpt_paint/paint_vertex_color_ops.c10
-rw-r--r--source/blender/editors/sculpt_paint/paint_vertex_color_utils.c5
-rw-r--r--source/blender/editors/sculpt_paint/paint_vertex_proj.c54
-rw-r--r--source/blender/editors/sculpt_paint/paint_vertex_weight_ops.c82
-rw-r--r--source/blender/editors/sculpt_paint/paint_vertex_weight_utils.c4
-rw-r--r--source/blender/editors/sculpt_paint/sculpt.c214
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_intern.h3
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_undo.c39
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_uv.c33
23 files changed, 1144 insertions, 988 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 f503ab37230..5cca61d4c78 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"
@@ -339,11 +340,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);
@@ -358,8 +360,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);
@@ -467,22 +467,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);
@@ -612,36 +611,33 @@ static void paint_draw_tex_overlay(
}
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) {
+ GPU_matrix_push();
+
/* 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);
+ GPU_matrix_translate_2f(x, y);
+ GPU_matrix_rotate_2d(-RAD2DEGF(primary ? ups->brush_rotation : ups->brush_rotation_sec));
+ GPU_matrix_translate_2f(-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;
+ GPU_matrix_translate_2f(x, y);
+ GPU_matrix_scale_2f(scale, scale);
+ GPU_matrix_translate_2f(-x, -y);
}
if (ups->draw_anchored) {
- const float *aim = ups->anchored_initial_mouse;
- quad.xmin = aim[0] - ups->anchored_size;
- quad.ymin = aim[1] - ups->anchored_size;
- quad.xmax = aim[0] + ups->anchored_size;
- quad.ymax = aim[1] + ups->anchored_size;
+ quad.xmin = ups->anchored_initial_mouse[0] - ups->anchored_size;
+ quad.ymin = ups->anchored_initial_mouse[1] - ups->anchored_size;
+ quad.xmax = ups->anchored_initial_mouse[0] + ups->anchored_size;
+ quad.ymax = ups->anchored_initial_mouse[1] + ups->anchored_size;
}
else {
const int radius = BKE_brush_size_get(vc->scene, brush) * zoom;
@@ -671,41 +667,48 @@ static void paint_draw_tex_overlay(
quad.xmax = brush->mask_stencil_dimension[0];
quad.ymax = brush->mask_stencil_dimension[1];
}
- glMatrixMode(GL_MODELVIEW);
- glPushMatrix();
+ GPU_matrix_push();
if (primary)
- glTranslate2fv(brush->stencil_pos);
+ GPU_matrix_translate_2fv(brush->stencil_pos);
else
- glTranslate2fv(brush->mask_stencil_pos);
- glRotatef(RAD2DEGF(mtex->rot), 0, 0, 1);
- glMatrixMode(GL_TEXTURE);
+ GPU_matrix_translate_2fv(brush->mask_stencil_pos);
+ GPU_matrix_rotate_2d(RAD2DEGF(mtex->rot));
}
/* set quad color. Colored overlay does not get blending */
+ GPUVertFormat *format = immVertexFormat();
+ uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
+ uint texCoord = GPU_vertformat_attr_add(format, "texCoord", GPU_COMP_F32, 2, GPU_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);
+ GPU_blend_set_func(GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
+ 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(GPU_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();
+ GPU_blend_set_func(GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA);
+
+ if (ELEM(mtex->brush_map_mode, MTEX_MAP_MODE_STENCIL, MTEX_MAP_MODE_VIEW)) {
+ GPU_matrix_pop();
}
}
}
@@ -726,19 +729,18 @@ static void paint_draw_cursor_overlay(
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;
- copy_v2_v2(center, aim);
- quad.xmin = aim[0] - ups->anchored_size;
- quad.ymin = aim[1] - ups->anchored_size;
- quad.xmax = aim[0] + ups->anchored_size;
- quad.ymax = aim[1] + ups->anchored_size;
+ copy_v2_v2(center, ups->anchored_initial_mouse);
+ quad.xmin = ups->anchored_initial_mouse[0] - ups->anchored_size;
+ quad.ymin = ups->anchored_initial_mouse[1] - ups->anchored_size;
+ quad.xmax = ups->anchored_initial_mouse[0] + ups->anchored_size;
+ quad.ymax = ups->anchored_initial_mouse[1] + ups->anchored_size;
}
else {
const int radius = BKE_brush_size_get(vc->scene, brush) * zoom;
@@ -754,32 +756,43 @@ static void paint_draw_cursor_overlay(
/* 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);
+ GPU_matrix_push();
+ GPU_matrix_translate_2fv(center);
+ GPU_matrix_scale_1f(ups->size_pressure_value);
+ GPU_matrix_translate_2f(-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);
+ GPUVertFormat *format = immVertexFormat();
+ uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
+ uint texCoord = GPU_vertformat_attr_add(format, "texCoord", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
+
+ GPU_blend_set_func(GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
+ immBindBuiltinProgram(GPU_SHADER_2D_IMAGE_ALPHA_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(GPU_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();
+
+ GPU_blend_set_func(GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA);
if (do_pop)
- glPopMatrix();
+ GPU_matrix_pop();
}
}
@@ -790,19 +803,13 @@ static void paint_draw_alpha_overlay(
/* 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);
+ /* Translate to region. */
+ GPU_matrix_push();
+ GPU_matrix_translate_2f(vc->ar->winrct.xmin, vc->ar->winrct.ymin);
+ x -= vc->ar->winrct.xmin;
+ y -= vc->ar->winrct.ymin;
/* coloured overlay should be drawn separately */
if (col) {
@@ -820,86 +827,99 @@ static void paint_draw_alpha_overlay(
paint_draw_cursor_overlay(ups, brush, vc, x, y, zoom);
}
- glPopAttrib();
- GPU_basic_shader_bind(GPU_SHADER_USE_COLOR);
+ GPU_matrix_pop();
+ 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(GPU_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(GPU_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(GPU_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(GPU_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(GPU_PRIM_LINES, 2);
+ immVertex2fv(pos, bez->vec[1]);
+ immVertex2fv(pos, bez->vec[2]);
+ immEnd();
}
static void paint_draw_curve_cursor(Brush *brush)
@@ -909,20 +929,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 */
+ uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_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(
@@ -932,25 +960,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(GPU_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(GPU_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();
}
}
@@ -1001,15 +1039,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))
@@ -1017,6 +1051,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)) {
@@ -1029,15 +1064,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 */
@@ -1053,10 +1088,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);
@@ -1077,34 +1111,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);
+
+ uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_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 0e56a1187e3..3213ee005cf 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"
@@ -713,7 +715,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 01a54e4360d..a0589623f92 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"
@@ -333,12 +333,10 @@ static void clip_planes_from_rect(
{
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);
}
@@ -375,12 +373,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;
@@ -393,9 +391,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 ab04a927573..897a74eb497 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"
@@ -265,7 +269,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;
@@ -274,7 +278,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);
@@ -291,6 +297,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);
@@ -400,18 +416,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);
+
+ GPUVertFormat *format = immVertexFormat();
+ uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_I32, 2, GPU_FETCH_INT_TO_FLOAT);
+
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+
+ GPU_line_width(4.0);
+ immUniformColor4ub(0, 0, 0, 255);
+
+ immBegin(GPU_PRIM_LINES, 2);
+ immVertex2i(pos, x, y);
+ immVertex2i(pos, pop->startmouse[0], pop->startmouse[1]);
+ immEnd();
+
+ GPU_line_width(2.0);
+ immUniformColor4ub(255, 255, 255, 255);
+
+ immBegin(GPU_PRIM_LINES, 2);
+ immVertex2i(pos, x, y);
+ immVertex2i(pos, pop->startmouse[0], pop->startmouse[1]);
+ immEnd();
+
+ immUnbindProgram();
+
+ GPU_blend(false);
+ GPU_line_smooth(false);
}
}
@@ -430,7 +462,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);
@@ -717,16 +750,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);
@@ -857,7 +894,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);
}
}
@@ -936,8 +973,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;
}
@@ -948,7 +983,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;
}
@@ -983,11 +1018,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 */
@@ -999,7 +1029,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;
@@ -1031,6 +1061,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);
@@ -1083,8 +1114,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);
+ }
}
}
}
@@ -1102,9 +1135,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;
}
@@ -1128,8 +1168,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);
}
@@ -1198,7 +1238,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 76190b13b61..da08766b322 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"
@@ -865,8 +866,9 @@ static void paint_2d_lift_soften(ImagePaintState *s, ImBuf *ibuf, ImBuf *ibufb,
out_off[0] = out_off[1] = 0;
if (!tile) {
- IMB_rectclip(ibuf, ibufb, &in_off[0], &in_off[1], &out_off[0],
- &out_off[1], &dim[0], &dim[1]);
+ IMB_rectclip(
+ ibuf, ibufb, &in_off[0], &in_off[1], &out_off[0],
+ &out_off[1], &dim[0], &dim[1]);
if ((dim[0] == 0) || (dim[1] == 0))
return;
@@ -1383,7 +1385,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 6b13decd41b..7badd30e6d0 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,
@@ -2642,9 +2635,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 */
@@ -2824,7 +2817,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 */
@@ -2927,19 +2920,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 {
@@ -2956,7 +2946,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;
}
}
@@ -2965,8 +2954,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);
}
}
@@ -3082,26 +3070,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];
@@ -3135,7 +3105,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 */
@@ -3162,17 +3132,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(&params);
- BKE_camera_params_from_object(&params, cam_ob);
+ BKE_camera_params_from_object(&params, cam_ob_eval);
BKE_camera_params_compute_viewplane(&params, ps->winx, ps->winy, 1.0f, 1.0f);
BKE_camera_params_compute_matrix(&params);
@@ -3219,11 +3189,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 */
@@ -3233,7 +3203,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;
@@ -3294,21 +3264,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]);
@@ -3329,10 +3299,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
@@ -3376,9 +3346,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);
@@ -3423,49 +3393,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;
}
@@ -3484,16 +3468,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);
}
}
@@ -3523,17 +3507,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;
}
@@ -3550,7 +3534,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;
}
}
@@ -3571,7 +3555,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);
@@ -3685,7 +3669,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
@@ -3698,13 +3682,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;
}
@@ -3712,7 +3696,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;
}
@@ -3723,7 +3707,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;
@@ -3754,11 +3738,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;
}
@@ -3814,7 +3798,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;
@@ -3837,7 +3821,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;
}
}
@@ -3846,28 +3830,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 */
@@ -3914,7 +3896,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;
@@ -3935,7 +3917,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);
}
}
@@ -3953,14 +3935,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);
@@ -3980,22 +3965,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) {
@@ -4882,7 +4851,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)
@@ -4948,16 +4917,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++;
@@ -5032,17 +5001,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);
@@ -5098,6 +5068,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 */
@@ -5120,7 +5091,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;
@@ -5220,7 +5190,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;
}
@@ -5244,14 +5214,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);
@@ -5322,11 +5290,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) {
@@ -5396,10 +5365,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 {
@@ -5454,8 +5424,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;
@@ -5469,9 +5442,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->shading.type,
+ 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 */
@@ -5487,9 +5461,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;
@@ -5503,7 +5474,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;
@@ -5604,7 +5575,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;
@@ -5643,20 +5614,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}
};
@@ -5692,7 +5654,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)
@@ -5701,60 +5662,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);
@@ -5841,59 +5776,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 */
@@ -5930,7 +5812,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;
@@ -5940,9 +5822,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 7ec7dd20dc5..e26a4811afc 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"
@@ -334,7 +336,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 b782a47192a..7d3049434d6 100644
--- a/source/blender/editors/sculpt_paint/paint_intern.h
+++ b/source/blender/editors/sculpt_paint/paint_intern.h
@@ -65,10 +65,11 @@ typedef void (*StrokeUpdateStep)(struct bContext *C, struct PaintStroke *stroke,
typedef void (*StrokeRedraw)(const struct bContext *C, struct PaintStroke *stroke, bool final);
typedef void (*StrokeDone)(const struct bContext *C, struct PaintStroke *stroke);
-struct PaintStroke *paint_stroke_new(struct bContext *C, struct wmOperator *op,
- StrokeGetLocation get_location, StrokeTestStart test_start,
- StrokeUpdateStep update_step, StrokeRedraw redraw,
- StrokeDone done, int event_type);
+struct PaintStroke *paint_stroke_new(
+ struct bContext *C, struct wmOperator *op,
+ StrokeGetLocation get_location, StrokeTestStart test_start,
+ StrokeUpdateStep update_step, StrokeRedraw redraw,
+ StrokeDone done, int event_type);
void paint_stroke_data_free(struct wmOperator *op);
bool paint_space_stroke_enabled(struct Brush *br, enum ePaintMode mode);
@@ -94,8 +95,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 +160,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 +219,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);
@@ -247,21 +249,22 @@ void SCULPT_OT_uv_sculpt_stroke(struct wmOperatorType *ot);
/* Convert the object-space axis-aligned bounding box (expressed as
* its minimum and maximum corners) into a screen-space rectangle,
* returns zero if the result is empty */
-bool paint_convert_bb_to_rect(struct rcti *rect,
- const float bb_min[3],
- const float bb_max[3],
- const struct ARegion *ar,
- struct RegionView3D *rv3d,
- struct Object *ob);
+bool paint_convert_bb_to_rect(
+ struct rcti *rect,
+ const float bb_min[3],
+ const float bb_max[3],
+ const struct ARegion *ar,
+ struct RegionView3D *rv3d,
+ struct Object *ob);
/* Get four planes in object-space that describe the projection of
* screen_rect from screen into object-space (essentially converting a
* 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);
+void paint_calc_redraw_planes(
+ float planes[4][4],
+ const struct ARegion *ar,
+ struct Object *ob,
+ const struct rcti *screen_rect);
float paint_calc_object_space_radius(struct ViewContext *vc, const float center[3], float pixel_radius);
float paint_get_tex_pixel(const struct MTex *mtex, float u, float v, struct ImagePool *pool, int thread);
@@ -309,8 +312,9 @@ typedef enum {
RC_COLOR_OVERRIDE = 32,
} RCFlags;
-void set_brush_rc_props(struct PointerRNA *ptr, const char *paint, const char *prop, const char *secondary_prop,
- RCFlags flags);
+void set_brush_rc_props(
+ struct PointerRNA *ptr, const char *paint, const char *prop, const char *secondary_prop,
+ RCFlags flags);
/* paint_hide.c */
diff --git a/source/blender/editors/sculpt_paint/paint_mask.c b/source/blender/editors/sculpt_paint/paint_mask.c
index e0fdcc0c7c8..a09c04f6fb0 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"
@@ -135,6 +134,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;
@@ -146,7 +146,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,11 +258,11 @@ static void mask_box_select_task_cb(
} BKE_pbvh_vertex_iter_end;
}
-int ED_sculpt_mask_box_select(struct bContext *C, ViewContext *vc, const rcti *rect, bool select, bool UNUSED(extend))
+int ED_sculpt_mask_box_select(struct bContext *C, ViewContext *vc, const rcti *rect, bool select)
{
+ 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;
@@ -280,11 +280,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);
@@ -426,9 +425,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;
@@ -446,7 +445,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;
@@ -462,10 +460,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 74984d090f8..05be3db635f 100644
--- a/source/blender/editors/sculpt_paint/paint_ops.c
+++ b/source/blender/editors/sculpt_paint/paint_ops.c
@@ -29,24 +29,33 @@
#include "BLI_string.h"
#include "BLI_utildefines.h"
#include "BLI_math_vector.h"
+#include "BLI_math_color.h"
#include "DNA_customdata_types.h"
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
#include "DNA_brush_types.h"
+#include "DNA_gpencil_types.h"
#include "BKE_brush.h"
#include "BKE_context.h"
#include "BKE_paint.h"
+#include "BKE_gpencil.h"
#include "BKE_main.h"
+#include "BKE_report.h"
+
+#include "DEG_depsgraph.h"
#include "ED_paint.h"
#include "ED_screen.h"
+#include "ED_select_utils.h"
#include "ED_image.h"
+#include "ED_gpencil.h"
#include "UI_resources.h"
#include "WM_api.h"
#include "WM_types.h"
+#include "WM_toolsystem.h"
#include "RNA_access.h"
#include "RNA_define.h"
@@ -95,6 +104,43 @@ static void BRUSH_OT_add(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
+static int brush_add_gpencil_exec(bContext *C, wmOperator *UNUSED(op))
+{
+ /*int type = RNA_enum_get(op->ptr, "type");*/
+ ToolSettings *ts = CTX_data_tool_settings(C);
+ Paint *paint = &ts->gp_paint->paint;
+ Brush *br = BKE_paint_brush(paint);
+ Main *bmain = CTX_data_main(C);
+ // ePaintMode mode = ePaintGpencil;
+
+ if (br) {
+ br = BKE_brush_copy(bmain, br);
+ }
+ else {
+ br = BKE_brush_add(bmain, "Brush", OB_MODE_GPENCIL_PAINT);
+ id_us_min(&br->id); /* fake user only */
+ }
+
+ BKE_paint_brush_set(paint, br);
+
+ /* TODO init grease pencil specific data */
+
+ return OPERATOR_FINISHED;
+}
+
+static void BRUSH_OT_add_gpencil(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Add Drawing Brush";
+ ot->description = "Add brush for grease pencil";
+ ot->idname = "BRUSH_OT_add_gpencil";
+
+ /* api callbacks */
+ ot->exec = brush_add_gpencil_exec;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+}
static int brush_scale_size_exec(bContext *C, wmOperator *op)
{
@@ -231,7 +277,6 @@ static void PALETTE_OT_color_add(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
-
static int palette_color_delete_exec(bContext *C, wmOperator *UNUSED(op))
{
Paint *paint = BKE_paint_get_active_from_context(C);
@@ -453,10 +498,21 @@ static int brush_select_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
- return brush_generic_tool_set(
+ /* 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. */
+ int ret = brush_generic_tool_set(
bmain, paint, tool, tool_offset,
paint_mode, tool_name, create_missing,
toggle);
+
+ if ((ret == OPERATOR_FINISHED) && (paint->brush != NULL)) {
+ Brush *brush = paint->brush;
+ WorkSpace *workspace = CTX_wm_workspace(C);
+ if (WM_toolsystem_ref_set_by_name(C, workspace, NULL, brush->id.name + 2, true)) {
+ /* ok */
+ }
+ }
+ return ret;
}
static void PAINT_OT_brush_select(wmOperatorType *ot)
@@ -1019,6 +1075,7 @@ void ED_operatortypes_paint(void)
/* brush */
WM_operatortype_append(BRUSH_OT_add);
+ WM_operatortype_append(BRUSH_OT_add_gpencil);
WM_operatortype_append(BRUSH_OT_scale_size);
WM_operatortype_append(BRUSH_OT_curve_preset);
WM_operatortype_append(BRUSH_OT_reset);
@@ -1039,7 +1096,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 */
@@ -1085,21 +1141,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;
@@ -1237,6 +1278,7 @@ 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);
+
WM_keymap_add_item(keymap, "PAINTCURVE_OT_delete_point", XKEY, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, "PAINTCURVE_OT_delete_point", DELKEY, KM_PRESS, 0, 0);
@@ -1307,7 +1349,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);
@@ -1346,7 +1387,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);
@@ -1378,7 +1418,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);
@@ -1399,14 +1438,16 @@ void ED_keymap_paint(wmKeyConfig *keyconf)
keymap = WM_keymap_ensure(keyconf, "Weight Paint Vertex Selection", 0, 0);
keymap->poll = vert_paint_poll;
kmi = WM_keymap_add_item(keymap, "PAINT_OT_vert_select_all", AKEY, KM_PRESS, 0, 0);
- RNA_enum_set(kmi->ptr, "action", SEL_TOGGLE);
+ RNA_enum_set(kmi->ptr, "action", SEL_SELECT);
+ kmi = WM_keymap_add_item(keymap, "PAINT_OT_vert_select_all", AKEY, KM_PRESS, KM_ALT, 0);
+ RNA_enum_set(kmi->ptr, "action", SEL_DESELECT);
kmi = WM_keymap_add_item(keymap, "PAINT_OT_vert_select_all", IKEY, KM_PRESS, KM_CTRL, 0);
RNA_enum_set(kmi->ptr, "action", SEL_INVERT);
WM_keymap_add_item(keymap, "VIEW3D_OT_select_border", BKEY, KM_PRESS, 0, 0);
kmi = WM_keymap_add_item(keymap, "VIEW3D_OT_select_lasso", EVT_TWEAK_A, KM_ANY, KM_CTRL, 0);
- RNA_boolean_set(kmi->ptr, "deselect", false);
+ RNA_enum_set(kmi->ptr, "mode", SEL_OP_ADD);
kmi = WM_keymap_add_item(keymap, "VIEW3D_OT_select_lasso", EVT_TWEAK_A, KM_ANY, KM_SHIFT | KM_CTRL, 0);
- RNA_boolean_set(kmi->ptr, "deselect", true);
+ RNA_enum_set(kmi->ptr, "mode", SEL_OP_SUB);
WM_keymap_add_item(keymap, "VIEW3D_OT_select_circle", CKEY, KM_PRESS, 0, 0);
/* Image/Texture Paint mode */
@@ -1419,7 +1460,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",
@@ -1443,7 +1483,9 @@ void ED_keymap_paint(wmKeyConfig *keyconf)
keymap->poll = facemask_paint_poll;
kmi = WM_keymap_add_item(keymap, "PAINT_OT_face_select_all", AKEY, KM_PRESS, 0, 0);
- RNA_enum_set(kmi->ptr, "action", SEL_TOGGLE);
+ RNA_enum_set(kmi->ptr, "action", SEL_SELECT);
+ kmi = WM_keymap_add_item(keymap, "PAINT_OT_face_select_all", AKEY, KM_PRESS, KM_ALT, 0);
+ RNA_enum_set(kmi->ptr, "action", SEL_DESELECT);
kmi = WM_keymap_add_item(keymap, "PAINT_OT_face_select_all", IKEY, KM_PRESS, KM_CTRL, 0);
RNA_enum_set(kmi->ptr, "action", SEL_INVERT);
kmi = WM_keymap_add_item(keymap, "PAINT_OT_face_select_hide", HKEY, KM_PRESS, 0, 0);
diff --git a/source/blender/editors/sculpt_paint/paint_stroke.c b/source/blender/editors/sculpt_paint/paint_stroke.c
index de804677de9..b5d68786664 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;
+
+ uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+ immUniformColor4ubv(paint->paint_cursor_col);
+
+ immBegin(GPU_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 = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_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_get_f(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(GPU_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();
+
+ immUnbindProgram();
- glDisable(GL_BLEND);
- glDisable(GL_LINE_SMOOTH);
+ GPU_line_smooth(false);
}
static bool paint_tool_require_location(Brush *brush, ePaintMode mode)
@@ -383,19 +411,24 @@ static bool paint_brush_update(
}
}
+ 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());
+ ups->brush_rotation += -brush->mtex.random_angle / 2.0f +
+ 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());
+ ups->brush_rotation_sec += -brush->mask_mtex.random_angle / 2.0f +
+ brush->mask_mtex.random_angle * BLI_rng_get_float(stroke->rng);
}
}
@@ -788,6 +821,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);
@@ -1353,7 +1390,15 @@ bool paint_poll(bContext *C)
ScrArea *sa = CTX_wm_area(C);
ARegion *ar = CTX_wm_region(C);
- return p && ob && BKE_paint_brush(p) &&
- (sa && ELEM(sa->spacetype, SPACE_VIEW3D, SPACE_IMAGE)) &&
- (ar && ar->regiontype == RGN_TYPE_WINDOW);
+ if (p && ob && BKE_paint_brush(p) &&
+ (sa && ELEM(sa->spacetype, SPACE_VIEW3D, SPACE_IMAGE)) &&
+ (ar && ar->regiontype == RGN_TYPE_WINDOW))
+ {
+ /* Check the current tool is a brush. */
+ bToolRef *tref = sa->runtime.tool;
+ if (tref && tref->runtime && tref->runtime->data_block[0]) {
+ return true;
+ }
+ }
+ return false;
}
diff --git a/source/blender/editors/sculpt_paint/paint_utils.c b/source/blender/editors/sculpt_paint/paint_utils.c
index 71b63ccbdff..e914a24092e 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"
@@ -132,17 +137,12 @@ bool paint_convert_bb_to_rect(
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;
@@ -150,7 +150,7 @@ void paint_calc_redraw_planes(
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);
}
@@ -283,26 +283,26 @@ static void imapaint_tri_weights(
}
/* 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_get_i(view);
+ GPU_matrix_model_view_get(matrix);
+ GPU_matrix_projection_get(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;
@@ -319,25 +319,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]];
@@ -356,12 +356,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;
@@ -433,6 +433,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;
@@ -456,21 +457,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);
@@ -479,7 +482,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;
@@ -488,7 +491,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);
@@ -502,10 +505,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);
@@ -517,10 +517,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);
}
@@ -536,7 +533,6 @@ void paint_sample_color(bContext *C, ARegion *ar, int x, int y, bool texpaint_pr
}
}
}
- dm->release(dm);
}
if (!sample_success) {
@@ -570,8 +566,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 e1d8cfc3221..c50df664a6a 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;
@@ -1511,7 +1562,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);
@@ -1956,7 +2007,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. */
@@ -2184,7 +2236,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_tag(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);
@@ -2248,7 +2302,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);
@@ -2331,6 +2385,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;
@@ -2349,15 +2404,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_tag(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;
}
@@ -2440,6 +2502,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);
@@ -2487,12 +2550,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);
@@ -2952,8 +3015,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);
@@ -3090,6 +3153,8 @@ static void vpaint_stroke_update_step(bContext *C, struct PaintStroke *stroke, P
swap_m4m4(vc->rv3d->persmat, mat);
+ BKE_mesh_batch_cache_dirty_tag(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);
}
@@ -3103,11 +3168,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 1a37973cd7d..436f4ac5993 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;
@@ -367,7 +370,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;
}
@@ -483,7 +486,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;
}
@@ -532,21 +535,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;
@@ -556,7 +559,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;
@@ -564,12 +567,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) {
@@ -617,10 +620,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);
}
@@ -631,7 +634,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)) {
@@ -640,10 +643,11 @@ 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];
- 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)
+ 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)
{
/* ok */
MDeformVert *dv = &me->dvert[index];
@@ -673,7 +677,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) {
@@ -695,7 +699,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) {
@@ -709,7 +713,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);
@@ -721,20 +725,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) {
@@ -751,8 +756,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__);
}
@@ -781,19 +786,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) {
@@ -845,7 +851,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..45037cfddfa 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"
@@ -68,13 +67,18 @@
#include "BKE_multires.h"
#include "BKE_paint.h"
#include "BKE_report.h"
+#include "BKE_screen.h"
#include "BKE_node.h"
#include "BKE_object.h"
#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 +90,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 +501,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 +509,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 +2101,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,
@@ -3519,13 +3523,16 @@ static void sculpt_topology_update(Sculpt *sd, Object *ob, Brush *brush, Unified
PBVHTopologyUpdateMode mode = 0;
float location[3];
- if (sd->flags & SCULPT_DYNTOPO_SUBDIVIDE)
- mode |= PBVH_Subdivide;
+ if (!(sd->flags & SCULPT_DYNTOPO_DETAIL_MANUAL)) {
+ if (sd->flags & SCULPT_DYNTOPO_SUBDIVIDE) {
+ mode |= PBVH_Subdivide;
+ }
- if ((sd->flags & SCULPT_DYNTOPO_COLLAPSE) ||
- (brush->sculpt_tool == SCULPT_TOOL_SIMPLIFY))
- {
- mode |= PBVH_Collapse;
+ if ((sd->flags & SCULPT_DYNTOPO_COLLAPSE) ||
+ (brush->sculpt_tool == SCULPT_TOOL_SIMPLIFY))
+ {
+ mode |= PBVH_Collapse;
+ }
}
for (n = 0; n < totnode; n++) {
@@ -4600,10 +4607,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 +4696,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 +4814,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 +4832,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 +4870,11 @@ 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);
+
+ DEG_id_tag_update(&ob->id, DEG_TAG_SHADING_UPDATE);
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 +4904,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_tag(ob->data, BKE_MESH_BATCH_DIRTY_SCULPT_COORDS);
}
/* Returns whether the mouse/stylus is over the mesh (1)
@@ -4946,7 +4958,7 @@ static void sculpt_stroke_update_step(bContext *C, struct PaintStroke *UNUSED(st
sculpt_update_cache_variants(C, sd, ob, itemptr);
sculpt_restore_mesh(sd, ob);
- if (sd->flags & SCULPT_DYNTOPO_DETAIL_CONSTANT) {
+ if (sd->flags & (SCULPT_DYNTOPO_DETAIL_CONSTANT | SCULPT_DYNTOPO_DETAIL_MANUAL)) {
BKE_pbvh_bmesh_detail_size_set(ss->pbvh, 1.0f / sd->constant_detail);
}
else if (sd->flags & SCULPT_DYNTOPO_DETAIL_BRUSH) {
@@ -4978,7 +4990,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 +5065,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 +5212,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 +5254,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 +5303,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 +5311,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 +5362,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 +5400,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 +5408,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 +5622,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 +5643,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 +5653,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 +5728,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 +5739,8 @@ void ED_object_sculptmode_enter_ex(
}
}
- /* VBO no longer valid */
- if (ob->derivedFinal) {
- GPU_drawobject_free(ob->derivedFinal);
- }
+ /* 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 +5748,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 +5773,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;
@@ -5772,22 +5793,26 @@ void ED_object_sculptmode_exit_ex(
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 +5825,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;
}
@@ -5825,13 +5854,13 @@ static void SCULPT_OT_sculptmode_toggle(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
-
-static bool sculpt_and_dynamic_topology_constant_detail_poll(bContext *C)
+static bool sculpt_and_constant_or_manual_detail_poll(bContext *C)
{
Object *ob = CTX_data_active_object(C);
Sculpt *sd = CTX_data_tool_settings(C)->sculpt;
- return sculpt_mode_poll(C) && ob->sculpt->bm && (sd->flags & SCULPT_DYNTOPO_DETAIL_CONSTANT);
+ return sculpt_mode_poll(C) && ob->sculpt->bm &&
+ (sd->flags & (SCULPT_DYNTOPO_DETAIL_CONSTANT | SCULPT_DYNTOPO_DETAIL_MANUAL));
}
static int sculpt_detail_flood_fill_exec(bContext *C, wmOperator *UNUSED(op))
@@ -5893,30 +5922,42 @@ static void SCULPT_OT_detail_flood_fill(wmOperatorType *ot)
/* api callbacks */
ot->exec = sculpt_detail_flood_fill_exec;
- ot->poll = sculpt_and_dynamic_topology_constant_detail_poll;
+ ot->poll = sculpt_and_constant_or_manual_detail_poll;
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
-static void sample_detail(bContext *C, int ss_co[2])
+static void sample_detail(bContext *C, int mx, int my)
{
+ /* Find 3D view to pick from. */
+ bScreen *screen = CTX_wm_screen(C);
+ ScrArea *sa = BKE_screen_find_area_xy(screen, SPACE_VIEW3D, mx, my);
+ ARegion *ar = (sa) ? BKE_area_find_region_xy(sa, RGN_TYPE_WINDOW, mx, my) : NULL;
+ if (ar == NULL) {
+ return;
+ }
+
+ /* Set context to 3D view. */
+ ScrArea *prev_sa = CTX_wm_area(C);
+ ARegion *prev_ar = CTX_wm_region(C);
+ CTX_wm_area_set(C, sa);
+ CTX_wm_region_set(C, ar);
+
ViewContext vc;
- Object *ob;
- Sculpt *sd;
- float ray_start[3], ray_end[3], ray_normal[3], depth;
- SculptDetailRaycastData srd;
- float mouse[2] = {ss_co[0], ss_co[1]};
ED_view3d_viewcontext_init(C, &vc);
- sd = CTX_data_tool_settings(C)->sculpt;
- ob = vc.obact;
-
+ /* Pick sample detail. */
+ Sculpt *sd = CTX_data_tool_settings(C)->sculpt;
+ Object *ob = vc.obact;
Brush *brush = BKE_paint_brush(&sd->paint);
sculpt_stroke_modifiers_check(C, ob, brush);
- depth = sculpt_raycast_init(&vc, mouse, ray_start, ray_end, ray_normal, false);
+ float mouse[2] = {mx - ar->winrct.xmin, my - ar->winrct.ymin};
+ float ray_start[3], ray_end[3], ray_normal[3];
+ float depth = sculpt_raycast_init(&vc, mouse, ray_start, ray_end, ray_normal, false);
+ SculptDetailRaycastData srd;
srd.hit = 0;
srd.ray_start = ray_start;
srd.ray_normal = ray_normal;
@@ -5930,39 +5971,41 @@ static void sample_detail(bContext *C, int ss_co[2])
/* convert edge length to detail resolution */
sd->constant_detail = 1.0f / srd.detail;
}
+
+ /* Restore context. */
+ CTX_wm_area_set(C, prev_sa);
+ CTX_wm_region_set(C, prev_ar);
}
static int sculpt_sample_detail_size_exec(bContext *C, wmOperator *op)
{
int ss_co[2];
RNA_int_get_array(op->ptr, "location", ss_co);
- sample_detail(C, ss_co);
+ sample_detail(C, ss_co[0], ss_co[1]);
return OPERATOR_FINISHED;
}
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;
}
-static int sculpt_sample_detail_size_modal(bContext *C, wmOperator *op, const wmEvent *e)
+static int sculpt_sample_detail_size_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
- switch (e->type) {
+ switch (event->type) {
case LEFTMOUSE:
- if (e->val == KM_PRESS) {
- ScrArea *sa = CTX_wm_area(C);
- int ss_co[2] = {e->mval[0], e->mval[1]};
+ if (event->val == KM_PRESS) {
+ int ss_co[2] = {event->x, event->y};
- sample_detail(C, ss_co);
+ sample_detail(C, ss_co[0], ss_co[1]);
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 +6014,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;
}
@@ -5994,7 +6036,7 @@ static void SCULPT_OT_sample_detail_size(wmOperatorType *ot)
ot->invoke = sculpt_sample_detail_size_invoke;
ot->exec = sculpt_sample_detail_size_exec;
ot->modal = sculpt_sample_detail_size_modal;
- ot->poll = sculpt_and_dynamic_topology_constant_detail_poll;
+ ot->poll = sculpt_and_constant_or_manual_detail_poll;
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
@@ -6012,7 +6054,7 @@ static int sculpt_set_detail_size_exec(bContext *C, wmOperator *UNUSED(op))
WM_operator_properties_create_ptr(&props_ptr, ot);
- if (sd->flags & SCULPT_DYNTOPO_DETAIL_CONSTANT) {
+ if (sd->flags & (SCULPT_DYNTOPO_DETAIL_CONSTANT | SCULPT_DYNTOPO_DETAIL_MANUAL)) {
set_brush_rc_props(&props_ptr, "sculpt", "constant_detail_resolution", NULL, 0);
RNA_string_set(&props_ptr, "data_path_primary", "tool_settings.sculpt.constant_detail_resolution");
}
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..b78d030407b 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_SHADING_UPDATE);
+
+ 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);
}
}
@@ -929,9 +931,10 @@ SculptUndoNode *sculpt_undo_push_node(
unode = sculpt_undo_alloc_node(ob, node, type);
- BLI_thread_unlock(LOCK_CUSTOM1);
-
- /* copy threaded, hopefully this is the performance critical part */
+ /* NOTE: If this ever becomes a bottleneck, make a lock inside of the node.
+ * so we release global lock sooner, but keep data locked for until it is
+ * fully initialized.
+ */
if (unode->grids) {
int totgrid, *grids;
@@ -968,6 +971,8 @@ SculptUndoNode *sculpt_undo_push_node(
if (ss->kb) BLI_strncpy(unode->shapeName, ss->kb->name, sizeof(ss->kb->name));
else unode->shapeName[0] = '\0';
+ BLI_thread_unlock(LOCK_CUSTOM1);
+
return unode;
}
diff --git a/source/blender/editors/sculpt_paint/sculpt_uv.c b/source/blender/editors/sculpt_paint/sculpt_uv.c
index 7e30c8b5b23..8fafc545fa9 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);
+ uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_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;
}