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
path: root/source
diff options
context:
space:
mode:
authorClément Foucault <foucault.clem@gmail.com>2019-02-22 18:06:13 +0300
committerClément Foucault <foucault.clem@gmail.com>2019-02-22 18:06:23 +0300
commit7372058649666c7b0425c2f4d1a688a65ad11e61 (patch)
treefe81d2b57503c5b50b90885be923ca9c4c2641ac /source
parente278b38b921d625a11544203808575a7180f75e8 (diff)
Wireframe: Add object and random coloring option in wireframe mode
The option is separated from the solid mode color option. Random color uses the same method as solid mode. Selection state is indicated by a brighter color that is outside the brightness range of the unselected state colors. The active state is indicated by the outlines that is, now, still drawn in wireframe mode. Coloring of the selection / active outline is not optimal because it can look ugly in some cases of color combination. But the outline color is using index range coloring so it's not trivial to change the color of the outline per object. For now we use the same outline color used in solid mode for consistency and also still add an emphasis on the selected objects. The Single color option uses the theme color. Maybe it would be nice to change the name of it in a latter commit to avoid confusion.
Diffstat (limited to 'source')
-rw-r--r--source/blender/blenloader/intern/versioning_280.c14
-rw-r--r--source/blender/draw/modes/object_mode.c12
-rw-r--r--source/blender/draw/modes/overlay_mode.c152
-rw-r--r--source/blender/makesdna/DNA_view3d_types.h3
-rw-r--r--source/blender/makesrna/intern/rna_space.c12
5 files changed, 145 insertions, 48 deletions
diff --git a/source/blender/blenloader/intern/versioning_280.c b/source/blender/blenloader/intern/versioning_280.c
index 07fae75974f..5234efdce03 100644
--- a/source/blender/blenloader/intern/versioning_280.c
+++ b/source/blender/blenloader/intern/versioning_280.c
@@ -2807,5 +2807,19 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain)
{
/* Versioning code until next subversion bump goes here. */
+
+ /* Add wireframe color. */
+ if (!DNA_struct_elem_find(fd->filesdna, "View3DShading", "char", "wire_color_type")) {
+ for (bScreen *screen = bmain->screen.first; screen; screen = screen->id.next) {
+ for (ScrArea *sa = screen->areabase.first; sa; sa = sa->next) {
+ for (SpaceLink *sl = sa->spacedata.first; sl; sl = sl->next) {
+ if (sl->spacetype == SPACE_VIEW3D) {
+ View3D *v3d = (View3D *)sl;
+ v3d->shading.wire_color_type = V3D_SHADING_SINGLE_COLOR;
+ }
+ }
+ }
+ }
+ }
}
}
diff --git a/source/blender/draw/modes/object_mode.c b/source/blender/draw/modes/object_mode.c
index 7439bd3255d..c0c290e1056 100644
--- a/source/blender/draw/modes/object_mode.c
+++ b/source/blender/draw/modes/object_mode.c
@@ -307,6 +307,7 @@ typedef struct OBJECT_PrivateData {
int id_ofs_prb_transform;
bool xray_enabled;
+ bool xray_enabled_and_not_wire;
} OBJECT_PrivateData; /* Transient data */
static struct {
@@ -995,7 +996,9 @@ static void OBJECT_cache_init(void *vedata)
}
g_data = stl->g_data;
- g_data->xray_enabled = XRAY_ENABLED(draw_ctx->v3d) && (draw_ctx->v3d->shading.type < OB_MATERIAL);
+ g_data->xray_enabled = XRAY_ENABLED(draw_ctx->v3d) &&
+ (draw_ctx->v3d->shading.type < OB_MATERIAL);
+ g_data->xray_enabled_and_not_wire = g_data->xray_enabled && draw_ctx->v3d->shading.type > OB_WIRE;
{
DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL | DRW_STATE_WIRE;
@@ -1003,7 +1006,7 @@ static void OBJECT_cache_init(void *vedata)
GPUShader *sh = sh_data->outline_prepass;
- if (g_data->xray_enabled) {
+ if (g_data->xray_enabled_and_not_wire) {
sh = sh_data->outline_prepass_wire;
}
@@ -1050,7 +1053,7 @@ static void OBJECT_cache_init(void *vedata)
psl->outlines_search = DRW_pass_create("Outlines Detect Pass", state);
- GPUShader *sh = (g_data->xray_enabled) ? sh_data->outline_detect_wire : sh_data->outline_detect;
+ GPUShader *sh = (g_data->xray_enabled_and_not_wire) ? sh_data->outline_detect_wire : sh_data->outline_detect;
DRWShadingGroup *grp = DRW_shgroup_create(sh, psl->outlines_search);
DRW_shgroup_uniform_texture_ref(grp, "outlineId", &e_data.outlines_id_tx);
DRW_shgroup_uniform_texture_ref(grp, "outlineDepth", &e_data.outlines_depth_tx);
@@ -2908,7 +2911,6 @@ static void OBJECT_cache_populate(void *vedata, Object *ob)
const bool do_outlines = (
(draw_ctx->v3d->flag & V3D_SELECT_OUTLINE) && ((ob->base_flag & BASE_SELECTED) != 0) &&
- (draw_ctx->v3d->shading.type != OB_WIRE) &&
((DRW_object_is_renderable(ob) && (ob->dt > OB_WIRE)) || (ob->dt == OB_WIRE)));
const bool show_relations = ((draw_ctx->v3d->flag & V3D_HIDE_HELPLINES) == 0);
const bool hide_object_extra = (v3d->overlay.flag & V3D_OVERLAY_HIDE_OBJECT_XTRAS) != 0;
@@ -2926,7 +2928,7 @@ static void OBJECT_cache_populate(void *vedata, Object *ob)
DRW_object_is_flat(ob, &flat_axis) &&
DRW_object_axis_orthogonal_to_view(ob, flat_axis));
- if (stl->g_data->xray_enabled || is_flat_object_viewed_from_side) {
+ if (stl->g_data->xray_enabled_and_not_wire || is_flat_object_viewed_from_side) {
geom = DRW_cache_object_edge_detection_get(ob, NULL);
}
else {
diff --git a/source/blender/draw/modes/overlay_mode.c b/source/blender/draw/modes/overlay_mode.c
index 30ea1bbeeaa..3cd9165abc4 100644
--- a/source/blender/draw/modes/overlay_mode.c
+++ b/source/blender/draw/modes/overlay_mode.c
@@ -29,6 +29,8 @@
#include "BKE_object.h"
#include "BKE_global.h"
+#include "BLI_hash.h"
+
#include "GPU_shader.h"
#include "DRW_render.h"
@@ -39,6 +41,7 @@
#endif
/* Structures */
+
typedef struct OVERLAY_StorageList {
struct OVERLAY_PrivateData *g_data;
} OVERLAY_StorageList;
@@ -59,6 +62,7 @@ typedef struct OVERLAY_Data {
typedef struct OVERLAY_PrivateData {
DRWShadingGroup *face_orientation_shgrp;
DRWShadingGroup *face_wires_shgrp;
+ BLI_mempool *wire_color_mempool;
View3DOverlay overlay;
float wire_step_param;
bool ghost_stencil_test;
@@ -102,7 +106,7 @@ static void overlay_engine_init(void *vedata)
if (!stl->g_data) {
/* Alloc transient pointers */
- stl->g_data = MEM_mallocN(sizeof(*stl->g_data), __func__);
+ stl->g_data = MEM_callocN(sizeof(*stl->g_data), __func__);
}
stl->g_data->ghost_stencil_test = false;
@@ -172,6 +176,13 @@ static void overlay_cache_init(void *vedata)
if (v3d->shading.type == OB_WIRE) {
g_data->overlay.flag |= V3D_OVERLAY_WIREFRAMES;
g_data->show_overlays = true;
+
+ if (ELEM(v3d->shading.wire_color_type,
+ V3D_SHADING_OBJECT_COLOR,
+ V3D_SHADING_RANDOM_COLOR))
+ {
+ g_data->wire_color_mempool = BLI_mempool_create(sizeof(float[3]), 0, 512, 0);
+ }
}
{
@@ -221,6 +232,92 @@ static void overlay_cache_init(void *vedata)
}
}
+static void overlay_wire_color_get(
+ const View3D *v3d, const OVERLAY_PrivateData *pd, const Object *ob, const bool use_coloring,
+ float **rim_col, float **wire_col)
+{
+#ifndef NDEBUG
+ *rim_col = NULL;
+ *wire_col = NULL;
+#endif
+ const DRWContextState *draw_ctx = DRW_context_state_get();
+
+ if (UNLIKELY(ob->base_flag & BASE_FROM_SET)) {
+ *rim_col = G_draw.block.colorDupli;
+ *wire_col = G_draw.block.colorDupli;
+ }
+ else if (UNLIKELY(ob->base_flag & BASE_FROM_DUPLI)) {
+ if (ob->base_flag & BASE_SELECTED) {
+ if (G.moving & G_TRANSFORM_OBJ) {
+ *rim_col = G_draw.block.colorTransform;
+ }
+ else {
+ *rim_col = G_draw.block.colorDupliSelect;
+ }
+ }
+ else {
+ *rim_col = G_draw.block.colorDupli;
+ }
+ *wire_col = G_draw.block.colorDupli;
+ }
+ else if ((ob->base_flag & BASE_SELECTED) && use_coloring) {
+ if (G.moving & G_TRANSFORM_OBJ) {
+ *rim_col = G_draw.block.colorTransform;
+ }
+ else if (ob == draw_ctx->obact) {
+ *rim_col = G_draw.block.colorActive;
+ }
+ else {
+ *rim_col = G_draw.block.colorSelect;
+ }
+ *wire_col = G_draw.block.colorWire;
+ }
+ else {
+ *rim_col = G_draw.block.colorWire;
+ *wire_col = G_draw.block.colorWire;
+ }
+
+ if (v3d->shading.type == OB_WIRE) {
+ if (ELEM(v3d->shading.wire_color_type,
+ V3D_SHADING_OBJECT_COLOR,
+ V3D_SHADING_RANDOM_COLOR))
+ {
+ *wire_col = BLI_mempool_alloc(pd->wire_color_mempool);
+ *rim_col = BLI_mempool_alloc(pd->wire_color_mempool);
+
+ if (v3d->shading.wire_color_type == V3D_SHADING_OBJECT_COLOR) {
+ linearrgb_to_srgb_v3_v3(*wire_col, ob->color);
+ mul_v3_fl(*wire_col, 0.5f);
+ copy_v3_v3(*rim_col, *wire_col);
+ }
+ else {
+ uint hash = BLI_ghashutil_strhash_p_murmur(ob->id.name);
+ if (ob->id.lib) {
+ hash = (hash * 13) ^ BLI_ghashutil_strhash_p_murmur(ob->id.lib->name);
+ }
+
+ float hue = BLI_hash_int_01(hash);
+ float hsv[3] = {hue, 0.75f, 0.8f};
+ hsv_to_rgb_v(hsv, *wire_col);
+ copy_v3_v3(*rim_col, *wire_col);
+ }
+
+ if ((ob->base_flag & BASE_SELECTED) && use_coloring) {
+ /* "Normalize" color. */
+ add_v3_fl(*wire_col, 1e-4f);
+ float brightness = max_fff((*wire_col)[0], (*wire_col)[1], (*wire_col)[2]);
+ mul_v3_fl(*wire_col, (0.5f / brightness));
+ add_v3_fl(*rim_col, 0.75f);
+ }
+ else {
+ mul_v3_fl(*rim_col, 0.5f);
+ add_v3_fl(*wire_col, 0.5f);
+ }
+ }
+ }
+ BLI_assert(*rim_col && *wire_col);
+}
+
static void overlay_cache_populate(void *vedata, Object *ob)
{
OVERLAY_Data *data = vedata;
@@ -267,49 +364,12 @@ static void overlay_cache_populate(void *vedata, Object *ob)
const bool is_sculpt_mode = is_active && (draw_ctx->object_mode & OB_MODE_SCULPT) != 0;
const bool all_wires = (ob->dtx & OB_DRAW_ALL_EDGES);
const bool is_wire = (ob->dt < OB_SOLID);
+ const bool use_coloring = (!is_edit_mode && !is_sculpt_mode && !has_edit_mesh_cage);
const int stencil_mask = (ob->dtx & OB_DRAWXRAY) ? 0x00 : 0xFF;
+ float *rim_col, *wire_col;
DRWShadingGroup *shgrp = NULL;
- const float *rim_col = NULL;
- const float *wire_col = NULL;
-
- if (UNLIKELY(ob->base_flag & BASE_FROM_SET)) {
- rim_col = G_draw.block.colorDupli;
- wire_col = G_draw.block.colorDupli;
- }
- else if (UNLIKELY(ob->base_flag & BASE_FROM_DUPLI)) {
- if (ob->base_flag & BASE_SELECTED) {
- if (G.moving & G_TRANSFORM_OBJ) {
- rim_col = G_draw.block.colorTransform;
- }
- else {
- rim_col = G_draw.block.colorDupliSelect;
- }
- }
- else {
- rim_col = G_draw.block.colorDupli;
- }
- wire_col = G_draw.block.colorDupli;
- }
- else if ((ob->base_flag & BASE_SELECTED) &&
- (!is_edit_mode && !is_sculpt_mode && !has_edit_mesh_cage))
- {
- if (G.moving & G_TRANSFORM_OBJ) {
- rim_col = G_draw.block.colorTransform;
- }
- else if (ob == draw_ctx->obact) {
- rim_col = G_draw.block.colorActive;
- }
- else {
- rim_col = G_draw.block.colorSelect;
- }
- wire_col = G_draw.block.colorWire;
- }
- else {
- rim_col = G_draw.block.colorWire;
- wire_col = G_draw.block.colorWire;
- }
- BLI_assert(rim_col && wire_col);
+ overlay_wire_color_get(v3d, pd, ob, use_coloring, &rim_col, &wire_col);
struct GPUBatch *geom;
geom = DRW_cache_object_face_wireframe_get(ob);
@@ -372,6 +432,7 @@ static void overlay_draw_scene(void *vedata)
{
OVERLAY_Data *data = vedata;
OVERLAY_PassList *psl = data->psl;
+ OVERLAY_StorageList *stl = data->stl;
DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get();
DefaultTextureList *dtxl = DRW_viewport_texture_list_get();
@@ -380,7 +441,8 @@ static void overlay_draw_scene(void *vedata)
}
DRW_draw_pass(psl->face_orientation_pass);
- MULTISAMPLE_SYNC_ENABLE(dfbl, dtxl);
+ /* This is replaced by the next code block */
+ // MULTISAMPLE_SYNC_ENABLE(dfbl, dtxl);
if (dfbl->multisample_fb != NULL) {
DRW_stats_query_start("Multisample Blit");
@@ -399,6 +461,12 @@ static void overlay_draw_scene(void *vedata)
/* TODO(fclem): find a way to unify the multisample pass together
* (non meshes + armature + wireframe) */
MULTISAMPLE_SYNC_DISABLE(dfbl, dtxl);
+
+ /* XXX TODO(fclem) do not discard data after drawing! Store them per viewport. */
+ if (stl->g_data->wire_color_mempool) {
+ BLI_mempool_destroy(stl->g_data->wire_color_mempool);
+ stl->g_data->wire_color_mempool = NULL;
+ }
}
static void overlay_engine_free(void)
diff --git a/source/blender/makesdna/DNA_view3d_types.h b/source/blender/makesdna/DNA_view3d_types.h
index a3d1573ae97..32f22ead652 100644
--- a/source/blender/makesdna/DNA_view3d_types.h
+++ b/source/blender/makesdna/DNA_view3d_types.h
@@ -154,7 +154,8 @@ typedef struct View3DShading {
char light;
char background_type;
char cavity_type;
- char pad[7];
+ char wire_color_type;
+ char pad[6];
/** FILE_MAXFILE. */
char studio_light[256];
diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c
index fce0a187cab..6782f253717 100644
--- a/source/blender/makesrna/intern/rna_space.c
+++ b/source/blender/makesrna/intern/rna_space.c
@@ -804,6 +804,11 @@ static const EnumPropertyItem *rna_View3DShading_color_type_itemf(
RNA_enum_items_add_value(&item, &totitem, rna_enum_shading_color_type_items, V3D_SHADING_TEXTURE_COLOR);
}
}
+ else if (shading->type == OB_WIRE) {
+ RNA_enum_items_add_value(&item, &totitem, rna_enum_shading_color_type_items, V3D_SHADING_SINGLE_COLOR);
+ RNA_enum_items_add_value(&item, &totitem, rna_enum_shading_color_type_items, V3D_SHADING_OBJECT_COLOR);
+ RNA_enum_items_add_value(&item, &totitem, rna_enum_shading_color_type_items, V3D_SHADING_RANDOM_COLOR);
+ }
RNA_enum_item_end(&item, &totitem);
*r_free = true;
@@ -2536,6 +2541,13 @@ static void rna_def_space_view3d_shading(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Color", "Color Type");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL);
+ prop = RNA_def_property(srna, "wireframe_color_type", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_sdna(prop, NULL, "wire_color_type");
+ RNA_def_property_enum_items(prop, rna_enum_shading_color_type_items);
+ RNA_def_property_enum_funcs(prop, NULL, NULL, "rna_View3DShading_color_type_itemf");
+ RNA_def_property_ui_text(prop, "Color", "Color Type");
+ RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL);
+
prop = RNA_def_property(srna, "single_color", PROP_FLOAT, PROP_COLOR);
RNA_def_property_float_sdna(prop, NULL, "single_color");
RNA_def_property_array(prop, 3);