[Bf-blender-cvs] [b62d140be93] blender2.8: Object Mode: Make Flat object outline visible in orthographic view

Clément Foucault noreply at git.blender.org
Fri Sep 14 18:32:12 CEST 2018


Commit: b62d140be9319ecb1e8f38228f0f22926d7a8880
Author: Clément Foucault
Date:   Fri Sep 14 18:30:26 2018 +0200
Branches: blender2.8
https://developer.blender.org/rBb62d140be9319ecb1e8f38228f0f22926d7a8880

Object Mode: Make Flat object outline visible in orthographic view

===================================================================

M	source/blender/draw/intern/draw_common.c
M	source/blender/draw/intern/draw_common.h
M	source/blender/draw/modes/object_mode.c
M	source/blender/draw/modes/overlay_mode.c

===================================================================

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);
 }



More information about the Bf-blender-cvs mailing list