Object Mode: Make Flat object outline visible in orthographic view
This commit is contained in:
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.
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue