blender-v3.6-release backports #111977

Merged
Philipp Oeser merged 17 commits from lichtwerk/blender:blender-v3.6-release into blender-v3.6-release 2023-09-05 15:50:28 +02:00
19 changed files with 177 additions and 67 deletions

View File

@ -164,7 +164,7 @@ ccl_device_noinline int svm_node_vector_displacement(
tangent = normalize(sd->dPdu);
}
float3 bitangent = normalize(cross(normal, tangent));
float3 bitangent = safe_normalize(cross(normal, tangent));
const AttributeDescriptor attr_sign = find_attribute(kg, sd, node.w);
if (attr_sign.offset != ATTR_STD_NOT_FOUND) {
float sign = primitive_surface_attribute_float(kg, sd, attr_sign, NULL, NULL);

View File

@ -717,6 +717,8 @@ class DOPESHEET_MT_channel_context_menu(Menu):
# This menu is used from the graph editor too.
is_graph_editor = context.area.type == 'GRAPH_EDITOR'
layout.operator_context = 'INVOKE_REGION_CHANNELS'
layout.separator()
layout.operator("anim.channels_view_selected")

View File

@ -384,7 +384,7 @@ static int remove_keyingset_button_exec(bContext *C, wmOperator *op)
int index = 0;
/* try to add to keyingset using property retrieved from UI */
if (UI_context_active_but_prop_get(C, &ptr, &prop, &index)) {
if (!UI_context_active_but_prop_get(C, &ptr, &prop, &index)) {
/* pass event on if no active button found */
return (OPERATOR_CANCELLED | OPERATOR_PASS_THROUGH);
}

View File

@ -2996,6 +2996,8 @@ static void constraint_ops_extra_draw(bContext *C, uiLayout *layout, void *con_v
uiLayoutSetUnitsX(layout, 4.0f);
UI_block_flag_enable(uiLayoutGetBlock(layout), UI_BLOCK_IS_FLIP);
/* Apply. */
uiItemO(layout,
CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Apply"),

View File

@ -1522,11 +1522,12 @@ static int make_links_data_exec(bContext *C, wmOperator *op)
case MAKE_LINKS_ANIMDATA:
BKE_animdata_copy_id(bmain, (ID *)ob_dst, (ID *)ob_src, 0);
if (ob_dst->data && ob_src->data) {
if (!BKE_id_is_editable(bmain, obdata_id)) {
is_lib = true;
break;
if (BKE_id_is_editable(bmain, obdata_id)) {
BKE_animdata_copy_id(bmain, (ID *)ob_dst->data, (ID *)ob_src->data, 0);
}
else {
is_lib = true;
}
BKE_animdata_copy_id(bmain, (ID *)ob_dst->data, (ID *)ob_src->data, 0);
}
DEG_id_tag_update(&ob_dst->id,
ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY | ID_RECALC_ANIMATION);
@ -2060,15 +2061,18 @@ static void tag_localizable_objects(bContext *C, const int mode)
/* Also forbid making objects local if other library objects are using
* them for modifiers or constraints.
*
* FIXME This is ignoring all other linked ID types potentially using the selected tagged
* objects! Probably works fine in most 'usual' cases though.
*/
for (Object *object = bmain->objects.first; object; object = object->id.next) {
if ((object->id.tag & LIB_TAG_DOIT) == 0) {
if ((object->id.tag & LIB_TAG_DOIT) == 0 && ID_IS_LINKED(object)) {
BKE_library_foreach_ID_link(
NULL, &object->id, tag_localizable_looper, NULL, IDWALK_READONLY);
}
if (object->data) {
ID *data_id = (ID *)object->data;
if ((data_id->tag & LIB_TAG_DOIT) == 0) {
if ((data_id->tag & LIB_TAG_DOIT) == 0 && ID_IS_LINKED(data_id)) {
BKE_library_foreach_ID_link(NULL, data_id, tag_localizable_looper, NULL, IDWALK_READONLY);
}
}

View File

@ -388,7 +388,7 @@ static bool screen_areas_can_align(bScreen *screen, ScrArea *sa1, ScrArea *sa2,
if (area->v3->vec.x - area->v1->vec.x < tolerance &&
(area->v1->vec.x == xmin || area->v3->vec.x == xmax))
{
/* There is a narrow vertical area sharing an edge of the combined bounds. */
WM_report(RPT_ERROR, "A narrow vertical area interferes with this operation.");
return false;
}
}
@ -403,7 +403,7 @@ static bool screen_areas_can_align(bScreen *screen, ScrArea *sa1, ScrArea *sa2,
if (area->v3->vec.y - area->v1->vec.y < tolerance &&
(area->v1->vec.y == ymin || area->v3->vec.y == ymax))
{
/* There is a narrow horizontal area sharing an edge of the combined bounds. */
WM_report(RPT_ERROR, "A narrow horizontal area interferes with this operation.");
return false;
}
}

View File

@ -468,6 +468,8 @@ static void workspace_add_menu(bContext *UNUSED(C), uiLayout *layout, void *temp
WorkspaceConfigFileData *startup_config = workspace_config_file_read(app_template);
WorkspaceConfigFileData *builtin_config = workspace_system_file_read(app_template);
UI_block_flag_enable(uiLayoutGetBlock(layout), UI_BLOCK_IS_FLIP);
if (startup_config) {
LISTBASE_FOREACH (WorkSpace *, workspace, &startup_config->workspaces) {
uiLayout *row = uiLayoutRow(layout, false);

View File

@ -12,6 +12,8 @@
#include "MEM_guardedalloc.h"
#include "CLG_log.h"
#include "BLI_array_utils.h"
#include "BLI_color.hh"
#include "BLI_color_mix.hh"
@ -72,6 +74,8 @@ using blender::IndexRange;
using namespace blender;
using namespace blender::color;
static CLG_LogRef LOG = {"ed.sculpt_paint"};
/* -------------------------------------------------------------------- */
/** \name Internal Utilities
* \{ */
@ -1559,34 +1563,43 @@ struct WPaintData {
static void smooth_brush_toggle_on(const bContext *C, Paint *paint, StrokeCache *cache)
{
Scene *scene = CTX_data_scene(C);
Brush *brush = paint->brush;
int cur_brush_size = BKE_brush_size_get(scene, brush);
STRNCPY(cache->saved_active_brush_name, brush->id.name + 2);
/* Switch to the blur (smooth) brush. */
brush = BKE_paint_toolslots_brush_get(paint, WPAINT_TOOL_BLUR);
if (brush) {
BKE_paint_brush_set(paint, brush);
cache->saved_smooth_size = BKE_brush_size_get(scene, brush);
BKE_brush_size_set(scene, brush, cur_brush_size);
BKE_curvemapping_init(brush->curve);
/* Switch to the blur (smooth) brush if possible. */
/* Note: used for both vertexpaint and weightpaint, VPAINT_TOOL_BLUR & WPAINT_TOOL_BLUR are the
* same, see comments for eBrushVertexPaintTool & eBrushWeightPaintTool. */
Brush *smooth_brush = BKE_paint_toolslots_brush_get(paint, WPAINT_TOOL_BLUR);
if (!smooth_brush) {
CLOG_WARN(&LOG, "Switching to the blur (smooth) brush not possible, corresponding brush not");
cache->saved_active_brush_name[0] = '\0';
return;
}
Brush *cur_brush = paint->brush;
int cur_brush_size = BKE_brush_size_get(scene, cur_brush);
STRNCPY(cache->saved_active_brush_name, cur_brush->id.name + 2);
BKE_paint_brush_set(paint, smooth_brush);
cache->saved_smooth_size = BKE_brush_size_get(scene, smooth_brush);
BKE_brush_size_set(scene, smooth_brush, cur_brush_size);
BKE_curvemapping_init(smooth_brush->curve);
}
static void smooth_brush_toggle_off(const bContext *C, Paint *paint, StrokeCache *cache)
{
Main *bmain = CTX_data_main(C);
Scene *scene = CTX_data_scene(C);
Brush *brush = BKE_paint_brush(paint);
/* The current brush should match with what we have stored in the cache. */
BLI_assert(brush == cache->brush);
/* Try to switch back to the saved/previous brush. */
BKE_brush_size_set(scene, brush, cache->saved_smooth_size);
brush = (Brush *)BKE_libblock_find_name(bmain, ID_BR, cache->saved_active_brush_name);
if (brush) {
BKE_paint_brush_set(paint, brush);
/* If saved_active_brush_name is not set, brush was not switched/affected in
* smooth_brush_toggle_on(). */
Brush *saved_active_brush = (Brush *)BKE_libblock_find_name(
bmain, ID_BR, cache->saved_active_brush_name);
if (saved_active_brush) {
Scene *scene = CTX_data_scene(C);
BKE_brush_size_set(scene, brush, cache->saved_smooth_size);
BKE_paint_brush_set(paint, saved_active_brush);
}
}

View File

@ -12,6 +12,8 @@
#include "MEM_guardedalloc.h"
#include "CLG_log.h"
#include "BLI_blenlib.h"
#include "BLI_dial_2d.h"
#include "BLI_ghash.h"
@ -82,6 +84,8 @@ using blender::Set;
using blender::Span;
using blender::Vector;
static CLG_LogRef LOG = {"ed.sculpt_paint"};
static float sculpt_calc_radius(ViewContext *vc,
const Brush *brush,
const Scene *scene,
@ -4388,40 +4392,43 @@ static void sculpt_init_mirror_clipping(Object *ob, SculptSession *ss)
static void smooth_brush_toggle_on(const bContext *C, Paint *paint, StrokeCache *cache)
{
Scene *scene = CTX_data_scene(C);
Brush *brush = paint->brush;
Brush *cur_brush = paint->brush;
if (brush->sculpt_tool == SCULPT_TOOL_MASK) {
cache->saved_mask_brush_tool = brush->mask_tool;
brush->mask_tool = BRUSH_MASK_SMOOTH;
if (cur_brush->sculpt_tool == SCULPT_TOOL_MASK) {
cache->saved_mask_brush_tool = cur_brush->mask_tool;
cur_brush->mask_tool = BRUSH_MASK_SMOOTH;
}
else if (ELEM(brush->sculpt_tool,
else if (ELEM(cur_brush->sculpt_tool,
SCULPT_TOOL_SLIDE_RELAX,
SCULPT_TOOL_DRAW_FACE_SETS,
SCULPT_TOOL_PAINT,
SCULPT_TOOL_SMEAR))
{
/* Do nothing, this tool has its own smooth mode. */
return;
}
else {
int cur_brush_size = BKE_brush_size_get(scene, brush);
STRNCPY(cache->saved_active_brush_name, brush->id.name + 2);
/* Switch to the smooth brush. */
brush = BKE_paint_toolslots_brush_get(paint, SCULPT_TOOL_SMOOTH);
if (brush) {
BKE_paint_brush_set(paint, brush);
cache->saved_smooth_size = BKE_brush_size_get(scene, brush);
BKE_brush_size_set(scene, brush, cur_brush_size);
BKE_curvemapping_init(brush->curve);
}
/* Switch to the smooth brush if possible. */
Brush *smooth_brush = BKE_paint_toolslots_brush_get(paint, SCULPT_TOOL_SMOOTH);
if (!smooth_brush) {
CLOG_WARN(&LOG, "Switching to the smooth brush not possible, corresponding brush not");
cache->saved_active_brush_name[0] = '\0';
return;
}
int cur_brush_size = BKE_brush_size_get(scene, cur_brush);
STRNCPY(cache->saved_active_brush_name, cur_brush->id.name + 2);
BKE_paint_brush_set(paint, smooth_brush);
cache->saved_smooth_size = BKE_brush_size_get(scene, smooth_brush);
BKE_brush_size_set(scene, smooth_brush, cur_brush_size);
BKE_curvemapping_init(smooth_brush->curve);
}
static void smooth_brush_toggle_off(const bContext *C, Paint *paint, StrokeCache *cache)
{
Main *bmain = CTX_data_main(C);
Scene *scene = CTX_data_scene(C);
Brush *brush = BKE_paint_brush(paint);
if (brush->sculpt_tool == SCULPT_TOOL_MASK) {
@ -4435,13 +4442,15 @@ static void smooth_brush_toggle_off(const bContext *C, Paint *paint, StrokeCache
{
/* Do nothing. */
}
else {
/* Try to switch back to the saved/previous brush. */
/* If saved_active_brush_name is not set, brush was not switched/affected in
* smooth_brush_toggle_on(). */
Brush *saved_active_brush = (Brush *)BKE_libblock_find_name(
bmain, ID_BR, cache->saved_active_brush_name);
if (saved_active_brush) {
Scene *scene = CTX_data_scene(C);
BKE_brush_size_set(scene, brush, cache->saved_smooth_size);
brush = (Brush *)BKE_libblock_find_name(bmain, ID_BR, cache->saved_active_brush_name);
if (brush) {
BKE_paint_brush_set(paint, brush);
}
BKE_paint_brush_set(paint, saved_active_brush);
}
}

View File

@ -2259,6 +2259,8 @@ static int keyframe_jump_exec(bContext *C, wmOperator *op)
BKE_scene_frame_set(scene, closest_frame);
ANIM_animdata_freelist(&anim_data);
/* Set notifier that things have changed. */
WM_event_add_notifier(C, NC_SCENE | ND_FRAME, ac.scene);
return OPERATOR_FINISHED;

View File

@ -65,6 +65,17 @@ static bool lib_id_preview_editing_poll(bContext *C)
return true;
}
static ID *lib_id_load_custom_preview_id_get(bContext *C, const wmOperator *op)
{
/* #invoke() gets the ID from context and saves it in the custom data. */
if (op->customdata) {
return static_cast<ID *>(op->customdata);
}
PointerRNA idptr = CTX_data_pointer_get(C, "id");
return static_cast<ID *>(idptr.data);
}
static int lib_id_load_custom_preview_exec(bContext *C, wmOperator *op)
{
char filepath[FILE_MAX];
@ -76,8 +87,12 @@ static int lib_id_load_custom_preview_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
PointerRNA idptr = CTX_data_pointer_get(C, "id");
ID *id = (ID *)idptr.data;
ID *id = lib_id_load_custom_preview_id_get(C, op);
if (!id) {
BKE_report(
op->reports, RPT_ERROR, "Failed to set preview: no ID in context (incorrect context?)");
return OPERATOR_CANCELLED;
}
BKE_previewimg_id_custom_set(id, filepath);
@ -86,6 +101,18 @@ static int lib_id_load_custom_preview_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
/**
* Obtain the ID from context, and spawn a File Browser to select the preview image. The
* File Browser may re-use the Asset Browser under the cursor, and clear the file-list on
* confirmation, leading to failure to obtain the ID at that point. So get it before spawning the
* File Browser (store it in the operator custom data).
*/
static int lib_id_load_custom_preview_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
op->customdata = lib_id_load_custom_preview_id_get(C, op);
return WM_operator_filesel(C, op, event);
}
static void ED_OT_lib_id_load_custom_preview(wmOperatorType *ot)
{
ot->name = "Load Custom Preview";
@ -95,7 +122,7 @@ static void ED_OT_lib_id_load_custom_preview(wmOperatorType *ot)
/* api callbacks */
ot->poll = lib_id_preview_editing_poll;
ot->exec = lib_id_load_custom_preview_exec;
ot->invoke = WM_operator_filesel;
ot->invoke = lib_id_load_custom_preview_invoke;
/* flags */
ot->flag = OPTYPE_UNDO | OPTYPE_INTERNAL;
@ -319,6 +346,9 @@ static int lib_id_override_editable_toggle_exec(bContext *C, wmOperator * /*op*/
else {
/* Reset override, which makes it non-editable (i.e. a system define override). */
BKE_lib_override_library_id_reset(bmain, id, true);
WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, nullptr);
WM_event_add_notifier(C, NC_WINDOW, nullptr);
}
WM_main_add_notifier(NC_WM | ND_LIB_OVERRIDE_CHANGED, nullptr);

View File

@ -237,6 +237,8 @@ static void gpencil_modifier_ops_extra_draw(bContext *C, uiLayout *layout, void
uiLayoutSetUnitsX(layout, 4.0f);
UI_block_flag_enable(uiLayoutGetBlock(layout), UI_BLOCK_IS_FLIP);
/* Apply. */
if (!(mti->flags & eGpencilModifierTypeFlag_NoApply)) {
uiItemO(layout,

View File

@ -3,7 +3,7 @@ void node_vector_displacement_tangent(
{
vec3 oN = normalize(normal_world_to_object(g_data.N));
vec3 oT = normalize(normal_world_to_object(T.xyz));
vec3 oB = T.w * normalize(cross(oN, oT));
vec3 oB = T.w * safe_normalize(cross(oN, oT));
result = (vector.xyz - midlevel) * scale;
result = result.x * oT + result.y * oN + result.z * oB;

View File

@ -838,13 +838,49 @@ static bool rna_Curve_is_editmode_get(PointerRNA *ptr)
}
}
static bool rna_TextCurve_is_select_bold_get(PointerRNA *ptr)
{
Curve *cu = (Curve *)ptr->owner_id;
if (cu->editfont != NULL) {
return (cu->editfont->select_char_info_flag & CU_CHINFO_BOLD);
}
return false;
}
static bool rna_TextCurve_is_select_italic_get(PointerRNA *ptr)
{
Curve *cu = (Curve *)ptr->owner_id;
if (cu->editfont != NULL) {
return (cu->editfont->select_char_info_flag & CU_CHINFO_ITALIC);
}
return false;
}
static bool rna_TextCurve_is_select_underline_get(PointerRNA *ptr)
{
Curve *cu = (Curve *)ptr->owner_id;
if (cu->editfont != NULL) {
return (cu->editfont->select_char_info_flag & CU_CHINFO_UNDERLINE);
}
return false;
}
static bool rna_TextCurve_is_select_smallcaps_get(PointerRNA *ptr)
{
Curve *cu = (Curve *)ptr->owner_id;
if (cu->editfont != NULL) {
return (cu->editfont->select_char_info_flag & CU_CHINFO_SMALLCAPS);
}
return false;
}
static bool rna_TextCurve_has_selection_get(PointerRNA *ptr)
{
Curve *cu = (Curve *)ptr->owner_id;
if (cu->editfont != NULL)
if (cu->editfont != NULL) {
return (cu->editfont->selboxes != NULL);
else
return false;
}
return false;
}
#else
@ -1284,25 +1320,23 @@ static void rna_def_font(BlenderRNA *UNUSED(brna), StructRNA *srna)
RNA_def_property_update(prop, 0, "rna_Curve_update_data");
prop = RNA_def_property(srna, "is_select_bold", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "editfont->select_char_info_flag", CU_CHINFO_BOLD);
RNA_def_property_boolean_funcs(prop, "rna_TextCurve_is_select_bold_get", NULL);
RNA_def_property_ui_text(prop, "Selected Bold", "Whether the selected text is bold");
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
prop = RNA_def_property(srna, "is_select_italic", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "editfont->select_char_info_flag", CU_CHINFO_ITALIC);
RNA_def_property_boolean_funcs(prop, "rna_TextCurve_is_select_italic_get", NULL);
RNA_def_property_ui_text(prop, "Selected Italic", "Whether the selected text is italics");
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
prop = RNA_def_property(srna, "is_select_underline", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(
prop, NULL, "editfont->select_char_info_flag", CU_CHINFO_UNDERLINE);
RNA_def_property_boolean_funcs(prop, "rna_TextCurve_is_select_underline_get", NULL);
RNA_def_property_ui_text(prop, "Selected Underline", "Whether the selected text is underlined");
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
prop = RNA_def_property(srna, "is_select_smallcaps", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(
prop, NULL, "editfont->select_char_info_flag", CU_CHINFO_SMALLCAPS);
RNA_def_property_ui_text(prop, "Selected Smallcaps", "Whether the selected text is small caps");
RNA_def_property_boolean_funcs(prop, "rna_TextCurve_is_select_smallcaps_get", NULL);
RNA_def_property_ui_text(prop, "Selected Small Caps", "Whether the selected text is small caps");
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
prop = RNA_def_property(srna, "has_selection", PROP_BOOLEAN, PROP_NONE);

View File

@ -1907,7 +1907,9 @@ static bool rna_Node_unregister(Main *UNUSED(bmain), StructRNA *type)
{
bNodeType *nt = RNA_struct_blender_type_get(type);
if (!nt) {
/* `nt->rna_ext.data` is the python object. If it's nullptr then it's an
* internally registered node, thus can't unregister. */
if (!nt || !nt->rna_ext.data) {
return false;
}

View File

@ -204,6 +204,8 @@ static void modifier_ops_extra_draw(bContext *C, uiLayout *layout, void *md_v)
uiLayoutSetUnitsX(layout, 4.0f);
UI_block_flag_enable(uiLayoutGetBlock(layout), UI_BLOCK_IS_FLIP);
/* Apply. */
uiItemO(layout,
CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Apply"),

View File

@ -582,7 +582,9 @@ void seq_cache_free_temp_cache(Scene *scene, short id, int timeline_frame)
seq_cache_relink_keys(key->link_next, key->link_prev);
}
BLI_ghash_remove(cache->hash, key, seq_cache_keyfree, seq_cache_valfree);
BLI_assert(key != cache->last_key);
if (key == cache->last_key) {
cache->last_key = NULL;
}
}
}
}

View File

@ -1554,6 +1554,8 @@ void SEQ_modifier_list_copy(Sequence *seqn, Sequence *seq)
smdn->next = smdn->prev = NULL;
BLI_addtail(&seqn->modifiers, smdn);
BLI_uniquename(
&seqn->modifiers, smdn, "Strip Modifier", '.', offsetof(SequenceModifierData, name), 64);
}
}

View File

@ -120,6 +120,8 @@ static void gpencil_shaderfx_ops_extra_draw(bContext *C, uiLayout *layout, void
uiLayoutSetUnitsX(layout, 4.0f);
UI_block_flag_enable(uiLayoutGetBlock(layout), UI_BLOCK_IS_FLIP);
/* Duplicate. */
uiItemO(layout,
CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Duplicate"),