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:
authorJeroen Bakker <j.bakker@atmind.nl>2019-09-03 14:42:11 +0300
committerJeroen Bakker <j.bakker@atmind.nl>2019-09-04 09:08:27 +0300
commit64f8f7db7cce0c8923afcabb523f7400f744387e (patch)
treec60fe2a51846a9b19860fbe016d1d64cea098880 /source/blender/editors/uvedit/uvedit_draw.c
parent0cb730146b09b4a38abcc04e9d4660d6c2f43945 (diff)
Fix T63755: Area Stretching Overlay
Support for UV Stretching overlay during multi object editing. The VBO now holds the ratios per fase. In the shader these ratios will be compared against the global ratios. The global rations are created from all selected objects. The current implementation does not fit well with the draw module. The plan is to move the drawing of other spaces towards the draw manager what leads to a better fit. Currently the details on this solution is unclear but this requirement will become an attentionpoint in the future design. Reviewed By: fclem Differential Revision: https://developer.blender.org/D5665
Diffstat (limited to 'source/blender/editors/uvedit/uvedit_draw.c')
-rw-r--r--source/blender/editors/uvedit/uvedit_draw.c164
1 files changed, 105 insertions, 59 deletions
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 {