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:
authorPhilipp Oeser <info@graphics-engineer.com>2019-09-18 13:28:12 +0300
committerPhilipp Oeser <info@graphics-engineer.com>2019-09-20 12:56:53 +0300
commit078fcc62534c21fd02b6549d51669763649a20f9 (patch)
treeca1e889a166ab5b14e5714c10e0aa77d14df74a1 /source/blender/editors/sculpt_paint/paint_cursor.c
parentfde8682d96d44f7600d69aae23dac36f584afd9e (diff)
Fix paint cursor drawing asserts
The new paint cursor (introduced in rBe0c792135adf) mixed 3d and 2d drawing leading to asserts [e.g. when tablet pressure sensitivity was enabled for size, see D5820 also]. We could get away with always drawing in 3D [using vertformat with comp_len 3 / GPU_SHADER_3D_UNIFORM_COLOR / imm_draw_circle_wire_3d], even if in the Image Editor, but this patch clearly separates what is drawn in 3d and what is in 2d. part of T69957 Reviewers: jbakker Differential Revision: https://developer.blender.org/D5836
Diffstat (limited to 'source/blender/editors/sculpt_paint/paint_cursor.c')
-rw-r--r--source/blender/editors/sculpt_paint/paint_cursor.c374
1 files changed, 201 insertions, 173 deletions
diff --git a/source/blender/editors/sculpt_paint/paint_cursor.c b/source/blender/editors/sculpt_paint/paint_cursor.c
index ff2800cb68c..523469912e1 100644
--- a/source/blender/editors/sculpt_paint/paint_cursor.c
+++ b/source/blender/editors/sculpt_paint/paint_cursor.c
@@ -1214,6 +1214,14 @@ static void sculpt_geometry_preview_lines_draw(const uint gpuattr, SculptSession
}
}
+static bool paint_use_2d_cursor(ePaintMode mode)
+{
+ if (mode >= PAINT_MODE_TEXTURE_3D) {
+ return true;
+ }
+ return false;
+}
+
static void paint_draw_cursor(bContext *C, int x, int y, void *UNUSED(unused))
{
Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C);
@@ -1224,6 +1232,9 @@ static void paint_draw_cursor(bContext *C, int x, int y, void *UNUSED(unused))
Brush *brush = BKE_paint_brush(paint);
ePaintMode mode = BKE_paintmode_get_active_from_context(C);
+ /* 2d or 3d painting? */
+ const bool use_2d_cursor = paint_use_2d_cursor(mode);
+
/* check that brush drawing is enabled */
if (ommit_cursor_drawing(paint, mode, brush)) {
return;
@@ -1261,37 +1272,6 @@ static void paint_draw_cursor(bContext *C, int x, int y, void *UNUSED(unused))
paint_calculate_rake_rotation(ups, brush, translation);
}
- /* draw overlay */
- bool alpha_overlay_active = paint_draw_alpha_overlay(ups, brush, &vc, x, y, zoomx, mode);
-
- /* TODO: as sculpt and other paint modes are unified, this
- * special mode of drawing will go away */
- Object *obact = vc.obact;
- if ((mode == PAINT_MODE_SCULPT) && obact && obact->sculpt) {
- float location[3];
- int pixel_radius;
-
- /* test if brush is over the mesh */
- 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);
- }
-
- /* check if brush is subtracting, use different color then */
- /* TODO: no way currently to know state of pen flip or
- * invert key modifier without starting a stroke */
- if (((ups->draw_inverted == 0) ^ ((brush->flag & BRUSH_DIR_IN) == 0)) &&
- BKE_brush_sculpt_has_secondary_color(brush)) {
- outline_col = brush->sub_col;
- }
-
- /* only do if brush is over the mesh */
- if (hit) {
- paint_cursor_on_hit(ups, brush, &vc, location);
- }
- }
-
if (ups->draw_anchored) {
final_radius = ups->anchored_size;
copy_v2_fl2(translation,
@@ -1304,176 +1284,224 @@ static void paint_draw_cursor(bContext *C, int x, int y, void *UNUSED(unused))
GPU_blend(true); /* TODO: also set blend mode? */
GPU_line_smooth(true);
- uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
- immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
+ if (use_2d_cursor) {
+ uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
- /* set brush color */
- immUniformColor3fvAlpha(outline_col, outline_alpha);
+ immUniformColor3fvAlpha(outline_col, outline_alpha);
- /* draw brush outline */
- if (ups->stroke_active && BKE_brush_use_size_pressure(scene, brush)) {
- /* inner at full alpha */
- imm_draw_circle_wire_2d(
- pos, translation[0], translation[1], final_radius * ups->size_pressure_value, 40);
+ /* draw brush outline */
+ if (ups->stroke_active && BKE_brush_use_size_pressure(scene, brush)) {
+ imm_draw_circle_wire_2d(
+ pos, translation[0], translation[1], final_radius * ups->size_pressure_value, 40);
+ }
/* outer at half alpha */
immUniformColor3fvAlpha(outline_col, outline_alpha * 0.5f);
+
+ GPU_line_width(1.0f);
+ imm_draw_circle_wire_2d(pos, translation[0], translation[1], final_radius, 40);
}
+ else { /* 3d painting */
+ uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
+
+ /* draw overlay */
+ bool alpha_overlay_active = paint_draw_alpha_overlay(ups, brush, &vc, x, y, zoomx, mode);
+
+ /* TODO: as sculpt and other paint modes are unified, this
+ * special mode of drawing will go away */
+ Object *obact = vc.obact;
+ SculptSession *ss = obact ? obact->sculpt : NULL;
+ if ((mode == PAINT_MODE_SCULPT) && ss) {
+ float location[3];
+ int pixel_radius;
+
+ /* test if brush is over the mesh */
+ 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);
+ }
- /* Only sculpt mode cursor for now */
+ /* check if brush is subtracting, use different color then */
+ /* TODO: no way currently to know state of pen flip or
+ * invert key modifier without starting a stroke */
+ if (((ups->draw_inverted == 0) ^ ((brush->flag & BRUSH_DIR_IN) == 0)) &&
+ BKE_brush_sculpt_has_secondary_color(brush)) {
+ outline_col = brush->sub_col;
+ }
- /* Disable for PBVH_GRIDS */
- SculptSession *ss = obact ? obact->sculpt : NULL;
- bool is_multires = ss && ss->pbvh && BKE_pbvh_type(ss->pbvh) == PBVH_GRIDS;
+ /* only do if brush is over the mesh */
+ if (hit) {
+ paint_cursor_on_hit(ups, brush, &vc, location);
+ }
+ }
- if ((mode == PAINT_MODE_SCULPT) && ss && !is_multires &&
- !(brush->falloff_shape & BRUSH_AIRBRUSH)) {
- Sculpt *sd = CTX_data_tool_settings(C)->sculpt;
- wmWindow *win = CTX_wm_window(C);
+ immUniformColor3fvAlpha(outline_col, outline_alpha);
- /* Update WM mouse cursor, disable when the 3D brush cursor is enabled */
- if (sd->paint.brush->overlay_flags & BRUSH_OVERLAY_CURSOR) {
- WM_cursor_set(win, CURSOR_STD);
- }
- else {
- WM_cursor_set(win, CURSOR_EDIT);
+ if (ups->stroke_active && BKE_brush_use_size_pressure(scene, brush)) {
+ imm_draw_circle_wire_3d(
+ pos, translation[0], translation[1], final_radius * ups->size_pressure_value, 40);
+ /* outer at half alpha */
+ immUniformColor3fvAlpha(outline_col, outline_alpha * 0.5f);
}
- if (!ups->stroke_active) {
- SculptCursorGeometryInfo gi;
- float mouse[2] = {x - ar->winrct.xmin, y - ar->winrct.ymin};
- int prev_active_vertex_index = ss->active_vertex_index;
- bool update_previews = false;
- if (sculpt_cursor_geometry_info_update(C, &gi, mouse, true) && !alpha_overlay_active) {
-
- if (prev_active_vertex_index != ss->active_vertex_index) {
- update_previews = true;
- }
+ /* Only sculpt mode cursor for now */
+ /* Disable for PBVH_GRIDS */
+ bool is_multires = ss && ss->pbvh && BKE_pbvh_type(ss->pbvh) == PBVH_GRIDS;
+ if ((mode == PAINT_MODE_SCULPT) && ss && !is_multires &&
+ !(brush->falloff_shape & BRUSH_AIRBRUSH)) {
+ Sculpt *sd = CTX_data_tool_settings(C)->sculpt;
+ wmWindow *win = CTX_wm_window(C);
+
+ /* Update WM mouse cursor, disable when the 3D brush cursor is enabled */
+ if (sd->paint.brush->overlay_flags & BRUSH_OVERLAY_CURSOR) {
+ WM_cursor_set(win, CURSOR_STD);
+ }
+ else {
+ WM_cursor_set(win, CURSOR_EDIT);
+ }
- float rds;
- if (!BKE_brush_use_locked_size(scene, brush)) {
- rds = paint_calc_object_space_radius(&vc, gi.location, BKE_brush_size_get(scene, brush));
- }
- else {
- rds = BKE_brush_unprojected_radius_get(scene, brush);
- }
+ if (!ups->stroke_active) {
+ SculptCursorGeometryInfo gi;
+ float mouse[2] = {x - ar->winrct.xmin, y - ar->winrct.ymin};
+ int prev_active_vertex_index = ss->active_vertex_index;
+ bool update_previews = false;
+ if (sculpt_cursor_geometry_info_update(C, &gi, mouse, true) && !alpha_overlay_active) {
- wmViewport(&ar->winrct);
+ if (prev_active_vertex_index != ss->active_vertex_index) {
+ update_previews = true;
+ }
- /* Draw 3D active vertex preview with symmetry*/
- if (len_v3v3(gi.active_vertex_co, gi.location) < rds) {
- cursor_draw_point_with_symmetry(pos, ar, gi.active_vertex_co, sd, vc.obact, rds);
- }
+ float rds;
+ if (!BKE_brush_use_locked_size(scene, brush)) {
+ rds = paint_calc_object_space_radius(
+ &vc, gi.location, BKE_brush_size_get(scene, brush));
+ }
+ else {
+ rds = BKE_brush_unprojected_radius_get(scene, brush);
+ }
- /* Draw pose brush origin */
- if (brush->sculpt_tool == SCULPT_TOOL_POSE && !is_multires) {
- immUniformColor4f(1.0f, 1.0f, 1.0f, 0.8f);
- if (update_previews) {
- BKE_sculpt_update_object_for_edit(depsgraph, vc.obact, true, false);
- sculpt_pose_calc_pose_data(sd, vc.obact, ss, gi.location, rds, ss->pose_origin, NULL);
+ wmViewport(&ar->winrct);
+
+ /* Draw 3D active vertex preview with symmetry*/
+ if (len_v3v3(gi.active_vertex_co, gi.location) < rds) {
+ cursor_draw_point_with_symmetry(pos, ar, gi.active_vertex_co, sd, vc.obact, rds);
}
- cursor_draw_point_screen_space(pos, ar, ss->pose_origin, vc.obact->obmat, 5);
- }
- /* Draw 3D brush cursor */
- GPU_matrix_push_projection();
- ED_view3d_draw_setup_view(CTX_wm_window(C),
- CTX_data_depsgraph_pointer(C),
- CTX_data_scene(C),
- ar,
- CTX_wm_view3d(C),
- NULL,
- NULL,
- NULL);
-
- float cursor_trans[4][4], cursor_rot[4][4];
- float z_axis[4] = {0.0f, 0.0f, 1.0f, 0.0f};
- float quat[4];
-
- copy_m4_m4(cursor_trans, vc.obact->obmat);
- translate_m4(cursor_trans, gi.location[0], gi.location[1], gi.location[2]);
- rotation_between_vecs_to_quat(quat, z_axis, gi.normal);
- quat_to_mat4(cursor_rot, quat);
-
- GPU_matrix_push();
- GPU_matrix_mul(cursor_trans);
- GPU_matrix_mul(cursor_rot);
- immUniformColor3fvAlpha(outline_col, outline_alpha);
- imm_draw_circle_wire_3d(pos, 0, 0, rds, 40);
- GPU_matrix_pop();
-
- /* Update and draw dynamic mesh preview lines */
- GPU_matrix_push();
- GPU_matrix_mul(vc.obact->obmat);
- if (brush->sculpt_tool == SCULPT_TOOL_GRAB && brush->flag & BRUSH_GRAB_ACTIVE_VERTEX) {
- if (BKE_pbvh_type(ss->pbvh) == PBVH_FACES && ss->modifiers_active) {
- sculpt_geometry_preview_lines_update(C, ss, rds);
- sculpt_geometry_preview_lines_draw(pos, ss);
+ /* Draw pose brush origin */
+ if (brush->sculpt_tool == SCULPT_TOOL_POSE && !is_multires) {
+ immUniformColor4f(1.0f, 1.0f, 1.0f, 0.8f);
+ if (update_previews) {
+ BKE_sculpt_update_object_for_edit(depsgraph, vc.obact, true, false);
+ sculpt_pose_calc_pose_data(
+ sd, vc.obact, ss, gi.location, rds, ss->pose_origin, NULL);
+ }
+ cursor_draw_point_screen_space(pos, ar, ss->pose_origin, vc.obact->obmat, 5);
}
- }
- /* Draw pose brush line preview */
- if (brush->sculpt_tool == SCULPT_TOOL_POSE && !is_multires) {
- immUniformColor4f(1.0f, 1.0f, 1.0f, 0.8f);
- GPU_line_width(2.0f);
- immBegin(GPU_PRIM_LINES, 2);
- immVertex3fv(pos, ss->pose_origin);
- immVertex3fv(pos, gi.location);
- immEnd();
- }
+ /* Draw 3D brush cursor */
+ GPU_matrix_push_projection();
+ ED_view3d_draw_setup_view(CTX_wm_window(C),
+ CTX_data_depsgraph_pointer(C),
+ CTX_data_scene(C),
+ ar,
+ CTX_wm_view3d(C),
+ NULL,
+ NULL,
+ NULL);
+
+ float cursor_trans[4][4], cursor_rot[4][4];
+ float z_axis[4] = {0.0f, 0.0f, 1.0f, 0.0f};
+ float quat[4];
+
+ copy_m4_m4(cursor_trans, vc.obact->obmat);
+ translate_m4(cursor_trans, gi.location[0], gi.location[1], gi.location[2]);
+ rotation_between_vecs_to_quat(quat, z_axis, gi.normal);
+ quat_to_mat4(cursor_rot, quat);
+
+ GPU_matrix_push();
+ GPU_matrix_mul(cursor_trans);
+ GPU_matrix_mul(cursor_rot);
+ immUniformColor3fvAlpha(outline_col, outline_alpha);
+ imm_draw_circle_wire_3d(pos, 0, 0, rds, 40);
+ GPU_matrix_pop();
+
+ /* Update and draw dynamic mesh preview lines */
+ GPU_matrix_push();
+ GPU_matrix_mul(vc.obact->obmat);
+ if (brush->sculpt_tool == SCULPT_TOOL_GRAB && brush->flag & BRUSH_GRAB_ACTIVE_VERTEX) {
+ if (BKE_pbvh_type(ss->pbvh) == PBVH_FACES && ss->modifiers_active) {
+ sculpt_geometry_preview_lines_update(C, ss, rds);
+ sculpt_geometry_preview_lines_draw(pos, ss);
+ }
+ }
+
+ /* Draw pose brush line preview */
+ if (brush->sculpt_tool == SCULPT_TOOL_POSE && !is_multires) {
+ immUniformColor4f(1.0f, 1.0f, 1.0f, 0.8f);
+ GPU_line_width(2.0f);
+ immBegin(GPU_PRIM_LINES, 2);
+ immVertex3fv(pos, ss->pose_origin);
+ immVertex3fv(pos, gi.location);
+ immEnd();
+ }
- GPU_matrix_pop();
+ GPU_matrix_pop();
- GPU_matrix_pop_projection();
+ GPU_matrix_pop_projection();
- wmWindowViewport(win);
+ wmWindowViewport(win);
+ }
+ else {
+ /* Draw default cursor when the mouse is not over the mesh or there are no supported
+ * overlays active */
+ GPU_line_width(1.0f);
+ imm_draw_circle_wire_3d(pos, translation[0], translation[1], final_radius, 40);
+ }
}
else {
- /* Draw default cursor when the mouse is not over the mesh or there are no supported
- * overlays active */
- GPU_line_width(1.0f);
- imm_draw_circle_wire_3d(pos, translation[0], translation[1], final_radius, 40);
- }
- }
- else {
- if (vc.obact->sculpt->cache && !vc.obact->sculpt->cache->first_time) {
- /* Draw cursor location preview when the stroke is active using the data from StrokeCache
- */
- float cursor_location[3];
- wmViewport(&ar->winrct);
- copy_v3_v3(cursor_location, ss->cache->true_location);
- if (ss->cache->brush->sculpt_tool == SCULPT_TOOL_GRAB) {
- add_v3_v3(cursor_location, ss->cache->grab_delta);
- }
- cursor_draw_point_with_symmetry(pos, ar, cursor_location, sd, vc.obact, ss->cache->radius);
-
- /* Draw cached dynamic mesh preview lines */
- if (brush->sculpt_tool == SCULPT_TOOL_GRAB && brush->flag & BRUSH_GRAB_ACTIVE_VERTEX) {
- if (BKE_pbvh_type(ss->pbvh) == PBVH_FACES && ss->modifiers_active) {
- GPU_matrix_push_projection();
- ED_view3d_draw_setup_view(CTX_wm_window(C),
- CTX_data_depsgraph_pointer(C),
- CTX_data_scene(C),
- ar,
- CTX_wm_view3d(C),
- NULL,
- NULL,
- NULL);
- GPU_matrix_push();
- GPU_matrix_mul(vc.obact->obmat);
- sculpt_geometry_preview_lines_draw(pos, ss);
- GPU_matrix_pop();
- GPU_matrix_pop_projection();
+ if (vc.obact->sculpt->cache && !vc.obact->sculpt->cache->first_time) {
+ /* Draw cursor location preview when the stroke is active using the data from StrokeCache
+ */
+ float cursor_location[3];
+ wmViewport(&ar->winrct);
+ copy_v3_v3(cursor_location, ss->cache->true_location);
+ if (ss->cache->brush->sculpt_tool == SCULPT_TOOL_GRAB) {
+ add_v3_v3(cursor_location, ss->cache->grab_delta);
+ }
+ cursor_draw_point_with_symmetry(
+ pos, ar, cursor_location, sd, vc.obact, ss->cache->radius);
+
+ /* Draw cached dynamic mesh preview lines */
+ if (brush->sculpt_tool == SCULPT_TOOL_GRAB && brush->flag & BRUSH_GRAB_ACTIVE_VERTEX) {
+ if (BKE_pbvh_type(ss->pbvh) == PBVH_FACES && ss->modifiers_active) {
+ GPU_matrix_push_projection();
+ ED_view3d_draw_setup_view(CTX_wm_window(C),
+ CTX_data_depsgraph_pointer(C),
+ CTX_data_scene(C),
+ ar,
+ CTX_wm_view3d(C),
+ NULL,
+ NULL,
+ NULL);
+ GPU_matrix_push();
+ GPU_matrix_mul(vc.obact->obmat);
+ sculpt_geometry_preview_lines_draw(pos, ss);
+ GPU_matrix_pop();
+ GPU_matrix_pop_projection();
+ }
}
- }
- wmWindowViewport(win);
+ wmWindowViewport(win);
+ }
}
}
- }
- else {
- /* Draw default cursor in unsupported modes */
- GPU_line_width(1.0f);
- imm_draw_circle_wire_3d(pos, translation[0], translation[1], final_radius, 40);
+ else {
+ /* Draw default cursor in unsupported modes */
+ GPU_line_width(1.0f);
+ imm_draw_circle_wire_3d(pos, translation[0], translation[1], final_radius, 40);
+ }
}
immUnbindProgram();