mirror of
https://github.com/blender/blender
synced 2026-09-29 04:37:17 +03:00
Merge branch 'master' into blender-v2.80-release
This commit is contained in:
commit
786f5ccea2
59 changed files with 837 additions and 1719 deletions
|
|
@ -3483,15 +3483,17 @@ def km_paint_curve(params):
|
|||
|
||||
items.extend([
|
||||
("paintcurve.add_point_slide", {"type": params.action_mouse, "value": 'PRESS', "ctrl": True}, None),
|
||||
("paintcurve.select", {"type": params.select_mouse, "value": params.select_mouse_value}, None),
|
||||
("paintcurve.select", {"type": params.select_mouse, "value": params.select_mouse_value, "shift": True},
|
||||
("paintcurve.select", {"type": params.select_mouse, "value": 'PRESS'},
|
||||
{"properties": [("extend", False)]}),
|
||||
("paintcurve.select", {"type": params.select_mouse, "value": 'PRESS', "shift": True},
|
||||
{"properties": [("extend", True)]}),
|
||||
("paintcurve.slide", {"type": params.action_mouse, "value": 'PRESS'}, None),
|
||||
("paintcurve.slide", {"type": params.action_mouse, "value": 'PRESS'},
|
||||
{"properties": [("align", False)]}),
|
||||
("paintcurve.slide", {"type": params.action_mouse, "value": 'PRESS', "shift": True},
|
||||
{"properties": [("align", True)]}),
|
||||
("paintcurve.select", {"type": 'A', "value": 'PRESS'},
|
||||
{"properties": [("toggle", True)]}),
|
||||
("paintcurve.cursor", {"type": params.action_mouse, "value": 'PRESS'}, None),
|
||||
("paintcurve.cursor", {"type": params.action_mouse, "value": 'PRESS', "shift": True, "ctrl": True}, None),
|
||||
("paintcurve.delete_point", {"type": 'X', "value": 'PRESS'}, None),
|
||||
("paintcurve.delete_point", {"type": 'DEL', "value": 'PRESS'}, None),
|
||||
("paintcurve.draw", {"type": 'RET', "value": 'PRESS'}, None),
|
||||
|
|
@ -4155,6 +4157,13 @@ def km_particle(params):
|
|||
{"properties": [("data_path_primary", 'tool_settings.particle_edit.brush.strength')]}),
|
||||
op_menu("VIEW3D_MT_particle_context_menu", params.context_menu_event),
|
||||
("particle.weight_set", {"type": 'K', "value": 'PRESS', "shift": True}, None),
|
||||
*(
|
||||
(("wm.context_set_enum",
|
||||
{"type": NUMBERS_1[i], "value": 'PRESS'},
|
||||
{"properties": [("data_path", "tool_settings.particle_edit.select_mode"), ("value", value)]})
|
||||
for i, value in enumerate(('PATH', 'POINT', 'TIP'))
|
||||
)
|
||||
),
|
||||
*_template_items_proportional_editing(connected=False),
|
||||
])
|
||||
|
||||
|
|
@ -5618,7 +5627,7 @@ def km_3d_view_tool_sculpt_box_hide(params):
|
|||
{"properties": [("action", 'HIDE')]}),
|
||||
("paint.hide_show", {"type": params.tool_tweak, "value": 'ANY', "ctrl": True},
|
||||
{"properties": [("action", 'SHOW')]}),
|
||||
("paint.hide_show", {"type": params.select_mouse, "value": 'PRESS'},
|
||||
("paint.hide_show", {"type": params.select_mouse, "value": params.select_mouse_value},
|
||||
{"properties": [("action", 'SHOW'), ("area", 'ALL')]}),
|
||||
]},
|
||||
)
|
||||
|
|
|
|||
|
|
@ -2697,10 +2697,12 @@ def km_paint_curve(params):
|
|||
|
||||
items.extend([
|
||||
("paintcurve.add_point_slide", {"type": 'LEFTMOUSE', "value": 'PRESS', "ctrl": True}, None),
|
||||
("paintcurve.select", {"type": 'LEFTMOUSE', "value": 'PRESS'}, None),
|
||||
("paintcurve.select", {"type": 'LEFTMOUSE', "value": 'PRESS'},
|
||||
{"properties": [("extend", False)]}),
|
||||
("paintcurve.select", {"type": 'LEFTMOUSE', "value": 'PRESS', "shift": True},
|
||||
{"properties": [("extend", True)]}),
|
||||
("paintcurve.slide", {"type": 'LEFTMOUSE', "value": 'PRESS'}, None),
|
||||
("paintcurve.slide", {"type": 'LEFTMOUSE', "value": 'PRESS'},
|
||||
{"properties": [("align", False)]}),
|
||||
("paintcurve.slide", {"type": 'LEFTMOUSE', "value": 'PRESS', "shift": True},
|
||||
{"properties": [("align", True)]}),
|
||||
("paintcurve.select", {"type": 'A', "value": 'PRESS'},
|
||||
|
|
|
|||
|
|
@ -40,22 +40,9 @@ class USERPREF_HT_header(Header):
|
|||
|
||||
row = layout.row()
|
||||
row.menu("USERPREF_MT_save_load", text="", icon='COLLAPSEMENU')
|
||||
# Use '_is_startup' so once factory settings are loaded
|
||||
# this display option will show, since it's confusing if disabling
|
||||
# the option makes it dissapiers.
|
||||
if prefs.use_preferences_save:
|
||||
use_userpref_skip_save_on_exit = bpy.app.use_userpref_skip_save_on_exit
|
||||
if use_userpref_skip_save_on_exit or getattr(USERPREF_HT_header, "_is_startup", False):
|
||||
USERPREF_HT_header._is_startup = True
|
||||
|
||||
sub = row.row(align=True)
|
||||
sub.alignment = 'LEFT'
|
||||
props = sub.operator(
|
||||
"preferences.autosave_override_toggle",
|
||||
text="Skip Auto-Save",
|
||||
emboss=False,
|
||||
icon='CHECKBOX_HLT' if use_userpref_skip_save_on_exit else 'CHECKBOX_DEHLT',
|
||||
)
|
||||
if prefs.use_preferences_save and (not bpy.app.use_userpref_skip_save_on_exit):
|
||||
pass
|
||||
else:
|
||||
sub = row.row(align=True)
|
||||
sub.active = prefs.is_dirty
|
||||
|
|
@ -103,13 +90,13 @@ class USERPREF_MT_save_load(Menu):
|
|||
|
||||
layout.operator_context = 'EXEC_AREA'
|
||||
if prefs.use_preferences_save:
|
||||
layout.operator("wm.save_userpref", text="Save Current State")
|
||||
layout.operator("wm.save_userpref", text="Save Preferences")
|
||||
sub_revert = layout.column(align=True)
|
||||
sub_revert.active = prefs.is_dirty
|
||||
sub_revert.operator("wm.read_userpref", text="Revert to Saved")
|
||||
sub_revert.operator("wm.read_userpref", text="Revert to Saved Preferences")
|
||||
|
||||
layout.operator_context = 'INVOKE_AREA'
|
||||
layout.operator("wm.read_factory_userpref", text="Load Factory Settings")
|
||||
layout.operator("wm.read_factory_userpref", text="Load Factory Preferences")
|
||||
|
||||
|
||||
class USERPREF_PT_save_preferences(Panel):
|
||||
|
|
|
|||
|
|
@ -160,6 +160,7 @@ void BKE_pose_copy_data(struct bPose **dst, const struct bPose *src, const bool
|
|||
void BKE_pose_channel_copy_data(struct bPoseChannel *pchan, const struct bPoseChannel *pchan_from);
|
||||
struct bPoseChannel *BKE_pose_channel_find_name(const struct bPose *pose, const char *name);
|
||||
struct bPoseChannel *BKE_pose_channel_active(struct Object *ob);
|
||||
struct bPoseChannel *BKE_pose_channel_active_or_first_selected(struct Object *ob);
|
||||
struct bPoseChannel *BKE_pose_channel_verify(struct bPose *pose, const char *name);
|
||||
struct bPoseChannel *BKE_pose_channel_get_mirrored(const struct bPose *pose, const char *name);
|
||||
|
||||
|
|
|
|||
|
|
@ -90,6 +90,8 @@ void BKE_armature_bone_hash_free(struct bArmature *arm);
|
|||
|
||||
bool BKE_armature_bone_flag_test_recursive(const struct Bone *bone, int flag);
|
||||
|
||||
void BKE_armature_refresh_layer_used(struct bArmature *arm);
|
||||
|
||||
float distfactor_to_bone(
|
||||
const float vec[3], const float b1[3], const float b2[3], float r1, float r2, float rdist);
|
||||
|
||||
|
|
|
|||
|
|
@ -30,7 +30,6 @@ extern "C" {
|
|||
struct Main;
|
||||
struct Text;
|
||||
struct TextLine;
|
||||
struct TextUndoBuf;
|
||||
|
||||
void BKE_text_free_lines(struct Text *text);
|
||||
void BKE_text_free(struct Text *text);
|
||||
|
|
@ -49,8 +48,8 @@ void BKE_text_copy_data(struct Main *bmain,
|
|||
const int flag);
|
||||
struct Text *BKE_text_copy(struct Main *bmain, const struct Text *ta);
|
||||
void BKE_text_make_local(struct Main *bmain, struct Text *text, const bool lib_local);
|
||||
void BKE_text_clear(struct Text *text, struct TextUndoBuf *utxt);
|
||||
void BKE_text_write(struct Text *text, struct TextUndoBuf *utxt, const char *str);
|
||||
void BKE_text_clear(struct Text *text);
|
||||
void BKE_text_write(struct Text *text, const char *str);
|
||||
int BKE_text_file_modified_check(struct Text *text);
|
||||
void BKE_text_file_modified_ignore(struct Text *text);
|
||||
|
||||
|
|
@ -77,29 +76,26 @@ void txt_move_eol(struct Text *text, const bool sel);
|
|||
void txt_move_toline(struct Text *text, unsigned int line, const bool sel);
|
||||
void txt_move_to(struct Text *text, unsigned int line, unsigned int ch, const bool sel);
|
||||
void txt_pop_sel(struct Text *text);
|
||||
void txt_delete_char(struct Text *text, struct TextUndoBuf *utxt);
|
||||
void txt_delete_word(struct Text *text, struct TextUndoBuf *utxt);
|
||||
void txt_delete_selected(struct Text *text, struct TextUndoBuf *utxt);
|
||||
void txt_delete_char(struct Text *text);
|
||||
void txt_delete_word(struct Text *text);
|
||||
void txt_delete_selected(struct Text *text);
|
||||
void txt_sel_all(struct Text *text);
|
||||
void txt_sel_clear(struct Text *text);
|
||||
void txt_sel_line(struct Text *text);
|
||||
char *txt_sel_to_buf(struct Text *text, int *r_buf_strlen);
|
||||
void txt_insert_buf(struct Text *text, struct TextUndoBuf *utxt, const char *in_buffer);
|
||||
void txt_undo_add_op(struct Text *text, struct TextUndoBuf *utxt, int op);
|
||||
void txt_do_undo(struct Text *text, struct TextUndoBuf *utxt);
|
||||
void txt_do_redo(struct Text *text, struct TextUndoBuf *utxt);
|
||||
void txt_split_curline(struct Text *text, struct TextUndoBuf *utxt);
|
||||
void txt_backspace_char(struct Text *text, struct TextUndoBuf *utxt);
|
||||
void txt_backspace_word(struct Text *text, struct TextUndoBuf *utxt);
|
||||
bool txt_add_char(struct Text *text, struct TextUndoBuf *utxt, unsigned int add);
|
||||
bool txt_add_raw_char(struct Text *text, struct TextUndoBuf *utxt, unsigned int add);
|
||||
bool txt_replace_char(struct Text *text, struct TextUndoBuf *utxt, unsigned int add);
|
||||
void txt_unindent(struct Text *text, struct TextUndoBuf *utxt);
|
||||
void txt_comment(struct Text *text, struct TextUndoBuf *utxt);
|
||||
void txt_indent(struct Text *text, struct TextUndoBuf *utxt);
|
||||
void txt_uncomment(struct Text *text, struct TextUndoBuf *utxt);
|
||||
void txt_move_lines(struct Text *text, struct TextUndoBuf *utxt, const int direction);
|
||||
void txt_duplicate_line(struct Text *text, struct TextUndoBuf *utxt);
|
||||
void txt_insert_buf(struct Text *text, const char *in_buffer);
|
||||
void txt_split_curline(struct Text *text);
|
||||
void txt_backspace_char(struct Text *text);
|
||||
void txt_backspace_word(struct Text *text);
|
||||
bool txt_add_char(struct Text *text, unsigned int add);
|
||||
bool txt_add_raw_char(struct Text *text, unsigned int add);
|
||||
bool txt_replace_char(struct Text *text, unsigned int add);
|
||||
void txt_unindent(struct Text *text);
|
||||
void txt_comment(struct Text *text);
|
||||
void txt_indent(struct Text *text);
|
||||
void txt_uncomment(struct Text *text);
|
||||
void txt_move_lines(struct Text *text, const int direction);
|
||||
void txt_duplicate_line(struct Text *text);
|
||||
int txt_setcurr_tab_spaces(struct Text *text, int space);
|
||||
bool txt_cursor_is_line_start(struct Text *text);
|
||||
bool txt_cursor_is_line_end(struct Text *text);
|
||||
|
|
@ -125,10 +121,9 @@ enum {
|
|||
TXT_MOVE_LINE_DOWN = 1,
|
||||
};
|
||||
|
||||
typedef struct TextUndoBuf {
|
||||
char *buf;
|
||||
int pos, len;
|
||||
} TextUndoBuf;
|
||||
/* Fast non-validating buffer conversion for undo. */
|
||||
char *txt_to_buf_for_undo(struct Text *text, int *r_buf_strlen);
|
||||
void txt_from_buf_for_undo(struct Text *text, const char *buf, int buf_len);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
|||
|
|
@ -43,6 +43,7 @@
|
|||
#include "BLT_translation.h"
|
||||
|
||||
#include "BKE_action.h"
|
||||
#include "BKE_armature.h"
|
||||
#include "BKE_anim.h"
|
||||
#include "BKE_animsys.h"
|
||||
#include "BKE_constraint.h"
|
||||
|
|
@ -524,6 +525,38 @@ bPoseChannel *BKE_pose_channel_active(Object *ob)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Use this when detecting the "other selected bone",
|
||||
* when we have multiple armatures in pose mode.
|
||||
*
|
||||
* In this case the active-selected is an obvious choice when finding the target for a
|
||||
* constraint for eg. however from the users perspective the active pose bone of the
|
||||
* active object is the _real_ active bone, so any other non-active selected bone
|
||||
* is a candidate for being the other selected bone, see: T58447.
|
||||
*/
|
||||
bPoseChannel *BKE_pose_channel_active_or_first_selected(struct Object *ob)
|
||||
{
|
||||
bArmature *arm = (ob) ? ob->data : NULL;
|
||||
|
||||
if (ELEM(NULL, ob, ob->pose, arm)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bPoseChannel *pchan = BKE_pose_channel_active(ob);
|
||||
if (pchan && (pchan->bone->flag & BONE_SELECTED) && PBONE_VISIBLE(arm, pchan->bone)) {
|
||||
return pchan;
|
||||
}
|
||||
|
||||
for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) {
|
||||
if (pchan->bone != NULL) {
|
||||
if ((pchan->bone->flag & BONE_SELECTED) && PBONE_VISIBLE(arm, pchan->bone)) {
|
||||
return pchan;
|
||||
}
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* \see #ED_armature_ebone_get_mirrored (edit-mode, matching function)
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -324,6 +324,24 @@ bool BKE_armature_bone_flag_test_recursive(const Bone *bone, int flag)
|
|||
}
|
||||
}
|
||||
|
||||
static void armature_refresh_layer_used_recursive(bArmature *arm, ListBase *bones)
|
||||
{
|
||||
for (Bone *bone = bones->first; bone; bone = bone->next) {
|
||||
arm->layer_used |= bone->layer;
|
||||
armature_refresh_layer_used_recursive(arm, &bone->childbase);
|
||||
}
|
||||
}
|
||||
|
||||
/* Update the layers_used variable after bones are moved between layer
|
||||
* NOTE: Used to be done in drawing code in 2.7, but that won't work with
|
||||
* Copy-on-Write, as drawing uses evaluated copies.
|
||||
*/
|
||||
void BKE_armature_refresh_layer_used(bArmature *arm)
|
||||
{
|
||||
arm->layer_used = 0;
|
||||
armature_refresh_layer_used_recursive(arm, &arm->bonebase);
|
||||
}
|
||||
|
||||
/* Finds the best possible extension to the name on a particular axis. (For renaming, check for
|
||||
* unique names afterwards) strip_number: removes number extensions (TODO: not used)
|
||||
* axis: the axis to name on
|
||||
|
|
|
|||
|
|
@ -670,9 +670,14 @@ WorkspaceConfigFileData *BKE_blendfile_workspace_config_read(const char *filepat
|
|||
}
|
||||
|
||||
if (bfd) {
|
||||
workspace_config = MEM_mallocN(sizeof(*workspace_config), __func__);
|
||||
workspace_config = MEM_callocN(sizeof(*workspace_config), __func__);
|
||||
workspace_config->main = bfd->main;
|
||||
workspace_config->workspaces = bfd->main->workspaces;
|
||||
|
||||
/* Only 2.80+ files have actual workspaces, don't try to use screens
|
||||
* from older versions. */
|
||||
if (bfd->main->versionfile >= 280) {
|
||||
workspace_config->workspaces = bfd->main->workspaces;
|
||||
}
|
||||
|
||||
MEM_freeN(bfd);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -745,9 +745,6 @@ static short layer_collection_sync(ViewLayer *view_layer,
|
|||
}
|
||||
|
||||
lc->runtime_flag |= LAYER_COLLECTION_HAS_OBJECTS;
|
||||
|
||||
/* Make sure flags on base are usable right away. */
|
||||
BKE_base_eval_flags(base);
|
||||
}
|
||||
|
||||
runtime_flag |= lc->runtime_flag;
|
||||
|
|
@ -814,6 +811,10 @@ void BKE_layer_collection_sync(const Scene *scene, ViewLayer *view_layer)
|
|||
BLI_freelistN(&view_layer->object_bases);
|
||||
view_layer->object_bases = new_object_bases;
|
||||
|
||||
for (Base *base = view_layer->object_bases.first; base; base = base->next) {
|
||||
BKE_base_eval_flags(base);
|
||||
}
|
||||
|
||||
/* Always set a valid active collection. */
|
||||
LayerCollection *active = view_layer->active_collection;
|
||||
|
||||
|
|
|
|||
|
|
@ -1590,7 +1590,7 @@ void BKE_ptcache_id_from_softbody(PTCacheID *pid, Object *ob, SoftBody *sb)
|
|||
|
||||
pid->stack_index = pid->cache->index;
|
||||
|
||||
pid->default_step = 10;
|
||||
pid->default_step = 1;
|
||||
pid->max_step = 20;
|
||||
pid->file_type = PTCACHE_FILE_PTCACHE;
|
||||
}
|
||||
|
|
@ -1655,7 +1655,7 @@ void BKE_ptcache_id_from_particles(PTCacheID *pid, Object *ob, ParticleSystem *p
|
|||
|
||||
pid->info_types = (1 << BPHYS_DATA_TIMES);
|
||||
|
||||
pid->default_step = 10;
|
||||
pid->default_step = 1;
|
||||
pid->max_step = 20;
|
||||
pid->file_type = PTCACHE_FILE_PTCACHE;
|
||||
}
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -379,6 +379,14 @@ void DepsgraphRelationBuilder::add_particle_forcefield_relations(const Operation
|
|||
{
|
||||
ListBase *relations = build_effector_relations(graph_, eff->group);
|
||||
|
||||
/* Make sure physics effects like wind are properly re-evaluating the modifier stack. */
|
||||
if (!BLI_listbase_is_empty(relations)) {
|
||||
TimeSourceKey time_src_key;
|
||||
ComponentKey geometry_key(&object->id, NodeType::GEOMETRY);
|
||||
add_relation(
|
||||
time_src_key, geometry_key, "Effector Time -> Particle", RELATION_CHECK_BEFORE_ADD);
|
||||
}
|
||||
|
||||
LISTBASE_FOREACH (EffectorRelation *, relation, relations) {
|
||||
if (relation->ob != object) {
|
||||
/* Relation to forcefield object, optionally including geometry. */
|
||||
|
|
|
|||
|
|
@ -161,6 +161,12 @@ void EEVEE_effects_init(EEVEE_ViewLayerData *sldata,
|
|||
effects->enabled_effects |= EEVEE_occlusion_init(sldata, vedata);
|
||||
effects->enabled_effects |= EEVEE_screen_raytrace_init(sldata, vedata);
|
||||
|
||||
if ((effects->enabled_effects & EFFECT_TAA) && effects->taa_current_sample > 1) {
|
||||
/* Update matrices here because EEVEE_screen_raytrace_init can have reset the
|
||||
* taa_current_sample. (See T66811) */
|
||||
EEVEE_temporal_sampling_update_matrices(vedata);
|
||||
}
|
||||
|
||||
EEVEE_volumes_init(sldata, vedata);
|
||||
EEVEE_subsurface_init(sldata, vedata);
|
||||
|
||||
|
|
|
|||
|
|
@ -253,7 +253,6 @@ int EEVEE_temporal_sampling_init(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data
|
|||
if (!DRW_state_is_image_render()) {
|
||||
effects->taa_current_sample += 1;
|
||||
repro_flag = 0;
|
||||
EEVEE_temporal_sampling_update_matrices(vedata);
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
|
|
|||
|
|
@ -317,33 +317,31 @@ void workbench_material_shgroup_uniform(WORKBENCH_PrivateData *wpd,
|
|||
const bool deferred,
|
||||
const int interp)
|
||||
{
|
||||
if (deferred && !workbench_is_matdata_pass_enabled(wpd)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (workbench_material_determine_color_type(wpd, material->ima, ob, false) ==
|
||||
V3D_SHADING_TEXTURE_COLOR) {
|
||||
GPUTexture *tex = GPU_texture_from_blender(material->ima, material->iuser, GL_TEXTURE_2D);
|
||||
DRW_shgroup_uniform_texture(grp, "image", tex);
|
||||
DRW_shgroup_uniform_bool_copy(
|
||||
grp, "imagePremultiplied", (material->ima->alpha_mode == IMA_ALPHA_PREMUL));
|
||||
DRW_shgroup_uniform_bool_copy(grp, "imageNearest", (interp == SHD_INTERP_CLOSEST));
|
||||
}
|
||||
else {
|
||||
DRW_shgroup_uniform_vec3(grp,
|
||||
"materialDiffuseColor",
|
||||
(use_metallic) ? material->base_color : material->diffuse_color,
|
||||
1);
|
||||
}
|
||||
|
||||
if (SPECULAR_HIGHLIGHT_ENABLED(wpd)) {
|
||||
if (use_metallic) {
|
||||
DRW_shgroup_uniform_float(grp, "materialMetallic", &material->metallic, 1);
|
||||
if (!deferred || workbench_is_matdata_pass_enabled(wpd)) {
|
||||
if (workbench_material_determine_color_type(wpd, material->ima, ob, false) ==
|
||||
V3D_SHADING_TEXTURE_COLOR) {
|
||||
GPUTexture *tex = GPU_texture_from_blender(material->ima, material->iuser, GL_TEXTURE_2D);
|
||||
DRW_shgroup_uniform_texture(grp, "image", tex);
|
||||
DRW_shgroup_uniform_bool_copy(
|
||||
grp, "imagePremultiplied", (material->ima->alpha_mode == IMA_ALPHA_PREMUL));
|
||||
DRW_shgroup_uniform_bool_copy(grp, "imageNearest", (interp == SHD_INTERP_CLOSEST));
|
||||
}
|
||||
else {
|
||||
DRW_shgroup_uniform_vec3(grp, "materialSpecularColor", material->specular_color, 1);
|
||||
DRW_shgroup_uniform_vec3(grp,
|
||||
"materialDiffuseColor",
|
||||
(use_metallic) ? material->base_color : material->diffuse_color,
|
||||
1);
|
||||
}
|
||||
|
||||
if (SPECULAR_HIGHLIGHT_ENABLED(wpd)) {
|
||||
if (use_metallic) {
|
||||
DRW_shgroup_uniform_float(grp, "materialMetallic", &material->metallic, 1);
|
||||
}
|
||||
else {
|
||||
DRW_shgroup_uniform_vec3(grp, "materialSpecularColor", material->specular_color, 1);
|
||||
}
|
||||
DRW_shgroup_uniform_float(grp, "materialRoughness", &material->roughness, 1);
|
||||
}
|
||||
DRW_shgroup_uniform_float(grp, "materialRoughness", &material->roughness, 1);
|
||||
}
|
||||
|
||||
if (WORLD_CLIPPING_ENABLED(wpd)) {
|
||||
|
|
|
|||
|
|
@ -1978,6 +1978,7 @@ static void draw_armature_edit(Object *ob)
|
|||
static void draw_armature_pose(Object *ob, const float const_color[4])
|
||||
{
|
||||
const DRWContextState *draw_ctx = DRW_context_state_get();
|
||||
const Scene *scene = draw_ctx->scene;
|
||||
bArmature *arm = ob->data;
|
||||
bPoseChannel *pchan;
|
||||
int index = -1;
|
||||
|
|
@ -1990,19 +1991,35 @@ static void draw_armature_pose(Object *ob, const float const_color[4])
|
|||
return;
|
||||
}
|
||||
|
||||
// if (!(base->flag & OB_FROMDUPLI)) // TODO
|
||||
{
|
||||
bool is_pose_select = false;
|
||||
/* Object can be edited in the scene. */
|
||||
if ((ob->base_flag & (BASE_FROM_SET | BASE_FROM_DUPLI)) == 0) {
|
||||
if ((draw_ctx->object_mode & OB_MODE_POSE) || (ob == draw_ctx->object_pose)) {
|
||||
arm->flag |= ARM_POSEMODE;
|
||||
}
|
||||
is_pose_select =
|
||||
/* If we're in pose-mode or object-mode with the ability to enter pose mode. */
|
||||
(
|
||||
/* Draw as if in pose mode (when selection is possible). */
|
||||
(arm->flag & ARM_POSEMODE) ||
|
||||
/* When we're in object mode, which may select bones. */
|
||||
((ob->mode & OB_MODE_POSE) &&
|
||||
(
|
||||
/* Switch from object mode when object lock is disabled. */
|
||||
((draw_ctx->object_mode == OB_MODE_OBJECT) &&
|
||||
(scene->toolsettings->object_flag & SCE_OBJECT_MODE_LOCK) == 0) ||
|
||||
/* Allow selection when in weight-paint mode
|
||||
* (selection code ensures this wont become active). */
|
||||
((draw_ctx->object_mode == OB_MODE_WEIGHT_PAINT) &&
|
||||
(draw_ctx->object_pose != NULL))))) &&
|
||||
DRW_state_is_select();
|
||||
|
||||
if (arm->flag & ARM_POSEMODE) {
|
||||
if (is_pose_select) {
|
||||
const Object *ob_orig = DEG_get_original_object(ob);
|
||||
index = ob_orig->runtime.select_id;
|
||||
}
|
||||
}
|
||||
|
||||
const bool is_pose_select = (arm->flag & ARM_POSEMODE) && DRW_state_is_select();
|
||||
const bool show_text = DRW_state_show_text();
|
||||
const bool show_relations = ((draw_ctx->v3d->flag & V3D_HIDE_HELPLINES) == 0);
|
||||
|
||||
|
|
|
|||
|
|
@ -55,16 +55,17 @@ void main()
|
|||
#endif
|
||||
|
||||
#ifdef USE_POINTS
|
||||
gl_PointSize = sizeVertex;
|
||||
float size = sizeVertex * 2.0;
|
||||
gl_PointSize = size;
|
||||
|
||||
/* calculate concentric radii in pixels */
|
||||
float radius = 0.5 * sizeVertex;
|
||||
float radius = sizeVertex;
|
||||
|
||||
/* start at the outside and progress toward the center */
|
||||
radii[0] = radius;
|
||||
radii[1] = radius - 1.0;
|
||||
|
||||
/* convert to PointCoord units */
|
||||
radii /= sizeVertex;
|
||||
radii /= size;
|
||||
#endif
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1121,6 +1121,8 @@ static int armature_bone_primitive_add_exec(bContext *C, wmOperator *op)
|
|||
add_v3_v3v3(bone->tail, bone->head, imat[2]); // bone with unit length 1, pointing up Z
|
||||
}
|
||||
|
||||
ED_armature_edit_refresh_layer_used(obedit->data);
|
||||
|
||||
/* note, notifier might evolve */
|
||||
WM_event_add_notifier(C, NC_OBJECT | ND_BONE_SELECT, obedit);
|
||||
|
||||
|
|
|
|||
|
|
@ -862,6 +862,7 @@ static int armature_fill_bones_exec(bContext *C, wmOperator *op)
|
|||
}
|
||||
|
||||
/* updates */
|
||||
ED_armature_edit_refresh_layer_used(arm);
|
||||
WM_event_add_notifier(C, NC_OBJECT | ND_POSE, obedit);
|
||||
|
||||
/* free points */
|
||||
|
|
@ -1053,6 +1054,7 @@ static int armature_merge_exec(bContext *C, wmOperator *op)
|
|||
|
||||
/* updates */
|
||||
ED_armature_edit_sync_selection(arm->edbo);
|
||||
ED_armature_edit_refresh_layer_used(arm);
|
||||
WM_event_add_notifier(C, NC_OBJECT | ND_POSE, obedit);
|
||||
}
|
||||
MEM_freeN(objects);
|
||||
|
|
@ -1460,8 +1462,8 @@ static int armature_delete_selected_exec(bContext *C, wmOperator *UNUSED(op))
|
|||
changed_multi = true;
|
||||
|
||||
ED_armature_edit_sync_selection(arm->edbo);
|
||||
ED_armature_edit_refresh_layer_used(arm);
|
||||
BKE_pose_tag_recalc(CTX_data_main(C), obedit->pose);
|
||||
|
||||
WM_event_add_notifier(C, NC_OBJECT | ND_BONE_SELECT, obedit);
|
||||
}
|
||||
}
|
||||
|
|
@ -1635,6 +1637,7 @@ static int armature_dissolve_selected_exec(bContext *C, wmOperator *UNUSED(op))
|
|||
if (changed) {
|
||||
changed_multi = true;
|
||||
ED_armature_edit_sync_selection(arm->edbo);
|
||||
ED_armature_edit_refresh_layer_used(arm);
|
||||
WM_event_add_notifier(C, NC_OBJECT | ND_BONE_SELECT, obedit);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -38,6 +38,7 @@
|
|||
|
||||
#include "BKE_action.h"
|
||||
#include "BKE_animsys.h"
|
||||
#include "BKE_armature.h"
|
||||
#include "BKE_constraint.h"
|
||||
#include "BKE_context.h"
|
||||
#include "BKE_fcurve.h"
|
||||
|
|
@ -426,6 +427,7 @@ int join_armature_exec(bContext *C, wmOperator *op)
|
|||
ED_armature_from_edit(bmain, arm);
|
||||
ED_armature_edit_free(arm);
|
||||
|
||||
BKE_armature_refresh_layer_used(arm);
|
||||
DEG_id_tag_update(&scene->id, ID_RECALC_SELECT);
|
||||
WM_event_add_notifier(C, NC_SCENE | ND_OB_ACTIVE, scene);
|
||||
|
||||
|
|
@ -671,6 +673,9 @@ static int separate_armature_exec(bContext *C, wmOperator *op)
|
|||
|
||||
ED_armature_to_edit(obedit->data);
|
||||
|
||||
ED_armature_edit_refresh_layer_used(obedit->data);
|
||||
BKE_armature_refresh_layer_used(newob->data);
|
||||
|
||||
/* parents tips remain selected when connected children are removed. */
|
||||
ED_armature_edit_deselect_all(obedit);
|
||||
|
||||
|
|
|
|||
|
|
@ -85,6 +85,18 @@ void ED_armature_edit_validate_active(struct bArmature *arm)
|
|||
}
|
||||
}
|
||||
|
||||
/* Update the layers_used variable after bones are moved between layer
|
||||
* NOTE: Used to be done in drawing code in 2.7, but that won't work with
|
||||
* Copy-on-Write, as drawing uses evaluated copies.
|
||||
*/
|
||||
void ED_armature_edit_refresh_layer_used(bArmature *arm)
|
||||
{
|
||||
arm->layer_used = 0;
|
||||
for (EditBone *ebo = arm->edbo->first; ebo; ebo = ebo->next) {
|
||||
arm->layer_used |= ebo->layer;
|
||||
}
|
||||
}
|
||||
|
||||
/* *************************************************************** */
|
||||
/* Bone Operations */
|
||||
|
||||
|
|
|
|||
|
|
@ -872,6 +872,8 @@ static int pose_bone_layers_exec(bContext *C, wmOperator *op)
|
|||
RNA_boolean_set_array(&ptr, "layers", layers);
|
||||
|
||||
if (prev_ob != ob) {
|
||||
BKE_armature_refresh_layer_used(ob->data);
|
||||
|
||||
/* Note, notifier might evolve. */
|
||||
WM_event_add_notifier(C, NC_OBJECT | ND_POSE, ob);
|
||||
DEG_id_tag_update((ID *)ob->data, ID_RECALC_COPY_ON_WRITE);
|
||||
|
|
@ -949,6 +951,8 @@ static int armature_bone_layers_exec(bContext *C, wmOperator *op)
|
|||
}
|
||||
CTX_DATA_END;
|
||||
|
||||
ED_armature_edit_refresh_layer_used(ob->data);
|
||||
|
||||
/* note, notifier might evolve */
|
||||
WM_event_add_notifier(C, NC_OBJECT | ND_POSE, ob);
|
||||
|
||||
|
|
|
|||
|
|
@ -40,6 +40,7 @@
|
|||
#include "BKE_object.h"
|
||||
#include "BKE_report.h"
|
||||
#include "BKE_layer.h"
|
||||
#include "BKE_modifier.h"
|
||||
|
||||
#include "DEG_depsgraph.h"
|
||||
|
||||
|
|
@ -181,10 +182,17 @@ bool ED_armature_pose_select_pick_with_buffer(ViewLayer *view_layer,
|
|||
|
||||
if (!extend && !deselect && !toggle) {
|
||||
{
|
||||
uint bases_len = 0;
|
||||
Base **bases = BKE_object_pose_base_array_get_unique(view_layer, v3d, &bases_len);
|
||||
ED_pose_deselect_all_multi_ex(bases, bases_len, SEL_DESELECT, true);
|
||||
MEM_freeN(bases);
|
||||
/* Don't use 'BKE_object_pose_base_array_get_unique'
|
||||
* because we may be selecting from object mode. */
|
||||
FOREACH_VISIBLE_BASE_BEGIN (view_layer, v3d, base_iter) {
|
||||
Object *ob_iter = base_iter->object;
|
||||
if ((ob_iter->type == OB_ARMATURE) && (ob_iter->mode & OB_MODE_POSE)) {
|
||||
if (ED_pose_deselect_all(ob_iter, SEL_DESELECT, true)) {
|
||||
ED_pose_bone_select_tag_update(ob_iter);
|
||||
}
|
||||
}
|
||||
}
|
||||
FOREACH_VISIBLE_BASE_END;
|
||||
}
|
||||
nearBone->flag |= (BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL);
|
||||
arm->act_bone = nearBone;
|
||||
|
|
@ -240,6 +248,38 @@ bool ED_armature_pose_select_pick_with_buffer(ViewLayer *view_layer,
|
|||
return nearBone != NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* While in weight-paint mode, a single pose may be active as well.
|
||||
* While not common, it's possible we have multiple armatures deforming a mesh.
|
||||
*
|
||||
* This function de-selects all other objects, and selects the new base.
|
||||
* It can't be set to the active object because we need
|
||||
* to keep this set to the weight paint object.
|
||||
*/
|
||||
void ED_armature_pose_select_in_wpaint_mode(ViewLayer *view_layer, Base *base_select)
|
||||
{
|
||||
BLI_assert(base_select && (base_select->object->type == OB_ARMATURE));
|
||||
Object *ob_active = OBACT(view_layer);
|
||||
BLI_assert(ob_active && (ob_active->mode & OB_MODE_WEIGHT_PAINT));
|
||||
VirtualModifierData virtualModifierData;
|
||||
ModifierData *md = modifiers_getVirtualModifierList(ob_active, &virtualModifierData);
|
||||
for (; md; md = md->next) {
|
||||
if (md->type == eModifierType_Armature) {
|
||||
ArmatureModifierData *amd = (ArmatureModifierData *)md;
|
||||
Object *ob_arm = amd->object;
|
||||
if (ob_arm != NULL) {
|
||||
Base *base_arm = BKE_view_layer_base_find(view_layer, ob_arm);
|
||||
if ((base_arm != NULL) && (base_arm != base_select) && (base_arm->flag & BASE_SELECTED)) {
|
||||
ED_object_base_select(base_arm, BA_DESELECT);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if ((base_select->flag & BASE_SELECTED) == 0) {
|
||||
ED_object_base_select(base_select, BA_SELECT);
|
||||
}
|
||||
}
|
||||
|
||||
/* 'select_mode' is usual SEL_SELECT/SEL_DESELECT/SEL_TOGGLE/SEL_INVERT.
|
||||
* When true, 'ignore_visibility' makes this func also affect invisible bones
|
||||
* (hidden or on hidden layers). */
|
||||
|
|
|
|||
|
|
@ -579,6 +579,7 @@ static bool gp_brush_push_apply(
|
|||
mul_v3_v3fl(delta, gso->dvec, inf);
|
||||
|
||||
/* apply */
|
||||
mul_mat3_m4_v3(gso->object->obmat, delta); /* only rotation component */
|
||||
add_v3_v3(&pt->x, delta);
|
||||
|
||||
/* compute lock axis */
|
||||
|
|
@ -646,7 +647,9 @@ static bool gp_brush_pinch_apply(
|
|||
inf = gp_brush_influence_calc(gso, radius, co) / 5.0f;
|
||||
|
||||
/* 1) Make this point relative to the cursor/midpoint (dvec) */
|
||||
sub_v3_v3v3(vec, &pt->x, gso->dvec);
|
||||
float fpt[3];
|
||||
mul_v3_m4v3(fpt, gso->object->obmat, &pt->x);
|
||||
sub_v3_v3v3(vec, fpt, gso->dvec);
|
||||
|
||||
/* 2) Shrink the distance by pulling the point towards the midpoint
|
||||
* (0.0 = at midpoint, 1 = at edge of brush region)
|
||||
|
|
@ -664,7 +667,8 @@ static bool gp_brush_pinch_apply(
|
|||
mul_v3_fl(vec, fac);
|
||||
|
||||
/* 3) Translate back to original space, with the shrinkage applied */
|
||||
add_v3_v3v3(&pt->x, gso->dvec, vec);
|
||||
add_v3_v3v3(fpt, gso->dvec, vec);
|
||||
mul_v3_m4v3(&pt->x, gso->object->imat, fpt);
|
||||
|
||||
/* compute lock axis */
|
||||
gpsculpt_compute_lock_axis(gso, pt, save_pt);
|
||||
|
|
@ -713,11 +717,14 @@ static bool gp_brush_twist_apply(
|
|||
|
||||
axis_angle_normalized_to_mat3(rmat, axis, angle);
|
||||
|
||||
/* Rotate point (no matrix-space transforms needed, as GP points are in world space) */
|
||||
sub_v3_v3v3(vec, &pt->x, gso->dvec); /* make relative to center
|
||||
* (center is stored in dvec) */
|
||||
/* Rotate point */
|
||||
float fpt[3];
|
||||
mul_v3_m4v3(fpt, gso->object->obmat, &pt->x);
|
||||
sub_v3_v3v3(vec, fpt, gso->dvec); /* make relative to center
|
||||
* (center is stored in dvec) */
|
||||
mul_m3_v3(rmat, vec);
|
||||
add_v3_v3v3(&pt->x, vec, gso->dvec); /* restore */
|
||||
add_v3_v3v3(fpt, vec, gso->dvec); /* restore */
|
||||
mul_v3_m4v3(&pt->x, gso->object->imat, fpt);
|
||||
|
||||
/* compute lock axis */
|
||||
gpsculpt_compute_lock_axis(gso, pt, save_pt);
|
||||
|
|
@ -1090,8 +1097,12 @@ static void gp_brush_clone_add(bContext *C, tGP_BrushEditData *gso)
|
|||
* get pasted relative to where the cursor is now
|
||||
*/
|
||||
for (i = 0, pt = new_stroke->points; i < new_stroke->totpoints; i++, pt++) {
|
||||
/* Rotate around center new position */
|
||||
mul_mat3_m4_v3(gso->object->obmat, &pt->x); /* only rotation component */
|
||||
|
||||
/* assume that the delta can just be applied, and then everything works */
|
||||
add_v3_v3(&pt->x, delta);
|
||||
mul_m4_v3(gso->object->imat, &pt->x);
|
||||
}
|
||||
|
||||
/* Store ref for later */
|
||||
|
|
|
|||
|
|
@ -225,8 +225,8 @@ static void gp_primitive_update_cps(tGPDprimitive *tgpi)
|
|||
}
|
||||
else if (tgpi->type == GP_STROKE_CURVE) {
|
||||
mid_v2_v2v2(tgpi->midpoint, tgpi->start, tgpi->end);
|
||||
copy_v2_v2(tgpi->cp1, tgpi->midpoint);
|
||||
copy_v2_v2(tgpi->cp2, tgpi->cp1);
|
||||
interp_v2_v2v2(tgpi->cp1, tgpi->midpoint, tgpi->start, 0.33f);
|
||||
interp_v2_v2v2(tgpi->cp2, tgpi->midpoint, tgpi->end, 0.33f);
|
||||
}
|
||||
else if (tgpi->type == GP_STROKE_ARC) {
|
||||
if (tgpi->flip) {
|
||||
|
|
|
|||
|
|
@ -170,6 +170,10 @@ bool ED_armature_pose_select_pick_with_buffer(struct ViewLayer *view_layer,
|
|||
bool deselect,
|
||||
bool toggle,
|
||||
bool do_nearest);
|
||||
|
||||
void ED_armature_pose_select_in_wpaint_mode(struct ViewLayer *view_layer,
|
||||
struct Base *base_select);
|
||||
|
||||
bool ED_armature_edit_select_pick(
|
||||
struct bContext *C, const int mval[2], bool extend, bool deselect, bool toggle);
|
||||
|
||||
|
|
@ -184,6 +188,8 @@ EditBone *ED_armature_ebone_get_mirrored(const struct ListBase *edbo, EditBone *
|
|||
void ED_armature_edit_sync_selection(struct ListBase *edbo);
|
||||
void ED_armature_edit_validate_active(struct bArmature *arm);
|
||||
|
||||
void ED_armature_edit_refresh_layer_used(struct bArmature *arm);
|
||||
|
||||
struct Base *ED_armature_base_and_ebone_from_select_buffer(struct Base **bases,
|
||||
uint bases_len,
|
||||
int hit,
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@
|
|||
|
||||
struct ARegion;
|
||||
struct SpaceText;
|
||||
struct TextUndoBuf;
|
||||
struct UndoStep;
|
||||
struct UndoType;
|
||||
|
||||
bool ED_text_region_location_from_cursor(struct SpaceText *st,
|
||||
|
|
@ -37,6 +37,6 @@ bool ED_text_region_location_from_cursor(struct SpaceText *st,
|
|||
/* text_undo.c */
|
||||
void ED_text_undosys_type(struct UndoType *ut);
|
||||
|
||||
struct TextUndoBuf *ED_text_undo_push_init(struct bContext *C);
|
||||
struct UndoStep *ED_text_undo_push_init(struct bContext *C);
|
||||
|
||||
#endif /* __ED_TEXT_H__ */
|
||||
|
|
|
|||
|
|
@ -1030,23 +1030,6 @@ bool ui_popup_context_menu_for_button(bContext *C, uiBut *but)
|
|||
0,
|
||||
"");
|
||||
UI_but_func_set(but2, popup_change_shortcut_func, but, NULL);
|
||||
|
||||
but2 = uiDefIconTextBut(block,
|
||||
UI_BTYPE_BUT,
|
||||
0,
|
||||
ICON_BLANK1,
|
||||
CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Remove Shortcut"),
|
||||
0,
|
||||
0,
|
||||
w,
|
||||
UI_UNIT_Y,
|
||||
NULL,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
"");
|
||||
UI_but_func_set(but2, remove_shortcut_func, but, NULL);
|
||||
}
|
||||
else {
|
||||
but2 = uiDefIconTextBut(block,
|
||||
|
|
@ -1067,6 +1050,23 @@ bool ui_popup_context_menu_for_button(bContext *C, uiBut *but)
|
|||
"please use User Preferences otherwise"));
|
||||
UI_but_flag_enable(but2, UI_BUT_DISABLED);
|
||||
}
|
||||
|
||||
but2 = uiDefIconTextBut(block,
|
||||
UI_BTYPE_BUT,
|
||||
0,
|
||||
ICON_BLANK1,
|
||||
CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Remove Shortcut"),
|
||||
0,
|
||||
0,
|
||||
w,
|
||||
UI_UNIT_Y,
|
||||
NULL,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
"");
|
||||
UI_but_func_set(but2, remove_shortcut_func, but, NULL);
|
||||
}
|
||||
/* only show 'assign' if there's a suitable key map for it to go in */
|
||||
else if (WM_keymap_guess_opname(C, idname)) {
|
||||
|
|
|
|||
|
|
@ -1052,8 +1052,7 @@ static int reports_to_text_exec(bContext *C, wmOperator *UNUSED(op))
|
|||
str = BKE_reports_string(reports, (G.debug & G_DEBUG) ? RPT_DEBUG : RPT_INFO);
|
||||
|
||||
if (str) {
|
||||
TextUndoBuf *utxt = NULL; // FIXME
|
||||
BKE_text_write(txt, utxt, str);
|
||||
BKE_text_write(txt, str);
|
||||
MEM_freeN(str);
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
|
|
|
|||
|
|
@ -63,6 +63,21 @@ enum ePickerType {
|
|||
/** \name Color Conversion
|
||||
* \{ */
|
||||
|
||||
static void ui_color_picker_rgb_round(float rgb[3])
|
||||
{
|
||||
/* Handle small rounding errors in color space conversions. Doing these for
|
||||
* all color space conversions would be expensive, but for the color picker
|
||||
* we can do the extra work. */
|
||||
for (int i = 0; i < 3; i++) {
|
||||
if (fabsf(rgb[i]) < 1e-6f) {
|
||||
rgb[i] = 0.0f;
|
||||
}
|
||||
else if (fabsf(1.0f - rgb[i]) < 1e-6f) {
|
||||
rgb[i] = 1.0f;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ui_rgb_to_color_picker_compat_v(const float rgb[3], float r_cp[3])
|
||||
{
|
||||
switch (U.color_picker_type) {
|
||||
|
|
@ -131,6 +146,7 @@ void ui_scene_linear_to_color_picker_space(uiBut *but, float rgb[3])
|
|||
* space for intuitive color picking. */
|
||||
if (!ui_but_is_color_gamma(but)) {
|
||||
IMB_colormanagement_scene_linear_to_color_picking_v3(rgb);
|
||||
ui_color_picker_rgb_round(rgb);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -138,6 +154,7 @@ void ui_color_picker_to_scene_linear_space(uiBut *but, float rgb[3])
|
|||
{
|
||||
if (!ui_but_is_color_gamma(but)) {
|
||||
IMB_colormanagement_color_picking_to_scene_linear_v3(rgb);
|
||||
ui_color_picker_rgb_round(rgb);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -201,6 +218,7 @@ static void ui_update_color_picker_buts_rgb(uiBut *from_but,
|
|||
copy_v3_v3(rgb_hex, rgb);
|
||||
if (from_but && !ui_but_is_color_gamma(from_but)) {
|
||||
IMB_colormanagement_scene_linear_to_srgb_v3(rgb_hex);
|
||||
ui_color_picker_rgb_round(rgb_hex);
|
||||
}
|
||||
|
||||
rgb_float_to_uchar(rgb_hex_uchar, rgb_hex);
|
||||
|
|
@ -287,6 +305,7 @@ static void ui_colorpicker_hex_rna_cb(bContext *UNUSED(C), void *bt1, void *hexc
|
|||
/* Hex code is assumed to be in sRGB space (coming from other applications, web, etc) */
|
||||
if (!ui_but_is_color_gamma(but)) {
|
||||
IMB_colormanagement_srgb_to_scene_linear_v3(rgb);
|
||||
ui_color_picker_rgb_round(rgb);
|
||||
}
|
||||
|
||||
ui_update_color_picker_buts_rgb(but, but->block, cpicker, rgb);
|
||||
|
|
@ -765,6 +784,7 @@ static void ui_block_colorpicker(uiBlock *block, uiBut *from_but, float rgba[4],
|
|||
|
||||
if (!ui_but_is_color_gamma(from_but)) {
|
||||
IMB_colormanagement_scene_linear_to_srgb_v3(rgb_hex);
|
||||
ui_color_picker_rgb_round(rgb_hex);
|
||||
}
|
||||
|
||||
rgb_float_to_uchar(rgb_hex_uchar, rgb_hex);
|
||||
|
|
|
|||
|
|
@ -441,6 +441,7 @@ static int masklay_new_exec(bContext *C, wmOperator *op)
|
|||
mask->masklay_act = mask->masklay_tot - 1;
|
||||
|
||||
WM_event_add_notifier(C, NC_MASK | NA_EDITED, mask);
|
||||
DEG_id_tag_update(&mask->id, ID_RECALC_COPY_ON_WRITE);
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
|
@ -474,6 +475,7 @@ static int masklay_remove_exec(bContext *C, wmOperator *UNUSED(op))
|
|||
BKE_mask_layer_remove(mask, masklay);
|
||||
|
||||
WM_event_add_notifier(C, NC_MASK | NA_EDITED, mask);
|
||||
DEG_id_tag_update(&mask->id, ID_RECALC_COPY_ON_WRITE);
|
||||
}
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
|
|
@ -2206,6 +2208,7 @@ static int mask_layer_move_exec(bContext *C, wmOperator *op)
|
|||
}
|
||||
|
||||
WM_event_add_notifier(C, NC_MASK | NA_EDITED, mask);
|
||||
DEG_id_tag_update(&mask->id, ID_RECALC_COPY_ON_WRITE);
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@
|
|||
#include "BLT_translation.h"
|
||||
|
||||
#include "DNA_anim_types.h"
|
||||
#include "DNA_armature_types.h"
|
||||
#include "DNA_constraint_types.h"
|
||||
#include "DNA_curve_types.h"
|
||||
#include "DNA_scene_types.h"
|
||||
|
|
@ -1815,10 +1816,15 @@ static bool get_new_constraint_target(
|
|||
*/
|
||||
if ((ob->type == OB_ARMATURE) && (ob->mode & OB_MODE_POSE) &&
|
||||
(!only_curve && !only_mesh)) {
|
||||
/* just use the active bone, and assume that it is visible + usable */
|
||||
*tar_ob = ob;
|
||||
*tar_pchan = BKE_pose_channel_active(ob);
|
||||
found = true;
|
||||
|
||||
/* Only use the object & bone if the bone is visible & selected
|
||||
* since we may have multiple objects in pose mode at once. */
|
||||
bPoseChannel *pchan = BKE_pose_channel_active_or_first_selected(ob);
|
||||
if (pchan != NULL) {
|
||||
*tar_pchan = pchan;
|
||||
*tar_ob = ob;
|
||||
found = true;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -964,9 +964,9 @@ static void paint_draw_curve_cursor(Brush *brush, ViewContext *vc)
|
|||
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
|
||||
|
||||
float selec_col[4], handle_col[4], pivot_col[4];
|
||||
UI_GetThemeColor4fv(TH_VERTEX_SELECT, selec_col);
|
||||
UI_GetThemeColor4fv(TH_PAINT_CURVE_HANDLE, handle_col);
|
||||
UI_GetThemeColor4fv(TH_PAINT_CURVE_PIVOT, pivot_col);
|
||||
UI_GetThemeColorType4fv(TH_VERTEX_SELECT, SPACE_VIEW3D, selec_col);
|
||||
UI_GetThemeColorType4fv(TH_PAINT_CURVE_HANDLE, SPACE_VIEW3D, handle_col);
|
||||
UI_GetThemeColorType4fv(TH_PAINT_CURVE_PIVOT, SPACE_VIEW3D, pivot_col);
|
||||
|
||||
for (i = 0; i < pc->tot_points - 1; i++, cp++) {
|
||||
int j;
|
||||
|
|
|
|||
|
|
@ -56,6 +56,7 @@
|
|||
#include "BKE_paint.h"
|
||||
#include "BKE_report.h"
|
||||
#include "BKE_subsurf.h"
|
||||
#include "BKE_layer.h"
|
||||
|
||||
#include "DEG_depsgraph.h"
|
||||
|
||||
|
|
@ -1305,18 +1306,47 @@ static int wpaint_mode_toggle_exec(bContext *C, wmOperator *op)
|
|||
BKE_paint_toolslots_brush_validate(bmain, &ts->wpaint->paint);
|
||||
}
|
||||
|
||||
/* When locked, it's almost impossible to select the pose
|
||||
* then the object to enter weight paint mode.
|
||||
/* When locked, it's almost impossible to select the pose-object
|
||||
* then the mesh-object to enter weight paint mode.
|
||||
* Even when the object mode is not locked this is inconvenient - so allow in either case.
|
||||
*
|
||||
* In this case move our pose object in/out of pose mode.
|
||||
* This is in fits with the convention of selecting multiple objects and entering a mode. */
|
||||
if (scene->toolsettings->object_flag & SCE_OBJECT_MODE_LOCK) {
|
||||
Object *ob_arm = modifiers_isDeformedByArmature(ob);
|
||||
if (ob_arm && (ob_arm->base_flag & BASE_SELECTED)) {
|
||||
if (ob_arm->mode & OB_MODE_POSE) {
|
||||
ED_object_posemode_exit_ex(bmain, ob_arm);
|
||||
}
|
||||
else {
|
||||
ED_object_posemode_enter_ex(bmain, ob_arm);
|
||||
* This is in fits with the convention of selecting multiple objects and entering a mode.
|
||||
*/
|
||||
{
|
||||
VirtualModifierData virtualModifierData;
|
||||
ModifierData *md = modifiers_getVirtualModifierList(ob, &virtualModifierData);
|
||||
if (md != NULL) {
|
||||
/* Can be NULL. */
|
||||
View3D *v3d = CTX_wm_view3d(C);
|
||||
ViewLayer *view_layer = CTX_data_view_layer(C);
|
||||
for (; md; md = md->next) {
|
||||
if (md->type == eModifierType_Armature) {
|
||||
ArmatureModifierData *amd = (ArmatureModifierData *)md;
|
||||
Object *ob_arm = amd->object;
|
||||
if (ob_arm != NULL) {
|
||||
const Base *base_arm = BKE_view_layer_base_find(view_layer, ob_arm);
|
||||
if (base_arm && BASE_VISIBLE(v3d, base_arm)) {
|
||||
if (is_mode_set) {
|
||||
if ((ob_arm->mode & OB_MODE_POSE) != 0) {
|
||||
ED_object_posemode_exit_ex(bmain, ob_arm);
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* Only check selected status when entering weight-paint mode
|
||||
* because we may have multiple armature objects.
|
||||
* Selecting one will de-select the other, which would leave it in pose-mode
|
||||
* when exiting weight paint mode. While usable, this looks like inconsistent
|
||||
* behavior from a user perspective. */
|
||||
if (base_arm->flag & BASE_SELECTED) {
|
||||
if ((ob_arm->mode & OB_MODE_POSE) == 0) {
|
||||
ED_object_posemode_enter_ex(bmain, ob_arm);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1515,6 +1515,11 @@ static int mode_set_exec(bContext *C, wmOperator *op)
|
|||
|
||||
sc->mode = mode;
|
||||
|
||||
if (sc->mode == SC_MODE_MASKEDIT && sc->view != SC_VIEW_CLIP) {
|
||||
/* Make sure we are in the right view for mask editing */
|
||||
sc->view = SC_VIEW_CLIP;
|
||||
}
|
||||
|
||||
WM_event_add_notifier(C, NC_SPACE | ND_SPACE_CLIP, NULL);
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
|
|
|
|||
|
|
@ -420,6 +420,14 @@ static void clip_listener(wmWindow *UNUSED(win), ScrArea *sa, wmNotifier *wmn, S
|
|||
ED_area_tag_redraw(sa);
|
||||
}
|
||||
break;
|
||||
case NC_WM:
|
||||
switch (wmn->data) {
|
||||
case ND_FILEREAD:
|
||||
case ND_UNDO:
|
||||
clip_area_sync_frame_from_scene(sa, scene);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -933,6 +933,40 @@ static void outliner_restrict_properties_enable_layer_collection_set(
|
|||
}
|
||||
}
|
||||
|
||||
static bool outliner_restrict_properties_collection_set(Scene *scene,
|
||||
TreeElement *te,
|
||||
PointerRNA *collection_ptr,
|
||||
PointerRNA *layer_collection_ptr,
|
||||
RestrictProperties *props,
|
||||
RestrictPropertiesActive *props_active)
|
||||
{
|
||||
TreeStoreElem *tselem = TREESTORE(te);
|
||||
LayerCollection *layer_collection = (tselem->type == TSE_LAYER_COLLECTION) ? te->directdata :
|
||||
NULL;
|
||||
Collection *collection = outliner_collection_from_tree_element(te);
|
||||
|
||||
if ((collection->flag & COLLECTION_IS_MASTER) ||
|
||||
(layer_collection && ((layer_collection->flag & LAYER_COLLECTION_EXCLUDE) != 0))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Create the PointerRNA. */
|
||||
RNA_id_pointer_create(&collection->id, collection_ptr);
|
||||
if (layer_collection != NULL) {
|
||||
RNA_pointer_create(&scene->id, &RNA_LayerCollection, layer_collection, layer_collection_ptr);
|
||||
}
|
||||
|
||||
/* Update the restriction column values for the collection children. */
|
||||
if (layer_collection) {
|
||||
outliner_restrict_properties_enable_layer_collection_set(
|
||||
layer_collection_ptr, collection_ptr, props, props_active);
|
||||
}
|
||||
else {
|
||||
outliner_restrict_properties_enable_collection_set(collection_ptr, props, props_active);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static void outliner_draw_restrictbuts(uiBlock *block,
|
||||
Scene *scene,
|
||||
ViewLayer *view_layer,
|
||||
|
|
@ -1337,30 +1371,16 @@ static void outliner_draw_restrictbuts(uiBlock *block,
|
|||
}
|
||||
}
|
||||
else if (outliner_is_collection_tree_element(te)) {
|
||||
LayerCollection *layer_collection = (tselem->type == TSE_LAYER_COLLECTION) ?
|
||||
te->directdata :
|
||||
NULL;
|
||||
Collection *collection = outliner_collection_from_tree_element(te);
|
||||
if ((!layer_collection || !(layer_collection->flag & LAYER_COLLECTION_EXCLUDE)) &&
|
||||
!(collection->flag & COLLECTION_IS_MASTER)) {
|
||||
PointerRNA collection_ptr;
|
||||
PointerRNA layer_collection_ptr;
|
||||
|
||||
PointerRNA collection_ptr;
|
||||
PointerRNA layer_collection_ptr;
|
||||
RNA_id_pointer_create(&collection->id, &collection_ptr);
|
||||
if (layer_collection != NULL) {
|
||||
RNA_pointer_create(
|
||||
&scene->id, &RNA_LayerCollection, layer_collection, &layer_collection_ptr);
|
||||
}
|
||||
if (outliner_restrict_properties_collection_set(
|
||||
scene, te, &collection_ptr, &layer_collection_ptr, &props, &props_active)) {
|
||||
|
||||
/* Update the restriction column values for the collection children. */
|
||||
if (layer_collection) {
|
||||
outliner_restrict_properties_enable_layer_collection_set(
|
||||
&layer_collection_ptr, &collection_ptr, &props, &props_active);
|
||||
}
|
||||
else {
|
||||
outliner_restrict_properties_enable_collection_set(
|
||||
&collection_ptr, &props, &props_active);
|
||||
}
|
||||
LayerCollection *layer_collection = (tselem->type == TSE_LAYER_COLLECTION) ?
|
||||
te->directdata :
|
||||
NULL;
|
||||
Collection *collection = outliner_collection_from_tree_element(te);
|
||||
|
||||
if (layer_collection != NULL) {
|
||||
if (soops->show_restrict_flags & SO_RESTRICT_HIDE) {
|
||||
|
|
@ -1563,6 +1583,12 @@ static void outliner_draw_restrictbuts(uiBlock *block,
|
|||
}
|
||||
}
|
||||
}
|
||||
else if (outliner_is_collection_tree_element(te)) {
|
||||
PointerRNA collection_ptr;
|
||||
PointerRNA layer_collection_ptr;
|
||||
outliner_restrict_properties_collection_set(
|
||||
scene, te, &collection_ptr, &layer_collection_ptr, &props, &props_active);
|
||||
}
|
||||
|
||||
if (TSELEM_OPEN(tselem, soops)) {
|
||||
outliner_draw_restrictbuts(block, scene, view_layer, ar, soops, &te->subtree, props_active);
|
||||
|
|
|
|||
|
|
@ -260,7 +260,7 @@ static void get_suggest_prefix(Text *text, int offset)
|
|||
texttool_suggest_prefix(line + i, len);
|
||||
}
|
||||
|
||||
static void confirm_suggestion(Text *text, TextUndoBuf *utxt)
|
||||
static void confirm_suggestion(Text *text)
|
||||
{
|
||||
SuggItem *sel;
|
||||
int i, over = 0;
|
||||
|
|
@ -285,7 +285,7 @@ static void confirm_suggestion(Text *text, TextUndoBuf *utxt)
|
|||
// for (i = 0; i < skipleft; i++)
|
||||
// txt_move_left(text, 0);
|
||||
BLI_assert(memcmp(sel->name, &line[i], over) == 0);
|
||||
txt_insert_buf(text, utxt, sel->name + over);
|
||||
txt_insert_buf(text, sel->name + over);
|
||||
|
||||
// for (i = 0; i < skipleft; i++)
|
||||
// txt_move_right(text, 0);
|
||||
|
|
@ -308,8 +308,8 @@ static int text_autocomplete_invoke(bContext *C, wmOperator *op, const wmEvent *
|
|||
ED_area_tag_redraw(CTX_wm_area(C));
|
||||
|
||||
if (texttool_suggest_first() == texttool_suggest_last()) {
|
||||
TextUndoBuf *utxt = ED_text_undo_push_init(C);
|
||||
confirm_suggestion(st->text, utxt);
|
||||
ED_text_undo_push_init(C);
|
||||
confirm_suggestion(st->text);
|
||||
text_update_line_edited(st->text->curl);
|
||||
text_autocomplete_free(C, op);
|
||||
ED_undo_push(C, op->type->name);
|
||||
|
|
@ -371,8 +371,8 @@ static int text_autocomplete_modal(bContext *C, wmOperator *op, const wmEvent *e
|
|||
case MIDDLEMOUSE:
|
||||
if (event->val == KM_PRESS) {
|
||||
if (text_do_suggest_select(st, ar)) {
|
||||
TextUndoBuf *utxt = ED_text_undo_push_init(C);
|
||||
confirm_suggestion(st->text, utxt);
|
||||
ED_text_undo_push_init(C);
|
||||
confirm_suggestion(st->text);
|
||||
text_update_line_edited(st->text->curl);
|
||||
ED_undo_push(C, op->type->name);
|
||||
swallow = 1;
|
||||
|
|
@ -410,8 +410,8 @@ static int text_autocomplete_modal(bContext *C, wmOperator *op, const wmEvent *e
|
|||
case PADENTER:
|
||||
if (event->val == KM_PRESS) {
|
||||
if (tools & TOOL_SUGG_LIST) {
|
||||
TextUndoBuf *utxt = ED_text_undo_push_init(C);
|
||||
confirm_suggestion(st->text, utxt);
|
||||
ED_text_undo_push_init(C);
|
||||
confirm_suggestion(st->text);
|
||||
text_update_line_edited(st->text->curl);
|
||||
ED_undo_push(C, op->type->name);
|
||||
swallow = 1;
|
||||
|
|
|
|||
|
|
@ -840,7 +840,7 @@ static int text_paste_exec(bContext *C, wmOperator *op)
|
|||
|
||||
text_drawcache_tag_update(CTX_wm_space_text(C), 0);
|
||||
|
||||
TextUndoBuf *utxt = ED_text_undo_push_init(C);
|
||||
ED_text_undo_push_init(C);
|
||||
|
||||
/* Convert clipboard content indentation to spaces if specified */
|
||||
if (text->flags & TXT_TABSTOSPACES) {
|
||||
|
|
@ -849,7 +849,7 @@ static int text_paste_exec(bContext *C, wmOperator *op)
|
|||
buf = new_buf;
|
||||
}
|
||||
|
||||
txt_insert_buf(text, utxt, buf);
|
||||
txt_insert_buf(text, buf);
|
||||
text_update_edited(text);
|
||||
|
||||
MEM_freeN(buf);
|
||||
|
|
@ -893,9 +893,9 @@ static int text_duplicate_line_exec(bContext *C, wmOperator *UNUSED(op))
|
|||
{
|
||||
Text *text = CTX_data_edit_text(C);
|
||||
|
||||
TextUndoBuf *utxt = ED_text_undo_push_init(C);
|
||||
ED_text_undo_push_init(C);
|
||||
|
||||
txt_duplicate_line(text, utxt);
|
||||
txt_duplicate_line(text);
|
||||
|
||||
WM_event_add_notifier(C, NC_TEXT | NA_EDITED, text);
|
||||
|
||||
|
|
@ -971,8 +971,8 @@ static int text_cut_exec(bContext *C, wmOperator *UNUSED(op))
|
|||
|
||||
txt_copy_clipboard(text);
|
||||
|
||||
TextUndoBuf *utxt = ED_text_undo_push_init(C);
|
||||
txt_delete_selected(text, utxt);
|
||||
ED_text_undo_push_init(C);
|
||||
txt_delete_selected(text);
|
||||
|
||||
text_update_cursor_moved(C);
|
||||
WM_event_add_notifier(C, NC_TEXT | NA_EDITED, text);
|
||||
|
|
@ -1008,14 +1008,14 @@ static int text_indent_exec(bContext *C, wmOperator *UNUSED(op))
|
|||
|
||||
text_drawcache_tag_update(CTX_wm_space_text(C), 0);
|
||||
|
||||
TextUndoBuf *utxt = ED_text_undo_push_init(C);
|
||||
ED_text_undo_push_init(C);
|
||||
|
||||
if (txt_has_sel(text)) {
|
||||
txt_order_cursors(text, false);
|
||||
txt_indent(text, utxt);
|
||||
txt_indent(text);
|
||||
}
|
||||
else {
|
||||
txt_add_char(text, utxt, '\t');
|
||||
txt_add_char(text, '\t');
|
||||
}
|
||||
|
||||
text_update_edited(text);
|
||||
|
|
@ -1049,10 +1049,10 @@ static int text_unindent_exec(bContext *C, wmOperator *UNUSED(op))
|
|||
|
||||
text_drawcache_tag_update(CTX_wm_space_text(C), 0);
|
||||
|
||||
TextUndoBuf *utxt = ED_text_undo_push_init(C);
|
||||
ED_text_undo_push_init(C);
|
||||
|
||||
txt_order_cursors(text, false);
|
||||
txt_unindent(text, utxt);
|
||||
txt_unindent(text);
|
||||
|
||||
text_update_edited(text);
|
||||
|
||||
|
|
@ -1090,15 +1090,15 @@ static int text_line_break_exec(bContext *C, wmOperator *UNUSED(op))
|
|||
|
||||
// double check tabs/spaces before splitting the line
|
||||
curts = txt_setcurr_tab_spaces(text, space);
|
||||
TextUndoBuf *utxt = ED_text_undo_push_init(C);
|
||||
txt_split_curline(text, utxt);
|
||||
ED_text_undo_push_init(C);
|
||||
txt_split_curline(text);
|
||||
|
||||
for (a = 0; a < curts; a++) {
|
||||
if (text->flags & TXT_TABSTOSPACES) {
|
||||
txt_add_char(text, utxt, ' ');
|
||||
txt_add_char(text, ' ');
|
||||
}
|
||||
else {
|
||||
txt_add_char(text, utxt, '\t');
|
||||
txt_add_char(text, '\t');
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1139,10 +1139,10 @@ static int text_comment_exec(bContext *C, wmOperator *UNUSED(op))
|
|||
if (txt_has_sel(text)) {
|
||||
text_drawcache_tag_update(CTX_wm_space_text(C), 0);
|
||||
|
||||
TextUndoBuf *utxt = ED_text_undo_push_init(C);
|
||||
ED_text_undo_push_init(C);
|
||||
|
||||
txt_order_cursors(text, false);
|
||||
txt_comment(text, utxt);
|
||||
txt_comment(text);
|
||||
text_update_edited(text);
|
||||
|
||||
text_update_cursor_moved(C);
|
||||
|
|
@ -1177,10 +1177,10 @@ static int text_uncomment_exec(bContext *C, wmOperator *UNUSED(op))
|
|||
if (txt_has_sel(text)) {
|
||||
text_drawcache_tag_update(CTX_wm_space_text(C), 0);
|
||||
|
||||
TextUndoBuf *utxt = ED_text_undo_push_init(C);
|
||||
ED_text_undo_push_init(C);
|
||||
|
||||
txt_order_cursors(text, false);
|
||||
txt_uncomment(text, utxt);
|
||||
txt_uncomment(text);
|
||||
text_update_edited(text);
|
||||
|
||||
text_update_cursor_moved(C);
|
||||
|
|
@ -1446,9 +1446,9 @@ static int move_lines_exec(bContext *C, wmOperator *op)
|
|||
Text *text = CTX_data_edit_text(C);
|
||||
const int direction = RNA_enum_get(op->ptr, "direction");
|
||||
|
||||
TextUndoBuf *utxt = ED_text_undo_push_init(C);
|
||||
ED_text_undo_push_init(C);
|
||||
|
||||
txt_move_lines(text, utxt, direction);
|
||||
txt_move_lines(text, direction);
|
||||
|
||||
text_update_cursor_moved(C);
|
||||
WM_event_add_notifier(C, NC_TEXT | NA_EDITED, text);
|
||||
|
|
@ -2230,13 +2230,13 @@ static int text_delete_exec(bContext *C, wmOperator *op)
|
|||
}
|
||||
}
|
||||
|
||||
TextUndoBuf *utxt = ED_text_undo_push_init(C);
|
||||
ED_text_undo_push_init(C);
|
||||
|
||||
if (type == DEL_PREV_WORD) {
|
||||
if (txt_cursor_is_line_start(text)) {
|
||||
txt_backspace_char(text, utxt);
|
||||
txt_backspace_char(text);
|
||||
}
|
||||
txt_backspace_word(text, utxt);
|
||||
txt_backspace_word(text);
|
||||
}
|
||||
else if (type == DEL_PREV_CHAR) {
|
||||
|
||||
|
|
@ -2252,13 +2252,13 @@ static int text_delete_exec(bContext *C, wmOperator *op)
|
|||
}
|
||||
}
|
||||
|
||||
txt_backspace_char(text, utxt);
|
||||
txt_backspace_char(text);
|
||||
}
|
||||
else if (type == DEL_NEXT_WORD) {
|
||||
if (txt_cursor_is_line_end(text)) {
|
||||
txt_delete_char(text, utxt);
|
||||
txt_delete_char(text);
|
||||
}
|
||||
txt_delete_word(text, utxt);
|
||||
txt_delete_word(text);
|
||||
}
|
||||
else if (type == DEL_NEXT_CHAR) {
|
||||
|
||||
|
|
@ -2274,7 +2274,7 @@ static int text_delete_exec(bContext *C, wmOperator *op)
|
|||
}
|
||||
}
|
||||
|
||||
txt_delete_char(text, utxt);
|
||||
txt_delete_char(text);
|
||||
}
|
||||
|
||||
text_update_line_edited(text->curl);
|
||||
|
|
@ -3190,18 +3190,18 @@ static int text_insert_exec(bContext *C, wmOperator *op)
|
|||
|
||||
str = RNA_string_get_alloc(op->ptr, "text", NULL, 0);
|
||||
|
||||
TextUndoBuf *utxt = ED_text_undo_push_init(C);
|
||||
ED_text_undo_push_init(C);
|
||||
|
||||
if (st && st->overwrite) {
|
||||
while (str[i]) {
|
||||
code = BLI_str_utf8_as_unicode_step(str, &i);
|
||||
done |= txt_replace_char(text, utxt, code);
|
||||
done |= txt_replace_char(text, code);
|
||||
}
|
||||
}
|
||||
else {
|
||||
while (str[i]) {
|
||||
code = BLI_str_utf8_as_unicode_step(str, &i);
|
||||
done |= txt_add_char(text, utxt, code);
|
||||
done |= txt_add_char(text, code);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -3319,8 +3319,8 @@ static int text_find_and_replace(bContext *C, wmOperator *op, short mode)
|
|||
|
||||
if (found) {
|
||||
if (mode == TEXT_REPLACE) {
|
||||
TextUndoBuf *utxt = ED_text_undo_push_init(C);
|
||||
txt_insert_buf(text, utxt, st->replacestr);
|
||||
ED_text_undo_push_init(C);
|
||||
txt_insert_buf(text, st->replacestr);
|
||||
if (text->curl && text->curl->format) {
|
||||
MEM_freeN(text->curl->format);
|
||||
text->curl->format = NULL;
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@
|
|||
|
||||
#include "DNA_text_types.h"
|
||||
|
||||
#include "BLI_array_store.h"
|
||||
#include "BLI_array_utils.h"
|
||||
|
||||
#include "BLT_translation.h"
|
||||
|
|
@ -35,6 +36,7 @@
|
|||
#include "BKE_report.h"
|
||||
#include "BKE_text.h"
|
||||
#include "BKE_undo_system.h"
|
||||
#include "BKE_main.h"
|
||||
|
||||
#include "WM_api.h"
|
||||
#include "WM_types.h"
|
||||
|
|
@ -53,18 +55,32 @@
|
|||
#include "text_intern.h"
|
||||
#include "text_format.h"
|
||||
|
||||
/* TODO(campbell): undo_system: move text undo out of text block. */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Implements ED Undo System
|
||||
* \{ */
|
||||
|
||||
#define ARRAY_CHUNK_SIZE 128
|
||||
|
||||
typedef struct TextUndoStep {
|
||||
UndoStep step;
|
||||
UndoRefID_Text text_ref;
|
||||
TextUndoBuf data;
|
||||
struct {
|
||||
BArrayState *state;
|
||||
int buf_len;
|
||||
} data;
|
||||
|
||||
struct {
|
||||
int line, line_select;
|
||||
int column, column_select;
|
||||
} cursor;
|
||||
|
||||
} TextUndoStep;
|
||||
|
||||
static struct {
|
||||
BArrayStore *buffer_store;
|
||||
int users;
|
||||
} g_text_buffers = {NULL};
|
||||
|
||||
static bool text_undosys_poll(bContext *UNUSED(C))
|
||||
{
|
||||
/* Only use when operators initialized. */
|
||||
|
|
@ -77,12 +93,8 @@ static void text_undosys_step_encode_init(struct bContext *C, UndoStep *us_p)
|
|||
TextUndoStep *us = (TextUndoStep *)us_p;
|
||||
BLI_assert(BLI_array_is_zeroed(&us->data, 1));
|
||||
|
||||
UNUSED_VARS(C);
|
||||
UNUSED_VARS(C, us);
|
||||
/* XXX, use to set the undo type only. */
|
||||
|
||||
us->data.buf = NULL;
|
||||
us->data.len = 0;
|
||||
us->data.pos = -1;
|
||||
}
|
||||
|
||||
static bool text_undosys_step_encode(struct bContext *C,
|
||||
|
|
@ -93,104 +105,66 @@ static bool text_undosys_step_encode(struct bContext *C,
|
|||
|
||||
Text *text = CTX_data_edit_text(C);
|
||||
|
||||
/* No undo data was generated. Hint, use global undo here. */
|
||||
if ((us->data.pos == -1) || (us->data.buf == NULL)) {
|
||||
return false;
|
||||
int buf_len = 0;
|
||||
|
||||
uchar *buf = (uchar *)txt_to_buf_for_undo(text, &buf_len);
|
||||
if (g_text_buffers.buffer_store == NULL) {
|
||||
g_text_buffers.buffer_store = BLI_array_store_create(1, ARRAY_CHUNK_SIZE);
|
||||
}
|
||||
g_text_buffers.users += 1;
|
||||
const size_t total_size_prev = BLI_array_store_calc_size_compacted_get(
|
||||
g_text_buffers.buffer_store);
|
||||
|
||||
us->data.state = BLI_array_store_state_add(g_text_buffers.buffer_store, buf, buf_len, NULL);
|
||||
MEM_freeN(buf);
|
||||
|
||||
us->cursor.line = txt_get_span(text->lines.first, text->curl);
|
||||
us->cursor.column = text->curc;
|
||||
|
||||
if (txt_has_sel(text)) {
|
||||
us->cursor.line_select = (text->curl == text->sell) ?
|
||||
us->cursor.line :
|
||||
txt_get_span(text->lines.first, text->sell);
|
||||
us->cursor.column_select = text->selc;
|
||||
}
|
||||
else {
|
||||
us->cursor.line_select = us->cursor.line;
|
||||
us->cursor.column_select = us->cursor.column;
|
||||
}
|
||||
|
||||
us_p->is_applied = true;
|
||||
|
||||
us->text_ref.ptr = text;
|
||||
|
||||
us->step.data_size = us->data.len;
|
||||
us->step.data_size = BLI_array_store_calc_size_compacted_get(g_text_buffers.buffer_store) -
|
||||
total_size_prev;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void text_undosys_step_decode_undo_impl(Text *text, TextUndoStep *us)
|
||||
{
|
||||
BLI_assert(us->step.is_applied == true);
|
||||
TextUndoBuf data = us->data;
|
||||
while (data.pos > -1) {
|
||||
txt_do_undo(text, &data);
|
||||
}
|
||||
BLI_assert(data.pos == -1);
|
||||
us->step.is_applied = false;
|
||||
}
|
||||
|
||||
static void text_undosys_step_decode_redo_impl(Text *text, TextUndoStep *us)
|
||||
{
|
||||
BLI_assert(us->step.is_applied == false);
|
||||
TextUndoBuf data = us->data;
|
||||
data.pos = -1;
|
||||
while (data.pos < us->data.pos) {
|
||||
txt_do_redo(text, &data);
|
||||
}
|
||||
BLI_assert(data.pos == us->data.pos);
|
||||
us->step.is_applied = true;
|
||||
}
|
||||
|
||||
static void text_undosys_step_decode_undo(TextUndoStep *us, bool is_final)
|
||||
{
|
||||
TextUndoStep *us_iter = us;
|
||||
while (us_iter->step.next && (us_iter->step.next->type == us_iter->step.type)) {
|
||||
if (us_iter->step.next->is_applied == false) {
|
||||
break;
|
||||
}
|
||||
us_iter = (TextUndoStep *)us_iter->step.next;
|
||||
}
|
||||
Text *text_prev = NULL;
|
||||
while ((us_iter != us) || (is_final && us_iter == us)) {
|
||||
Text *text = us_iter->text_ref.ptr;
|
||||
text_undosys_step_decode_undo_impl(text, us_iter);
|
||||
if (text_prev != text) {
|
||||
text_update_edited(text);
|
||||
text_prev = text;
|
||||
}
|
||||
if (is_final) {
|
||||
break;
|
||||
}
|
||||
us_iter = (TextUndoStep *)us_iter->step.prev;
|
||||
}
|
||||
}
|
||||
|
||||
static void text_undosys_step_decode_redo(TextUndoStep *us)
|
||||
{
|
||||
TextUndoStep *us_iter = us;
|
||||
while (us_iter->step.prev && (us_iter->step.prev->type == us_iter->step.type)) {
|
||||
if (us_iter->step.prev->is_applied == true) {
|
||||
break;
|
||||
}
|
||||
us_iter = (TextUndoStep *)us_iter->step.prev;
|
||||
}
|
||||
Text *text_prev = NULL;
|
||||
while (us_iter && (us_iter->step.is_applied == false)) {
|
||||
Text *text = us_iter->text_ref.ptr;
|
||||
text_undosys_step_decode_redo_impl(text, us_iter);
|
||||
if (text_prev != text) {
|
||||
text_update_edited(text);
|
||||
text_prev = text;
|
||||
}
|
||||
if (us_iter == us) {
|
||||
break;
|
||||
}
|
||||
us_iter = (TextUndoStep *)us_iter->step.next;
|
||||
}
|
||||
}
|
||||
|
||||
static void text_undosys_step_decode(
|
||||
struct bContext *C, struct Main *UNUSED(bmain), UndoStep *us_p, int dir, bool is_final)
|
||||
static void text_undosys_step_decode(struct bContext *C,
|
||||
struct Main *UNUSED(bmain),
|
||||
UndoStep *us_p,
|
||||
int UNUSED(dir),
|
||||
bool UNUSED(is_final))
|
||||
{
|
||||
TextUndoStep *us = (TextUndoStep *)us_p;
|
||||
|
||||
if (dir < 0) {
|
||||
text_undosys_step_decode_undo(us, is_final);
|
||||
}
|
||||
else {
|
||||
text_undosys_step_decode_redo(us);
|
||||
}
|
||||
|
||||
Text *text = us->text_ref.ptr;
|
||||
size_t buf_len;
|
||||
|
||||
{
|
||||
const uchar *buf = BLI_array_store_state_data_get_alloc(us->data.state, &buf_len);
|
||||
txt_from_buf_for_undo(text, (const char *)buf, buf_len);
|
||||
MEM_freeN((void *)buf);
|
||||
}
|
||||
|
||||
const bool has_select = ((us->cursor.line != us->cursor.line_select) ||
|
||||
(us->cursor.column != us->cursor.column_select));
|
||||
if (has_select) {
|
||||
txt_move_to(text, us->cursor.line_select, us->cursor.column_select, false);
|
||||
}
|
||||
txt_move_to(text, us->cursor.line, us->cursor.column, has_select);
|
||||
|
||||
SpaceText *st = CTX_wm_space_text(C);
|
||||
if (st) {
|
||||
/* Not essential, always show text being undo where possible. */
|
||||
|
|
@ -204,7 +178,14 @@ static void text_undosys_step_decode(
|
|||
static void text_undosys_step_free(UndoStep *us_p)
|
||||
{
|
||||
TextUndoStep *us = (TextUndoStep *)us_p;
|
||||
MEM_SAFE_FREE(us->data.buf);
|
||||
|
||||
BLI_array_store_state_remove(g_text_buffers.buffer_store, us->data.state);
|
||||
|
||||
g_text_buffers.users -= 1;
|
||||
if (g_text_buffers.users == 0) {
|
||||
BLI_array_store_destroy(g_text_buffers.buffer_store);
|
||||
g_text_buffers.buffer_store = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static void text_undosys_foreach_ID_ref(UndoStep *us_p,
|
||||
|
|
@ -240,12 +221,16 @@ void ED_text_undosys_type(UndoType *ut)
|
|||
* \{ */
|
||||
|
||||
/* Use operator system to finish the undo step. */
|
||||
TextUndoBuf *ED_text_undo_push_init(bContext *C)
|
||||
UndoStep *ED_text_undo_push_init(bContext *C)
|
||||
{
|
||||
UndoStack *ustack = ED_undo_stack_get();
|
||||
UndoStep *us_p = BKE_undosys_step_push_init_with_type(ustack, C, NULL, BKE_UNDOSYS_TYPE_TEXT);
|
||||
TextUndoStep *us = (TextUndoStep *)us_p;
|
||||
return &us->data;
|
||||
Main *bmain = CTX_data_main(C);
|
||||
wmWindowManager *wm = bmain->wm.first;
|
||||
if (wm->op_undo_depth <= 1) {
|
||||
UndoStep *us_p = BKE_undosys_step_push_init_with_type(ustack, C, NULL, BKE_UNDOSYS_TYPE_TEXT);
|
||||
return us_p;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
|
|
|||
|
|
@ -72,39 +72,7 @@ static void PREFERENCES_OT_reset_default_theme(wmOperatorType *ot)
|
|||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Toggle Auto-Save Override
|
||||
*
|
||||
* This operator only exists so there is a useful tool-tip for for adjusting the global flag.
|
||||
* \{ */
|
||||
|
||||
static int preferences_autosave_override_toggle_exec(bContext *UNUSED(C), wmOperator *UNUSED(op))
|
||||
{
|
||||
G.f ^= G_FLAG_USERPREF_NO_SAVE_ON_EXIT;
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
static void PREFERENCES_OT_autosave_override_toggle(wmOperatorType *ot)
|
||||
{
|
||||
/* identifiers */
|
||||
ot->name = "Toggle Override Auto-Save";
|
||||
ot->idname = "PREFERENCES_OT_autosave_override_toggle";
|
||||
ot->description =
|
||||
"The current session has \"Factory Preferences\" loaded "
|
||||
"which disables automatically saving.\n"
|
||||
"Disable this to auto-save the preferences";
|
||||
|
||||
/* callbacks */
|
||||
ot->exec = preferences_autosave_override_toggle_exec;
|
||||
|
||||
/* flags */
|
||||
ot->flag = OPTYPE_REGISTER;
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
void ED_operatortypes_userpref(void)
|
||||
{
|
||||
WM_operatortype_append(PREFERENCES_OT_reset_default_theme);
|
||||
WM_operatortype_append(PREFERENCES_OT_autosave_override_toggle);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -662,7 +662,10 @@ static void view3d_widgets(void)
|
|||
WM_gizmogrouptype_append_and_link(gzmap_type, VIEW3D_GGT_camera);
|
||||
WM_gizmogrouptype_append_and_link(gzmap_type, VIEW3D_GGT_camera_view);
|
||||
WM_gizmogrouptype_append_and_link(gzmap_type, VIEW3D_GGT_empty_image);
|
||||
/* TODO(campbell): Not working well enough, disable for now. */
|
||||
#if 0
|
||||
WM_gizmogrouptype_append_and_link(gzmap_type, VIEW3D_GGT_armature_spline);
|
||||
#endif
|
||||
|
||||
WM_gizmogrouptype_append(VIEW3D_GGT_xform_gizmo);
|
||||
WM_gizmogrouptype_append(VIEW3D_GGT_xform_cage);
|
||||
|
|
|
|||
|
|
@ -4661,6 +4661,7 @@ static int background_image_add_invoke(bContext *C, wmOperator *op, const wmEven
|
|||
cam->flag |= CAM_SHOW_BG_IMAGE;
|
||||
|
||||
WM_event_add_notifier(C, NC_CAMERA | ND_DRAW_RENDER_VIEWPORT, cam);
|
||||
DEG_id_tag_update(&cam->id, ID_RECALC_COPY_ON_WRITE);
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
|
@ -4721,6 +4722,8 @@ static int background_image_remove_exec(bContext *C, wmOperator *op)
|
|||
BKE_camera_background_image_remove(cam, bgpic_rem);
|
||||
|
||||
WM_event_add_notifier(C, NC_CAMERA | ND_DRAW_RENDER_VIEWPORT, cam);
|
||||
DEG_id_tag_update(&cam->id, ID_RECALC_COPY_ON_WRITE);
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
else {
|
||||
|
|
|
|||
|
|
@ -2321,10 +2321,15 @@ static bool ed_object_select_pick(bContext *C,
|
|||
WM_event_add_notifier(C, NC_OBJECT | ND_BONE_ACTIVE, basact->object);
|
||||
DEG_id_tag_update(&scene->id, ID_RECALC_BASE_FLAGS);
|
||||
|
||||
/* in weightpaint, we use selected bone to select vertexgroup,
|
||||
* so no switch to new active object */
|
||||
/* In weight-paint, we use selected bone to select vertex-group,
|
||||
* so don't switch to new active object. */
|
||||
if (oldbasact && (oldbasact->object->mode & OB_MODE_WEIGHT_PAINT)) {
|
||||
/* prevent activating */
|
||||
/* Prevent activating.
|
||||
* Selection causes this to be considered the 'active' pose in weight-paint mode.
|
||||
* Eventually this limitation may be removed.
|
||||
* For now, de-select all other pose objects deforming this mesh. */
|
||||
ED_armature_pose_select_in_wpaint_mode(view_layer, basact);
|
||||
|
||||
basact = NULL;
|
||||
}
|
||||
}
|
||||
|
|
@ -2395,7 +2400,7 @@ static bool ed_object_select_pick(bContext *C,
|
|||
}
|
||||
else {
|
||||
/* When enabled, this puts other objects out of multi pose-mode. */
|
||||
if (is_pose_mode == false) {
|
||||
if (is_pose_mode == false || (basact->object->mode & OB_MODE_POSE) == 0) {
|
||||
object_deselect_all_except(view_layer, basact);
|
||||
ED_object_base_select(basact, BA_SELECT);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@
|
|||
#include "BLI_math.h"
|
||||
#include "BLI_rect.h"
|
||||
#include "BLI_utildefines.h"
|
||||
#include "BLI_linklist.h"
|
||||
|
||||
#include "BKE_action.h"
|
||||
#include "BKE_camera.h"
|
||||
|
|
@ -38,6 +39,7 @@
|
|||
#include "BKE_global.h"
|
||||
#include "BKE_layer.h"
|
||||
#include "BKE_main.h"
|
||||
#include "BKE_modifier.h"
|
||||
#include "BKE_report.h"
|
||||
#include "BKE_scene.h"
|
||||
|
||||
|
|
@ -962,8 +964,8 @@ static bool drw_select_filter_object_mode_lock(Object *ob, void *user_data)
|
|||
* we want to select pose bones (this doesn't switch modes). */
|
||||
static bool drw_select_filter_object_mode_lock_for_weight_paint(Object *ob, void *user_data)
|
||||
{
|
||||
const Object *ob_pose = user_data;
|
||||
return (DEG_get_original_object(ob) == ob_pose);
|
||||
LinkNode *ob_pose_list = user_data;
|
||||
return ob_pose_list && (BLI_linklist_index(ob_pose_list, DEG_get_original_object(ob)) != -1);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -1044,10 +1046,22 @@ int view3d_opengl_select(ViewContext *vc,
|
|||
case VIEW3D_SELECT_FILTER_WPAINT_POSE_MODE_LOCK: {
|
||||
Object *obact = vc->obact;
|
||||
BLI_assert(obact && (obact->mode & OB_MODE_WEIGHT_PAINT));
|
||||
Object *ob_pose = BKE_object_pose_armature_get(obact);
|
||||
|
||||
/* While this uses 'alloca' in a loop (which we typically avoid),
|
||||
* the number of items is nearly always 1, maybe 2..3 in rare cases. */
|
||||
LinkNode *ob_pose_list = NULL;
|
||||
VirtualModifierData virtualModifierData;
|
||||
const ModifierData *md = modifiers_getVirtualModifierList(obact, &virtualModifierData);
|
||||
for (; md; md = md->next) {
|
||||
if (md->type == eModifierType_Armature) {
|
||||
ArmatureModifierData *amd = (ArmatureModifierData *)md;
|
||||
if (amd->object && (amd->object->mode & OB_MODE_POSE)) {
|
||||
BLI_linklist_prepend_alloca(&ob_pose_list, amd->object);
|
||||
}
|
||||
}
|
||||
}
|
||||
object_filter.fn = drw_select_filter_object_mode_lock_for_weight_paint;
|
||||
object_filter.user_data = ob_pose;
|
||||
object_filter.user_data = ob_pose_list;
|
||||
break;
|
||||
}
|
||||
case VIEW3D_SELECT_FILTER_NOP:
|
||||
|
|
|
|||
|
|
@ -6703,9 +6703,28 @@ static void slide_origdata_free_date(SlideOrigData *sod)
|
|||
/** \name Transform Edge Slide
|
||||
* \{ */
|
||||
|
||||
/**
|
||||
* Get the first valid EdgeSlideData.
|
||||
*
|
||||
* Note we cannot trust TRANS_DATA_CONTAINER_FIRST_OK because of multi-object that
|
||||
* may leave items with invalid custom data in the transform data container.
|
||||
*/
|
||||
static EdgeSlideData *edgeSlideFirstGet(TransInfo *t)
|
||||
{
|
||||
FOREACH_TRANS_DATA_CONTAINER (t, tc) {
|
||||
EdgeSlideData *sld = tc->custom.mode.data;
|
||||
if (sld == NULL) {
|
||||
continue;
|
||||
}
|
||||
return sld;
|
||||
}
|
||||
BLI_assert(!"Should never happen, at least one EdgeSlideData should be valid");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void calcEdgeSlideCustomPoints(struct TransInfo *t)
|
||||
{
|
||||
EdgeSlideData *sld = TRANS_DATA_CONTAINER_FIRST_OK(t)->custom.mode.data;
|
||||
EdgeSlideData *sld = edgeSlideFirstGet(t);
|
||||
|
||||
setCustomPoints(t, &t->mouse, sld->mval_end, sld->mval_start);
|
||||
|
||||
|
|
@ -7679,10 +7698,14 @@ void projectEdgeSlideData(TransInfo *t, bool is_final)
|
|||
{
|
||||
FOREACH_TRANS_DATA_CONTAINER (t, tc) {
|
||||
EdgeSlideData *sld = tc->custom.mode.data;
|
||||
SlideOrigData *sod = &sld->orig_data;
|
||||
|
||||
if (sld == NULL) {
|
||||
continue;
|
||||
}
|
||||
|
||||
SlideOrigData *sod = &sld->orig_data;
|
||||
if (sod->use_origfaces == false) {
|
||||
return;
|
||||
continue;
|
||||
}
|
||||
|
||||
slide_origdata_interp_data(tc->obedit,
|
||||
|
|
@ -7705,7 +7728,7 @@ void freeEdgeSlideVerts(TransInfo *UNUSED(t),
|
|||
{
|
||||
EdgeSlideData *sld = custom_data->data;
|
||||
|
||||
if (!sld) {
|
||||
if (sld == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -7847,9 +7870,9 @@ static eRedrawFlag handleEventEdgeSlide(struct TransInfo *t, const struct wmEven
|
|||
|
||||
static void drawEdgeSlide(TransInfo *t)
|
||||
{
|
||||
if ((t->mode == TFM_EDGE_SLIDE) && TRANS_DATA_CONTAINER_FIRST_OK(t)->custom.mode.data) {
|
||||
if ((t->mode == TFM_EDGE_SLIDE) && edgeSlideFirstGet(t)) {
|
||||
const EdgeSlideParams *slp = t->custom.mode.data;
|
||||
EdgeSlideData *sld = TRANS_DATA_CONTAINER_FIRST_OK(t)->custom.mode.data;
|
||||
EdgeSlideData *sld = edgeSlideFirstGet(t);
|
||||
const bool is_clamp = !(t->flag & T_ALT_TRANSFORM);
|
||||
|
||||
/* Even mode */
|
||||
|
|
@ -7968,7 +7991,7 @@ static void drawEdgeSlide(TransInfo *t)
|
|||
static void doEdgeSlide(TransInfo *t, float perc)
|
||||
{
|
||||
EdgeSlideParams *slp = t->custom.mode.data;
|
||||
EdgeSlideData *sld_active = TRANS_DATA_CONTAINER_FIRST_OK(t)->custom.mode.data;
|
||||
EdgeSlideData *sld_active = edgeSlideFirstGet(t);
|
||||
|
||||
slp->perc = perc;
|
||||
|
||||
|
|
@ -7979,6 +8002,11 @@ static void doEdgeSlide(TransInfo *t, float perc)
|
|||
const float perc_final = fabsf(perc);
|
||||
FOREACH_TRANS_DATA_CONTAINER (t, tc) {
|
||||
EdgeSlideData *sld = tc->custom.mode.data;
|
||||
|
||||
if (sld == NULL) {
|
||||
continue;
|
||||
}
|
||||
|
||||
TransDataEdgeSlideVert *sv = sld->sv;
|
||||
for (int i = 0; i < sld->totsv; i++, sv++) {
|
||||
madd_v3_v3v3fl(sv->v->co, sv->v_co_orig, sv->dir_side[side_index], perc_final);
|
||||
|
|
@ -7992,6 +8020,11 @@ static void doEdgeSlide(TransInfo *t, float perc)
|
|||
const int side_index = sld_active->curr_side_unclamp;
|
||||
FOREACH_TRANS_DATA_CONTAINER (t, tc) {
|
||||
EdgeSlideData *sld = tc->custom.mode.data;
|
||||
|
||||
if (sld == NULL) {
|
||||
continue;
|
||||
}
|
||||
|
||||
TransDataEdgeSlideVert *sv = sld->sv;
|
||||
for (int i = 0; i < sld->totsv; i++, sv++) {
|
||||
float dir_flip[3];
|
||||
|
|
@ -8028,6 +8061,11 @@ static void doEdgeSlide(TransInfo *t, float perc)
|
|||
|
||||
FOREACH_TRANS_DATA_CONTAINER (t, tc) {
|
||||
EdgeSlideData *sld = tc->custom.mode.data;
|
||||
|
||||
if (sld == NULL) {
|
||||
continue;
|
||||
}
|
||||
|
||||
TransDataEdgeSlideVert *sv = sld->sv;
|
||||
for (int i = 0; i < sld->totsv; i++, sv++) {
|
||||
if (sv->edge_len > FLT_EPSILON) {
|
||||
|
|
|
|||
|
|
@ -7100,6 +7100,10 @@ void special_aftertrans_update(bContext *C, TransInfo *t)
|
|||
FOREACH_TRANS_DATA_CONTAINER (t, tc) {
|
||||
EdgeSlideData *sld = tc->custom.mode.data;
|
||||
|
||||
if (sld == NULL) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Free temporary faces to avoid auto-merging and deleting
|
||||
* during cleanup - psy-fi. */
|
||||
freeEdgeSlideTempFaces(sld);
|
||||
|
|
|
|||
|
|
@ -1762,32 +1762,11 @@ static bool imb_exr_is_multilayer_file(MultiPartInputFile &file)
|
|||
const ChannelList &channels = file.header(0).channels();
|
||||
std::set<std::string> layerNames;
|
||||
|
||||
/* will not include empty layer names */
|
||||
/* This will not include empty layer names, so files with just R/G/B/A
|
||||
* channels without a layer name will be single layer. */
|
||||
channels.layers(layerNames);
|
||||
|
||||
if (layerNames.size() > 1) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (layerNames.size()) {
|
||||
/* if layerNames is not empty, it means at least one layer is non-empty,
|
||||
* but it also could be layers without names in the file and such case
|
||||
* shall be considered a multilayer exr
|
||||
*
|
||||
* that's what we do here: test whether they're empty layer names together
|
||||
* with non-empty ones in the file
|
||||
*/
|
||||
for (ChannelList::ConstIterator i = channels.begin(); i != channels.end(); i++) {
|
||||
std::string layerName = i.name();
|
||||
size_t pos = layerName.rfind('.');
|
||||
|
||||
if (pos == std::string::npos) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
return (layerNames.size() > 0);
|
||||
}
|
||||
|
||||
static void imb_exr_type_by_channels(ChannelList &channels,
|
||||
|
|
|
|||
|
|
@ -55,8 +55,6 @@ typedef struct Text {
|
|||
} Text;
|
||||
|
||||
#define TXT_TABSIZE 4
|
||||
#define TXT_INIT_UNDO 1024
|
||||
#define TXT_MAX_UNDO (TXT_INIT_UNDO * TXT_INIT_UNDO)
|
||||
|
||||
/* text flags */
|
||||
enum {
|
||||
|
|
|
|||
|
|
@ -268,18 +268,6 @@ static IDProperty *rna_EditBone_idprops(PointerRNA *ptr, bool create)
|
|||
return ebone->prop;
|
||||
}
|
||||
|
||||
/* Update the layers_used variable after bones are moved between layer
|
||||
* NOTE: Used to be done in drawing code in 2.7, but that won't work with
|
||||
* Copy-on-Write, as drawing uses evaluated copies.
|
||||
*/
|
||||
static void rna_Armature_layer_used_refresh(bArmature *arm, ListBase *bones)
|
||||
{
|
||||
for (Bone *bone = bones->first; bone; bone = bone->next) {
|
||||
arm->layer_used |= bone->layer;
|
||||
rna_Armature_layer_used_refresh(arm, &bone->childbase);
|
||||
}
|
||||
}
|
||||
|
||||
static void rna_bone_layer_set(int *layer, const bool *values)
|
||||
{
|
||||
int i, tot = 0;
|
||||
|
|
@ -312,8 +300,7 @@ static void rna_Bone_layer_set(PointerRNA *ptr, const bool *values)
|
|||
|
||||
rna_bone_layer_set(&bone->layer, values);
|
||||
|
||||
arm->layer_used = 0;
|
||||
rna_Armature_layer_used_refresh(arm, &arm->bonebase);
|
||||
BKE_armature_refresh_layer_used(arm);
|
||||
}
|
||||
|
||||
static void rna_Armature_layer_set(PointerRNA *ptr, const bool *values)
|
||||
|
|
|
|||
|
|
@ -98,11 +98,13 @@ static void rna_Object_select_set(
|
|||
Base *base = BKE_view_layer_base_find(view_layer, ob);
|
||||
|
||||
if (!base) {
|
||||
BKE_reportf(reports,
|
||||
RPT_ERROR,
|
||||
"Object '%s' not in View Layer '%s'!",
|
||||
ob->id.name + 2,
|
||||
view_layer->name);
|
||||
if (select) {
|
||||
BKE_reportf(reports,
|
||||
RPT_ERROR,
|
||||
"Object '%s' can't be selected because it is not in View Layer '%s'!",
|
||||
ob->id.name + 2,
|
||||
view_layer->name);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -113,10 +115,7 @@ static void rna_Object_select_set(
|
|||
WM_main_add_notifier(NC_SCENE | ND_OB_SELECT, scene);
|
||||
}
|
||||
|
||||
static bool rna_Object_select_get(Object *ob,
|
||||
bContext *C,
|
||||
ReportList *reports,
|
||||
ViewLayer *view_layer)
|
||||
static bool rna_Object_select_get(Object *ob, bContext *C, ViewLayer *view_layer)
|
||||
{
|
||||
if (view_layer == NULL) {
|
||||
view_layer = CTX_data_view_layer(C);
|
||||
|
|
@ -124,11 +123,6 @@ static bool rna_Object_select_get(Object *ob,
|
|||
Base *base = BKE_view_layer_base_find(view_layer, ob);
|
||||
|
||||
if (!base) {
|
||||
BKE_reportf(reports,
|
||||
RPT_ERROR,
|
||||
"Object '%s' not in View Layer '%s'!",
|
||||
ob->id.name + 2,
|
||||
view_layer->name);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -144,11 +138,13 @@ static void rna_Object_hide_set(
|
|||
Base *base = BKE_view_layer_base_find(view_layer, ob);
|
||||
|
||||
if (!base) {
|
||||
BKE_reportf(reports,
|
||||
RPT_ERROR,
|
||||
"Object '%s' not in View Layer '%s'!",
|
||||
ob->id.name + 2,
|
||||
view_layer->name);
|
||||
if (hide) {
|
||||
BKE_reportf(reports,
|
||||
RPT_ERROR,
|
||||
"Object '%s' can't be hidden because it is not in View Layer '%s'!",
|
||||
ob->id.name + 2,
|
||||
view_layer->name);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -165,10 +161,7 @@ static void rna_Object_hide_set(
|
|||
WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene);
|
||||
}
|
||||
|
||||
static bool rna_Object_hide_get(Object *ob,
|
||||
bContext *C,
|
||||
ReportList *reports,
|
||||
ViewLayer *view_layer)
|
||||
static bool rna_Object_hide_get(Object *ob, bContext *C, ViewLayer *view_layer)
|
||||
{
|
||||
if (view_layer == NULL) {
|
||||
view_layer = CTX_data_view_layer(C);
|
||||
|
|
@ -176,19 +169,13 @@ static bool rna_Object_hide_get(Object *ob,
|
|||
Base *base = BKE_view_layer_base_find(view_layer, ob);
|
||||
|
||||
if (!base) {
|
||||
BKE_reportf(reports,
|
||||
RPT_ERROR,
|
||||
"Object '%s' not in View Layer '%s'!",
|
||||
ob->id.name + 2,
|
||||
view_layer->name);
|
||||
return false;
|
||||
}
|
||||
|
||||
return ((base->flag & BASE_HIDDEN) != 0);
|
||||
}
|
||||
|
||||
static bool rna_Object_visible_get(
|
||||
Object *ob, bContext *C, ReportList *reports, ViewLayer *view_layer, View3D *v3d)
|
||||
static bool rna_Object_visible_get(Object *ob, bContext *C, ViewLayer *view_layer, View3D *v3d)
|
||||
{
|
||||
if (view_layer == NULL) {
|
||||
view_layer = CTX_data_view_layer(C);
|
||||
|
|
@ -199,21 +186,13 @@ static bool rna_Object_visible_get(
|
|||
Base *base = BKE_view_layer_base_find(view_layer, ob);
|
||||
|
||||
if (!base) {
|
||||
BKE_reportf(reports,
|
||||
RPT_ERROR,
|
||||
"Object '%s' not in View Layer '%s'!",
|
||||
ob->id.name + 2,
|
||||
view_layer->name);
|
||||
return false;
|
||||
}
|
||||
|
||||
return BASE_VISIBLE(v3d, base);
|
||||
}
|
||||
|
||||
static bool rna_Object_holdout_get(Object *ob,
|
||||
bContext *C,
|
||||
ReportList *reports,
|
||||
ViewLayer *view_layer)
|
||||
static bool rna_Object_holdout_get(Object *ob, bContext *C, ViewLayer *view_layer)
|
||||
{
|
||||
if (view_layer == NULL) {
|
||||
view_layer = CTX_data_view_layer(C);
|
||||
|
|
@ -221,21 +200,13 @@ static bool rna_Object_holdout_get(Object *ob,
|
|||
Base *base = BKE_view_layer_base_find(view_layer, ob);
|
||||
|
||||
if (!base) {
|
||||
BKE_reportf(reports,
|
||||
RPT_ERROR,
|
||||
"Object '%s' not in View Layer '%s'!",
|
||||
ob->id.name + 2,
|
||||
view_layer->name);
|
||||
return false;
|
||||
}
|
||||
|
||||
return ((base->flag & BASE_HOLDOUT) != 0);
|
||||
}
|
||||
|
||||
static bool rna_Object_indirect_only_get(Object *ob,
|
||||
bContext *C,
|
||||
ReportList *reports,
|
||||
ViewLayer *view_layer)
|
||||
static bool rna_Object_indirect_only_get(Object *ob, bContext *C, ViewLayer *view_layer)
|
||||
{
|
||||
if (view_layer == NULL) {
|
||||
view_layer = CTX_data_view_layer(C);
|
||||
|
|
@ -243,11 +214,6 @@ static bool rna_Object_indirect_only_get(Object *ob,
|
|||
Base *base = BKE_view_layer_base_find(view_layer, ob);
|
||||
|
||||
if (!base) {
|
||||
BKE_reportf(reports,
|
||||
RPT_ERROR,
|
||||
"Object '%s' not in View Layer '%s'!",
|
||||
ob->id.name + 2,
|
||||
view_layer->name);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -741,7 +707,7 @@ void RNA_api_object(StructRNA *srna)
|
|||
func = RNA_def_function(srna, "select_get", "rna_Object_select_get");
|
||||
RNA_def_function_ui_description(
|
||||
func, "Test if the object is selected. The selection state is per view layer");
|
||||
RNA_def_function_flag(func, FUNC_USE_CONTEXT | FUNC_USE_REPORTS);
|
||||
RNA_def_function_flag(func, FUNC_USE_CONTEXT);
|
||||
parm = RNA_def_pointer(
|
||||
func, "view_layer", "ViewLayer", "", "Use this instead of the active view layer");
|
||||
parm = RNA_def_boolean(func, "result", 0, "", "Object selected");
|
||||
|
|
@ -760,7 +726,7 @@ void RNA_api_object(StructRNA *srna)
|
|||
RNA_def_function_ui_description(
|
||||
func,
|
||||
"Test if the object is hidden for viewport editing. This hiding state is per view layer");
|
||||
RNA_def_function_flag(func, FUNC_USE_CONTEXT | FUNC_USE_REPORTS);
|
||||
RNA_def_function_flag(func, FUNC_USE_CONTEXT);
|
||||
parm = RNA_def_pointer(
|
||||
func, "view_layer", "ViewLayer", "", "Use this instead of the active view layer");
|
||||
parm = RNA_def_boolean(func, "result", 0, "", "Object hideed");
|
||||
|
|
@ -779,7 +745,7 @@ void RNA_api_object(StructRNA *srna)
|
|||
RNA_def_function_ui_description(func,
|
||||
"Test if the object is visible in the 3D viewport, taking into "
|
||||
"account all visibility settings");
|
||||
RNA_def_function_flag(func, FUNC_USE_CONTEXT | FUNC_USE_REPORTS);
|
||||
RNA_def_function_flag(func, FUNC_USE_CONTEXT);
|
||||
parm = RNA_def_pointer(
|
||||
func, "view_layer", "ViewLayer", "", "Use this instead of the active view layer");
|
||||
parm = RNA_def_pointer(
|
||||
|
|
@ -789,7 +755,7 @@ void RNA_api_object(StructRNA *srna)
|
|||
|
||||
func = RNA_def_function(srna, "holdout_get", "rna_Object_holdout_get");
|
||||
RNA_def_function_ui_description(func, "Test if object is masked in the view layer");
|
||||
RNA_def_function_flag(func, FUNC_USE_CONTEXT | FUNC_USE_REPORTS);
|
||||
RNA_def_function_flag(func, FUNC_USE_CONTEXT);
|
||||
parm = RNA_def_pointer(
|
||||
func, "view_layer", "ViewLayer", "", "Use this instead of the active view layer");
|
||||
parm = RNA_def_boolean(func, "result", 0, "", "Object holdout");
|
||||
|
|
@ -799,7 +765,7 @@ void RNA_api_object(StructRNA *srna)
|
|||
RNA_def_function_ui_description(func,
|
||||
"Test if object is set to contribute only indirectly (through "
|
||||
"shadows and reflections) in the view layer");
|
||||
RNA_def_function_flag(func, FUNC_USE_CONTEXT | FUNC_USE_REPORTS);
|
||||
RNA_def_function_flag(func, FUNC_USE_CONTEXT);
|
||||
parm = RNA_def_pointer(
|
||||
func, "view_layer", "ViewLayer", "", "Use this instead of the active view layer");
|
||||
parm = RNA_def_boolean(func, "result", 0, "", "Object indirect only");
|
||||
|
|
|
|||
|
|
@ -523,6 +523,8 @@ static void rna_FieldSettings_shape_update(Main *bmain, Scene *scene, PointerRNA
|
|||
if (!particle_id_check(ptr)) {
|
||||
Object *ob = (Object *)ptr->id.data;
|
||||
ED_object_check_force_modifiers(bmain, scene, ob);
|
||||
|
||||
DEG_id_tag_update(&ob->id, ID_RECALC_TRANSFORM);
|
||||
WM_main_add_notifier(NC_OBJECT | ND_DRAW, ob);
|
||||
WM_main_add_notifier(NC_OBJECT | ND_MODIFIER, ob);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2105,6 +2105,13 @@ static void rna_SpaceClipEditor_clip_mode_update(Main *UNUSED(bmain),
|
|||
{
|
||||
SpaceClip *sc = (SpaceClip *)(ptr->data);
|
||||
|
||||
if (sc->mode == SC_MODE_MASKEDIT && sc->view != SC_VIEW_CLIP) {
|
||||
/* Make sure we are in the right view for mask editing */
|
||||
sc->view = SC_VIEW_CLIP;
|
||||
ScrArea *sa = rna_area_from_space(ptr);
|
||||
ED_area_tag_refresh(sa);
|
||||
}
|
||||
|
||||
sc->scopes.ok = 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -34,13 +34,13 @@
|
|||
|
||||
static void rna_Text_clear(Text *text)
|
||||
{
|
||||
BKE_text_clear(text, NULL);
|
||||
BKE_text_clear(text);
|
||||
WM_main_add_notifier(NC_TEXT | NA_EDITED, text);
|
||||
}
|
||||
|
||||
static void rna_Text_write(Text *text, const char *str)
|
||||
{
|
||||
BKE_text_write(text, NULL, str);
|
||||
BKE_text_write(text, str);
|
||||
WM_main_add_notifier(NC_TEXT | NA_EDITED, text);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -187,7 +187,9 @@ static Mesh *applyModifier(ModifierData *md, const ModifierEvalContext *ctx, Mes
|
|||
}
|
||||
}
|
||||
|
||||
if (harden_normals && !(((Mesh *)ctx->object->data)->flag & ME_AUTOSMOOTH)) {
|
||||
Object *ob = ctx->object;
|
||||
|
||||
if (harden_normals && (ob->type == OB_MESH) && !(((Mesh *)ob->data)->flag & ME_AUTOSMOOTH)) {
|
||||
modifier_setError(md, "Enable 'Auto Smooth' option in mesh settings for hardening");
|
||||
harden_normals = false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -335,7 +335,7 @@ static Mesh *doMirrorOnAxis(MirrorModifierData *mmd,
|
|||
}
|
||||
|
||||
/* handle custom split normals */
|
||||
if ((((Mesh *)ob->data)->flag & ME_AUTOSMOOTH) &&
|
||||
if (ob->type == OB_MESH && (((Mesh *)ob->data)->flag & ME_AUTOSMOOTH) &&
|
||||
CustomData_has_layer(&result->ldata, CD_CUSTOMLOOPNORMAL)) {
|
||||
const int totloop = result->totloop;
|
||||
const int totpoly = result->totpoly;
|
||||
|
|
|
|||
|
|
@ -3235,7 +3235,11 @@ void wm_event_do_handlers(bContext *C)
|
|||
if (scene_eval != NULL) {
|
||||
const int is_playing_sound = BKE_sound_scene_playing(scene_eval);
|
||||
|
||||
if (is_playing_sound != -1) {
|
||||
if (scene_eval->id.recalc & ID_RECALC_AUDIO_SEEK) {
|
||||
/* Ignore seek here, the audio will be updated to the scene frame after jump during next
|
||||
* dependency graph update. */
|
||||
}
|
||||
else if (is_playing_sound != -1) {
|
||||
bool is_playing_screen;
|
||||
|
||||
is_playing_screen = (ED_screen_animation_playing(wm) != NULL);
|
||||
|
|
|
|||
|
|
@ -623,8 +623,6 @@ bool WM_file_read(bContext *C, const char *filepath, ReportList *reports)
|
|||
|
||||
/* we didn't succeed, now try to read Blender file */
|
||||
if (retval == BKE_READ_EXOTIC_OK_BLEND) {
|
||||
bool use_data = true;
|
||||
bool use_userdef = false;
|
||||
const int G_f_orig = G.f;
|
||||
ListBase wmbase;
|
||||
|
||||
|
|
@ -670,18 +668,14 @@ bool WM_file_read(bContext *C, const char *filepath, ReportList *reports)
|
|||
wm_window_match_do(C, &wmbase, &bmain->wm, &bmain->wm);
|
||||
WM_check(C); /* opens window(s), checks keymaps */
|
||||
|
||||
if (retval == BKE_BLENDFILE_READ_OK_USERPREFS) {
|
||||
/* in case a userdef is read from regular .blend */
|
||||
wm_init_userdef(bmain, false);
|
||||
use_userdef = true;
|
||||
}
|
||||
|
||||
if (retval != BKE_BLENDFILE_READ_FAIL) {
|
||||
if (do_history) {
|
||||
wm_history_file_update();
|
||||
}
|
||||
}
|
||||
|
||||
const bool use_data = true;
|
||||
const bool use_userdef = false;
|
||||
wm_file_read_post(C, false, false, use_data, use_userdef, false);
|
||||
|
||||
success = true;
|
||||
|
|
@ -1871,7 +1865,9 @@ void WM_OT_read_factory_userpref(wmOperatorType *ot)
|
|||
{
|
||||
ot->name = "Load Factory Preferences";
|
||||
ot->idname = "WM_OT_read_factory_userpref";
|
||||
ot->description = "Load default preferences";
|
||||
ot->description =
|
||||
"Load factory default preferences. "
|
||||
"To make changes to preferences permanent, use \"Save Preferences\"";
|
||||
|
||||
ot->invoke = WM_operator_confirm;
|
||||
ot->exec = wm_userpref_read_exec;
|
||||
|
|
@ -2044,7 +2040,9 @@ void WM_OT_read_factory_settings(wmOperatorType *ot)
|
|||
{
|
||||
ot->name = "Load Factory Settings";
|
||||
ot->idname = "WM_OT_read_factory_settings";
|
||||
ot->description = "Load default file and preferences";
|
||||
ot->description =
|
||||
"Load factory default startup file and preferences. "
|
||||
"To make changes permanent, use \"Save Startup File\" and \"Save Preferences\"";
|
||||
|
||||
ot->invoke = WM_operator_confirm;
|
||||
ot->exec = wm_homefile_read_exec;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue