From baf0547de57397d2f12404d1cc1e861aa1e90d83 Mon Sep 17 00:00:00 2001 From: Jeroen Bakker Date: Wed, 2 May 2018 12:05:40 +0200 Subject: [PATCH] Workbench: Single Color Modes - ability to switch between Single Color, Object Color, Material Color and Random Color - fixed Shading and Lighting popover - Renamed Solid -> Single Color --- release/scripts/startup/bl_ui/space_view3d.py | 14 ++-- .../engines/workbench/workbench_materials.c | 65 ++++++++++++++----- source/blender/makesdna/DNA_view3d_types.h | 12 +++- source/blender/makesrna/intern/rna_space.c | 30 +++++++-- 4 files changed, 89 insertions(+), 32 deletions(-) diff --git a/release/scripts/startup/bl_ui/space_view3d.py b/release/scripts/startup/bl_ui/space_view3d.py index 089e83c9aab..2fa4061faaf 100644 --- a/release/scripts/startup/bl_ui/space_view3d.py +++ b/release/scripts/startup/bl_ui/space_view3d.py @@ -53,8 +53,8 @@ class VIEW3D_HT_header(Header): # Contains buttons like Mode, Pivot, Manipulator, Layer, Mesh Select Mode... row = layout - row.popover(space_type='VIEW_3D', region_type='UI', panel_type="VIEW3D_PT_shading", text="Shading") - row.popover(space_type='VIEW_3D', region_type='UI', panel_type="VIEW3D_PT_overlay", text="Overlay") + row.popover(space_type='VIEW_3D', region_type='HEADER', panel_type="VIEW3D_PT_shading", text="Shading") + row.popover(space_type='VIEW_3D', region_type='HEADER', panel_type="VIEW3D_PT_overlay", text="Overlay") layout.template_header_3D() @@ -3528,12 +3528,12 @@ class VIEW3D_PT_view3d_name(Panel): class VIEW3D_PT_shading(Panel): bl_space_type = 'VIEW_3D' - bl_region_type = 'UI' + bl_region_type = 'HEADER' bl_label = "Shading" @classmethod def poll(cls, context): - return False + return True def draw(self, context): layout = self.layout @@ -3549,7 +3549,7 @@ class VIEW3D_PT_shading(Panel): col.row().prop(shading, "light", expand=True) col.separator() - col.prop(shading, "show_random_object_colors") + col.row().prop(shading, "single_color_mode", expand=True) col.prop(shading, "show_object_overlap") if shading.light == 'STUDIO': @@ -3580,12 +3580,12 @@ class VIEW3D_PT_shading(Panel): class VIEW3D_PT_overlay(Panel): bl_space_type = 'VIEW_3D' - bl_region_type = 'UI' + bl_region_type = 'HEADER' bl_label = "Overlay" @classmethod def poll(cls, context): - return False + return True def draw(self, context): layout = self.layout diff --git a/source/blender/draw/engines/workbench/workbench_materials.c b/source/blender/draw/engines/workbench/workbench_materials.c index 261c1a1e8ac..6ea65855f0b 100644 --- a/source/blender/draw/engines/workbench/workbench_materials.c +++ b/source/blender/draw/engines/workbench/workbench_materials.c @@ -26,6 +26,7 @@ #include "workbench_private.h" #include "BLI_dynstr.h" +#include "BLI_alloca.h" #include "BKE_particle.h" @@ -172,10 +173,10 @@ static void workbench_init_object_data(ObjectEngineData *engine_data) data->object_id = e_data.next_object_id++; } -static void get_material_solid_color(WORKBENCH_PrivateData *wpd, WORKBENCH_ObjectData *engine_object_data, Object *ob, float *color, float hsv_saturation, float hsv_value) +static void get_material_solid_color(WORKBENCH_PrivateData *wpd, WORKBENCH_ObjectData *engine_object_data, Object *ob, Material *mat, float *color, float hsv_saturation, float hsv_value) { static float default_color[] = {1.0f, 1.0f, 1.0f}; - if (DRW_object_is_paint_mode(ob)) { + if (DRW_object_is_paint_mode(ob) || wpd->drawtype_options & V3D_DRAWOPTION_SINGLE_COLOR) { copy_v3_v3(color, default_color); } else if (wpd->drawtype_options & V3D_DRAWOPTION_RANDOMIZE) { @@ -183,9 +184,18 @@ static void get_material_solid_color(WORKBENCH_PrivateData *wpd, WORKBENCH_Objec float hsv[3] = {offset, hsv_saturation, hsv_value}; hsv_to_rgb_v(hsv, color); } - else { + else if (wpd->drawtype_options & V3D_DRAWOPTION_OBJECT_COLOR) { copy_v3_v3(color, ob->col); } + else { + /* V3D_DRAWOPTION_MATERIAL_COLOR */ + if (mat) { + copy_v3_v3(color, &mat->r); + } + else { + copy_v3_v3(color, default_color); + } + } } void workbench_materials_engine_init(WORKBENCH_Data *vedata) @@ -298,7 +308,7 @@ void workbench_materials_cache_init(WORKBENCH_Data *vedata) } -static WORKBENCH_MaterialData *get_or_create_material_data(WORKBENCH_Data *vedata, IDProperty *props, Object *ob) +static WORKBENCH_MaterialData *get_or_create_material_data(WORKBENCH_Data *vedata, IDProperty *props, Object *ob, Material *mat) { WORKBENCH_StorageList *stl = vedata->stl; WORKBENCH_PassList *psl = vedata->psl; @@ -312,7 +322,7 @@ static WORKBENCH_MaterialData *get_or_create_material_data(WORKBENCH_Data *vedat const float hsv_value = BKE_collection_engine_property_value_get_float(props, "random_object_color_value"); /* Solid */ - get_material_solid_color(wpd, engine_object_data, ob, color, hsv_saturation, hsv_value); + get_material_solid_color(wpd, engine_object_data, ob, mat, color, hsv_saturation, hsv_value); copy_v3_v3(material_template.color, color); material_template.object_id = engine_object_data->object_id; unsigned int hash = get_material_hash(wpd, &material_template); @@ -352,7 +362,7 @@ static void workbench_cache_populate_particles(WORKBENCH_Data *vedata, IDPropert if (draw_as == PART_DRAW_PATH) { struct Gwn_Batch *geom = DRW_cache_particles_get_hair(psys, NULL); - WORKBENCH_MaterialData *material = get_or_create_material_data(vedata, props, ob); + WORKBENCH_MaterialData *material = get_or_create_material_data(vedata, props, ob, NULL); DRW_shgroup_call_add(material->shgrp, geom, mat); } } @@ -370,21 +380,41 @@ void workbench_materials_solid_cache_populate(WORKBENCH_Data *vedata, Object *ob if (ob->type == OB_MESH) { workbench_cache_populate_particles(vedata, props, ob); } - - struct Gwn_Batch *geom = DRW_cache_object_surface_get(ob); - + WORKBENCH_MaterialData *material; - if (geom) { + if (ELEM(ob->type, OB_MESH, OB_CURVE, OB_SURF, OB_FONT)) { const DRWContextState *draw_ctx = DRW_context_state_get(); const bool is_active = (ob == draw_ctx->obact); - - material = get_or_create_material_data(vedata, props, ob); const bool is_sculpt_mode = is_active && (draw_ctx->object_mode & OB_MODE_SCULPT) != 0; - if (is_sculpt_mode) { - DRW_shgroup_call_sculpt_add(material->shgrp, ob, ob->obmat); - } - else { - DRW_shgroup_call_object_add(material->shgrp, geom, ob); + + if ((vedata->stl->g_data->drawtype_options & V3D_DRAWOPTION_SOLID_COLOR_MASK) != 0 || is_sculpt_mode) { + /* No material split needed */ + struct Gwn_Batch *geom = DRW_cache_object_surface_get(ob); + if (geom) { + material = get_or_create_material_data(vedata, props, ob, NULL); + if (is_sculpt_mode) { + DRW_shgroup_call_sculpt_add(material->shgrp, ob, ob->obmat); + } + else { + DRW_shgroup_call_object_add(material->shgrp, geom, ob); + } + } + } + else { /* MATERIAL colors */ + const int materials_len = MAX2(1, (is_sculpt_mode ? 1 : ob->totcol)); + struct GPUMaterial **gpumat_array = BLI_array_alloca(gpumat_array, materials_len); + for (int i = 0; i < materials_len; i ++) { + gpumat_array[i] = NULL; + } + + struct Gwn_Batch **mat_geom = DRW_cache_object_surface_material_get(ob, gpumat_array, materials_len); + if (mat_geom) { + for (int i = 0; i < materials_len; ++i) { + Material *mat = give_current_material(ob, i + 1); + material = get_or_create_material_data(vedata, props, ob, mat); + DRW_shgroup_call_object_add(material->shgrp, mat_geom[i], ob); + } + } } } } @@ -419,4 +449,3 @@ void workbench_materials_draw_scene(WORKBENCH_Data *vedata) DRW_UBO_FREE_SAFE(wpd->world_ubo); } - diff --git a/source/blender/makesdna/DNA_view3d_types.h b/source/blender/makesdna/DNA_view3d_types.h index 313997082c7..0644837727e 100644 --- a/source/blender/makesdna/DNA_view3d_types.h +++ b/source/blender/makesdna/DNA_view3d_types.h @@ -80,10 +80,18 @@ enum { V3D_LIGHTING_SCENE = 2 }; +/* + * V3D_DRAWOPTION_OBJECT_COLOR, V3D_DRAWOPTION_OBJECT_OVERLAP, + * V3D_DRAWOPTION_SINGLE_COLOR, V3D_DRAWOPTION_MATERIAL_COLOR are mutual exclusive +*/ enum { - V3D_DRAWOPTION_RANDOMIZE = (1 << 0), - V3D_DRAWOPTION_OBJECT_OVERLAP = (2 << 0), + V3D_DRAWOPTION_MATERIAL_COLOR = (0 << 0), + V3D_DRAWOPTION_RANDOMIZE = (1 << 0), + V3D_DRAWOPTION_OBJECT_OVERLAP = (1 << 1), + V3D_DRAWOPTION_SINGLE_COLOR = (1 << 2), + V3D_DRAWOPTION_OBJECT_COLOR = (1 << 4), }; +#define V3D_DRAWOPTION_SOLID_COLOR_MASK (V3D_DRAWOPTION_SINGLE_COLOR | V3D_DRAWOPTION_RANDOMIZE | V3D_DRAWOPTION_OBJECT_COLOR | V3D_DRAWOPTION_MATERIAL_COLOR) enum { V3D_OVERLAY_FACE_ORIENTATION = (1 << 0), diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c index 89465f8e6a0..30c00b93867 100644 --- a/source/blender/makesrna/intern/rna_space.c +++ b/source/blender/makesrna/intern/rna_space.c @@ -177,7 +177,7 @@ static const EnumPropertyItem autosnap_items[] = { const EnumPropertyItem rna_enum_shading_type_items[] = { {OB_WIRE, "WIREFRAME", ICON_WIRE, "Wireframe", "Display the object as wire edges"}, - {OB_SOLID, "SOLID", ICON_SOLID, "Solid", "Display the object solid"}, + {OB_SOLID, "SOLID", ICON_SOLID, "Single Color", "Display the object or material in a single color"}, {OB_TEXTURE, "TEXTURED", ICON_POTATO, "Texture", "Display the object solid, with a texture"}, {OB_MATERIAL, "MATERIAL", ICON_MATERIAL_DATA, "Material", "Display objects solid, with GLSL material"}, {OB_RENDER, "RENDERED", ICON_SMOOTH, "Rendered", "Display render preview"}, @@ -679,6 +679,16 @@ static void rna_3DViewShading_type_set(PointerRNA *ptr, int value) v3d->drawtype = value; } +static void rna_View3DShading_single_color_mode_set(PointerRNA *ptr, int value) { + View3D *v3d = (View3D *)ptr->data; + v3d->drawtype_options = (v3d->drawtype_options &~ V3D_DRAWOPTION_SOLID_COLOR_MASK) + value; +} + +static int rna_View3DShading_single_color_mode_get(PointerRNA *ptr) { + View3D *v3d = (View3D *)ptr->data; + return v3d->drawtype_options & V3D_DRAWOPTION_SOLID_COLOR_MASK; +} + static const EnumPropertyItem *rna_3DViewShading_type_itemf( bContext *C, PointerRNA *UNUSED(ptr), PropertyRNA *UNUSED(prop), bool *r_free) @@ -2184,6 +2194,14 @@ static void rna_def_space_view3d_shading(BlenderRNA *brna) StructRNA *srna; PropertyRNA *prop; + static const EnumPropertyItem single_color_mode_items[] = { + {V3D_DRAWOPTION_SINGLE_COLOR, "SINGLE", 0, "Single", "Show scene in a single color"}, + {V3D_DRAWOPTION_OBJECT_COLOR, "OBJECT", 0, "Object", "Show Object color"}, + {V3D_DRAWOPTION_MATERIAL_COLOR, "MATERIAL", 0, "Material", "Show Material color"}, + {V3D_DRAWOPTION_RANDOMIZE, "RANDOM", 0, "Random", "Show random object color"}, + {0, NULL, 0, NULL, NULL} + }; + srna = RNA_def_struct(brna, "View3DShading", NULL); RNA_def_struct_sdna(srna, "View3D"); RNA_def_struct_nested(brna, srna, "SpaceView3D"); @@ -2210,10 +2228,12 @@ static void rna_def_space_view3d_shading(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Object Overlap", "Show Object Overlap"); RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, "rna_3DViewShading_type_update"); - prop = RNA_def_property(srna, "show_random_object_colors", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "drawtype_options", V3D_DRAWOPTION_RANDOMIZE); - RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); - RNA_def_property_ui_text(prop, "Random Colors", "Show random object colors"); + prop = RNA_def_property(srna, "single_color_mode", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_items(prop, single_color_mode_items); + RNA_def_property_enum_funcs(prop, "rna_View3DShading_single_color_mode_get", + "rna_View3DShading_single_color_mode_set", + NULL); + RNA_def_property_ui_text(prop, "Color", "Single Color Mode"); RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, "rna_3DViewShading_type_update"); }