Changeset View
Changeset View
Standalone View
Standalone View
source/blender/editors/sculpt_paint/paint_cursor.cc
- This file was moved from source/blender/editors/sculpt_paint/paint_cursor.c.
| Show First 20 Lines • Show All 58 Lines • ▼ Show 20 Lines | |||||
| * | * | ||||
| * Some of the cursor drawing code is doing non-draw stuff | * Some of the cursor drawing code is doing non-draw stuff | ||||
| * (e.g. updating the brush rake angle). This should be cleaned up | * (e.g. updating the brush rake angle). This should be cleaned up | ||||
| * still. | * still. | ||||
| * | * | ||||
| * There is also some ugliness with sculpt-specific code. | * There is also some ugliness with sculpt-specific code. | ||||
| */ | */ | ||||
| typedef struct TexSnapshot { | struct TexSnapshot { | ||||
| GPUTexture *overlay_texture; | GPUTexture *overlay_texture; | ||||
| int winx; | int winx; | ||||
| int winy; | int winy; | ||||
| int old_size; | int old_size; | ||||
| float old_zoom; | float old_zoom; | ||||
| bool old_col; | bool old_col; | ||||
| } TexSnapshot; | }; | ||||
| typedef struct CursorSnapshot { | struct CursorSnapshot { | ||||
| GPUTexture *overlay_texture; | GPUTexture *overlay_texture; | ||||
| int size; | int size; | ||||
| int zoom; | int zoom; | ||||
| int curve_preset; | int curve_preset; | ||||
| } CursorSnapshot; | }; | ||||
| static TexSnapshot primary_snap = {0}; | static TexSnapshot primary_snap = {0}; | ||||
| static TexSnapshot secondary_snap = {0}; | static TexSnapshot secondary_snap = {0}; | ||||
| static CursorSnapshot cursor_snap = {0}; | static CursorSnapshot cursor_snap = {0}; | ||||
| void paint_cursor_delete_textures(void) | void paint_cursor_delete_textures(void) | ||||
| { | { | ||||
| if (primary_snap.overlay_texture) { | if (primary_snap.overlay_texture) { | ||||
| ▲ Show 20 Lines • Show All 45 Lines • ▼ Show 20 Lines | typedef struct LoadTexData { | ||||
| float rotation; | float rotation; | ||||
| float radius; | float radius; | ||||
| } LoadTexData; | } LoadTexData; | ||||
| static void load_tex_task_cb_ex(void *__restrict userdata, | static void load_tex_task_cb_ex(void *__restrict userdata, | ||||
| const int j, | const int j, | ||||
| const TaskParallelTLS *__restrict tls) | const TaskParallelTLS *__restrict tls) | ||||
| { | { | ||||
| LoadTexData *data = userdata; | LoadTexData *data = static_cast<LoadTexData *>(userdata); | ||||
| Brush *br = data->br; | Brush *br = data->br; | ||||
| ViewContext *vc = data->vc; | ViewContext *vc = data->vc; | ||||
| MTex *mtex = data->mtex; | MTex *mtex = data->mtex; | ||||
| uchar *buffer = data->buffer; | uchar *buffer = data->buffer; | ||||
| const bool col = data->col; | const bool col = data->col; | ||||
| struct ImagePool *pool = data->pool; | struct ImagePool *pool = data->pool; | ||||
| const int size = data->size; | const int size = data->size; | ||||
| const float rotation = data->rotation; | const float rotation = data->rotation; | ||||
| const float radius = data->radius; | const float radius = data->radius; | ||||
| bool convert_to_linear = false; | bool convert_to_linear = false; | ||||
| struct ColorSpace *colorspace = NULL; | struct ColorSpace *colorspace = nullptr; | ||||
| const int thread_id = BLI_task_parallel_thread_id(tls); | const int thread_id = BLI_task_parallel_thread_id(tls); | ||||
| if (mtex->tex && mtex->tex->type == TEX_IMAGE && mtex->tex->ima) { | if (mtex->tex && mtex->tex->type == TEX_IMAGE && mtex->tex->ima) { | ||||
| ImBuf *tex_ibuf = BKE_image_pool_acquire_ibuf(mtex->tex->ima, &mtex->tex->iuser, pool); | ImBuf *tex_ibuf = BKE_image_pool_acquire_ibuf(mtex->tex->ima, &mtex->tex->iuser, pool); | ||||
| /* For consistency, sampling always returns color in linear space. */ | /* For consistency, sampling always returns color in linear space. */ | ||||
| if (tex_ibuf && tex_ibuf->rect_float == NULL) { | if (tex_ibuf && tex_ibuf->rect_float == nullptr) { | ||||
| convert_to_linear = true; | convert_to_linear = true; | ||||
| colorspace = tex_ibuf->rect_colorspace; | colorspace = tex_ibuf->rect_colorspace; | ||||
| } | } | ||||
| BKE_image_pool_release_ibuf(mtex->tex->ima, tex_ibuf, pool); | BKE_image_pool_release_ibuf(mtex->tex->ima, tex_ibuf, pool); | ||||
| } | } | ||||
| for (int i = 0; i < size; i++) { | for (int i = 0; i < size; i++) { | ||||
| /* Largely duplicated from tex_strength. */ | /* Largely duplicated from tex_strength. */ | ||||
| ▲ Show 20 Lines • Show All 61 Lines • ▼ Show 20 Lines | |||||
| static int load_tex(Brush *br, ViewContext *vc, float zoom, bool col, bool primary) | static int load_tex(Brush *br, ViewContext *vc, float zoom, bool col, bool primary) | ||||
| { | { | ||||
| bool init; | bool init; | ||||
| TexSnapshot *target; | TexSnapshot *target; | ||||
| MTex *mtex = (primary) ? &br->mtex : &br->mask_mtex; | MTex *mtex = (primary) ? &br->mtex : &br->mask_mtex; | ||||
| ePaintOverlayControlFlags overlay_flags = BKE_paint_get_overlay_flags(); | ePaintOverlayControlFlags overlay_flags = BKE_paint_get_overlay_flags(); | ||||
| uchar *buffer = NULL; | uchar *buffer = nullptr; | ||||
| int size; | int size; | ||||
| bool refresh; | bool refresh; | ||||
| ePaintOverlayControlFlags invalid = | ePaintOverlayControlFlags invalid = | ||||
| ((primary) ? (overlay_flags & PAINT_OVERLAY_INVALID_TEXTURE_PRIMARY) : | ((primary) ? (overlay_flags & PAINT_OVERLAY_INVALID_TEXTURE_PRIMARY) : | ||||
| (overlay_flags & PAINT_OVERLAY_INVALID_TEXTURE_SECONDARY)); | (overlay_flags & PAINT_OVERLAY_INVALID_TEXTURE_SECONDARY)); | ||||
| target = (primary) ? &primary_snap : &secondary_snap; | target = (primary) ? &primary_snap : &secondary_snap; | ||||
| refresh = !target->overlay_texture || (invalid != 0) || | refresh = !target->overlay_texture || (invalid != 0) || | ||||
| !same_tex_snap(target, mtex, vc, col, zoom); | !same_tex_snap(target, mtex, vc, col, zoom); | ||||
| init = (target->overlay_texture != 0); | init = (target->overlay_texture != 0); | ||||
| if (refresh) { | if (refresh) { | ||||
| struct ImagePool *pool = NULL; | struct ImagePool *pool = nullptr; | ||||
| /* Stencil is rotated later. */ | /* Stencil is rotated later. */ | ||||
| const float rotation = (mtex->brush_map_mode != MTEX_MAP_MODE_STENCIL) ? -mtex->rot : 0.0f; | const float rotation = (mtex->brush_map_mode != MTEX_MAP_MODE_STENCIL) ? -mtex->rot : 0.0f; | ||||
| const float radius = BKE_brush_size_get(vc->scene, br) * zoom; | const float radius = BKE_brush_size_get(vc->scene, br) * zoom; | ||||
| make_tex_snap(target, vc, zoom); | make_tex_snap(target, vc, zoom); | ||||
| if (mtex->brush_map_mode == MTEX_MAP_MODE_VIEW) { | if (mtex->brush_map_mode == MTEX_MAP_MODE_VIEW) { | ||||
| int s = BKE_brush_size_get(vc->scene, br); | int s = BKE_brush_size_get(vc->scene, br); | ||||
| Show All 15 Lines | if (refresh) { | ||||
| } | } | ||||
| else { | else { | ||||
| size = 512; | size = 512; | ||||
| } | } | ||||
| if (target->old_size != size || target->old_col != col) { | if (target->old_size != size || target->old_col != col) { | ||||
| if (target->overlay_texture) { | if (target->overlay_texture) { | ||||
| GPU_texture_free(target->overlay_texture); | GPU_texture_free(target->overlay_texture); | ||||
| target->overlay_texture = NULL; | target->overlay_texture = nullptr; | ||||
| } | } | ||||
| init = false; | init = false; | ||||
| target->old_size = size; | target->old_size = size; | ||||
| target->old_col = col; | target->old_col = col; | ||||
| } | } | ||||
| if (col) { | if (col) { | ||||
| buffer = MEM_mallocN(sizeof(uchar) * size * size * 4, "load_tex"); | buffer = static_cast<uchar *>(MEM_mallocN(sizeof(uchar) * size * size * 4, "load_tex")); | ||||
| } | } | ||||
| else { | else { | ||||
| buffer = MEM_mallocN(sizeof(uchar) * size * size, "load_tex"); | buffer = static_cast<uchar *>(MEM_mallocN(sizeof(uchar) * size * size, "load_tex")); | ||||
| } | } | ||||
| pool = BKE_image_pool_new(); | pool = BKE_image_pool_new(); | ||||
| if (mtex->tex && mtex->tex->nodetree) { | if (mtex->tex && mtex->tex->nodetree) { | ||||
| /* Has internal flag to detect it only does it once. */ | /* Has internal flag to detect it only does it once. */ | ||||
| ntreeTexBeginExecTree(mtex->tex->nodetree); | ntreeTexBeginExecTree(mtex->tex->nodetree); | ||||
| } | } | ||||
| LoadTexData data = { | LoadTexData data{}; | ||||
| .br = br, | data.br = br; | ||||
| .vc = vc, | data.vc = vc; | ||||
| .mtex = mtex, | data.mtex = mtex; | ||||
| .buffer = buffer, | data.buffer = buffer; | ||||
| .col = col, | data.col = col; | ||||
| .pool = pool, | data.pool = pool; | ||||
| .size = size, | data.size = size; | ||||
| .rotation = rotation, | data.rotation = rotation; | ||||
| .radius = radius, | data.radius = radius; | ||||
| }; | |||||
| TaskParallelSettings settings; | TaskParallelSettings settings; | ||||
| BLI_parallel_range_settings_defaults(&settings); | BLI_parallel_range_settings_defaults(&settings); | ||||
| BLI_task_parallel_range(0, size, &data, load_tex_task_cb_ex, &settings); | BLI_task_parallel_range(0, size, &data, load_tex_task_cb_ex, &settings); | ||||
| if (mtex->tex && mtex->tex->nodetree) { | if (mtex->tex && mtex->tex->nodetree) { | ||||
| ntreeTexEndExecTree(mtex->tex->nodetree->execdata); | ntreeTexEndExecTree(mtex->tex->nodetree->execdata); | ||||
| } | } | ||||
| if (pool) { | if (pool) { | ||||
| BKE_image_pool_free(pool); | BKE_image_pool_free(pool); | ||||
| } | } | ||||
| if (!target->overlay_texture) { | if (!target->overlay_texture) { | ||||
| eGPUTextureFormat format = col ? GPU_RGBA8 : GPU_R8; | eGPUTextureFormat format = col ? GPU_RGBA8 : GPU_R8; | ||||
| target->overlay_texture = GPU_texture_create_2d( | target->overlay_texture = GPU_texture_create_2d( | ||||
| "paint_cursor_overlay", size, size, 1, format, NULL); | "paint_cursor_overlay", size, size, 1, format, nullptr); | ||||
| GPU_texture_update(target->overlay_texture, GPU_DATA_UBYTE, buffer); | GPU_texture_update(target->overlay_texture, GPU_DATA_UBYTE, buffer); | ||||
| if (!col) { | if (!col) { | ||||
| GPU_texture_swizzle_set(target->overlay_texture, "rrrr"); | GPU_texture_swizzle_set(target->overlay_texture, "rrrr"); | ||||
| } | } | ||||
| } | } | ||||
| if (init) { | if (init) { | ||||
| Show All 12 Lines | static int load_tex(Brush *br, ViewContext *vc, float zoom, bool col, bool primary) | ||||
| return 1; | return 1; | ||||
| } | } | ||||
| static void load_tex_cursor_task_cb(void *__restrict userdata, | static void load_tex_cursor_task_cb(void *__restrict userdata, | ||||
| const int j, | const int j, | ||||
| const TaskParallelTLS *__restrict UNUSED(tls)) | const TaskParallelTLS *__restrict UNUSED(tls)) | ||||
| { | { | ||||
| LoadTexData *data = userdata; | LoadTexData *data = static_cast<LoadTexData *>(userdata); | ||||
| Brush *br = data->br; | Brush *br = data->br; | ||||
| uchar *buffer = data->buffer; | uchar *buffer = data->buffer; | ||||
| const int size = data->size; | const int size = data->size; | ||||
| for (int i = 0; i < size; i++) { | for (int i = 0; i < size; i++) { | ||||
| /* Largely duplicated from tex_strength. */ | /* Largely duplicated from tex_strength. */ | ||||
| Show All 16 Lines | static void load_tex_cursor_task_cb(void *__restrict userdata, | ||||
| } | } | ||||
| } | } | ||||
| static int load_tex_cursor(Brush *br, ViewContext *vc, float zoom) | static int load_tex_cursor(Brush *br, ViewContext *vc, float zoom) | ||||
| { | { | ||||
| bool init; | bool init; | ||||
| ePaintOverlayControlFlags overlay_flags = BKE_paint_get_overlay_flags(); | ePaintOverlayControlFlags overlay_flags = BKE_paint_get_overlay_flags(); | ||||
| uchar *buffer = NULL; | uchar *buffer = nullptr; | ||||
| int size; | int size; | ||||
| const bool refresh = !cursor_snap.overlay_texture || | const bool refresh = !cursor_snap.overlay_texture || | ||||
| (overlay_flags & PAINT_OVERLAY_INVALID_CURVE) || cursor_snap.zoom != zoom || | (overlay_flags & PAINT_OVERLAY_INVALID_CURVE) || cursor_snap.zoom != zoom || | ||||
| cursor_snap.curve_preset != br->curve_preset; | cursor_snap.curve_preset != br->curve_preset; | ||||
| init = (cursor_snap.overlay_texture != 0); | init = (cursor_snap.overlay_texture != 0); | ||||
| Show All 17 Lines | if (refresh) { | ||||
| if (size < cursor_snap.size) { | if (size < cursor_snap.size) { | ||||
| size = cursor_snap.size; | size = cursor_snap.size; | ||||
| } | } | ||||
| if (cursor_snap.size != size) { | if (cursor_snap.size != size) { | ||||
| if (cursor_snap.overlay_texture) { | if (cursor_snap.overlay_texture) { | ||||
| GPU_texture_free(cursor_snap.overlay_texture); | GPU_texture_free(cursor_snap.overlay_texture); | ||||
| cursor_snap.overlay_texture = NULL; | cursor_snap.overlay_texture = nullptr; | ||||
| } | } | ||||
| init = false; | init = false; | ||||
| cursor_snap.size = size; | cursor_snap.size = size; | ||||
| } | } | ||||
| buffer = MEM_mallocN(sizeof(uchar) * size * size, "load_tex"); | buffer = static_cast<uchar *>(MEM_mallocN(sizeof(uchar) * size * size, "load_tex")); | ||||
| BKE_curvemapping_init(br->curve); | BKE_curvemapping_init(br->curve); | ||||
| LoadTexData data = { | LoadTexData data{}; | ||||
| .br = br, | data.br = br; | ||||
| .buffer = buffer, | data.buffer = buffer; | ||||
| .size = size, | data.size = size; | ||||
| }; | |||||
| TaskParallelSettings settings; | TaskParallelSettings settings; | ||||
| BLI_parallel_range_settings_defaults(&settings); | BLI_parallel_range_settings_defaults(&settings); | ||||
| BLI_task_parallel_range(0, size, &data, load_tex_cursor_task_cb, &settings); | BLI_task_parallel_range(0, size, &data, load_tex_cursor_task_cb, &settings); | ||||
| if (!cursor_snap.overlay_texture) { | if (!cursor_snap.overlay_texture) { | ||||
| cursor_snap.overlay_texture = GPU_texture_create_2d( | cursor_snap.overlay_texture = GPU_texture_create_2d( | ||||
| "cursor_snap_overaly", size, size, 1, GPU_R8, NULL); | "cursor_snap_overaly", size, size, 1, GPU_R8, nullptr); | ||||
| GPU_texture_update(cursor_snap.overlay_texture, GPU_DATA_UBYTE, buffer); | GPU_texture_update(cursor_snap.overlay_texture, GPU_DATA_UBYTE, buffer); | ||||
| GPU_texture_swizzle_set(cursor_snap.overlay_texture, "rrrr"); | GPU_texture_swizzle_set(cursor_snap.overlay_texture, "rrrr"); | ||||
| } | } | ||||
| if (init) { | if (init) { | ||||
| GPU_texture_update(cursor_snap.overlay_texture, GPU_DATA_UBYTE, buffer); | GPU_texture_update(cursor_snap.overlay_texture, GPU_DATA_UBYTE, buffer); | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 626 Lines • ▼ Show 20 Lines | |||||
| { | { | ||||
| const char symm = SCULPT_mesh_symmetry_xyz_get(ob); | const char symm = SCULPT_mesh_symmetry_xyz_get(ob); | ||||
| float location[3], symm_rot_mat[4][4]; | float location[3], symm_rot_mat[4][4]; | ||||
| for (int i = 0; i <= symm; i++) { | for (int i = 0; i <= symm; i++) { | ||||
| if (i == 0 || (symm & i && (symm != 5 || i != 3) && (symm != 6 || !ELEM(i, 3, 5)))) { | if (i == 0 || (symm & i && (symm != 5 || i != 3) && (symm != 6 || !ELEM(i, 3, 5)))) { | ||||
| /* Axis Symmetry. */ | /* Axis Symmetry. */ | ||||
| flip_v3_v3(location, true_location, (char)i); | flip_v3_v3(location, true_location, ePaintSymmetryFlags(i)); | ||||
| cursor_draw_point_screen_space(gpuattr, region, location, ob->object_to_world, 3); | cursor_draw_point_screen_space(gpuattr, region, location, ob->object_to_world, 3); | ||||
| /* Tiling. */ | /* Tiling. */ | ||||
| cursor_draw_tiling_preview(gpuattr, region, location, sd, ob, radius); | cursor_draw_tiling_preview(gpuattr, region, location, sd, ob, radius); | ||||
| /* Radial Symmetry. */ | /* Radial Symmetry. */ | ||||
| for (char raxis = 0; raxis < 3; raxis++) { | for (char raxis = 0; raxis < 3; raxis++) { | ||||
| for (int r = 1; r < sd->radial_symm[raxis]; r++) { | for (int r = 1; r < sd->radial_symm[raxis]; r++) { | ||||
| float angle = 2 * M_PI * r / sd->radial_symm[(int)raxis]; | float angle = 2 * M_PI * r / sd->radial_symm[(int)raxis]; | ||||
| flip_v3_v3(location, true_location, (char)i); | flip_v3_v3(location, true_location, ePaintSymmetryFlags(i)); | ||||
| unit_m4(symm_rot_mat); | unit_m4(symm_rot_mat); | ||||
| rotate_m4(symm_rot_mat, raxis + 'X', angle); | rotate_m4(symm_rot_mat, raxis + 'X', angle); | ||||
| mul_m4_v3(symm_rot_mat, location); | mul_m4_v3(symm_rot_mat, location); | ||||
| cursor_draw_tiling_preview(gpuattr, region, location, sd, ob, radius); | cursor_draw_tiling_preview(gpuattr, region, location, sd, ob, radius); | ||||
| cursor_draw_point_screen_space(gpuattr, region, location, ob->object_to_world, 3); | cursor_draw_point_screen_space(gpuattr, region, location, ob->object_to_world, 3); | ||||
| } | } | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 140 Lines • ▼ Show 20 Lines | static bool paint_cursor_context_init(bContext *C, | ||||
| pcontext->C = C; | pcontext->C = C; | ||||
| pcontext->region = region; | pcontext->region = region; | ||||
| pcontext->wm = CTX_wm_manager(C); | pcontext->wm = CTX_wm_manager(C); | ||||
| pcontext->win = CTX_wm_window(C); | pcontext->win = CTX_wm_window(C); | ||||
| pcontext->depsgraph = CTX_data_depsgraph_pointer(C); | pcontext->depsgraph = CTX_data_depsgraph_pointer(C); | ||||
| pcontext->scene = CTX_data_scene(C); | pcontext->scene = CTX_data_scene(C); | ||||
| pcontext->ups = &pcontext->scene->toolsettings->unified_paint_settings; | pcontext->ups = &pcontext->scene->toolsettings->unified_paint_settings; | ||||
| pcontext->paint = BKE_paint_get_active_from_context(C); | pcontext->paint = BKE_paint_get_active_from_context(C); | ||||
| if (pcontext->paint == NULL) { | if (pcontext->paint == nullptr) { | ||||
| return false; | return false; | ||||
| } | } | ||||
| pcontext->brush = BKE_paint_brush(pcontext->paint); | pcontext->brush = BKE_paint_brush(pcontext->paint); | ||||
| if (pcontext->brush == NULL) { | if (pcontext->brush == nullptr) { | ||||
| return false; | return false; | ||||
| } | } | ||||
| pcontext->mode = BKE_paintmode_get_active_from_context(C); | pcontext->mode = BKE_paintmode_get_active_from_context(C); | ||||
| ED_view3d_viewcontext_init(C, &pcontext->vc, pcontext->depsgraph); | ED_view3d_viewcontext_init(C, &pcontext->vc, pcontext->depsgraph); | ||||
| if (pcontext->brush->flag & BRUSH_CURVE) { | if (pcontext->brush->flag & BRUSH_CURVE) { | ||||
| pcontext->cursor_type = PAINT_CURSOR_CURVE; | pcontext->cursor_type = PAINT_CURSOR_CURVE; | ||||
| Show All 22 Lines | if (((pcontext->ups->draw_inverted == 0) ^ ((pcontext->brush->flag & BRUSH_DIR_IN) == 0)) && | ||||
| copy_v3_v3(pcontext->outline_col, pcontext->brush->sub_col); | copy_v3_v3(pcontext->outline_col, pcontext->brush->sub_col); | ||||
| } | } | ||||
| else { | else { | ||||
| copy_v3_v3(pcontext->outline_col, pcontext->brush->add_col); | copy_v3_v3(pcontext->outline_col, pcontext->brush->add_col); | ||||
| } | } | ||||
| pcontext->outline_alpha = pcontext->brush->add_col[3]; | pcontext->outline_alpha = pcontext->brush->add_col[3]; | ||||
| Object *active_object = pcontext->vc.obact; | Object *active_object = pcontext->vc.obact; | ||||
| pcontext->ss = active_object ? active_object->sculpt : NULL; | pcontext->ss = active_object ? active_object->sculpt : nullptr; | ||||
| if (pcontext->ss && pcontext->ss->draw_faded_cursor) { | if (pcontext->ss && pcontext->ss->draw_faded_cursor) { | ||||
| pcontext->outline_alpha = 0.3f; | pcontext->outline_alpha = 0.3f; | ||||
| copy_v3_fl(pcontext->outline_col, 0.8f); | copy_v3_fl(pcontext->outline_col, 0.8f); | ||||
| } | } | ||||
| const bool is_brush_tool = PAINT_brush_tool_poll(C); | const bool is_brush_tool = PAINT_brush_tool_poll(C); | ||||
| if (!is_brush_tool) { | if (!is_brush_tool) { | ||||
| Show All 28 Lines | else { | ||||
| Brush *brush = BKE_paint_brush(&sd->paint); | Brush *brush = BKE_paint_brush(&sd->paint); | ||||
| pcontext->pixel_radius = BKE_brush_size_get(pcontext->scene, brush); | pcontext->pixel_radius = BKE_brush_size_get(pcontext->scene, brush); | ||||
| } | } | ||||
| } | } | ||||
| static void paint_cursor_sculpt_session_update_and_init(PaintCursorContext *pcontext) | static void paint_cursor_sculpt_session_update_and_init(PaintCursorContext *pcontext) | ||||
| { | { | ||||
| BLI_assert(pcontext->ss != NULL); | BLI_assert(pcontext->ss != nullptr); | ||||
| BLI_assert(pcontext->mode == PAINT_MODE_SCULPT); | BLI_assert(pcontext->mode == PAINT_MODE_SCULPT); | ||||
| bContext *C = pcontext->C; | bContext *C = pcontext->C; | ||||
| SculptSession *ss = pcontext->ss; | SculptSession *ss = pcontext->ss; | ||||
| Brush *brush = pcontext->brush; | Brush *brush = pcontext->brush; | ||||
| Scene *scene = pcontext->scene; | Scene *scene = pcontext->scene; | ||||
| UnifiedPaintSettings *ups = pcontext->ups; | UnifiedPaintSettings *ups = pcontext->ups; | ||||
| ViewContext *vc = &pcontext->vc; | ViewContext *vc = &pcontext->vc; | ||||
| SculptCursorGeometryInfo gi; | SculptCursorGeometryInfo gi; | ||||
| const float mval_fl[2] = { | const float mval_fl[2] = { | ||||
| pcontext->x - pcontext->region->winrct.xmin, | float(pcontext->x - pcontext->region->winrct.xmin), | ||||
| pcontext->y - pcontext->region->winrct.ymin, | float(pcontext->y - pcontext->region->winrct.ymin), | ||||
| }; | }; | ||||
| /* This updates the active vertex, which is needed for most of the Sculpt/Vertex Colors tools to | /* This updates the active vertex, which is needed for most of the Sculpt/Vertex Colors tools to | ||||
| * work correctly */ | * work correctly */ | ||||
| pcontext->prev_active_vertex = ss->active_vertex; | pcontext->prev_active_vertex = ss->active_vertex; | ||||
| if (!ups->stroke_active) { | if (!ups->stroke_active) { | ||||
| pcontext->is_cursor_over_mesh = SCULPT_cursor_geometry_info_update( | pcontext->is_cursor_over_mesh = SCULPT_cursor_geometry_info_update( | ||||
| C, &gi, mval_fl, (pcontext->brush->falloff_shape == PAINT_FALLOFF_SHAPE_SPHERE)); | C, &gi, mval_fl, (pcontext->brush->falloff_shape == PAINT_FALLOFF_SHAPE_SPHERE)); | ||||
| Show All 10 Lines | static void paint_cursor_sculpt_session_update_and_init(PaintCursorContext *pcontext) | ||||
| if (BKE_brush_use_locked_size(scene, brush)) { | if (BKE_brush_use_locked_size(scene, brush)) { | ||||
| BKE_brush_size_set(scene, brush, pcontext->pixel_radius); | BKE_brush_size_set(scene, brush, pcontext->pixel_radius); | ||||
| } | } | ||||
| if (pcontext->is_cursor_over_mesh) { | if (pcontext->is_cursor_over_mesh) { | ||||
| paint_cursor_update_unprojected_radius(ups, brush, vc, pcontext->scene_space_location); | paint_cursor_update_unprojected_radius(ups, brush, vc, pcontext->scene_space_location); | ||||
| } | } | ||||
| pcontext->is_multires = ss->pbvh != NULL && BKE_pbvh_type(ss->pbvh) == PBVH_GRIDS; | pcontext->is_multires = ss->pbvh != nullptr && BKE_pbvh_type(ss->pbvh) == PBVH_GRIDS; | ||||
| pcontext->sd = CTX_data_tool_settings(pcontext->C)->sculpt; | pcontext->sd = CTX_data_tool_settings(pcontext->C)->sculpt; | ||||
| } | } | ||||
| static void paint_update_mouse_cursor(PaintCursorContext *pcontext) | static void paint_update_mouse_cursor(PaintCursorContext *pcontext) | ||||
| { | { | ||||
| WM_cursor_set(pcontext->win, WM_CURSOR_PAINT); | WM_cursor_set(pcontext->win, WM_CURSOR_PAINT); | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 205 Lines • ▼ Show 20 Lines | static void paint_cursor_draw_3d_view_brush_cursor_inactive(PaintCursorContext *pcontext) | ||||
| const bool is_brush_tool = PAINT_brush_tool_poll(pcontext->C); | const bool is_brush_tool = PAINT_brush_tool_poll(pcontext->C); | ||||
| /* Pose brush updates and rotation origins. */ | /* Pose brush updates and rotation origins. */ | ||||
| if (is_brush_tool && brush->sculpt_tool == SCULPT_TOOL_POSE) { | if (is_brush_tool && brush->sculpt_tool == SCULPT_TOOL_POSE) { | ||||
| /* Just after switching to the Pose Brush, the active vertex can be the same and the | /* Just after switching to the Pose Brush, the active vertex can be the same and the | ||||
| * cursor won't be tagged to update, so always initialize the preview chain if it is | * cursor won't be tagged to update, so always initialize the preview chain if it is | ||||
| * null before drawing it. */ | * nullptr before drawing it. */ | ||||
| SculptSession *ss = pcontext->ss; | SculptSession *ss = pcontext->ss; | ||||
| if (update_previews || !ss->pose_ik_chain_preview) { | if (update_previews || !ss->pose_ik_chain_preview) { | ||||
| BKE_sculpt_update_object_for_edit( | BKE_sculpt_update_object_for_edit( | ||||
| pcontext->depsgraph, pcontext->vc.obact, true, false, false); | pcontext->depsgraph, pcontext->vc.obact, true, false, false); | ||||
| /* Free the previous pose brush preview. */ | /* Free the previous pose brush preview. */ | ||||
| if (ss->pose_ik_chain_preview) { | if (ss->pose_ik_chain_preview) { | ||||
| SCULPT_pose_ik_chain_free(ss->pose_ik_chain_preview); | SCULPT_pose_ik_chain_free(ss->pose_ik_chain_preview); | ||||
| Show All 26 Lines | static void paint_cursor_draw_3d_view_brush_cursor_inactive(PaintCursorContext *pcontext) | ||||
| /* Setup 3D perspective drawing. */ | /* Setup 3D perspective drawing. */ | ||||
| GPU_matrix_push_projection(); | GPU_matrix_push_projection(); | ||||
| ED_view3d_draw_setup_view(pcontext->wm, | ED_view3d_draw_setup_view(pcontext->wm, | ||||
| pcontext->win, | pcontext->win, | ||||
| pcontext->depsgraph, | pcontext->depsgraph, | ||||
| pcontext->scene, | pcontext->scene, | ||||
| pcontext->region, | pcontext->region, | ||||
| CTX_wm_view3d(pcontext->C), | CTX_wm_view3d(pcontext->C), | ||||
| NULL, | nullptr, | ||||
| NULL, | nullptr, | ||||
| NULL); | nullptr); | ||||
| GPU_matrix_push(); | GPU_matrix_push(); | ||||
| GPU_matrix_mul(pcontext->vc.obact->object_to_world); | GPU_matrix_mul(pcontext->vc.obact->object_to_world); | ||||
| /* Drawing Cursor overlays in 3D object space. */ | /* Drawing Cursor overlays in 3D object space. */ | ||||
| if (is_brush_tool && brush->sculpt_tool == SCULPT_TOOL_GRAB && | if (is_brush_tool && brush->sculpt_tool == SCULPT_TOOL_GRAB && | ||||
| (brush->flag & BRUSH_GRAB_ACTIVE_VERTEX)) { | (brush->flag & BRUSH_GRAB_ACTIVE_VERTEX)) { | ||||
| SCULPT_geometry_preview_lines_update(pcontext->C, pcontext->ss, pcontext->radius); | SCULPT_geometry_preview_lines_update(pcontext->C, pcontext->ss, pcontext->radius); | ||||
| ▲ Show 20 Lines • Show All 46 Lines • ▼ Show 20 Lines | static void paint_cursor_draw_3d_view_brush_cursor_inactive(PaintCursorContext *pcontext) | ||||
| /* Reset drawing. */ | /* Reset drawing. */ | ||||
| GPU_matrix_pop_projection(); | GPU_matrix_pop_projection(); | ||||
| wmWindowViewport(pcontext->win); | wmWindowViewport(pcontext->win); | ||||
| } | } | ||||
| static void paint_cursor_cursor_draw_3d_view_brush_cursor_active(PaintCursorContext *pcontext) | static void paint_cursor_cursor_draw_3d_view_brush_cursor_active(PaintCursorContext *pcontext) | ||||
| { | { | ||||
| BLI_assert(pcontext->ss != NULL); | BLI_assert(pcontext->ss != nullptr); | ||||
| BLI_assert(pcontext->mode == PAINT_MODE_SCULPT); | BLI_assert(pcontext->mode == PAINT_MODE_SCULPT); | ||||
| SculptSession *ss = pcontext->ss; | SculptSession *ss = pcontext->ss; | ||||
| Brush *brush = pcontext->brush; | Brush *brush = pcontext->brush; | ||||
| /* The cursor can be updated as active before creating the StrokeCache, so this needs to be | /* The cursor can be updated as active before creating the StrokeCache, so this needs to be | ||||
| * checked. */ | * checked. */ | ||||
| if (!ss->cache) { | if (!ss->cache) { | ||||
| Show All 10 Lines | static void paint_cursor_cursor_draw_3d_view_brush_cursor_active(PaintCursorContext *pcontext) | ||||
| wmViewport(&pcontext->region->winrct); | wmViewport(&pcontext->region->winrct); | ||||
| GPU_matrix_push_projection(); | GPU_matrix_push_projection(); | ||||
| ED_view3d_draw_setup_view(pcontext->wm, | ED_view3d_draw_setup_view(pcontext->wm, | ||||
| pcontext->win, | pcontext->win, | ||||
| pcontext->depsgraph, | pcontext->depsgraph, | ||||
| pcontext->scene, | pcontext->scene, | ||||
| pcontext->region, | pcontext->region, | ||||
| CTX_wm_view3d(pcontext->C), | CTX_wm_view3d(pcontext->C), | ||||
| NULL, | nullptr, | ||||
| NULL, | nullptr, | ||||
| NULL); | nullptr); | ||||
| GPU_matrix_push(); | GPU_matrix_push(); | ||||
| GPU_matrix_mul(pcontext->vc.obact->object_to_world); | GPU_matrix_mul(pcontext->vc.obact->object_to_world); | ||||
| /* Draw the special active cursors different tools may have. */ | /* Draw the special active cursors different tools may have. */ | ||||
| if (brush->sculpt_tool == SCULPT_TOOL_GRAB) { | if (brush->sculpt_tool == SCULPT_TOOL_GRAB) { | ||||
| sculpt_geometry_preview_lines_draw(pcontext->pos, brush, pcontext->is_multires, ss); | sculpt_geometry_preview_lines_draw(pcontext->pos, brush, pcontext->is_multires, ss); | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 173 Lines • ▼ Show 20 Lines | |||||
| } | } | ||||
| /* Public API */ | /* Public API */ | ||||
| void ED_paint_cursor_start(Paint *p, bool (*poll)(bContext *C)) | void ED_paint_cursor_start(Paint *p, bool (*poll)(bContext *C)) | ||||
| { | { | ||||
| if (p && !p->paint_cursor) { | if (p && !p->paint_cursor) { | ||||
| p->paint_cursor = WM_paint_cursor_activate( | p->paint_cursor = WM_paint_cursor_activate( | ||||
| SPACE_TYPE_ANY, RGN_TYPE_ANY, poll, paint_draw_cursor, NULL); | SPACE_TYPE_ANY, RGN_TYPE_ANY, poll, paint_draw_cursor, nullptr); | ||||
| } | } | ||||
| /* Invalidate the paint cursors. */ | /* Invalidate the paint cursors. */ | ||||
| BKE_paint_invalidate_overlay_all(); | BKE_paint_invalidate_overlay_all(); | ||||
| } | } | ||||