Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source/blender/draw/intern/draw_cache_extract.h16
-rw-r--r--source/blender/draw/intern/draw_cache_extract_mesh.c26
-rw-r--r--source/blender/draw/intern/draw_cache_impl.h6
-rw-r--r--source/blender/draw/intern/draw_cache_impl_mesh.c67
-rw-r--r--source/blender/editors/uvedit/uvedit_draw.c164
-rw-r--r--source/blender/gpu/shaders/gpu_shader_2D_edituvs_stretch_vert.glsl20
6 files changed, 187 insertions, 112 deletions
diff --git a/source/blender/draw/intern/draw_cache_extract.h b/source/blender/draw/intern/draw_cache_extract.h
index 9305dc6eef7..70778ca6014 100644
--- a/source/blender/draw/intern/draw_cache_extract.h
+++ b/source/blender/draw/intern/draw_cache_extract.h
@@ -136,8 +136,8 @@ typedef enum DRWBatchFlag {
MBC_EDIT_LNOR = (1 << 6),
MBC_EDIT_FACEDOTS = (1 << 7),
MBC_EDIT_MESH_ANALYSIS = (1 << 8),
- MBC_EDITUV_FACES_STRECH_AREA = (1 << 9),
- MBC_EDITUV_FACES_STRECH_ANGLE = (1 << 10),
+ MBC_EDITUV_FACES_STRETCH_AREA = (1 << 9),
+ MBC_EDITUV_FACES_STRETCH_ANGLE = (1 << 10),
MBC_EDITUV_FACES = (1 << 11),
MBC_EDITUV_EDGES = (1 << 12),
MBC_EDITUV_VERTS = (1 << 13),
@@ -157,7 +157,7 @@ typedef enum DRWBatchFlag {
} DRWBatchFlag;
#define MBC_EDITUV \
- (MBC_EDITUV_FACES_STRECH_AREA | MBC_EDITUV_FACES_STRECH_ANGLE | MBC_EDITUV_FACES | \
+ (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)
#define FOREACH_MESH_BUFFER_CACHE(batch_cache, mbc) \
@@ -183,8 +183,8 @@ typedef struct MeshBatchCache {
GPUBatch *edit_fdots;
GPUBatch *edit_mesh_analysis;
/* Edit UVs */
- GPUBatch *edituv_faces_strech_area;
- GPUBatch *edituv_faces_strech_angle;
+ GPUBatch *edituv_faces_stretch_area;
+ GPUBatch *edituv_faces_stretch_angle;
GPUBatch *edituv_faces;
GPUBatch *edituv_edges;
GPUBatch *edituv_verts;
@@ -234,6 +234,12 @@ typedef struct MeshBatchCache {
/* Valid only if edge_detection is up to date. */
bool is_manifold;
+ /* Total areas for drawing UV Stretching. Contains the summed area in mesh
+ * space (`tot_area`) and the summed area in uv space (`tot_uvarea`).
+ *
+ * Only valid after `DRW_mesh_batch_cache_create_requested` has been called. */
+ float tot_area, tot_uv_area;
+
bool no_loose_wire;
} MeshBatchCache;
diff --git a/source/blender/draw/intern/draw_cache_extract_mesh.c b/source/blender/draw/intern/draw_cache_extract_mesh.c
index d952965de35..8bca2ad2c45 100644
--- a/source/blender/draw/intern/draw_cache_extract_mesh.c
+++ b/source/blender/draw/intern/draw_cache_extract_mesh.c
@@ -2676,7 +2676,7 @@ static void *extract_stretch_area_init(const MeshRenderData *mr, void *buf)
{
static GPUVertFormat format = {0};
if (format.attr_len == 0) {
- GPU_vertformat_attr_add(&format, "stretch", GPU_COMP_U16, 1, GPU_FETCH_INT_TO_FLOAT_UNIT);
+ GPU_vertformat_attr_add(&format, "ratio", GPU_COMP_U16, 1, GPU_FETCH_INT_TO_FLOAT_UNIT);
}
GPUVertBuf *vbo = buf;
@@ -2703,7 +2703,7 @@ BLI_INLINE float area_ratio_to_stretch(float ratio, float tot_ratio, float inv_t
static void mesh_stretch_area_finish(const MeshRenderData *mr, void *buf, void *UNUSED(data))
{
- float totarea = 0, totuvarea = 0;
+ float tot_area = 0.0f, tot_uv_area = 0.0f;
float *area_ratio = MEM_mallocN(sizeof(float) * mr->poly_len, __func__);
if (mr->extract_type == MR_EXTRACT_BMESH) {
@@ -2716,8 +2716,8 @@ static void mesh_stretch_area_finish(const MeshRenderData *mr, void *buf, void *
BM_ITER_MESH_INDEX (efa, &f_iter, mr->bm, BM_FACES_OF_MESH, f) {
float area = BM_face_calc_area(efa);
float uvarea = BM_face_calc_area_uv(efa, uv_ofs);
- totarea += area;
- totuvarea += uvarea;
+ tot_area += area;
+ tot_uv_area += uvarea;
area_ratio[f] = area_ratio_get(area, uvarea);
}
}
@@ -2727,8 +2727,8 @@ static void mesh_stretch_area_finish(const MeshRenderData *mr, void *buf, void *
for (int p = 0; p < mr->poly_len; p++, mpoly++) {
float area = BKE_mesh_calc_poly_area(mpoly, &mr->mloop[mpoly->loopstart], mr->mvert);
float uvarea = BKE_mesh_calc_poly_uv_area(mpoly, uv_data);
- totarea += area;
- totuvarea += uvarea;
+ tot_area += area;
+ tot_uv_area += uvarea;
area_ratio[p] = area_ratio_get(area, uvarea);
}
}
@@ -2737,21 +2737,13 @@ static void mesh_stretch_area_finish(const MeshRenderData *mr, void *buf, void *
BLI_assert(0);
}
- float tot_ratio, inv_tot_ratio;
- if (totarea < FLT_EPSILON || totuvarea < FLT_EPSILON) {
- tot_ratio = 0.0f;
- inv_tot_ratio = 0.0f;
- }
- else {
- tot_ratio = totarea / totuvarea;
- inv_tot_ratio = totuvarea / totarea;
- }
+ mr->cache->tot_area = tot_area;
+ mr->cache->tot_uv_area = tot_uv_area;
/* Convert in place to avoid an extra allocation */
uint16_t *poly_stretch = (uint16_t *)area_ratio;
for (int p = 0; p < mr->poly_len; p++) {
- float stretch = area_ratio_to_stretch(area_ratio[p], tot_ratio, inv_tot_ratio);
- poly_stretch[p] = (1.0f - stretch) * 65534.0f;
+ poly_stretch[p] = area_ratio[p] * 65534.0f;
}
/* Copy face data for each loop. */
diff --git a/source/blender/draw/intern/draw_cache_impl.h b/source/blender/draw/intern/draw_cache_impl.h
index 3e33346c7d8..970b6053cf9 100644
--- a/source/blender/draw/intern/draw_cache_impl.h
+++ b/source/blender/draw/intern/draw_cache_impl.h
@@ -150,8 +150,10 @@ struct GPUBatch *DRW_mesh_batch_cache_get_verts_with_select_id(struct Mesh *me);
/* Object mode Wireframe overlays */
struct GPUBatch *DRW_mesh_batch_cache_get_wireframes_face(struct Mesh *me);
/* edit-mesh UV editor */
-struct GPUBatch *DRW_mesh_batch_cache_get_edituv_faces_strech_area(struct Mesh *me);
-struct GPUBatch *DRW_mesh_batch_cache_get_edituv_faces_strech_angle(struct Mesh *me);
+struct GPUBatch *DRW_mesh_batch_cache_get_edituv_faces_stretch_area(struct Mesh *me,
+ float *tot_area,
+ float *tot_uv_area);
+struct GPUBatch *DRW_mesh_batch_cache_get_edituv_faces_stretch_angle(struct Mesh *me);
struct GPUBatch *DRW_mesh_batch_cache_get_edituv_faces(struct Mesh *me);
struct GPUBatch *DRW_mesh_batch_cache_get_edituv_edges(struct Mesh *me);
struct GPUBatch *DRW_mesh_batch_cache_get_edituv_verts(struct Mesh *me);
diff --git a/source/blender/draw/intern/draw_cache_impl_mesh.c b/source/blender/draw/intern/draw_cache_impl_mesh.c
index 456e21db6ed..96c677dc184 100644
--- a/source/blender/draw/intern/draw_cache_impl_mesh.c
+++ b/source/blender/draw/intern/draw_cache_impl_mesh.c
@@ -502,14 +502,17 @@ static void mesh_batch_cache_discard_uvedit(MeshBatchCache *cache)
GPU_INDEXBUF_DISCARD_SAFE(mbufcache->ibo.edituv_points);
GPU_INDEXBUF_DISCARD_SAFE(mbufcache->ibo.edituv_fdots);
}
- GPU_BATCH_DISCARD_SAFE(cache->batch.edituv_faces_strech_area);
- GPU_BATCH_DISCARD_SAFE(cache->batch.edituv_faces_strech_angle);
+ GPU_BATCH_DISCARD_SAFE(cache->batch.edituv_faces_stretch_area);
+ GPU_BATCH_DISCARD_SAFE(cache->batch.edituv_faces_stretch_angle);
GPU_BATCH_DISCARD_SAFE(cache->batch.edituv_faces);
GPU_BATCH_DISCARD_SAFE(cache->batch.edituv_edges);
GPU_BATCH_DISCARD_SAFE(cache->batch.edituv_verts);
GPU_BATCH_DISCARD_SAFE(cache->batch.edituv_fdots);
GPU_BATCH_DISCARD_SAFE(cache->batch.wire_loops_uvs);
+ cache->tot_area = 0.0f;
+ cache->tot_uv_area = 0.0f;
+
cache->batch_ready &= ~MBC_EDITUV;
}
@@ -577,8 +580,8 @@ void DRW_mesh_batch_cache_dirty_tag(Mesh *me, int mode)
GPU_VERTBUF_DISCARD_SAFE(mbufcache->vbo.edituv_data);
GPU_VERTBUF_DISCARD_SAFE(mbufcache->vbo.fdots_edituv_data);
}
- GPU_BATCH_DISCARD_SAFE(cache->batch.edituv_faces_strech_area);
- GPU_BATCH_DISCARD_SAFE(cache->batch.edituv_faces_strech_angle);
+ GPU_BATCH_DISCARD_SAFE(cache->batch.edituv_faces_stretch_area);
+ GPU_BATCH_DISCARD_SAFE(cache->batch.edituv_faces_stretch_angle);
GPU_BATCH_DISCARD_SAFE(cache->batch.edituv_faces);
GPU_BATCH_DISCARD_SAFE(cache->batch.edituv_edges);
GPU_BATCH_DISCARD_SAFE(cache->batch.edituv_verts);
@@ -874,20 +877,34 @@ GPUBatch *DRW_mesh_batch_cache_get_verts_with_select_id(Mesh *me)
/** \name UV Image editor API
* \{ */
-GPUBatch *DRW_mesh_batch_cache_get_edituv_faces_strech_area(Mesh *me)
+/* Creates the GPUBatch for drawing the UV Stretching Area Overlay.
+ * Optional retrieves the total area or total uv area of the mesh.
+ *
+ * The `cache->tot_area` and cache->tot_uv_area` update are calculation are
+ * only valid after calling `DRW_mesh_batch_cache_create_requested`. */
+GPUBatch *DRW_mesh_batch_cache_get_edituv_faces_stretch_area(Mesh *me,
+ float *tot_area,
+ float *tot_uv_area)
{
MeshBatchCache *cache = mesh_batch_cache_get(me);
texpaint_request_active_uv(cache, me);
- mesh_batch_cache_add_request(cache, MBC_EDITUV_FACES_STRECH_AREA);
- return DRW_batch_request(&cache->batch.edituv_faces_strech_area);
+ mesh_batch_cache_add_request(cache, MBC_EDITUV_FACES_STRETCH_AREA);
+
+ if (tot_area != NULL) {
+ *tot_area = cache->tot_area;
+ }
+ if (tot_uv_area != NULL) {
+ *tot_uv_area = cache->tot_uv_area;
+ }
+ return DRW_batch_request(&cache->batch.edituv_faces_stretch_area);
}
-GPUBatch *DRW_mesh_batch_cache_get_edituv_faces_strech_angle(Mesh *me)
+GPUBatch *DRW_mesh_batch_cache_get_edituv_faces_stretch_angle(Mesh *me)
{
MeshBatchCache *cache = mesh_batch_cache_get(me);
texpaint_request_active_uv(cache, me);
- mesh_batch_cache_add_request(cache, MBC_EDITUV_FACES_STRECH_ANGLE);
- return DRW_batch_request(&cache->batch.edituv_faces_strech_angle);
+ mesh_batch_cache_add_request(cache, MBC_EDITUV_FACES_STRETCH_ANGLE);
+ return DRW_batch_request(&cache->batch.edituv_faces_stretch_angle);
}
GPUBatch *DRW_mesh_batch_cache_get_edituv_faces(Mesh *me)
@@ -1001,8 +1018,8 @@ void DRW_mesh_batch_cache_create_requested(
}
if (batch_requested &
- (MBC_SURFACE | MBC_SURF_PER_MAT | MBC_WIRE_LOOPS_UVS | MBC_EDITUV_FACES_STRECH_AREA |
- MBC_EDITUV_FACES_STRECH_ANGLE | MBC_EDITUV_FACES | MBC_EDITUV_EDGES | MBC_EDITUV_VERTS)) {
+ (MBC_SURFACE | MBC_SURF_PER_MAT | MBC_WIRE_LOOPS_UVS | MBC_EDITUV_FACES_STRETCH_AREA |
+ MBC_EDITUV_FACES_STRETCH_ANGLE | 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) {
if (CustomData_get_layer(&me->vdata, CD_ORCO) == NULL) {
@@ -1078,8 +1095,8 @@ void DRW_mesh_batch_cache_create_requested(
/* We only clear the batches as they may already have been
* referenced. */
GPU_BATCH_CLEAR_SAFE(cache->batch.wire_loops_uvs);
- GPU_BATCH_CLEAR_SAFE(cache->batch.edituv_faces_strech_area);
- GPU_BATCH_CLEAR_SAFE(cache->batch.edituv_faces_strech_angle);
+ 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);
GPU_BATCH_CLEAR_SAFE(cache->batch.edituv_edges);
GPU_BATCH_CLEAR_SAFE(cache->batch.edituv_verts);
@@ -1261,17 +1278,17 @@ void DRW_mesh_batch_cache_create_requested(
DRW_vbo_request(cache->batch.edituv_faces, &mbufcache->vbo.uv);
DRW_vbo_request(cache->batch.edituv_faces, &mbufcache->vbo.edituv_data);
}
- if (DRW_batch_requested(cache->batch.edituv_faces_strech_area, GPU_PRIM_TRIS)) {
- DRW_ibo_request(cache->batch.edituv_faces_strech_area, &mbufcache->ibo.edituv_tris);
- DRW_vbo_request(cache->batch.edituv_faces_strech_area, &mbufcache->vbo.uv);
- DRW_vbo_request(cache->batch.edituv_faces_strech_area, &mbufcache->vbo.edituv_data);
- DRW_vbo_request(cache->batch.edituv_faces_strech_area, &mbufcache->vbo.stretch_area);
- }
- if (DRW_batch_requested(cache->batch.edituv_faces_strech_angle, GPU_PRIM_TRIS)) {
- DRW_ibo_request(cache->batch.edituv_faces_strech_angle, &mbufcache->ibo.edituv_tris);
- DRW_vbo_request(cache->batch.edituv_faces_strech_angle, &mbufcache->vbo.uv);
- DRW_vbo_request(cache->batch.edituv_faces_strech_angle, &mbufcache->vbo.edituv_data);
- DRW_vbo_request(cache->batch.edituv_faces_strech_angle, &mbufcache->vbo.stretch_angle);
+ if (DRW_batch_requested(cache->batch.edituv_faces_stretch_area, GPU_PRIM_TRIS)) {
+ DRW_ibo_request(cache->batch.edituv_faces_stretch_area, &mbufcache->ibo.edituv_tris);
+ DRW_vbo_request(cache->batch.edituv_faces_stretch_area, &mbufcache->vbo.uv);
+ DRW_vbo_request(cache->batch.edituv_faces_stretch_area, &mbufcache->vbo.edituv_data);
+ DRW_vbo_request(cache->batch.edituv_faces_stretch_area, &mbufcache->vbo.stretch_area);
+ }
+ if (DRW_batch_requested(cache->batch.edituv_faces_stretch_angle, GPU_PRIM_TRIS)) {
+ DRW_ibo_request(cache->batch.edituv_faces_stretch_angle, &mbufcache->ibo.edituv_tris);
+ DRW_vbo_request(cache->batch.edituv_faces_stretch_angle, &mbufcache->vbo.uv);
+ DRW_vbo_request(cache->batch.edituv_faces_stretch_angle, &mbufcache->vbo.edituv_data);
+ DRW_vbo_request(cache->batch.edituv_faces_stretch_angle, &mbufcache->vbo.stretch_angle);
}
if (DRW_batch_requested(cache->batch.edituv_edges, GPU_PRIM_LINES)) {
DRW_ibo_request(cache->batch.edituv_edges, &mbufcache->ibo.edituv_lines);
diff --git a/source/blender/editors/uvedit/uvedit_draw.c b/source/blender/editors/uvedit/uvedit_draw.c
index fe761f65702..89d3b155171 100644
--- a/source/blender/editors/uvedit/uvedit_draw.c
+++ b/source/blender/editors/uvedit/uvedit_draw.c
@@ -69,6 +69,17 @@
#include "uvedit_intern.h"
+/* Struct containing the needed batches per object.
+ * this optimizes the way how data is requested from
+ * the draw manager. */
+typedef struct UVEditGPUBatches {
+ Object *ob_eval;
+ GPUBatch *faces;
+ GPUBatch *edges;
+ GPUBatch *verts;
+ GPUBatch *facedots;
+} UVEditGPUBatches;
+
static int draw_uvs_face_check(const ToolSettings *ts)
{
/* checks if we are selecting only faces */
@@ -164,40 +175,45 @@ void ED_image_draw_cursor(ARegion *ar, const float cursor[2])
static void uvedit_get_batches(Object *ob,
SpaceImage *sima,
const Scene *scene,
- GPUBatch **faces,
- GPUBatch **edges,
- GPUBatch **verts,
- GPUBatch **facedots)
+ UVEditGPUBatches *batches,
+ float *tot_area,
+ float *tot_area_uv)
{
int drawfaces = draw_uvs_face_check(scene->toolsettings);
const bool draw_stretch = (sima->flag & SI_DRAW_STRETCH) != 0;
const bool draw_faces = (sima->flag & SI_NO_DRAWFACES) == 0;
DRW_mesh_batch_cache_validate(ob->data);
- *edges = DRW_mesh_batch_cache_get_edituv_edges(ob->data);
- *verts = DRW_mesh_batch_cache_get_edituv_verts(ob->data);
+ batches->edges = DRW_mesh_batch_cache_get_edituv_edges(ob->data);
+ batches->verts = DRW_mesh_batch_cache_get_edituv_verts(ob->data);
if (drawfaces) {
- *facedots = DRW_mesh_batch_cache_get_edituv_facedots(ob->data);
+ batches->facedots = DRW_mesh_batch_cache_get_edituv_facedots(ob->data);
}
else {
- *facedots = NULL;
+ batches->facedots = NULL;
}
if (draw_stretch && (sima->dt_uvstretch == SI_UVDT_STRETCH_AREA)) {
- *faces = DRW_mesh_batch_cache_get_edituv_faces_strech_area(ob->data);
+ batches->faces = DRW_mesh_batch_cache_get_edituv_faces_stretch_area(ob->data, NULL, NULL);
}
else if (draw_stretch) {
- *faces = DRW_mesh_batch_cache_get_edituv_faces_strech_angle(ob->data);
+ batches->faces = DRW_mesh_batch_cache_get_edituv_faces_stretch_angle(ob->data);
}
else if (draw_faces) {
- *faces = DRW_mesh_batch_cache_get_edituv_faces(ob->data);
+ batches->faces = DRW_mesh_batch_cache_get_edituv_faces(ob->data);
}
else {
- *faces = NULL;
+ batches->faces = NULL;
}
DRW_mesh_batch_cache_create_requested(ob, ob->data, scene, false, false);
+
+ /* after create_requested we can load the actual areas */
+ float tmp_tot_area, tmp_tot_area_uv;
+ DRW_mesh_batch_cache_get_edituv_faces_stretch_area(ob->data, &tmp_tot_area, &tmp_tot_area_uv);
+ *tot_area += tmp_tot_area;
+ *tot_area_uv += tmp_tot_area_uv;
}
static void draw_uvs_shadow(SpaceImage *UNUSED(sima),
@@ -279,10 +295,14 @@ static void draw_uvs_texpaint(Scene *scene, Object *ob, Depsgraph *depsgraph)
}
/* draws uv's in the image space */
-static void draw_uvs(SpaceImage *sima, Scene *scene, Object *obedit, Depsgraph *depsgraph)
+static void draw_uvs(SpaceImage *sima,
+ Scene *scene,
+ Depsgraph *depsgraph,
+ UVEditGPUBatches *batch,
+ float tot_area_ratio,
+ float tot_area_ratio_inv)
{
- GPUBatch *faces, *edges, *verts, *facedots;
- Object *ob_eval = DEG_get_evaluated_object(depsgraph, obedit);
+ Object *ob_eval = batch->ob_eval;
const ToolSettings *ts = scene->toolsettings;
float col1[4], col2[4], col3[4], transparent[4] = {0.0f, 0.0f, 0.0f, 0.0f};
@@ -296,12 +316,10 @@ static void draw_uvs(SpaceImage *sima, Scene *scene, Object *obedit, Depsgraph *
/* When sync selection is enabled, all faces are drawn (except for hidden)
* so if cage is the same as the final, there is no point in drawing this. */
if (!((ts->uv_flag & UV_SYNC_SELECTION) && is_cage_like_final_meshes)) {
- draw_uvs_shadow(sima, scene, obedit, depsgraph);
+ draw_uvs_shadow(sima, scene, ob_eval, depsgraph);
}
}
- uvedit_get_batches(ob_eval, sima, scene, &faces, &edges, &verts, &facedots);
-
bool interpedges;
bool draw_stretch = (sima->flag & SI_DRAW_STRETCH) != 0;
if (ts->uv_flag & UV_SYNC_SELECTION) {
@@ -314,8 +332,8 @@ static void draw_uvs(SpaceImage *sima, Scene *scene, Object *obedit, Depsgraph *
GPU_blend_set_func_separate(
GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
- if (faces) {
- GPU_batch_program_set_builtin(faces,
+ if (batch->faces) {
+ GPU_batch_program_set_builtin(batch->faces,
(draw_stretch) ? (sima->dt_uvstretch == SI_UVDT_STRETCH_AREA) ?
GPU_SHADER_2D_UV_FACES_STRETCH_AREA :
GPU_SHADER_2D_UV_FACES_STRETCH_ANGLE :
@@ -328,23 +346,27 @@ static void draw_uvs(SpaceImage *sima, Scene *scene, Object *obedit, Depsgraph *
UI_GetThemeColor4fv(TH_FACE_SELECT, col2);
UI_GetThemeColor4fv(TH_EDITMESH_ACTIVE, col3);
col3[3] *= 0.2; /* Simulate dithering */
- GPU_batch_uniform_4fv(faces, "faceColor", col1);
- GPU_batch_uniform_4fv(faces, "selectColor", col2);
- GPU_batch_uniform_4fv(faces, "activeColor", col3);
+ GPU_batch_uniform_4fv(batch->faces, "faceColor", col1);
+ GPU_batch_uniform_4fv(batch->faces, "selectColor", col2);
+ GPU_batch_uniform_4fv(batch->faces, "activeColor", col3);
}
else if (sima->dt_uvstretch == SI_UVDT_STRETCH_ANGLE) {
float asp[2];
ED_space_image_get_uv_aspect(sima, &asp[0], &asp[1]);
- GPU_batch_uniform_2fv(faces, "aspect", asp);
+ GPU_batch_uniform_2fv(batch->faces, "aspect", asp);
+ }
+ else if (sima->dt_uvstretch == SI_UVDT_STRETCH_AREA) {
+ GPU_batch_uniform_1f(batch->faces, "totalAreaRatio", tot_area_ratio);
+ GPU_batch_uniform_1f(batch->faces, "totalAreaRatioInv", tot_area_ratio_inv);
}
- GPU_batch_draw(faces);
+ GPU_batch_draw(batch->faces);
if (!draw_stretch) {
GPU_blend(false);
}
}
- if (edges) {
+ if (batch->edges) {
if (sima->flag & SI_SMOOTH_UV) {
GPU_line_smooth(true);
GPU_blend(true);
@@ -356,14 +378,16 @@ static void draw_uvs(SpaceImage *sima, Scene *scene, Object *obedit, Depsgraph *
GPU_viewport_size_get_f(viewport_size);
GPU_line_width(1.0f);
- GPU_batch_program_set_builtin(edges, GPU_SHADER_2D_LINE_DASHED_UNIFORM_COLOR);
- GPU_batch_uniform_4fv_array(edges, "colors", 2, (float *)dash_colors);
- GPU_batch_uniform_2f(
- edges, "viewport_size", viewport_size[2] / UI_DPI_FAC, viewport_size[3] / UI_DPI_FAC);
- GPU_batch_uniform_1i(edges, "colors_len", 2); /* "advanced" mode */
- GPU_batch_uniform_1f(edges, "dash_width", 4.0f);
- GPU_batch_uniform_1f(edges, "dash_factor", 0.5f);
- GPU_batch_draw(edges);
+ GPU_batch_program_set_builtin(batch->edges, GPU_SHADER_2D_LINE_DASHED_UNIFORM_COLOR);
+ GPU_batch_uniform_4fv_array(batch->edges, "colors", 2, (float *)dash_colors);
+ GPU_batch_uniform_2f(batch->edges,
+ "viewport_size",
+ viewport_size[2] / UI_DPI_FAC,
+ viewport_size[3] / UI_DPI_FAC);
+ GPU_batch_uniform_1i(batch->edges, "colors_len", 2); /* "advanced" mode */
+ GPU_batch_uniform_1f(batch->edges, "dash_width", 4.0f);
+ GPU_batch_uniform_1f(batch->edges, "dash_factor", 0.5f);
+ GPU_batch_draw(batch->edges);
break;
}
case SI_UVDT_BLACK:
@@ -376,14 +400,14 @@ static void draw_uvs(SpaceImage *sima, Scene *scene, Object *obedit, Depsgraph *
UI_GetThemeColor4fv(TH_EDGE_SELECT, col2);
GPU_batch_program_set_builtin(
- edges, (interpedges) ? GPU_SHADER_2D_UV_EDGES_SMOOTH : GPU_SHADER_2D_UV_EDGES);
+ batch->edges, (interpedges) ? GPU_SHADER_2D_UV_EDGES_SMOOTH : GPU_SHADER_2D_UV_EDGES);
if (sima->dt_uv == SI_UVDT_OUTLINE) {
/* Black Outline. */
GPU_line_width(3.0f);
- GPU_batch_uniform_4f(edges, "edgeColor", 0.0f, 0.0f, 0.0f, 1.0f);
- GPU_batch_uniform_4f(edges, "selectColor", 0.0f, 0.0f, 0.0f, 1.0f);
- GPU_batch_draw(edges);
+ GPU_batch_uniform_4f(batch->edges, "edgeColor", 0.0f, 0.0f, 0.0f, 1.0f);
+ GPU_batch_uniform_4f(batch->edges, "selectColor", 0.0f, 0.0f, 0.0f, 1.0f);
+ GPU_batch_draw(batch->edges);
UI_GetThemeColor4fv(TH_WIRE_EDIT, col1);
}
@@ -397,9 +421,9 @@ static void draw_uvs(SpaceImage *sima, Scene *scene, Object *obedit, Depsgraph *
/* Inner Line. Use depth test to insure selection is drawn on top. */
GPU_depth_test(true);
GPU_line_width(1.0f);
- GPU_batch_uniform_4fv(edges, "edgeColor", col1);
- GPU_batch_uniform_4fv(edges, "selectColor", col2);
- GPU_batch_draw(edges);
+ GPU_batch_uniform_4fv(batch->edges, "edgeColor", col1);
+ GPU_batch_uniform_4fv(batch->edges, "selectColor", col2);
+ GPU_batch_draw(batch->edges);
GPU_depth_test(false);
glProvokingVertex(GL_LAST_VERTEX_CONVENTION);
@@ -411,44 +435,44 @@ static void draw_uvs(SpaceImage *sima, Scene *scene, Object *obedit, Depsgraph *
GPU_blend(false);
}
}
- if (verts || facedots) {
+ if (batch->verts || batch->facedots) {
UI_GetThemeColor4fv(TH_VERTEX_SELECT, col2);
- if (verts) {
+ if (batch->verts) {
const float point_size = UI_GetThemeValuef(TH_VERTEX_SIZE);
const float pinned_col[4] = {1.0f, 0.0f, 0.0f, 1.0f}; /* TODO Theme? */
UI_GetThemeColor4fv(TH_VERTEX, col1);
GPU_blend(true);
GPU_program_point_size(true);
- GPU_batch_program_set_builtin(verts, GPU_SHADER_2D_UV_VERTS);
- GPU_batch_uniform_4f(verts, "vertColor", col1[0], col1[1], col1[2], 1.0f);
- GPU_batch_uniform_4fv(verts, "selectColor", transparent);
- GPU_batch_uniform_4fv(verts, "pinnedColor", pinned_col);
- GPU_batch_uniform_1f(verts, "pointSize", (point_size + 1.5f) * M_SQRT2);
- GPU_batch_uniform_1f(verts, "outlineWidth", 0.75f);
- GPU_batch_draw(verts);
+ GPU_batch_program_set_builtin(batch->verts, GPU_SHADER_2D_UV_VERTS);
+ GPU_batch_uniform_4f(batch->verts, "vertColor", col1[0], col1[1], col1[2], 1.0f);
+ GPU_batch_uniform_4fv(batch->verts, "selectColor", transparent);
+ GPU_batch_uniform_4fv(batch->verts, "pinnedColor", pinned_col);
+ GPU_batch_uniform_1f(batch->verts, "pointSize", (point_size + 1.5f) * M_SQRT2);
+ GPU_batch_uniform_1f(batch->verts, "outlineWidth", 0.75f);
+ GPU_batch_draw(batch->verts);
/* We have problem in this mode when face order make some verts
* appear unselected because an adjacent face is not selected and
* render after the selected face.
* So, to avoid sorting verts by state we just render selected verts
* on top. A bit overkill but it's simple. */
- GPU_batch_uniform_4fv(verts, "vertColor", transparent);
- GPU_batch_uniform_4fv(verts, "selectColor", col2);
- GPU_batch_draw(verts);
+ GPU_batch_uniform_4fv(batch->verts, "vertColor", transparent);
+ GPU_batch_uniform_4fv(batch->verts, "selectColor", col2);
+ GPU_batch_draw(batch->verts);
GPU_blend(false);
GPU_program_point_size(false);
}
- if (facedots) {
+ if (batch->facedots) {
const float point_size = UI_GetThemeValuef(TH_FACEDOT_SIZE);
GPU_point_size(point_size);
UI_GetThemeColor4fv(TH_WIRE, col1);
- GPU_batch_program_set_builtin(facedots, GPU_SHADER_2D_UV_FACEDOTS);
- GPU_batch_uniform_4fv(facedots, "vertColor", col1);
- GPU_batch_uniform_4fv(facedots, "selectColor", col2);
- GPU_batch_draw(facedots);
+ GPU_batch_program_set_builtin(batch->facedots, GPU_SHADER_2D_UV_FACEDOTS);
+ GPU_batch_uniform_4fv(batch->facedots, "vertColor", col1);
+ GPU_batch_uniform_4fv(batch->facedots, "selectColor", col2);
+ GPU_batch_draw(batch->facedots);
}
}
}
@@ -495,10 +519,32 @@ void ED_uvedit_draw_main(SpaceImage *sima,
GPU_clear_depth(1.0f);
GPU_clear(GPU_DEPTH_BIT);
}
+
+ /* go over all objects and create the batches + add their areas to the total */
+ UVEditGPUBatches *batches = MEM_mallocN(sizeof(UVEditGPUBatches) * objects_len, __func__);
+ float tot_area = 0.0f;
+ float tot_area_uv = 0.0f;
+ float tot_area_ratio = 0.0f;
+ float tot_area_ratio_inv = 0.0f;
+
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *ob_iter = objects[ob_index];
- draw_uvs(sima, scene, ob_iter, depsgraph);
+ Object *ob_eval = DEG_get_evaluated_object(depsgraph, ob_iter);
+ batches[ob_index].ob_eval = ob_eval;
+ uvedit_get_batches(ob_eval, sima, scene, &batches[ob_index], &tot_area, &tot_area_uv);
+ }
+
+ if (tot_area > FLT_EPSILON && tot_area_uv > FLT_EPSILON) {
+ tot_area_ratio = tot_area / tot_area_uv;
+ tot_area_ratio_inv = tot_area_uv / tot_area;
+ }
+
+ /* go over all batches created in the previous loop and draw them */
+ for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
+ UVEditGPUBatches *batch = &batches[ob_index];
+ draw_uvs(sima, scene, depsgraph, batch, tot_area_ratio, tot_area_ratio_inv);
}
+ MEM_freeN(batches);
MEM_freeN(objects);
}
else {
diff --git a/source/blender/gpu/shaders/gpu_shader_2D_edituvs_stretch_vert.glsl b/source/blender/gpu/shaders/gpu_shader_2D_edituvs_stretch_vert.glsl
index 0ce5504dfa8..b0fa9eaed21 100644
--- a/source/blender/gpu/shaders/gpu_shader_2D_edituvs_stretch_vert.glsl
+++ b/source/blender/gpu/shaders/gpu_shader_2D_edituvs_stretch_vert.glsl
@@ -4,12 +4,15 @@ uniform vec2 aspect;
in vec2 pos;
-#ifndef STRETCH_ANGLE
-in float stretch;
-#else
-
+#ifdef STRETCH_ANGLE
in vec2 uv_angles;
in float angle;
+
+#else
+in float ratio;
+uniform float totalAreaRatio;
+uniform float totalAreaRatioInv;
+
#endif
noperspective out vec4 finalColor;
@@ -69,6 +72,12 @@ float angle_normalized_v2v2(vec2 v1, vec2 v2)
return (q) ? a : M_PI - a;
}
+float area_ratio_to_stretch(float ratio, float tot_ratio, float inv_tot_ratio)
+{
+ ratio *= (ratio > 0.0f) ? tot_ratio : -inv_tot_ratio;
+ return (ratio > 1.0f) ? (1.0f / ratio) : ratio;
+}
+
void main()
{
gl_Position = ModelViewProjectionMatrix * vec4(pos, 0.0, 1.0);
@@ -80,6 +89,9 @@ void main()
float stretch = 1.0 - abs(uv_angle - angle);
stretch = stretch;
stretch = 1.0 - stretch * stretch;
+#else
+ float stretch = 1.0 - area_ratio_to_stretch(ratio, totalAreaRatio, -totalAreaRatioInv);
+
#endif
finalColor = vec4(weight_to_rgb(stretch), 1.0);