Commit: dc1a17501d6be4a74a9ac49b5c25960861ccfe94 Author: Pablo Dobarro Date: Sat Mar 16 02:09:04 2019 +0100 Branches: sculpt-mode-features https://developer.blender.org/rBdc1a17501d6be4a74a9ac49b5c25960861ccfe94
Brush cursor: Radial symmetry and tiling preview support =================================================================== M source/blender/editors/sculpt_paint/paint_cursor.c =================================================================== diff --git a/source/blender/editors/sculpt_paint/paint_cursor.c b/source/blender/editors/sculpt_paint/paint_cursor.c index c9880ae3af1..b4633a0a3fd 100644 --- a/source/blender/editors/sculpt_paint/paint_cursor.c +++ b/source/blender/editors/sculpt_paint/paint_cursor.c @@ -45,6 +45,7 @@ #include "BKE_node.h" #include "BKE_paint.h" #include "BKE_colortools.h" +#include "BKE_object.h" #include "WM_api.h" #include "wm_cursors.h" @@ -1044,37 +1045,93 @@ static bool ommit_cursor_drawing(Paint *paint, ePaintMode mode, Brush *brush) return true; } -void cursor_draw_point_with_symmetry(const uint gpuatrr, const ARegion *ar,const float pos[3], const char symm, const float obmat[4][4], const float persmat[4][4]){ +void cursor_draw_point_screen_space(const uint gpuattr, const ARegion *ar, float location[3], + float obmat[4][4], float persmat[4][4]) +{ float ar_width = ar->winrct.xmax - ar->winrct.xmin; float ar_height = ar->winrct.ymax - ar->winrct.ymin; - int i = 0; - for (i = 0; i <= symm; ++i) { - if (i == 0 || (symm & i && (symm != 5 || i != 3) && (symm != 6 || (i != 3 && i != 5)))) { - float vertex_pos[3] = { - pos[0], - pos[1], - pos[2], - }; - flip_v3_v3(vertex_pos, vertex_pos, (char)i); - - float translation_vertex_cursor[2]; - mul_m4_v3(obmat, vertex_pos); - float pv4[4] = { - vertex_pos[0], - vertex_pos[1], - vertex_pos[2], - 1.0f, - }; - mul_m4_v4(persmat, pv4); - - if (pv4[3] > 0.0f) { - float width_half = ar_width * 0.5f; - float height_half = ar_height * 0.5f; - translation_vertex_cursor[0] = width_half + width_half * (pv4[0] / pv4[3]); - translation_vertex_cursor[1] = height_half + height_half * (pv4[1] / pv4[3]); + float pv4[4], translation_vertex_cursor[2]; + mul_m4_v3(obmat, location); + copy_v3_v3(pv4, location); + pv4[3] = 1.0f; + mul_m4_v4(persmat, pv4); + if (pv4[3] > 0.0f) { + float width_half = ar_width * 0.5f; + float height_half = ar_height * 0.5f; + translation_vertex_cursor[0] = width_half + width_half * (pv4[0] / pv4[3]); + translation_vertex_cursor[1] = height_half + height_half * (pv4[1] / pv4[3]); + } + imm_draw_circle_fill_3d(gpuattr, translation_vertex_cursor[0], translation_vertex_cursor[1], 3, 10); +} + +void cursor_draw_tiling_preview(const uint gpuattr, const ARegion *ar, float true_location[3], + Sculpt *sd, Object *ob, float persmat[4][4], float radius) +{ + BoundBox *bb = BKE_object_boundbox_get(ob); + float orgLoc[3], location[3], pv4[4], translation_vertex_cursor[2]; + int dim, tile_pass = 0; + int start[3]; + int end[3]; + int cur[3]; + const float *bbMin = bb->vec[0]; + const float *bbMax = bb->vec[6]; + const float *step = sd->paint.tile_offset; + + copy_v3_v3(orgLoc, true_location); + for (dim = 0; dim < 3; ++dim) { + if ((sd->paint.symmetry_flags & (PAINT_TILE_X << dim)) && step[dim] > 0) { + start[dim] = (bbMin[dim] - orgLoc[dim] - radius) / step[dim]; + end[dim] = (bbMax[dim] - orgLoc[dim] + radius) / step[dim]; + } + else + start[dim] = end[dim] = 0; + } + copy_v3_v3_int(cur, start); + for (cur[0] = start[0]; cur[0] <= end[0]; ++cur[0]) { + for (cur[1] = start[1]; cur[1] <= end[1]; ++cur[1]) { + for (cur[2] = start[2]; cur[2] <= end[2]; ++cur[2]) { + if (!cur[0] && !cur[1] && !cur[2]) + continue; /* skip tile at orgLoc, this was already handled before all others */ + ++tile_pass; + for (dim = 0; dim < 3; ++dim) { + location[dim] = cur[dim] * step[dim] + orgLoc[dim]; + } + cursor_draw_point_screen_space(gpuattr, ar, location, ob->obmat, persmat); } + } + } +} +void cursor_draw_point_with_symmetry(const uint gpuattr, const ARegion *ar,const float true_location[3], + Sculpt *sd, Object *ob, float persmat[4][4], float radius) +{ + const char symm = sd->paint.symmetry_flags & PAINT_SYMM_AXIS_ALL; + float location[3], pv4[4], translation_vertex_cursor[2], symm_rot_mat[4][4]; + + copy_v3_v3(location, true_location); + for (int i = 0; i <= symm; ++i) { + if (i == 0 || (symm & i && (symm != 5 || i != 3) && (symm != 6 || (i != 3 && i != 5)))) { - imm_draw_circle_fill_3d(gpuatrr, translation_vertex_cursor[0], translation_vertex_cursor[1], 3, 10); + /* Axis Symmetry */ + flip_v3_v3(location, true_location, (char)i); + cursor_draw_point_screen_space(gpuattr, ar, location, ob->obmat, persmat); + + /* Tiling */ + copy_v3_v3(location, true_location); + cursor_draw_tiling_preview(gpuattr, ar, location, sd, ob, persmat, radius); + + /* Radial Symmetry */ + for (char raxis = 0; raxis < 3; raxis++) { + for (int r = 1; r < sd->radial_symm[raxis]; r++) { + float angle = 2 * M_PI * r / sd->radial_symm[(int)raxis]; + flip_v3_v3(location, true_location, (char)i); + unit_m4(symm_rot_mat); + rotate_m4(symm_rot_mat, raxis+'X', angle); + mul_m4_v3(symm_rot_mat, location); + + cursor_draw_tiling_preview(gpuattr, ar, location, sd, ob, persmat, radius); + cursor_draw_point_screen_space(gpuattr, ar, location, ob->obmat, persmat); + } + } } } } @@ -1082,7 +1139,6 @@ void cursor_draw_point_with_symmetry(const uint gpuatrr, const ARegion *ar,const static void paint_draw_cursor(bContext *C, int x, int y, void *UNUSED(unused)) { Scene *scene = CTX_data_scene(C); - Depsgraph *depsgraph = CTX_data_depsgraph(C); ARegion *ar = CTX_wm_region(C); UnifiedPaintSettings *ups = &scene->toolsettings->unified_paint_settings; Paint *paint = BKE_paint_get_active_from_context(C); @@ -1183,8 +1239,6 @@ static void paint_draw_cursor(bContext *C, int x, int y, void *UNUSED(unused)) /* Only sculpt cursor for now */ if ((mode == PAINT_MODE_SCULPT) && vc.obact->sculpt) { Sculpt *sd = CTX_data_tool_settings(C)->sculpt; - const char symm = sd->paint.symmetry_flags & PAINT_SYMM_AXIS_ALL; - wmWindow *win = CTX_wm_window(C); if (sd->paint.brush->overlay_flags & BRUSH_OVERLAY_CURSOR) { WM_cursor_set(win, CURSOR_STD); @@ -1199,7 +1253,6 @@ static void paint_draw_cursor(bContext *C, int x, int y, void *UNUSED(unused)) gi.use_sampled_normal = true; hit = sculpt_stroke_get_geometry_info(C, &gi, mouse); if (hit && !alpha_overlay_active) { - 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)); @@ -1212,7 +1265,7 @@ static void paint_draw_cursor(bContext *C, int x, int y, void *UNUSED(unused)) /* draw 3D vertex preview */ if (len_v3v3(gi.nearest_vertex_co, gi.location) < rds) { - cursor_draw_point_with_symmetry(pos3d, ar, gi.nearest_vertex_co, symm, vc.obact->obmat, vc.rv3d->persmat); + cursor_draw_point_with_symmetry(pos3d, ar, gi.nearest_vertex_co, sd, vc.obact, vc.rv3d->persmat, rds); } /* draw brush cursor */ @@ -1250,7 +1303,7 @@ static void paint_draw_cursor(bContext *C, int x, int y, void *UNUSED(unused)) if (ss->cache->brush->sculpt_tool == SCULPT_TOOL_GRAB) { add_v3_v3(cursor_location, ss->cache->grab_delta); } - cursor_draw_point_with_symmetry(pos3d, ar, cursor_location, symm, vc.obact->obmat, vc.rv3d->persmat); + cursor_draw_point_with_symmetry(pos3d, ar, cursor_location, sd, vc.obact, vc.rv3d->persmat, ss->cache->radius); } } } @@ -1259,7 +1312,6 @@ static void paint_draw_cursor(bContext *C, int x, int y, void *UNUSED(unused)) imm_draw_circle_wire_3d(pos3d, translation[0], translation[1], final_radius, 40); } - immUnbindProgram(); /* restore GL state */ _______________________________________________ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org https://lists.blender.org/mailman/listinfo/bf-blender-cvs