diff options
author | Clément Foucault <foucault.clem@gmail.com> | 2018-09-14 19:30:26 +0300 |
---|---|---|
committer | Clément Foucault <foucault.clem@gmail.com> | 2018-09-14 19:32:04 +0300 |
commit | b62d140be9319ecb1e8f38228f0f22926d7a8880 (patch) | |
tree | 92fec4b6d3307b82cc6925dcbd616452385ef3c2 | |
parent | 5feb03c3ae3353f1a616412f7384511f693ebc33 (diff) |
Object Mode: Make Flat object outline visible in orthographic view
-rw-r--r-- | source/blender/draw/intern/draw_common.c | 40 | ||||
-rw-r--r-- | source/blender/draw/intern/draw_common.h | 3 | ||||
-rw-r--r-- | source/blender/draw/modes/object_mode.c | 11 | ||||
-rw-r--r-- | source/blender/draw/modes/overlay_mode.c | 21 |
4 files changed, 73 insertions, 2 deletions
diff --git a/source/blender/draw/intern/draw_common.c b/source/blender/draw/intern/draw_common.c index 3d6b2015e49..876f4401927 100644 --- a/source/blender/draw/intern/draw_common.c +++ b/source/blender/draw/intern/draw_common.c @@ -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; +} diff --git a/source/blender/draw/intern/draw_common.h b/source/blender/draw/intern/draw_common.h index da136c8f377..814e90b1db0 100644 --- a/source/blender/draw/intern/draw_common.h +++ b/source/blender/draw/intern/draw_common.h @@ -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; diff --git a/source/blender/draw/modes/object_mode.c b/source/blender/draw/modes/object_mode.c index 1ea34949a1e..f2d316bbed1 100644 --- a/source/blender/draw/modes/object_mode.c +++ b/source/blender/draw/modes/object_mode.c @@ -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); diff --git a/source/blender/draw/modes/overlay_mode.c b/source/blender/draw/modes/overlay_mode.c index 04d1b2f1648..15ec414d19b 100644 --- a/source/blender/draw/modes/overlay_mode.c +++ b/source/blender/draw/modes/overlay_mode.c @@ -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); } |