Merge branch 'master' into sculpt-dev

This commit is contained in:
Pablo Dobarro 2021-06-03 22:46:38 +02:00
commit b1e59f1a20
9 changed files with 211 additions and 157 deletions

View File

@ -6206,6 +6206,9 @@ class VIEW3D_PT_overlay_geometry(Panel):
sub.active = overlay.show_fade_inactive
sub.prop(overlay, "fade_inactive_alpha", text="Fade Inactive Geometry")
row = col.row(align=True)
row.prop(overlay, "show_mode_transfer", text="Flash on Mode Transfer")
col = layout.column(align=True)
col.active = display_all

View File

@ -149,6 +149,7 @@ set(SRC
engines/overlay/overlay_image.c
engines/overlay/overlay_lattice.c
engines/overlay/overlay_metaball.c
engines/overlay/overlay_mode_transfer.c
engines/overlay/overlay_motion_path.c
engines/overlay/overlay_outline.c
engines/overlay/overlay_paint.c

View File

@ -207,6 +207,7 @@ static void OVERLAY_cache_init(void *vedata)
OVERLAY_armature_cache_init(vedata);
OVERLAY_background_cache_init(vedata);
OVERLAY_fade_cache_init(vedata);
OVERLAY_mode_transfer_cache_init(vedata);
OVERLAY_extra_cache_init(vedata);
OVERLAY_facing_cache_init(vedata);
OVERLAY_gpencil_cache_init(vedata);
@ -323,6 +324,7 @@ static void OVERLAY_cache_populate(void *vedata, Object *ob)
!is_select;
const bool draw_fade = draw_surface && (pd->overlay.flag & V3D_OVERLAY_FADE_INACTIVE) &&
overlay_should_fade_object(ob, draw_ctx->obact);
const bool draw_mode_transfer = draw_surface && (pd->overlay.flag & V3D_OVERLAY_MODE_TRANSFER);
const bool draw_bones = (pd->overlay.flag & V3D_OVERLAY_HIDE_BONES) == 0;
const bool draw_wires = draw_surface && has_surface &&
(pd->wireframe_mode || !pd->hide_overlays);
@ -349,6 +351,9 @@ static void OVERLAY_cache_populate(void *vedata, Object *ob)
if (draw_facing) {
OVERLAY_facing_cache_populate(vedata, ob);
}
if (draw_mode_transfer) {
OVERLAY_mode_transfer_cache_populate(vedata, ob);
}
if (draw_wires) {
OVERLAY_wireframe_cache_populate(vedata, ob, dupli, do_init);
}
@ -504,6 +509,7 @@ static void OVERLAY_cache_finish(void *vedata)
{GPU_ATTACHMENT_TEXTURE(dtxl->depth_in_front), GPU_ATTACHMENT_TEXTURE(dtxl->color)});
}
OVERLAY_mode_transfer_cache_finish(vedata);
OVERLAY_antialiasing_cache_finish(vedata);
OVERLAY_armature_cache_finish(vedata);
OVERLAY_image_cache_finish(vedata);
@ -566,6 +572,7 @@ static void OVERLAY_draw_scene(void *vedata)
OVERLAY_image_draw(vedata);
OVERLAY_fade_draw(vedata);
OVERLAY_facing_draw(vedata);
OVERLAY_mode_transfer_draw(vedata);
OVERLAY_extra_blend_draw(vedata);
OVERLAY_volume_draw(vedata);
@ -605,6 +612,7 @@ static void OVERLAY_draw_scene(void *vedata)
OVERLAY_fade_infront_draw(vedata);
OVERLAY_facing_infront_draw(vedata);
OVERLAY_mode_transfer_infront_draw(vedata);
if (DRW_state_is_fbo()) {
GPU_framebuffer_bind(fbl->overlay_line_in_front_fb);

View File

@ -0,0 +1,159 @@
/*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* Copyright 2021, Blender Foundation.
*/
/** \file
* \ingroup draw_engine
*/
#include "BKE_paint.h"
#include "DRW_render.h"
#include "ED_view3d.h"
#include "PIL_time.h"
#include "UI_resources.h"
#include "overlay_private.h"
void OVERLAY_mode_transfer_cache_init(OVERLAY_Data *vedata)
{
OVERLAY_PassList *psl = vedata->psl;
OVERLAY_PrivateData *pd = vedata->stl->pd;
pd->mode_transfer.time = PIL_check_seconds_timer();
for (int i = 0; i < 2; i++) {
/* Non Meshes Pass (Camera, empties, lights ...) */
DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_EQUAL | DRW_STATE_BLEND_ALPHA;
DRW_PASS_CREATE(psl->mode_transfer_ps[i], state | pd->clipping_state);
}
}
#define MODE_TRANSFER_FLASH_LENGTH 0.55f
/* TODO(pablodp606): Remove this option for 3.0 if fade in/out is not used. */
#define MODE_TRANSFER_FLASH_FADE 0.0f
#define MODE_TRANSFER_FLASH_MAX_ALPHA 0.25f
static bool mode_transfer_is_animation_running(const float anim_time)
{
return anim_time >= 0.0f && anim_time <= MODE_TRANSFER_FLASH_LENGTH;
}
static float mode_transfer_alpha_for_animation_time_get(const float anim_time)
{
if (anim_time > MODE_TRANSFER_FLASH_LENGTH) {
return 0.0f;
}
if (anim_time < 0.0f) {
return 0.0f;
}
if (MODE_TRANSFER_FLASH_FADE <= 0.0f) {
return (1.0f - (anim_time / MODE_TRANSFER_FLASH_LENGTH)) * MODE_TRANSFER_FLASH_MAX_ALPHA;
}
const float flash_fade_in_time = MODE_TRANSFER_FLASH_LENGTH * MODE_TRANSFER_FLASH_FADE;
const float flash_fade_out_time = MODE_TRANSFER_FLASH_LENGTH - flash_fade_in_time;
float alpha = 0.0f;
if (anim_time < flash_fade_in_time) {
alpha = anim_time / flash_fade_in_time;
}
else {
const float fade_out_anim_time = anim_time - flash_fade_in_time;
alpha = 1.0f - (fade_out_anim_time / flash_fade_out_time);
}
return alpha * MODE_TRANSFER_FLASH_MAX_ALPHA;
}
void OVERLAY_mode_transfer_cache_populate(OVERLAY_Data *vedata, Object *ob)
{
OVERLAY_PrivateData *pd = vedata->stl->pd;
OVERLAY_PassList *psl = vedata->psl;
if (pd->xray_enabled) {
return;
}
const float animation_time = pd->mode_transfer.time -
ob->runtime.overlay_mode_transfer_start_time;
if (!mode_transfer_is_animation_running(animation_time)) {
return;
}
const DRWContextState *draw_ctx = DRW_context_state_get();
const bool use_sculpt_pbvh = BKE_sculptsession_use_pbvh_draw(ob, draw_ctx->v3d) &&
!DRW_state_is_image_render();
const bool is_xray = (ob->dtx & OB_DRAW_IN_FRONT) != 0;
DRWShadingGroup *mode_transfer_grp[2];
for (int i = 0; i < 2; i++) {
GPUShader *sh = OVERLAY_shader_uniform_color();
mode_transfer_grp[i] = DRW_shgroup_create(sh, psl->mode_transfer_ps[i]);
DRW_shgroup_uniform_block(mode_transfer_grp[i], "globalsBlock", G_draw.block_ubo);
float color[4];
UI_GetThemeColor3fv(TH_VERTEX_SELECT, color);
color[3] = mode_transfer_alpha_for_animation_time_get(animation_time);
srgb_to_linearrgb_v4(color, color);
DRW_shgroup_uniform_vec4_copy(mode_transfer_grp[i], "color", color);
}
if (!pd->use_in_front) {
mode_transfer_grp[IN_FRONT] = mode_transfer_grp[NOT_IN_FRONT];
}
pd->mode_transfer.any_animated = true;
if (use_sculpt_pbvh) {
DRW_shgroup_call_sculpt(mode_transfer_grp[is_xray], ob, false, false);
}
else {
struct GPUBatch *geom = DRW_cache_object_surface_get(ob);
if (geom) {
DRW_shgroup_call(mode_transfer_grp[is_xray], geom, ob);
}
}
}
void OVERLAY_mode_transfer_draw(OVERLAY_Data *vedata)
{
OVERLAY_PassList *psl = vedata->psl;
DRW_draw_pass(psl->mode_transfer_ps[NOT_IN_FRONT]);
}
void OVERLAY_mode_transfer_infront_draw(OVERLAY_Data *vedata)
{
OVERLAY_PassList *psl = vedata->psl;
DRW_draw_pass(psl->mode_transfer_ps[IN_FRONT]);
}
void OVERLAY_mode_transfer_cache_finish(OVERLAY_Data *vedata)
{
OVERLAY_PrivateData *pd = vedata->stl->pd;
if (pd->mode_transfer.any_animated) {
DRW_viewport_request_redraw();
}
pd->mode_transfer.any_animated = false;
}

View File

@ -107,6 +107,7 @@ typedef struct OVERLAY_PassList {
DRWPass *gpencil_canvas_ps;
DRWPass *facing_ps[2];
DRWPass *fade_ps[2];
DRWPass *mode_transfer_ps[2];
DRWPass *grid_ps;
DRWPass *image_background_ps;
DRWPass *image_background_scene_ps;
@ -282,6 +283,7 @@ typedef struct OVERLAY_PrivateData {
DRWShadingGroup *extra_grid_grp;
DRWShadingGroup *facing_grp[2];
DRWShadingGroup *fade_grp[2];
DRWShadingGroup *flash_grp[2];
DRWShadingGroup *motion_path_lines_grp;
DRWShadingGroup *motion_path_points_grp;
DRWShadingGroup *outlines_grp;
@ -414,6 +416,10 @@ typedef struct OVERLAY_PrivateData {
struct {
DRWCallBuffer *handle[2];
} mball;
struct {
double time;
bool any_animated;
} mode_transfer;
} OVERLAY_PrivateData; /* Transient data */
typedef struct OVERLAY_StorageList {
@ -607,6 +613,12 @@ void OVERLAY_fade_cache_populate(OVERLAY_Data *vedata, Object *ob);
void OVERLAY_fade_draw(OVERLAY_Data *vedata);
void OVERLAY_fade_infront_draw(OVERLAY_Data *vedata);
void OVERLAY_mode_transfer_cache_init(OVERLAY_Data *vedata);
void OVERLAY_mode_transfer_cache_populate(OVERLAY_Data *vedata, Object *ob);
void OVERLAY_mode_transfer_draw(OVERLAY_Data *vedata);
void OVERLAY_mode_transfer_infront_draw(OVERLAY_Data *vedata);
void OVERLAY_mode_transfer_cache_finish(OVERLAY_Data *vedata);
void OVERLAY_grid_init(OVERLAY_Data *vedata);
void OVERLAY_grid_cache_init(OVERLAY_Data *vedata);
void OVERLAY_grid_draw(OVERLAY_Data *vedata);

View File

@ -36,10 +36,8 @@
#include "BLI_math.h"
#include "BLI_utildefines.h"
#include "GPU_immediate.h"
#include "GPU_immediate_util.h"
#include "GPU_matrix.h"
#include "GPU_state.h"
#include "PIL_time.h"
#include "BLT_translation.h"
#include "BKE_context.h"
@ -422,68 +420,13 @@ bool ED_object_mode_generic_has_data(struct Depsgraph *depsgraph, struct Object
/** \} */
/* -------------------------------------------------------------------- */
/* -------------------------------------------------------------------- */
/** \name Transfer Mode
*
* Enters the same mode of the current active object in another object,
* leaving the mode of the current object.
* \{ */
typedef struct SwitchObjectCustomData {
void *draw_handle;
Object *target_object;
Mesh *mesh;
MLoopTri *looptri;
wmTimer *timer;
int tottris;
double start_time;
float alpha;
} SwitchObjectCustomData;
static void transfer_mode_draw(const bContext *UNUSED(C), ARegion *UNUSED(ar), void *arg)
{
SwitchObjectCustomData *cd = arg;
if (!cd->mesh) {
return;
}
if (!cd->looptri) {
return;
}
GPU_blend(GPU_BLEND_ALPHA);
GPU_line_smooth(true);
uint pos3d = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_3D_CLIPPED_UNIFORM_COLOR);
GPU_matrix_push();
GPU_matrix_mul(cd->target_object->obmat);
immUniformThemeColorAlpha(TH_VERTEX_SELECT, 0.25 * cd->alpha);
Mesh *mesh = cd->mesh;
immBegin(GPU_PRIM_TRIS, cd->tottris * 3);
for (int i = 0; i < cd->tottris; i++) {
MLoopTri *looptri = &cd->looptri[i];
for (int j = 0; j < 3; j++) {
MLoop *loop = &mesh->mloop[looptri->tri[j]];
MVert *vert = &mesh->mvert[loop->v];
float co[3] = {0.0f, 0.0f, 0.0f};
immVertex3fv(pos3d, vert->co);
}
}
immEnd();
immUnbindProgram();
GPU_matrix_pop();
GPU_blend(GPU_BLEND_NONE);
GPU_line_smooth(false);
}
static bool object_transfer_mode_poll(bContext *C)
{
if (!CTX_wm_region_view3d(C)) {
@ -509,6 +452,13 @@ static void object_transfer_mode_reposition_view_pivot(bContext *C, const int mv
ups->last_stroke_valid = true;
}
static void object_overlay_mode_transfer_animation_start(bContext *C, Object *ob_dst)
{
Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C);
Object *ob_dst_eval = DEG_get_evaluated_object(depsgraph, ob_dst);
ob_dst_eval->runtime.overlay_mode_transfer_start_time = PIL_check_seconds_timer();
}
static bool object_transfer_mode_to_base(bContext *C, wmOperator *op, Base *base_dst)
{
Scene *scene = CTX_data_scene(C);
@ -546,6 +496,8 @@ static bool object_transfer_mode_to_base(bContext *C, wmOperator *op, Base *base
ob_dst_orig = DEG_get_original_object(ob_dst);
ED_object_mode_set_ex(C, last_mode, true, op->reports);
object_overlay_mode_transfer_animation_start(C, ob_dst);
WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene);
WM_toolsystem_update_from_context_view3d(C);
mode_transfered = true;
@ -555,74 +507,8 @@ static bool object_transfer_mode_to_base(bContext *C, wmOperator *op, Base *base
return mode_transfered;
}
static bool object_transfer_mode_flash_animation_update(bContext *C, wmOperator *op) {
SwitchObjectCustomData *cd = op->customdata;
if (cd == NULL) {
return true;
}
ARegion *region = CTX_wm_region(C);
if (cd->start_time == 0.0) {
cd->start_time = PIL_check_seconds_timer();
}
const double time = PIL_check_seconds_timer();
const double delta_time = time - cd->start_time;
float alpha = 1.0f - (4.0 * delta_time);
if (alpha > 0.01f) {
cd->alpha = alpha;
ED_region_tag_redraw(region);
return false;
}
WM_event_remove_timer(CTX_wm_manager(C), CTX_wm_window(C), cd->timer);
ED_region_draw_cb_exit(region->type, cd->draw_handle);
MEM_freeN(op->customdata);
ED_region_tag_redraw(region);
return true;
}
static void object_transfer_mode_flash_animation_begin(bContext *C, wmOperator *op, Base *base_dst) {
if (!base_dst) {
return;
}
if (!base_dst->object) {
return;
}
ARegion *region = CTX_wm_region(C);
SwitchObjectCustomData *cd = MEM_callocN(sizeof(SwitchObjectCustomData),
"Switch Object Custom Data");
cd->timer = WM_event_add_timer(CTX_wm_manager(C), CTX_wm_window(C), TIMER, 0.05f);
cd->draw_handle = ED_region_draw_cb_activate(
region->type, transfer_mode_draw, cd, REGION_DRAW_POST_VIEW);
cd->target_object = base_dst->object;
cd->start_time = 0.0;
Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
Object *evaluated_object = DEG_get_evaluated_object(depsgraph, cd->target_object);
Mesh *mesh = BKE_modifier_get_evaluated_mesh_from_evaluated_object(evaluated_object, false);
const MLoopTri *looptri = BKE_mesh_runtime_looptri_ensure(mesh);
cd->looptri = looptri;
cd->tottris = BKE_mesh_runtime_looptri_len(mesh);
cd->mesh = mesh;
cd->alpha = 1.0f;
op->customdata = cd;
}
static int object_transfer_mode_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
const bool use_eyedropper = RNA_boolean_get(op->ptr, "use_eyedropper");
const bool flash_object = RNA_boolean_get(op->ptr, "flash_object");
if (use_eyedropper) {
switch (event->type) {
case LEFTMOUSE:
if (event->val == KM_PRESS) {
@ -644,12 +530,7 @@ static int object_transfer_mode_modal(bContext *C, wmOperator *op, const wmEvent
return OPERATOR_CANCELLED;
}
if (!flash_object) {
return OPERATOR_FINISHED;
}
object_transfer_mode_flash_animation_begin(C, op, base_dst);
return OPERATOR_FINISHED;
}
break;
case RIGHTMOUSE: {
@ -658,24 +539,12 @@ static int object_transfer_mode_modal(bContext *C, wmOperator *op, const wmEvent
return OPERATOR_CANCELLED;
}
}
if (!flash_object) {
return OPERATOR_RUNNING_MODAL;
}
}
if (!object_transfer_mode_flash_animation_update(C, op)) {
return OPERATOR_RUNNING_MODAL;
}
return OPERATOR_FINISHED;
return OPERATOR_RUNNING_MODAL;
}
static int object_transfer_mode_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
const bool use_eyedropper = RNA_boolean_get(op->ptr, "use_eyedropper");
const bool flash_object = RNA_boolean_get(op->ptr, "flash_object");
if (use_eyedropper) {
ED_workspace_status_text(C, TIP_("Click in the viewport to select an object"));
WM_cursor_modal_set(CTX_wm_window(C), WM_CURSOR_EYEDROPPER);
@ -696,14 +565,7 @@ static int object_transfer_mode_invoke(bContext *C, wmOperator *op, const wmEven
object_transfer_mode_reposition_view_pivot(C, event->mval);
}
if (!flash_object) {
return OPERATOR_FINISHED;
}
object_transfer_mode_flash_animation_begin(C, op, base_dst);
WM_event_add_modal_handler(C, op);
return OPERATOR_RUNNING_MODAL;
return OPERATOR_FINISHED;
}
void OBJECT_OT_transfer_mode(wmOperatorType *ot)
@ -723,9 +585,6 @@ void OBJECT_OT_transfer_mode(wmOperatorType *ot)
/* Undo push is handled by the operator. */
ot->flag = OPTYPE_REGISTER;
RNA_def_boolean(
ot->srna, "flash_object", true, "Flash Object", "Flash object when entering the new mode");
RNA_def_boolean(ot->srna,
"use_eyedropper",
false,
@ -733,4 +592,4 @@ void OBJECT_OT_transfer_mode(wmOperatorType *ot)
"Pick the object to switch to using an eyedropper");
}
/** \} */
/** \} */

View File

@ -144,6 +144,9 @@ typedef struct Object_Runtime {
*/
char is_data_eval_owned;
/** Start time of the mode transfer overlay animation. */
double overlay_mode_transfer_start_time;
/** Axis aligned boundbox (in localspace). */
struct BoundBox *bb;

View File

@ -515,6 +515,7 @@ enum {
V3D_OVERLAY_HIDE_OBJECT_ORIGINS = (1 << 10),
V3D_OVERLAY_STATS = (1 << 11),
V3D_OVERLAY_FADE_INACTIVE = (1 << 12),
V3D_OVERLAY_MODE_TRANSFER = (1 << 13),
};
/** #View3DOverlay.edit_flag */

View File

@ -4129,6 +4129,14 @@ static void rna_def_space_view3d_overlay(BlenderRNA *brna)
prop, "Fade Inactive Objects", "Fade inactive geometry using the viewport background color");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL);
prop = RNA_def_property(srna, "show_mode_transfer", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "overlay.flag", V3D_OVERLAY_MODE_TRANSFER);
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
RNA_def_property_ui_text(prop,
"Flash on Mode Transfer",
"Flash the target object when tranfering the active mode to it");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL);
prop = RNA_def_property(srna, "fade_inactive_alpha", PROP_FLOAT, PROP_FACTOR);
RNA_def_property_float_sdna(prop, NULL, "overlay.fade_alpha");
RNA_def_property_ui_text(prop, "Opacity", "Strength of the fade effect");