UV: add UV orientation overlay to UV editor #119329
|
@ -1579,10 +1579,10 @@ class IMAGE_PT_overlay_guides(Panel):
|
|||
layout.prop(uvedit, "tile_grid_shape", text="Tiles")
|
||||
|
||||
|
||||
class IMAGE_PT_overlay_uv_stretch(Panel):
|
||||
class IMAGE_PT_overlay_uv_color(Panel):
|
||||
bl_space_type = 'IMAGE_EDITOR'
|
||||
bl_region_type = 'HEADER'
|
||||
bl_label = "UV Stretch"
|
||||
bl_label = "UV Color"
|
||||
bl_parent_id = "IMAGE_PT_overlay"
|
||||
|
||||
@classmethod
|
||||
|
@ -1600,11 +1600,11 @@ class IMAGE_PT_overlay_uv_stretch(Panel):
|
|||
layout.active = overlay.show_overlays
|
||||
|
||||
row = layout.row(align=True)
|
||||
row.row().prop(uvedit, "show_stretch", text="")
|
||||
row.row().prop(uvedit, "show_color", text="")
|
||||
subrow = row.row()
|
||||
subrow.active = uvedit.show_stretch
|
||||
subrow.prop(uvedit, "display_stretch_type", text="")
|
||||
subrow.prop(uvedit, "stretch_opacity", text="Opacity")
|
||||
subrow.active = uvedit.show_color
|
||||
subrow.prop(uvedit, "display_color_type", text="")
|
||||
subrow.prop(uvedit, "color_opacity", text="Opacity")
|
||||
|
||||
|
||||
class IMAGE_PT_overlay_uv_edit_geometry(Panel):
|
||||
|
@ -1635,7 +1635,7 @@ class IMAGE_PT_overlay_uv_edit_geometry(Panel):
|
|||
|
||||
# Faces
|
||||
row = col.row()
|
||||
row.active = not uvedit.show_stretch
|
||||
row.active = not uvedit.show_color
|
||||
row.prop(uvedit, "show_faces", text="Faces")
|
||||
|
||||
|
||||
|
@ -1756,7 +1756,7 @@ classes = (
|
|||
IMAGE_PT_gizmo_display,
|
||||
IMAGE_PT_overlay,
|
||||
IMAGE_PT_overlay_guides,
|
||||
IMAGE_PT_overlay_uv_stretch,
|
||||
IMAGE_PT_overlay_uv_color,
|
||||
IMAGE_PT_overlay_uv_edit_geometry,
|
||||
IMAGE_PT_overlay_texture_paint,
|
||||
IMAGE_PT_overlay_image,
|
||||
|
|
|
@ -2947,13 +2947,13 @@ void blo_do_versions_400(FileData *fd, Library * /*lib*/, Main *bmain)
|
|||
}
|
||||
|
||||
if (!MAIN_VERSION_FILE_ATLEAST(bmain, 402, 4)) {
|
||||
if (!DNA_struct_member_exists(fd->filesdna, "SpaceImage", "float", "stretch_opacity")) {
|
||||
if (!DNA_struct_member_exists(fd->filesdna, "SpaceImage", "float", "color_opacity")) {
|
||||
LISTBASE_FOREACH (bScreen *, screen, &bmain->screens) {
|
||||
LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
|
||||
LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) {
|
||||
if (sl->spacetype == SPACE_IMAGE) {
|
||||
SpaceImage *sima = reinterpret_cast<SpaceImage *>(sl);
|
||||
sima->stretch_opacity = 0.9f;
|
||||
sima->color_opacity = 0.9f;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -50,6 +50,7 @@ set(SRC
|
|||
intern/mesh_extractors/extract_mesh_vbo_edituv_data.cc
|
||||
intern/mesh_extractors/extract_mesh_vbo_edituv_stretch_angle.cc
|
||||
intern/mesh_extractors/extract_mesh_vbo_edituv_stretch_area.cc
|
||||
intern/mesh_extractors/extract_mesh_vbo_edituv_nor.cc
|
||||
intern/mesh_extractors/extract_mesh_vbo_fdots_edituv_data.cc
|
||||
intern/mesh_extractors/extract_mesh_vbo_fdots_nor.cc
|
||||
intern/mesh_extractors/extract_mesh_vbo_fdots_pos.cc
|
||||
|
@ -691,6 +692,7 @@ set(GLSL_SRC
|
|||
intern/shaders/common_subdiv_vbo_edge_fac_comp.glsl
|
||||
intern/shaders/common_subdiv_vbo_edituv_strech_angle_comp.glsl
|
||||
intern/shaders/common_subdiv_vbo_edituv_strech_area_comp.glsl
|
||||
intern/shaders/common_subdiv_vbo_edituv_nor_comp.glsl
|
||||
intern/shaders/common_subdiv_vbo_lnor_comp.glsl
|
||||
intern/shaders/common_subdiv_vbo_sculpt_data_comp.glsl
|
||||
intern/shaders/common_view_clipping_lib.glsl
|
||||
|
@ -800,7 +802,7 @@ set(GLSL_SRC
|
|||
engines/overlay/shaders/overlay_edit_uv_faces_vert.glsl
|
||||
engines/overlay/shaders/overlay_edit_uv_image_mask_frag.glsl
|
||||
engines/overlay/shaders/overlay_edit_uv_image_vert.glsl
|
||||
engines/overlay/shaders/overlay_edit_uv_stretching_vert.glsl
|
||||
engines/overlay/shaders/overlay_edit_uv_color_vert.glsl
|
||||
engines/overlay/shaders/overlay_edit_uv_tiled_image_borders_vert.glsl
|
||||
engines/overlay/shaders/overlay_edit_uv_verts_frag.glsl
|
||||
engines/overlay/shaders/overlay_edit_uv_verts_vert.glsl
|
||||
|
|
|
@ -130,15 +130,15 @@ void OVERLAY_edit_uv_init(OVERLAY_Data *vedata)
|
|||
const bool do_face_dots = (ts->uv_flag & UV_SYNC_SELECTION) ?
|
||||
(ts->selectmode & SCE_SELECT_FACE) != 0 :
|
||||
(ts->uv_selectmode == UV_SELECT_FACE);
|
||||
const bool do_uvstretching_overlay = is_image_type && is_uv_editor && is_edit_mode &&
|
||||
((sima->flag & SI_DRAW_STRETCH) != 0);
|
||||
const bool do_uvcolor_overlay = is_image_type && is_uv_editor && is_edit_mode &&
|
||||
((sima->flag & SI_DRAW_COLOR) != 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_verts = show_overlays && (!do_edges_only);
|
||||
pd->edit_uv.do_faces = show_overlays && do_faces && !do_uvstretching_overlay;
|
||||
pd->edit_uv.do_faces = show_overlays && do_faces && !do_uvcolor_overlay;
|
||||
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_shadow_overlay = show_overlays && is_image_type &&
|
||||
|
@ -159,9 +159,9 @@ void OVERLAY_edit_uv_init(OVERLAY_Data *vedata)
|
|||
draw_ctx->depsgraph, &sima->mask_info.mask->id) :
|
||||
nullptr;
|
||||
|
||||
pd->edit_uv.do_uv_stretching_overlay = show_overlays && do_uvstretching_overlay;
|
||||
pd->edit_uv.do_uv_color_overlay = show_overlays && do_uvcolor_overlay;
|
||||
pd->edit_uv.uv_opacity = sima->uv_opacity;
|
||||
pd->edit_uv.stretch_opacity = sima->stretch_opacity;
|
||||
pd->edit_uv.color_opacity = sima->color_opacity;
|
||||
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.dash_length = 4.0f * UI_SCALE_FAC;
|
||||
|
@ -169,7 +169,7 @@ void OVERLAY_edit_uv_init(OVERLAY_Data *vedata)
|
|||
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 = eSpaceImage_UVDT_Stretch(sima->dt_uvstretch);
|
||||
pd->edit_uv.draw_type = eSpaceImage_UVDT_Color(sima->dt_uvcolor);
|
||||
BLI_listbase_clear(&pd->edit_uv.totals);
|
||||
pd->edit_uv.total_area_ratio = 0.0f;
|
||||
|
||||
|
@ -277,25 +277,33 @@ void OVERLAY_edit_uv_cache_init(OVERLAY_Data *vedata)
|
|||
}
|
||||
|
||||
/* uv stretching */
|
||||
if (pd->edit_uv.do_uv_stretching_overlay) {
|
||||
DRW_PASS_CREATE(psl->edit_uv_stretching_ps,
|
||||
if (pd->edit_uv.do_uv_color_overlay) {
|
||||
DRW_PASS_CREATE(psl->edit_uv_color_ps,
|
||||
DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_ALWAYS | DRW_STATE_BLEND_ALPHA);
|
||||
if (pd->edit_uv.draw_type == SI_UVDT_STRETCH_ANGLE) {
|
||||
GPUShader *sh = OVERLAY_shader_edit_uv_stretching_angle_get();
|
||||
pd->edit_uv_stretching_grp = DRW_shgroup_create(sh, psl->edit_uv_stretching_ps);
|
||||
DRW_shgroup_uniform_block(pd->edit_uv_stretching_grp, "globalsBlock", G_draw.block_ubo);
|
||||
DRW_shgroup_uniform_vec2_copy(pd->edit_uv_stretching_grp, "aspect", pd->edit_uv.uv_aspect);
|
||||
pd->edit_uv_color_grp = DRW_shgroup_create(sh, psl->edit_uv_color_ps);
|
||||
DRW_shgroup_uniform_block(pd->edit_uv_color_grp, "globalsBlock", G_draw.block_ubo);
|
||||
DRW_shgroup_uniform_vec2_copy(pd->edit_uv_color_grp, "aspect", pd->edit_uv.uv_aspect);
|
||||
DRW_shgroup_uniform_float_copy(
|
||||
pd->edit_uv_stretching_grp, "stretch_opacity", pd->edit_uv.stretch_opacity);
|
||||
pd->edit_uv_color_grp, "color_opacity", pd->edit_uv.color_opacity);
|
||||
}
|
||||
else /* SI_UVDT_STRETCH_AREA */ {
|
||||
else if (pd->edit_uv.draw_type == SI_UVDT_STRETCH_AREA) {
|
||||
GPUShader *sh = OVERLAY_shader_edit_uv_stretching_area_get();
|
||||
pd->edit_uv_stretching_grp = DRW_shgroup_create(sh, psl->edit_uv_stretching_ps);
|
||||
DRW_shgroup_uniform_block(pd->edit_uv_stretching_grp, "globalsBlock", G_draw.block_ubo);
|
||||
pd->edit_uv_color_grp = DRW_shgroup_create(sh, psl->edit_uv_color_ps);
|
||||
DRW_shgroup_uniform_block(pd->edit_uv_color_grp, "globalsBlock", G_draw.block_ubo);
|
||||
DRW_shgroup_uniform_float(
|
||||
pd->edit_uv_stretching_grp, "totalAreaRatio", &pd->edit_uv.total_area_ratio, 1);
|
||||
pd->edit_uv_color_grp, "totalAreaRatio", &pd->edit_uv.total_area_ratio, 1);
|
||||
DRW_shgroup_uniform_float_copy(
|
||||
pd->edit_uv_stretching_grp, "stretch_opacity", pd->edit_uv.stretch_opacity);
|
||||
pd->edit_uv_color_grp, "color_opacity", pd->edit_uv.color_opacity);
|
||||
}
|
||||
else /* SI_UVDT_ORIENTATION */ {
|
||||
GPUShader *sh = OVERLAY_shader_edit_uv_orientation_get();
|
||||
pd->edit_uv_color_grp = DRW_shgroup_create(sh, psl->edit_uv_color_ps);
|
||||
DRW_shgroup_uniform_block(pd->edit_uv_color_grp, "globalsBlock", G_draw.block_ubo);
|
||||
DRW_shgroup_uniform_vec2_copy(pd->edit_uv_color_grp, "aspect", pd->edit_uv.uv_aspect);
|
||||
DRW_shgroup_uniform_float_copy(
|
||||
pd->edit_uv_color_grp, "color_opacity", pd->edit_uv.color_opacity);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -475,19 +483,22 @@ static void overlay_edit_uv_cache_populate(OVERLAY_Data *vedata, Object *ob)
|
|||
}
|
||||
}
|
||||
|
||||
if (pd->edit_uv.do_uv_stretching_overlay) {
|
||||
if (pd->edit_uv.do_uv_color_overlay) {
|
||||
if (pd->edit_uv.draw_type == SI_UVDT_STRETCH_ANGLE) {
|
||||
geom = DRW_mesh_batch_cache_get_edituv_faces_stretch_angle(ob, mesh);
|
||||
}
|
||||
else /* SI_UVDT_STRETCH_AREA */ {
|
||||
else if (pd->edit_uv.draw_type == SI_UVDT_STRETCH_AREA) {
|
||||
OVERLAY_StretchingAreaTotals *totals = static_cast<OVERLAY_StretchingAreaTotals *>(
|
||||
MEM_mallocN(sizeof(OVERLAY_StretchingAreaTotals), __func__));
|
||||
BLI_addtail(&pd->edit_uv.totals, totals);
|
||||
geom = DRW_mesh_batch_cache_get_edituv_faces_stretch_area(
|
||||
ob, mesh, &totals->total_area, &totals->total_area_uv);
|
||||
}
|
||||
else /* SI_UVDT_ORIENTATION */ {
|
||||
geom = DRW_mesh_batch_cache_get_edituv_faces_orientation(ob, mesh);
|
||||
}
|
||||
if (geom) {
|
||||
DRW_shgroup_call_obmat(pd->edit_uv_stretching_grp, geom, nullptr);
|
||||
DRW_shgroup_call_obmat(pd->edit_uv_color_grp, geom, nullptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -528,7 +539,7 @@ void OVERLAY_edit_uv_cache_finish(OVERLAY_Data *vedata)
|
|||
OVERLAY_StorageList *stl = vedata->stl;
|
||||
OVERLAY_PrivateData *pd = stl->pd;
|
||||
|
||||
if (pd->edit_uv.do_uv_stretching_overlay) {
|
||||
if (pd->edit_uv.do_uv_color_overlay) {
|
||||
edit_uv_stretching_update_ratios(vedata);
|
||||
}
|
||||
}
|
||||
|
@ -566,8 +577,8 @@ void OVERLAY_edit_uv_draw(OVERLAY_Data *vedata)
|
|||
}
|
||||
}
|
||||
|
||||
if (pd->edit_uv.do_uv_stretching_overlay) {
|
||||
DRW_draw_pass(psl->edit_uv_stretching_ps);
|
||||
if (pd->edit_uv.do_uv_color_overlay) {
|
||||
DRW_draw_pass(psl->edit_uv_color_ps);
|
||||
}
|
||||
|
||||
if (pd->edit_uv.do_uv_overlay) {
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
# define USE_GEOM_SHADER_WORKAROUND 0
|
||||
#endif
|
||||
|
||||
/* Needed for eSpaceImage_UVDT_Stretch and eMaskOverlayMode */
|
||||
/* Needed for eSpaceImage_UVDT_Color and eMaskOverlayMode */
|
||||
#include "DNA_mask_types.h"
|
||||
#include "DNA_space_types.h"
|
||||
/* Forward declarations */
|
||||
|
@ -92,7 +92,7 @@ struct OVERLAY_PassList {
|
|||
DRWPass *edit_uv_edges_ps;
|
||||
DRWPass *edit_uv_verts_ps;
|
||||
DRWPass *edit_uv_faces_ps;
|
||||
DRWPass *edit_uv_stretching_ps;
|
||||
DRWPass *edit_uv_color_ps;
|
||||
DRWPass *edit_uv_tiled_image_borders_ps;
|
||||
DRWPass *edit_uv_stencil_ps;
|
||||
DRWPass *edit_uv_mask_ps;
|
||||
|
@ -274,7 +274,7 @@ struct OVERLAY_PrivateData {
|
|||
DRWShadingGroup *edit_uv_shadow_edges_grp;
|
||||
DRWShadingGroup *edit_uv_faces_grp;
|
||||
DRWShadingGroup *edit_uv_face_dots_grp;
|
||||
DRWShadingGroup *edit_uv_stretching_grp;
|
||||
DRWShadingGroup *edit_uv_color_grp;
|
||||
DRWShadingGroup *edit_curves_points_grp[2];
|
||||
DRWShadingGroup *edit_curves_lines_grp[2];
|
||||
DRWShadingGroup *extra_grid_grp;
|
||||
|
@ -383,7 +383,7 @@ struct OVERLAY_PrivateData {
|
|||
struct {
|
||||
bool do_uv_overlay;
|
||||
bool do_uv_shadow_overlay;
|
||||
bool do_uv_stretching_overlay;
|
||||
bool do_uv_color_overlay;
|
||||
bool do_tiled_image_overlay;
|
||||
bool do_tiled_image_border_overlay;
|
||||
bool do_stencil_overlay;
|
||||
|
@ -395,7 +395,7 @@ struct OVERLAY_PrivateData {
|
|||
|
||||
float uv_opacity;
|
||||
|
||||
float stretch_opacity;
|
||||
float color_opacity;
|
||||
|
||||
int image_size[2];
|
||||
float image_aspect[2];
|
||||
|
@ -407,7 +407,7 @@ struct OVERLAY_PrivateData {
|
|||
|
||||
/* stretching overlay */
|
||||
float uv_aspect[2];
|
||||
eSpaceImage_UVDT_Stretch draw_type;
|
||||
eSpaceImage_UVDT_Color draw_type;
|
||||
ListBase totals;
|
||||
float total_area_ratio;
|
||||
|
||||
|
@ -759,6 +759,7 @@ GPUShader *OVERLAY_shader_edit_uv_face_dots_get();
|
|||
GPUShader *OVERLAY_shader_edit_uv_verts_get();
|
||||
GPUShader *OVERLAY_shader_edit_uv_stretching_area_get();
|
||||
GPUShader *OVERLAY_shader_edit_uv_stretching_angle_get();
|
||||
GPUShader *OVERLAY_shader_edit_uv_orientation_get();
|
||||
GPUShader *OVERLAY_shader_edit_uv_tiled_image_borders_get();
|
||||
GPUShader *OVERLAY_shader_edit_uv_stencil_image();
|
||||
GPUShader *OVERLAY_shader_edit_uv_mask_image();
|
||||
|
|
|
@ -60,6 +60,7 @@ struct OVERLAY_Shaders {
|
|||
GPUShader *edit_uv_face_dots;
|
||||
GPUShader *edit_uv_stretching_angle;
|
||||
GPUShader *edit_uv_stretching_area;
|
||||
GPUShader *edit_uv_orientation;
|
||||
GPUShader *edit_uv_tiled_image_borders;
|
||||
GPUShader *edit_uv_stencil_image;
|
||||
GPUShader *edit_uv_mask_image;
|
||||
|
@ -1099,7 +1100,7 @@ GPUShader *OVERLAY_shader_edit_uv_stretching_area_get()
|
|||
OVERLAY_Shaders *sh_data = &e_data.sh_data[0];
|
||||
if (!sh_data->edit_uv_stretching_area) {
|
||||
sh_data->edit_uv_stretching_area = GPU_shader_create_from_info_name(
|
||||
"overlay_edit_uv_stretching_area");
|
||||
"overlay_edit_uv_color_stretching_area");
|
||||
}
|
||||
|
||||
return sh_data->edit_uv_stretching_area;
|
||||
|
@ -1110,12 +1111,23 @@ GPUShader *OVERLAY_shader_edit_uv_stretching_angle_get()
|
|||
OVERLAY_Shaders *sh_data = &e_data.sh_data[0];
|
||||
if (!sh_data->edit_uv_stretching_angle) {
|
||||
sh_data->edit_uv_stretching_angle = GPU_shader_create_from_info_name(
|
||||
"overlay_edit_uv_stretching_angle");
|
||||
"overlay_edit_uv_color_stretching_angle");
|
||||
}
|
||||
|
||||
return sh_data->edit_uv_stretching_angle;
|
||||
}
|
||||
|
||||
GPUShader *OVERLAY_shader_edit_uv_orientation_get()
|
||||
{
|
||||
OVERLAY_Shaders *sh_data = &e_data.sh_data[0];
|
||||
if (!sh_data->edit_uv_orientation) {
|
||||
sh_data->edit_uv_orientation = GPU_shader_create_from_info_name(
|
||||
"overlay_edit_uv_color_orientation");
|
||||
}
|
||||
|
||||
return sh_data->edit_uv_orientation;
|
||||
}
|
||||
|
||||
GPUShader *OVERLAY_shader_edit_uv_tiled_image_borders_get()
|
||||
{
|
||||
OVERLAY_Shaders *sh_data = &e_data.sh_data[0];
|
||||
|
|
|
@ -376,28 +376,34 @@ GPU_SHADER_CREATE_INFO(overlay_edit_uv_mask_image)
|
|||
/** \name UV Stretching
|
||||
* \{ */
|
||||
|
||||
GPU_SHADER_CREATE_INFO(overlay_edit_uv_stretching)
|
||||
GPU_SHADER_CREATE_INFO(overlay_edit_uv_color)
|
||||
.vertex_in(0, Type::VEC2, "pos")
|
||||
.push_constant(Type::VEC2, "aspect")
|
||||
.push_constant(Type::FLOAT, "stretch_opacity")
|
||||
.push_constant(Type::FLOAT, "color_opacity")
|
||||
.vertex_out(overlay_edit_nopersp_color_iface)
|
||||
.fragment_out(0, Type::VEC4, "fragColor")
|
||||
.vertex_source("overlay_edit_uv_stretching_vert.glsl")
|
||||
.vertex_source("overlay_edit_uv_color_vert.glsl")
|
||||
.fragment_source("overlay_varying_color.glsl")
|
||||
.additional_info("draw_mesh", "draw_globals");
|
||||
|
||||
GPU_SHADER_CREATE_INFO(overlay_edit_uv_stretching_area)
|
||||
GPU_SHADER_CREATE_INFO(overlay_edit_uv_color_stretching_area)
|
||||
.do_static_compilation(true)
|
||||
.define("STRETCH_AREA")
|
||||
.vertex_in(1, Type::FLOAT, "ratio")
|
||||
.push_constant(Type::FLOAT, "totalAreaRatio")
|
||||
.additional_info("overlay_edit_uv_stretching");
|
||||
.additional_info("overlay_edit_uv_color");
|
||||
|
||||
GPU_SHADER_CREATE_INFO(overlay_edit_uv_stretching_angle)
|
||||
GPU_SHADER_CREATE_INFO(overlay_edit_uv_color_stretching_angle)
|
||||
.do_static_compilation(true)
|
||||
.define("STRETCH_ANGLE")
|
||||
.vertex_in(1, Type::VEC2, "uv_angles")
|
||||
.vertex_in(2, Type::FLOAT, "angle")
|
||||
.additional_info("overlay_edit_uv_stretching");
|
||||
.additional_info("overlay_edit_uv_color");
|
||||
|
||||
GPU_SHADER_CREATE_INFO(overlay_edit_uv_color_orientation)
|
||||
.do_static_compilation(true)
|
||||
.vertex_in(1, Type::VEC3, "uv_nor")
|
||||
.additional_info("overlay_edit_uv_color");
|
||||
|
||||
/** \} */
|
||||
|
||||
|
|
|
@ -70,17 +70,18 @@ void main()
|
|||
vec3 world_pos = point_object_to_world(vec3(pos, 0.0));
|
||||
gl_Position = point_world_to_ndc(world_pos);
|
||||
|
||||
#ifdef STRETCH_ANGLE
|
||||
#if defined(STRETCH_ANGLE)
|
||||
vec2 v1 = angle_to_v2(uv_angles.x * M_PI);
|
||||
vec2 v2 = angle_to_v2(uv_angles.y * M_PI);
|
||||
float uv_angle = angle_normalized_v2v2(v1, v2) / M_PI;
|
||||
float stretch = 1.0 - abs(uv_angle - angle);
|
||||
stretch = stretch;
|
||||
stretch = 1.0 - stretch * stretch;
|
||||
float weight = 1.0 - abs(uv_angle - angle);
|
||||
weight = 1.0 - weight * weight;
|
||||
#elif defined(STRETCH_AREA)
|
||||
float weight = 1.0 - area_ratio_to_stretch(ratio, totalAreaRatio);
|
||||
#else
|
||||
float stretch = 1.0 - area_ratio_to_stretch(ratio, totalAreaRatio);
|
||||
float weight = (uv_nor.z + 1.0) / 2.0;
|
||||
|
||||
#endif
|
||||
|
||||
finalColor = vec4(weight_to_rgb(stretch), stretch_opacity);
|
||||
finalColor = vec4(weight_to_rgb(weight), color_opacity);
|
||||
}
|
|
@ -88,6 +88,7 @@ struct MeshBufferList {
|
|||
GPUVertBuf *edituv_data;
|
||||
GPUVertBuf *edituv_stretch_area;
|
||||
GPUVertBuf *edituv_stretch_angle;
|
||||
GPUVertBuf *edituv_orientation;
|
||||
GPUVertBuf *mesh_analysis;
|
||||
GPUVertBuf *fdots_pos;
|
||||
GPUVertBuf *fdots_nor;
|
||||
|
@ -143,6 +144,7 @@ struct MeshBatchList {
|
|||
/* Edit UVs */
|
||||
GPUBatch *edituv_faces_stretch_area;
|
||||
GPUBatch *edituv_faces_stretch_angle;
|
||||
GPUBatch *edituv_faces_orientation;
|
||||
GPUBatch *edituv_faces;
|
||||
GPUBatch *edituv_edges;
|
||||
GPUBatch *edituv_verts;
|
||||
|
@ -186,6 +188,7 @@ enum DRWBatchFlag {
|
|||
MBC_SKIN_ROOTS = (1u << MBC_BATCH_INDEX(edit_skin_roots)),
|
||||
MBC_EDITUV_FACES_STRETCH_AREA = (1u << MBC_BATCH_INDEX(edituv_faces_stretch_area)),
|
||||
MBC_EDITUV_FACES_STRETCH_ANGLE = (1u << MBC_BATCH_INDEX(edituv_faces_stretch_angle)),
|
||||
MBC_EDITUV_FACES_ORIENTATION = (1u << MBC_BATCH_INDEX(edituv_faces_orientation)),
|
||||
MBC_EDITUV_FACES = (1u << MBC_BATCH_INDEX(edituv_faces)),
|
||||
MBC_EDITUV_EDGES = (1u << MBC_BATCH_INDEX(edituv_edges)),
|
||||
MBC_EDITUV_VERTS = (1u << MBC_BATCH_INDEX(edituv_verts)),
|
||||
|
@ -295,8 +298,9 @@ struct MeshBatchCache {
|
|||
};
|
||||
|
||||
#define MBC_EDITUV \
|
||||
(MBC_EDITUV_FACES_STRETCH_AREA | MBC_EDITUV_FACES_STRETCH_ANGLE | MBC_EDITUV_FACES | \
|
||||
MBC_EDITUV_EDGES | MBC_EDITUV_VERTS | MBC_EDITUV_FACEDOTS | MBC_WIRE_LOOPS_UVS)
|
||||
(MBC_EDITUV_FACES_STRETCH_AREA | MBC_EDITUV_FACES_STRETCH_ANGLE | \
|
||||
MBC_EDITUV_FACES_ORIENTATION | MBC_EDITUV_FACES | MBC_EDITUV_EDGES | MBC_EDITUV_VERTS | \
|
||||
MBC_EDITUV_FACEDOTS | MBC_WIRE_LOOPS_UVS)
|
||||
|
||||
void mesh_buffer_cache_create_requested(TaskGraph *task_graph,
|
||||
MeshBatchCache &cache,
|
||||
|
|
|
@ -639,6 +639,7 @@ void mesh_buffer_cache_create_requested(TaskGraph *task_graph,
|
|||
EXTRACT_ADD_REQUESTED(vbo, edituv_data);
|
||||
EXTRACT_ADD_REQUESTED(vbo, edituv_stretch_area);
|
||||
EXTRACT_ADD_REQUESTED(vbo, edituv_stretch_angle);
|
||||
EXTRACT_ADD_REQUESTED(vbo, edituv_orientation);
|
||||
EXTRACT_ADD_REQUESTED(vbo, mesh_analysis);
|
||||
EXTRACT_ADD_REQUESTED(vbo, fdots_pos);
|
||||
EXTRACT_ADD_REQUESTED(vbo, fdots_nor);
|
||||
|
@ -868,6 +869,7 @@ void mesh_buffer_cache_create_requested_subdiv(MeshBatchCache &cache,
|
|||
EXTRACT_ADD_REQUESTED(vbo, tan);
|
||||
EXTRACT_ADD_REQUESTED(vbo, edituv_stretch_area);
|
||||
EXTRACT_ADD_REQUESTED(vbo, edituv_stretch_angle);
|
||||
EXTRACT_ADD_REQUESTED(vbo, edituv_orientation);
|
||||
EXTRACT_ADD_REQUESTED(ibo, lines_paint_mask);
|
||||
EXTRACT_ADD_REQUESTED(ibo, lines_adjacency);
|
||||
EXTRACT_ADD_REQUESTED(vbo, weights);
|
||||
|
|
|
@ -252,6 +252,7 @@ GPUBatch *DRW_mesh_batch_cache_get_edituv_faces_stretch_area(Object *object,
|
|||
float **tot_area,
|
||||
float **tot_uv_area);
|
||||
GPUBatch *DRW_mesh_batch_cache_get_edituv_faces_stretch_angle(Object *object, Mesh *mesh);
|
||||
GPUBatch *DRW_mesh_batch_cache_get_edituv_faces_orientation(Object *object, Mesh *mesh);
|
||||
GPUBatch *DRW_mesh_batch_cache_get_edituv_faces(Object *object, Mesh *mesh);
|
||||
GPUBatch *DRW_mesh_batch_cache_get_edituv_edges(Object *object, Mesh *mesh);
|
||||
GPUBatch *DRW_mesh_batch_cache_get_edituv_verts(Object *object, Mesh *mesh);
|
||||
|
|
|
@ -87,6 +87,7 @@ namespace blender::draw {
|
|||
#define _BATCH_MAP8(a, b, c, d, e, f, g, h) _BATCH_MAP7(a, b, c, d, e, f, g) | _BATCH_MAP1(h)
|
||||
#define _BATCH_MAP9(a, b, c, d, e, f, g, h, i) _BATCH_MAP8(a, b, c, d, e, f, g, h) | _BATCH_MAP1(i)
|
||||
#define _BATCH_MAP10(a, b, c, d, e, f, g, h, i, j) _BATCH_MAP9(a, b, c, d, e, f, g, h, i) | _BATCH_MAP1(j)
|
||||
#define _BATCH_MAP11(a, b, c, d, e, f, g, h, i, j, k) _BATCH_MAP10(a, b, c, d, e, f, g, h, i, j) | _BATCH_MAP1(k)
|
||||
|
||||
#define BATCH_MAP(...) VA_NARGS_CALL_OVERLOAD(_BATCH_MAP, __VA_ARGS__)
|
||||
|
||||
|
@ -112,8 +113,8 @@ static constexpr DRWBatchFlag batches_that_use_buffer(const int buffer_index)
|
|||
return MBC_SURFACE_WEIGHTS;
|
||||
case BUFFER_INDEX(vbo.uv):
|
||||
return MBC_SURFACE | MBC_EDITUV_FACES_STRETCH_AREA | MBC_EDITUV_FACES_STRETCH_ANGLE |
|
||||
MBC_EDITUV_FACES | MBC_EDITUV_EDGES | MBC_EDITUV_VERTS | MBC_WIRE_LOOPS_UVS |
|
||||
MBC_SURFACE_PER_MAT;
|
||||
MBC_EDITUV_FACES_ORIENTATION | MBC_EDITUV_FACES | MBC_EDITUV_EDGES |
|
||||
MBC_EDITUV_VERTS | MBC_WIRE_LOOPS_UVS | MBC_SURFACE_PER_MAT;
|
||||
case BUFFER_INDEX(vbo.tan):
|
||||
return MBC_SURFACE_PER_MAT;
|
||||
case BUFFER_INDEX(vbo.sculpt_data):
|
||||
|
@ -124,11 +125,13 @@ static constexpr DRWBatchFlag batches_that_use_buffer(const int buffer_index)
|
|||
return MBC_EDIT_TRIANGLES | MBC_EDIT_EDGES | MBC_EDIT_VERTICES;
|
||||
case BUFFER_INDEX(vbo.edituv_data):
|
||||
return MBC_EDITUV_FACES | MBC_EDITUV_FACES_STRETCH_AREA | MBC_EDITUV_FACES_STRETCH_ANGLE |
|
||||
MBC_EDITUV_EDGES | MBC_EDITUV_VERTS;
|
||||
MBC_EDITUV_FACES_ORIENTATION | MBC_EDITUV_EDGES | MBC_EDITUV_VERTS;
|
||||
case BUFFER_INDEX(vbo.edituv_stretch_area):
|
||||
return MBC_EDITUV_FACES_STRETCH_AREA;
|
||||
case BUFFER_INDEX(vbo.edituv_stretch_angle):
|
||||
return MBC_EDITUV_FACES_STRETCH_ANGLE;
|
||||
case BUFFER_INDEX(vbo.edituv_orientation):
|
||||
return MBC_EDITUV_FACES_ORIENTATION;
|
||||
case BUFFER_INDEX(vbo.mesh_analysis):
|
||||
return MBC_EDIT_MESH_ANALYSIS;
|
||||
case BUFFER_INDEX(vbo.fdots_pos):
|
||||
|
@ -186,7 +189,8 @@ static constexpr DRWBatchFlag batches_that_use_buffer(const int buffer_index)
|
|||
case BUFFER_INDEX(ibo.lines_adjacency):
|
||||
return MBC_EDGE_DETECTION;
|
||||
case BUFFER_INDEX(ibo.edituv_tris):
|
||||
return MBC_EDITUV_FACES | MBC_EDITUV_FACES_STRETCH_AREA | MBC_EDITUV_FACES_STRETCH_ANGLE;
|
||||
return MBC_EDITUV_FACES | MBC_EDITUV_FACES_STRETCH_AREA | MBC_EDITUV_FACES_STRETCH_ANGLE |
|
||||
MBC_EDITUV_FACES_ORIENTATION;
|
||||
case BUFFER_INDEX(ibo.edituv_lines):
|
||||
return MBC_EDITUV_EDGES | MBC_WIRE_LOOPS_UVS;
|
||||
case BUFFER_INDEX(ibo.edituv_points):
|
||||
|
@ -676,6 +680,7 @@ static void mesh_batch_cache_discard_uvedit(MeshBatchCache &cache)
|
|||
FOREACH_MESH_BUFFER_CACHE (cache, mbc) {
|
||||
GPU_VERTBUF_DISCARD_SAFE(mbc->buff.vbo.edituv_stretch_angle);
|
||||
GPU_VERTBUF_DISCARD_SAFE(mbc->buff.vbo.edituv_stretch_area);
|
||||
GPU_VERTBUF_DISCARD_SAFE(mbc->buff.vbo.edituv_orientation);
|
||||
GPU_VERTBUF_DISCARD_SAFE(mbc->buff.vbo.uv);
|
||||
GPU_VERTBUF_DISCARD_SAFE(mbc->buff.vbo.edituv_data);
|
||||
GPU_VERTBUF_DISCARD_SAFE(mbc->buff.vbo.fdots_uv);
|
||||
|
@ -687,6 +692,7 @@ static void mesh_batch_cache_discard_uvedit(MeshBatchCache &cache)
|
|||
}
|
||||
DRWBatchFlag batch_map = BATCH_MAP(vbo.edituv_stretch_angle,
|
||||
vbo.edituv_stretch_area,
|
||||
vbo.edituv_orientation,
|
||||
vbo.uv,
|
||||
vbo.edituv_data,
|
||||
vbo.fdots_uv,
|
||||
|
@ -1211,6 +1217,14 @@ GPUBatch *DRW_mesh_batch_cache_get_edituv_faces_stretch_angle(Object *object, Me
|
|||
return DRW_batch_request(&cache.batch.edituv_faces_stretch_angle);
|
||||
}
|
||||
|
||||
GPUBatch *DRW_mesh_batch_cache_get_edituv_faces_orientation(Object *object, Mesh *mesh)
|
||||
{
|
||||
MeshBatchCache &cache = *mesh_batch_cache_get(mesh);
|
||||
edituv_request_active_uv(cache, object, mesh);
|
||||
mesh_batch_cache_add_request(cache, MBC_EDITUV_FACES_ORIENTATION);
|
||||
return DRW_batch_request(&cache.batch.edituv_faces_orientation);
|
||||
}
|
||||
|
||||
GPUBatch *DRW_mesh_batch_cache_get_edituv_faces(Object *object, Mesh *mesh)
|
||||
{
|
||||
MeshBatchCache &cache = *mesh_batch_cache_get(mesh);
|
||||
|
@ -1400,9 +1414,9 @@ void DRW_mesh_batch_cache_create_requested(TaskGraph *task_graph,
|
|||
}
|
||||
}
|
||||
|
||||
if (batch_requested &
|
||||
(MBC_SURFACE | MBC_WIRE_LOOPS_UVS | MBC_EDITUV_FACES_STRETCH_AREA |
|
||||
MBC_EDITUV_FACES_STRETCH_ANGLE | MBC_EDITUV_FACES | MBC_EDITUV_EDGES | MBC_EDITUV_VERTS))
|
||||
if (batch_requested & (MBC_SURFACE | MBC_WIRE_LOOPS_UVS | MBC_EDITUV_FACES_STRETCH_AREA |
|
||||
MBC_EDITUV_FACES_STRETCH_ANGLE | MBC_EDITUV_FACES_ORIENTATION |
|
||||
MBC_EDITUV_FACES | MBC_EDITUV_EDGES | MBC_EDITUV_VERTS))
|
||||
{
|
||||
/* Modifiers will only generate an orco layer if the mesh is deformed. */
|
||||
if (cache.cd_needed.orco != 0) {
|
||||
|
@ -1481,6 +1495,7 @@ void DRW_mesh_batch_cache_create_requested(TaskGraph *task_graph,
|
|||
GPU_BATCH_CLEAR_SAFE(cache.batch.wire_loops_uvs);
|
||||
GPU_BATCH_CLEAR_SAFE(cache.batch.edituv_faces_stretch_area);
|
||||
GPU_BATCH_CLEAR_SAFE(cache.batch.edituv_faces_stretch_angle);
|
||||
GPU_BATCH_CLEAR_SAFE(cache.batch.edituv_faces_orientation);
|
||||
GPU_BATCH_CLEAR_SAFE(cache.batch.edituv_faces);
|
||||
GPU_BATCH_CLEAR_SAFE(cache.batch.edituv_edges);
|
||||
GPU_BATCH_CLEAR_SAFE(cache.batch.edituv_verts);
|
||||
|
@ -1779,6 +1794,17 @@ void DRW_mesh_batch_cache_create_requested(TaskGraph *task_graph,
|
|||
DRW_vbo_request(cache.batch.edituv_faces_stretch_angle, &mbuflist->vbo.edituv_data);
|
||||
DRW_vbo_request(cache.batch.edituv_faces_stretch_angle, &mbuflist->vbo.edituv_stretch_angle);
|
||||
}
|
||||
assert_deps_valid(MBC_EDITUV_FACES_ORIENTATION,
|
||||
{BUFFER_INDEX(ibo.edituv_tris),
|
||||
BUFFER_INDEX(vbo.uv),
|
||||
BUFFER_INDEX(vbo.edituv_data),
|
||||
BUFFER_INDEX(vbo.edituv_orientation)});
|
||||
if (DRW_batch_requested(cache.batch.edituv_faces_orientation, GPU_PRIM_TRIS)) {
|
||||
DRW_ibo_request(cache.batch.edituv_faces_orientation, &mbuflist->ibo.edituv_tris);
|
||||
DRW_vbo_request(cache.batch.edituv_faces_orientation, &mbuflist->vbo.uv);
|
||||
DRW_vbo_request(cache.batch.edituv_faces_orientation, &mbuflist->vbo.edituv_data);
|
||||
DRW_vbo_request(cache.batch.edituv_faces_orientation, &mbuflist->vbo.edituv_orientation);
|
||||
}
|
||||
assert_deps_valid(
|
||||
MBC_EDITUV_EDGES,
|
||||
{BUFFER_INDEX(ibo.edituv_lines), BUFFER_INDEX(vbo.uv), BUFFER_INDEX(vbo.edituv_data)});
|
||||
|
@ -1838,6 +1864,7 @@ void DRW_mesh_batch_cache_create_requested(TaskGraph *task_graph,
|
|||
assert_final_deps_valid(BUFFER_INDEX(vbo.edituv_data));
|
||||
assert_final_deps_valid(BUFFER_INDEX(vbo.edituv_stretch_area));
|
||||
assert_final_deps_valid(BUFFER_INDEX(vbo.edituv_stretch_angle));
|
||||
assert_final_deps_valid(BUFFER_INDEX(vbo.edituv_orientation));
|
||||
assert_final_deps_valid(BUFFER_INDEX(vbo.fdots_uv));
|
||||
assert_final_deps_valid(BUFFER_INDEX(vbo.fdots_edituv_data));
|
||||
for (const int i : IndexRange(GPU_MAX_ATTR)) {
|
||||
|
|
|
@ -59,6 +59,7 @@ extern "C" char datatoc_common_subdiv_vbo_lnor_comp_glsl[];
|
|||
extern "C" char datatoc_common_subdiv_vbo_sculpt_data_comp_glsl[];
|
||||
extern "C" char datatoc_common_subdiv_vbo_edituv_strech_angle_comp_glsl[];
|
||||
extern "C" char datatoc_common_subdiv_vbo_edituv_strech_area_comp_glsl[];
|
||||
extern "C" char datatoc_common_subdiv_vbo_edituv_nor_comp_glsl[];
|
||||
|
||||
namespace blender::draw {
|
||||
|
||||
|
@ -84,6 +85,7 @@ enum {
|
|||
SHADER_BUFFER_SCULPT_DATA,
|
||||
SHADER_BUFFER_UV_STRETCH_ANGLE,
|
||||
SHADER_BUFFER_UV_STRETCH_AREA,
|
||||
SHADER_BUFFER_UV_ORIENTATION,
|
||||
|
||||
NUM_SHADERS,
|
||||
};
|
||||
|
@ -140,6 +142,9 @@ static const char *get_shader_code(int shader_type)
|
|||
case SHADER_BUFFER_UV_STRETCH_AREA: {
|
||||
return datatoc_common_subdiv_vbo_edituv_strech_area_comp_glsl;
|
||||
}
|
||||
case SHADER_BUFFER_UV_ORIENTATION: {
|
||||
return datatoc_common_subdiv_vbo_edituv_nor_comp_glsl;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -205,6 +210,9 @@ static const char *get_shader_name(int shader_type)
|
|||
case SHADER_BUFFER_UV_STRETCH_AREA: {
|
||||
return "subdiv uv stretch area";
|
||||
}
|
||||
case SHADER_BUFFER_UV_ORIENTATION: {
|
||||
return "subdiv uv orientation";
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -1983,6 +1991,31 @@ void draw_subdiv_build_edituv_stretch_angle_buffer(const DRWSubdivCache &cache,
|
|||
GPU_shader_unbind();
|
||||
}
|
||||
|
||||
void draw_subdiv_build_edituv_orientation_buffer(const DRWSubdivCache &cache,
|
||||
GPUVertBuf *uvs,
|
||||
int uvs_offset,
|
||||
GPUVertBuf *orientations)
|
||||
{
|
||||
GPUShader *shader = get_subdiv_shader(SHADER_BUFFER_UV_ORIENTATION);
|
||||
GPU_shader_bind(shader);
|
||||
|
||||
int binding_point = 0;
|
||||
/* Inputs */
|
||||
GPU_vertbuf_bind_as_ssbo(uvs, binding_point++);
|
||||
|
||||
/* Outputs */
|
||||
GPU_vertbuf_bind_as_ssbo(orientations, binding_point++);
|
||||
BLI_assert(binding_point <= MAX_GPU_SUBDIV_SSBOS);
|
||||
|
||||
drw_subdiv_compute_dispatch(cache, shader, uvs_offset, 0, cache.num_subdiv_quads);
|
||||
|
||||
/* This generates a vertex buffer, so we need to put a barrier on the vertex attribute array. */
|
||||
GPU_memory_barrier(GPU_BARRIER_VERTEX_ATTRIB_ARRAY);
|
||||
|
||||
/* Cleanup. */
|
||||
GPU_shader_unbind();
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
|
|
|
@ -294,6 +294,11 @@ void draw_subdiv_build_edituv_stretch_angle_buffer(const DRWSubdivCache &cache,
|
|||
int uvs_offset,
|
||||
GPUVertBuf *stretch_angles);
|
||||
|
||||
void draw_subdiv_build_edituv_orientation_buffer(const DRWSubdivCache &cache,
|
||||
GPUVertBuf *uvs,
|
||||
int uvs_offset,
|
||||
GPUVertBuf *orientations);
|
||||
|
||||
/** Return the format used for the positions and normals VBO. */
|
||||
GPUVertFormat *draw_subdiv_get_pos_nor_format();
|
||||
|
||||
|
|
|
@ -362,6 +362,7 @@ extern const MeshExtract extract_edit_data;
|
|||
extern const MeshExtract extract_edituv_data;
|
||||
extern const MeshExtract extract_edituv_stretch_area;
|
||||
extern const MeshExtract extract_edituv_stretch_angle;
|
||||
extern const MeshExtract extract_edituv_orientation;
|
||||
extern const MeshExtract extract_mesh_analysis;
|
||||
extern const MeshExtract extract_fdots_pos;
|
||||
extern const MeshExtract extract_fdots_nor;
|
||||
|
|
|
@ -0,0 +1,202 @@
|
|||
/* SPDX-FileCopyrightText: 2021 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/** \file
|
||||
* \ingroup draw
|
||||
*/
|
||||
|
||||
#include "MEM_guardedalloc.h"
|
||||
|
||||
#include "BKE_mesh.hh"
|
||||
|
||||
#include "BKE_editmesh.hh"
|
||||
|
||||
#include "BLI_math_vector_types.hh"
|
||||
|
||||
#include "extract_mesh.hh"
|
||||
|
||||
#include "draw_subdivision.hh"
|
||||
|
||||
namespace blender::draw {
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
/** \name Extract Edit UV normals
|
||||
* \{ */
|
||||
|
||||
struct MeshExtract_UVNormal_Data {
|
||||
float3 *vbo_data;
|
||||
const float2 *uv;
|
||||
int cd_ofs;
|
||||
};
|
||||
|
||||
static void extract_edituv_uv_nor_init(const MeshRenderData &mr,
|
||||
MeshBatchCache & /*cache*/,
|
||||
void *buf,
|
||||
void *tls_data)
|
||||
{
|
||||
GPUVertBuf *vbo = static_cast<GPUVertBuf *>(buf);
|
||||
static GPUVertFormat format = {0};
|
||||
if (format.attr_len == 0) {
|
||||
GPU_vertformat_attr_add(&format, "uv_nor", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
|
||||
}
|
||||
|
||||
GPU_vertbuf_init_with_format(vbo, &format);
|
||||
GPU_vertbuf_data_alloc(vbo, mr.loop_len);
|
||||
|
||||
MeshExtract_UVNormal_Data *data = static_cast<MeshExtract_UVNormal_Data *>(tls_data);
|
||||
data->vbo_data = (float3 *)GPU_vertbuf_get_data(vbo);
|
||||
|
||||
/* Special iterator needed to save about half of the computing cost. */
|
||||
if (mr.extract_type == MR_EXTRACT_BMESH) {
|
||||
data->cd_ofs = CustomData_get_offset(&mr.bm->ldata, CD_PROP_FLOAT2);
|
||||
}
|
||||
else {
|
||||
BLI_assert(mr.extract_type == MR_EXTRACT_MESH);
|
||||
data->uv = (const float2 *)CustomData_get_layer(&mr.mesh->corner_data, CD_PROP_FLOAT2);
|
||||
}
|
||||
}
|
||||
|
||||
static void extract_edituv_uv_nor_iter_face_bm(const MeshRenderData &mr,
|
||||
const BMFace *f,
|
||||
const int f_index,
|
||||
void *_data)
|
||||
{
|
||||
MeshExtract_UVNormal_Data *data = static_cast<MeshExtract_UVNormal_Data *>(_data);
|
||||
int tri_first_index_real = poly_to_tri_count(f_index, BM_elem_index_get(f->l_first));
|
||||
|
||||
for (int i = 0; i < f->len; i++) {
|
||||
data->vbo_data[BM_elem_index_get(f->l_first) + i] = {0.0f, 0.0f, -1.0f};
|
||||
}
|
||||
|
||||
BMLoop *(*looptris)[3] = mr.edit_bmesh->looptris;
|
||||
int tri_len = f->len - 2;
|
||||
for (int offs = 0; offs < tri_len; offs++) {
|
||||
BMLoop **elt = looptris[tri_first_index_real + offs];
|
||||
const float(*luv_0)[2], (*luv_1)[2], (*luv_2)[2];
|
||||
luv_0 = BM_ELEM_CD_GET_FLOAT2_P(elt[0], data->cd_ofs);
|
||||
luv_1 = BM_ELEM_CD_GET_FLOAT2_P(elt[1], data->cd_ofs);
|
||||
luv_2 = BM_ELEM_CD_GET_FLOAT2_P(elt[2], data->cd_ofs);
|
||||
|
||||
float3 e1 = {luv_0[0][0] - luv_1[0][0], luv_0[0][1] - luv_1[0][1], 0.0f};
|
||||
float3 e2 = {luv_2[0][0] - luv_0[0][0], luv_2[0][1] - luv_0[0][1], 0.0f};
|
||||
|
||||
float3 normal = {e1[1] * e2[2] - e1[2] * e2[1],
|
||||
e1[2] * e2[0] - e1[0] * e2[2],
|
||||
e1[0] * e2[1] - e1[1] * e2[0]};
|
||||
normalize_v3(normal);
|
||||
if (normal.z > 0.0f) {
|
||||
data->vbo_data[BM_elem_index_get(elt[0])] = normal;
|
||||
data->vbo_data[BM_elem_index_get(elt[1])] = normal;
|
||||
data->vbo_data[BM_elem_index_get(elt[2])] = normal;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void extract_edituv_uv_nor_iter_face_mesh(const MeshRenderData &mr,
|
||||
const int face_index,
|
||||
void *_data)
|
||||
{
|
||||
MeshExtract_UVNormal_Data *data = static_cast<MeshExtract_UVNormal_Data *>(_data);
|
||||
const IndexRange face = mr.faces[face_index];
|
||||
|
||||
int face_end = face.start() + face.size();
|
||||
for (int i = face.start(); i < face_end; i++) {
|
||||
data->vbo_data[i] = {0.0f, 0.0f, -1.0f};
|
||||
}
|
||||
|
||||
int tri_first_index_real = poly_to_tri_count(face_index, face.start());
|
||||
int tri_len = face.size() - 2;
|
||||
for (int offs = 0; offs < tri_len; offs++) {
|
||||
const int3 &tri = mr.corner_tris[tri_first_index_real + offs];
|
||||
float2 luv_0 = data->uv[tri[0]];
|
||||
float2 luv_1 = data->uv[tri[1]];
|
||||
float2 luv_2 = data->uv[tri[2]];
|
||||
|
||||
float3 e1 = {luv_0[0] - luv_1[0], luv_0[1] - luv_1[1], 0.0f};
|
||||
float3 e2 = {luv_2[0] - luv_0[0], luv_2[1] - luv_0[1], 0.0f};
|
||||
|
||||
float3 normal = {e1[1] * e2[2] - e1[2] * e2[1],
|
||||
e1[2] * e2[0] - e1[0] * e2[2],
|
||||
e1[0] * e2[1] - e1[1] * e2[0]};
|
||||
normalize_v3(normal);
|
||||
if (normal.z > 0.0f) {
|
||||
data->vbo_data[tri[0]] = normal;
|
||||
data->vbo_data[tri[1]] = normal;
|
||||
data->vbo_data[tri[2]] = normal;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static GPUVertFormat *get_edituv_stretch_uv_nor_subdiv()
|
||||
{
|
||||
static GPUVertFormat format = {0};
|
||||
if (format.attr_len == 0) {
|
||||
GPU_vertformat_attr_add(&format, "uv_nor", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
|
||||
}
|
||||
return &format;
|
||||
}
|
||||
|
||||
static void extract_edituv_uv_nor_init_subdiv(const DRWSubdivCache &subdiv_cache,
|
||||
const MeshRenderData &mr,
|
||||
MeshBatchCache &cache,
|
||||
void *buffer,
|
||||
void * /*tls_data*/)
|
||||
{
|
||||
GPUVertBuf *refined_vbo = static_cast<GPUVertBuf *>(buffer);
|
||||
|
||||
GPU_vertbuf_init_build_on_device(
|
||||
refined_vbo, get_edituv_stretch_uv_nor_subdiv(), subdiv_cache.num_subdiv_loops);
|
||||
|
||||
GPUVertBuf *uvs = cache.final.buff.vbo.uv;
|
||||
|
||||
/* UVs are stored contiguously so we need to compute the offset in the UVs buffer for the active
|
||||
* UV layer. */
|
||||
CustomData *cd_ldata = (mr.extract_type == MR_EXTRACT_MESH) ? &mr.mesh->corner_data :
|
||||
&mr.bm->ldata;
|
||||
|
||||
uint32_t uv_layers = cache.cd_used.uv;
|
||||
/* HACK to fix #68857 */
|
||||
if (mr.extract_type == MR_EXTRACT_BMESH && cache.cd_used.edit_uv == 1) {
|
||||
int layer = CustomData_get_active_layer(cd_ldata, CD_PROP_FLOAT2);
|
||||
if (layer != -1 && !CustomData_layer_is_anonymous(cd_ldata, CD_PROP_FLOAT2, layer)) {
|
||||
uv_layers |= (1 << layer);
|
||||
}
|
||||
}
|
||||
|
||||
int uvs_offset = 0;
|
||||
for (int i = 0; i < MAX_MTFACE; i++) {
|
||||
if (uv_layers & (1 << i)) {
|
||||
if (i == CustomData_get_active_layer(cd_ldata, CD_PROP_FLOAT2)) {
|
||||
break;
|
||||
}
|
||||
|
||||
uvs_offset += 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* The data is at `offset * num loops`, and we have 2 values per index. */
|
||||
uvs_offset *= subdiv_cache.num_subdiv_loops * 2;
|
||||
|
||||
draw_subdiv_build_edituv_orientation_buffer(subdiv_cache, uvs, uvs_offset, refined_vbo);
|
||||
}
|
||||
|
||||
constexpr MeshExtract create_extractor_edituv_orientation()
|
||||
{
|
||||
MeshExtract extractor = {nullptr};
|
||||
extractor.init = extract_edituv_uv_nor_init;
|
||||
extractor.iter_face_bm = extract_edituv_uv_nor_iter_face_bm;
|
||||
extractor.iter_face_mesh = extract_edituv_uv_nor_iter_face_mesh;
|
||||
extractor.init_subdiv = extract_edituv_uv_nor_init_subdiv;
|
||||
extractor.data_type = MR_DATA_NONE;
|
||||
extractor.data_size = sizeof(MeshExtract_UVNormal_Data);
|
||||
extractor.use_threading = false;
|
||||
extractor.mesh_buffer_offset = offsetof(MeshBufferList, vbo.edituv_orientation);
|
||||
return extractor;
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
const MeshExtract extract_edituv_orientation = create_extractor_edituv_orientation();
|
||||
|
||||
} // namespace blender::draw
|
|
@ -0,0 +1,58 @@
|
|||
/* SPDX-FileCopyrightText: 2021-2023 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/* To be compiled with common_subdiv_lib.glsl */
|
||||
|
||||
layout(std430, binding = 0) readonly buffer inputUVs
|
||||
{
|
||||
vec2 uvs[];
|
||||
};
|
||||
|
||||
layout(std430, binding = 1) writeonly buffer outputNormals
|
||||
{
|
||||
vec3 uv_normals[];
|
||||
};
|
||||
|
||||
void main()
|
||||
{
|
||||
/* We execute for each quad. */
|
||||
uint quad_index = get_global_invocation_index();
|
||||
if (quad_index >= total_dispatch_size) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* The start index of the loop is quad_index * 4. */
|
||||
uint start_loop_index = quad_index * 4;
|
||||
|
||||
uint triangle_loop_index = quad_index * 6;
|
||||
|
||||
uint loop_0 = start_loop_index;
|
||||
uint loop_1 = start_loop_index + 1;
|
||||
uint loop_2 = start_loop_index + 2;
|
||||
uint loop_3 = start_loop_index + 3;
|
||||
|
||||
vec2 luv_0= uvs[src_offset + loop_0];
|
||||
vec2 luv_1= uvs[src_offset + loop_1];
|
||||
vec2 luv_2= uvs[src_offset + loop_2];
|
||||
vec2 luv_3= uvs[src_offset + loop_3];
|
||||
|
||||
vec3 e1 = vec3(luv_0 - luv_1, 0.0);
|
||||
vec3 e2 = vec3(luv_2 - luv_0, 0.0);
|
||||
vec3 e3 = vec3(luv_3 - luv_2, 0.0);
|
||||
|
||||
vec3 normal_1 = normalize(cross(e1, e2));
|
||||
vec3 normal_2 = normalize(cross(e2, e3));
|
||||
|
||||
uv_normals[loop_1] = normal_1;
|
||||
uv_normals[loop_3] = normal_2;
|
||||
if (normal_1.z > 0.0) {
|
||||
uv_normals[loop_0] = normal_1;
|
||||
uv_normals[loop_2] = normal_1;
|
||||
}
|
||||
else {
|
||||
uv_normals[loop_0] = normal_2;
|
||||
uv_normals[loop_2] = normal_2;
|
||||
|
||||
}
|
||||
}
|
|
@ -101,7 +101,7 @@ static SpaceLink *image_create(const ScrArea * /*area*/, const Scene * /*scene*/
|
|||
simage->lock = true;
|
||||
simage->flag = SI_SHOW_GPENCIL | SI_USE_ALPHA | SI_COORDFLOATS;
|
||||
simage->uv_opacity = 1.0f;
|
||||
simage->stretch_opacity = 1.0f;
|
||||
simage->color_opacity = 1.0f;
|
||||
simage->overlay.flag = SI_OVERLAY_SHOW_OVERLAYS | SI_OVERLAY_SHOW_GRID_BACKGROUND;
|
||||
|
||||
BKE_imageuser_default(&simage->iuser);
|
||||
|
|
|
@ -1261,7 +1261,7 @@ typedef struct SpaceImage {
|
|||
/** UV draw type. */
|
||||
char dt_uv;
|
||||
/** Sticky selection type. */
|
||||
char dt_uvstretch;
|
||||
char dt_uvcolor;
|
||||
char around;
|
||||
|
||||
char gizmo_flag;
|
||||
|
@ -1273,7 +1273,7 @@ typedef struct SpaceImage {
|
|||
|
||||
float uv_opacity;
|
||||
|
||||
float stretch_opacity;
|
||||
float color_opacity;
|
||||
|
||||
int tile_grid_shape[2];
|
||||
/**
|
||||
|
@ -1294,11 +1294,12 @@ typedef enum eSpaceImage_UVDT {
|
|||
SI_UVDT_WHITE = 3,
|
||||
} eSpaceImage_UVDT;
|
||||
|
||||
/** #SpaceImage.dt_uvstretch */
|
||||
typedef enum eSpaceImage_UVDT_Stretch {
|
||||
/** #SpaceImage.dt_uvcolor */
|
||||
typedef enum eSpaceImage_UVDT_Color {
|
||||
SI_UVDT_STRETCH_ANGLE = 0,
|
||||
SI_UVDT_STRETCH_AREA = 1,
|
||||
} eSpaceImage_UVDT_Stretch;
|
||||
SI_UVDT_ORIENTATION = 2,
|
||||
} eSpaceImage_UVDT_Color;
|
||||
|
||||
/** #SpaceImage.pixel_round_mode */
|
||||
typedef enum eSpaceImage_PixelRoundMode {
|
||||
|
@ -1347,7 +1348,7 @@ typedef enum eSpaceImage_Flag {
|
|||
*/
|
||||
SI_DRAW_TILE = (1 << 19),
|
||||
SI_FLAG_UNUSED_20 = (1 << 20), /* cleared */
|
||||
SI_DRAW_STRETCH = (1 << 21),
|
||||
SI_DRAW_COLOR = (1 << 21),
|
||||
SI_SHOW_GPENCIL = (1 << 22),
|
||||
SI_FLAG_UNUSED_23 = (1 << 23), /* cleared */
|
||||
|
||||
|
|
|
@ -3618,9 +3618,24 @@ static void rna_def_space_image_uv(BlenderRNA *brna)
|
|||
StructRNA *srna;
|
||||
PropertyRNA *prop;
|
||||
|
||||
static const EnumPropertyItem dt_uvstretch_items[] = {
|
||||
{SI_UVDT_STRETCH_ANGLE, "ANGLE", 0, "Angle", "Angular distortion between UV and 3D angles"},
|
||||
{SI_UVDT_STRETCH_AREA, "AREA", 0, "Area", "Area distortion between UV and 3D faces"},
|
||||
static const EnumPropertyItem dt_uvcolor_items[] = {
|
||||
{SI_UVDT_STRETCH_ANGLE,
|
||||
"ANGLE",
|
||||
0,
|
||||
"Angle Stretch",
|
||||
"Angular distortion between UV and 3D angles (blue for low distortion, red for high "
|
||||
"distortion)"},
|
||||
{SI_UVDT_STRETCH_AREA,
|
||||
"AREA",
|
||||
0,
|
||||
"Area Stretch",
|
||||
"Area distortion between UV and 3D faces (blue for low distortion, red for high "
|
||||
"distortion)"},
|
||||
{SI_UVDT_ORIENTATION,
|
||||
"UV_ORIENTATION",
|
||||
0,
|
||||
"UV Orientation",
|
||||
"Orientation of UVs (blue for negative, red for positive)"},
|
||||
{0, nullptr, 0, nullptr, nullptr},
|
||||
};
|
||||
|
||||
|
@ -3651,8 +3666,8 @@ static void rna_def_space_image_uv(BlenderRNA *brna)
|
|||
RNA_def_property_ui_text(prop, "Display As", "Display style for UV edges");
|
||||
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_IMAGE, nullptr);
|
||||
|
||||
prop = RNA_def_property(srna, "show_stretch", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, nullptr, "flag", SI_DRAW_STRETCH);
|
||||
prop = RNA_def_property(srna, "show_color", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, nullptr, "flag", SI_DRAW_COLOR);
|
||||
RNA_def_property_ui_text(
|
||||
prop,
|
||||
"Display Stretch",
|
||||
|
@ -3660,10 +3675,10 @@ static void rna_def_space_image_uv(BlenderRNA *brna)
|
|||
"their 3D coordinates (blue for low distortion, red for high distortion)");
|
||||
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_IMAGE, nullptr);
|
||||
|
||||
prop = RNA_def_property(srna, "display_stretch_type", PROP_ENUM, PROP_NONE);
|
||||
RNA_def_property_enum_sdna(prop, nullptr, "dt_uvstretch");
|
||||
RNA_def_property_enum_items(prop, dt_uvstretch_items);
|
||||
RNA_def_property_ui_text(prop, "Display Stretch Type", "Type of stretch to display");
|
||||
prop = RNA_def_property(srna, "display_color_type", PROP_ENUM, PROP_NONE);
|
||||
RNA_def_property_enum_sdna(prop, nullptr, "dt_uvcolor");
|
||||
RNA_def_property_enum_items(prop, dt_uvcolor_items);
|
||||
RNA_def_property_ui_text(prop, "Display Color Overlay Type", "Type of color overlay to display");
|
||||
RNA_def_property_translation_context(prop, BLT_I18NCONTEXT_ID_MESH);
|
||||
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_IMAGE, nullptr);
|
||||
|
||||
|
@ -3732,10 +3747,10 @@ static void rna_def_space_image_uv(BlenderRNA *brna)
|
|||
RNA_def_property_ui_text(prop, "UV Opacity", "Opacity of UV overlays");
|
||||
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_IMAGE, nullptr);
|
||||
|
||||
prop = RNA_def_property(srna, "stretch_opacity", PROP_FLOAT, PROP_FACTOR);
|
||||
RNA_def_property_float_sdna(prop, nullptr, "stretch_opacity");
|
||||
prop = RNA_def_property(srna, "color_opacity", PROP_FLOAT, PROP_FACTOR);
|
||||
RNA_def_property_float_sdna(prop, nullptr, "color_opacity");
|
||||
RNA_def_property_range(prop, 0.0f, 1.0f);
|
||||
RNA_def_property_ui_text(prop, "Stretch Opacity", "Opacity of the UV Stretch overlay");
|
||||
RNA_def_property_ui_text(prop, "Color Opacity", "Opacity of the UV Color overlay");
|
||||
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_IMAGE, nullptr);
|
||||
|
||||
prop = RNA_def_property(srna, "pixel_round_mode", PROP_ENUM, PROP_NONE);
|
||||
|
|
Loading…
Reference in New Issue