Object Mode: Make Flat object outline visible in orthographic view

This commit is contained in:
Clément Foucault 2018-09-14 18:30:26 +02:00
parent 5feb03c3ae
commit b62d140be9
Notes: blender-bot 2023-02-14 06:42:53 +01:00
Referenced by issue #56549, Plane/Thin feature invisible in orthographic view.
4 changed files with 73 additions and 2 deletions

View File

@ -30,6 +30,7 @@
#include "UI_resources.h"
#include "BKE_object.h"
#include "BKE_global.h"
#include "BKE_colorband.h"
@ -882,3 +883,42 @@ float *DRW_color_background_blend_get(int theme_id)
return ret;
}
bool DRW_object_is_flat(Object *ob, int *axis)
{
float dim[3];
if (!ELEM(ob->type, OB_MESH, OB_CURVE, OB_SURF, OB_FONT, OB_MBALL)) {
/* Non-meshes object cannot be considered as flat. */
return false;
}
BKE_object_dimensions_get(ob, dim);
if (dim[0] == 0.0f) {
*axis = 0;
return true;
}
else if (dim[1] == 0.0f) {
*axis = 1;
return true;
}
else if (dim[2] == 0.0f) {
*axis = 2;
return true;
}
return false;
}
bool DRW_object_axis_orthogonal_to_view(Object *ob, int axis)
{
float ob_rot[3][3], invviewmat[4][4];
DRW_viewport_matrix_get(invviewmat, DRW_MAT_VIEWINV);
BKE_object_rot_to_mat3(ob, ob_rot, true);
float dot = dot_v3v3(ob_rot[axis], invviewmat[2]);
if (fabsf(dot) < 1e-3) {
return true;
}
return false;
}

View File

@ -153,6 +153,9 @@ int DRW_object_wire_theme_get(
struct Object *ob, struct ViewLayer *view_layer, float **r_color);
float *DRW_color_background_blend_get(int theme_id);
bool DRW_object_is_flat(Object *ob, int *axis);
bool DRW_object_axis_orthogonal_to_view(Object *ob, int axis);
/* draw_armature.c */
typedef struct DRWArmaturePasses {
struct DRWPass *bone_solid;

View File

@ -2615,6 +2615,7 @@ static void OBJECT_cache_populate(void *vedata, Object *ob)
ViewLayer *view_layer = draw_ctx->view_layer;
Scene *scene = draw_ctx->scene;
View3D *v3d = draw_ctx->v3d;
RegionView3D *rv3d = draw_ctx->rv3d;
ModifierData *md = NULL;
int theme_id = TH_UNDEFINED;
@ -2637,12 +2638,20 @@ static void OBJECT_cache_populate(void *vedata, Object *ob)
struct GPUBatch *geom;
const bool xray_enabled = ((v3d->shading.flag & V3D_SHADING_XRAY) != 0) &&
(v3d->shading.type < OB_MATERIAL);
if (xray_enabled) {
/* This fixes only the biggest case which is a plane in ortho view. */
int flat_axis = 0;
bool is_flat_object_viewed_from_side = (rv3d->persp == RV3D_ORTHO) &&
DRW_object_is_flat(ob, &flat_axis) &&
DRW_object_axis_orthogonal_to_view(ob, flat_axis);
if (xray_enabled || is_flat_object_viewed_from_side) {
geom = DRW_cache_object_edge_detection_get(ob, NULL);
}
else {
geom = DRW_cache_object_surface_get(ob);
}
if (geom) {
theme_id = DRW_object_wire_theme_get(ob, view_layer, NULL);
DRWShadingGroup *shgroup = shgroup_theme_id_to_outline_or(stl, theme_id, NULL);

View File

@ -40,6 +40,7 @@ typedef struct OVERLAY_StorageList {
typedef struct OVERLAY_PassList {
struct DRWPass *face_orientation_pass;
struct DRWPass *flat_wireframe_pass;
struct DRWPass *face_wireframe_pass;
struct DRWPass *face_wireframe_full_pass;
} OVERLAY_PassList;
@ -176,6 +177,8 @@ static void overlay_cache_init(void *vedata)
/* Wireframe */
DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_LESS_EQUAL | DRW_STATE_BLEND;
psl->flat_wireframe_pass = DRW_pass_create("Flat Object Wires", state | DRW_STATE_WRITE_DEPTH);
psl->face_wireframe_full_pass = DRW_pass_create("All Face Wires", state);
stl->g_data->sculpt_wires_full = DRW_shgroup_create(e_data.face_wireframe_sculpt_sh, psl->face_wireframe_full_pass);
@ -216,6 +219,7 @@ static void overlay_cache_populate(void *vedata, Object *ob)
OVERLAY_PrivateData *pd = stl->g_data;
OVERLAY_PassList *psl = data->psl;
const DRWContextState *draw_ctx = DRW_context_state_get();
RegionView3D *rv3d = draw_ctx->rv3d;
View3D *v3d = draw_ctx->v3d;
if (!stl->g_data->show_overlays)
@ -242,12 +246,27 @@ static void overlay_cache_populate(void *vedata, Object *ob)
const bool all_wires = (stl->g_data->overlay.wireframe_threshold == 1.0f) ||
(ob->dtx & OB_DRAW_ALL_EDGES);
/* This fixes only the biggest case which is a plane in ortho view. */
int flat_axis = 0;
bool is_flat_object_viewed_from_side = (rv3d->persp == RV3D_ORTHO) &&
DRW_object_is_flat(ob, &flat_axis) &&
DRW_object_axis_orthogonal_to_view(ob, flat_axis);
if (is_sculpt_mode) {
DRWShadingGroup *shgrp = (all_wires || DRW_object_is_flat_normal(ob))
? stl->g_data->sculpt_wires_full
: stl->g_data->sculpt_wires;
DRW_shgroup_call_sculpt_add(shgrp, ob, ob->obmat);
}
else if (is_flat_object_viewed_from_side) {
/* Avoid loosing flat objects when in ortho views (see T56549) */
struct GPUBatch *geom = DRW_cache_object_wire_outline_get(ob);
GPUShader *sh = GPU_shader_get_builtin_shader(GPU_SHADER_3D_UNIFORM_COLOR);
DRWShadingGroup *shgrp = DRW_shgroup_create(sh, psl->flat_wireframe_pass);
DRW_shgroup_stencil_mask(shgrp, (ob->dtx & OB_DRAWXRAY) ? 0x00 : 0xFF);
DRW_shgroup_uniform_vec4(shgrp, "color", ts.colorWire, 1);
DRW_shgroup_call_object_add(shgrp, geom, ob);
}
else {
int tri_count;
GPUTexture *verts = NULL, *faceids;
@ -283,7 +302,6 @@ static void overlay_cache_populate(void *vedata, Object *ob)
DRW_shgroup_uniform_vec3(shgrp, "rimColor", rim_col, 1);
DRW_shgroup_call_object_procedural_triangles_culled_add(shgrp, tri_count, ob);
}
}
}
}
@ -322,6 +340,7 @@ static void overlay_draw_scene(void *vedata)
GPU_framebuffer_bind(dfbl->default_fb);
}
DRW_draw_pass(psl->face_orientation_pass);
DRW_draw_pass(psl->flat_wireframe_pass);
DRW_draw_pass(psl->face_wireframe_pass);
DRW_draw_pass(psl->face_wireframe_full_pass);
}