Changeset View
Changeset View
Standalone View
Standalone View
source/blender/draw/engines/overlay/overlay_edit_uv.c
| Show All 20 Lines | |||||
| */ | */ | ||||
| #include "DRW_render.h" | #include "DRW_render.h" | ||||
| #include "draw_cache_impl.h" | #include "draw_cache_impl.h" | ||||
| #include "draw_manager_text.h" | #include "draw_manager_text.h" | ||||
| #include "BKE_editmesh.h" | #include "BKE_editmesh.h" | ||||
| #include "BKE_image.h" | #include "BKE_image.h" | ||||
| #include "BKE_paint.h" | |||||
| #include "DNA_brush_types.h" | |||||
| #include "DNA_mesh_types.h" | #include "DNA_mesh_types.h" | ||||
| #include "ED_image.h" | #include "ED_image.h" | ||||
| #include "IMB_imbuf_types.h" | |||||
| #include "GPU_batch.h" | #include "GPU_batch.h" | ||||
| #include "UI_interface.h" | #include "UI_interface.h" | ||||
| #include "UI_resources.h" | #include "UI_resources.h" | ||||
| #include "overlay_private.h" | #include "overlay_private.h" | ||||
| typedef struct OVERLAY_StretchingAreaTotals { | typedef struct OVERLAY_StretchingAreaTotals { | ||||
| Show All 30 Lines | |||||
| void OVERLAY_edit_uv_init(OVERLAY_Data *vedata) | void OVERLAY_edit_uv_init(OVERLAY_Data *vedata) | ||||
| { | { | ||||
| OVERLAY_StorageList *stl = vedata->stl; | OVERLAY_StorageList *stl = vedata->stl; | ||||
| OVERLAY_PrivateData *pd = stl->pd; | OVERLAY_PrivateData *pd = stl->pd; | ||||
| const DRWContextState *draw_ctx = DRW_context_state_get(); | const DRWContextState *draw_ctx = DRW_context_state_get(); | ||||
| SpaceImage *sima = (SpaceImage *)draw_ctx->space_data; | SpaceImage *sima = (SpaceImage *)draw_ctx->space_data; | ||||
| const Scene *scene = draw_ctx->scene; | const Scene *scene = draw_ctx->scene; | ||||
| const ToolSettings *ts = scene->toolsettings; | ToolSettings *ts = scene->toolsettings; | ||||
| const Brush *brush = BKE_paint_brush(&ts->imapaint.paint); | |||||
| const bool show_overlays = !pd->hide_overlays; | const bool show_overlays = !pd->hide_overlays; | ||||
| Image *image = sima->image; | Image *image = sima->image; | ||||
| /* By design no image is an image type. This so editor shows UV's by default. */ | /* By design no image is an image type. This so editor shows UV's by default. */ | ||||
| const bool is_image_type = | const bool is_image_type = | ||||
| (image == NULL) || ELEM(image->type, IMA_TYPE_IMAGE, IMA_TYPE_MULTILAYER, IMA_TYPE_UV_TEST); | (image == NULL) || ELEM(image->type, IMA_TYPE_IMAGE, IMA_TYPE_MULTILAYER, IMA_TYPE_UV_TEST); | ||||
| const bool is_uv_editor = sima->mode == SI_MODE_UV; | const bool is_uv_editor = sima->mode == SI_MODE_UV; | ||||
| const bool has_edit_object = (draw_ctx->object_edit) != NULL; | const bool has_edit_object = (draw_ctx->object_edit) != NULL; | ||||
| const bool is_paint_mode = sima->mode == SI_MODE_PAINT; | const bool is_paint_mode = sima->mode == SI_MODE_PAINT; | ||||
| const bool is_view_mode = sima->mode == SI_MODE_VIEW; | const bool is_view_mode = sima->mode == SI_MODE_VIEW; | ||||
| const bool is_edit_mode = draw_ctx->object_mode == OB_MODE_EDIT; | const bool is_edit_mode = draw_ctx->object_mode == OB_MODE_EDIT; | ||||
| const bool do_uv_overlay = is_image_type && is_uv_editor && has_edit_object; | const bool do_uv_overlay = is_image_type && is_uv_editor && has_edit_object; | ||||
| const bool show_modified_uvs = sima->flag & SI_DRAWSHADOW; | const bool show_modified_uvs = sima->flag & SI_DRAWSHADOW; | ||||
| const bool is_tiled_image = image && (image->source == IMA_SRC_TILED); | const bool is_tiled_image = image && (image->source == IMA_SRC_TILED); | ||||
| const bool do_faces = ((sima->flag & SI_NO_DRAWFACES) == 0); | const bool do_faces = ((sima->flag & SI_NO_DRAWFACES) == 0); | ||||
| const bool do_face_dots = (ts->uv_flag & UV_SYNC_SELECTION) ? | const bool do_face_dots = (ts->uv_flag & UV_SYNC_SELECTION) ? | ||||
| (ts->selectmode & SCE_SELECT_FACE) != 0 : | (ts->selectmode & SCE_SELECT_FACE) != 0 : | ||||
| (ts->uv_selectmode == UV_SELECT_FACE); | (ts->uv_selectmode == UV_SELECT_FACE); | ||||
| const bool do_uvstretching_overlay = is_image_type && is_uv_editor && is_edit_mode && | const bool do_uvstretching_overlay = is_image_type && is_uv_editor && is_edit_mode && | ||||
| ((sima->flag & SI_DRAW_STRETCH) != 0); | ((sima->flag & SI_DRAW_STRETCH) != 0); | ||||
| const bool do_tex_paint_shadows = (sima->flag & SI_NO_DRAW_TEXPAINT) == 0; | const bool do_tex_paint_shadows = (sima->flag & SI_NO_DRAW_TEXPAINT) == 0; | ||||
| const bool do_stencil_overlay = is_paint_mode && is_image_type && brush && | |||||
| (brush->imagepaint_tool == PAINT_TOOL_CLONE) && | |||||
| brush->clone.image; | |||||
| pd->edit_uv.do_faces = show_overlays && do_faces && !do_uvstretching_overlay; | pd->edit_uv.do_faces = show_overlays && do_faces && !do_uvstretching_overlay; | ||||
| pd->edit_uv.do_face_dots = show_overlays && do_faces && do_face_dots; | pd->edit_uv.do_face_dots = show_overlays && do_faces && do_face_dots; | ||||
| pd->edit_uv.do_uv_overlay = show_overlays && do_uv_overlay; | pd->edit_uv.do_uv_overlay = show_overlays && do_uv_overlay; | ||||
| pd->edit_uv.do_uv_shadow_overlay = show_overlays && is_image_type && | pd->edit_uv.do_uv_shadow_overlay = show_overlays && is_image_type && | ||||
| ((is_paint_mode && do_tex_paint_shadows && | ((is_paint_mode && do_tex_paint_shadows && | ||||
| ((draw_ctx->object_mode & | ((draw_ctx->object_mode & | ||||
| (OB_MODE_TEXTURE_PAINT | OB_MODE_EDIT)) != 0)) || | (OB_MODE_TEXTURE_PAINT | OB_MODE_EDIT)) != 0)) || | ||||
| (is_view_mode && do_tex_paint_shadows && | (is_view_mode && do_tex_paint_shadows && | ||||
| ((draw_ctx->object_mode & (OB_MODE_TEXTURE_PAINT)) != 0)) || | ((draw_ctx->object_mode & (OB_MODE_TEXTURE_PAINT)) != 0)) || | ||||
| (do_uv_overlay && (show_modified_uvs))); | (do_uv_overlay && (show_modified_uvs))); | ||||
| pd->edit_uv.do_uv_stretching_overlay = show_overlays && do_uvstretching_overlay; | pd->edit_uv.do_uv_stretching_overlay = show_overlays && do_uvstretching_overlay; | ||||
| pd->edit_uv.uv_opacity = sima->uv_opacity; | pd->edit_uv.uv_opacity = sima->uv_opacity; | ||||
| pd->edit_uv.do_tiled_image_overlay = show_overlays && is_image_type && is_tiled_image; | pd->edit_uv.do_tiled_image_overlay = show_overlays && is_image_type && is_tiled_image; | ||||
| pd->edit_uv.do_tiled_image_border_overlay = is_image_type && is_tiled_image; | pd->edit_uv.do_tiled_image_border_overlay = is_image_type && is_tiled_image; | ||||
| pd->edit_uv.dash_length = 4.0f * UI_DPI_FAC; | pd->edit_uv.dash_length = 4.0f * UI_DPI_FAC; | ||||
| pd->edit_uv.line_style = edit_uv_line_style_from_space_image(sima); | pd->edit_uv.line_style = edit_uv_line_style_from_space_image(sima); | ||||
| pd->edit_uv.do_smooth_wire = ((U.gpu_flag & USER_GPU_FLAG_OVERLAY_SMOOTH_WIRE) > 0); | pd->edit_uv.do_smooth_wire = ((U.gpu_flag & USER_GPU_FLAG_OVERLAY_SMOOTH_WIRE) > 0); | ||||
| pd->edit_uv.do_stencil_overlay = show_overlays && do_stencil_overlay; | |||||
| pd->edit_uv.draw_type = sima->dt_uvstretch; | pd->edit_uv.draw_type = sima->dt_uvstretch; | ||||
| BLI_listbase_clear(&pd->edit_uv.totals); | BLI_listbase_clear(&pd->edit_uv.totals); | ||||
| pd->edit_uv.total_area_ratio = 0.0f; | pd->edit_uv.total_area_ratio = 0.0f; | ||||
| pd->edit_uv.total_area_ratio_inv = 0.0f; | pd->edit_uv.total_area_ratio_inv = 0.0f; | ||||
| ED_space_image_get_uv_aspect(sima, &pd->edit_uv.aspect[0], &pd->edit_uv.aspect[1]); | ED_space_image_get_uv_aspect(sima, &pd->edit_uv.aspect[0], &pd->edit_uv.aspect[1]); | ||||
| } | } | ||||
| void OVERLAY_edit_uv_cache_init(OVERLAY_Data *vedata) | void OVERLAY_edit_uv_cache_init(OVERLAY_Data *vedata) | ||||
| { | { | ||||
| OVERLAY_StorageList *stl = vedata->stl; | OVERLAY_StorageList *stl = vedata->stl; | ||||
| OVERLAY_PassList *psl = vedata->psl; | OVERLAY_PassList *psl = vedata->psl; | ||||
| OVERLAY_PrivateData *pd = stl->pd; | OVERLAY_PrivateData *pd = stl->pd; | ||||
| const DRWContextState *draw_ctx = DRW_context_state_get(); | |||||
| SpaceImage *sima = (SpaceImage *)draw_ctx->space_data; | |||||
| Image *image = sima->image; | |||||
| const Scene *scene = draw_ctx->scene; | |||||
| ToolSettings *ts = scene->toolsettings; | |||||
| if (pd->edit_uv.do_uv_overlay || pd->edit_uv.do_uv_shadow_overlay) { | if (pd->edit_uv.do_uv_overlay || pd->edit_uv.do_uv_shadow_overlay) { | ||||
| /* uv edges */ | /* uv edges */ | ||||
| { | { | ||||
| DRW_PASS_CREATE(psl->edit_uv_edges_ps, | DRW_PASS_CREATE(psl->edit_uv_edges_ps, | ||||
| DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL | | DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL | | ||||
| DRW_STATE_BLEND_ALPHA); | DRW_STATE_BLEND_ALPHA); | ||||
| GPUShader *sh = OVERLAY_shader_edit_uv_edges_get(); | GPUShader *sh = OVERLAY_shader_edit_uv_edges_get(); | ||||
| if (pd->edit_uv.do_uv_shadow_overlay) { | if (pd->edit_uv.do_uv_shadow_overlay) { | ||||
| ▲ Show 20 Lines • Show All 76 Lines • ▼ Show 20 Lines | else /* SI_UVDT_STRETCH_AREA */ { | ||||
| DRW_shgroup_uniform_float( | DRW_shgroup_uniform_float( | ||||
| pd->edit_uv_stretching_grp, "totalAreaRatio", &pd->edit_uv.total_area_ratio, 1); | pd->edit_uv_stretching_grp, "totalAreaRatio", &pd->edit_uv.total_area_ratio, 1); | ||||
| DRW_shgroup_uniform_float( | DRW_shgroup_uniform_float( | ||||
| pd->edit_uv_stretching_grp, "totalAreaRatioInv", &pd->edit_uv.total_area_ratio_inv, 1); | pd->edit_uv_stretching_grp, "totalAreaRatioInv", &pd->edit_uv.total_area_ratio_inv, 1); | ||||
| } | } | ||||
| } | } | ||||
| if (pd->edit_uv.do_tiled_image_border_overlay) { | if (pd->edit_uv.do_tiled_image_border_overlay) { | ||||
| const DRWContextState *draw_ctx = DRW_context_state_get(); | |||||
| SpaceImage *sima = (SpaceImage *)draw_ctx->space_data; | |||||
| Image *image = sima->image; | |||||
| GPUBatch *geom = DRW_cache_quad_wires_get(); | GPUBatch *geom = DRW_cache_quad_wires_get(); | ||||
| float obmat[4][4]; | float obmat[4][4]; | ||||
| unit_m4(obmat); | unit_m4(obmat); | ||||
| DRW_PASS_CREATE(psl->edit_uv_tiled_image_borders_ps, | DRW_PASS_CREATE(psl->edit_uv_tiled_image_borders_ps, | ||||
| DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_ALWAYS); | DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_ALWAYS); | ||||
| GPUShader *sh = OVERLAY_shader_edit_uv_tiled_image_borders_get(); | GPUShader *sh = OVERLAY_shader_edit_uv_tiled_image_borders_get(); | ||||
| Show All 22 Lines | if (pd->edit_uv.do_tiled_image_overlay) { | ||||
| obmat[3][1] = (float)((active_tile->tile_number - 1001) / 10); | obmat[3][1] = (float)((active_tile->tile_number - 1001) / 10); | ||||
| grp = DRW_shgroup_create(sh, psl->edit_uv_tiled_image_borders_ps); | grp = DRW_shgroup_create(sh, psl->edit_uv_tiled_image_borders_ps); | ||||
| DRW_shgroup_uniform_vec4_copy(grp, "color", selected_color); | DRW_shgroup_uniform_vec4_copy(grp, "color", selected_color); | ||||
| DRW_shgroup_call_obmat(grp, geom, obmat); | DRW_shgroup_call_obmat(grp, geom, obmat); | ||||
| } | } | ||||
| } | } | ||||
| if (pd->edit_uv.do_tiled_image_overlay) { | if (pd->edit_uv.do_tiled_image_overlay) { | ||||
| const DRWContextState *draw_ctx = DRW_context_state_get(); | |||||
| SpaceImage *sima = (SpaceImage *)draw_ctx->space_data; | |||||
| Image *image = sima->image; | |||||
| struct DRWTextStore *dt = DRW_text_cache_ensure(); | struct DRWTextStore *dt = DRW_text_cache_ensure(); | ||||
| uchar color[4]; | uchar color[4]; | ||||
| /* Color Management: Exception here as texts are drawn in sRGB space directly. */ | /* Color Management: Exception here as texts are drawn in sRGB space directly. */ | ||||
| UI_GetThemeColorShade4ubv(TH_BACK, 60, color); | UI_GetThemeColorShade4ubv(TH_BACK, 60, color); | ||||
| char text[16]; | char text[16]; | ||||
| LISTBASE_FOREACH (ImageTile *, tile, &image->tiles) { | LISTBASE_FOREACH (ImageTile *, tile, &image->tiles) { | ||||
| BLI_snprintf(text, 5, "%d", tile->tile_number); | BLI_snprintf(text, 5, "%d", tile->tile_number); | ||||
| float tile_location[3] = { | float tile_location[3] = { | ||||
| ((tile->tile_number - 1001) % 10), ((tile->tile_number - 1001) / 10), 0.0f}; | ((tile->tile_number - 1001) % 10), ((tile->tile_number - 1001) / 10), 0.0f}; | ||||
| DRW_text_cache_add(dt, | DRW_text_cache_add(dt, | ||||
| tile_location, | tile_location, | ||||
| text, | text, | ||||
| strlen(text), | strlen(text), | ||||
| 10, | 10, | ||||
| 10, | 10, | ||||
| DRW_TEXT_CACHE_GLOBALSPACE | DRW_TEXT_CACHE_ASCII, | DRW_TEXT_CACHE_GLOBALSPACE | DRW_TEXT_CACHE_ASCII, | ||||
| color); | color); | ||||
| } | } | ||||
| } | } | ||||
| if (pd->edit_uv.do_stencil_overlay) { | |||||
| const Brush *brush = BKE_paint_brush(&ts->imapaint.paint); | |||||
| DRW_PASS_CREATE(psl->edit_uv_stencil_ps, | |||||
| DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_ALWAYS | DRW_STATE_BLEND_ALPHA_PREMUL); | |||||
| GPUShader *sh = OVERLAY_shader_edit_uv_stencil_image(); | |||||
| GPUBatch *geom = DRW_cache_quad_get(); | |||||
| DRWShadingGroup *grp = DRW_shgroup_create(sh, psl->edit_uv_stencil_ps); | |||||
| Image *stencil_image = brush->clone.image; | |||||
| ImBuf *stencil_ibuf = BKE_image_acquire_ibuf(stencil_image, NULL, &pd->edit_uv.stencil_lock); | |||||
| pd->edit_uv.stencil_ibuf = stencil_ibuf; | |||||
| pd->edit_uv.stencil_image = stencil_image; | |||||
| GPUTexture *stencil_texture = BKE_image_get_gpu_texture(stencil_image, NULL, stencil_ibuf); | |||||
| DRW_shgroup_uniform_texture(grp, "imgTexture", stencil_texture); | |||||
| DRW_shgroup_uniform_bool_copy(grp, "imgPremultiplied", true); | |||||
| DRW_shgroup_uniform_bool_copy(grp, "imgAlphaBlend", true); | |||||
| DRW_shgroup_uniform_vec4_copy(grp, "color", (float[4]){1.0f, 1.0f, 1.0f, brush->clone.alpha}); | |||||
| float size_image[2]; | |||||
| BKE_image_get_size_fl(image, NULL, size_image); | |||||
| float size_stencil_image[2] = {stencil_ibuf->x, stencil_ibuf->y}; | |||||
| float obmat[4][4]; | |||||
| unit_m4(obmat); | |||||
| obmat[3][1] = brush->clone.offset[1]; | |||||
| obmat[3][0] = brush->clone.offset[0]; | |||||
| obmat[0][0] = size_stencil_image[0] / size_image[0]; | |||||
| obmat[1][1] = size_stencil_image[1] / size_image[1]; | |||||
| DRW_shgroup_call_obmat(grp, geom, obmat); | |||||
| } | |||||
| else { | |||||
| pd->edit_uv.stencil_ibuf = NULL; | |||||
| pd->edit_uv.stencil_image = NULL; | |||||
| } | |||||
| } | } | ||||
| void OVERLAY_edit_uv_cache_populate(OVERLAY_Data *vedata, Object *ob) | void OVERLAY_edit_uv_cache_populate(OVERLAY_Data *vedata, Object *ob) | ||||
| { | { | ||||
| OVERLAY_StorageList *stl = vedata->stl; | OVERLAY_StorageList *stl = vedata->stl; | ||||
| OVERLAY_PrivateData *pd = stl->pd; | OVERLAY_PrivateData *pd = stl->pd; | ||||
| GPUBatch *geom; | GPUBatch *geom; | ||||
| ▲ Show 20 Lines • Show All 75 Lines • ▼ Show 20 Lines | if (pd->edit_uv.draw_type == SI_UVDT_STRETCH_AREA) { | ||||
| if (total_area > FLT_EPSILON && total_area_uv > FLT_EPSILON) { | if (total_area > FLT_EPSILON && total_area_uv > FLT_EPSILON) { | ||||
| pd->edit_uv.total_area_ratio = total_area / total_area_uv; | pd->edit_uv.total_area_ratio = total_area / total_area_uv; | ||||
| pd->edit_uv.total_area_ratio_inv = total_area_uv / total_area; | pd->edit_uv.total_area_ratio_inv = total_area_uv / total_area; | ||||
| } | } | ||||
| } | } | ||||
| BLI_freelistN(&pd->edit_uv.totals); | BLI_freelistN(&pd->edit_uv.totals); | ||||
| } | } | ||||
| static void OVERLAY_edit_uv_draw_finish(OVERLAY_Data *vedata) | |||||
| { | |||||
| OVERLAY_StorageList *stl = vedata->stl; | |||||
| OVERLAY_PrivateData *pd = stl->pd; | |||||
| if (pd->edit_uv.stencil_ibuf) { | |||||
| BKE_image_release_ibuf( | |||||
| pd->edit_uv.stencil_image, pd->edit_uv.stencil_ibuf, pd->edit_uv.stencil_lock); | |||||
| pd->edit_uv.stencil_image = NULL; | |||||
| pd->edit_uv.stencil_ibuf = NULL; | |||||
| } | |||||
| } | |||||
| void OVERLAY_edit_uv_draw(OVERLAY_Data *vedata) | void OVERLAY_edit_uv_draw(OVERLAY_Data *vedata) | ||||
| { | { | ||||
| OVERLAY_PassList *psl = vedata->psl; | OVERLAY_PassList *psl = vedata->psl; | ||||
| OVERLAY_StorageList *stl = vedata->stl; | OVERLAY_StorageList *stl = vedata->stl; | ||||
| OVERLAY_PrivateData *pd = stl->pd; | OVERLAY_PrivateData *pd = stl->pd; | ||||
| if (pd->edit_uv.do_tiled_image_border_overlay) { | if (pd->edit_uv.do_tiled_image_border_overlay) { | ||||
| DRW_draw_pass(psl->edit_uv_tiled_image_borders_ps); | DRW_draw_pass(psl->edit_uv_tiled_image_borders_ps); | ||||
| } | } | ||||
| if (pd->edit_uv.do_uv_stretching_overlay) { | if (pd->edit_uv.do_uv_stretching_overlay) { | ||||
| edit_uv_stretching_update_ratios(vedata); | edit_uv_stretching_update_ratios(vedata); | ||||
| DRW_draw_pass(psl->edit_uv_stretching_ps); | DRW_draw_pass(psl->edit_uv_stretching_ps); | ||||
| } | } | ||||
| if (pd->edit_uv.do_uv_overlay) { | if (pd->edit_uv.do_uv_overlay) { | ||||
| if (pd->edit_uv.do_faces) { | if (pd->edit_uv.do_faces) { | ||||
| DRW_draw_pass(psl->edit_uv_faces_ps); | DRW_draw_pass(psl->edit_uv_faces_ps); | ||||
| } | } | ||||
| DRW_draw_pass(psl->edit_uv_edges_ps); | DRW_draw_pass(psl->edit_uv_edges_ps); | ||||
| DRW_draw_pass(psl->edit_uv_verts_ps); | DRW_draw_pass(psl->edit_uv_verts_ps); | ||||
| } | } | ||||
| else if (pd->edit_uv.do_uv_shadow_overlay) { | else if (pd->edit_uv.do_uv_shadow_overlay) { | ||||
| DRW_draw_pass(psl->edit_uv_edges_ps); | DRW_draw_pass(psl->edit_uv_edges_ps); | ||||
| } | } | ||||
| if (pd->edit_uv.do_stencil_overlay) { | |||||
| DRW_draw_pass(psl->edit_uv_stencil_ps); | |||||
| } | |||||
| OVERLAY_edit_uv_draw_finish(vedata); | |||||
| } | } | ||||
| /* \{ */ | /* \} */ | ||||