Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHans Goudey <h.goudey@me.com>2020-10-26 18:41:51 +0300
committerHans Goudey <h.goudey@me.com>2020-10-26 18:41:51 +0300
commit5288298cfa6fe735204350f4826daeed52375c43 (patch)
tree45714678f3ffb98b69df884eddb29c7df1de2644
parent3c02fdb2c87bf8b1a8f46360d2c168ad59198d8f (diff)
parente04491073d91434a5c3a93ec36d94efd3b540eec (diff)
Merge branch 'geometry-nodes' into geometry-nodes-boolean-node
-rw-r--r--intern/clog/CLG_log.h2
-rw-r--r--intern/clog/clog.c8
-rw-r--r--intern/cycles/blender/addon/ui.py2
-rw-r--r--intern/cycles/util/util_task.cpp15
-rw-r--r--intern/cycles/util/util_task.h4
-rw-r--r--release/scripts/modules/bl_keymap_utils/keymap_from_toolbar.py29
-rw-r--r--release/scripts/presets/keyconfig/keymap_data/blender_default.py12
-rw-r--r--release/scripts/presets/keyconfig/keymap_data/industry_compatible_data.py8
-rw-r--r--release/scripts/startup/bl_operators/anim.py2
-rw-r--r--release/scripts/startup/bl_operators/clip.py2
-rw-r--r--release/scripts/startup/bl_operators/console.py2
-rw-r--r--release/scripts/startup/bl_operators/geometry_nodes.py3
-rw-r--r--release/scripts/startup/bl_operators/sequencer.py4
-rw-r--r--release/scripts/startup/bl_operators/userpref.py4
-rw-r--r--release/scripts/startup/bl_operators/wm.py4
-rw-r--r--release/scripts/startup/bl_ui/properties_data_empty.py2
-rw-r--r--release/scripts/startup/bl_ui/properties_data_gpencil.py4
-rw-r--r--release/scripts/startup/bl_ui/properties_data_mesh.py2
-rw-r--r--release/scripts/startup/bl_ui/properties_freestyle.py2
-rw-r--r--release/scripts/startup/bl_ui/properties_grease_pencil_common.py2
-rw-r--r--release/scripts/startup/bl_ui/properties_mask_common.py2
-rw-r--r--release/scripts/startup/bl_ui/properties_material_gpencil.py2
-rw-r--r--release/scripts/startup/bl_ui/properties_object.py2
-rw-r--r--release/scripts/startup/bl_ui/properties_paint_common.py2
-rw-r--r--release/scripts/startup/bl_ui/properties_physics_common.py4
-rw-r--r--release/scripts/startup/bl_ui/properties_physics_field.py4
-rw-r--r--release/scripts/startup/bl_ui/properties_physics_fluid.py2
-rw-r--r--release/scripts/startup/bl_ui/space_clip.py8
-rw-r--r--release/scripts/startup/bl_ui/space_dopesheet.py2
-rw-r--r--release/scripts/startup/bl_ui/space_sequencer.py6
-rw-r--r--release/scripts/startup/bl_ui/space_text.py2
-rw-r--r--release/scripts/startup/bl_ui/space_toolsystem_toolbar.py6
-rw-r--r--release/scripts/startup/bl_ui/space_userpref.py12
-rw-r--r--release/scripts/startup/bl_ui/space_view3d.py28
-rw-r--r--release/scripts/startup/bl_ui/space_view3d_toolbar.py32
-rw-r--r--source/blender/blenfont/BLF_api.h6
-rw-r--r--source/blender/blenfont/intern/blf_font.c6
-rw-r--r--source/blender/blenkernel/BKE_DerivedMesh.h1
-rw-r--r--source/blender/blenkernel/BKE_geometry.hh1
-rw-r--r--source/blender/blenkernel/BKE_modifier.h6
-rw-r--r--source/blender/blenkernel/BKE_pointcache.h2
-rw-r--r--source/blender/blenkernel/CMakeLists.txt1
-rw-r--r--source/blender/blenkernel/intern/DerivedMesh.c15
-rw-r--r--source/blender/blenkernel/intern/armature.c3
-rw-r--r--source/blender/blenkernel/intern/cloth.c22
-rw-r--r--source/blender/blenkernel/intern/crazyspace.c4
-rw-r--r--source/blender/blenkernel/intern/curve.c13
-rw-r--r--source/blender/blenkernel/intern/fcurve.c6
-rw-r--r--source/blender/blenkernel/intern/geometry.cc8
-rw-r--r--source/blender/blenkernel/intern/lattice_deform.c151
-rw-r--r--source/blender/blenkernel/intern/lattice_deform_test.cc138
-rw-r--r--source/blender/blenkernel/intern/lib_id_delete.c4
-rw-r--r--source/blender/blenkernel/intern/lib_override.c52
-rw-r--r--source/blender/blenkernel/intern/modifier.c13
-rw-r--r--source/blender/blenkernel/intern/pointcache.c35
-rw-r--r--source/blender/blenlib/intern/mesh_boolean.cc2
-rw-r--r--source/blender/blenloader/intern/versioning_290.c14
-rw-r--r--source/blender/bmesh/tools/bmesh_bevel.c33
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_relations.cc3
-rw-r--r--source/blender/editors/armature/armature_naming.c2
-rw-r--r--source/blender/editors/armature/armature_select.c4
-rw-r--r--source/blender/editors/armature/meshlaplacian.c3
-rw-r--r--source/blender/editors/armature/pose_edit.c2
-rw-r--r--source/blender/editors/curve/editcurve_query.c4
-rw-r--r--source/blender/editors/curve/editcurve_select.c33
-rw-r--r--source/blender/editors/gpencil/gpencil_edit.c4
-rw-r--r--source/blender/editors/interface/interface.c202
-rw-r--r--source/blender/editors/interface/interface_eyedropper.c2
-rw-r--r--source/blender/editors/interface/interface_panel.c16
-rw-r--r--source/blender/editors/interface/interface_templates.c2
-rw-r--r--source/blender/editors/mesh/editmesh_bevel.c28
-rw-r--r--source/blender/editors/mesh/editmesh_mask_extract.c6
-rw-r--r--source/blender/editors/mesh/editmesh_select_similar.c2
-rw-r--r--source/blender/editors/object/object_hook.c8
-rw-r--r--source/blender/editors/object/object_modifier.c4
-rw-r--r--source/blender/editors/object/object_relations.c2
-rw-r--r--source/blender/editors/physics/particle_object.c4
-rw-r--r--source/blender/editors/screen/screen_ops.c4
-rw-r--r--source/blender/editors/sculpt_paint/paint_mask.c132
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_cloth.c120
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_face_set.c215
-rw-r--r--source/blender/editors/space_clip/tracking_ops.c6
-rw-r--r--source/blender/editors/space_clip/tracking_select.c12
-rw-r--r--source/blender/editors/space_sequencer/sequencer_edit.c4
-rw-r--r--source/blender/editors/space_text/text_ops.c4
-rw-r--r--source/blender/editors/space_view3d/view3d_buttons.c11
-rw-r--r--source/blender/editors/transform/transform.c18
-rw-r--r--source/blender/gpencil_modifiers/intern/MOD_gpencilarmature.c2
-rw-r--r--source/blender/gpu/CMakeLists.txt1
-rw-r--r--source/blender/gpu/intern/gpu_debug.cc2
-rw-r--r--source/blender/gpu/intern/gpu_shader.cc60
-rw-r--r--source/blender/gpu/intern/gpu_shader_interface.cc1
-rw-r--r--source/blender/gpu/intern/gpu_shader_private.hh2
-rw-r--r--source/blender/gpu/opengl/gl_debug.cc52
-rw-r--r--source/blender/gpu/opengl/gl_shader.cc8
-rw-r--r--source/blender/makesdna/DNA_modifier_types.h4
-rw-r--r--source/blender/makesrna/intern/rna_action.c2
-rw-r--r--source/blender/makesrna/intern/rna_color.c2
-rw-r--r--source/blender/makesrna/intern/rna_curve.c8
-rw-r--r--source/blender/makesrna/intern/rna_modifier.c4
-rw-r--r--source/blender/makesrna/intern/rna_nodetree.c8
-rw-r--r--source/blender/makesrna/intern/rna_scene.c22
-rw-r--r--source/blender/makesrna/intern/rna_sculpt_paint.c2
-rw-r--r--source/blender/makesrna/intern/rna_sequencer.c6
-rw-r--r--source/blender/makesrna/intern/rna_space.c4
-rw-r--r--source/blender/makesrna/intern/rna_texture.c4
-rw-r--r--source/blender/makesrna/intern/rna_userdef.c2
-rw-r--r--source/blender/modifiers/intern/MOD_armature.c2
-rw-r--r--source/blender/modifiers/intern/MOD_array.c4
-rw-r--r--source/blender/modifiers/intern/MOD_bevel.c2
-rw-r--r--source/blender/modifiers/intern/MOD_boolean.c18
-rw-r--r--source/blender/modifiers/intern/MOD_correctivesmooth.c10
-rw-r--r--source/blender/modifiers/intern/MOD_datatransfer.c9
-rw-r--r--source/blender/modifiers/intern/MOD_decimate.c2
-rw-r--r--source/blender/modifiers/intern/MOD_laplaciandeform.c15
-rw-r--r--source/blender/modifiers/intern/MOD_laplaciansmooth.c2
-rw-r--r--source/blender/modifiers/intern/MOD_mesh_to_volume.cc4
-rw-r--r--source/blender/modifiers/intern/MOD_meshcache.c8
-rw-r--r--source/blender/modifiers/intern/MOD_meshdeform.c10
-rw-r--r--source/blender/modifiers/intern/MOD_meshsequencecache.c4
-rw-r--r--source/blender/modifiers/intern/MOD_multires.c4
-rw-r--r--source/blender/modifiers/intern/MOD_nodes.cc196
-rw-r--r--source/blender/modifiers/intern/MOD_normal_edit.c15
-rw-r--r--source/blender/modifiers/intern/MOD_skin.c42
-rw-r--r--source/blender/modifiers/intern/MOD_solidify_nonmanifold.c21
-rw-r--r--source/blender/modifiers/intern/MOD_subsurf.c4
-rw-r--r--source/blender/modifiers/intern/MOD_surfacedeform.c44
-rw-r--r--source/blender/modifiers/intern/MOD_ui_common.c4
-rw-r--r--source/blender/modifiers/intern/MOD_volume_displace.cc2
-rw-r--r--source/blender/modifiers/intern/MOD_volume_to_mesh.cc8
-rw-r--r--source/blender/modifiers/intern/MOD_weighted_normal.c3
-rw-r--r--source/blender/nodes/NOD_geometry_exec.hh9
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_transform.cc26
-rw-r--r--source/blender/sequencer/BKE_sequencer.h481
-rw-r--r--source/blender/sequencer/CMakeLists.txt2
-rw-r--r--source/blender/sequencer/intern/effects.c2
-rw-r--r--source/blender/sequencer/intern/image_cache.c2
-rw-r--r--source/blender/sequencer/intern/modifier.c2
-rw-r--r--source/blender/sequencer/intern/prefetch.c6
-rw-r--r--source/blender/sequencer/intern/sequencer.c8
-rw-r--r--source/blender/sequencer/intern/sequencer.h190
-rw-r--r--source/blender/windowmanager/intern/wm_operators.c4
142 files changed, 1864 insertions, 1117 deletions
diff --git a/intern/clog/CLG_log.h b/intern/clog/CLG_log.h
index a2841c5c8b3..3e51e228bac 100644
--- a/intern/clog/CLG_log.h
+++ b/intern/clog/CLG_log.h
@@ -150,6 +150,8 @@ void CLG_level_set(int level);
void CLG_logref_init(CLG_LogRef *clg_ref);
+int CLG_color_support_get(CLG_LogRef *clg_ref);
+
/** Declare outside function, declare as extern in header. */
#define CLG_LOGREF_DECLARE_GLOBAL(var, id) \
static CLG_LogRef _static_##var = {id}; \
diff --git a/intern/clog/clog.c b/intern/clog/clog.c
index 37c8393f532..2bc3985c71f 100644
--- a/intern/clog/clog.c
+++ b/intern/clog/clog.c
@@ -755,4 +755,12 @@ void CLG_logref_init(CLG_LogRef *clg_ref)
#endif
}
+int CLG_color_support_get(CLG_LogRef *clg_ref)
+{
+ if (clg_ref->type == NULL) {
+ CLG_logref_init(clg_ref);
+ }
+ return clg_ref->type->ctx->use_color;
+}
+
/** \} */
diff --git a/intern/cycles/blender/addon/ui.py b/intern/cycles/blender/addon/ui.py
index 72d98e78c4d..6b88be3e7aa 100644
--- a/intern/cycles/blender/addon/ui.py
+++ b/intern/cycles/blender/addon/ui.py
@@ -1271,7 +1271,7 @@ class CYCLES_OBJECT_PT_visibility(CyclesButtonsPanel, Panel):
layout.prop(ob, "hide_select", text="Selectable", invert_checkbox=True, toggle=False)
- col = layout.column(heading="Show in")
+ col = layout.column(heading="Show In")
col.prop(ob, "hide_viewport", text="Viewports", invert_checkbox=True, toggle=False)
col.prop(ob, "hide_render", text="Renders", invert_checkbox=True, toggle=False)
diff --git a/intern/cycles/util/util_task.cpp b/intern/cycles/util/util_task.cpp
index 4fb61392e92..50c236ac968 100644
--- a/intern/cycles/util/util_task.cpp
+++ b/intern/cycles/util/util_task.cpp
@@ -24,7 +24,7 @@ CCL_NAMESPACE_BEGIN
/* Task Pool */
-TaskPool::TaskPool() : start_time(time_dt()), num_tasks_handled(0)
+TaskPool::TaskPool() : start_time(time_dt()), num_tasks_pushed(0)
{
}
@@ -36,7 +36,7 @@ TaskPool::~TaskPool()
void TaskPool::push(TaskRunFunction &&task)
{
tbb_group.run(std::move(task));
- num_tasks_handled++;
+ num_tasks_pushed++;
}
void TaskPool::wait_work(Summary *stats)
@@ -45,14 +45,19 @@ void TaskPool::wait_work(Summary *stats)
if (stats != NULL) {
stats->time_total = time_dt() - start_time;
- stats->num_tasks_handled = num_tasks_handled;
+ stats->num_tasks_handled = num_tasks_pushed;
}
+
+ num_tasks_pushed = 0;
}
void TaskPool::cancel()
{
- tbb_group.cancel();
- tbb_group.wait();
+ if (num_tasks_pushed > 0) {
+ tbb_group.cancel();
+ tbb_group.wait();
+ num_tasks_pushed = 0;
+ }
}
bool TaskPool::canceled()
diff --git a/intern/cycles/util/util_task.h b/intern/cycles/util/util_task.h
index d3c3c11f8e2..f2718600f30 100644
--- a/intern/cycles/util/util_task.h
+++ b/intern/cycles/util/util_task.h
@@ -71,8 +71,8 @@ class TaskPool {
/* Time time stamp of first task pushed. */
double start_time;
- /* Number of all tasks handled by this pool. */
- int num_tasks_handled;
+ /* Number of all tasks pushed to the pool. Cleared after wait_work() and cancel(). */
+ int num_tasks_pushed;
};
/* Task Scheduler
diff --git a/release/scripts/modules/bl_keymap_utils/keymap_from_toolbar.py b/release/scripts/modules/bl_keymap_utils/keymap_from_toolbar.py
index e18cca7fe25..ebc5370a7af 100644
--- a/release/scripts/modules/bl_keymap_utils/keymap_from_toolbar.py
+++ b/release/scripts/modules/bl_keymap_utils/keymap_from_toolbar.py
@@ -192,16 +192,25 @@ def generate(context, space_type, use_fallback_keys=True, use_reset=True):
# PAINT_OT_brush_select
mode = context.active_object.mode
# See: BKE_paint_get_tool_prop_id_from_paintmode
- attr = {
- 'SCULPT': "sculpt_tool",
- 'VERTEX_PAINT': "vertex_tool",
- 'WEIGHT_PAINT': "weight_tool",
- 'TEXTURE_PAINT': "image_tool",
- 'PAINT_GPENCIL': "gpencil_tool",
- 'VERTEX_GPENCIL': "gpencil_vertex_tool",
- 'SCULPT_GPENCIL': "gpencil_sculpt_tool",
- 'WEIGHT_GPENCIL': "gpencil_weight_tool",
- }.get(mode, None)
+ if space_type == 'IMAGE_EDITOR':
+ if context.space_data.ui_mode == 'PAINT':
+ attr = "image_tool"
+ else:
+ attr = None
+ elif space_type == 'VIEW_3D':
+ attr = {
+ 'SCULPT': "sculpt_tool",
+ 'VERTEX_PAINT': "vertex_tool",
+ 'WEIGHT_PAINT': "weight_tool",
+ 'TEXTURE_PAINT': "image_tool",
+ 'PAINT_GPENCIL': "gpencil_tool",
+ 'VERTEX_GPENCIL': "gpencil_vertex_tool",
+ 'SCULPT_GPENCIL': "gpencil_sculpt_tool",
+ 'WEIGHT_GPENCIL': "gpencil_weight_tool",
+ }.get(mode, None)
+ else:
+ attr = None
+
if attr is not None:
setattr(kmi_hack_brush_select_properties, attr, item.data_block)
kmi_found = wm.keyconfigs.find_item_from_operator(
diff --git a/release/scripts/presets/keyconfig/keymap_data/blender_default.py b/release/scripts/presets/keyconfig/keymap_data/blender_default.py
index c462bf12825..ac81a706858 100644
--- a/release/scripts/presets/keyconfig/keymap_data/blender_default.py
+++ b/release/scripts/presets/keyconfig/keymap_data/blender_default.py
@@ -2336,10 +2336,10 @@ def km_text(params):
("text.run_script", {"type": 'P', "value": 'PRESS', "alt": True}, None),
("text.cut", {"type": 'X', "value": 'PRESS', "ctrl": True}, None),
("text.copy", {"type": 'C', "value": 'PRESS', "ctrl": True}, None),
- ("text.paste", {"type": 'V', "value": 'PRESS', "ctrl": True}, None),
+ ("text.paste", {"type": 'V', "value": 'PRESS', "ctrl": True, "repeat": True}, None),
("text.cut", {"type": 'DEL', "value": 'PRESS', "shift": True}, None),
("text.copy", {"type": 'INSERT', "value": 'PRESS', "ctrl": True}, None),
- ("text.paste", {"type": 'INSERT', "value": 'PRESS', "shift": True}, None),
+ ("text.paste", {"type": 'INSERT', "value": 'PRESS', "shift": True, "repeat": True}, None),
("text.duplicate_line", {"type": 'D', "value": 'PRESS', "ctrl": True, "repeat": True}, None),
("text.select_all", {"type": 'A', "value": 'PRESS', "ctrl": True}, None),
("text.select_line", {"type": 'A', "value": 'PRESS', "shift": True, "ctrl": True}, None),
@@ -2669,7 +2669,7 @@ def km_console(_params):
{"properties": [("interactive", True)]}),
("console.copy_as_script", {"type": 'C', "value": 'PRESS', "shift": True, "ctrl": True}, None),
("console.copy", {"type": 'C', "value": 'PRESS', "ctrl": True}, None),
- ("console.paste", {"type": 'V', "value": 'PRESS', "ctrl": True}, None),
+ ("console.paste", {"type": 'V', "value": 'PRESS', "ctrl": True, "repeat": True}, None),
("console.select_set", {"type": 'LEFTMOUSE', "value": 'PRESS'}, None),
("console.select_word", {"type": 'LEFTMOUSE', "value": 'DOUBLE_CLICK'}, None),
("console.insert", {"type": 'TAB', "value": 'PRESS', "ctrl": True, "repeat": True},
@@ -4861,7 +4861,7 @@ def km_font(params):
("font.select_all", {"type": 'A', "value": 'PRESS', "ctrl": True}, None),
("font.text_copy", {"type": 'C', "value": 'PRESS', "ctrl": True}, None),
("font.text_cut", {"type": 'X', "value": 'PRESS', "ctrl": True}, None),
- ("font.text_paste", {"type": 'V', "value": 'PRESS', "ctrl": True}, None),
+ ("font.text_paste", {"type": 'V', "value": 'PRESS', "ctrl": True, "repeat": True}, None),
("font.line_break", {"type": 'RET', "value": 'PRESS', "repeat": True}, None),
("font.text_insert", {"type": 'TEXTINPUT', "value": 'ANY', "any": True, "repeat": True}, None),
("font.text_insert", {"type": 'BACK_SPACE', "value": 'PRESS', "alt": True, "repeat": True},
@@ -6490,10 +6490,8 @@ def km_3d_view_tool_sculpt_face_set_edit(params):
"3D View Tool: Sculpt, Face Set Edit",
{"space_type": 'VIEW_3D', "region_type": 'WINDOW'},
{"items": [
- ("sculpt.face_set_edit", {"type": params.tool_mouse, "value": 'ANY'},
+ ("sculpt.face_set_edit", {"type": params.tool_mouse, "value": 'PRESS'},
None),
- ("sculpt.face_set_edit", {"type": params.tool_tweak, "value": 'ANY'},
- None)
]},
)
diff --git a/release/scripts/presets/keyconfig/keymap_data/industry_compatible_data.py b/release/scripts/presets/keyconfig/keymap_data/industry_compatible_data.py
index 666dbb30365..c79a59145cf 100644
--- a/release/scripts/presets/keyconfig/keymap_data/industry_compatible_data.py
+++ b/release/scripts/presets/keyconfig/keymap_data/industry_compatible_data.py
@@ -1603,10 +1603,10 @@ def km_text(params):
("text.run_script", {"type": 'P', "value": 'PRESS', "alt": True}, None),
("text.cut", {"type": 'X', "value": 'PRESS', "ctrl": True}, None),
("text.copy", {"type": 'C', "value": 'PRESS', "ctrl": True}, None),
- ("text.paste", {"type": 'V', "value": 'PRESS', "ctrl": True}, None),
+ ("text.paste", {"type": 'V', "value": 'PRESS', "ctrl": True, "repeat": True}, None),
("text.cut", {"type": 'DEL', "value": 'PRESS', "shift": True}, None),
("text.copy", {"type": 'INSERT', "value": 'PRESS', "ctrl": True}, None),
- ("text.paste", {"type": 'INSERT', "value": 'PRESS', "shift": True}, None),
+ ("text.paste", {"type": 'INSERT', "value": 'PRESS', "shift": True, "repeat": True}, None),
("text.duplicate_line", {"type": 'D', "value": 'PRESS', "ctrl": True, "repeat": True}, None),
("text.select_all", {"type": 'A', "value": 'PRESS', "ctrl": True}, None),
("text.select_line", {"type": 'A', "value": 'PRESS', "shift": True, "ctrl": True}, None),
@@ -1906,7 +1906,7 @@ def km_console(params):
{"properties": [("interactive", True)]}),
("console.copy_as_script", {"type": 'C', "value": 'PRESS', "shift": True, "ctrl": True}, None),
("console.copy", {"type": 'C', "value": 'PRESS', "ctrl": True}, None),
- ("console.paste", {"type": 'V', "value": 'PRESS', "ctrl": True}, None),
+ ("console.paste", {"type": 'V', "value": 'PRESS', "ctrl": True, "repeat": True}, None),
("console.select_set", {"type": 'LEFTMOUSE', "value": 'PRESS'}, None),
("console.select_word", {"type": 'LEFTMOUSE', "value": 'DOUBLE_CLICK'}, None),
("console.insert", {"type": 'TAB', "value": 'PRESS', "ctrl": True, "repeat": True},
@@ -3752,7 +3752,7 @@ def km_font(params):
("font.select_all", {"type": 'A', "value": 'PRESS', "ctrl": True}, None),
("font.text_copy", {"type": 'C', "value": 'PRESS', "ctrl": True}, None),
("font.text_cut", {"type": 'X', "value": 'PRESS', "ctrl": True}, None),
- ("font.text_paste", {"type": 'V', "value": 'PRESS', "ctrl": True}, None),
+ ("font.text_paste", {"type": 'V', "value": 'PRESS', "ctrl": True, "repeat": True}, None),
("font.line_break", {"type": 'RET', "value": 'PRESS'}, None),
("font.text_insert", {"type": 'TEXTINPUT', "value": 'ANY', "any": True}, None),
("font.text_insert", {"type": 'BACK_SPACE', "value": 'PRESS', "alt": True},
diff --git a/release/scripts/startup/bl_operators/anim.py b/release/scripts/startup/bl_operators/anim.py
index d0b4b485d82..8334557d1f6 100644
--- a/release/scripts/startup/bl_operators/anim.py
+++ b/release/scripts/startup/bl_operators/anim.py
@@ -348,7 +348,7 @@ class UpdateAnimatedTransformConstraint(Operator):
bl_options = {'REGISTER', 'UNDO'}
use_convert_to_radians: BoolProperty(
- name="Convert To Radians",
+ name="Convert to Radians",
description="Convert fcurves/drivers affecting rotations to radians (Warning: use this only once!)",
default=True,
)
diff --git a/release/scripts/startup/bl_operators/clip.py b/release/scripts/startup/bl_operators/clip.py
index b4795168a19..a3c54a7b069 100644
--- a/release/scripts/startup/bl_operators/clip.py
+++ b/release/scripts/startup/bl_operators/clip.py
@@ -1011,7 +1011,7 @@ class CLIP_OT_track_settings_as_default(Operator):
"""Copy tracking settings from active track to default settings"""
bl_idname = "clip.track_settings_as_default"
- bl_label = "Track Settings As Default"
+ bl_label = "Track Settings as Default"
bl_options = {'UNDO', 'REGISTER'}
@classmethod
diff --git a/release/scripts/startup/bl_operators/console.py b/release/scripts/startup/bl_operators/console.py
index b62b9310224..bffac4eef55 100644
--- a/release/scripts/startup/bl_operators/console.py
+++ b/release/scripts/startup/bl_operators/console.py
@@ -85,7 +85,7 @@ class ConsoleAutocomplete(Operator):
class ConsoleCopyAsScript(Operator):
"""Copy the console contents for use in a script"""
bl_idname = "console.copy_as_script"
- bl_label = "Copy to Clipboard (as script)"
+ bl_label = "Copy to Clipboard (as Script)"
@classmethod
def poll(cls, context):
diff --git a/release/scripts/startup/bl_operators/geometry_nodes.py b/release/scripts/startup/bl_operators/geometry_nodes.py
index 7643c49f33e..b915827f0e6 100644
--- a/release/scripts/startup/bl_operators/geometry_nodes.py
+++ b/release/scripts/startup/bl_operators/geometry_nodes.py
@@ -39,6 +39,9 @@ class NewGeometryNodeTree(bpy.types.Operator):
input_node.location.x = -200 - input_node.width
output_node.location.x = 200
+
+ group.links.new(output_node.inputs[0], input_node.outputs[0])
+
context.space_data.node_tree = group
return {'FINISHED'}
diff --git a/release/scripts/startup/bl_operators/sequencer.py b/release/scripts/startup/bl_operators/sequencer.py
index 6b420d20e14..df1098bdd3f 100644
--- a/release/scripts/startup/bl_operators/sequencer.py
+++ b/release/scripts/startup/bl_operators/sequencer.py
@@ -32,7 +32,7 @@ class SequencerCrossfadeSounds(Operator):
"""Do cross-fading volume animation of two selected sound strips"""
bl_idname = "sequencer.crossfade_sounds"
- bl_label = "Crossfade sounds"
+ bl_label = "Crossfade Sounds"
bl_options = {'REGISTER', 'UNDO'}
@classmethod
@@ -83,7 +83,7 @@ class SequencerSplitMulticam(Operator):
"""Split multi-cam strip and select camera"""
bl_idname = "sequencer.split_multicam"
- bl_label = "Split multicam"
+ bl_label = "Split Multicam"
bl_options = {'REGISTER', 'UNDO'}
camera: IntProperty(
diff --git a/release/scripts/startup/bl_operators/userpref.py b/release/scripts/startup/bl_operators/userpref.py
index 31d601debba..07dba491dbd 100644
--- a/release/scripts/startup/bl_operators/userpref.py
+++ b/release/scripts/startup/bl_operators/userpref.py
@@ -1112,9 +1112,9 @@ class PREFERENCES_OT_studiolight_uninstall(Operator):
class PREFERENCES_OT_studiolight_copy_settings(Operator):
- """Copy Studio Light settings to the Studio light editor"""
+ """Copy Studio Light settings to the Studio Light editor"""
bl_idname = "preferences.studiolight_copy_settings"
- bl_label = "Copy Studio Light settings"
+ bl_label = "Copy Studio Light Settings"
index: IntProperty()
def execute(self, context):
diff --git a/release/scripts/startup/bl_operators/wm.py b/release/scripts/startup/bl_operators/wm.py
index e9a658bdc10..aa4e4e77993 100644
--- a/release/scripts/startup/bl_operators/wm.py
+++ b/release/scripts/startup/bl_operators/wm.py
@@ -1660,7 +1660,7 @@ class WM_OT_owner_disable(Operator):
class WM_OT_tool_set_by_id(Operator):
"""Set the tool by name (for keymaps)"""
bl_idname = "wm.tool_set_by_id"
- bl_label = "Set Tool By Name"
+ bl_label = "Set Tool by Name"
name: StringProperty(
name="Identifier",
@@ -1718,7 +1718,7 @@ class WM_OT_tool_set_by_id(Operator):
class WM_OT_tool_set_by_index(Operator):
"""Set the tool by index (for keymaps)"""
bl_idname = "wm.tool_set_by_index"
- bl_label = "Set Tool By Index"
+ bl_label = "Set Tool by Index"
index: IntProperty(
name="Index in toolbar",
default=0,
diff --git a/release/scripts/startup/bl_ui/properties_data_empty.py b/release/scripts/startup/bl_ui/properties_data_empty.py
index c8a1d9e238c..7ded4c775a7 100644
--- a/release/scripts/startup/bl_ui/properties_data_empty.py
+++ b/release/scripts/startup/bl_ui/properties_data_empty.py
@@ -54,7 +54,7 @@ class DATA_PT_empty(DataButtonsPanel, Panel):
depth_row.prop(ob, "empty_image_depth", text="Depth", expand=True)
col.row().prop(ob, "empty_image_side", text="Side", expand=True)
- col = layout.column(heading="Show in", align=True)
+ col = layout.column(heading="Show In", align=True)
col.prop(ob, "show_empty_image_orthographic", text="Orthographic")
col.prop(ob, "show_empty_image_perspective", text="Perspective")
col.prop(ob, "show_empty_image_only_axis_aligned", text="Only Axis Aligned")
diff --git a/release/scripts/startup/bl_ui/properties_data_gpencil.py b/release/scripts/startup/bl_ui/properties_data_gpencil.py
index 946578937bb..affdba6f693 100644
--- a/release/scripts/startup/bl_ui/properties_data_gpencil.py
+++ b/release/scripts/startup/bl_ui/properties_data_gpencil.py
@@ -101,7 +101,7 @@ class GPENCIL_MT_layer_context_menu(Menu):
layout.separator()
layout.operator("gpencil.lock_all", icon='LOCKED', text="Lock All")
- layout.operator("gpencil.unlock_all", icon='UNLOCKED', text="UnLock All")
+ layout.operator("gpencil.unlock_all", icon='UNLOCKED', text="Unlock All")
layout.prop(gpd, "use_autolock_layers", text="Autolock Inactive Layers")
layout.separator()
@@ -263,7 +263,7 @@ class DATA_PT_gpencil_onion_skinning_display(DataButtonsPanel, Panel):
layout.use_property_split = True
layout.enabled = gpd.users <= 1
- layout.prop(gpd, "use_ghosts_always", text="View In Render")
+ layout.prop(gpd, "use_ghosts_always", text="View in Render")
col = layout.column(align=True)
col.prop(gpd, "use_onion_fade", text="Fade")
diff --git a/release/scripts/startup/bl_ui/properties_data_mesh.py b/release/scripts/startup/bl_ui/properties_data_mesh.py
index 2ea439a7e89..924a89755f8 100644
--- a/release/scripts/startup/bl_ui/properties_data_mesh.py
+++ b/release/scripts/startup/bl_ui/properties_data_mesh.py
@@ -57,7 +57,7 @@ class MESH_MT_vertex_group_context_menu(Menu):
layout.separator()
props = layout.operator("object.vertex_group_lock", icon='LOCKED', text="Lock All")
props.action, props.mask = 'LOCK', 'ALL'
- props = layout.operator("object.vertex_group_lock", icon='UNLOCKED', text="UnLock All")
+ props = layout.operator("object.vertex_group_lock", icon='UNLOCKED', text="Unlock All")
props.action, props.mask = 'UNLOCK', 'ALL'
props = layout.operator("object.vertex_group_lock", text="Lock Invert All")
props.action, props.mask = 'INVERT', 'ALL'
diff --git a/release/scripts/startup/bl_ui/properties_freestyle.py b/release/scripts/startup/bl_ui/properties_freestyle.py
index 3a2b26aaebb..3d574fca2ff 100644
--- a/release/scripts/startup/bl_ui/properties_freestyle.py
+++ b/release/scripts/startup/bl_ui/properties_freestyle.py
@@ -162,7 +162,7 @@ class VIEWLAYER_PT_freestyle(ViewLayerFreestyleButtonsPanel, Panel):
if freestyle.mode == 'SCRIPT':
row = layout.row()
- row.label(text="Style modules:")
+ row.label(text="Style Modules:")
row.operator("scene.freestyle_module_add", text="Add")
for module in freestyle.modules:
box = layout.box()
diff --git a/release/scripts/startup/bl_ui/properties_grease_pencil_common.py b/release/scripts/startup/bl_ui/properties_grease_pencil_common.py
index 910d6b64b74..97e87f5451c 100644
--- a/release/scripts/startup/bl_ui/properties_grease_pencil_common.py
+++ b/release/scripts/startup/bl_ui/properties_grease_pencil_common.py
@@ -884,7 +884,7 @@ class GreasePencilLayerDisplayPanel:
col.prop(gpl, "channel_color")
col = layout.row(align=True)
- col.prop(gpl, "use_solo_mode", text="Show Only On Keyframed")
+ col.prop(gpl, "use_solo_mode", text="Show Only on Keyframed")
class GreasePencilFlipTintColors(Operator):
diff --git a/release/scripts/startup/bl_ui/properties_mask_common.py b/release/scripts/startup/bl_ui/properties_mask_common.py
index 6ee755722f3..4d25b8ca309 100644
--- a/release/scripts/startup/bl_ui/properties_mask_common.py
+++ b/release/scripts/startup/bl_ui/properties_mask_common.py
@@ -37,7 +37,7 @@ def draw_mask_context_menu(layout, context):
layout.separator()
- layout.operator("mask.shape_key_rekey", text="Re-key Shape Points")
+ layout.operator("mask.shape_key_rekey", text="Re-Key Shape Points")
layout.operator("mask.feather_weight_clear")
layout.operator("mask.shape_key_feather_reset", text="Reset Feather Animation")
diff --git a/release/scripts/startup/bl_ui/properties_material_gpencil.py b/release/scripts/startup/bl_ui/properties_material_gpencil.py
index 4ed7b1ac7b9..da54ff1a137 100644
--- a/release/scripts/startup/bl_ui/properties_material_gpencil.py
+++ b/release/scripts/startup/bl_ui/properties_material_gpencil.py
@@ -39,7 +39,7 @@ class GPENCIL_MT_material_context_menu(Menu):
layout.separator()
layout.operator("gpencil.material_lock_all", icon='LOCKED', text="Lock All")
- layout.operator("gpencil.material_unlock_all", icon='UNLOCKED', text="UnLock All")
+ layout.operator("gpencil.material_unlock_all", icon='UNLOCKED', text="Unlock All")
layout.operator("gpencil.material_lock_unused", text="Lock Unselected")
layout.operator("gpencil.lock_layer", text="Lock Unused")
diff --git a/release/scripts/startup/bl_ui/properties_object.py b/release/scripts/startup/bl_ui/properties_object.py
index b142f6085fa..4530b4bbe48 100644
--- a/release/scripts/startup/bl_ui/properties_object.py
+++ b/release/scripts/startup/bl_ui/properties_object.py
@@ -364,7 +364,7 @@ class OBJECT_PT_visibility(ObjectButtonsPanel, Panel):
layout.prop(ob, "hide_select", text="Selectable", toggle=False, invert_checkbox=True)
- col = layout.column(heading="Show in")
+ col = layout.column(heading="Show In")
col.prop(ob, "hide_viewport", text="Viewports", toggle=False, invert_checkbox=True)
col.prop(ob, "hide_render", text="Renders", toggle=False, invert_checkbox=True)
diff --git a/release/scripts/startup/bl_ui/properties_paint_common.py b/release/scripts/startup/bl_ui/properties_paint_common.py
index cf44bb36fb5..01454f8ee05 100644
--- a/release/scripts/startup/bl_ui/properties_paint_common.py
+++ b/release/scripts/startup/bl_ui/properties_paint_common.py
@@ -330,7 +330,7 @@ class StrokePanel(BrushPanel):
col.separator()
if brush.use_anchor:
- col.prop(brush, "use_edge_to_edge", text="Edge To Edge")
+ col.prop(brush, "use_edge_to_edge", text="Edge to Edge")
if brush.use_airbrush:
col.prop(brush, "rate", text="Rate", slider=True)
diff --git a/release/scripts/startup/bl_ui/properties_physics_common.py b/release/scripts/startup/bl_ui/properties_physics_common.py
index abc75ceed2c..b8c0035ee6b 100644
--- a/release/scripts/startup/bl_ui/properties_physics_common.py
+++ b/release/scripts/startup/bl_ui/properties_physics_common.py
@@ -228,7 +228,7 @@ def point_cache_ui(self, cache, enabled, cachetype):
sub = col.row()
sub.enabled = enabled
- sub.operator("ptcache.bake", text="Calculate To Frame").bake = False
+ sub.operator("ptcache.bake", text="Calculate to Frame").bake = False
sub = col.column()
sub.enabled = enabled
@@ -237,7 +237,7 @@ def point_cache_ui(self, cache, enabled, cachetype):
col = flow.column()
col.operator("ptcache.bake_all", text="Bake All Dynamics").bake = True
col.operator("ptcache.free_bake_all", text="Delete All Bakes")
- col.operator("ptcache.bake_all", text="Update All To Frame").bake = False
+ col.operator("ptcache.bake_all", text="Update All to Frame").bake = False
def effector_weights_ui(self, weights, weight_type):
diff --git a/release/scripts/startup/bl_ui/properties_physics_field.py b/release/scripts/startup/bl_ui/properties_physics_field.py
index d1ff1dc9f5e..c8c49ee02b0 100644
--- a/release/scripts/startup/bl_ui/properties_physics_field.py
+++ b/release/scripts/startup/bl_ui/properties_physics_field.py
@@ -102,7 +102,7 @@ class PHYSICS_PT_field_settings(PhysicButtonsPanel, Panel):
col.separator()
col = flow.column()
- col.prop(field, "guide_clump_amount", text="Clumping amount")
+ col.prop(field, "guide_clump_amount", text="Clumping Amount")
col.prop(field, "guide_clump_shape")
col.prop(field, "use_max_distance")
@@ -378,7 +378,7 @@ class PHYSICS_PT_collision_particle(PhysicButtonsPanel, Panel):
class PHYSICS_PT_collision_softbody(PhysicButtonsPanel, Panel):
- bl_label = "Softbody And Cloth"
+ bl_label = "Softbody & Cloth"
bl_parent_id = "PHYSICS_PT_collision"
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH'}
diff --git a/release/scripts/startup/bl_ui/properties_physics_fluid.py b/release/scripts/startup/bl_ui/properties_physics_fluid.py
index 779bdb5cd11..15c5e70d8b2 100644
--- a/release/scripts/startup/bl_ui/properties_physics_fluid.py
+++ b/release/scripts/startup/bl_ui/properties_physics_fluid.py
@@ -196,7 +196,7 @@ class PHYSICS_PT_settings(PhysicButtonsPanel, Panel):
col = flow.column()
if PhysicButtonsPanel.poll_gas_domain(context):
col.prop(domain, "clipping", text="Empty Space")
- col.prop(domain, "delete_in_obstacle", text="Delete In Obstacle")
+ col.prop(domain, "delete_in_obstacle", text="Delete in Obstacle")
if domain.cache_type == 'MODULAR':
col.separator()
diff --git a/release/scripts/startup/bl_ui/space_clip.py b/release/scripts/startup/bl_ui/space_clip.py
index a23dfae55b7..4b24f36eace 100644
--- a/release/scripts/startup/bl_ui/space_clip.py
+++ b/release/scripts/startup/bl_ui/space_clip.py
@@ -560,7 +560,7 @@ class CLIP_PT_tools_solve(CLIP_PT_tracking_panel, Panel):
class CLIP_PT_tools_cleanup(CLIP_PT_tracking_panel, Panel):
bl_space_type = 'CLIP_EDITOR'
bl_region_type = 'TOOLS'
- bl_label = "Clean up"
+ bl_label = "Clean Up"
bl_options = {'DEFAULT_CLOSED'}
bl_category = "Solve"
@@ -1000,9 +1000,9 @@ class CLIP_PT_stabilization(CLIP_PT_reconstruction_panel, Panel):
row.prop(stab, "show_tracks_expanded", text="", emboss=False)
if not stab.show_tracks_expanded:
- row.label(text="Tracks For Stabilization")
+ row.label(text="Tracks for Stabilization")
else:
- row.label(text="Tracks For Location")
+ row.label(text="Tracks for Location")
row = box.row()
row.template_list("UI_UL_list", "stabilization_tracks", stab, "tracks",
stab, "active_track_index", rows=2)
@@ -1018,7 +1018,7 @@ class CLIP_PT_stabilization(CLIP_PT_reconstruction_panel, Panel):
# Usually we don't hide things from interface, but here every pixel of
# vertical space is precious.
if stab.use_stabilize_rotation:
- box.label(text="Tracks For Rotation / Scale")
+ box.label(text="Tracks for Rotation/Scale")
row = box.row()
row.template_list("UI_UL_list", "stabilization_rotation_tracks",
stab, "rotation_tracks",
diff --git a/release/scripts/startup/bl_ui/space_dopesheet.py b/release/scripts/startup/bl_ui/space_dopesheet.py
index a866921f326..5e53eec4ae6 100644
--- a/release/scripts/startup/bl_ui/space_dopesheet.py
+++ b/release/scripts/startup/bl_ui/space_dopesheet.py
@@ -336,7 +336,7 @@ class DOPESHEET_MT_view(Menu):
layout.separator()
- layout.prop(st.dopesheet, "use_multi_word_filter", text="Multi-word Match Search")
+ layout.prop(st.dopesheet, "use_multi_word_filter", text="Multi-Word Match Search")
layout.separator()
diff --git a/release/scripts/startup/bl_ui/space_sequencer.py b/release/scripts/startup/bl_ui/space_sequencer.py
index 72395e1de5e..7d881948466 100644
--- a/release/scripts/startup/bl_ui/space_sequencer.py
+++ b/release/scripts/startup/bl_ui/space_sequencer.py
@@ -1071,7 +1071,7 @@ class SEQUENCER_PT_effect(SequencerButtonsPanel, Panel):
flow.prop(strip, "use_only_boost")
elif strip_type == 'SPEED':
- layout.prop(strip, "use_default_fade", text="Stretch to input strip length")
+ layout.prop(strip, "use_default_fade", text="Stretch to Input Strip Length")
if not strip.use_default_fade:
layout.prop(strip, "use_as_speed")
if strip.use_as_speed:
@@ -1113,7 +1113,7 @@ class SEQUENCER_PT_effect(SequencerButtonsPanel, Panel):
# The multicam strip needs at least 2 strips to be useful
if strip_channel > 2:
BT_ROW = 4
- col.label(text=" Cut to")
+ col.label(text="Cut To")
row = col.row()
for i in range(1, strip_channel):
@@ -1153,7 +1153,7 @@ class SEQUENCER_PT_effect(SequencerButtonsPanel, Panel):
col.prop(strip, "use_frame_interpolate")
elif strip_type in {'CROSS', 'GAMMA_CROSS', 'WIPE', 'ALPHA_OVER', 'ALPHA_UNDER', 'OVER_DROP'}:
- col.prop(strip, "use_default_fade", text="Default fade")
+ col.prop(strip, "use_default_fade", text="Default Fade")
if not strip.use_default_fade:
col.prop(strip, "effect_fader", text="Effect Fader")
elif strip_type == 'GAUSSIAN_BLUR':
diff --git a/release/scripts/startup/bl_ui/space_text.py b/release/scripts/startup/bl_ui/space_text.py
index 8a45069470b..f1326823fe8 100644
--- a/release/scripts/startup/bl_ui/space_text.py
+++ b/release/scripts/startup/bl_ui/space_text.py
@@ -177,7 +177,7 @@ class TEXT_PT_find(Panel):
row = col.row(align=True)
row.operator("text.replace")
- row.operator("text.replace", text="Replace all").all = True
+ row.operator("text.replace", text="Replace All").all = True
layout.separator()
diff --git a/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py b/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py
index b3f4757d10a..a923bb305d9 100644
--- a/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py
+++ b/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py
@@ -1259,6 +1259,7 @@ class _defs_sculpt:
def draw_settings(_context, layout, tool):
props = tool.operator_properties("paint.mask_line_gesture")
layout.prop(props, "use_front_faces_only", expand=False)
+ layout.prop(props, "use_limit_to_segment", expand=False)
return dict(
idname="builtin.line_mask",
@@ -1331,12 +1332,17 @@ class _defs_sculpt:
@ToolDef.from_fn
def project_line():
+ def draw_settings(_context, layout, tool):
+ props = tool.operator_properties("sculpt.project_line_gesture")
+ layout.prop(props, "use_limit_to_segment", expand=False)
+
return dict(
idname="builtin.line_project",
label="Line Project",
icon="ops.sculpt.line_project",
widget=None,
keymap=(),
+ draw_settings=draw_settings,
)
@ToolDef.from_fn
diff --git a/release/scripts/startup/bl_ui/space_userpref.py b/release/scripts/startup/bl_ui/space_userpref.py
index b4b8a631b93..10b52e1fe3a 100644
--- a/release/scripts/startup/bl_ui/space_userpref.py
+++ b/release/scripts/startup/bl_ui/space_userpref.py
@@ -279,7 +279,7 @@ class USERPREF_PT_interface_temporary_windows(InterfacePanel, CenterAlignMixIn,
view = prefs.view
col = layout.column()
- col.prop(view, "render_display_type", text="Render in")
+ col.prop(view, "render_display_type", text="Render In")
col.prop(view, "filebrowser_display_type", text="File Browser")
@@ -373,8 +373,8 @@ class USERPREF_PT_edit_objects_new(EditingPanel, CenterAlignMixIn, Panel):
flow = layout.grid_flow(row_major=False, columns=0, even_columns=True, even_rows=False, align=False)
- flow.prop(edit, "material_link", text="Link Materials to")
- flow.prop(edit, "object_align", text="Align to")
+ flow.prop(edit, "material_link", text="Link Materials To")
+ flow.prop(edit, "object_align", text="Align To")
flow.prop(edit, "use_enter_edit_mode", text="Enter Edit Mode")
flow.prop(edit, "collection_instance_empty_size", text="Instance Empty Size")
@@ -479,7 +479,7 @@ class USERPREF_PT_edit_misc(EditingPanel, CenterAlignMixIn, Panel):
col = layout.column()
col.prop(edit, "sculpt_paint_overlay_color", text="Sculpt Overlay Color")
- col.prop(edit, "node_margin", text="Node Auto-offset Margin")
+ col.prop(edit, "node_margin", text="Node Auto-Offset Margin")
# -----------------------------------------------------------------------------
@@ -1348,7 +1348,7 @@ class USERPREF_PT_saveload_blend(SaveLoadPanel, CenterAlignMixIn, Panel):
col.prop(view, "use_save_prompt")
col.prop(paths, "use_save_preview_images")
- col = layout.column(heading="Default to")
+ col = layout.column(heading="Default To")
col.prop(paths, "use_relative_paths")
col.prop(paths, "use_file_compression")
col.prop(paths, "use_load_ui")
@@ -1377,7 +1377,7 @@ class USERPREF_PT_saveload_blend_autosave(SaveLoadPanel, CenterAlignMixIn, Panel
col = layout.column()
col.active = paths.use_auto_save_temporary_files
- col.prop(paths, "auto_save_time", text="Timer (mins)")
+ col.prop(paths, "auto_save_time", text="Timer (Minutes)")
class USERPREF_PT_saveload_file_browser(SaveLoadPanel, CenterAlignMixIn, Panel):
diff --git a/release/scripts/startup/bl_ui/space_view3d.py b/release/scripts/startup/bl_ui/space_view3d.py
index af6e752227e..cb2ead39e2a 100644
--- a/release/scripts/startup/bl_ui/space_view3d.py
+++ b/release/scripts/startup/bl_ui/space_view3d.py
@@ -2257,7 +2257,7 @@ class VIEW3D_MT_object(Menu):
ob = context.active_object
if ob and ob.type == 'GPENCIL' and context.gpencil_data:
- layout.operator_menu_enum("gpencil.convert", "type", text="Convert to")
+ layout.operator_menu_enum("gpencil.convert", "type", text="Convert To")
else:
layout.operator_menu_enum("object.convert", "target")
@@ -3035,14 +3035,14 @@ class VIEW3D_MT_mask(Menu):
layout.separator()
- props = layout.operator("sculpt.mask_expand", text="Expand Mask By Topology")
+ props = layout.operator("sculpt.mask_expand", text="Expand Mask by Topology")
props.use_normals = False
props.keep_previous_mask = False
props.invert = True
props.smooth_iterations = 2
props.create_face_set = False
- props = layout.operator("sculpt.mask_expand", text="Expand Mask By Curvature")
+ props = layout.operator("sculpt.mask_expand", text="Expand Mask by Curvature")
props.use_normals = True
props.keep_previous_mask = True
props.invert = False
@@ -3428,7 +3428,7 @@ class VIEW3D_MT_pose_constraints(Menu):
def draw(self, _context):
layout = self.layout
- layout.operator("pose.constraint_add_with_targets", text="Add (With Targets)...")
+ layout.operator("pose.constraint_add_with_targets", text="Add (with Targets)...")
layout.operator("pose.constraints_copy")
layout.operator("pose.constraints_clear")
@@ -3440,9 +3440,9 @@ class VIEW3D_MT_pose_names(Menu):
layout = self.layout
layout.operator_context = 'EXEC_REGION_WIN'
- layout.operator("pose.autoside_names", text="AutoName Left/Right").axis = 'XAXIS'
- layout.operator("pose.autoside_names", text="AutoName Front/Back").axis = 'YAXIS'
- layout.operator("pose.autoside_names", text="AutoName Top/Bottom").axis = 'ZAXIS'
+ layout.operator("pose.autoside_names", text="Auto-Name Left/Right").axis = 'XAXIS'
+ layout.operator("pose.autoside_names", text="Auto-Name Front/Back").axis = 'YAXIS'
+ layout.operator("pose.autoside_names", text="Auto-Name Top/Bottom").axis = 'ZAXIS'
layout.operator("pose.flip_names")
@@ -4769,9 +4769,9 @@ class VIEW3D_MT_edit_armature_names(Menu):
layout = self.layout
layout.operator_context = 'EXEC_REGION_WIN'
- layout.operator("armature.autoside_names", text="AutoName Left/Right").type = 'XAXIS'
- layout.operator("armature.autoside_names", text="AutoName Front/Back").type = 'YAXIS'
- layout.operator("armature.autoside_names", text="AutoName Top/Bottom").type = 'ZAXIS'
+ layout.operator("armature.autoside_names", text="Auto-Name Left/Right").type = 'XAXIS'
+ layout.operator("armature.autoside_names", text="Auto-Name Front/Back").type = 'YAXIS'
+ layout.operator("armature.autoside_names", text="Auto-Name Top/Bottom").type = 'ZAXIS'
layout.operator("armature.flip_names", text="Flip Names")
@@ -5074,7 +5074,7 @@ class VIEW3D_MT_edit_gpencil_transform(Menu):
class VIEW3D_MT_edit_gpencil_showhide(Menu):
- bl_label = "Show/hide"
+ bl_label = "Show/Hide"
def draw(self, _context):
layout = self.layout
@@ -5862,7 +5862,7 @@ class VIEW3D_PT_shading_options(Panel):
row = col.row()
row.active = not xray_active
- row.prop(shading, "use_dof", text="Depth Of Field")
+ row.prop(shading, "use_dof", text="Depth of Field")
if shading.type in {'WIREFRAME', 'SOLID'}:
row = layout.split()
@@ -6553,7 +6553,7 @@ class VIEW3D_PT_snapping(Panel):
layout = self.layout
col = layout.column()
- col.label(text="Snap to")
+ col.label(text="Snap To")
col.prop(tool_settings, "snap_elements", expand=True)
col.separator()
@@ -6561,7 +6561,7 @@ class VIEW3D_PT_snapping(Panel):
col.prop(tool_settings, "use_snap_grid_absolute")
if snap_elements != {'INCREMENT'}:
- col.label(text="Snap with")
+ col.label(text="Snap With")
row = col.row(align=True)
row.prop(tool_settings, "snap_target", expand=True)
diff --git a/release/scripts/startup/bl_ui/space_view3d_toolbar.py b/release/scripts/startup/bl_ui/space_view3d_toolbar.py
index e9118a8be91..701c98ce489 100644
--- a/release/scripts/startup/bl_ui/space_view3d_toolbar.py
+++ b/release/scripts/startup/bl_ui/space_view3d_toolbar.py
@@ -124,11 +124,7 @@ class View3DPanel:
# Used by vertex & weight paint
def draw_vpaint_symmetry(layout, vpaint, mesh):
-
col = layout.column()
- col.use_property_split = True
- col.use_property_decorate = False
-
row = col.row(heading="Mirror", align=True)
row.prop(mesh, "use_mirror_x", text="X", toggle=True)
row.prop(mesh, "use_mirror_y", text="Y", toggle=True)
@@ -681,7 +677,7 @@ class VIEW3D_PT_tools_brush_falloff(Panel, View3DPaintPanel, FalloffPanel):
class VIEW3D_PT_tools_brush_falloff_frontface(View3DPaintPanel, Panel):
bl_context = ".imagepaint" # dot on purpose (access from topbar)
- bl_label = "Front-face Falloff"
+ bl_label = "Front-Face Falloff"
bl_parent_id = "VIEW3D_PT_tools_brush_falloff"
bl_options = {'DEFAULT_CLOSED'}
@@ -955,14 +951,20 @@ class VIEW3D_PT_tools_weightpaint_symmetry(Panel, View3DPaintPanel):
def draw(self, context):
layout = self.layout
+ layout.use_property_split = True
+ layout.use_property_decorate = False
+
tool_settings = context.tool_settings
wpaint = tool_settings.weight_paint
- draw_vpaint_symmetry(layout, wpaint, context.object.data)
+ mesh = context.object.data
- col = layout.column()
- row = col.row(align=True)
- row.prop(context.object.data, 'use_mirror_vertex_group_x')
+ draw_vpaint_symmetry(layout, wpaint, mesh)
+ col = layout.column(align=True)
+ col.prop(mesh, 'use_mirror_vertex_group_x', text="Vertex Group X")
+ row = col.row()
+ row.active = mesh.use_mirror_vertex_group_x
+ row.prop(mesh, "use_mirror_topology")
class VIEW3D_PT_tools_weightpaint_symmetry_for_topbar(Panel):
bl_space_type = 'TOPBAR'
@@ -995,14 +997,6 @@ class VIEW3D_PT_tools_weightpaint_options(Panel, View3DPaintPanel):
col.prop(wpaint, "use_group_restrict")
- obj = context.weight_paint_object
- if obj.type == 'MESH':
- mesh = obj.data
- col.prop(mesh, "use_mirror_x")
- row = col.row()
- row.active = mesh.use_mirror_x
- row.prop(mesh, "use_mirror_topology")
-
# ********** default tools for vertex-paint ****************
@@ -1037,8 +1031,12 @@ class VIEW3D_PT_tools_vertexpaint_symmetry(Panel, View3DPaintPanel):
def draw(self, context):
layout = self.layout
+ layout.use_property_split = True
+ layout.use_property_decorate = False
+
tool_settings = context.tool_settings
vpaint = tool_settings.vertex_paint
+
draw_vpaint_symmetry(layout, vpaint, context.object.data)
diff --git a/source/blender/blenfont/BLF_api.h b/source/blender/blenfont/BLF_api.h
index 03877957f42..1f39257a4c2 100644
--- a/source/blender/blenfont/BLF_api.h
+++ b/source/blender/blenfont/BLF_api.h
@@ -74,7 +74,7 @@ void BLF_color4f(int fontid, float r, float g, float b, float a);
void BLF_color4fv(int fontid, const float rgba[4]);
void BLF_color3f(int fontid, float r, float g, float b);
void BLF_color3fv_alpha(int fontid, const float rgb[3], float alpha);
-/* also available: UI_FontThemeColor(fontid, colorid) */
+/* Also available: `UI_FontThemeColor(fontid, colorid)`. */
/* Set a 4x4 matrix to be multiplied before draw the text.
* Remember that you need call BLF_enable(BLF_MATRIX)
@@ -89,8 +89,8 @@ void BLF_color3fv_alpha(int fontid, const float rgb[3], float alpha);
*/
void BLF_matrix(int fontid, const float m[16]);
-/* Batch drawcalls together as long as
- * the modelview matrix and the font remain unchanged. */
+/* Batch draw-calls together as long as
+ * the model-view matrix and the font remain unchanged. */
void BLF_batch_draw_begin(void);
void BLF_batch_draw_flush(void);
void BLF_batch_draw_end(void);
diff --git a/source/blender/blenfont/intern/blf_font.c b/source/blender/blenfont/intern/blf_font.c
index 1501ee07b66..189cbaf152d 100644
--- a/source/blender/blenfont/intern/blf_font.c
+++ b/source/blender/blenfont/intern/blf_font.c
@@ -75,9 +75,9 @@ static SpinLock blf_glyph_cache_mutex;
* \{ */
/**
- * Drawcalls are precious! make them count!
- * Since most of the Text elems are not covered by other UI elements, we can
- * group some strings together and render them in one drawcall. This behavior
+ * Draw-calls are precious! make them count!
+ * Since most of the Text elements are not covered by other UI elements, we can
+ * group some strings together and render them in one draw-call. This behavior
* is on demand only, between #BLF_batch_draw_begin() and #BLF_batch_draw_end().
*/
static void blf_batch_draw_init(void)
diff --git a/source/blender/blenkernel/BKE_DerivedMesh.h b/source/blender/blenkernel/BKE_DerivedMesh.h
index b517ecfa599..092eec578c9 100644
--- a/source/blender/blenkernel/BKE_DerivedMesh.h
+++ b/source/blender/blenkernel/BKE_DerivedMesh.h
@@ -364,6 +364,7 @@ struct Mesh *editbmesh_get_eval_cage_and_final(struct Depsgraph *depsgraph,
float (*editbmesh_vert_coords_alloc(struct BMEditMesh *em, int *r_vert_len))[3];
bool editbmesh_modifier_is_enabled(struct Scene *scene,
+ const struct Object *ob,
struct ModifierData *md,
bool has_prev_mesh);
void makeDerivedMesh(struct Depsgraph *depsgraph,
diff --git a/source/blender/blenkernel/BKE_geometry.hh b/source/blender/blenkernel/BKE_geometry.hh
index e2532d639c4..a90a1f433f2 100644
--- a/source/blender/blenkernel/BKE_geometry.hh
+++ b/source/blender/blenkernel/BKE_geometry.hh
@@ -62,6 +62,7 @@ class Geometry {
void user_remove();
bool is_mutable() const;
+ bool mesh_available() const;
void mesh_set_and_keep_ownership(Mesh *mesh);
void mesh_set_and_transfer_ownership(Mesh *mesh);
void mesh_reset();
diff --git a/source/blender/blenkernel/BKE_modifier.h b/source/blender/blenkernel/BKE_modifier.h
index b2015c4e6d7..10528a651e5 100644
--- a/source/blender/blenkernel/BKE_modifier.h
+++ b/source/blender/blenkernel/BKE_modifier.h
@@ -427,8 +427,10 @@ bool BKE_modifier_is_non_geometrical(ModifierData *md);
bool BKE_modifier_is_enabled(const struct Scene *scene,
struct ModifierData *md,
int required_mode);
-void BKE_modifier_set_error(struct ModifierData *md, const char *format, ...)
- ATTR_PRINTF_FORMAT(2, 3);
+void BKE_modifier_set_error(const struct Object *ob,
+ struct ModifierData *md,
+ const char *format,
+ ...) ATTR_PRINTF_FORMAT(3, 4);
bool BKE_modifier_is_preview(struct ModifierData *md);
void BKE_modifiers_foreach_ID_link(struct Object *ob, IDWalkFunc walk, void *userData);
diff --git a/source/blender/blenkernel/BKE_pointcache.h b/source/blender/blenkernel/BKE_pointcache.h
index f8e04b75b3d..a45b134f825 100644
--- a/source/blender/blenkernel/BKE_pointcache.h
+++ b/source/blender/blenkernel/BKE_pointcache.h
@@ -167,7 +167,7 @@ typedef struct PTCacheID {
* (the cfra parameter is just for using same function pointer with totwrite). */
int (*totpoint)(void *calldata, int cfra);
/* report error if number of points does not match */
- void (*error)(void *calldata, const char *message);
+ void (*error)(const struct ID *owner_id, void *calldata, const char *message);
/* number of points written for current cache frame */
int (*totwrite)(void *calldata, int cfra);
diff --git a/source/blender/blenkernel/CMakeLists.txt b/source/blender/blenkernel/CMakeLists.txt
index 070e54653fd..e8b843b725b 100644
--- a/source/blender/blenkernel/CMakeLists.txt
+++ b/source/blender/blenkernel/CMakeLists.txt
@@ -720,6 +720,7 @@ if(WITH_GTESTS)
set(TEST_SRC
intern/armature_test.cc
intern/fcurve_test.cc
+ intern/lattice_deform_test.cc
)
set(TEST_INC
../editors/include
diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c
index d551eaf04e4..7b2e1be7b5d 100644
--- a/source/blender/blenkernel/intern/DerivedMesh.c
+++ b/source/blender/blenkernel/intern/DerivedMesh.c
@@ -1021,7 +1021,7 @@ static void mesh_calc_modifiers(struct Depsgraph *depsgraph,
if ((mti->flags & eModifierTypeFlag_RequiresOriginalData) &&
have_non_onlydeform_modifiers_appled) {
- BKE_modifier_set_error(md, "Modifier requires original data, bad stack position");
+ BKE_modifier_set_error(ob, md, "Modifier requires original data, bad stack position");
continue;
}
@@ -1047,10 +1047,10 @@ static void mesh_calc_modifiers(struct Depsgraph *depsgraph,
if (unsupported) {
if (sculpt_dyntopo) {
- BKE_modifier_set_error(md, "Not supported in dyntopo");
+ BKE_modifier_set_error(ob, md, "Not supported in dyntopo");
}
else {
- BKE_modifier_set_error(md, "Not supported in sculpt mode");
+ BKE_modifier_set_error(ob, md, "Not supported in sculpt mode");
}
continue;
}
@@ -1378,7 +1378,10 @@ float (*editbmesh_vert_coords_alloc(BMEditMesh *em, int *r_vert_len))[3]
return cos;
}
-bool editbmesh_modifier_is_enabled(Scene *scene, ModifierData *md, bool has_prev_mesh)
+bool editbmesh_modifier_is_enabled(Scene *scene,
+ const Object *ob,
+ ModifierData *md,
+ bool has_prev_mesh)
{
const ModifierTypeInfo *mti = BKE_modifier_get_info(md->type);
const int required_mode = eModifierMode_Realtime | eModifierMode_Editmode;
@@ -1388,7 +1391,7 @@ bool editbmesh_modifier_is_enabled(Scene *scene, ModifierData *md, bool has_prev
}
if ((mti->flags & eModifierTypeFlag_RequiresOriginalData) && has_prev_mesh) {
- BKE_modifier_set_error(md, "Modifier requires original data, bad stack position");
+ BKE_modifier_set_error(ob, md, "Modifier requires original data, bad stack position");
return false;
}
@@ -1522,7 +1525,7 @@ static void editbmesh_calc_modifiers(struct Depsgraph *depsgraph,
for (int i = 0; md; i++, md = md->next, md_datamask = md_datamask->next) {
const ModifierTypeInfo *mti = BKE_modifier_get_info(md->type);
- if (!editbmesh_modifier_is_enabled(scene, md, mesh_final != NULL)) {
+ if (!editbmesh_modifier_is_enabled(scene, ob, md, mesh_final != NULL)) {
continue;
}
diff --git a/source/blender/blenkernel/intern/armature.c b/source/blender/blenkernel/intern/armature.c
index 4aa328fcb22..bad2ed53436 100644
--- a/source/blender/blenkernel/intern/armature.c
+++ b/source/blender/blenkernel/intern/armature.c
@@ -2581,7 +2581,8 @@ void BKE_pose_rebuild(Main *bmain, Object *ob, bArmature *arm, const bool do_id_
void BKE_pose_ensure(Main *bmain, Object *ob, bArmature *arm, const bool do_id_user)
{
BLI_assert(!ELEM(NULL, arm, ob));
- if ((ob->pose == NULL) || (ob->pose->flag & POSE_RECALC)) {
+ if (ob->type == OB_ARMATURE && ((ob->pose == NULL) || (ob->pose->flag & POSE_RECALC))) {
+ BLI_assert(GS(arm->id.name) == ID_AR);
BKE_pose_rebuild(bmain, ob, arm, do_id_user);
}
}
diff --git a/source/blender/blenkernel/intern/cloth.c b/source/blender/blenkernel/intern/cloth.c
index 403722b80cf..e9df562a15f 100644
--- a/source/blender/blenkernel/intern/cloth.c
+++ b/source/blender/blenkernel/intern/cloth.c
@@ -55,7 +55,7 @@
/* Prototypes for internal functions.
*/
static void cloth_to_object(Object *ob, ClothModifierData *clmd, float (*vertexCos)[3]);
-static void cloth_from_mesh(ClothModifierData *clmd, Mesh *mesh);
+static void cloth_from_mesh(ClothModifierData *clmd, const Object *ob, Mesh *mesh);
static bool cloth_from_object(
Object *ob, ClothModifierData *clmd, Mesh *mesh, float framenr, int first);
static void cloth_update_springs(ClothModifierData *clmd);
@@ -234,13 +234,13 @@ static bool do_init_cloth(Object *ob, ClothModifierData *clmd, Mesh *result, int
if (clmd->clothObject == NULL) {
if (!cloth_from_object(ob, clmd, result, framenr, 1)) {
BKE_ptcache_invalidate(cache);
- BKE_modifier_set_error(&(clmd->modifier), "Can't initialize cloth");
+ BKE_modifier_set_error(ob, &(clmd->modifier), "Can't initialize cloth");
return false;
}
if (clmd->clothObject == NULL) {
BKE_ptcache_invalidate(cache);
- BKE_modifier_set_error(&(clmd->modifier), "Null cloth object");
+ BKE_modifier_set_error(ob, &(clmd->modifier), "Null cloth object");
return false;
}
@@ -742,7 +742,7 @@ static bool cloth_from_object(
clmd->clothObject->edgeset = NULL;
}
else {
- BKE_modifier_set_error(&(clmd->modifier), "Out of memory on allocating clmd->clothObject");
+ BKE_modifier_set_error(ob, &(clmd->modifier), "Out of memory on allocating clmd->clothObject");
return false;
}
@@ -751,7 +751,7 @@ static bool cloth_from_object(
return false;
}
- cloth_from_mesh(clmd, mesh);
+ cloth_from_mesh(clmd, ob, mesh);
/* create springs */
clmd->clothObject->springs = NULL;
@@ -814,7 +814,7 @@ static bool cloth_from_object(
if (!cloth_build_springs(clmd, mesh)) {
cloth_free_modifier(clmd);
- BKE_modifier_set_error(&(clmd->modifier), "Cannot build springs");
+ BKE_modifier_set_error(ob, &(clmd->modifier), "Cannot build springs");
return false;
}
@@ -831,7 +831,7 @@ static bool cloth_from_object(
return true;
}
-static void cloth_from_mesh(ClothModifierData *clmd, Mesh *mesh)
+static void cloth_from_mesh(ClothModifierData *clmd, const Object *ob, Mesh *mesh)
{
const MLoop *mloop = mesh->mloop;
const MLoopTri *looptri = BKE_mesh_runtime_looptri_ensure(mesh);
@@ -844,8 +844,8 @@ static void cloth_from_mesh(ClothModifierData *clmd, Mesh *mesh)
"clothVertex");
if (clmd->clothObject->verts == NULL) {
cloth_free_modifier(clmd);
- BKE_modifier_set_error(&(clmd->modifier),
- "Out of memory on allocating clmd->clothObject->verts");
+ BKE_modifier_set_error(
+ ob, &(clmd->modifier), "Out of memory on allocating clmd->clothObject->verts");
printf("cloth_free_modifier clmd->clothObject->verts\n");
return;
}
@@ -861,8 +861,8 @@ static void cloth_from_mesh(ClothModifierData *clmd, Mesh *mesh)
clmd->clothObject->tri = MEM_mallocN(sizeof(MVertTri) * looptri_num, "clothLoopTris");
if (clmd->clothObject->tri == NULL) {
cloth_free_modifier(clmd);
- BKE_modifier_set_error(&(clmd->modifier),
- "Out of memory on allocating clmd->clothObject->looptri");
+ BKE_modifier_set_error(
+ ob, &(clmd->modifier), "Out of memory on allocating clmd->clothObject->looptri");
printf("cloth_free_modifier clmd->clothObject->looptri\n");
return;
}
diff --git a/source/blender/blenkernel/intern/crazyspace.c b/source/blender/blenkernel/intern/crazyspace.c
index 01c05c62b70..4e1ec9ba35e 100644
--- a/source/blender/blenkernel/intern/crazyspace.c
+++ b/source/blender/blenkernel/intern/crazyspace.c
@@ -273,7 +273,7 @@ int BKE_crazyspace_get_first_deform_matrices_editbmesh(struct Depsgraph *depsgra
for (i = 0; md && i <= cageIndex; i++, md = md->next) {
const ModifierTypeInfo *mti = BKE_modifier_get_info(md->type);
- if (!editbmesh_modifier_is_enabled(scene, md, me != NULL)) {
+ if (!editbmesh_modifier_is_enabled(scene, ob, md, me != NULL)) {
continue;
}
@@ -302,7 +302,7 @@ int BKE_crazyspace_get_first_deform_matrices_editbmesh(struct Depsgraph *depsgra
}
for (; md && i <= cageIndex; md = md->next, i++) {
- if (editbmesh_modifier_is_enabled(scene, md, me != NULL) &&
+ if (editbmesh_modifier_is_enabled(scene, ob, md, me != NULL) &&
BKE_modifier_is_correctable_deformed(md)) {
numleft++;
}
diff --git a/source/blender/blenkernel/intern/curve.c b/source/blender/blenkernel/intern/curve.c
index 82548112096..fa45a4ba836 100644
--- a/source/blender/blenkernel/intern/curve.c
+++ b/source/blender/blenkernel/intern/curve.c
@@ -438,7 +438,6 @@ ListBase *BKE_curve_editNurbs_get(Curve *cu)
short BKE_curve_type_get(const Curve *cu)
{
- Nurb *nu;
int type = cu->type;
if (cu->vfont) {
@@ -448,7 +447,7 @@ short BKE_curve_type_get(const Curve *cu)
if (!cu->type) {
type = OB_CURVE;
- for (nu = cu->nurb.first; nu; nu = nu->next) {
+ LISTBASE_FOREACH (Nurb *, nu, &cu->nurb) {
if (nu->pntsv > 1) {
type = OB_SURF;
}
@@ -5276,8 +5275,7 @@ void BKE_curve_transform_ex(Curve *cu,
}
if (do_keys && cu->key) {
- KeyBlock *kb;
- for (kb = cu->key->block.first; kb; kb = kb->next) {
+ LISTBASE_FOREACH (KeyBlock *, kb, &cu->key->block) {
float *fp = kb->data;
int n = kb->totelem;
@@ -5437,9 +5435,8 @@ bool BKE_curve_material_index_validate(Curve *cu)
}
}
else {
- Nurb *nu;
const int max_idx = max_ii(0, cu->totcol - 1);
- for (nu = cu->nurb.first; nu; nu = nu->next) {
+ LISTBASE_FOREACH (Nurb *, nu, &cu->nurb) {
if (nu->mat_nr > max_idx) {
nu->mat_nr = 0;
is_valid = false;
@@ -5505,12 +5502,12 @@ void BKE_curve_material_remap(Curve *cu, const unsigned int *remap, unsigned int
void BKE_curve_smooth_flag_set(Curve *cu, const bool use_smooth)
{
if (use_smooth) {
- for (Nurb *nu = cu->nurb.first; nu; nu = nu->next) {
+ LISTBASE_FOREACH (Nurb *, nu, &cu->nurb) {
nu->flag |= CU_SMOOTH;
}
}
else {
- for (Nurb *nu = cu->nurb.first; nu; nu = nu->next) {
+ LISTBASE_FOREACH (Nurb *, nu, &cu->nurb) {
nu->flag &= ~CU_SMOOTH;
}
}
diff --git a/source/blender/blenkernel/intern/fcurve.c b/source/blender/blenkernel/intern/fcurve.c
index dcf4c78dfd8..c4055c0f611 100644
--- a/source/blender/blenkernel/intern/fcurve.c
+++ b/source/blender/blenkernel/intern/fcurve.c
@@ -1646,7 +1646,7 @@ static float fcurve_eval_keyframes_extrapolate(
return endpoint_bezt->vec[1][1] - (fac * dx);
}
- /* Use the gradient of the second handle (later) of neighbour to calculate the gradient and thus
+ /* Use the gradient of the second handle (later) of neighbor to calculate the gradient and thus
* the value of the curve at evaluation time. */
int handle = direction_to_neighbor > 0 ? 0 : 2;
float dx = endpoint_bezt->vec[1][0] - evaltime;
@@ -1922,7 +1922,7 @@ static float fcurve_eval_keyframes_interpolate(FCurve *fcu, BezTriple *bezts, fl
return 0.0f;
}
-/* Calculate F-Curve value for 'evaltime' using BezTriple keyframes. */
+/* Calculate F-Curve value for 'evaltime' using #BezTriple keyframes. */
static float fcurve_eval_keyframes(FCurve *fcu, BezTriple *bezts, float evaltime)
{
if (evaltime <= bezts->vec[1][0]) {
@@ -1937,7 +1937,7 @@ static float fcurve_eval_keyframes(FCurve *fcu, BezTriple *bezts, float evaltime
return fcurve_eval_keyframes_interpolate(fcu, bezts, evaltime);
}
-/* Calculate F-Curve value for 'evaltime' using FPoint samples. */
+/* Calculate F-Curve value for 'evaltime' using #FPoint samples. */
static float fcurve_eval_samples(FCurve *fcu, FPoint *fpts, float evaltime)
{
FPoint *prevfpt, *lastfpt, *fpt;
diff --git a/source/blender/blenkernel/intern/geometry.cc b/source/blender/blenkernel/intern/geometry.cc
index 014197ed423..58ec71108da 100644
--- a/source/blender/blenkernel/intern/geometry.cc
+++ b/source/blender/blenkernel/intern/geometry.cc
@@ -58,6 +58,14 @@ bool Geometry::is_mutable() const
}
/**
+ * Returns true when this geometry has a mesh component.
+ */
+bool Geometry::mesh_available() const
+{
+ return mesh_ != nullptr;
+}
+
+/**
* Replace the mesh in the geometry. The caller remains the owner of the given mesh and is
* responsible for freeing it eventually.
*/
diff --git a/source/blender/blenkernel/intern/lattice_deform.c b/source/blender/blenkernel/intern/lattice_deform.c
index 919093f3630..43965813b84 100644
--- a/source/blender/blenkernel/intern/lattice_deform.c
+++ b/source/blender/blenkernel/intern/lattice_deform.c
@@ -49,14 +49,24 @@
#include "BKE_deform.h"
+#ifdef __SSE2__
+# include <emmintrin.h>
+#endif
+
/* -------------------------------------------------------------------- */
/** \name Lattice Deform API
* \{ */
typedef struct LatticeDeformData {
- const Object *object;
- float *latticedata;
+ /* Convert from object space to deform space */
float latmat[4][4];
+ /* Cached reference to the lattice to use for evaluation. When in edit mode this attribute
+ * is set to the edit mode lattice. */
+ const Lattice *lt;
+ /* Preprocessed lattice points (converted to deform space). */
+ float *latticedata;
+ /* Prefetched DeformWeights of the lattice. */
+ float *lattice_weights;
} LatticeDeformData;
LatticeDeformData *BKE_lattice_deform_data_create(const Object *oblatt, const Object *ob)
@@ -72,6 +82,7 @@ LatticeDeformData *BKE_lattice_deform_data_create(const Object *oblatt, const Ob
float fu, fv, fw;
int u, v, w;
float *latticedata;
+ float *lattice_weights = NULL;
float latmat[4][4];
LatticeDeformData *lattice_deform_data;
@@ -80,8 +91,10 @@ LatticeDeformData *BKE_lattice_deform_data_create(const Object *oblatt, const Ob
}
bp = lt->def;
- fp = latticedata = MEM_mallocN(sizeof(float[3]) * lt->pntsu * lt->pntsv * lt->pntsw,
- "latticedata");
+ const int32_t num_points = lt->pntsu * lt->pntsv * lt->pntsw;
+ /* We allocate one additional float for SSE2 optimizations. Without this
+ * the SSE2 instructions for the last item would read in unallocated memory. */
+ fp = latticedata = MEM_mallocN(sizeof(float[3]) * num_points + sizeof(float), "latticedata");
/* for example with a particle system: (ob == NULL) */
if (ob == NULL) {
@@ -100,6 +113,20 @@ LatticeDeformData *BKE_lattice_deform_data_create(const Object *oblatt, const Ob
invert_m4_m4(imat, latmat);
}
+ /* Prefetch latice deform group weights. */
+ int defgrp_index = -1;
+ const MDeformVert *dvert = BKE_lattice_deform_verts_get(oblatt);
+ if (lt->vgroup[0] && dvert) {
+ defgrp_index = BKE_object_defgroup_name_index(ob, lt->vgroup);
+
+ if (defgrp_index != -1) {
+ lattice_weights = MEM_malloc_arrayN(sizeof(float), num_points, "lattice_weights");
+ for (int index = 0; index < num_points; index++) {
+ lattice_weights[index] = BKE_defvert_find_weight(dvert + index, defgrp_index);
+ }
+ }
+ }
+
for (w = 0, fw = lt->fw; w < lt->pntsw; w++, fw += lt->dw) {
for (v = 0, fv = lt->fv; v < lt->pntsv; v++, fv += lt->dv) {
for (u = 0, fu = lt->fu; u < lt->pntsu; u++, bp++, co += 3, fp += 3, fu += lt->du) {
@@ -121,7 +148,8 @@ LatticeDeformData *BKE_lattice_deform_data_create(const Object *oblatt, const Ob
lattice_deform_data = MEM_mallocN(sizeof(LatticeDeformData), "Lattice Deform Data");
lattice_deform_data->latticedata = latticedata;
- lattice_deform_data->object = oblatt;
+ lattice_deform_data->lattice_weights = lattice_weights;
+ lattice_deform_data->lt = lt;
copy_m4_m4(lattice_deform_data->latmat, latmat);
return lattice_deform_data;
@@ -131,30 +159,21 @@ void BKE_lattice_deform_data_eval_co(LatticeDeformData *lattice_deform_data,
float co[3],
float weight)
{
- const Object *ob = lattice_deform_data->object;
- Lattice *lt = ob->data;
+ float *latticedata = lattice_deform_data->latticedata;
+ float *lattice_weights = lattice_deform_data->lattice_weights;
+ BLI_assert(latticedata);
+ const Lattice *lt = lattice_deform_data->lt;
float u, v, w, tu[4], tv[4], tw[4];
float vec[3];
int idx_w, idx_v, idx_u;
int ui, vi, wi, uu, vv, ww;
/* vgroup influence */
- int defgrp_index = -1;
float co_prev[3], weight_blend = 0.0f;
- const MDeformVert *dvert = BKE_lattice_deform_verts_get(ob);
- float *__restrict latticedata = lattice_deform_data->latticedata;
-
- if (lt->editlatt) {
- lt = lt->editlatt->latt;
- }
- if (latticedata == NULL) {
- return;
- }
-
- if (lt->vgroup[0] && dvert) {
- defgrp_index = BKE_object_defgroup_name_index(ob, lt->vgroup);
- copy_v3_v3(co_prev, co);
- }
+ copy_v3_v3(co_prev, co);
+#ifdef __SSE2__
+ __m128 co_vec = _mm_loadu_ps(co_prev);
+#endif
/* co is in local coords, treat with latmat */
mul_v3_m4v3(vec, lattice_deform_data->latmat, co);
@@ -197,67 +216,47 @@ void BKE_lattice_deform_data_eval_co(LatticeDeformData *lattice_deform_data,
wi = 0;
}
- for (ww = wi - 1; ww <= wi + 2; ww++) {
- w = tw[ww - wi + 1];
+ const int w_stride = lt->pntsu * lt->pntsv;
+ const int idx_w_max = (lt->pntsw - 1) * lt->pntsu * lt->pntsv;
+ const int v_stride = lt->pntsu;
+ const int idx_v_max = (lt->pntsv - 1) * lt->pntsu;
+ const int idx_u_max = (lt->pntsu - 1);
- if (w != 0.0f) {
- if (ww > 0) {
- if (ww < lt->pntsw) {
- idx_w = ww * lt->pntsu * lt->pntsv;
- }
- else {
- idx_w = (lt->pntsw - 1) * lt->pntsu * lt->pntsv;
+ for (ww = wi - 1; ww <= wi + 2; ww++) {
+ w = weight * tw[ww - wi + 1];
+ idx_w = CLAMPIS(ww * w_stride, 0, idx_w_max);
+ for (vv = vi - 1; vv <= vi + 2; vv++) {
+ v = w * tv[vv - vi + 1];
+ idx_v = CLAMPIS(vv * v_stride, 0, idx_v_max);
+ for (uu = ui - 1; uu <= ui + 2; uu++) {
+ u = v * tu[uu - ui + 1];
+ idx_u = CLAMPIS(uu, 0, idx_u_max);
+ const int idx = idx_w + idx_v + idx_u;
+#ifdef __SSE2__
+ {
+ __m128 weight_vec = _mm_set1_ps(u);
+ /* This will load one extra element, this is ok because
+ * we ignore that part of register anyway.
+ */
+ __m128 lattice_vec = _mm_loadu_ps(&latticedata[idx * 3]);
+ co_vec = _mm_add_ps(co_vec, _mm_mul_ps(lattice_vec, weight_vec));
}
- }
- else {
- idx_w = 0;
- }
-
- for (vv = vi - 1; vv <= vi + 2; vv++) {
- v = w * tv[vv - vi + 1];
-
- if (v != 0.0f) {
- if (vv > 0) {
- if (vv < lt->pntsv) {
- idx_v = idx_w + vv * lt->pntsu;
- }
- else {
- idx_v = idx_w + (lt->pntsv - 1) * lt->pntsu;
- }
- }
- else {
- idx_v = idx_w;
- }
-
- for (uu = ui - 1; uu <= ui + 2; uu++) {
- u = weight * v * tu[uu - ui + 1];
-
- if (u != 0.0f) {
- if (uu > 0) {
- if (uu < lt->pntsu) {
- idx_u = idx_v + uu;
- }
- else {
- idx_u = idx_v + (lt->pntsu - 1);
- }
- }
- else {
- idx_u = idx_v;
- }
-
- madd_v3_v3fl(co, &latticedata[idx_u * 3], u);
-
- if (defgrp_index != -1) {
- weight_blend += (u * BKE_defvert_find_weight(dvert + idx_u, defgrp_index));
- }
- }
- }
+#else
+ madd_v3_v3fl(co, &latticedata[idx * 3], u);
+#endif
+ if (lattice_weights) {
+ weight_blend += (u * lattice_weights[idx]);
}
}
}
}
+#ifdef __SSE2__
+ {
+ copy_v3_v3(co, (float *)&co_vec);
+ }
+#endif
- if (defgrp_index != -1) {
+ if (lattice_weights) {
interp_v3_v3v3(co, co_prev, co, weight_blend);
}
}
diff --git a/source/blender/blenkernel/intern/lattice_deform_test.cc b/source/blender/blenkernel/intern/lattice_deform_test.cc
new file mode 100644
index 00000000000..33a4cc1d871
--- /dev/null
+++ b/source/blender/blenkernel/intern/lattice_deform_test.cc
@@ -0,0 +1,138 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2020 by Blender Foundation.
+ */
+#include "testing/testing.h"
+
+#include "BKE_idtype.h"
+#include "BKE_lattice.h"
+
+#include "MEM_guardedalloc.h"
+
+#include "DNA_lattice_types.h"
+#include "DNA_mesh_types.h"
+#include "DNA_object_types.h"
+
+#include "BLI_rand.hh"
+
+namespace blender::bke::tests {
+
+struct LatticeDeformTestContext {
+ Lattice lattice;
+ Object ob_lattice;
+ Mesh mesh;
+ Object ob_mesh;
+ float (*coords)[3];
+ LatticeDeformData *ldd;
+};
+
+static void test_lattice_deform_init(LatticeDeformTestContext *ctx,
+ RandomNumberGenerator *rng,
+ int32_t num_items)
+{
+ /* Generate random input data between -5 and 5. */
+ ctx->coords = (float(*)[3])MEM_malloc_arrayN(sizeof(float[3]), num_items, __func__);
+ for (uint32_t index = 0; index < num_items; index++) {
+ ctx->coords[index][0] = (rng->get_float() - 0.5f) * 10;
+ ctx->coords[index][1] = (rng->get_float() - 0.5f) * 10;
+ ctx->coords[index][2] = (rng->get_float() - 0.5f) * 10;
+ }
+ IDType_ID_LT.init_data(&ctx->lattice.id);
+ IDType_ID_OB.init_data(&ctx->ob_lattice.id);
+ ctx->ob_lattice.type = OB_LATTICE;
+ ctx->ob_lattice.data = &ctx->lattice;
+ IDType_ID_OB.init_data(&ctx->ob_mesh.id);
+ IDType_ID_ME.init_data(&ctx->mesh.id);
+ ctx->ob_mesh.type = OB_MESH;
+ ctx->ob_mesh.data = &ctx->mesh;
+
+ ctx->ldd = BKE_lattice_deform_data_create(&ctx->ob_lattice, &ctx->ob_mesh);
+}
+
+static void test_lattice_deform(LatticeDeformTestContext *ctx, int32_t num_items)
+{
+ for (int i = 0; i < num_items; i++) {
+ float *co = &ctx->coords[i][0];
+ BKE_lattice_deform_data_eval_co(ctx->ldd, co, 1.0f);
+ }
+}
+
+static void test_lattice_deform_free(LatticeDeformTestContext *ctx)
+{
+ BKE_lattice_deform_data_destroy(ctx->ldd);
+ MEM_freeN(ctx->coords);
+ IDType_ID_LT.free_data(&ctx->lattice.id);
+ IDType_ID_OB.free_data(&ctx->ob_lattice.id);
+ IDType_ID_OB.free_data(&ctx->ob_mesh.id);
+ IDType_ID_ME.free_data(&ctx->mesh.id);
+}
+
+TEST(lattice_deform_performance, performance_no_dvert_1)
+{
+ const int32_t num_items = 1;
+ LatticeDeformTestContext ctx = {0};
+ RandomNumberGenerator rng;
+ test_lattice_deform_init(&ctx, &rng, num_items);
+ test_lattice_deform(&ctx, num_items);
+ test_lattice_deform_free(&ctx);
+}
+TEST(lattice_deform_performance, performance_no_dvert_1000)
+{
+ const int32_t num_items = 1000;
+ LatticeDeformTestContext ctx = {0};
+ RandomNumberGenerator rng;
+ test_lattice_deform_init(&ctx, &rng, num_items);
+ test_lattice_deform(&ctx, num_items);
+ test_lattice_deform_free(&ctx);
+}
+TEST(lattice_deform_performance, performance_no_dvert_10000)
+{
+ const int32_t num_items = 10000;
+ LatticeDeformTestContext ctx = {0};
+ RandomNumberGenerator rng;
+ test_lattice_deform_init(&ctx, &rng, num_items);
+ test_lattice_deform(&ctx, num_items);
+ test_lattice_deform_free(&ctx);
+}
+TEST(lattice_deform_performance, performance_no_dvert_100000)
+{
+ const int32_t num_items = 100000;
+ LatticeDeformTestContext ctx = {0};
+ RandomNumberGenerator rng;
+ test_lattice_deform_init(&ctx, &rng, num_items);
+ test_lattice_deform(&ctx, num_items);
+ test_lattice_deform_free(&ctx);
+}
+TEST(lattice_deform_performance, performance_no_dvert_1000000)
+{
+ const int32_t num_items = 1000000;
+ LatticeDeformTestContext ctx = {0};
+ RandomNumberGenerator rng;
+ test_lattice_deform_init(&ctx, &rng, num_items);
+ test_lattice_deform(&ctx, num_items);
+ test_lattice_deform_free(&ctx);
+}
+TEST(lattice_deform_performance, performance_no_dvert_10000000)
+{
+ const int32_t num_items = 10000000;
+ LatticeDeformTestContext ctx = {0};
+ RandomNumberGenerator rng;
+ test_lattice_deform_init(&ctx, &rng, num_items);
+ test_lattice_deform(&ctx, num_items);
+ test_lattice_deform_free(&ctx);
+}
+
+} // namespace blender::bke::tests \ No newline at end of file
diff --git a/source/blender/blenkernel/intern/lib_id_delete.c b/source/blender/blenkernel/intern/lib_id_delete.c
index 1e45a3c1163..25c48479ef9 100644
--- a/source/blender/blenkernel/intern/lib_id_delete.c
+++ b/source/blender/blenkernel/intern/lib_id_delete.c
@@ -261,7 +261,9 @@ static void id_delete(Main *bmain, const bool do_tagged_deletion)
bool keep_looping = true;
while (keep_looping) {
ID *id, *id_next;
- ID *last_remapped_id = tagged_deleted_ids.last;
+ /* Marked volatile to avoid a macOS Clang optimization bug. See T81077.
+ * #last_remapped_id.next is assumed to be NULL by optimizer which is wrong. */
+ volatile ID *last_remapped_id = tagged_deleted_ids.last;
keep_looping = false;
/* First tag and remove from Main all datablocks directly from target lib.
diff --git a/source/blender/blenkernel/intern/lib_override.c b/source/blender/blenkernel/intern/lib_override.c
index 3bac0cf6289..79e33f768b6 100644
--- a/source/blender/blenkernel/intern/lib_override.c
+++ b/source/blender/blenkernel/intern/lib_override.c
@@ -1230,13 +1230,16 @@ bool BKE_lib_override_library_status_check_local(Main *bmain, ID *local)
BLI_assert(GS(local->name) == GS(reference->name));
if (GS(local->name) == ID_OB) {
- /* Our beloved pose's bone cross-data pointers... Usually, depsgraph evaluation would ensure
- * this is valid, but in some cases (like hidden collections etc.) this won't be the case, so
- * we need to take care of this ourselves. */
+ /* Our beloved pose's bone cross-data pointers.. Usually, depsgraph evaluation would
+ * ensure this is valid, but in some situations (like hidden collections etc.) this won't
+ * be the case, so we need to take care of this ourselves. */
Object *ob_local = (Object *)local;
- if (ob_local->data != NULL && ob_local->type == OB_ARMATURE && ob_local->pose != NULL &&
- ob_local->pose->flag & POSE_RECALC) {
- BKE_pose_rebuild(bmain, ob_local, ob_local->data, true);
+ if (ob_local->type == OB_ARMATURE) {
+ Object *ob_reference = (Object *)local->override_library->reference;
+ BLI_assert(ob_local->data != NULL);
+ BLI_assert(ob_reference->data != NULL);
+ BKE_pose_ensure(bmain, ob_local, ob_local->data, true);
+ BKE_pose_ensure(bmain, ob_reference, ob_reference->data, true);
}
}
@@ -1296,13 +1299,16 @@ bool BKE_lib_override_library_status_check_reference(Main *bmain, ID *local)
}
if (GS(local->name) == ID_OB) {
- /* Our beloved pose's bone cross-data pointers... Usually, depsgraph evaluation would ensure
- * this is valid, but in some cases (like hidden collections etc.) this won't be the case, so
- * we need to take care of this ourselves. */
+ /* Our beloved pose's bone cross-data pointers.. Usually, depsgraph evaluation would
+ * ensure this is valid, but in some situations (like hidden collections etc.) this won't
+ * be the case, so we need to take care of this ourselves. */
Object *ob_local = (Object *)local;
- if (ob_local->data != NULL && ob_local->type == OB_ARMATURE && ob_local->pose != NULL &&
- ob_local->pose->flag & POSE_RECALC) {
- BKE_pose_rebuild(bmain, ob_local, ob_local->data, true);
+ if (ob_local->type == OB_ARMATURE) {
+ Object *ob_reference = (Object *)local->override_library->reference;
+ BLI_assert(ob_local->data != NULL);
+ BLI_assert(ob_reference->data != NULL);
+ BKE_pose_ensure(bmain, ob_local, ob_local->data, true);
+ BKE_pose_ensure(bmain, ob_reference, ob_reference->data, true);
}
}
@@ -1353,13 +1359,16 @@ bool BKE_lib_override_library_operations_create(Main *bmain, ID *local)
}
if (GS(local->name) == ID_OB) {
- /* Our beloved pose's bone cross-data pointers... Usually, depsgraph evaluation would
+ /* Our beloved pose's bone cross-data pointers.. Usually, depsgraph evaluation would
* ensure this is valid, but in some situations (like hidden collections etc.) this won't
* be the case, so we need to take care of this ourselves. */
Object *ob_local = (Object *)local;
- if (ob_local->data != NULL && ob_local->type == OB_ARMATURE && ob_local->pose != NULL &&
- ob_local->pose->flag & POSE_RECALC) {
- BKE_pose_rebuild(bmain, ob_local, ob_local->data, true);
+ if (ob_local->type == OB_ARMATURE) {
+ Object *ob_reference = (Object *)local->override_library->reference;
+ BLI_assert(ob_local->data != NULL);
+ BLI_assert(ob_reference->data != NULL);
+ BKE_pose_ensure(bmain, ob_local, ob_local->data, true);
+ BKE_pose_ensure(bmain, ob_reference, ob_reference->data, true);
}
}
@@ -1417,6 +1426,17 @@ void BKE_lib_override_library_main_operations_create(Main *bmain, const bool for
BKE_lib_override_library_main_tag(bmain, IDOVERRIDE_LIBRARY_TAG_UNUSED, true);
}
+ /* Usual pose bones issue, need to be done outside of the threaded process or we may run into
+ * concurency issues here.
+ * Note that calling #BKE_pose_ensure again in thread in
+ * #BKE_lib_override_library_operations_create is not a problem then.. */
+ LISTBASE_FOREACH (Object *, ob, &bmain->objects) {
+ if (ob->type == OB_ARMATURE) {
+ BLI_assert(ob->data != NULL);
+ BKE_pose_ensure(bmain, ob, ob->data, true);
+ }
+ }
+
TaskPool *task_pool = BLI_task_pool_create(bmain, TASK_PRIORITY_HIGH);
FOREACH_MAIN_ID_BEGIN (bmain, id) {
diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c
index 0aa85f0ad50..d79a03dce6e 100644
--- a/source/blender/blenkernel/intern/modifier.c
+++ b/source/blender/blenkernel/intern/modifier.c
@@ -389,7 +389,7 @@ bool BKE_modifier_is_non_geometrical(ModifierData *md)
return (mti->type == eModifierTypeType_NonGeometrical);
}
-void BKE_modifier_set_error(ModifierData *md, const char *_format, ...)
+void BKE_modifier_set_error(const Object *ob, ModifierData *md, const char *_format, ...)
{
char buffer[512];
va_list ap;
@@ -406,7 +406,16 @@ void BKE_modifier_set_error(ModifierData *md, const char *_format, ...)
md->error = BLI_strdup(buffer);
- CLOG_STR_ERROR(&LOG, md->error);
+#ifndef NDEBUG
+ if ((md->mode & eModifierMode_Virtual) == 0) {
+ /* Ensure correct object is passed in. */
+ const Object *ob_orig = (Object *)DEG_get_original_id((ID *)&ob->id);
+ const ModifierData *md_orig = md->orig_modifier_data ? md->orig_modifier_data : md;
+ BLI_assert(BLI_findindex(&ob_orig->modifiers, md_orig) != -1);
+ }
+#endif
+
+ CLOG_ERROR(&LOG, "Object: \"%s\", Modifier: \"%s\", %s", ob->id.name + 2, md->name, md->error);
}
/* used for buttons, to find out if the 'draw deformed in editmode' option is
diff --git a/source/blender/blenkernel/intern/pointcache.c b/source/blender/blenkernel/intern/pointcache.c
index 5944d1a693b..45440eebacd 100644
--- a/source/blender/blenkernel/intern/pointcache.c
+++ b/source/blender/blenkernel/intern/pointcache.c
@@ -256,7 +256,9 @@ static int ptcache_softbody_totpoint(void *soft_v, int UNUSED(cfra))
SoftBody *soft = soft_v;
return soft->totpoint;
}
-static void ptcache_softbody_error(void *UNUSED(soft_v), const char *UNUSED(message))
+static void ptcache_softbody_error(const ID *UNUSED(owner_id),
+ void *UNUSED(soft_v),
+ const char *UNUSED(message))
{
/* ignored for now */
}
@@ -471,7 +473,9 @@ static int ptcache_particle_totpoint(void *psys_v, int UNUSED(cfra))
return psys->totpart;
}
-static void ptcache_particle_error(void *UNUSED(psys_v), const char *UNUSED(message))
+static void ptcache_particle_error(const ID *UNUSED(owner_id),
+ void *UNUSED(psys_v),
+ const char *UNUSED(message))
{
/* ignored for now */
}
@@ -642,10 +646,11 @@ static int ptcache_cloth_totpoint(void *cloth_v, int UNUSED(cfra))
return clmd->clothObject ? clmd->clothObject->mvert_num : 0;
}
-static void ptcache_cloth_error(void *cloth_v, const char *message)
+static void ptcache_cloth_error(const ID *owner_id, void *cloth_v, const char *message)
{
ClothModifierData *clmd = cloth_v;
- BKE_modifier_set_error(&clmd->modifier, "%s", message);
+ BLI_assert(GS(owner_id->name) == ID_OB);
+ BKE_modifier_set_error((Object *)owner_id, &clmd->modifier, "%s", message);
}
static int ptcache_dynamicpaint_totpoint(void *sd, int UNUSED(cfra))
@@ -659,7 +664,9 @@ static int ptcache_dynamicpaint_totpoint(void *sd, int UNUSED(cfra))
return surface->data->total_points;
}
-static void ptcache_dynamicpaint_error(void *UNUSED(sd), const char *UNUSED(message))
+static void ptcache_dynamicpaint_error(const ID *UNUSED(owner_id),
+ void *UNUSED(sd),
+ const char *UNUSED(message))
{
/* ignored for now */
}
@@ -853,7 +860,9 @@ static int ptcache_rigidbody_totpoint(void *rb_v, int UNUSED(cfra))
return rbw->numbodies;
}
-static void ptcache_rigidbody_error(void *UNUSED(rb_v), const char *UNUSED(message))
+static void ptcache_rigidbody_error(const struct ID *UNUSED(owner_id),
+ void *UNUSED(rb_v),
+ const char *UNUSED(message))
{
/* ignored for now */
}
@@ -2095,19 +2104,19 @@ static int ptcache_read_stream(PTCacheID *pid, int cfra)
}
if (!ptcache_file_header_begin_read(pf)) {
- pid->error(pid->calldata, "Failed to read point cache file");
+ pid->error(pid->owner_id, pid->calldata, "Failed to read point cache file");
error = 1;
}
else if (pf->type != pid->type) {
- pid->error(pid->calldata, "Point cache file has wrong type");
+ pid->error(pid->owner_id, pid->calldata, "Point cache file has wrong type");
error = 1;
}
else if (!pid->read_header(pf)) {
- pid->error(pid->calldata, "Failed to read point cache file header");
+ pid->error(pid->owner_id, pid->calldata, "Failed to read point cache file header");
error = 1;
}
else if (pf->totpoint != pid->totpoint(pid->calldata, cfra)) {
- pid->error(pid->calldata, "Number of points in cache does not match mesh");
+ pid->error(pid->owner_id, pid->calldata, "Number of points in cache does not match mesh");
error = 1;
}
@@ -2116,7 +2125,7 @@ static int ptcache_read_stream(PTCacheID *pid, int cfra)
/* We have stream reading here. */
if (!pid->read_stream(pf, pid->calldata)) {
- pid->error(pid->calldata, "Failed to read point cache file data");
+ pid->error(pid->owner_id, pid->calldata, "Failed to read point cache file data");
error = 1;
}
}
@@ -2152,7 +2161,7 @@ static int ptcache_read(PTCacheID *pid, int cfra)
int pid_totpoint = pid->totpoint(pid->calldata, cfra);
if (totpoint != pid_totpoint) {
- pid->error(pid->calldata, "Number of points in cache does not match mesh");
+ pid->error(pid->owner_id, pid->calldata, "Number of points in cache does not match mesh");
totpoint = MIN2(totpoint, pid_totpoint);
}
}
@@ -2208,7 +2217,7 @@ static int ptcache_interpolate(PTCacheID *pid, float cfra, int cfra1, int cfra2)
int pid_totpoint = pid->totpoint(pid->calldata, (int)cfra);
if (totpoint != pid_totpoint) {
- pid->error(pid->calldata, "Number of points in cache does not match mesh");
+ pid->error(pid->owner_id, pid->calldata, "Number of points in cache does not match mesh");
totpoint = MIN2(totpoint, pid_totpoint);
}
}
diff --git a/source/blender/blenlib/intern/mesh_boolean.cc b/source/blender/blenlib/intern/mesh_boolean.cc
index 169687cf9d1..bad0b84d10f 100644
--- a/source/blender/blenlib/intern/mesh_boolean.cc
+++ b/source/blender/blenlib/intern/mesh_boolean.cc
@@ -2068,7 +2068,7 @@ static bool apply_bool_op(BoolOpType bool_optype, const Array<int> &winding)
return true;
}
for (int i = 1; i < nw; ++i) {
- if (winding[i] == 1) {
+ if (winding[i] >= 1) {
return false;
}
}
diff --git a/source/blender/blenloader/intern/versioning_290.c b/source/blender/blenloader/intern/versioning_290.c
index 00085cb7d59..eeb0dd336a3 100644
--- a/source/blender/blenloader/intern/versioning_290.c
+++ b/source/blender/blenloader/intern/versioning_290.c
@@ -705,14 +705,12 @@ void blo_do_versions_290(FileData *fd, Library *UNUSED(lib), Main *bmain)
}
/* Solver and Collections for Boolean. */
- if (!DNA_struct_elem_find(fd->filesdna, "BooleanModifierData", "char", "solver")) {
- for (Object *object = bmain->objects.first; object != NULL; object = object->id.next) {
- LISTBASE_FOREACH (ModifierData *, md, &object->modifiers) {
- if (md->type == eModifierType_Boolean) {
- BooleanModifierData *bmd = (BooleanModifierData *)md;
- bmd->solver = eBooleanModifierSolver_Fast;
- bmd->flag = eBooleanModifierFlag_Object;
- }
+ for (Object *object = bmain->objects.first; object != NULL; object = object->id.next) {
+ LISTBASE_FOREACH (ModifierData *, md, &object->modifiers) {
+ if (md->type == eModifierType_Boolean) {
+ BooleanModifierData *bmd = (BooleanModifierData *)md;
+ bmd->solver = eBooleanModifierSolver_Fast;
+ bmd->flag = eBooleanModifierFlag_Object;
}
}
}
diff --git a/source/blender/bmesh/tools/bmesh_bevel.c b/source/blender/bmesh/tools/bmesh_bevel.c
index f54db513d0f..3a6ae9883e2 100644
--- a/source/blender/bmesh/tools/bmesh_bevel.c
+++ b/source/blender/bmesh/tools/bmesh_bevel.c
@@ -1520,9 +1520,16 @@ static bool good_offset_on_edge_between(EdgeHalf *e1, EdgeHalf *e2, EdgeHalf *em
* in-between edge emid. Viewed from the vertex normal side, the CCW order of these edges is e1,
* emid, e2. Return true if we placed meetco as compromise between where two edges met. If we did,
* put the ratio of sines of angles in *r_sinratio too.
+ * However, if the bp->offset_type is BEVEL_AMT_PERCENT or BEVEL_AMT_ABSOLUTE, we just slide
+ * along emid by the specified amount.
*/
-static bool offset_on_edge_between(
- EdgeHalf *e1, EdgeHalf *e2, EdgeHalf *emid, BMVert *v, float meetco[3], float *r_sinratio)
+static bool offset_on_edge_between(BevelParams *bp,
+ EdgeHalf *e1,
+ EdgeHalf *e2,
+ EdgeHalf *emid,
+ BMVert *v,
+ float meetco[3],
+ float *r_sinratio)
{
bool retval = false;
@@ -1532,6 +1539,22 @@ static bool offset_on_edge_between(
float meet1[3], meet2[3];
bool ok1 = offset_meet_edge(e1, emid, v, meet1, &ang1);
bool ok2 = offset_meet_edge(emid, e2, v, meet2, &ang2);
+ if (bp->offset_type == BEVEL_AMT_PERCENT || bp->offset_type == BEVEL_AMT_ABSOLUTE) {
+ BMVert *v2 = BM_edge_other_vert(emid->e, v);
+ if (bp->offset_type == BEVEL_AMT_PERCENT) {
+ interp_v3_v3v3(meetco, v->co, v2->co, bp->offset / 100.0f);
+ }
+ else {
+ float dir[3];
+ sub_v3_v3v3(dir, v2->co, v->co);
+ normalize_v3(dir);
+ madd_v3_v3v3fl(meetco, v->co, dir, bp->offset);
+ }
+ if (r_sinratio) {
+ *r_sinratio = (ang1 == 0.0f) ? 1.0f : sinf(ang2) / sinf(ang1);
+ }
+ return true;
+ }
if (ok1 && ok2) {
mid_v3_v3v3(meetco, meet1, meet2);
if (r_sinratio) {
@@ -2953,7 +2976,7 @@ static void build_boundary(BevelParams *bp, BevVert *bv, bool construct)
}
else if (not_in_plane > 0) {
if (bp->loop_slide && not_in_plane == 1 && good_offset_on_edge_between(e, e2, enip, bv->v)) {
- if (offset_on_edge_between(e, e2, enip, bv->v, co, &r)) {
+ if (offset_on_edge_between(bp, e, e2, enip, bv->v, co, &r)) {
eon = enip;
}
}
@@ -2964,7 +2987,7 @@ static void build_boundary(BevelParams *bp, BevVert *bv, bool construct)
else {
/* n_in_plane > 0 and n_not_in_plane == 0. */
if (bp->loop_slide && in_plane == 1 && good_offset_on_edge_between(e, e2, eip, bv->v)) {
- if (offset_on_edge_between(e, e2, eip, bv->v, co, &r)) {
+ if (offset_on_edge_between(bp, e, e2, eip, bv->v, co, &r)) {
eon = eip;
}
}
@@ -7195,7 +7218,7 @@ static float geometry_collide_offset(BevelParams *bp, EdgeHalf *eb)
if (bp->offset_type == BEVEL_AMT_PERCENT || bp->offset_type == BEVEL_AMT_ABSOLUTE) {
if (ea->is_bev && ebother != NULL && ebother->prev->is_bev) {
if (bp->offset_type == BEVEL_AMT_PERCENT) {
- return bp->offset > 50.0f ? 50.0f : 100.f;
+ return 50.0f;
}
/* This is only right sometimes. The exact answer is very hard to calculate. */
float blen = BM_edge_calc_length(eb->e);
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc
index 86a365a4901..ec5cbc5c605 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc
@@ -2667,6 +2667,9 @@ void DepsgraphRelationBuilder::build_scene_sequencer(Scene *scene)
if (scene->ed == nullptr) {
return;
}
+ if (built_map_.checkIsBuiltAndTag(scene, BuilderMap::TAG_SCENE_SEQUENCER)) {
+ return;
+ }
build_scene_audio(scene);
ComponentKey scene_audio_key(&scene->id, NodeType::AUDIO);
/* Make sure dependencies from sequences data goes to the sequencer evaluation. */
diff --git a/source/blender/editors/armature/armature_naming.c b/source/blender/editors/armature/armature_naming.c
index 60a1434ed42..8bcaf72f678 100644
--- a/source/blender/editors/armature/armature_naming.c
+++ b/source/blender/editors/armature/armature_naming.c
@@ -606,7 +606,7 @@ void ARMATURE_OT_autoside_names(wmOperatorType *ot)
};
/* identifiers */
- ot->name = "AutoName by Axis";
+ ot->name = "Auto-Name by Axis";
ot->idname = "ARMATURE_OT_autoside_names";
ot->description =
"Automatically renames the selected bones according to which side of the target axis they "
diff --git a/source/blender/editors/armature/armature_select.c b/source/blender/editors/armature/armature_select.c
index 27718b61d70..66c12a0d0d7 100644
--- a/source/blender/editors/armature/armature_select.c
+++ b/source/blender/editors/armature/armature_select.c
@@ -1550,10 +1550,10 @@ enum {
static const EnumPropertyItem prop_similar_types[] = {
{SIMEDBONE_CHILDREN, "CHILDREN", 0, "Children", ""},
- {SIMEDBONE_CHILDREN_IMMEDIATE, "CHILDREN_IMMEDIATE", 0, "Immediate children", ""},
+ {SIMEDBONE_CHILDREN_IMMEDIATE, "CHILDREN_IMMEDIATE", 0, "Immediate Children", ""},
{SIMEDBONE_SIBLINGS, "SIBLINGS", 0, "Siblings", ""},
{SIMEDBONE_LENGTH, "LENGTH", 0, "Length", ""},
- {SIMEDBONE_DIRECTION, "DIRECTION", 0, "Direction (Y axis)", ""},
+ {SIMEDBONE_DIRECTION, "DIRECTION", 0, "Direction (Y Axis)", ""},
{SIMEDBONE_PREFIX, "PREFIX", 0, "Prefix", ""},
{SIMEDBONE_SUFFIX, "SUFFIX", 0, "Suffix", ""},
{SIMEDBONE_LAYER, "LAYER", 0, "Layer", ""},
diff --git a/source/blender/editors/armature/meshlaplacian.c b/source/blender/editors/armature/meshlaplacian.c
index e51e5ec5cef..3c0b6dacbf6 100644
--- a/source/blender/editors/armature/meshlaplacian.c
+++ b/source/blender/editors/armature/meshlaplacian.c
@@ -1547,7 +1547,8 @@ static void meshdeform_matrix_solve(MeshDeformModifierData *mmd, MeshDeformBind
}
}
else {
- BKE_modifier_set_error(&mmd->modifier, "Failed to find bind solution (increase precision?)");
+ BKE_modifier_set_error(
+ mmd->object, &mmd->modifier, "Failed to find bind solution (increase precision?)");
error("Mesh Deform: failed to find bind solution.");
break;
}
diff --git a/source/blender/editors/armature/pose_edit.c b/source/blender/editors/armature/pose_edit.c
index e8c35958115..857176937dc 100644
--- a/source/blender/editors/armature/pose_edit.c
+++ b/source/blender/editors/armature/pose_edit.c
@@ -638,7 +638,7 @@ void POSE_OT_autoside_names(wmOperatorType *ot)
};
/* identifiers */
- ot->name = "AutoName by Axis";
+ ot->name = "Auto-Name by Axis";
ot->idname = "POSE_OT_autoside_names";
ot->description =
"Automatically renames the selected bones according to which side of the target axis they "
diff --git a/source/blender/editors/curve/editcurve_query.c b/source/blender/editors/curve/editcurve_query.c
index 48571ab2a9b..369137cbe25 100644
--- a/source/blender/editors/curve/editcurve_query.c
+++ b/source/blender/editors/curve/editcurve_query.c
@@ -26,6 +26,7 @@
#include "MEM_guardedalloc.h"
+#include "BLI_listbase.h"
#include "BLI_math.h"
#include "BKE_curve.h"
@@ -170,7 +171,6 @@ void ED_curve_nurb_vert_selected_find(
/* in nu and (bezt or bp) selected are written if there's 1 sel. */
/* if more points selected in 1 spline: return only nu, bezt and bp are 0 */
ListBase *editnurb = &cu->editnurb->nurbs;
- Nurb *nu1;
BezTriple *bezt1;
BPoint *bp1;
int a;
@@ -179,7 +179,7 @@ void ED_curve_nurb_vert_selected_find(
*r_bezt = NULL;
*r_bp = NULL;
- for (nu1 = editnurb->first; nu1; nu1 = nu1->next) {
+ LISTBASE_FOREACH (Nurb *, nu1, editnurb) {
if (nu1->type == CU_BEZIER) {
bezt1 = nu1->bezt;
a = nu1->pntsu;
diff --git a/source/blender/editors/curve/editcurve_select.c b/source/blender/editors/curve/editcurve_select.c
index aa4ba332b66..cb0a66bf5a8 100644
--- a/source/blender/editors/curve/editcurve_select.c
+++ b/source/blender/editors/curve/editcurve_select.c
@@ -237,9 +237,7 @@ int ED_curve_select_count(View3D *v3d, struct EditNurb *editnurb)
bool ED_curve_select_check(View3D *v3d, struct EditNurb *editnurb)
{
- Nurb *nu;
-
- for (nu = editnurb->nurbs.first; nu; nu = nu->next) {
+ LISTBASE_FOREACH (Nurb *, nu, &editnurb->nurbs) {
if (ED_curve_nurb_select_check(v3d, nu)) {
return true;
}
@@ -284,13 +282,12 @@ bool ED_curve_deselect_all_multi(struct bContext *C)
bool ED_curve_select_swap(EditNurb *editnurb, bool hide_handles)
{
- Nurb *nu;
BPoint *bp;
BezTriple *bezt;
int a;
bool changed = false;
- for (nu = editnurb->nurbs.first; nu; nu = nu->next) {
+ LISTBASE_FOREACH (Nurb *, nu, &editnurb->nurbs) {
if (nu->type == CU_BEZIER) {
bezt = nu->bezt;
a = nu->pntsu;
@@ -331,7 +328,6 @@ static void select_adjacent_cp(ListBase *editnurb,
const bool cont,
const bool selstatus)
{
- Nurb *nu;
BezTriple *bezt;
BPoint *bp;
int a;
@@ -341,7 +337,7 @@ static void select_adjacent_cp(ListBase *editnurb,
return;
}
- for (nu = editnurb->first; nu; nu = nu->next) {
+ LISTBASE_FOREACH (Nurb *, nu, editnurb) {
lastsel = false;
if (nu->type == CU_BEZIER) {
a = nu->pntsu;
@@ -412,7 +408,6 @@ static void select_adjacent_cp(ListBase *editnurb,
static void selectend_nurb(Object *obedit, eEndPoint_Types selfirst, bool doswap, bool selstatus)
{
ListBase *editnurb = object_editcurve_get(obedit);
- Nurb *nu;
BPoint *bp;
BezTriple *bezt;
Curve *cu;
@@ -425,7 +420,7 @@ static void selectend_nurb(Object *obedit, eEndPoint_Types selfirst, bool doswap
cu = (Curve *)obedit->data;
cu->actvert = CU_ACT_NONE;
- for (nu = editnurb->first; nu; nu = nu->next) {
+ LISTBASE_FOREACH (Nurb *, nu, editnurb) {
if (nu->type == CU_BEZIER) {
a = nu->pntsu;
@@ -632,10 +627,9 @@ static int select_linked_exec(bContext *C, wmOperator *UNUSED(op))
Curve *cu = obedit->data;
EditNurb *editnurb = cu->editnurb;
ListBase *nurbs = &editnurb->nurbs;
- Nurb *nu;
bool changed = false;
- for (nu = nurbs->first; nu; nu = nu->next) {
+ LISTBASE_FOREACH (Nurb *, nu, nurbs) {
if (ED_curve_nurb_select_check(v3d, nu)) {
changed |= ED_curve_nurb_select_all(nu);
}
@@ -887,7 +881,6 @@ void CURVE_OT_select_previous(wmOperatorType *ot)
static void curve_select_more(Object *obedit)
{
ListBase *editnurb = object_editcurve_get(obedit);
- Nurb *nu;
BPoint *bp, *tempbp;
int a;
short sel = 0;
@@ -897,7 +890,7 @@ static void curve_select_more(Object *obedit)
/* The algorithm is designed to work in planar cases so it */
/* may not be optimal always (example: end of NURBS sphere) */
if (obedit->type == OB_SURF) {
- for (nu = editnurb->first; nu; nu = nu->next) {
+ LISTBASE_FOREACH (Nurb *, nu, editnurb) {
BLI_bitmap *selbpoints;
a = nu->pntsu * nu->pntsv;
bp = nu->bp;
@@ -997,7 +990,6 @@ void CURVE_OT_select_more(wmOperatorType *ot)
static void curve_select_less(Object *obedit)
{
ListBase *editnurb = object_editcurve_get(obedit);
- Nurb *nu;
BPoint *bp;
BezTriple *bezt;
int a;
@@ -1005,7 +997,7 @@ static void curve_select_less(Object *obedit)
bool lastsel = false;
if (obedit->type == OB_SURF) {
- for (nu = editnurb->first; nu; nu = nu->next) {
+ LISTBASE_FOREACH (Nurb *, nu, editnurb) {
BLI_bitmap *selbpoints;
a = nu->pntsu * nu->pntsv;
bp = nu->bp;
@@ -1077,7 +1069,7 @@ static void curve_select_less(Object *obedit)
}
}
else {
- for (nu = editnurb->first; nu; nu = nu->next) {
+ LISTBASE_FOREACH (Nurb *, nu, editnurb) {
lastsel = false;
/* check what type of curve/nurb it is */
if (nu->type == CU_BEZIER) {
@@ -1210,14 +1202,13 @@ void CURVE_OT_select_less(wmOperatorType *ot)
static void curve_select_random(ListBase *editnurb, float randfac, int seed, bool select)
{
- Nurb *nu;
BezTriple *bezt;
BPoint *bp;
int a;
RNG *rng = BLI_rng_new_srandom(seed);
- for (nu = editnurb->first; nu; nu = nu->next) {
+ LISTBASE_FOREACH (Nurb *, nu, editnurb) {
if (nu->type == CU_BEZIER) {
bezt = nu->bezt;
a = nu->pntsu;
@@ -1702,8 +1693,7 @@ static int curve_select_similar_exec(bContext *C, wmOperator *op)
Curve *cu = obedit->data;
EditNurb *editnurb = cu->editnurb;
- Nurb *nu;
- for (nu = editnurb->nurbs.first; nu; nu = nu->next) {
+ LISTBASE_FOREACH (Nurb *, nu, &editnurb->nurbs) {
if (!ED_curve_nurb_select_check(v3d, nu)) {
continue;
}
@@ -1736,9 +1726,8 @@ static int curve_select_similar_exec(bContext *C, wmOperator *op)
Curve *cu = obedit->data;
EditNurb *editnurb = cu->editnurb;
bool changed = false;
- Nurb *nu;
- for (nu = editnurb->nurbs.first; nu; nu = nu->next) {
+ LISTBASE_FOREACH (Nurb *, nu, &editnurb->nurbs) {
switch (optype) {
case SIMCURHAND_TYPE: {
if (nu->type & type_ref) {
diff --git a/source/blender/editors/gpencil/gpencil_edit.c b/source/blender/editors/gpencil/gpencil_edit.c
index 7d79e748f75..98789706a13 100644
--- a/source/blender/editors/gpencil/gpencil_edit.c
+++ b/source/blender/editors/gpencil/gpencil_edit.c
@@ -3152,8 +3152,8 @@ void GPENCIL_OT_stroke_cyclical_set(wmOperatorType *ot)
PropertyRNA *prop;
static const EnumPropertyItem cyclic_type[] = {
- {GP_STROKE_CYCLIC_CLOSE, "CLOSE", 0, "Close all", ""},
- {GP_STROKE_CYCLIC_OPEN, "OPEN", 0, "Open all", ""},
+ {GP_STROKE_CYCLIC_CLOSE, "CLOSE", 0, "Close All", ""},
+ {GP_STROKE_CYCLIC_OPEN, "OPEN", 0, "Open All", ""},
{GP_STROKE_CYCLIC_TOGGLE, "TOGGLE", 0, "Toggle", ""},
{0, NULL, 0, NULL, NULL},
};
diff --git a/source/blender/editors/interface/interface.c b/source/blender/editors/interface/interface.c
index 601ab44c3d6..ea9385cb08f 100644
--- a/source/blender/editors/interface/interface.c
+++ b/source/blender/editors/interface/interface.c
@@ -772,6 +772,95 @@ static void ui_but_extra_icons_update_from_old_but(const uiBut *new_but, const u
}
/**
+ * Update pointers and other information in the old active button based on new information in the
+ * corresponding new button from the current layout pass.
+ *
+ * \param oldbut: The button from the last layout pass that will be moved to the new block.
+ * \param but: The newly added button with much of the up to date information, to be feed later.
+ *
+ * \note #uiBut has ownership of many of its pointers. When the button is freed all these
+ * pointers are freed as well, so ownership has to be moved out of \a but in order to free it.
+ */
+static void ui_but_update_old_active_from_new(uiBut *oldbut, uiBut *but)
+{
+ BLI_assert(oldbut->active);
+
+ /* flags from the buttons we want to refresh, may want to add more here... */
+ const int flag_copy = UI_BUT_REDALERT | UI_HAS_ICON;
+ const int drawflag_copy = 0; /* None currently. */
+
+ /* still stuff needs to be copied */
+ oldbut->rect = but->rect;
+ oldbut->context = but->context; /* set by Layout */
+
+ /* drawing */
+ oldbut->icon = but->icon;
+ oldbut->iconadd = but->iconadd;
+ oldbut->alignnr = but->alignnr;
+
+ /* typically the same pointers, but not on undo/redo */
+ /* XXX some menu buttons store button itself in but->poin. Ugly */
+ if (oldbut->poin != (char *)oldbut) {
+ SWAP(char *, oldbut->poin, but->poin);
+ SWAP(void *, oldbut->func_argN, but->func_argN);
+ }
+
+ /* Move tooltip from new to old. */
+ SWAP(uiButToolTipFunc, oldbut->tip_func, but->tip_func);
+ SWAP(void *, oldbut->tip_argN, but->tip_argN);
+
+ oldbut->flag = (oldbut->flag & ~flag_copy) | (but->flag & flag_copy);
+ oldbut->drawflag = (oldbut->drawflag & ~drawflag_copy) | (but->drawflag & drawflag_copy);
+
+ ui_but_extra_icons_update_from_old_but(but, oldbut);
+ SWAP(ListBase, but->extra_op_icons, oldbut->extra_op_icons);
+
+ if (oldbut->type == UI_BTYPE_SEARCH_MENU) {
+ uiButSearch *search_oldbut = (uiButSearch *)oldbut, *search_but = (uiButSearch *)but;
+
+ SWAP(uiButSearchArgFreeFn, search_oldbut->arg_free_fn, search_but->arg_free_fn);
+ SWAP(void *, search_oldbut->arg, search_but->arg);
+ }
+
+ /* copy hardmin for list rows to prevent 'sticking' highlight to mouse position
+ * when scrolling without moving mouse (see T28432) */
+ if (ELEM(oldbut->type, UI_BTYPE_ROW, UI_BTYPE_LISTROW)) {
+ oldbut->hardmax = but->hardmax;
+ }
+
+ if (oldbut->type == UI_BTYPE_PROGRESS_BAR) {
+ uiButProgressbar *progress_oldbut = (uiButProgressbar *)oldbut;
+ uiButProgressbar *progress_but = (uiButProgressbar *)but;
+ progress_oldbut->progress = progress_but->progress;
+ }
+
+ /* move/copy string from the new button to the old */
+ /* needed for alt+mouse wheel over enums */
+ if (but->str != but->strdata) {
+ if (oldbut->str != oldbut->strdata) {
+ SWAP(char *, but->str, oldbut->str);
+ }
+ else {
+ oldbut->str = but->str;
+ but->str = but->strdata;
+ }
+ }
+ else {
+ if (oldbut->str != oldbut->strdata) {
+ MEM_freeN(oldbut->str);
+ oldbut->str = oldbut->strdata;
+ }
+ BLI_strncpy(oldbut->strdata, but->strdata, sizeof(oldbut->strdata));
+ }
+
+ if (but->dragpoin && (but->dragflag & UI_BUT_DRAGPOIN_FREE)) {
+ SWAP(void *, but->dragpoin, oldbut->dragpoin);
+ }
+
+ /* note: if layout hasn't been applied yet, it uses old button pointers... */
+}
+
+/**
* \return true when \a but_p is set (only done for active buttons).
*/
static bool ui_but_update_from_old_block(const bContext *C,
@@ -779,138 +868,51 @@ static bool ui_but_update_from_old_block(const bContext *C,
uiBut **but_p,
uiBut **but_old_p)
{
- const int drawflag_copy = 0; /* None currently. */
-
uiBlock *oldblock = block->oldblock;
- uiBut *oldbut = NULL, *but = *but_p;
- bool found_active = false;
+ uiBut *but = *but_p;
#if 0
- /* simple/stupid - search every time */
- oldbut = ui_but_find_old(oldblock, but);
- (void)but_old_p;
+ /* Simple method - search every time. Keep this for easy testing of the "fast path." */
+ uiBut *oldbut = ui_but_find_old(oldblock, but);
+ UNUSED_VARS(but_old_p);
#else
BLI_assert(*but_old_p == NULL || BLI_findindex(&oldblock->buttons, *but_old_p) != -1);
- /* Fast-path - avoid loop-in-loop, calling #ui_but_find_old
- * as long as old/new buttons are aligned. */
+ /* As long as old and new buttons are aligned, avoid loop-in-loop (calling #ui_but_find_old). */
+ uiBut *oldbut;
if (LIKELY(*but_old_p && ui_but_equals_old(but, *but_old_p))) {
oldbut = *but_old_p;
}
else {
- /* fallback to block search */
+ /* Fallback to block search. */
oldbut = ui_but_find_old(oldblock, but);
}
(*but_old_p) = oldbut ? oldbut->next : NULL;
#endif
+ bool found_active = false;
+
if (!oldbut) {
- return found_active;
+ return false;
}
if (oldbut->active) {
- /* flags from the buttons we want to refresh, may want to add more here... */
- const int flag_copy = UI_BUT_REDALERT | UI_HAS_ICON;
-
- found_active = true;
-
-#if 0
- but->flag = oldbut->flag;
- but->active = oldbut->active;
- but->pos = oldbut->pos;
- but->ofs = oldbut->ofs;
- but->editstr = oldbut->editstr;
- but->editval = oldbut->editval;
- but->editvec = oldbut->editvec;
- but->selsta = oldbut->selsta;
- but->selend = oldbut->selend;
- but->softmin = oldbut->softmin;
- but->softmax = oldbut->softmax;
- oldbut->active = NULL;
-#endif
-
- /* move button over from oldblock to new block */
+ /* Move button over from oldblock to new block. */
BLI_remlink(&oldblock->buttons, oldbut);
BLI_insertlinkafter(&block->buttons, but, oldbut);
oldbut->block = block;
*but_p = oldbut;
- /* still stuff needs to be copied */
- oldbut->rect = but->rect;
- oldbut->context = but->context; /* set by Layout */
-
- /* drawing */
- oldbut->icon = but->icon;
- oldbut->iconadd = but->iconadd;
- oldbut->alignnr = but->alignnr;
-
- /* typically the same pointers, but not on undo/redo */
- /* XXX some menu buttons store button itself in but->poin. Ugly */
- if (oldbut->poin != (char *)oldbut) {
- SWAP(char *, oldbut->poin, but->poin);
- SWAP(void *, oldbut->func_argN, but->func_argN);
- }
-
- /* Move tooltip from new to old. */
- SWAP(uiButToolTipFunc, oldbut->tip_func, but->tip_func);
- SWAP(void *, oldbut->tip_argN, but->tip_argN);
-
- oldbut->flag = (oldbut->flag & ~flag_copy) | (but->flag & flag_copy);
- oldbut->drawflag = (oldbut->drawflag & ~drawflag_copy) | (but->drawflag & drawflag_copy);
-
- ui_but_extra_icons_update_from_old_but(but, oldbut);
- SWAP(ListBase, but->extra_op_icons, oldbut->extra_op_icons);
-
- if (oldbut->type == UI_BTYPE_SEARCH_MENU) {
- uiButSearch *search_oldbut = (uiButSearch *)oldbut, *search_but = (uiButSearch *)but;
-
- SWAP(uiButSearchArgFreeFn, search_oldbut->arg_free_fn, search_but->arg_free_fn);
- SWAP(void *, search_oldbut->arg, search_but->arg);
- }
-
- /* copy hardmin for list rows to prevent 'sticking' highlight to mouse position
- * when scrolling without moving mouse (see T28432) */
- if (ELEM(oldbut->type, UI_BTYPE_ROW, UI_BTYPE_LISTROW)) {
- oldbut->hardmax = but->hardmax;
- }
-
- if (oldbut->type == UI_BTYPE_PROGRESS_BAR) {
- uiButProgressbar *progress_oldbut = (uiButProgressbar *)oldbut;
- uiButProgressbar *progress_but = (uiButProgressbar *)but;
- progress_oldbut->progress = progress_but->progress;
- }
+ ui_but_update_old_active_from_new(oldbut, but);
if (!BLI_listbase_is_empty(&block->butstore)) {
UI_butstore_register_update(block, oldbut, but);
}
- /* move/copy string from the new button to the old */
- /* needed for alt+mouse wheel over enums */
- if (but->str != but->strdata) {
- if (oldbut->str != oldbut->strdata) {
- SWAP(char *, but->str, oldbut->str);
- }
- else {
- oldbut->str = but->str;
- but->str = but->strdata;
- }
- }
- else {
- if (oldbut->str != oldbut->strdata) {
- MEM_freeN(oldbut->str);
- oldbut->str = oldbut->strdata;
- }
- BLI_strncpy(oldbut->strdata, but->strdata, sizeof(oldbut->strdata));
- }
-
- if (but->dragpoin && (but->dragflag & UI_BUT_DRAGPOIN_FREE)) {
- SWAP(void *, but->dragpoin, oldbut->dragpoin);
- }
-
BLI_remlink(&block->buttons, but);
ui_but_free(C, but);
- /* note: if layout hasn't been applied yet, it uses old button pointers... */
+ found_active = true;
}
else {
const int flag_copy = UI_BUT_DRAG_MULTI;
diff --git a/source/blender/editors/interface/interface_eyedropper.c b/source/blender/editors/interface/interface_eyedropper.c
index a740a152f1c..4d0e1584156 100644
--- a/source/blender/editors/interface/interface_eyedropper.c
+++ b/source/blender/editors/interface/interface_eyedropper.c
@@ -78,7 +78,7 @@ wmKeyMap *eyedropper_colorband_modal_keymap(wmKeyConfig *keyconf)
{
static const EnumPropertyItem modal_items_point[] = {
{EYE_MODAL_POINT_CANCEL, "CANCEL", 0, "Cancel", ""},
- {EYE_MODAL_POINT_SAMPLE, "SAMPLE_SAMPLE", 0, "Sample a point", ""},
+ {EYE_MODAL_POINT_SAMPLE, "SAMPLE_SAMPLE", 0, "Sample a Point", ""},
{EYE_MODAL_POINT_CONFIRM, "SAMPLE_CONFIRM", 0, "Confirm Sampling", ""},
{EYE_MODAL_POINT_RESET, "SAMPLE_RESET", 0, "Reset Sampling", ""},
{0, NULL, 0, NULL, NULL},
diff --git a/source/blender/editors/interface/interface_panel.c b/source/blender/editors/interface/interface_panel.c
index 2a95a34e5e7..7fa45545a16 100644
--- a/source/blender/editors/interface/interface_panel.c
+++ b/source/blender/editors/interface/interface_panel.c
@@ -313,7 +313,7 @@ Panel *UI_panel_add_instanced(const bContext *C,
Panel *new_panel = panel_add_instanced(region, panels, panel_type, custom_data);
- /* Do this after #panel_add_instatnced so all subpanels are added. */
+ /* Do this after #panel_add_instatnced so all sub-panels are added. */
panel_set_expansion_from_list_data(C, new_panel);
return new_panel;
@@ -325,7 +325,7 @@ Panel *UI_panel_add_instanced(const bContext *C,
*/
void UI_list_panel_unique_str(Panel *panel, char *r_name)
{
- /* The panel sortorder will be unique for a specific panel type because the instanced
+ /* The panel sort-order will be unique for a specific panel type because the instanced
* panel list is regenerated for every change in the data order / length. */
snprintf(r_name, INSTANCED_PANEL_UNIQUE_STR_LEN, "%d", panel->sortorder);
}
@@ -805,7 +805,7 @@ static float panel_region_offset_x_get(const ARegion *region)
/**
* Starting from the "block size" set in #UI_panel_end, calculate the full size
- * of the panel including the subpanel headers and buttons.
+ * of the panel including the sub-panel headers and buttons.
*/
static void panel_calculate_size_recursive(ARegion *region, Panel *panel)
{
@@ -854,7 +854,7 @@ static void panel_calculate_size_recursive(ARegion *region, Panel *panel)
void UI_panel_end(Panel *panel, int width, int height)
{
/* Store the size of the buttons layout in the panel. The actual panel size
- * (including subpanels) is calculated in #UI_panels_end. */
+ * (including sub-panels) is calculated in #UI_panels_end. */
panel->blocksizex = width;
panel->blocksizey = height;
}
@@ -916,13 +916,13 @@ static void panel_set_expansion_from_seach_filter_recursive(const bContext *C,
const bool use_animation)
{
/* This has to run on inactive panels that may not have a type,
- * but we can prevent running on headerless panels in some cases. */
+ * but we can prevent running on header-less panels in some cases. */
if (panel->type == NULL || !(panel->type->flag & PNL_NO_HEADER)) {
SET_FLAG_FROM_TEST(panel->runtime_flag, use_search_closed, PANEL_USE_CLOSED_FROM_SEARCH);
}
LISTBASE_FOREACH (Panel *, child_panel, &panel->children) {
- /* Don't check if the subpanel is active, otherwise the
+ /* Don't check if the sub-panel is active, otherwise the
* expansion won't be reset when the parent is closed. */
panel_set_expansion_from_seach_filter_recursive(
C, child_panel, use_search_closed, use_animation);
@@ -964,8 +964,8 @@ static void panel_remove_invisible_layouts_recursive(Panel *panel, const Panel *
}
}
else if (UI_panel_is_closed(panel)) {
- /* If subpanels have no search results but the parent panel does, then the parent panel open
- * and the subpanels will close. In that case there must be a way to hide the buttons in the
+ /* If sub-panels have no search results but the parent panel does, then the parent panel open
+ * and the sub-panels will close. In that case there must be a way to hide the buttons in the
* panel but keep the header buttons. */
LISTBASE_FOREACH (uiButtonGroup *, button_group, &block->button_groups) {
if (button_group->flag & UI_BUTTON_GROUP_PANEL_HEADER) {
diff --git a/source/blender/editors/interface/interface_templates.c b/source/blender/editors/interface/interface_templates.c
index d4d24b3e3c2..62c387638dc 100644
--- a/source/blender/editors/interface/interface_templates.c
+++ b/source/blender/editors/interface/interface_templates.c
@@ -5330,7 +5330,7 @@ static void ui_template_palette_menu(bContext *UNUSED(C), uiLayout *layout, void
{
uiLayout *row;
- uiItemL(layout, IFACE_("Sort by:"), ICON_NONE);
+ uiItemL(layout, IFACE_("Sort By:"), ICON_NONE);
row = uiLayoutRow(layout, false);
uiItemEnumO_value(row, IFACE_("Hue"), ICON_NONE, "PALETTE_OT_sort", "type", 1);
row = uiLayoutRow(layout, false);
diff --git a/source/blender/editors/mesh/editmesh_bevel.c b/source/blender/editors/mesh/editmesh_bevel.c
index a90d6530453..012bca050cf 100644
--- a/source/blender/editors/mesh/editmesh_bevel.c
+++ b/source/blender/editors/mesh/editmesh_bevel.c
@@ -642,56 +642,56 @@ wmKeyMap *bevel_modal_keymap(wmKeyConfig *keyconf)
static const EnumPropertyItem modal_items[] = {
{BEV_MODAL_CANCEL, "CANCEL", 0, "Cancel", "Cancel bevel"},
{BEV_MODAL_CONFIRM, "CONFIRM", 0, "Confirm", "Confirm bevel"},
- {BEV_MODAL_VALUE_OFFSET, "VALUE_OFFSET", 0, "Change offset", "Value changes offset"},
- {BEV_MODAL_VALUE_PROFILE, "VALUE_PROFILE", 0, "Change profile", "Value changes profile"},
- {BEV_MODAL_VALUE_SEGMENTS, "VALUE_SEGMENTS", 0, "Change segments", "Value changes segments"},
- {BEV_MODAL_SEGMENTS_UP, "SEGMENTS_UP", 0, "Increase segments", "Increase segments"},
- {BEV_MODAL_SEGMENTS_DOWN, "SEGMENTS_DOWN", 0, "Decrease segments", "Decrease segments"},
+ {BEV_MODAL_VALUE_OFFSET, "VALUE_OFFSET", 0, "Change Offset", "Value changes offset"},
+ {BEV_MODAL_VALUE_PROFILE, "VALUE_PROFILE", 0, "Change Profile", "Value changes profile"},
+ {BEV_MODAL_VALUE_SEGMENTS, "VALUE_SEGMENTS", 0, "Change Segments", "Value changes segments"},
+ {BEV_MODAL_SEGMENTS_UP, "SEGMENTS_UP", 0, "Increase Segments", "Increase segments"},
+ {BEV_MODAL_SEGMENTS_DOWN, "SEGMENTS_DOWN", 0, "Decrease Segments", "Decrease segments"},
{BEV_MODAL_OFFSET_MODE_CHANGE,
"OFFSET_MODE_CHANGE",
0,
- "Change offset mode",
+ "Change Offset Mode",
"Cycle through offset modes"},
{BEV_MODAL_CLAMP_OVERLAP_TOGGLE,
"CLAMP_OVERLAP_TOGGLE",
0,
- "Toggle clamp overlap",
+ "Toggle Clamp Overlap",
"Toggle clamp overlap flag"},
{BEV_MODAL_AFFECT_CHANGE,
"AFFECT_CHANGE",
0,
- "Change affect type",
+ "Change Affect Type",
"Change which geometry type the operation affects, edges or vertices"},
{BEV_MODAL_HARDEN_NORMALS_TOGGLE,
"HARDEN_NORMALS_TOGGLE",
0,
- "Toggle harden normals",
+ "Toggle Harden Normals",
"Toggle harden normals flag"},
{BEV_MODAL_MARK_SEAM_TOGGLE,
"MARK_SEAM_TOGGLE",
0,
- "Toggle mark seam",
+ "Toggle Mark Seam",
"Toggle mark seam flag"},
{BEV_MODAL_MARK_SHARP_TOGGLE,
"MARK_SHARP_TOGGLE",
0,
- "Toggle mark sharp",
+ "Toggle Mark Sharp",
"Toggle mark sharp flag"},
{BEV_MODAL_OUTER_MITER_CHANGE,
"OUTER_MITER_CHANGE",
0,
- "Change outer miter",
+ "Change Outer Miter",
"Cycle through outer miter kinds"},
{BEV_MODAL_INNER_MITER_CHANGE,
"INNER_MITER_CHANGE",
0,
- "Change inner miter",
+ "Change Inner Miter",
"Cycle through inner miter kinds"},
{BEV_MODAL_PROFILE_TYPE_CHANGE, "PROFILE_TYPE_CHANGE", 0, "Cycle through profile types", ""},
{BEV_MODAL_VERTEX_MESH_CHANGE,
"VERTEX_MESH_CHANGE",
0,
- "Change intersection method",
+ "Change Intersection Method",
"Cycle through intersection methods"},
{0, NULL, 0, NULL, NULL},
};
diff --git a/source/blender/editors/mesh/editmesh_mask_extract.c b/source/blender/editors/mesh/editmesh_mask_extract.c
index 0a9aa724764..96abd2226db 100644
--- a/source/blender/editors/mesh/editmesh_mask_extract.c
+++ b/source/blender/editors/mesh/editmesh_mask_extract.c
@@ -346,7 +346,7 @@ void MESH_OT_paint_mask_extract(wmOperatorType *ot)
ot->invoke = paint_mask_extract_invoke;
ot->exec = paint_mask_extract_exec;
- ot->flag = OPTYPE_REGISTER;
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
RNA_def_float(
ot->srna,
@@ -430,7 +430,7 @@ void MESH_OT_face_set_extract(wmOperatorType *ot)
ot->invoke = face_set_extract_invoke;
ot->modal = face_set_extract_modal;
- ot->flag = OPTYPE_REGISTER;
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
geometry_extract_props(ot->srna);
}
@@ -598,7 +598,7 @@ void MESH_OT_paint_mask_slice(wmOperatorType *ot)
ot->poll = geometry_extract_poll;
ot->exec = paint_mask_slice_exec;
- ot->flag = OPTYPE_REGISTER;
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
RNA_def_float(
ot->srna,
diff --git a/source/blender/editors/mesh/editmesh_select_similar.c b/source/blender/editors/mesh/editmesh_select_similar.c
index f94d3ba5a70..00349983c57 100644
--- a/source/blender/editors/mesh/editmesh_select_similar.c
+++ b/source/blender/editors/mesh/editmesh_select_similar.c
@@ -83,7 +83,7 @@ static const EnumPropertyItem prop_similar_types[] = {
{SIMFACE_SIDES, "SIDES", 0, "Polygon Sides", ""},
{SIMFACE_PERIMETER, "PERIMETER", 0, "Perimeter", ""},
{SIMFACE_NORMAL, "NORMAL", 0, "Normal", ""},
- {SIMFACE_COPLANAR, "COPLANAR", 0, "Co-planar", ""},
+ {SIMFACE_COPLANAR, "COPLANAR", 0, "Coplanar", ""},
{SIMFACE_SMOOTH, "SMOOTH", 0, "Flat/Smooth", ""},
{SIMFACE_FACEMAP, "FACE_MAP", 0, "Face-Map", ""},
#ifdef WITH_FREESTYLE
diff --git a/source/blender/editors/object/object_hook.c b/source/blender/editors/object/object_hook.c
index 5cfe02dbc59..91c9916d227 100644
--- a/source/blender/editors/object/object_hook.c
+++ b/source/blender/editors/object/object_hook.c
@@ -238,12 +238,11 @@ static void select_editlattice_hook(Object *obedit, HookModifierData *hmd)
static int return_editcurve_indexar(Object *obedit, int *r_tot, int **r_indexar, float r_cent[3])
{
ListBase *editnurb = object_editcurve_get(obedit);
- Nurb *nu;
BPoint *bp;
BezTriple *bezt;
int *index, a, nr, totvert = 0;
- for (nu = editnurb->first; nu; nu = nu->next) {
+ LISTBASE_FOREACH (Nurb *, nu, editnurb) {
if (nu->type == CU_BEZIER) {
bezt = nu->bezt;
a = nu->pntsu;
@@ -280,7 +279,7 @@ static int return_editcurve_indexar(Object *obedit, int *r_tot, int **r_indexar,
nr = 0;
zero_v3(r_cent);
- for (nu = editnurb->first; nu; nu = nu->next) {
+ LISTBASE_FOREACH (Nurb *, nu, editnurb) {
if (nu->type == CU_BEZIER) {
bezt = nu->bezt;
a = nu->pntsu;
@@ -377,12 +376,11 @@ static bool object_hook_index_array(Main *bmain,
static void select_editcurve_hook(Object *obedit, HookModifierData *hmd)
{
ListBase *editnurb = object_editcurve_get(obedit);
- Nurb *nu;
BPoint *bp;
BezTriple *bezt;
int index = 0, a, nr = 0;
- for (nu = editnurb->first; nu; nu = nu->next) {
+ LISTBASE_FOREACH (Nurb *, nu, editnurb) {
if (nu->type == CU_BEZIER) {
bezt = nu->bezt;
a = nu->pntsu;
diff --git a/source/blender/editors/object/object_modifier.c b/source/blender/editors/object/object_modifier.c
index 4eed9187d66..b8891b612c9 100644
--- a/source/blender/editors/object/object_modifier.c
+++ b/source/blender/editors/object/object_modifier.c
@@ -1478,8 +1478,8 @@ static char *modifier_apply_as_shapekey_get_description(struct bContext *UNUSED(
void OBJECT_OT_modifier_apply_as_shapekey(wmOperatorType *ot)
{
- ot->name = "Apply Modifier As Shapekey";
- ot->description = "Apply modifier as a new shapekey and remove from the stack";
+ ot->name = "Apply Modifier as Shape Key";
+ ot->description = "Apply modifier as a new shape key and remove from the stack";
ot->idname = "OBJECT_OT_modifier_apply_as_shapekey";
ot->invoke = modifier_apply_as_shapekey_invoke;
diff --git a/source/blender/editors/object/object_relations.c b/source/blender/editors/object/object_relations.c
index de3e5f3d5f9..3d65a9e5fcb 100644
--- a/source/blender/editors/object/object_relations.c
+++ b/source/blender/editors/object/object_relations.c
@@ -1359,7 +1359,7 @@ enum {
static const EnumPropertyItem prop_make_track_types[] = {
{CREATE_TRACK_DAMPTRACK, "DAMPTRACK", 0, "Damped Track Constraint", ""},
- {CREATE_TRACK_TRACKTO, "TRACKTO", 0, "Track To Constraint", ""},
+ {CREATE_TRACK_TRACKTO, "TRACKTO", 0, "Track to Constraint", ""},
{CREATE_TRACK_LOCKTRACK, "LOCKTRACK", 0, "Lock Track Constraint", ""},
{0, NULL, 0, NULL, NULL},
};
diff --git a/source/blender/editors/physics/particle_object.c b/source/blender/editors/physics/particle_object.c
index 56bdc5c21f4..017cd63d9d5 100644
--- a/source/blender/editors/physics/particle_object.c
+++ b/source/blender/editors/physics/particle_object.c
@@ -691,7 +691,7 @@ void PARTICLE_OT_disconnect_hair(wmOperatorType *ot)
ot->flag = OPTYPE_UNDO;
RNA_def_boolean(
- ot->srna, "all", 0, "All hair", "Disconnect all hair systems from the emitter mesh");
+ ot->srna, "all", 0, "All Hair", "Disconnect all hair systems from the emitter mesh");
}
/* from/to_world_space : whether from/to particles are in world or hair space
@@ -981,7 +981,7 @@ void PARTICLE_OT_connect_hair(wmOperatorType *ot)
/* No REGISTER, redo does not work due to missing update, see T47750. */
ot->flag = OPTYPE_UNDO;
- RNA_def_boolean(ot->srna, "all", 0, "All hair", "Connect all hair systems to the emitter mesh");
+ RNA_def_boolean(ot->srna, "all", 0, "All Hair", "Connect all hair systems to the emitter mesh");
}
/************************ particle system copy operator *********************/
diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c
index 27a1d4e4a50..6f80165ed3c 100644
--- a/source/blender/editors/screen/screen_ops.c
+++ b/source/blender/editors/screen/screen_ops.c
@@ -5523,8 +5523,8 @@ static void keymap_modal_set(wmKeyConfig *keyconf)
static const EnumPropertyItem modal_items[] = {
{KM_MODAL_CANCEL, "CANCEL", 0, "Cancel", ""},
{KM_MODAL_APPLY, "APPLY", 0, "Apply", ""},
- {KM_MODAL_SNAP_ON, "SNAP", 0, "Snap on", ""},
- {KM_MODAL_SNAP_OFF, "SNAP_OFF", 0, "Snap off", ""},
+ {KM_MODAL_SNAP_ON, "SNAP", 0, "Snap On", ""},
+ {KM_MODAL_SNAP_OFF, "SNAP_OFF", 0, "Snap Off", ""},
{0, NULL, 0, NULL, NULL},
};
diff --git a/source/blender/editors/sculpt_paint/paint_mask.c b/source/blender/editors/sculpt_paint/paint_mask.c
index 2193a31f19b..605cdfcbe9b 100644
--- a/source/blender/editors/sculpt_paint/paint_mask.c
+++ b/source/blender/editors/sculpt_paint/paint_mask.c
@@ -246,8 +246,16 @@ typedef struct LassoGestureData {
} LassoGestureData;
typedef struct LineGestureData {
+ /* Plane aligned to the gesture line. */
float true_plane[4];
float plane[4];
+
+ /* Planes to limit the action to the length of the gesture segment at both sides of the affected
+ * area. */
+ float side_plane[2][4];
+ float true_side_plane[2][4];
+ bool use_side_planes;
+
bool flip;
} LineGestureData;
@@ -320,6 +328,13 @@ static void sculpt_gesture_operator_properties(wmOperatorType *ot)
false,
"Front Faces Only",
"Affect only faces facing towards the view");
+
+ RNA_def_boolean(ot->srna,
+ "use_limit_to_segment",
+ false,
+ "Limit to Segment",
+ "Apply the gesture action only to the area that is contained within the "
+ "segement without extending its effect to the entire line");
}
static void sculpt_gesture_context_init_common(bContext *C,
@@ -332,6 +347,7 @@ static void sculpt_gesture_context_init_common(bContext *C,
/* Operator properties. */
sgcontext->front_faces_only = RNA_boolean_get(op->ptr, "use_front_faces_only");
+ sgcontext->line.use_side_planes = RNA_boolean_get(op->ptr, "use_limit_to_segment");
/* SculptSession */
sgcontext->ss = ob->sculpt;
@@ -448,6 +464,50 @@ static SculptGestureContext *sculpt_gesture_init_from_box(bContext *C, wmOperato
return sgcontext;
}
+static void sculpt_gesture_line_plane_from_tri(float *r_plane,
+ SculptGestureContext *sgcontext,
+ const bool flip,
+ const float p1[3],
+ const float p2[3],
+ const float p3[3])
+{
+ float normal[3];
+ normal_tri_v3(normal, p1, p2, p3);
+ mul_v3_mat3_m4v3(normal, sgcontext->vc.obact->imat, normal);
+ if (flip) {
+ mul_v3_fl(normal, -1.0f);
+ }
+ float plane_point_object_space[3];
+ mul_v3_m4v3(plane_point_object_space, sgcontext->vc.obact->imat, p1);
+ plane_from_point_normal_v3(r_plane, plane_point_object_space, normal);
+}
+
+/* Creates 4 points in the plane defined by the line and 2 extra points with an offset relative to
+ * this plane. */
+static void sculpt_gesture_line_calculate_plane_points(SculptGestureContext *sgcontext,
+ float line_points[2][2],
+ float r_plane_points[4][3],
+ float r_offset_plane_points[2][3])
+{
+ float depth_point[3];
+ add_v3_v3v3(depth_point, sgcontext->true_view_origin, sgcontext->true_view_normal);
+ ED_view3d_win_to_3d(
+ sgcontext->vc.v3d, sgcontext->vc.region, depth_point, line_points[0], r_plane_points[0]);
+ ED_view3d_win_to_3d(
+ sgcontext->vc.v3d, sgcontext->vc.region, depth_point, line_points[1], r_plane_points[3]);
+
+ madd_v3_v3v3fl(depth_point, sgcontext->true_view_origin, sgcontext->true_view_normal, 10.0f);
+ ED_view3d_win_to_3d(
+ sgcontext->vc.v3d, sgcontext->vc.region, depth_point, line_points[0], r_plane_points[1]);
+ ED_view3d_win_to_3d(
+ sgcontext->vc.v3d, sgcontext->vc.region, depth_point, line_points[1], r_plane_points[2]);
+
+ float normal[3];
+ normal_tri_v3(normal, r_plane_points[0], r_plane_points[1], r_plane_points[2]);
+ add_v3_v3v3(r_offset_plane_points[0], r_plane_points[0], normal);
+ add_v3_v3v3(r_offset_plane_points[1], r_plane_points[3], normal);
+}
+
static SculptGestureContext *sculpt_gesture_init_from_line(bContext *C, wmOperator *op)
{
SculptGestureContext *sgcontext = MEM_callocN(sizeof(SculptGestureContext),
@@ -464,36 +524,33 @@ static SculptGestureContext *sculpt_gesture_init_from_line(bContext *C, wmOperat
sgcontext->line.flip = RNA_boolean_get(op->ptr, "flip");
- float depth_point[3];
- float plane_points[3][3];
-
- /* Calculate a triangle in the line's plane. */
- add_v3_v3v3(depth_point, sgcontext->true_view_origin, sgcontext->true_view_normal);
- ED_view3d_win_to_3d(
- sgcontext->vc.v3d, sgcontext->vc.region, depth_point, line_points[0], plane_points[0]);
-
- madd_v3_v3v3fl(depth_point, sgcontext->true_view_origin, sgcontext->true_view_normal, 10.0f);
- ED_view3d_win_to_3d(
- sgcontext->vc.v3d, sgcontext->vc.region, depth_point, line_points[0], plane_points[1]);
- ED_view3d_win_to_3d(
- sgcontext->vc.v3d, sgcontext->vc.region, depth_point, line_points[1], plane_points[2]);
-
- /* Calculate final line plane and normal using the triangle. */
- float normal[3];
- normal_tri_v3(normal, plane_points[0], plane_points[1], plane_points[2]);
- if (!sgcontext->vc.rv3d->is_persp) {
- mul_v3_fl(normal, -1.0f);
- }
-
- /* Apply flip. */
- if (sgcontext->line.flip) {
- mul_v3_fl(normal, -1.0f);
- }
-
- mul_v3_mat3_m4v3(normal, sgcontext->vc.obact->imat, normal);
- float plane_point_object_space[3];
- mul_v3_m4v3(plane_point_object_space, sgcontext->vc.obact->imat, plane_points[0]);
- plane_from_point_normal_v3(sgcontext->line.true_plane, plane_point_object_space, normal);
+ float plane_points[4][3];
+ float offset_plane_points[2][3];
+ sculpt_gesture_line_calculate_plane_points(
+ sgcontext, line_points, plane_points, offset_plane_points);
+
+ /* Calculate line plane and normal. */
+ const bool flip = sgcontext->line.flip ^ !sgcontext->vc.rv3d->is_persp;
+ sculpt_gesture_line_plane_from_tri(sgcontext->line.true_plane,
+ sgcontext,
+ flip,
+ plane_points[0],
+ plane_points[1],
+ plane_points[2]);
+
+ /* Calculate the side planes. */
+ sculpt_gesture_line_plane_from_tri(sgcontext->line.true_side_plane[0],
+ sgcontext,
+ false,
+ plane_points[1],
+ plane_points[0],
+ offset_plane_points[0]);
+ sculpt_gesture_line_plane_from_tri(sgcontext->line.true_side_plane[1],
+ sgcontext,
+ false,
+ plane_points[3],
+ plane_points[2],
+ offset_plane_points[1]);
return sgcontext;
}
@@ -544,14 +601,20 @@ static void sculpt_gesture_flip_for_symmetry_pass(SculptGestureContext *sgcontex
flip_v3_v3(sgcontext->view_normal, sgcontext->true_view_normal, symmpass);
flip_v3_v3(sgcontext->view_origin, sgcontext->true_view_origin, symmpass);
flip_plane(sgcontext->line.plane, sgcontext->line.true_plane, symmpass);
+ flip_plane(sgcontext->line.side_plane[0], sgcontext->line.true_side_plane[0], symmpass);
+ flip_plane(sgcontext->line.side_plane[1], sgcontext->line.true_side_plane[1], symmpass);
}
static void sculpt_gesture_update_effected_nodes_by_line_plane(SculptGestureContext *sgcontext)
{
SculptSession *ss = sgcontext->ss;
- float clip_planes[1][4];
+ float clip_planes[3][4];
copy_v4_v4(clip_planes[0], sgcontext->line.plane);
- PBVHFrustumPlanes frustum = {.planes = clip_planes, .num_planes = 1};
+ copy_v4_v4(clip_planes[1], sgcontext->line.side_plane[0]);
+ copy_v4_v4(clip_planes[2], sgcontext->line.side_plane[1]);
+
+ const int num_planes = sgcontext->line.use_side_planes ? 3 : 1;
+ PBVHFrustumPlanes frustum = {.planes = clip_planes, .num_planes = num_planes};
BKE_pbvh_search_gather(ss->pbvh,
BKE_pbvh_node_frustum_contain_AABB,
&frustum,
@@ -630,6 +693,11 @@ static bool sculpt_gesture_is_vertex_effected(SculptGestureContext *sgcontext, P
case SCULPT_GESTURE_SHAPE_LASSO:
return sculpt_gesture_is_effected_lasso(sgcontext, vd->co);
case SCULPT_GESTURE_SHAPE_LINE:
+ if (sgcontext->line.use_side_planes) {
+ return plane_point_side_v3(sgcontext->line.plane, vd->co) > 0.0f &&
+ plane_point_side_v3(sgcontext->line.side_plane[0], vd->co) > 0.0f &&
+ plane_point_side_v3(sgcontext->line.side_plane[1], vd->co) > 0.0f;
+ }
return plane_point_side_v3(sgcontext->line.plane, vd->co) > 0.0f;
}
return false;
diff --git a/source/blender/editors/sculpt_paint/sculpt_cloth.c b/source/blender/editors/sculpt_paint/sculpt_cloth.c
index 1a1200bb6c2..20b164fa80c 100644
--- a/source/blender/editors/sculpt_paint/sculpt_cloth.c
+++ b/source/blender/editors/sculpt_paint/sculpt_cloth.c
@@ -139,14 +139,14 @@ static float cloth_brush_simulation_falloff_get(const Brush *brush,
const float falloff = radius + (radius * brush->cloth_sim_limit * brush->cloth_sim_falloff);
if (distance > limit) {
- /* Outiside the limits. */
+ /* Outside the limits. */
return 0.0f;
}
if (distance < falloff) {
/* Before the falloff area. */
return 1.0f;
}
- /* Do a smoothstep transition inside the falloff area. */
+ /* Do a smooth-step transition inside the falloff area. */
float p = 1.0f - ((distance - falloff) / (limit - falloff));
return 3.0f * p * p - 2.0f * p * p * p;
}
@@ -214,7 +214,7 @@ static void cloth_brush_add_length_constraint(SculptSession *ss,
/* Reallocation if the array capacity is exceeded. */
cloth_brush_reallocate_constraints(cloth_sim);
- /* Add the constraint to the GSet to avoid creating it again. */
+ /* Add the constraint to the #GSet to avoid creating it again. */
BLI_edgeset_add(cloth_sim->created_length_constraints, v1, v2);
}
@@ -326,12 +326,15 @@ static void do_cloth_brush_build_constraints_task_cb_ex(
* positions. */
const bool cloth_is_deform_brush = ss->cache != NULL && brush != NULL &&
SCULPT_is_cloth_deform_brush(brush);
+
+ const bool use_falloff_plane = brush->cloth_force_falloff_type ==
+ BRUSH_CLOTH_FORCE_FALLOFF_PLANE;
float radius_squared = 0.0f;
if (cloth_is_deform_brush) {
radius_squared = ss->cache->initial_radius * ss->cache->initial_radius;
}
- /* Only limit the contraint creation to a radius when the simulation is local. */
+ /* Only limit the constraint creation to a radius when the simulation is local. */
const float cloth_sim_radius_squared = brush->cloth_simulation_area_type ==
BRUSH_CLOTH_SIMULATION_AREA_LOCAL ?
data->cloth_sim_radius * data->cloth_sim_radius :
@@ -380,12 +383,21 @@ static void do_cloth_brush_build_constraints_task_cb_ex(
if (brush && brush->sculpt_tool == SCULPT_TOOL_CLOTH) {
/* The cloth brush works by applying forces in most of its modes, but some of them require
* deformation coordinates to make the simulation stable. */
- if (brush->cloth_deform_type == BRUSH_CLOTH_DEFORM_GRAB && len_squared < radius_squared) {
- /* When the grab brush brush is used as part of the cloth brush, deformation constraints
- * are created with different strengths and only inside the radius of the brush. */
- const float fade = BKE_brush_curve_strength(brush, sqrtf(len_squared), ss->cache->radius);
- cloth_brush_add_deformation_constraint(
- data->cloth_sim, node_index, vd.index, fade * CLOTH_DEFORMATION_GRAB_STRENGTH);
+ if (brush->cloth_deform_type == BRUSH_CLOTH_DEFORM_GRAB) {
+ if (use_falloff_plane) {
+ /* With plane falloff the strength of the constraints is set when applying the
+ * deformation forces. */
+ cloth_brush_add_deformation_constraint(
+ data->cloth_sim, node_index, vd.index, CLOTH_DEFORMATION_GRAB_STRENGTH);
+ }
+ else if (len_squared < radius_squared) {
+ /* With radial falloff deformation constraints are created with different strengths and
+ * only inside the radius of the brush. */
+ const float fade = BKE_brush_curve_strength(
+ brush, sqrtf(len_squared), ss->cache->radius);
+ cloth_brush_add_deformation_constraint(
+ data->cloth_sim, node_index, vd.index, fade * CLOTH_DEFORMATION_GRAB_STRENGTH);
+ }
}
else if (brush->cloth_deform_type == BRUSH_CLOTH_DEFORM_SNAKE_HOOK) {
/* Cloth Snake Hook creates deformation constraint with fixed strength because the strength
@@ -436,9 +448,8 @@ static void do_cloth_brush_apply_forces_task_cb_ex(void *__restrict userdata,
const float *grab_delta = data->grab_delta;
float(*imat)[4] = data->mat;
- const bool use_falloff_plane = !SCULPT_is_cloth_deform_brush(brush) &&
- brush->cloth_force_falloff_type ==
- BRUSH_CLOTH_FORCE_FALLOFF_PLANE;
+ const bool use_falloff_plane = brush->cloth_force_falloff_type ==
+ BRUSH_CLOTH_FORCE_FALLOFF_PLANE;
PBVHVertexIter vd;
const float bstrength = ss->cache->bstrength;
@@ -448,7 +459,7 @@ static void do_cloth_brush_apply_forces_task_cb_ex(void *__restrict userdata,
ss, &test, data->brush->falloff_shape);
const int thread_id = BLI_task_parallel_thread_id(tls);
- /* For Pich Perpendicular Deform Type. */
+ /* For Pinch Perpendicular Deform Type. */
float x_object_space[3];
float z_object_space[3];
if (brush->cloth_deform_type == BRUSH_CLOTH_DEFORM_PINCH_PERPENDICULAR) {
@@ -470,12 +481,6 @@ static void do_cloth_brush_apply_forces_task_cb_ex(void *__restrict userdata,
madd_v3_v3fl(gravity, ss->cache->gravity_direction, -data->sd->gravity_factor);
}
- /* Original data for deform brushes. */
- SculptOrigVertData orig_data;
- if (SCULPT_is_cloth_deform_brush(brush)) {
- SCULPT_orig_vert_data_init(&orig_data, data->ob, data->nodes[n]);
- }
-
BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
{
float force[3];
@@ -486,8 +491,7 @@ static void do_cloth_brush_apply_forces_task_cb_ex(void *__restrict userdata,
float current_vertex_location[3];
if (brush->cloth_deform_type == BRUSH_CLOTH_DEFORM_GRAB) {
- SCULPT_orig_vert_data_update(&orig_data, &vd);
- copy_v3_v3(current_vertex_location, orig_data.co);
+ copy_v3_v3(current_vertex_location, ss->cache->cloth_sim->init_pos[vd.index]);
}
else {
copy_v3_v3(current_vertex_location, vd.co);
@@ -504,7 +508,7 @@ static void do_cloth_brush_apply_forces_task_cb_ex(void *__restrict userdata,
float dist = sqrtf(test.dist);
if (use_falloff_plane) {
- dist = dist_to_plane_v3(vd.co, deform_plane);
+ dist = dist_to_plane_v3(current_vertex_location, deform_plane);
}
const float fade = sim_factor * bstrength *
@@ -539,9 +543,15 @@ static void do_cloth_brush_apply_forces_task_cb_ex(void *__restrict userdata,
break;
case BRUSH_CLOTH_DEFORM_GRAB:
madd_v3_v3v3fl(cloth_sim->deformation_pos[vd.index],
- orig_data.co,
+ cloth_sim->init_pos[vd.index],
ss->cache->grab_delta_symmetry,
fade);
+ if (use_falloff_plane) {
+ cloth_sim->deformation_strength[vd.index] = clamp_f(fade, 0.0f, 1.0f);
+ }
+ else {
+ cloth_sim->deformation_strength[vd.index] = 1.0f;
+ }
zero_v3(force);
break;
case BRUSH_CLOTH_DEFORM_SNAKE_HOOK:
@@ -920,7 +930,7 @@ static void cloth_brush_apply_brush_foces(Sculpt *sd, Object *ob, PBVHNode **nod
BKE_curvemapping_init(brush->curve);
- /* Init the grab delta. */
+ /* Initialize the grab delta. */
copy_v3_v3(grab_delta, ss->cache->grab_delta_symmetry);
normalize_v3(grab_delta);
@@ -930,7 +940,7 @@ static void cloth_brush_apply_brush_foces(Sculpt *sd, Object *ob, PBVHNode **nod
return;
}
- /* Calcuate push offset. */
+ /* Calculate push offset. */
if (brush->cloth_deform_type == BRUSH_CLOTH_DEFORM_PUSH) {
mul_v3_v3fl(offset, ss->cache->sculpt_normal_symm, ss->cache->radius);
@@ -944,7 +954,7 @@ static void cloth_brush_apply_brush_foces(Sculpt *sd, Object *ob, PBVHNode **nod
brush->cloth_force_falloff_type == BRUSH_CLOTH_FORCE_FALLOFF_PLANE) {
SCULPT_calc_brush_plane(sd, ob, nodes, totnode, area_no, area_co);
- /* Init stroke local space matrix. */
+ /* Initialize stroke local space matrix. */
cross_v3_v3v3(mat[0], area_no, ss->cache->grab_delta_symmetry);
mat[0][3] = 0.0f;
cross_v3_v3v3(mat[1], area_no, mat[0]);
@@ -965,8 +975,8 @@ static void cloth_brush_apply_brush_foces(Sculpt *sd, Object *ob, PBVHNode **nod
}
}
- if (brush->cloth_deform_type == BRUSH_CLOTH_DEFORM_SNAKE_HOOK) {
- /* Set the deformation strength to 0. Snake hook will initialize the strength in the required
+ if (ELEM(brush->cloth_deform_type, BRUSH_CLOTH_DEFORM_SNAKE_HOOK, BRUSH_CLOTH_DEFORM_GRAB)) {
+ /* Set the deformation strength to 0. Brushes will initialize the strength in the required
* area. */
const int totverts = SCULPT_vertex_count_get(ss);
for (int i = 0; i < totverts; i++) {
@@ -1058,7 +1068,7 @@ void SCULPT_cloth_brush_ensure_nodes_constraints(
PBVHNode **nodes,
int totnode,
SculptClothSimulation *cloth_sim,
- /* Cannot be const, because it is assigned to a non-const variable.
+ /* Cannot be `const`, because it is assigned to a `non-const` variable.
* NOLINTNEXTLINE: readability-non-const-parameter. */
float initial_location[3],
const float radius)
@@ -1127,14 +1137,27 @@ void SCULPT_cloth_sim_activate_nodes(SculptClothSimulation *cloth_sim,
}
}
+static void sculpt_cloth_ensure_constraints_in_simulation_area(Sculpt *sd,
+ Object *ob,
+ PBVHNode **nodes,
+ int totnode)
+{
+ SculptSession *ss = ob->sculpt;
+ Brush *brush = BKE_paint_brush(&sd->paint);
+ const float radius = ss->cache->initial_radius;
+ const float limit = radius + (radius * brush->cloth_sim_limit);
+ float sim_location[3];
+ cloth_brush_simulation_location_get(ss, brush, sim_location);
+ SCULPT_cloth_brush_ensure_nodes_constraints(
+ sd, ob, nodes, totnode, ss->cache->cloth_sim, sim_location, limit);
+}
+
/* Main Brush Function. */
void SCULPT_do_cloth_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
{
SculptSession *ss = ob->sculpt;
Brush *brush = BKE_paint_brush(&sd->paint);
- /* In the first brush step of each symmetry pass, build the constraints for the vertices in all
- * nodes inside the simulation's limits. */
/* Brushes that use anchored strokes and restore the mesh can't rely on symmetry passes and steps
* count as it is always the first step, so the simulation needs to be created when it does not
* exist for this stroke. */
@@ -1151,14 +1174,26 @@ void SCULPT_do_cloth_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode
SCULPT_is_cloth_deform_brush(brush));
SCULPT_cloth_brush_simulation_init(ss, ss->cache->cloth_sim);
}
+
+ if (brush->cloth_simulation_area_type == BRUSH_CLOTH_SIMULATION_AREA_LOCAL) {
+ /* When using simulation a fixed local simulation area, constraints are created only using
+ * the initial stroke position and initial radius (per symmetry pass) instead of per node.
+ * This allows to skip unnecessary constraints that will never be simulated, making the
+ * solver faster. When the simulation starts for a node, the node gets activated and all its
+ * constraints are considered final. As the same node can be included inside the brush radius
+ * from multiple symmetry passes, the cloth brush can't activate the node for simulation yet
+ * as this will cause the ensure constraints function to skip the node in the next symmetry
+ * passes. It needs to build the constraints here and skip simulating the first step, so all
+ * passes can add their constraints to all affected nodes. */
+ sculpt_cloth_ensure_constraints_in_simulation_area(sd, ob, nodes, totnode);
+ }
+ /* The first step of a symmetry pass is never simulated as deformation modes need valid delta
+ * for brush tip alignment. */
return;
}
/* Ensure the constraints for the nodes. */
- const float radius = ss->cache->initial_radius;
- const float limit = radius + (radius * brush->cloth_sim_limit);
- SCULPT_cloth_brush_ensure_nodes_constraints(
- sd, ob, nodes, totnode, ss->cache->cloth_sim, ss->cache->location, limit);
+ sculpt_cloth_ensure_constraints_in_simulation_area(sd, ob, nodes, totnode);
/* Store the initial state in the simulation. */
SCULPT_cloth_brush_store_simulation_state(ss, ss->cache->cloth_sim);
@@ -1228,9 +1263,14 @@ void SCULPT_cloth_plane_falloff_preview_draw(const uint gpuattr,
const float outline_col[3],
float outline_alpha)
{
- float local_mat_inv[4][4];
- invert_m4_m4(local_mat_inv, ss->cache->stroke_local_mat);
- GPU_matrix_mul(ss->cache->stroke_local_mat);
+ float local_mat[4][4];
+ copy_m4_m4(local_mat, ss->cache->stroke_local_mat);
+
+ if (ss->cache->brush->cloth_deform_type == BRUSH_CLOTH_DEFORM_GRAB) {
+ add_v3_v3v3(local_mat[3], ss->cache->true_location, ss->cache->grab_delta);
+ }
+
+ GPU_matrix_mul(local_mat);
const float dist = ss->cache->radius;
const float arrow_x = ss->cache->radius * 0.2f;
@@ -1274,7 +1314,7 @@ static EnumPropertyItem prop_cloth_filter_type[] = {
"SCALE",
0,
"Scale",
- "Scales the mesh as a softbody using the origin of the object as scale"},
+ "Scales the mesh as a soft-body using the origin of the object as scale"},
{0, NULL, 0, NULL, NULL},
};
diff --git a/source/blender/editors/sculpt_paint/sculpt_face_set.c b/source/blender/editors/sculpt_paint/sculpt_face_set.c
index af6a06caf69..3c87407b2db 100644
--- a/source/blender/editors/sculpt_paint/sculpt_face_set.c
+++ b/source/blender/editors/sculpt_paint/sculpt_face_set.c
@@ -1018,6 +1018,7 @@ void SCULPT_OT_face_sets_randomize_colors(wmOperatorType *ot)
typedef enum eSculptFaceSetEditMode {
SCULPT_FACE_SET_EDIT_GROW = 0,
SCULPT_FACE_SET_EDIT_SHRINK = 1,
+ SCULPT_FACE_SET_EDIT_DELETE_GEOMETRY = 2,
} eSculptFaceSetEditMode;
static EnumPropertyItem prop_sculpt_face_sets_edit_types[] = {
@@ -1035,6 +1036,13 @@ static EnumPropertyItem prop_sculpt_face_sets_edit_types[] = {
"Shrink Face Set",
"Shrinks the Face Sets boundary by one face based on mesh topology",
},
+ {
+ SCULPT_FACE_SET_EDIT_DELETE_GEOMETRY,
+ "DELETE_GEOMETRY",
+ 0,
+ "Delete Geometry",
+ "Deletes the faces that are assigned to the Face Set",
+ },
{0, NULL, 0, NULL, NULL},
};
@@ -1096,6 +1104,78 @@ static void sculpt_face_set_shrink(Object *ob,
}
}
+static bool check_single_face_set(SculptSession *ss, int *face_sets, const bool check_visible_only)
+{
+
+ int first_face_set = SCULPT_FACE_SET_NONE;
+ if (check_visible_only) {
+ for (int f = 0; f < ss->totfaces; f++) {
+ if (face_sets[f] > 0) {
+ first_face_set = face_sets[f];
+ break;
+ }
+ }
+ }
+ else {
+ first_face_set = abs(face_sets[0]);
+ }
+
+ if (first_face_set == SCULPT_FACE_SET_NONE) {
+ return true;
+ }
+
+ for (int f = 0; f < ss->totfaces; f++) {
+ const int face_set_id = check_visible_only ? face_sets[f] : abs(face_sets[f]);
+ if (face_set_id != first_face_set) {
+ return false;
+ }
+ }
+ return true;
+}
+
+static void sculpt_face_set_delete_geometry(Object *ob,
+ SculptSession *ss,
+ const int active_face_set_id,
+ const bool modify_hidden)
+{
+
+ Mesh *mesh = ob->data;
+ const BMAllocTemplate allocsize = BMALLOC_TEMPLATE_FROM_ME(mesh);
+ BMesh *bm = BM_mesh_create(&allocsize,
+ &((struct BMeshCreateParams){
+ .use_toolflags = true,
+ }));
+
+ BM_mesh_bm_from_me(bm,
+ mesh,
+ (&(struct BMeshFromMeshParams){
+ .calc_face_normal = true,
+ }));
+
+ BM_mesh_elem_table_init(bm, BM_FACE);
+ BM_mesh_elem_table_ensure(bm, BM_FACE);
+ BM_mesh_elem_hflag_disable_all(bm, BM_VERT | BM_EDGE | BM_FACE, BM_ELEM_TAG, false);
+ BMIter iter;
+ BMFace *f;
+ BM_ITER_MESH (f, &iter, bm, BM_FACES_OF_MESH) {
+ const int face_index = BM_elem_index_get(f);
+ const int face_set_id = modify_hidden ? abs(ss->face_sets[face_index]) :
+ ss->face_sets[face_index];
+ BM_elem_flag_set(f, BM_ELEM_TAG, face_set_id == active_face_set_id);
+ }
+ BM_mesh_delete_hflag_context(bm, BM_ELEM_TAG, DEL_FACES);
+ BM_mesh_elem_hflag_disable_all(bm, BM_VERT | BM_EDGE | BM_FACE, BM_ELEM_TAG, false);
+
+ BM_mesh_bm_to_me(NULL,
+ bm,
+ ob->data,
+ (&(struct BMeshToMeshParams){
+ .calc_object_remap = false,
+ }));
+
+ BM_mesh_free(bm);
+}
+
static void sculpt_face_set_apply_edit(Object *ob,
const int active_face_set_id,
const int mode,
@@ -1103,80 +1183,135 @@ static void sculpt_face_set_apply_edit(Object *ob,
{
SculptSession *ss = ob->sculpt;
- int *prev_face_sets = MEM_dupallocN(ss->face_sets);
-
switch (mode) {
- case SCULPT_FACE_SET_EDIT_GROW:
+ case SCULPT_FACE_SET_EDIT_GROW: {
+ int *prev_face_sets = MEM_dupallocN(ss->face_sets);
sculpt_face_set_grow(ob, ss, prev_face_sets, active_face_set_id, modify_hidden);
+ MEM_SAFE_FREE(prev_face_sets);
break;
- case SCULPT_FACE_SET_EDIT_SHRINK:
+ }
+ case SCULPT_FACE_SET_EDIT_SHRINK: {
+ int *prev_face_sets = MEM_dupallocN(ss->face_sets);
sculpt_face_set_shrink(ob, ss, prev_face_sets, active_face_set_id, modify_hidden);
+ MEM_SAFE_FREE(prev_face_sets);
+ break;
+ }
+ case SCULPT_FACE_SET_EDIT_DELETE_GEOMETRY:
+ sculpt_face_set_delete_geometry(ob, ss, active_face_set_id, modify_hidden);
break;
}
-
- MEM_SAFE_FREE(prev_face_sets);
}
-static int sculpt_face_set_edit_invoke(bContext *C, wmOperator *op, const wmEvent *event)
+static bool sculpt_face_set_edit_is_operation_valid(SculptSession *ss,
+ const eSculptFaceSetEditMode mode,
+ const bool modify_hidden)
{
- Object *ob = CTX_data_active_object(C);
- SculptSession *ss = ob->sculpt;
- Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C);
-
- const int mode = RNA_enum_get(op->ptr, "mode");
-
- /* Dyntopo not supported. */
if (BKE_pbvh_type(ss->pbvh) == PBVH_BMESH) {
+ /* Dyntopo is not supported. */
return OPERATOR_CANCELLED;
}
- /* Ignore other events to avoid repeated operations. */
- if (event->val != KM_PRESS) {
- return OPERATOR_CANCELLED;
+ if (mode == SCULPT_FACE_SET_EDIT_DELETE_GEOMETRY) {
+ if (BKE_pbvh_type(ss->pbvh) == PBVH_GRIDS) {
+ /* Modification of base mesh geometry requires special remapping of multires displacement,
+ * which does not happen here.
+ * Disable delete operation. It can be supported in the future by doing similar displacement
+ * data remapping as what happens in the mesh edit mode. */
+ return false;
+ }
+ if (check_single_face_set(ss, ss->face_sets, !modify_hidden)) {
+ /* Cancel the operator if the mesh only contains one Face Set to avoid deleting the
+ * entire object. */
+ return false;
+ }
}
+ return true;
+}
- BKE_sculpt_update_object_for_edit(depsgraph, ob, true, false, false);
+static void sculpt_face_set_edit_modify_geometry(bContext *C,
+ Object *ob,
+ const int active_face_set,
+ const eSculptFaceSetEditMode mode,
+ const bool modify_hidden)
+{
+ ED_sculpt_undo_geometry_begin(ob, "edit face set delete geometry");
+ sculpt_face_set_apply_edit(ob, abs(active_face_set), mode, modify_hidden);
+ ED_sculpt_undo_geometry_end(ob);
+ BKE_mesh_batch_cache_dirty_tag(ob->data, BKE_MESH_BATCH_DIRTY_ALL);
+ DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
+ WM_event_add_notifier(C, NC_GEOM | ND_DATA, ob->data);
+}
- /* Update the current active Face Set and Vertex as the operator can be used directly from the
- * tool without brush cursor. */
- SculptCursorGeometryInfo sgi;
- float mouse[2];
- mouse[0] = event->mval[0];
- mouse[1] = event->mval[1];
- SCULPT_cursor_geometry_info_update(C, &sgi, mouse, false);
+static void face_set_edit_do_post_visibility_updates(Object *ob, PBVHNode **nodes, int totnode)
+{
+ SculptSession *ss = ob->sculpt;
+ PBVH *pbvh = ss->pbvh;
+
+ /* Sync face sets visibility and vertex visibility as now all Face Sets are visible. */
+ SCULPT_visibility_sync_all_face_sets_to_vertices(ob);
+
+ for (int i = 0; i < totnode; i++) {
+ BKE_pbvh_node_mark_update_visibility(nodes[i]);
+ }
+
+ BKE_pbvh_update_vertex_data(ss->pbvh, PBVH_UpdateVisibility);
+
+ if (BKE_pbvh_type(pbvh) == PBVH_FACES) {
+ BKE_mesh_flush_hidden_from_verts(ob->data);
+ }
+}
+static void sculpt_face_set_edit_modify_face_sets(Object *ob,
+ const int active_face_set,
+ const eSculptFaceSetEditMode mode,
+ const bool modify_hidden)
+{
PBVH *pbvh = ob->sculpt->pbvh;
PBVHNode **nodes;
int totnode;
BKE_pbvh_search_gather(pbvh, NULL, NULL, &nodes, &totnode);
if (!nodes) {
- return OPERATOR_CANCELLED;
+ return;
}
-
SCULPT_undo_push_begin("face set edit");
SCULPT_undo_push_node(ob, nodes[0], SCULPT_UNDO_FACE_SETS);
-
- const int active_face_set = SCULPT_active_face_set_get(ss);
- const bool modify_hidden = RNA_boolean_get(op->ptr, "modify_hidden");
-
sculpt_face_set_apply_edit(ob, abs(active_face_set), mode, modify_hidden);
-
SCULPT_undo_push_end();
+ face_set_edit_do_post_visibility_updates(ob, nodes, totnode);
+ MEM_freeN(nodes);
+}
- /* Sync face sets visibility and vertex visibility as now all Face Sets are visible. */
- SCULPT_visibility_sync_all_face_sets_to_vertices(ob);
+static int sculpt_face_set_edit_invoke(bContext *C, wmOperator *op, const wmEvent *event)
+{
+ Object *ob = CTX_data_active_object(C);
+ SculptSession *ss = ob->sculpt;
+ Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C);
- for (int i = 0; i < totnode; i++) {
- BKE_pbvh_node_mark_update_visibility(nodes[i]);
+ const int mode = RNA_enum_get(op->ptr, "mode");
+ const bool modify_hidden = RNA_boolean_get(op->ptr, "modify_hidden");
+
+ if (!sculpt_face_set_edit_is_operation_valid(ss, mode, modify_hidden)) {
+ return OPERATOR_CANCELLED;
}
- BKE_pbvh_update_vertex_data(ss->pbvh, PBVH_UpdateVisibility);
+ BKE_sculpt_update_object_for_edit(depsgraph, ob, true, false, false);
- MEM_SAFE_FREE(nodes);
+ /* Update the current active Face Set and Vertex as the operator can be used directly from the
+ * tool without brush cursor. */
+ SculptCursorGeometryInfo sgi;
+ const float mouse[2] = {event->mval[0], event->mval[1]};
+ SCULPT_cursor_geometry_info_update(C, &sgi, mouse, false);
+ const int active_face_set = SCULPT_active_face_set_get(ss);
- if (BKE_pbvh_type(pbvh) == PBVH_FACES) {
- BKE_mesh_flush_hidden_from_verts(ob->data);
+ switch (mode) {
+ case SCULPT_FACE_SET_EDIT_DELETE_GEOMETRY:
+ sculpt_face_set_edit_modify_geometry(C, ob, active_face_set, mode, modify_hidden);
+ break;
+ case SCULPT_FACE_SET_EDIT_GROW:
+ case SCULPT_FACE_SET_EDIT_SHRINK:
+ sculpt_face_set_edit_modify_face_sets(ob, active_face_set, mode, modify_hidden);
+ break;
}
SCULPT_tag_update_overlays(C);
diff --git a/source/blender/editors/space_clip/tracking_ops.c b/source/blender/editors/space_clip/tracking_ops.c
index 0631b6ea8a0..4d3e6cf4d6a 100644
--- a/source/blender/editors/space_clip/tracking_ops.c
+++ b/source/blender/editors/space_clip/tracking_ops.c
@@ -1043,13 +1043,13 @@ static int clear_track_path_exec(bContext *C, wmOperator *op)
void CLIP_OT_clear_track_path(wmOperatorType *ot)
{
static const EnumPropertyItem clear_path_actions[] = {
- {TRACK_CLEAR_UPTO, "UPTO", 0, "Clear up-to", "Clear path up to current frame"},
+ {TRACK_CLEAR_UPTO, "UPTO", 0, "Clear Up To", "Clear path up to current frame"},
{TRACK_CLEAR_REMAINED,
"REMAINED",
0,
- "Clear remained",
+ "Clear Remained",
"Clear path at remaining frames (after current)"},
- {TRACK_CLEAR_ALL, "ALL", 0, "Clear all", "Clear the whole path"},
+ {TRACK_CLEAR_ALL, "ALL", 0, "Clear All", "Clear the whole path"},
{0, NULL, 0, NULL, NULL},
};
diff --git a/source/blender/editors/space_clip/tracking_select.c b/source/blender/editors/space_clip/tracking_select.c
index 478d22c7582..063ea9592aa 100644
--- a/source/blender/editors/space_clip/tracking_select.c
+++ b/source/blender/editors/space_clip/tracking_select.c
@@ -975,15 +975,15 @@ static int select_grouped_exec(bContext *C, wmOperator *op)
void CLIP_OT_select_grouped(wmOperatorType *ot)
{
static const EnumPropertyItem select_group_items[] = {
- {0, "KEYFRAMED", 0, "Keyframed tracks", "Select all keyframed tracks"},
- {1, "ESTIMATED", 0, "Estimated tracks", "Select all estimated tracks"},
- {2, "TRACKED", 0, "Tracked tracks", "Select all tracked tracks"},
- {3, "LOCKED", 0, "Locked tracks", "Select all locked tracks"},
- {4, "DISABLED", 0, "Disabled tracks", "Select all disabled tracks"},
+ {0, "KEYFRAMED", 0, "Keyframed Tracks", "Select all keyframed tracks"},
+ {1, "ESTIMATED", 0, "Estimated Tracks", "Select all estimated tracks"},
+ {2, "TRACKED", 0, "Tracked Tracks", "Select all tracked tracks"},
+ {3, "LOCKED", 0, "Locked Tracks", "Select all locked tracks"},
+ {4, "DISABLED", 0, "Disabled Tracks", "Select all disabled tracks"},
{5,
"COLOR",
0,
- "Tracks with same color",
+ "Tracks with Same Color",
"Select all tracks with same color as active track"},
{6, "FAILED", 0, "Failed Tracks", "Select all tracks which failed to be reconstructed"},
{0, NULL, 0, NULL, NULL},
diff --git a/source/blender/editors/space_sequencer/sequencer_edit.c b/source/blender/editors/space_sequencer/sequencer_edit.c
index 8a705ef49dd..9554608ea7c 100644
--- a/source/blender/editors/space_sequencer/sequencer_edit.c
+++ b/source/blender/editors/space_sequencer/sequencer_edit.c
@@ -97,11 +97,11 @@ EnumPropertyItem sequencer_prop_effect_types[] = {
#define SEQ_SIDE_MOUSE -1
EnumPropertyItem prop_side_types[] = {
- {SEQ_SIDE_MOUSE, "MOUSE", 0, "Mouse position", ""},
+ {SEQ_SIDE_MOUSE, "MOUSE", 0, "Mouse Position", ""},
{SEQ_SIDE_LEFT, "LEFT", 0, "Left", ""},
{SEQ_SIDE_RIGHT, "RIGHT", 0, "Right", ""},
{SEQ_SIDE_BOTH, "BOTH", 0, "Both", ""},
- {SEQ_SIDE_NO_CHANGE, "NO_CHANGE", 0, "No change", ""},
+ {SEQ_SIDE_NO_CHANGE, "NO_CHANGE", 0, "No Change", ""},
{0, NULL, 0, NULL, NULL},
};
diff --git a/source/blender/editors/space_text/text_ops.c b/source/blender/editors/space_text/text_ops.c
index 5c7f84ea386..3c3b11f0786 100644
--- a/source/blender/editors/space_text/text_ops.c
+++ b/source/blender/editors/space_text/text_ops.c
@@ -409,7 +409,7 @@ void TEXT_OT_open(wmOperatorType *ot)
FILE_DEFAULTDISPLAY,
FILE_SORT_ALPHA); /* TODO: relative_path. */
RNA_def_boolean(
- ot->srna, "internal", 0, "Make internal", "Make text file internal after loading");
+ ot->srna, "internal", 0, "Make Internal", "Make text file internal after loading");
}
/** \} */
@@ -3693,7 +3693,7 @@ void TEXT_OT_replace(wmOperatorType *ot)
/* properties */
PropertyRNA *prop;
- prop = RNA_def_boolean(ot->srna, "all", false, "Replace all", "Replace all occurrences");
+ prop = RNA_def_boolean(ot->srna, "all", false, "Replace All", "Replace all occurrences");
RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
}
diff --git a/source/blender/editors/space_view3d/view3d_buttons.c b/source/blender/editors/space_view3d/view3d_buttons.c
index 8e03ed6e11d..f67eb73bbd1 100644
--- a/source/blender/editors/space_view3d/view3d_buttons.c
+++ b/source/blender/editors/space_view3d/view3d_buttons.c
@@ -283,7 +283,6 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float
else if (ob->type == OB_CURVE || ob->type == OB_SURF) {
TransformMedian_Curve *median = &median_basis.curve;
Curve *cu = ob->data;
- Nurb *nu;
BPoint *bp;
BezTriple *bezt;
int a;
@@ -291,8 +290,7 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float
StructRNA *seltype = NULL;
void *selp = NULL;
- nu = nurbs->first;
- while (nu) {
+ LISTBASE_FOREACH (Nurb *, nu, nurbs) {
if (nu->type == CU_BEZIER) {
bezt = nu->bezt;
a = nu->pntsu;
@@ -343,7 +341,6 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float
bp++;
}
}
- nu = nu->next;
}
if (totcurvedata == 1) {
@@ -973,15 +970,13 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float
const TransformMedian_Curve *median = &median_basis.curve,
*ve_median = &ve_median_basis.curve;
Curve *cu = ob->data;
- Nurb *nu;
BPoint *bp;
BezTriple *bezt;
int a;
ListBase *nurbs = BKE_curve_editNurbs_get(cu);
const float scale_w = compute_scale_factor(ve_median->weight, median->weight);
- nu = nurbs->first;
- while (nu) {
+ LISTBASE_FOREACH (Nurb *, nu, nurbs) {
if (nu->type == CU_BEZIER) {
for (a = nu->pntsu, bezt = nu->bezt; a--; bezt++) {
if (bezt->f2 & SELECT) {
@@ -1038,8 +1033,6 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float
}
BKE_nurb_test_2d(nu);
BKE_nurb_handles_test(nu, true, false); /* test for bezier too */
-
- nu = nu->next;
}
}
else if ((ob->type == OB_LATTICE) && (apply_vcos || median_basis.lattice.weight)) {
diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c
index 4e08b6b1c5d..1b1740cd5bc 100644
--- a/source/blender/editors/transform/transform.c
+++ b/source/blender/editors/transform/transform.c
@@ -646,12 +646,12 @@ wmKeyMap *transform_modal_keymap(wmKeyConfig *keyconf)
static const EnumPropertyItem modal_items[] = {
{TFM_MODAL_CONFIRM, "CONFIRM", 0, "Confirm", ""},
{TFM_MODAL_CANCEL, "CANCEL", 0, "Cancel", ""},
- {TFM_MODAL_AXIS_X, "AXIS_X", 0, "X axis", ""},
- {TFM_MODAL_AXIS_Y, "AXIS_Y", 0, "Y axis", ""},
- {TFM_MODAL_AXIS_Z, "AXIS_Z", 0, "Z axis", ""},
- {TFM_MODAL_PLANE_X, "PLANE_X", 0, "X plane", ""},
- {TFM_MODAL_PLANE_Y, "PLANE_Y", 0, "Y plane", ""},
- {TFM_MODAL_PLANE_Z, "PLANE_Z", 0, "Z plane", ""},
+ {TFM_MODAL_AXIS_X, "AXIS_X", 0, "X Axis", ""},
+ {TFM_MODAL_AXIS_Y, "AXIS_Y", 0, "Y Axis", ""},
+ {TFM_MODAL_AXIS_Z, "AXIS_Z", 0, "Z Axis", ""},
+ {TFM_MODAL_PLANE_X, "PLANE_X", 0, "X Plane", ""},
+ {TFM_MODAL_PLANE_Y, "PLANE_Y", 0, "Y Plane", ""},
+ {TFM_MODAL_PLANE_Z, "PLANE_Z", 0, "Z Plane", ""},
{TFM_MODAL_CONS_OFF, "CONS_OFF", 0, "Clear Constraints", ""},
{TFM_MODAL_SNAP_INV_ON, "SNAP_INV_ON", 0, "Snap Invert", ""},
{TFM_MODAL_SNAP_INV_OFF, "SNAP_INV_OFF", 0, "Snap Invert (Off)", ""},
@@ -672,13 +672,13 @@ wmKeyMap *transform_modal_keymap(wmKeyConfig *keyconf)
0,
"Decrease Max AutoIK Chain Length",
""},
- {TFM_MODAL_EDGESLIDE_UP, "EDGESLIDE_EDGE_NEXT", 0, "Select next Edge Slide Edge", ""},
- {TFM_MODAL_EDGESLIDE_DOWN, "EDGESLIDE_PREV_NEXT", 0, "Select previous Edge Slide Edge", ""},
+ {TFM_MODAL_EDGESLIDE_UP, "EDGESLIDE_EDGE_NEXT", 0, "Select Next Edge Slide Edge", ""},
+ {TFM_MODAL_EDGESLIDE_DOWN, "EDGESLIDE_PREV_NEXT", 0, "Select Previous Edge Slide Edge", ""},
{TFM_MODAL_PROPSIZE, "PROPORTIONAL_SIZE", 0, "Adjust Proportional Influence", ""},
{TFM_MODAL_INSERTOFS_TOGGLE_DIR,
"INSERTOFS_TOGGLE_DIR",
0,
- "Toggle Direction for Node Auto-offset",
+ "Toggle Direction for Node Auto-Offset",
""},
{TFM_MODAL_TRANSLATE, "TRANSLATE", 0, "Move", ""},
{TFM_MODAL_ROTATE, "ROTATE", 0, "Rotate", ""},
diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpencilarmature.c b/source/blender/gpencil_modifiers/intern/MOD_gpencilarmature.c
index aee345757c6..c67d622ffec 100644
--- a/source/blender/gpencil_modifiers/intern/MOD_gpencilarmature.c
+++ b/source/blender/gpencil_modifiers/intern/MOD_gpencilarmature.c
@@ -215,7 +215,7 @@ static void panel_draw(const bContext *UNUSED(C), Panel *panel)
uiLayoutSetPropDecorate(sub, false);
uiItemR(sub, ptr, "invert_vertex_group", 0, "", ICON_ARROW_LEFTRIGHT);
- col = uiLayoutColumnWithHeading(layout, true, IFACE_("Bind to"));
+ col = uiLayoutColumnWithHeading(layout, true, IFACE_("Bind To"));
uiItemR(col, ptr, "use_vertex_groups", 0, IFACE_("Vertex Groups"), ICON_NONE);
uiItemR(col, ptr, "use_bone_envelopes", 0, IFACE_("Bone Envelopes"), ICON_NONE);
diff --git a/source/blender/gpu/CMakeLists.txt b/source/blender/gpu/CMakeLists.txt
index 482e4086452..92f540f859f 100644
--- a/source/blender/gpu/CMakeLists.txt
+++ b/source/blender/gpu/CMakeLists.txt
@@ -44,6 +44,7 @@ set(INC
../nodes
../nodes/intern
+ ../../../intern/clog
../../../intern/ghost
../../../intern/glew-mx
../../../intern/guardedalloc
diff --git a/source/blender/gpu/intern/gpu_debug.cc b/source/blender/gpu/intern/gpu_debug.cc
index d7944f0de50..63e7024b74b 100644
--- a/source/blender/gpu/intern/gpu_debug.cc
+++ b/source/blender/gpu/intern/gpu_debug.cc
@@ -74,7 +74,7 @@ void GPU_debug_get_groups_names(int name_buf_len, char *r_name_buf)
for (StringRef &name : stack) {
sz += BLI_snprintf_rlen(r_name_buf + sz, name_buf_len - sz, "%s > ", name.data());
}
- r_name_buf[sz - 2] = ':';
+ r_name_buf[sz - 3] = '\0';
}
/* Return true if inside a debug group with the same name. */
diff --git a/source/blender/gpu/intern/gpu_shader.cc b/source/blender/gpu/intern/gpu_shader.cc
index 05c81c2efeb..5f46f57c09a 100644
--- a/source/blender/gpu/intern/gpu_shader.cc
+++ b/source/blender/gpu/intern/gpu_shader.cc
@@ -23,6 +23,7 @@
#include "MEM_guardedalloc.h"
+#include "BLI_dynstr.h"
#include "BLI_math_base.h"
#include "BLI_math_vector.h"
#include "BLI_path_util.h"
@@ -47,8 +48,12 @@
#include "gpu_context_private.hh"
#include "gpu_shader_private.hh"
+#include "CLG_log.h"
+
extern "C" char datatoc_gpu_shader_colorspace_lib_glsl[];
+static CLG_LogRef LOG = {"gpu.shader"};
+
using namespace blender;
using namespace blender::gpu;
@@ -56,12 +61,21 @@ using namespace blender::gpu;
/** \name Debug functions
* \{ */
-void Shader::print_errors(Span<const char *> sources, char *log, const char *stage)
+void Shader::print_log(Span<const char *> sources, char *log, const char *stage, const bool error)
{
const char line_prefix[] = " | ";
+ char err_col[] = "\033[31;1m";
+ char warn_col[] = "\033[33;1m";
+ char info_col[] = "\033[0;2m";
+ char reset_col[] = "\033[0;0m";
char *sources_combined = BLI_string_join_arrayN((const char **)sources.data(), sources.size());
+ DynStr *dynstr = BLI_dynstr_new();
+
+ if (!CLG_color_support_get(&LOG)) {
+ err_col[0] = warn_col[0] = info_col[0] = reset_col[0] = '\0';
+ }
- fprintf(stderr, "GPUShader: Compilation Log : %s : %s\n", this->name, stage);
+ BLI_dynstr_appendf(dynstr, "\n");
char *log_line = log, *line_end;
char *error_line_number_end;
@@ -136,10 +150,10 @@ void Shader::print_errors(Span<const char *> sources, char *log, const char *sta
}
/* Separate from previous block. */
if (last_error_line != error_line) {
- fprintf(stderr, "\033[90m%s\033[39m\n", line_prefix);
+ BLI_dynstr_appendf(dynstr, "%s%s%s\n", info_col, line_prefix, reset_col);
}
else if (error_char != last_error_char) {
- fprintf(stderr, "%s\n", line_prefix);
+ BLI_dynstr_appendf(dynstr, "%s\n", line_prefix);
}
/* Print line from the source file that is producing the error. */
if ((error_line != -1) && (error_line != last_error_line || error_char != last_error_char)) {
@@ -159,24 +173,24 @@ void Shader::print_errors(Span<const char *> sources, char *log, const char *sta
/* Print error source. */
if (found_line_id) {
if (error_line != last_error_line) {
- fprintf(stderr, "%5d | ", src_line_index);
+ BLI_dynstr_appendf(dynstr, "%5d | ", src_line_index);
}
else {
- fprintf(stderr, line_prefix);
+ BLI_dynstr_appendf(dynstr, line_prefix);
}
- fwrite(src_line, (src_line_end + 1) - src_line, 1, stderr);
+ BLI_dynstr_nappend(dynstr, src_line, (src_line_end + 1) - src_line);
/* Print char offset. */
- fprintf(stderr, line_prefix);
+ BLI_dynstr_appendf(dynstr, line_prefix);
if (error_char != -1) {
for (int i = 0; i < error_char; i++) {
- fprintf(stderr, " ");
+ BLI_dynstr_appendf(dynstr, " ");
}
- fprintf(stderr, "^");
+ BLI_dynstr_appendf(dynstr, "^");
}
- fprintf(stderr, "\n");
+ BLI_dynstr_appendf(dynstr, "\n");
}
}
- fprintf(stderr, line_prefix);
+ BLI_dynstr_appendf(dynstr, line_prefix);
/* Skip to message. Avoid redundant info. */
const char *keywords[] = {"error", "warning"};
for (int i = 0; i < ARRAY_SIZE(prefix); i++) {
@@ -191,22 +205,32 @@ void Shader::print_errors(Span<const char *> sources, char *log, const char *sta
log_line++;
}
if (type == 0) {
- fprintf(stderr, "\033[31;1mError\033[0;2m: ");
+ BLI_dynstr_appendf(dynstr, "%s%s%s: ", err_col, "Error", info_col);
}
else if (type == 1) {
- fprintf(stderr, "\033[33;1mWarning\033[0;2m: ");
+ BLI_dynstr_appendf(dynstr, "%s%s%s: ", warn_col, "Warning", info_col);
}
/* Print the error itself. */
- fprintf(stderr, "\033[2m");
- fwrite(log_line, (line_end + 1) - log_line, 1, stderr);
- fprintf(stderr, "\033[0m");
+ BLI_dynstr_appendf(dynstr, info_col);
+ BLI_dynstr_nappend(dynstr, log_line, (line_end + 1) - log_line);
+ BLI_dynstr_appendf(dynstr, reset_col);
/* Continue to next line. */
log_line = line_end + 1;
last_error_line = error_line;
last_error_char = error_char;
}
- fprintf(stderr, "\n");
MEM_freeN(sources_combined);
+
+ CLG_Severity severity = error ? CLG_SEVERITY_ERROR : CLG_SEVERITY_WARN;
+
+ if (((LOG.type->flag & CLG_FLAG_USE) && (LOG.type->level >= 0)) ||
+ (severity >= CLG_SEVERITY_WARN)) {
+ const char *_str = BLI_dynstr_get_cstring(dynstr);
+ CLG_log_str(LOG.type, severity, this->name, stage, _str);
+ MEM_freeN((void *)_str);
+ }
+
+ BLI_dynstr_free(dynstr);
}
/** \} */
diff --git a/source/blender/gpu/intern/gpu_shader_interface.cc b/source/blender/gpu/intern/gpu_shader_interface.cc
index 4a7c7bc15a3..e5fb8025e7f 100644
--- a/source/blender/gpu/intern/gpu_shader_interface.cc
+++ b/source/blender/gpu/intern/gpu_shader_interface.cc
@@ -85,7 +85,6 @@ void ShaderInterface::debug_print(void)
char *name_buf = name_buffer_;
const char format[] = " | %.8x : %4d : %s\n";
- printf(" \033[1mGPUShaderInterface : \033[0m\n");
if (attrs.size() > 0) {
printf("\n Attributes :\n");
}
diff --git a/source/blender/gpu/intern/gpu_shader_private.hh b/source/blender/gpu/intern/gpu_shader_private.hh
index b7acc0f9353..eac39dccd81 100644
--- a/source/blender/gpu/intern/gpu_shader_private.hh
+++ b/source/blender/gpu/intern/gpu_shader_private.hh
@@ -70,7 +70,7 @@ class Shader {
};
protected:
- void print_errors(Span<const char *> sources, char *log, const char *stage);
+ void print_log(Span<const char *> sources, char *log, const char *stage, const bool error);
};
/* Syntacting suggar. */
diff --git a/source/blender/gpu/opengl/gl_debug.cc b/source/blender/gpu/opengl/gl_debug.cc
index b2b05124463..69289d7602e 100644
--- a/source/blender/gpu/opengl/gl_debug.cc
+++ b/source/blender/gpu/opengl/gl_debug.cc
@@ -33,6 +33,8 @@
#include "GPU_debug.h"
#include "GPU_platform.h"
+#include "CLG_log.h"
+
#include "glew-mx.h"
#include "gl_context.hh"
@@ -42,8 +44,12 @@
#include <stdio.h>
+static CLG_LogRef LOG = {"gpu.debug"};
+
/* Avoid too much NVidia buffer info in the output log. */
#define TRIM_NVIDIA_BUFFER_INFO 1
+/* Avoid unneeded shader statistics. */
+#define TRIM_SHADER_STATS_INFO 1
namespace blender::gpu::debug {
@@ -61,8 +67,6 @@ namespace blender::gpu::debug {
# define APIENTRY
#endif
-#define VERBOSE 1
-
static void APIENTRY debug_callback(GLenum UNUSED(source),
GLenum type,
GLuint UNUSED(id),
@@ -79,43 +83,57 @@ static void APIENTRY debug_callback(GLenum UNUSED(source),
if (TRIM_NVIDIA_BUFFER_INFO &&
GPU_type_matches(GPU_DEVICE_NVIDIA, GPU_OS_ANY, GPU_DRIVER_OFFICIAL) &&
- STREQLEN("Buffer detailed info", message, 20)) {
- /** Supress buffer infos flooding the output. */
+ STRPREFIX(message, "Buffer detailed info")) {
+ /** Suppress buffer infos flooding the output. */
return;
}
- const char format[] = "GPUDebug: %s%s%s\033[0m\n";
+ if (TRIM_SHADER_STATS_INFO && STRPREFIX(message, "Shader Stats")) {
+ /** Suppress buffer infos flooding the output. */
+ return;
+ }
+
+ const bool use_color = CLG_color_support_get(&LOG);
if (ELEM(severity, GL_DEBUG_SEVERITY_LOW, GL_DEBUG_SEVERITY_NOTIFICATION)) {
- if (VERBOSE) {
- fprintf(stderr, format, "\033[2m", "", message);
+ if (((LOG.type->flag & CLG_FLAG_USE) && (LOG.type->level >= CLG_SEVERITY_INFO))) {
+ const char *format = use_color ? "\033[2m%s\033[0m" : "%s";
+ CLG_logf(LOG.type, CLG_SEVERITY_INFO, "Notification", "", format, message);
}
}
else {
char debug_groups[512] = "";
GPU_debug_get_groups_names(sizeof(debug_groups), debug_groups);
+ CLG_Severity clog_severity;
switch (type) {
case GL_DEBUG_TYPE_ERROR:
case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR:
case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR:
- fprintf(stderr, format, "\033[31;1mError\033[39m: ", debug_groups, message);
+ clog_severity = CLG_SEVERITY_ERROR;
break;
case GL_DEBUG_TYPE_PORTABILITY:
case GL_DEBUG_TYPE_PERFORMANCE:
case GL_DEBUG_TYPE_OTHER:
case GL_DEBUG_TYPE_MARKER: /* KHR has this, ARB does not */
default:
- fprintf(stderr, format, "\033[33;1mWarning\033[39m: ", debug_groups, message);
+ clog_severity = CLG_SEVERITY_WARN;
break;
}
- if (VERBOSE && severity == GL_DEBUG_SEVERITY_HIGH) {
- /* Focus on error message. */
- fprintf(stderr, "\033[2m");
- BLI_system_backtrace(stderr);
- fprintf(stderr, "\033[0m\n");
- fflush(stderr);
+ if (((LOG.type->flag & CLG_FLAG_USE) && (LOG.type->level >= clog_severity))) {
+ CLG_logf(LOG.type, clog_severity, debug_groups, "", message);
+ if (severity == GL_DEBUG_SEVERITY_HIGH) {
+ /* Focus on error message. */
+ if (use_color) {
+ fprintf(stderr, "\033[2m");
+ }
+ BLI_system_backtrace(stderr);
+ if (use_color) {
+ fprintf(stderr, "\033[0m\n");
+ }
+ fflush(stderr);
+ }
}
}
}
@@ -125,6 +143,8 @@ static void APIENTRY debug_callback(GLenum UNUSED(source),
/* This function needs to be called once per context. */
void init_gl_callbacks(void)
{
+ CLOG_ENSURE(&LOG);
+
char msg[256] = "";
const char format[] = "Successfully hooked OpenGL debug callback using %s";
@@ -154,7 +174,7 @@ void init_gl_callbacks(void)
msg);
}
else {
- fprintf(stderr, "GPUDebug: Failed to hook OpenGL debug callback. Use fallback debug layer.\n");
+ CLOG_STR_WARN(&LOG, "Failed to hook OpenGL debug callback. Use fallback debug layer.");
init_debug_layer();
}
}
diff --git a/source/blender/gpu/opengl/gl_shader.cc b/source/blender/gpu/opengl/gl_shader.cc
index 9af9bf96503..193e4ee8a70 100644
--- a/source/blender/gpu/opengl/gl_shader.cc
+++ b/source/blender/gpu/opengl/gl_shader.cc
@@ -134,13 +134,13 @@ GLuint GLShader::create_shader_stage(GLenum gl_stage, MutableSpan<const char *>
if (log[0] != '\0') {
switch (gl_stage) {
case GL_VERTEX_SHADER:
- this->print_errors(sources, log, "VertShader");
+ this->print_log(sources, log, "VertShader", !status);
break;
case GL_GEOMETRY_SHADER:
- this->print_errors(sources, log, "GeomShader");
+ this->print_log(sources, log, "GeomShader", !status);
break;
case GL_FRAGMENT_SHADER:
- this->print_errors(sources, log, "FragShader");
+ this->print_log(sources, log, "FragShader", !status);
break;
}
}
@@ -186,7 +186,7 @@ bool GLShader::finalize(void)
char log[5000];
glGetProgramInfoLog(shader_program_, sizeof(log), NULL, log);
Span<const char *> sources;
- this->print_errors(sources, log, "Linking");
+ this->print_log(sources, log, "Linking", true);
return false;
}
diff --git a/source/blender/makesdna/DNA_modifier_types.h b/source/blender/makesdna/DNA_modifier_types.h
index 414c21fd428..a077e3c3f43 100644
--- a/source/blender/makesdna/DNA_modifier_types.h
+++ b/source/blender/makesdna/DNA_modifier_types.h
@@ -2222,6 +2222,10 @@ enum {
typedef struct NodesModifierData {
ModifierData modifier;
struct bNodeTree *node_group;
+
+ /* This property exists only temporary for testing purposes. */
+ float test_float_input;
+ char _pad[4];
} NodesModifierData;
typedef struct MeshToVolumeModifierData {
diff --git a/source/blender/makesrna/intern/rna_action.c b/source/blender/makesrna/intern/rna_action.c
index 89687c1234c..576431b7fd1 100644
--- a/source/blender/makesrna/intern/rna_action.c
+++ b/source/blender/makesrna/intern/rna_action.c
@@ -450,7 +450,7 @@ static void rna_def_dopesheet(BlenderRNA *brna)
prop = RNA_def_property(srna, "show_shapekeys", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_negative_sdna(prop, NULL, "filterflag", ADS_FILTER_NOSHAPEKEYS);
RNA_def_property_ui_text(
- prop, "Display Shapekeys", "Include visualization of shape key related animation data");
+ prop, "Display Shape Keys", "Include visualization of shape key related animation data");
RNA_def_property_ui_icon(prop, ICON_SHAPEKEY_DATA, 0);
RNA_def_property_update(prop, NC_ANIMATION | ND_ANIMCHAN | NA_EDITED, NULL);
diff --git a/source/blender/makesrna/intern/rna_color.c b/source/blender/makesrna/intern/rna_color.c
index 79f2ab70651..b02377f4bb0 100644
--- a/source/blender/makesrna/intern/rna_color.c
+++ b/source/blender/makesrna/intern/rna_color.c
@@ -796,7 +796,7 @@ static void rna_def_curvemapping(BlenderRNA *brna)
static const EnumPropertyItem tone_items[] = {
{CURVE_TONE_STANDARD, "STANDARD", 0, "Standard", ""},
- {CURVE_TONE_FILMLIKE, "FILMLIKE", 0, "Film like", ""},
+ {CURVE_TONE_FILMLIKE, "FILMLIKE", 0, "Filmlike", ""},
{0, NULL, 0, NULL, NULL},
};
diff --git a/source/blender/makesrna/intern/rna_curve.c b/source/blender/makesrna/intern/rna_curve.c
index 2d6bf2897e0..2e73fabe103 100644
--- a/source/blender/makesrna/intern/rna_curve.c
+++ b/source/blender/makesrna/intern/rna_curve.c
@@ -543,11 +543,9 @@ static void rna_Curve_resolution_u_update_data(Main *bmain, Scene *scene, Pointe
{
Curve *cu = (Curve *)ptr->owner_id;
ListBase *nurbs = BKE_curve_nurbs_get(cu);
- Nurb *nu = nurbs->first;
- while (nu) {
+ LISTBASE_FOREACH (Nurb *, nu, nurbs) {
nu->resolu = cu->resolu;
- nu = nu->next;
}
rna_Curve_update_data(bmain, scene, ptr);
@@ -557,11 +555,9 @@ static void rna_Curve_resolution_v_update_data(Main *bmain, Scene *scene, Pointe
{
Curve *cu = (Curve *)ptr->owner_id;
ListBase *nurbs = BKE_curve_nurbs_get(cu);
- Nurb *nu = nurbs->first;
- while (nu) {
+ LISTBASE_FOREACH (Nurb *, nu, nurbs) {
nu->resolv = cu->resolv;
- nu = nu->next;
}
rna_Curve_update_data(bmain, scene, ptr);
diff --git a/source/blender/makesrna/intern/rna_modifier.c b/source/blender/makesrna/intern/rna_modifier.c
index 7715a35af76..af5892d8933 100644
--- a/source/blender/makesrna/intern/rna_modifier.c
+++ b/source/blender/makesrna/intern/rna_modifier.c
@@ -6941,6 +6941,10 @@ static void rna_def_modifier_nodes(BlenderRNA *brna)
RNA_def_property_flag(prop, PROP_EDITABLE);
RNA_def_property_update(prop, 0, "rna_Modifier_dependency_update");
+ prop = RNA_def_property(srna, "test_float_input", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_ui_text(prop, "Float Input", "Temporary float input for testing purposes");
+ RNA_def_property_update(prop, 0, "rna_Modifier_dependency_update");
+
RNA_define_lib_overridable(false);
}
# endif
diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c
index b0f039c5b21..3c69db0efcc 100644
--- a/source/blender/makesrna/intern/rna_nodetree.c
+++ b/source/blender/makesrna/intern/rna_nodetree.c
@@ -4789,7 +4789,7 @@ static void def_sh_tex_voronoi(StructRNA *srna)
{SHD_VORONOI_DISTANCE_TO_EDGE,
"DISTANCE_TO_EDGE",
0,
- "Distance To Edge",
+ "Distance to Edge",
"Computes the distance to the edge of the voronoi cell"},
{SHD_VORONOI_N_SPHERE_RADIUS,
"N_SPHERE_RADIUS",
@@ -7726,15 +7726,15 @@ static void def_cmp_viewer(StructRNA *srna)
static const EnumPropertyItem tileorder_items[] = {
{0, "CENTEROUT", 0, "Center", "Expand from center"},
{1, "RANDOM", 0, "Random", "Random tiles"},
- {2, "BOTTOMUP", 0, "Bottom up", "Expand from bottom"},
- {3, "RULE_OF_THIRDS", 0, "Rule of thirds", "Expand from 9 places"},
+ {2, "BOTTOMUP", 0, "Bottom Up", "Expand from bottom"},
+ {3, "RULE_OF_THIRDS", 0, "Rule of Thirds", "Expand from 9 places"},
{0, NULL, 0, NULL, NULL},
};
prop = RNA_def_property(srna, "tile_order", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "custom1");
RNA_def_property_enum_items(prop, tileorder_items);
- RNA_def_property_ui_text(prop, "Tile order", "Tile order");
+ RNA_def_property_ui_text(prop, "Tile Order", "Tile order");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
prop = RNA_def_property(srna, "center_x", PROP_FLOAT, PROP_NONE);
diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c
index 24cff501b59..62d5917bc10 100644
--- a/source/blender/makesrna/intern/rna_scene.c
+++ b/source/blender/makesrna/intern/rna_scene.c
@@ -379,7 +379,7 @@ const EnumPropertyItem rna_enum_image_type_items[] = {
{R_IMF_IMTYPE_FFMPEG,
"FFMPEG",
ICON_FILE_MOVIE,
- "FFmpeg video",
+ "FFmpeg Video",
"The most versatile way to output video files"},
#endif
{0, NULL, 0, NULL, NULL},
@@ -2864,13 +2864,13 @@ static void rna_def_tool_settings(BlenderRNA *brna)
};
static const EnumPropertyItem gpencil_stroke_snap_items[] = {
- {0, "NONE", 0, "All points", "Snap to all points"},
+ {0, "NONE", 0, "All Points", "Snap to all points"},
{GP_PROJECT_DEPTH_STROKE_ENDPOINTS,
"ENDS",
0,
- "End points",
+ "End Points",
"Snap to first and last points and interpolate"},
- {GP_PROJECT_DEPTH_STROKE_FIRST, "FIRST", 0, "First point", "Snap to first point"},
+ {GP_PROJECT_DEPTH_STROKE_FIRST, "FIRST", 0, "First Point", "Snap to first point"},
{0, NULL, 0, NULL, NULL},
};
@@ -5510,12 +5510,12 @@ static void rna_def_scene_ffmpeg_settings(BlenderRNA *brna)
"Constant Bitrate",
"Configure constant bit rate, rather than constant output quality"},
{FFM_CRF_LOSSLESS, "LOSSLESS", 0, "Lossless", ""},
- {FFM_CRF_PERC_LOSSLESS, "PERC_LOSSLESS", 0, "Perceptually lossless", ""},
- {FFM_CRF_HIGH, "HIGH", 0, "High quality", ""},
- {FFM_CRF_MEDIUM, "MEDIUM", 0, "Medium quality", ""},
- {FFM_CRF_LOW, "LOW", 0, "Low quality", ""},
- {FFM_CRF_VERYLOW, "VERYLOW", 0, "Very low quality", ""},
- {FFM_CRF_LOWEST, "LOWEST", 0, "Lowest quality", ""},
+ {FFM_CRF_PERC_LOSSLESS, "PERC_LOSSLESS", 0, "Perceptually Lossless", ""},
+ {FFM_CRF_HIGH, "HIGH", 0, "High Quality", ""},
+ {FFM_CRF_MEDIUM, "MEDIUM", 0, "Medium Quality", ""},
+ {FFM_CRF_LOW, "LOW", 0, "Low Quality", ""},
+ {FFM_CRF_VERYLOW, "VERYLOW", 0, "Very Low Quality", ""},
+ {FFM_CRF_LOWEST, "LOWEST", 0, "Lowest Quality", ""},
{0, NULL, 0, NULL, NULL},
};
@@ -5738,7 +5738,7 @@ static void rna_def_scene_render_data(BlenderRNA *brna)
{0,
"AUTO",
0,
- "Auto-detect",
+ "Auto-Detect",
"Automatically determine the number of threads, based on CPUs"},
{R_FIXED_THREADS, "FIXED", 0, "Fixed", "Manually determine the number of threads"},
{0, NULL, 0, NULL, NULL},
diff --git a/source/blender/makesrna/intern/rna_sculpt_paint.c b/source/blender/makesrna/intern/rna_sculpt_paint.c
index c7bdf7a2dd6..e477bf6d284 100644
--- a/source/blender/makesrna/intern/rna_sculpt_paint.c
+++ b/source/blender/makesrna/intern/rna_sculpt_paint.c
@@ -1151,7 +1151,7 @@ static void rna_def_particle_edit(BlenderRNA *brna)
static const EnumPropertyItem edit_type_items[] = {
{PE_TYPE_PARTICLES, "PARTICLES", 0, "Particles", ""},
- {PE_TYPE_SOFTBODY, "SOFT_BODY", 0, "Soft body", ""},
+ {PE_TYPE_SOFTBODY, "SOFT_BODY", 0, "Soft Body", ""},
{PE_TYPE_CLOTH, "CLOTH", 0, "Cloth", ""},
{0, NULL, 0, NULL, NULL},
};
diff --git a/source/blender/makesrna/intern/rna_sequencer.c b/source/blender/makesrna/intern/rna_sequencer.c
index 9d322d0d09b..e180ab5dfb6 100644
--- a/source/blender/makesrna/intern/rna_sequencer.c
+++ b/source/blender/makesrna/intern/rna_sequencer.c
@@ -1936,7 +1936,7 @@ static void rna_def_sequence(BlenderRNA *brna)
RNA_def_property_boolean_sdna(prop, NULL, "cache_flag", SEQ_CACHE_STORE_PREPROCESSED);
RNA_def_property_ui_text(
prop,
- "Cache Pre-processed",
+ "Cache Pre-Processed",
"Cache pre-processed images, for faster tweaking of effects at the cost of memory usage");
prop = RNA_def_property(srna, "use_cache_composite", PROP_BOOLEAN, PROP_NONE);
@@ -2100,7 +2100,7 @@ static void rna_def_editor(BlenderRNA *brna)
RNA_def_property_ui_range(prop, 0.0f, SEQ_CACHE_COST_MAX, 0.1f, 1);
RNA_def_property_float_sdna(prop, NULL, "recycle_max_cost");
RNA_def_property_ui_text(
- prop, "Recycle Up To Cost", "Only frames with cost lower than this value will be recycled");
+ prop, "Recycle Up to Cost", "Only frames with cost lower than this value will be recycled");
}
static void rna_def_filter_video(StructRNA *srna)
@@ -2822,7 +2822,7 @@ static void rna_def_speed_control(StructRNA *srna)
prop = RNA_def_property(srna, "use_frame_interpolate", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flags", SEQ_SPEED_USE_INTERPOLATION);
RNA_def_property_ui_text(
- prop, "Frame interpolation", "Do crossfade blending between current and next frame");
+ prop, "Frame Interpolation", "Do crossfade blending between current and next frame");
RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_invalidate_raw_update");
}
diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c
index 91e572caab0..eab48888d48 100644
--- a/source/blender/makesrna/intern/rna_space.c
+++ b/source/blender/makesrna/intern/rna_space.c
@@ -5150,7 +5150,7 @@ static void rna_def_space_dopesheet(BlenderRNA *brna)
prop = RNA_def_property(srna, "show_interpolation", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", SACTION_SHOW_INTERPOLATION);
RNA_def_property_ui_text(prop,
- "Show Handles And Interpolation",
+ "Show Handles and Interpolation",
"Display keyframe handle types and non-bezier interpolation modes");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_DOPESHEET, NULL);
@@ -5173,7 +5173,7 @@ static void rna_def_space_dopesheet(BlenderRNA *brna)
/* editing */
prop = RNA_def_property(srna, "use_auto_merge_keyframes", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", SACTION_NOTRANSKEYCULL);
- RNA_def_property_ui_text(prop, "AutoMerge Keyframes", "Automatically merge nearby keyframes");
+ RNA_def_property_ui_text(prop, "Auto-Merge Keyframes", "Automatically merge nearby keyframes");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_DOPESHEET, NULL);
prop = RNA_def_property(srna, "use_realtime_update", PROP_BOOLEAN, PROP_NONE);
diff --git a/source/blender/makesrna/intern/rna_texture.c b/source/blender/makesrna/intern/rna_texture.c
index 4d5f0f6c2fa..fb6d40b3a55 100644
--- a/source/blender/makesrna/intern/rna_texture.c
+++ b/source/blender/makesrna/intern/rna_texture.c
@@ -1074,8 +1074,8 @@ static void rna_def_texture_stucci(BlenderRNA *brna)
static const EnumPropertyItem prop_stucci_stype[] = {
{TEX_PLASTIC, "PLASTIC", 0, "Plastic", "Use standard stucci"},
- {TEX_WALLIN, "WALL_IN", 0, "Wall in", "Create Dimples"},
- {TEX_WALLOUT, "WALL_OUT", 0, "Wall out", "Create Ridges"},
+ {TEX_WALLIN, "WALL_IN", 0, "Wall In", "Create Dimples"},
+ {TEX_WALLOUT, "WALL_OUT", 0, "Wall Out", "Create Ridges"},
{0, NULL, 0, NULL, NULL},
};
diff --git a/source/blender/makesrna/intern/rna_userdef.c b/source/blender/makesrna/intern/rna_userdef.c
index c31766efe58..3d389dd9b07 100644
--- a/source/blender/makesrna/intern/rna_userdef.c
+++ b/source/blender/makesrna/intern/rna_userdef.c
@@ -4786,7 +4786,7 @@ static void rna_def_userdef_view(BlenderRNA *brna)
prop = RNA_def_property(srna, "font_path_ui_mono", PROP_STRING, PROP_FILEPATH);
RNA_def_property_string_sdna(prop, NULL, "font_path_ui_mono");
- RNA_def_property_ui_text(prop, "Mono-space Font", "Path to interface mono-space Font");
+ RNA_def_property_ui_text(prop, "Monospaced Font", "Path to interface monospaced Font");
RNA_def_property_update(prop, NC_WINDOW, "rna_userdef_font_update");
/* Language. */
diff --git a/source/blender/modifiers/intern/MOD_armature.c b/source/blender/modifiers/intern/MOD_armature.c
index 324cac3df8b..38fb19e3233 100644
--- a/source/blender/modifiers/intern/MOD_armature.c
+++ b/source/blender/modifiers/intern/MOD_armature.c
@@ -258,7 +258,7 @@ static void panel_draw(const bContext *UNUSED(C), Panel *panel)
uiItemR(col, ptr, "use_deform_preserve_volume", 0, NULL, ICON_NONE);
uiItemR(col, ptr, "use_multi_modifier", 0, NULL, ICON_NONE);
- col = uiLayoutColumnWithHeading(layout, true, IFACE_("Bind to"));
+ col = uiLayoutColumnWithHeading(layout, true, IFACE_("Bind To"));
uiItemR(col, ptr, "use_vertex_groups", 0, IFACE_("Vertex Groups"), ICON_NONE);
uiItemR(col, ptr, "use_bone_envelopes", 0, IFACE_("Bone Envelopes"), ICON_NONE);
diff --git a/source/blender/modifiers/intern/MOD_array.c b/source/blender/modifiers/intern/MOD_array.c
index 7e21300f3c2..6ca50a34ebf 100644
--- a/source/blender/modifiers/intern/MOD_array.c
+++ b/source/blender/modifiers/intern/MOD_array.c
@@ -508,6 +508,7 @@ static Mesh *arrayModifier_doArray(ArrayModifierData *amd,
if (offset_is_too_small) {
BKE_modifier_set_error(
+ ctx->object,
&amd->modifier,
"The offset is too small, we cannot generate the amount of geometry it would require");
}
@@ -518,7 +519,8 @@ static Mesh *arrayModifier_doArray(ArrayModifierData *amd,
else if (((size_t)count * (size_t)chunk_nverts + (size_t)start_cap_nverts +
(size_t)end_cap_nverts) > max_num_vertices) {
count = 1;
- BKE_modifier_set_error(&amd->modifier,
+ BKE_modifier_set_error(ctx->object,
+ &amd->modifier,
"The amount of copies is too high, we cannot generate the amount of "
"geometry it would require");
}
diff --git a/source/blender/modifiers/intern/MOD_bevel.c b/source/blender/modifiers/intern/MOD_bevel.c
index b84c8a186b5..04ddac338e5 100644
--- a/source/blender/modifiers/intern/MOD_bevel.c
+++ b/source/blender/modifiers/intern/MOD_bevel.c
@@ -208,7 +208,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
Object *ob = ctx->object;
if (harden_normals && (ob->type == OB_MESH) && !(((Mesh *)ob->data)->flag & ME_AUTOSMOOTH)) {
- BKE_modifier_set_error(md, "Enable 'Auto Smooth' in Object Data Properties");
+ BKE_modifier_set_error(ob, md, "Enable 'Auto Smooth' in Object Data Properties");
harden_normals = false;
}
diff --git a/source/blender/modifiers/intern/MOD_boolean.c b/source/blender/modifiers/intern/MOD_boolean.c
index 7700c8bbff9..5d28aea54b5 100644
--- a/source/blender/modifiers/intern/MOD_boolean.c
+++ b/source/blender/modifiers/intern/MOD_boolean.c
@@ -189,7 +189,7 @@ static int bm_face_isect_pair(BMFace *f, void *UNUSED(user_data))
return BM_elem_flag_test(f, BM_FACE_TAG) ? 1 : 0;
}
-static bool BMD_error_messages(ModifierData *md, Collection *col)
+static bool BMD_error_messages(const Object *ob, ModifierData *md, Collection *col)
{
BooleanModifierData *bmd = (BooleanModifierData *)md;
@@ -202,21 +202,21 @@ static bool BMD_error_messages(ModifierData *md, Collection *col)
#ifndef WITH_GMP
/* If compiled without GMP, return a error. */
if (use_exact) {
- BKE_modifier_set_error(md, "Compiled without GMP, using fast solver");
+ BKE_modifier_set_error(ob, md, "Compiled without GMP, using fast solver");
error_returns_result = false;
}
#endif
/* If intersect is selected using fast solver, return a error. */
if (operand_collection && operation_intersect && !use_exact) {
- BKE_modifier_set_error(md, "Cannot execute, intersect only available using exact solver");
+ BKE_modifier_set_error(ob, md, "Cannot execute, intersect only available using exact solver");
error_returns_result = true;
}
/* If the selected collection is empty and using fast solver, return a error. */
if (operand_collection) {
if (!use_exact && BKE_collection_is_empty(col)) {
- BKE_modifier_set_error(md, "Cannot execute, fast solver and empty collection");
+ BKE_modifier_set_error(ob, md, "Cannot execute, fast solver and empty collection");
error_returns_result = true;
}
@@ -225,7 +225,7 @@ static bool BMD_error_messages(ModifierData *md, Collection *col)
FOREACH_COLLECTION_OBJECT_RECURSIVE_BEGIN (col, operand_ob) {
if (operand_ob->type != OB_MESH) {
BKE_modifier_set_error(
- md, "Cannot execute, the selected collection contains non mesh objects");
+ ob, md, "Cannot execute, the selected collection contains non mesh objects");
error_returns_result = true;
}
}
@@ -587,7 +587,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
return result;
}
- BMD_error_messages(md, NULL);
+ BMD_error_messages(ctx->object, md, NULL);
Object *operand_ob = bmd->object;
@@ -615,7 +615,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
/* if new mesh returned, return it; otherwise there was
* an error, so delete the modifier object */
if (result == NULL) {
- BKE_modifier_set_error(md, "Cannot execute boolean operation");
+ BKE_modifier_set_error(object, md, "Cannot execute boolean operation");
}
}
}
@@ -626,7 +626,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
}
/* Return result for certain errors. */
- if (BMD_error_messages(md, col) == confirm_return) {
+ if (BMD_error_messages(ctx->object, md, col) == confirm_return) {
return result;
}
@@ -669,7 +669,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
/* if new mesh returned, return it; otherwise there was
* an error, so delete the modifier object */
if (result == NULL) {
- BKE_modifier_set_error(md, "Cannot execute boolean operation");
+ BKE_modifier_set_error(object, md, "Cannot execute boolean operation");
}
}
}
diff --git a/source/blender/modifiers/intern/MOD_correctivesmooth.c b/source/blender/modifiers/intern/MOD_correctivesmooth.c
index eaf8c44a9be..5884ec0aa17 100644
--- a/source/blender/modifiers/intern/MOD_correctivesmooth.c
+++ b/source/blender/modifiers/intern/MOD_correctivesmooth.c
@@ -615,7 +615,7 @@ static void correctivesmooth_modifier_do(ModifierData *md,
csmd_orig->bind_coords_num = csmd->bind_coords_num;
}
else {
- BKE_modifier_set_error(md, "Attempt to bind from inactive dependency graph");
+ BKE_modifier_set_error(ob, md, "Attempt to bind from inactive dependency graph");
}
}
@@ -625,7 +625,7 @@ static void correctivesmooth_modifier_do(ModifierData *md,
}
if ((csmd->rest_source == MOD_CORRECTIVESMOOTH_RESTSOURCE_BIND) && (csmd->bind_coords == NULL)) {
- BKE_modifier_set_error(md, "Bind data required");
+ BKE_modifier_set_error(ob, md, "Bind data required");
goto error;
}
@@ -633,14 +633,14 @@ static void correctivesmooth_modifier_do(ModifierData *md,
if (csmd->rest_source == MOD_CORRECTIVESMOOTH_RESTSOURCE_BIND) {
if (csmd->bind_coords_num != numVerts) {
BKE_modifier_set_error(
- md, "Bind vertex count mismatch: %u to %u", csmd->bind_coords_num, numVerts);
+ ob, md, "Bind vertex count mismatch: %u to %u", csmd->bind_coords_num, numVerts);
goto error;
}
}
else {
/* MOD_CORRECTIVESMOOTH_RESTSOURCE_ORCO */
if (ob->type != OB_MESH) {
- BKE_modifier_set_error(md, "Object is not a mesh");
+ BKE_modifier_set_error(ob, md, "Object is not a mesh");
goto error;
}
else {
@@ -648,7 +648,7 @@ static void correctivesmooth_modifier_do(ModifierData *md,
if (me_numVerts != numVerts) {
BKE_modifier_set_error(
- md, "Original vertex count mismatch: %u to %u", me_numVerts, numVerts);
+ ob, md, "Original vertex count mismatch: %u to %u", me_numVerts, numVerts);
goto error;
}
}
diff --git a/source/blender/modifiers/intern/MOD_datatransfer.c b/source/blender/modifiers/intern/MOD_datatransfer.c
index 17d716b731c..9b6a21c840d 100644
--- a/source/blender/modifiers/intern/MOD_datatransfer.c
+++ b/source/blender/modifiers/intern/MOD_datatransfer.c
@@ -232,16 +232,19 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
if (BKE_reports_contain(&reports, RPT_ERROR)) {
const char *report_str = BKE_reports_string(&reports, RPT_ERROR);
- BKE_modifier_set_error(md, "%s", report_str);
+ BKE_modifier_set_error(ctx->object, md, "%s", report_str);
MEM_freeN((void *)report_str);
}
else if ((dtmd->data_types & DT_TYPE_LNOR) && !(me->flag & ME_AUTOSMOOTH)) {
- BKE_modifier_set_error((ModifierData *)dtmd, "Enable 'Auto Smooth' in Object Data Properties");
+ BKE_modifier_set_error(
+ ctx->object, (ModifierData *)dtmd, "Enable 'Auto Smooth' in Object Data Properties");
}
else if (result->totvert > HIGH_POLY_WARNING ||
((Mesh *)(ob_source->data))->totvert > HIGH_POLY_WARNING) {
BKE_modifier_set_error(
- md, "Source or destination object has a high polygon count, computation might be slow");
+ ctx->object,
+ md,
+ "Source or destination object has a high polygon count, computation might be slow");
}
return result;
diff --git a/source/blender/modifiers/intern/MOD_decimate.c b/source/blender/modifiers/intern/MOD_decimate.c
index 2532afc933e..10ed4f8d80b 100644
--- a/source/blender/modifiers/intern/MOD_decimate.c
+++ b/source/blender/modifiers/intern/MOD_decimate.c
@@ -140,7 +140,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
}
if (dmd->face_count <= 3) {
- BKE_modifier_set_error(md, "Modifier requires more than 3 input faces");
+ BKE_modifier_set_error(ctx->object, md, "Modifier requires more than 3 input faces");
return mesh;
}
diff --git a/source/blender/modifiers/intern/MOD_laplaciandeform.c b/source/blender/modifiers/intern/MOD_laplaciandeform.c
index 8eb9e97573d..d3dc8c93c02 100644
--- a/source/blender/modifiers/intern/MOD_laplaciandeform.c
+++ b/source/blender/modifiers/intern/MOD_laplaciandeform.c
@@ -684,14 +684,15 @@ static void LaplacianDeformModifier_do(
else {
if (sysdif == LAPDEFORM_SYSTEM_CHANGE_VERTEXES) {
BKE_modifier_set_error(
- &lmd->modifier, "Vertices changed from %d to %d", lmd->total_verts, numVerts);
+ ob, &lmd->modifier, "Vertices changed from %d to %d", lmd->total_verts, numVerts);
}
else if (sysdif == LAPDEFORM_SYSTEM_CHANGE_EDGES) {
BKE_modifier_set_error(
- &lmd->modifier, "Edges changed from %d to %d", sys->total_edges, mesh->totedge);
+ ob, &lmd->modifier, "Edges changed from %d to %d", sys->total_edges, mesh->totedge);
}
else if (sysdif == LAPDEFORM_SYSTEM_CHANGE_NOT_VALID_GROUP) {
- BKE_modifier_set_error(&lmd->modifier,
+ BKE_modifier_set_error(ob,
+ &lmd->modifier,
"Vertex group '%s' is not valid, or maybe empty",
sys->anchor_grp_name);
}
@@ -704,8 +705,10 @@ static void LaplacianDeformModifier_do(
}
else {
if (!isValidVertexGroup(lmd, ob, mesh)) {
- BKE_modifier_set_error(
- &lmd->modifier, "Vertex group '%s' is not valid, or maybe empty", lmd->anchor_grp_name);
+ BKE_modifier_set_error(ob,
+ &lmd->modifier,
+ "Vertex group '%s' is not valid, or maybe empty",
+ lmd->anchor_grp_name);
lmd->flag &= ~MOD_LAPLACIANDEFORM_BIND;
}
else if (lmd->total_verts > 0 && lmd->total_verts == numVerts) {
@@ -725,7 +728,7 @@ static void LaplacianDeformModifier_do(
}
}
if (sys && sys->is_matrix_computed && !sys->has_solution) {
- BKE_modifier_set_error(&lmd->modifier, "The system did not find a solution");
+ BKE_modifier_set_error(ob, &lmd->modifier, "The system did not find a solution");
}
}
diff --git a/source/blender/modifiers/intern/MOD_laplaciansmooth.c b/source/blender/modifiers/intern/MOD_laplaciansmooth.c
index f7a8faf7a1c..d51f95bd18d 100644
--- a/source/blender/modifiers/intern/MOD_laplaciansmooth.c
+++ b/source/blender/modifiers/intern/MOD_laplaciansmooth.c
@@ -82,7 +82,7 @@ struct BLaplacianSystem {
typedef struct BLaplacianSystem LaplacianSystem;
static void required_data_mask(Object *ob, ModifierData *md, CustomData_MeshMasks *r_cddata_masks);
-static bool is_disabled(const struct Scene *UNUSED(scene), ModifierData *md, bool useRenderParams);
+static bool is_disabled(const struct Scene *scene, ModifierData *md, bool useRenderParams);
static float compute_volume(const float center[3],
float (*vertexCos)[3],
const MPoly *mpoly,
diff --git a/source/blender/modifiers/intern/MOD_mesh_to_volume.cc b/source/blender/modifiers/intern/MOD_mesh_to_volume.cc
index cc16da0fa80..426bba05d76 100644
--- a/source/blender/modifiers/intern/MOD_mesh_to_volume.cc
+++ b/source/blender/modifiers/intern/MOD_mesh_to_volume.cc
@@ -273,8 +273,8 @@ static Volume *modifyVolume(ModifierData *md, const ModifierEvalContext *ctx, Vo
return volume;
#else
- UNUSED_VARS(md, ctx);
- BKE_modifier_set_error(md, "Compiled without OpenVDB");
+ UNUSED_VARS(md);
+ BKE_modifier_set_error(ctx->object, md, "Compiled without OpenVDB");
return input_volume;
#endif
}
diff --git a/source/blender/modifiers/intern/MOD_meshcache.c b/source/blender/modifiers/intern/MOD_meshcache.c
index 5d5b8b847d5..b808d738fe8 100644
--- a/source/blender/modifiers/intern/MOD_meshcache.c
+++ b/source/blender/modifiers/intern/MOD_meshcache.c
@@ -171,13 +171,13 @@ static void meshcache_do(MeshCacheModifierData *mcmd,
/* we could support any object type */
if (UNLIKELY(ob->type != OB_MESH)) {
- BKE_modifier_set_error(&mcmd->modifier, "'Integrate' only valid for Mesh objects");
+ BKE_modifier_set_error(ob, &mcmd->modifier, "'Integrate' only valid for Mesh objects");
}
else if (UNLIKELY(me->totvert != numVerts)) {
- BKE_modifier_set_error(&mcmd->modifier, "'Integrate' original mesh vertex mismatch");
+ BKE_modifier_set_error(ob, &mcmd->modifier, "'Integrate' original mesh vertex mismatch");
}
else if (UNLIKELY(me->totpoly == 0)) {
- BKE_modifier_set_error(&mcmd->modifier, "'Integrate' requires faces");
+ BKE_modifier_set_error(ob, &mcmd->modifier, "'Integrate' requires faces");
}
else {
/* the moons align! */
@@ -216,7 +216,7 @@ static void meshcache_do(MeshCacheModifierData *mcmd,
/* -------------------------------------------------------------------- */
/* Apply the transformation matrix (if needed) */
if (UNLIKELY(err_str)) {
- BKE_modifier_set_error(&mcmd->modifier, "%s", err_str);
+ BKE_modifier_set_error(ob, &mcmd->modifier, "%s", err_str);
}
else if (ok) {
bool use_matrix = false;
diff --git a/source/blender/modifiers/intern/MOD_meshdeform.c b/source/blender/modifiers/intern/MOD_meshdeform.c
index e2c8db07623..0e530312238 100644
--- a/source/blender/modifiers/intern/MOD_meshdeform.c
+++ b/source/blender/modifiers/intern/MOD_meshdeform.c
@@ -373,7 +373,7 @@ static void meshdeformModifier_do(ModifierData *md,
Object *ob_target = mmd->object;
cagemesh = BKE_modifier_get_evaluated_mesh_from_evaluated_object(ob_target, false);
if (cagemesh == NULL) {
- BKE_modifier_set_error(md, "Cannot get mesh from cage object");
+ BKE_modifier_set_error(ctx->object, md, "Cannot get mesh from cage object");
return;
}
@@ -388,7 +388,7 @@ static void meshdeformModifier_do(ModifierData *md,
if (!mmd->bindcagecos) {
/* progress bar redraw can make this recursive .. */
if (!DEG_is_active(ctx->depsgraph)) {
- BKE_modifier_set_error(md, "Attempt to bind from inactive dependency graph");
+ BKE_modifier_set_error(ob, md, "Attempt to bind from inactive dependency graph");
goto finally;
}
if (!recursive_bind_sentinel) {
@@ -405,16 +405,16 @@ static void meshdeformModifier_do(ModifierData *md,
totcagevert = BKE_mesh_wrapper_vert_len(cagemesh);
if (mmd->totvert != totvert) {
- BKE_modifier_set_error(md, "Vertices changed from %d to %d", mmd->totvert, totvert);
+ BKE_modifier_set_error(ob, md, "Vertices changed from %d to %d", mmd->totvert, totvert);
goto finally;
}
else if (mmd->totcagevert != totcagevert) {
BKE_modifier_set_error(
- md, "Cage vertices changed from %d to %d", mmd->totcagevert, totcagevert);
+ ob, md, "Cage vertices changed from %d to %d", mmd->totcagevert, totcagevert);
goto finally;
}
else if (mmd->bindcagecos == NULL) {
- BKE_modifier_set_error(md, "Bind data missing");
+ BKE_modifier_set_error(ob, md, "Bind data missing");
goto finally;
}
diff --git a/source/blender/modifiers/intern/MOD_meshsequencecache.c b/source/blender/modifiers/intern/MOD_meshsequencecache.c
index 70732636d02..73106b2e816 100644
--- a/source/blender/modifiers/intern/MOD_meshsequencecache.c
+++ b/source/blender/modifiers/intern/MOD_meshsequencecache.c
@@ -127,7 +127,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
BKE_cachefile_reader_open(cache_file, &mcmd->reader, ctx->object, mcmd->object_path);
if (!mcmd->reader) {
BKE_modifier_set_error(
- md, "Could not create Alembic reader for file %s", cache_file->filepath);
+ ctx->object, md, "Could not create Alembic reader for file %s", cache_file->filepath);
return mesh;
}
}
@@ -170,7 +170,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
}
if (err_str) {
- BKE_modifier_set_error(md, "%s", err_str);
+ BKE_modifier_set_error(ctx->object, md, "%s", err_str);
}
if (!ELEM(result, NULL, mesh) && (mesh != org_mesh)) {
diff --git a/source/blender/modifiers/intern/MOD_multires.c b/source/blender/modifiers/intern/MOD_multires.c
index e3a8d651183..0798f02cc10 100644
--- a/source/blender/modifiers/intern/MOD_multires.c
+++ b/source/blender/modifiers/intern/MOD_multires.c
@@ -216,7 +216,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
{
Mesh *result = mesh;
#if !defined(WITH_OPENSUBDIV)
- BKE_modifier_set_error(md, "Disabled, built without OpenSubdiv");
+ BKE_modifier_set_error(ctx->object, md, "Disabled, built without OpenSubdiv");
return result;
#endif
MultiresModifierData *mmd = (MultiresModifierData *)md;
@@ -300,7 +300,7 @@ static void deformMatrices(ModifierData *md,
{
#if !defined(WITH_OPENSUBDIV)
- BKE_modifier_set_error(md, "Disabled, built without OpenSubdiv");
+ BKE_modifier_set_error(ctx->object, md, "Disabled, built without OpenSubdiv");
return;
#endif
diff --git a/source/blender/modifiers/intern/MOD_nodes.cc b/source/blender/modifiers/intern/MOD_nodes.cc
index 38712054f22..5a368f7087f 100644
--- a/source/blender/modifiers/intern/MOD_nodes.cc
+++ b/source/blender/modifiers/intern/MOD_nodes.cc
@@ -121,110 +121,98 @@ using namespace blender::bke;
class GeometryNodesEvaluator {
private:
LinearAllocator<> allocator_;
- const DerivedNodeTree &tree_;
- Map<const DOutputSocket *, GMutablePointer> group_input_data_;
+ Map<const DInputSocket *, GMutablePointer> value_by_input_;
Vector<const DInputSocket *> group_outputs_;
MultiFunctionByNode &mf_by_node_;
const DataTypeConversions &conversions_;
public:
- GeometryNodesEvaluator(const DerivedNodeTree &tree,
- Map<const DOutputSocket *, GMutablePointer> group_input_data,
+ GeometryNodesEvaluator(const Map<const DOutputSocket *, GMutablePointer> &group_input_data,
Vector<const DInputSocket *> group_outputs,
MultiFunctionByNode &mf_by_node)
- : tree_(tree),
- group_input_data_(std::move(group_input_data)),
- group_outputs_(std::move(group_outputs)),
+ : group_outputs_(std::move(group_outputs)),
mf_by_node_(mf_by_node),
conversions_(get_implicit_type_conversions())
{
+ for (auto item : group_input_data.items()) {
+ this->forward_to_inputs(*item.key, item.value);
+ }
}
Vector<GMutablePointer> execute()
{
Vector<GMutablePointer> results;
for (const DInputSocket *group_output : group_outputs_) {
- const CPPType &type = *socket_cpp_type_get(*group_output->typeinfo());
- void *result_buffer = allocator_.allocate(type.size(), type.alignment());
- this->compute_input_socket(*group_output, result_buffer);
- results.append(GMutablePointer{type, result_buffer});
+ GMutablePointer result = this->get_input_value(*group_output);
+ results.append(result);
}
- for (GMutablePointer value : group_input_data_.values()) {
- value.type()->destruct(value.get());
+ for (GMutablePointer value : value_by_input_.values()) {
+ value.destruct();
}
return results;
}
private:
- void compute_input_socket(const DInputSocket &socket_to_compute, void *r_value)
+ GMutablePointer get_input_value(const DInputSocket &socket_to_compute)
{
+ std::optional<GMutablePointer> value = value_by_input_.pop_try(&socket_to_compute);
+ if (value.has_value()) {
+ /* This input has been computed before, return it directly. */
+ return *value;
+ }
+
Span<const DOutputSocket *> from_sockets = socket_to_compute.linked_sockets();
Span<const DGroupInput *> from_group_inputs = socket_to_compute.linked_group_inputs();
const int total_inputs = from_sockets.size() + from_group_inputs.size();
BLI_assert(total_inputs <= 1);
+ const CPPType &type = *socket_cpp_type_get(*socket_to_compute.typeinfo());
+
if (total_inputs == 0) {
+ /* The input is not connected, use the value from the socket itself. */
bNodeSocket &bsocket = *socket_to_compute.bsocket();
- socket_cpp_value_get(bsocket, r_value);
- return;
+ void *buffer = allocator_.allocate(type.size(), type.alignment());
+ socket_cpp_value_get(bsocket, buffer);
+ return GMutablePointer{type, buffer};
}
if (from_group_inputs.size() == 1) {
+ /* The input gets its value from the input of a group that is not further connected. */
bNodeSocket &bsocket = *from_group_inputs[0]->bsocket();
- socket_cpp_value_get(bsocket, r_value);
- return;
+ void *buffer = allocator_.allocate(type.size(), type.alignment());
+ socket_cpp_value_get(bsocket, buffer);
+ return GMutablePointer{type, buffer};
}
+ /* Compute the socket now. */
const DOutputSocket &from_socket = *from_sockets[0];
- const CPPType &from_type = *socket_cpp_type_get(*from_socket.typeinfo());
- const CPPType &to_type = *socket_cpp_type_get(*socket_to_compute.typeinfo());
- if (from_type == to_type) {
- this->compute_output_socket(from_socket, r_value);
- }
- else {
- /* The type of both sockets don't match, so a conversion is necessary. */
- if (conversions_.is_convertible(from_type, to_type)) {
- void *from_value = allocator_.allocate(from_type.size(), from_type.alignment());
- this->compute_output_socket(from_socket, from_value);
- conversions_.convert(from_type, to_type, from_value, r_value);
- from_type.destruct(from_value);
- }
- else {
- /* Use a default value when the types cannot be converted. */
- to_type.copy_to_uninitialized(to_type.default_value(), r_value);
- }
- }
+ this->compute_output_and_forward(from_socket);
+ return value_by_input_.pop(&socket_to_compute);
}
- void compute_output_socket(const DOutputSocket &socket_to_compute, void *r_value)
+ void compute_output_and_forward(const DOutputSocket &socket_to_compute)
{
- const GMutablePointer *group_input = group_input_data_.lookup_ptr(&socket_to_compute);
- if (group_input != nullptr) {
- const CPPType &type = *group_input->type();
- type.copy_to_uninitialized(group_input->get(), r_value);
- return;
- }
-
const DNode &node = socket_to_compute.node();
- GValueByName node_inputs{allocator_};
- /* Compute all inputs for the node. */
+ /* Prepare inputs required to execute the node. */
+ GValueByName node_inputs{allocator_};
for (const DInputSocket *input_socket : node.inputs()) {
- const CPPType &type = *socket_cpp_type_get(*input_socket->typeinfo());
- void *buffer = allocator_.allocate(type.size(), type.alignment());
- compute_input_socket(*input_socket, buffer);
- node_inputs.move_in(input_socket->identifier(), GMutablePointer{type, buffer});
- type.destruct(buffer);
+ if (input_socket->is_available()) {
+ GMutablePointer value = this->get_input_value(*input_socket);
+ node_inputs.transfer_ownership_in(input_socket->identifier(), value);
+ }
}
- /* Execute the node itself. */
+ /* Execute the node. */
GValueByName node_outputs{allocator_};
this->execute_node(node, node_inputs, node_outputs);
- /* Pass relevant value to the caller. */
- bNodeSocket *bsocket_to_compute = socket_to_compute.bsocket();
- const CPPType &type_to_compute = *socket_cpp_type_get(*bsocket_to_compute->typeinfo);
- GMutablePointer computed_value = node_outputs.extract(bsocket_to_compute->identifier);
- type_to_compute.relocate_to_uninitialized(computed_value.get(), r_value);
+ /* Forward computed outputs to linked input sockets. */
+ for (const DOutputSocket *output_socket : node.outputs()) {
+ if (output_socket->is_available()) {
+ GMutablePointer value = node_outputs.extract(output_socket->identifier());
+ this->forward_to_inputs(*output_socket, value);
+ }
+ }
}
void execute_node(const DNode &node, GValueByName &node_inputs, GValueByName &node_outputs)
@@ -266,6 +254,54 @@ class GeometryNodesEvaluator {
value.destruct();
}
}
+
+ void forward_to_inputs(const DOutputSocket &from_socket, GMutablePointer value_to_forward)
+ {
+ Span<const DInputSocket *> to_sockets_all = from_socket.linked_sockets();
+
+ const CPPType &from_type = *value_to_forward.type();
+
+ Vector<const DInputSocket *> to_sockets_same_type;
+ for (const DInputSocket *to_socket : to_sockets_all) {
+ const CPPType &to_type = *socket_cpp_type_get(*to_socket->typeinfo());
+ if (from_type == to_type) {
+ to_sockets_same_type.append(to_socket);
+ }
+ else {
+ void *buffer = allocator_.allocate(to_type.size(), to_type.alignment());
+ if (conversions_.is_convertible(from_type, to_type)) {
+ conversions_.convert(from_type, to_type, value_to_forward.get(), buffer);
+ }
+ else {
+ to_type.copy_to_uninitialized(to_type.default_value(), buffer);
+ }
+ value_by_input_.add_new(to_socket, GMutablePointer{to_type, buffer});
+ }
+ }
+
+ if (to_sockets_same_type.size() == 0) {
+ /* This value is not further used, so destruct it. */
+ value_to_forward.destruct();
+ }
+ else if (to_sockets_same_type.size() == 1) {
+ /* This value is only used on one input socket, no need to copy it. */
+ const DInputSocket *to_socket = to_sockets_same_type[0];
+ value_by_input_.add_new(to_socket, value_to_forward);
+ }
+ else {
+ /* Multiple inputs use the value, make a copy for every input except for one. */
+ const DInputSocket *first_to_socket = to_sockets_same_type[0];
+ Span<const DInputSocket *> other_to_sockets = to_sockets_same_type.as_span().drop_front(1);
+ const CPPType &type = *value_to_forward.type();
+
+ value_by_input_.add_new(first_to_socket, value_to_forward);
+ for (const DInputSocket *to_socket : other_to_sockets) {
+ void *buffer = allocator_.allocate(type.size(), type.alignment());
+ type.copy_to_uninitialized(value_to_forward.get(), buffer);
+ value_by_input_.add_new(to_socket, GMutablePointer{type, buffer});
+ }
+ }
+ }
};
/**
@@ -274,25 +310,48 @@ class GeometryNodesEvaluator {
* often than necessary. It's going to be replaced soon.
*/
static GeometryPtr compute_geometry(const DerivedNodeTree &tree,
- const DOutputSocket *group_input,
- GeometryPtr group_input_geometry,
- const DInputSocket &socket_to_compute)
+ Span<const DOutputSocket *> group_input_sockets,
+ const DInputSocket &socket_to_compute,
+ GeometryPtr input_geometry,
+ NodesModifierData *nmd)
{
ResourceCollector resources;
+ LinearAllocator<> &allocator = resources.linear_allocator();
MultiFunctionByNode mf_by_node = get_multi_function_per_node(tree, resources);
- /* Use this buffer so that it is not destructed when the scope ends. The evaluator is responsible
- * for destructing it. */
- TypedBuffer<GeometryPtr> buffer;
- new (buffer.ptr()) GeometryPtr(std::move(group_input_geometry));
-
Map<const DOutputSocket *, GMutablePointer> group_inputs;
- group_inputs.add_new(group_input, GMutablePointer{buffer.ptr()});
+
+ if (group_input_sockets.size() > 0) {
+ Span<const DOutputSocket *> remaining_input_sockets = group_input_sockets;
+
+ /* If the group expects a geometry as first input, use the geometry that has been passed to
+ * modifier. */
+ const DOutputSocket *first_input_socket = group_input_sockets[0];
+ if (first_input_socket->bsocket()->type == SOCK_GEOMETRY) {
+ GeometryPtr *geometry_in = allocator.construct<GeometryPtr>(std::move(input_geometry));
+ group_inputs.add_new(first_input_socket, geometry_in);
+ remaining_input_sockets = remaining_input_sockets.drop_front(1);
+ }
+
+ /* Initialize remaining group inputs. */
+ for (const DOutputSocket *socket : remaining_input_sockets) {
+ const CPPType &type = *socket_cpp_type_get(*socket->typeinfo());
+ if (type.is<float>()) {
+ float *value_in = allocator.construct<float>(nmd->test_float_input);
+ group_inputs.add_new(socket, value_in);
+ }
+ else {
+ void *value_in = allocator.allocate(type.size(), type.alignment());
+ type.copy_to_uninitialized(type.default_value(), value_in);
+ group_inputs.add_new(socket, {type, value_in});
+ }
+ }
+ }
Vector<const DInputSocket *> group_outputs;
group_outputs.append(&socket_to_compute);
- GeometryNodesEvaluator evaluator{tree, group_inputs, group_outputs, mf_by_node};
+ GeometryNodesEvaluator evaluator{group_inputs, group_outputs, mf_by_node};
Vector<GMutablePointer> results = evaluator.execute();
BLI_assert(results.size() == 1);
GMutablePointer result = results[0];
@@ -340,7 +399,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *UNUSED(ctx)
input_geometry->mesh_set_and_keep_ownership(mesh);
GeometryPtr new_geometry = compute_geometry(
- tree, group_inputs[0], std::move(input_geometry), *group_outputs[0]);
+ tree, group_inputs, *group_outputs[0], std::move(input_geometry), nmd);
make_geometry_mutable(new_geometry);
Mesh *new_mesh = new_geometry->mesh_release();
if (new_mesh == nullptr) {
@@ -360,6 +419,7 @@ static void panel_draw(const bContext *UNUSED(C), Panel *panel)
uiLayoutSetPropDecorate(layout, false);
uiItemR(layout, ptr, "node_group", 0, NULL, ICON_MESH_DATA);
+ uiItemR(layout, ptr, "test_float_input", 0, NULL, ICON_NONE);
modifier_panel_end(layout, ptr);
}
diff --git a/source/blender/modifiers/intern/MOD_normal_edit.c b/source/blender/modifiers/intern/MOD_normal_edit.c
index 1be74a8fed2..0ec564d2e2d 100644
--- a/source/blender/modifiers/intern/MOD_normal_edit.c
+++ b/source/blender/modifiers/intern/MOD_normal_edit.c
@@ -476,7 +476,15 @@ static bool is_valid_target(NormalEditModifierData *enmd)
if ((enmd->mode == MOD_NORMALEDIT_MODE_DIRECTIONAL) && enmd->target) {
return true;
}
- BKE_modifier_set_error((ModifierData *)enmd, "Invalid target settings");
+ return false;
+}
+
+static bool is_valid_target_with_error(const Object *ob, NormalEditModifierData *enmd)
+{
+ if (is_valid_target(enmd)) {
+ return true;
+ }
+ BKE_modifier_set_error(ob, (ModifierData *)enmd, "Invalid target settings");
return false;
}
@@ -491,7 +499,7 @@ static Mesh *normalEditModifier_do(NormalEditModifierData *enmd,
(enmd->mix_limit == (float)M_PI));
/* Do not run that modifier at all if autosmooth is disabled! */
- if (!is_valid_target(enmd) || mesh->totloop == 0) {
+ if (!is_valid_target_with_error(ctx->object, enmd) || mesh->totloop == 0) {
return mesh;
}
@@ -506,7 +514,8 @@ static Mesh *normalEditModifier_do(NormalEditModifierData *enmd,
if (!(((Mesh *)ob->data)->flag & ME_AUTOSMOOTH))
#endif
{
- BKE_modifier_set_error((ModifierData *)enmd, "Enable 'Auto Smooth' in Object Data Properties");
+ BKE_modifier_set_error(
+ ob, (ModifierData *)enmd, "Enable 'Auto Smooth' in Object Data Properties");
return mesh;
}
diff --git a/source/blender/modifiers/intern/MOD_skin.c b/source/blender/modifiers/intern/MOD_skin.c
index 20445a7006a..203736fb9ff 100644
--- a/source/blender/modifiers/intern/MOD_skin.c
+++ b/source/blender/modifiers/intern/MOD_skin.c
@@ -1760,13 +1760,19 @@ static bool skin_output_branch_hulls(
return result;
}
+typedef enum eSkinErrorFlag {
+ SKIN_ERROR_NO_VALID_ROOT = (1 << 0),
+ SKIN_ERROR_HULL = (1 << 1),
+} eSkinErrorFlag;
+
static BMesh *build_skin(SkinNode *skin_nodes,
int totvert,
const MeshElemMap *emap,
const MEdge *medge,
int totedge,
const MDeformVert *input_dvert,
- SkinModifierData *smd)
+ SkinModifierData *smd,
+ eSkinErrorFlag *r_error)
{
SkinOutput so;
int v;
@@ -1802,7 +1808,7 @@ static BMesh *build_skin(SkinNode *skin_nodes,
skin_update_merged_vertices(skin_nodes, totvert);
if (!skin_output_branch_hulls(&so, skin_nodes, totvert, emap, medge)) {
- BKE_modifier_set_error(&smd->modifier, "Hull error");
+ *r_error |= SKIN_ERROR_HULL;
}
/* Merge triangles here in the hope of providing better target
@@ -1848,7 +1854,7 @@ static void skin_set_orig_indices(Mesh *mesh)
* 2) Generate node frames
* 3) Output vertices and polygons from frames, connections, and hulls
*/
-static Mesh *base_skin(Mesh *origmesh, SkinModifierData *smd)
+static Mesh *base_skin(Mesh *origmesh, SkinModifierData *smd, eSkinErrorFlag *r_error)
{
Mesh *result;
MVertSkin *nodes;
@@ -1878,16 +1884,14 @@ static Mesh *base_skin(Mesh *origmesh, SkinModifierData *smd)
MEM_freeN(emat);
emat = NULL;
- bm = build_skin(skin_nodes, totvert, emap, medge, totedge, dvert, smd);
+ bm = build_skin(skin_nodes, totvert, emap, medge, totedge, dvert, smd, r_error);
MEM_freeN(skin_nodes);
MEM_freeN(emap);
MEM_freeN(emapmem);
if (!has_valid_root) {
- BKE_modifier_set_error(
- &smd->modifier,
- "No valid root vertex found (you need one per mesh island you want to skin)");
+ *r_error |= SKIN_ERROR_NO_VALID_ROOT;
}
if (!bm) {
@@ -1904,7 +1908,7 @@ static Mesh *base_skin(Mesh *origmesh, SkinModifierData *smd)
return result;
}
-static Mesh *final_skin(SkinModifierData *smd, Mesh *mesh)
+static Mesh *final_skin(SkinModifierData *smd, Mesh *mesh, eSkinErrorFlag *r_error)
{
Mesh *result;
@@ -1914,7 +1918,7 @@ static Mesh *final_skin(SkinModifierData *smd, Mesh *mesh)
}
mesh = subdivide_base(mesh);
- result = base_skin(mesh, smd);
+ result = base_skin(mesh, smd, r_error);
BKE_id_free(NULL, mesh);
return result;
@@ -1934,11 +1938,25 @@ static void initData(ModifierData *md)
md->mode |= eModifierMode_Editmode;
}
-static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *UNUSED(ctx), Mesh *mesh)
+static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mesh)
{
- Mesh *result;
+ eSkinErrorFlag error = 0;
+ Mesh *result = final_skin((SkinModifierData *)md, mesh, &error);
+
+ if (error & SKIN_ERROR_NO_VALID_ROOT) {
+ error &= ~SKIN_ERROR_NO_VALID_ROOT;
+ BKE_modifier_set_error(
+ ctx->object,
+ md,
+ "No valid root vertex found (you need one per mesh island you want to skin)");
+ }
+ if (error & SKIN_ERROR_HULL) {
+ error &= ~SKIN_ERROR_HULL;
+ BKE_modifier_set_error(ctx->object, md, "Hull error");
+ }
+ BLI_assert(error == 0);
- if (!(result = final_skin((SkinModifierData *)md, mesh))) {
+ if (result == NULL) {
return mesh;
}
return result;
diff --git a/source/blender/modifiers/intern/MOD_solidify_nonmanifold.c b/source/blender/modifiers/intern/MOD_solidify_nonmanifold.c
index 47adb7ba0bd..8acf07f9181 100644
--- a/source/blender/modifiers/intern/MOD_solidify_nonmanifold.c
+++ b/source/blender/modifiers/intern/MOD_solidify_nonmanifold.c
@@ -2501,16 +2501,25 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md,
MEM_freeN(face_edges);
}
if (edge_index != numNewEdges) {
- BKE_modifier_set_error(
- md, "Internal Error: edges array wrong size: %u instead of %u", numNewEdges, edge_index);
+ BKE_modifier_set_error(ctx->object,
+ md,
+ "Internal Error: edges array wrong size: %u instead of %u",
+ numNewEdges,
+ edge_index);
}
if (poly_index != numNewPolys) {
- BKE_modifier_set_error(
- md, "Internal Error: polys array wrong size: %u instead of %u", numNewPolys, poly_index);
+ BKE_modifier_set_error(ctx->object,
+ md,
+ "Internal Error: polys array wrong size: %u instead of %u",
+ numNewPolys,
+ poly_index);
}
if (loop_index != numNewLoops) {
- BKE_modifier_set_error(
- md, "Internal Error: loops array wrong size: %u instead of %u", numNewLoops, loop_index);
+ BKE_modifier_set_error(ctx->object,
+ md,
+ "Internal Error: loops array wrong size: %u instead of %u",
+ numNewLoops,
+ loop_index);
}
BLI_assert(edge_index == numNewEdges);
BLI_assert(poly_index == numNewPolys);
diff --git a/source/blender/modifiers/intern/MOD_subsurf.c b/source/blender/modifiers/intern/MOD_subsurf.c
index c30dd9f8765..1aa015682dd 100644
--- a/source/blender/modifiers/intern/MOD_subsurf.c
+++ b/source/blender/modifiers/intern/MOD_subsurf.c
@@ -254,7 +254,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
{
Mesh *result = mesh;
#if !defined(WITH_OPENSUBDIV)
- BKE_modifier_set_error(md, "Disabled, built without OpenSubdiv");
+ BKE_modifier_set_error(ctx->object, md, "Disabled, built without OpenSubdiv");
return result;
#endif
SubsurfModifierData *smd = (SubsurfModifierData *)md;
@@ -309,7 +309,7 @@ static void deformMatrices(ModifierData *md,
int num_verts)
{
#if !defined(WITH_OPENSUBDIV)
- BKE_modifier_set_error(md, "Disabled, built without OpenSubdiv");
+ BKE_modifier_set_error(ctx->object, md, "Disabled, built without OpenSubdiv");
return;
#endif
diff --git a/source/blender/modifiers/intern/MOD_surfacedeform.c b/source/blender/modifiers/intern/MOD_surfacedeform.c
index aef7df3282f..0c91c1a7715 100644
--- a/source/blender/modifiers/intern/MOD_surfacedeform.c
+++ b/source/blender/modifiers/intern/MOD_surfacedeform.c
@@ -1009,7 +1009,8 @@ static void bindVert(void *__restrict userdata,
freeBindData(bwdata);
}
-static bool surfacedeformBind(SurfaceDeformModifierData *smd_orig,
+static bool surfacedeformBind(Object *ob,
+ SurfaceDeformModifierData *smd_orig,
SurfaceDeformModifierData *smd_eval,
float (*vertexCos)[3],
uint numverts,
@@ -1030,20 +1031,20 @@ static bool surfacedeformBind(SurfaceDeformModifierData *smd_orig,
vert_edges = MEM_calloc_arrayN(tnumverts, sizeof(*vert_edges), "SDefVertEdgeMap");
if (vert_edges == NULL) {
- BKE_modifier_set_error((ModifierData *)smd_eval, "Out of memory");
+ BKE_modifier_set_error(ob, (ModifierData *)smd_eval, "Out of memory");
return false;
}
adj_array = MEM_malloc_arrayN(tnumedges, 2 * sizeof(*adj_array), "SDefVertEdge");
if (adj_array == NULL) {
- BKE_modifier_set_error((ModifierData *)smd_eval, "Out of memory");
+ BKE_modifier_set_error(ob, (ModifierData *)smd_eval, "Out of memory");
MEM_freeN(vert_edges);
return false;
}
edge_polys = MEM_calloc_arrayN(tnumedges, sizeof(*edge_polys), "SDefEdgeFaceMap");
if (edge_polys == NULL) {
- BKE_modifier_set_error((ModifierData *)smd_eval, "Out of memory");
+ BKE_modifier_set_error(ob, (ModifierData *)smd_eval, "Out of memory");
MEM_freeN(vert_edges);
MEM_freeN(adj_array);
return false;
@@ -1051,14 +1052,14 @@ static bool surfacedeformBind(SurfaceDeformModifierData *smd_orig,
smd_orig->verts = MEM_malloc_arrayN(numverts, sizeof(*smd_orig->verts), "SDefBindVerts");
if (smd_orig->verts == NULL) {
- BKE_modifier_set_error((ModifierData *)smd_eval, "Out of memory");
+ BKE_modifier_set_error(ob, (ModifierData *)smd_eval, "Out of memory");
freeAdjacencyMap(vert_edges, adj_array, edge_polys);
return false;
}
BKE_bvhtree_from_mesh_get(&treeData, target, BVHTREE_FROM_LOOPTRI, 2);
if (treeData.tree == NULL) {
- BKE_modifier_set_error((ModifierData *)smd_eval, "Out of memory");
+ BKE_modifier_set_error(ob, (ModifierData *)smd_eval, "Out of memory");
freeAdjacencyMap(vert_edges, adj_array, edge_polys);
MEM_freeN(smd_orig->verts);
smd_orig->verts = NULL;
@@ -1069,8 +1070,8 @@ static bool surfacedeformBind(SurfaceDeformModifierData *smd_orig,
mpoly, medge, mloop, tnumpoly, tnumedges, vert_edges, adj_array, edge_polys);
if (adj_result == MOD_SDEF_BIND_RESULT_NONMANY_ERR) {
- BKE_modifier_set_error((ModifierData *)smd_eval,
- "Target has edges with more than two polygons");
+ BKE_modifier_set_error(
+ ob, (ModifierData *)smd_eval, "Target has edges with more than two polygons");
freeAdjacencyMap(vert_edges, adj_array, edge_polys);
free_bvhtree_from_mesh(&treeData);
MEM_freeN(smd_orig->verts);
@@ -1097,7 +1098,7 @@ static bool surfacedeformBind(SurfaceDeformModifierData *smd_orig,
};
if (data.targetCos == NULL) {
- BKE_modifier_set_error((ModifierData *)smd_eval, "Out of memory");
+ BKE_modifier_set_error(ob, (ModifierData *)smd_eval, "Out of memory");
freeData((ModifierData *)smd_orig);
return false;
}
@@ -1116,20 +1117,20 @@ static bool surfacedeformBind(SurfaceDeformModifierData *smd_orig,
MEM_freeN(data.targetCos);
if (data.success == MOD_SDEF_BIND_RESULT_MEM_ERR) {
- BKE_modifier_set_error((ModifierData *)smd_eval, "Out of memory");
+ BKE_modifier_set_error(ob, (ModifierData *)smd_eval, "Out of memory");
freeData((ModifierData *)smd_orig);
}
else if (data.success == MOD_SDEF_BIND_RESULT_NONMANY_ERR) {
- BKE_modifier_set_error((ModifierData *)smd_eval,
- "Target has edges with more than two polygons");
+ BKE_modifier_set_error(
+ ob, (ModifierData *)smd_eval, "Target has edges with more than two polygons");
freeData((ModifierData *)smd_orig);
}
else if (data.success == MOD_SDEF_BIND_RESULT_CONCAVE_ERR) {
- BKE_modifier_set_error((ModifierData *)smd_eval, "Target contains concave polygons");
+ BKE_modifier_set_error(ob, (ModifierData *)smd_eval, "Target contains concave polygons");
freeData((ModifierData *)smd_orig);
}
else if (data.success == MOD_SDEF_BIND_RESULT_OVERLAP_ERR) {
- BKE_modifier_set_error((ModifierData *)smd_eval, "Target contains overlapping vertices");
+ BKE_modifier_set_error(ob, (ModifierData *)smd_eval, "Target contains overlapping vertices");
freeData((ModifierData *)smd_orig);
}
else if (data.success == MOD_SDEF_BIND_RESULT_GENERIC_ERR) {
@@ -1137,7 +1138,7 @@ static bool surfacedeformBind(SurfaceDeformModifierData *smd_orig,
* to explain this with a reasonably sized message.
* Though it shouldn't really matter all that much,
* because this is very unlikely to occur */
- BKE_modifier_set_error((ModifierData *)smd_eval, "Target contains invalid polygons");
+ BKE_modifier_set_error(ob, (ModifierData *)smd_eval, "Target contains invalid polygons");
freeData((ModifierData *)smd_orig);
}
@@ -1234,7 +1235,7 @@ static void surfacedeformModifier_do(ModifierData *md,
if (!(smd->flags & MOD_SDEF_BIND)) {
if (smd->verts != NULL) {
if (!DEG_is_active(ctx->depsgraph)) {
- BKE_modifier_set_error(md, "Attempt to bind from inactive dependency graph");
+ BKE_modifier_set_error(ob, md, "Attempt to bind from inactive dependency graph");
return;
}
ModifierData *md_orig = BKE_modifier_get_original(md);
@@ -1246,7 +1247,7 @@ static void surfacedeformModifier_do(ModifierData *md,
Object *ob_target = smd->target;
target = BKE_modifier_get_evaluated_mesh_from_evaluated_object(ob_target, false);
if (!target) {
- BKE_modifier_set_error(md, "No valid target mesh");
+ BKE_modifier_set_error(ob, md, "No valid target mesh");
return;
}
@@ -1256,7 +1257,7 @@ static void surfacedeformModifier_do(ModifierData *md,
/* If not bound, execute bind. */
if (smd->verts == NULL) {
if (!DEG_is_active(ctx->depsgraph)) {
- BKE_modifier_set_error(md, "Attempt to unbind from inactive dependency graph");
+ BKE_modifier_set_error(ob, md, "Attempt to unbind from inactive dependency graph");
return;
}
@@ -1270,7 +1271,7 @@ static void surfacedeformModifier_do(ModifierData *md,
/* Avoid converting edit-mesh data, binding is an exception. */
BKE_mesh_wrapper_ensure_mdata(target);
- if (!surfacedeformBind(smd_orig, smd, vertexCos, numverts, tnumpoly, tnumverts, target)) {
+ if (!surfacedeformBind(ob, smd_orig, smd, vertexCos, numverts, tnumpoly, tnumverts, target)) {
smd->flags &= ~MOD_SDEF_BIND;
}
/* Early abort, this is binding 'call', no need to perform whole evaluation. */
@@ -1279,11 +1280,12 @@ static void surfacedeformModifier_do(ModifierData *md,
/* Poly count checks */
if (smd->numverts != numverts) {
- BKE_modifier_set_error(md, "Vertices changed from %u to %u", smd->numverts, numverts);
+ BKE_modifier_set_error(ob, md, "Vertices changed from %u to %u", smd->numverts, numverts);
return;
}
if (smd->numpoly != tnumpoly) {
- BKE_modifier_set_error(md, "Target polygons changed from %u to %u", smd->numpoly, tnumpoly);
+ BKE_modifier_set_error(
+ ob, md, "Target polygons changed from %u to %u", smd->numpoly, tnumpoly);
return;
}
diff --git a/source/blender/modifiers/intern/MOD_ui_common.c b/source/blender/modifiers/intern/MOD_ui_common.c
index bad76a0b559..ba43434aeb3 100644
--- a/source/blender/modifiers/intern/MOD_ui_common.c
+++ b/source/blender/modifiers/intern/MOD_ui_common.c
@@ -229,14 +229,14 @@ static void modifier_ops_extra_draw(bContext *C, uiLayout *layout, void *md_v)
/* Apply as shapekey. */
if (BKE_modifier_is_same_topology(md) && !BKE_modifier_is_non_geometrical(md)) {
uiItemBooleanO(layout,
- CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Apply As Shapekey"),
+ CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Apply as Shape Key"),
ICON_SHAPEKEY_DATA,
"OBJECT_OT_modifier_apply_as_shapekey",
"keep_modifier",
false);
uiItemBooleanO(layout,
- CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Save As Shapekey"),
+ CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Save as Shape Key"),
ICON_SHAPEKEY_DATA,
"OBJECT_OT_modifier_apply_as_shapekey",
"keep_modifier",
diff --git a/source/blender/modifiers/intern/MOD_volume_displace.cc b/source/blender/modifiers/intern/MOD_volume_displace.cc
index 22bf5cd4893..7293945312a 100644
--- a/source/blender/modifiers/intern/MOD_volume_displace.cc
+++ b/source/blender/modifiers/intern/MOD_volume_displace.cc
@@ -307,7 +307,7 @@ static Volume *modifyVolume(ModifierData *md, const ModifierEvalContext *ctx, Vo
return volume;
#else
UNUSED_VARS(md, ctx);
- BKE_modifier_set_error(md, "Compiled without OpenVDB");
+ BKE_modifier_set_error(ctx->object, md, "Compiled without OpenVDB");
return volume;
#endif
}
diff --git a/source/blender/modifiers/intern/MOD_volume_to_mesh.cc b/source/blender/modifiers/intern/MOD_volume_to_mesh.cc
index ea292155d3c..bbd1bdb6955 100644
--- a/source/blender/modifiers/intern/MOD_volume_to_mesh.cc
+++ b/source/blender/modifiers/intern/MOD_volume_to_mesh.cc
@@ -281,7 +281,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
VolumeGrid *volume_grid = BKE_volume_grid_find(volume, vmmd->grid_name);
if (volume_grid == nullptr) {
- BKE_modifier_set_error(md, "Cannot find '%s' grid", vmmd->grid_name);
+ BKE_modifier_set_error(vmmd->object, md, "Cannot find '%s' grid", vmmd->grid_name);
return input_mesh;
}
@@ -290,7 +290,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
const VolumeGridType grid_type = BKE_volume_grid_type(volume_grid);
VolumeToMeshOp to_mesh_op{*grid, *vmmd, *ctx};
if (!BKE_volume_grid_type_operation(grid_type, to_mesh_op)) {
- BKE_modifier_set_error(md, "Expected a scalar grid");
+ BKE_modifier_set_error(ctx->object, md, "Expected a scalar grid");
return input_mesh;
}
@@ -301,8 +301,8 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
}
return mesh;
#else
- UNUSED_VARS(md, ctx);
- BKE_modifier_set_error(md, "Compiled without OpenVDB");
+ UNUSED_VARS(md);
+ BKE_modifier_set_error(ctx->object, md, "Compiled without OpenVDB");
return input_mesh;
#endif
}
diff --git a/source/blender/modifiers/intern/MOD_weighted_normal.c b/source/blender/modifiers/intern/MOD_weighted_normal.c
index 65bb009fc58..bd15d909834 100644
--- a/source/blender/modifiers/intern/MOD_weighted_normal.c
+++ b/source/blender/modifiers/intern/MOD_weighted_normal.c
@@ -574,7 +574,8 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
if (!(((Mesh *)ob->data)->flag & ME_AUTOSMOOTH))
#endif
{
- BKE_modifier_set_error((ModifierData *)wnmd, "Enable 'Auto Smooth' in Object Data Properties");
+ BKE_modifier_set_error(
+ ctx->object, (ModifierData *)wnmd, "Enable 'Auto Smooth' in Object Data Properties");
return mesh;
}
diff --git a/source/blender/nodes/NOD_geometry_exec.hh b/source/blender/nodes/NOD_geometry_exec.hh
index fe6dc732898..70e2af6c7fb 100644
--- a/source/blender/nodes/NOD_geometry_exec.hh
+++ b/source/blender/nodes/NOD_geometry_exec.hh
@@ -55,7 +55,14 @@ class GValueByName {
}
}
- /* Add a value to the container. */
+ /* Add a value to the container. The container is responsible for destructing the value that is
+ * passed in. */
+ void transfer_ownership_in(StringRef name, GMutablePointer value)
+ {
+ values_.add_new(name, value);
+ }
+
+ /* Add a value to the container. The caller remains responsible for destructing the value. */
void move_in(StringRef name, GMutablePointer value)
{
const CPPType &type = *value.type();
diff --git a/source/blender/nodes/geometry/nodes/node_geo_transform.cc b/source/blender/nodes/geometry/nodes/node_geo_transform.cc
index 1e58cea1ef7..d0ac41b3641 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_transform.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_transform.cc
@@ -35,40 +35,32 @@ static bNodeSocketTemplate geo_node_transform_out[] = {
namespace blender::nodes {
static void geo_transform_exec(bNode *UNUSED(node), GValueByName &inputs, GValueByName &outputs)
{
- GeometryPtr geometry_in = inputs.extract<GeometryPtr>("Geometry");
- GeometryPtr geometry_out;
+ GeometryPtr geometry = inputs.extract<GeometryPtr>("Geometry");
- if (!geometry_in.has_value()) {
- outputs.move_in("Geometry", std::move(geometry_out));
+ if (!geometry.has_value() || !geometry->mesh_available()) {
+ outputs.move_in("Geometry", std::move(geometry));
return;
}
- Mesh *mesh_in = geometry_in->mesh_get_for_read();
- if (mesh_in == nullptr) {
- outputs.move_in("Geometry", std::move(geometry_out));
- return;
- }
+ bke::make_geometry_mutable(geometry);
+
+ Mesh *mesh = geometry->mesh_get_for_write();
const float3 translation = inputs.extract<float3>("Translation");
const float3 rotation = inputs.extract<float3>("Rotation");
const float3 scale = inputs.extract<float3>("Scale");
- geometry_out = GeometryPtr{new Geometry()};
- Mesh *mesh_out = BKE_mesh_copy_for_eval(mesh_in, false);
-
/* Use only translation if rotation and scale are zero. */
if (translation.length() > 0.0f && rotation.length() == 0.0f && scale.length() == 0.0f) {
- BKE_mesh_translate(mesh_out, translation, true);
+ BKE_mesh_translate(mesh, translation, true);
}
else {
float mat[4][4];
loc_eul_size_to_mat4(mat, translation, rotation, scale);
- BKE_mesh_transform(mesh_out, mat, true);
+ BKE_mesh_transform(mesh, mat, true);
}
- geometry_out->mesh_set_and_transfer_ownership(mesh_out);
-
- outputs.move_in("Geometry", std::move(geometry_out));
+ outputs.move_in("Geometry", std::move(geometry));
}
} // namespace blender::nodes
diff --git a/source/blender/sequencer/BKE_sequencer.h b/source/blender/sequencer/BKE_sequencer.h
index 04be46f0ccf..90b1d611842 100644
--- a/source/blender/sequencer/BKE_sequencer.h
+++ b/source/blender/sequencer/BKE_sequencer.h
@@ -20,7 +20,7 @@
#pragma once
/** \file
- * \ingroup bke
+ * \ingroup sequencer
*/
#ifdef __cplusplus
@@ -39,20 +39,37 @@ struct Scene;
struct Sequence;
struct SequenceModifierData;
struct Stereo3dFormat;
-struct StripColorBalance;
struct StripElem;
struct TextVars;
struct bContext;
struct bSound;
-
struct SeqIndexBuildContext;
-#define EARLY_NO_INPUT -1
-#define EARLY_DO_EFFECT 0
-#define EARLY_USE_INPUT_1 1
-#define EARLY_USE_INPUT_2 2
+/* Wipe effect */
+enum {
+ DO_SINGLE_WIPE,
+ DO_DOUBLE_WIPE,
+ /* DO_BOX_WIPE, */ /* UNUSED */
+ /* DO_CROSS_WIPE, */ /* UNUSED */
+ DO_IRIS_WIPE,
+ DO_CLOCK_WIPE,
+};
-/* sequence iterator */
+/* RNA enums, just to be more readable */
+enum {
+ SEQ_SIDE_NONE = 0,
+ SEQ_SIDE_LEFT,
+ SEQ_SIDE_RIGHT,
+ SEQ_SIDE_BOTH,
+ SEQ_SIDE_NO_CHANGE,
+};
+
+/* **********************************************************************
+ * sequencer.c
+ *
+ * Sequencer iterators
+ * **********************************************************************
+ */
typedef struct SeqIterator {
struct Sequence **array;
@@ -62,12 +79,6 @@ typedef struct SeqIterator {
int valid;
} SeqIterator;
-void BKE_sequence_iterator_begin(struct Editing *ed,
- SeqIterator *iter,
- const bool use_current_sequences);
-void BKE_sequence_iterator_next(SeqIterator *iter);
-void BKE_sequence_iterator_end(SeqIterator *iter);
-
#define SEQ_ALL_BEGIN(ed, _seq) \
{ \
SeqIterator iter_macro; \
@@ -90,6 +101,19 @@ void BKE_sequence_iterator_end(SeqIterator *iter);
#define SEQ_CURRENT_END SEQ_ALL_END
+void BKE_sequence_iterator_begin(struct Editing *ed,
+ SeqIterator *iter,
+ const bool use_current_sequences);
+void BKE_sequence_iterator_next(SeqIterator *iter);
+void BKE_sequence_iterator_end(SeqIterator *iter);
+
+/* **********************************************************************
+ * sequencer.c
+ *
+ * Sequencer render functions
+ * **********************************************************************
+ */
+
typedef enum eSeqTaskId {
SEQ_TASK_MAIN_RENDER,
SEQ_TASK_PREFETCH_RENDER,
@@ -118,6 +142,12 @@ typedef struct SeqRenderData {
// bool gpu_full_samples;
} SeqRenderData;
+struct ImBuf *BKE_sequencer_give_ibuf(const SeqRenderData *context, float cfra, int chanshown);
+struct ImBuf *BKE_sequencer_give_ibuf_direct(const SeqRenderData *context,
+ float cfra,
+ struct Sequence *seq);
+void BKE_sequence_alpha_mode_from_extension(struct Sequence *seq);
+void BKE_sequence_init_colorspace(struct Sequence *seq);
void BKE_sequencer_new_render_data(struct Main *bmain,
struct Depsgraph *depsgraph,
struct Scene *scene,
@@ -127,132 +157,24 @@ void BKE_sequencer_new_render_data(struct Main *bmain,
int for_render,
SeqRenderData *r_context);
-int BKE_sequencer_cmp_time_startdisp(const void *a, const void *b);
-
-/* Wipe effect */
-enum {
- DO_SINGLE_WIPE,
- DO_DOUBLE_WIPE,
- /* DO_BOX_WIPE, */ /* UNUSED */
- /* DO_CROSS_WIPE, */ /* UNUSED */
- DO_IRIS_WIPE,
- DO_CLOCK_WIPE,
-};
-
-struct SeqEffectHandle {
- bool multithreaded;
- bool supports_mask;
-
- /* constructors & destructor */
- /* init is _only_ called on first creation */
- void (*init)(struct Sequence *seq);
-
- /* number of input strips needed
- * (called directly after construction) */
- int (*num_inputs)(void);
-
- /* load is called first time after readblenfile in
- * get_sequence_effect automatically */
- void (*load)(struct Sequence *seqconst);
-
- /* duplicate */
- void (*copy)(struct Sequence *dst, struct Sequence *src, const int flag);
-
- /* destruct */
- void (*free)(struct Sequence *seq, const bool do_id_user);
-
- /* returns: -1: no input needed,
- * 0: no early out,
- * 1: out = ibuf1,
- * 2: out = ibuf2 */
- int (*early_out)(struct Sequence *seq, float facf0, float facf1);
-
- /* stores the y-range of the effect IPO */
- void (*store_icu_yrange)(struct Sequence *seq, short adrcode, float *ymin, float *ymax);
-
- /* stores the default facf0 and facf1 if no IPO is present */
- void (*get_default_fac)(struct Sequence *seq, float cfra, float *facf0, float *facf1);
-
- /* execute the effect
- * sequence effects are only required to either support
- * float-rects or byte-rects
- * (mixed cases are handled one layer up...) */
-
- struct ImBuf *(*execute)(const SeqRenderData *context,
- struct Sequence *seq,
- float cfra,
- float facf0,
- float facf1,
- struct ImBuf *ibuf1,
- struct ImBuf *ibuf2,
- struct ImBuf *ibuf3);
-
- struct ImBuf *(*init_execution)(const SeqRenderData *context,
- struct ImBuf *ibuf1,
- struct ImBuf *ibuf2,
- struct ImBuf *ibuf3);
-
- void (*execute_slice)(const SeqRenderData *context,
- struct Sequence *seq,
- float cfra,
- float facf0,
- float facf1,
- struct ImBuf *ibuf1,
- struct ImBuf *ibuf2,
- struct ImBuf *ibuf3,
- int start_line,
- int total_lines,
- struct ImBuf *out);
-};
-
-/* ********************* prototypes *************** */
-
/* **********************************************************************
* sequencer.c
*
- * sequencer render functions
+ * Sequencer color space functions
* ********************************************************************** */
-double BKE_sequencer_rendersize_to_scale_factor(int size);
-struct ImBuf *BKE_sequencer_give_ibuf(const SeqRenderData *context, float cfra, int chanshown);
-struct ImBuf *BKE_sequencer_give_ibuf_direct(const SeqRenderData *context,
- float cfra,
- struct Sequence *seq);
-struct ImBuf *BKE_sequencer_give_ibuf_seqbase(const SeqRenderData *context,
- float cfra,
- int chan_shown,
- struct ListBase *seqbasep);
-struct ImBuf *BKE_sequencer_effect_execute_threaded(struct SeqEffectHandle *sh,
- const SeqRenderData *context,
- struct Sequence *seq,
- float cfra,
- float facf0,
- float facf1,
- struct ImBuf *ibuf1,
- struct ImBuf *ibuf2,
- struct ImBuf *ibuf3);
-
-/* **********************************************************************
- * sequencer.c
- *
- * sequencer color space functions
- * ********************************************************************** */
-
-void BKE_sequencer_imbuf_to_sequencer_space(struct Scene *scene,
- struct ImBuf *ibuf,
- bool make_float);
void BKE_sequencer_imbuf_from_sequencer_space(struct Scene *scene, struct ImBuf *ibuf);
void BKE_sequencer_pixel_from_sequencer_space_v4(struct Scene *scene, float pixel[4]);
/* **********************************************************************
- * sequencer scene functions
+ * sequencer.c
+ *
+ * Sequencer scene functions
* ********************************************************************** */
struct Editing *BKE_sequencer_editing_get(struct Scene *scene, bool alloc);
struct Editing *BKE_sequencer_editing_ensure(struct Scene *scene);
void BKE_sequencer_editing_free(struct Scene *scene, const bool do_id_user);
-
void BKE_sequencer_sort(struct Scene *scene);
-
struct Sequence *BKE_sequencer_from_elem(ListBase *seqbase, struct StripElem *se);
struct Sequence *BKE_sequencer_active_get(struct Scene *scene);
int BKE_sequencer_active_get_pair(struct Scene *scene,
@@ -260,7 +182,6 @@ int BKE_sequencer_active_get_pair(struct Scene *scene,
struct Sequence **seq_other);
void BKE_sequencer_active_set(struct Scene *scene, struct Sequence *seq);
struct Mask *BKE_sequencer_mask_get(struct Scene *scene);
-
/* apply functions recursively */
int BKE_sequencer_base_recursive_apply(struct ListBase *seqbase,
int (*apply_fn)(struct Sequence *seq, void *),
@@ -268,16 +189,14 @@ int BKE_sequencer_base_recursive_apply(struct ListBase *seqbase,
int BKE_sequencer_recursive_apply(struct Sequence *seq,
int (*apply_fn)(struct Sequence *, void *),
void *arg);
-
+float BKE_sequence_get_fps(struct Scene *scene, struct Sequence *seq);
+int BKE_sequencer_find_next_prev_edit(struct Scene *scene,
+ int cfra,
+ const short side,
+ const bool do_skip_mute,
+ const bool do_center,
+ const bool do_unselected);
/* maintenance functions, mostly for RNA */
-/* extern */
-
-void BKE_sequencer_free_clipboard(void);
-
-void BKE_sequencer_base_clipboard_pointers_free(struct ListBase *seqbase);
-void BKE_sequencer_base_clipboard_pointers_store(struct Main *bmain, struct ListBase *seqbase);
-void BKE_sequencer_base_clipboard_pointers_restore(struct ListBase *seqbase, struct Main *bmain);
-
void BKE_sequence_free(struct Scene *scene, struct Sequence *seq, const bool do_clean_animdata);
void BKE_sequence_free_anim(struct Sequence *seq);
const char *BKE_sequence_give_name(struct Sequence *seq);
@@ -294,22 +213,11 @@ void BKE_sequence_movie_reload_if_needed(struct Main *bmain,
bool *r_was_reloaded,
bool *r_can_produce_frames);
int BKE_sequencer_evaluate_frame(struct Scene *scene, int cfra);
-int BKE_sequencer_get_shown_sequences(struct ListBase *seqbasep,
- int cfra,
- int chanshown,
- struct Sequence **seq_arr_out);
-
struct StripElem *BKE_sequencer_give_stripelem(struct Sequence *seq, int cfra);
-
-/* intern */
void BKE_sequencer_update_changed_seq_and_deps(struct Scene *scene,
struct Sequence *changed_seq,
int len_change,
int ibuf_change);
-bool BKE_sequencer_input_have_to_preprocess(const SeqRenderData *context,
- struct Sequence *seq,
- float cfra);
-
bool BKE_sequencer_proxy_rebuild_context(struct Main *bmain,
struct Depsgraph *depsgraph,
struct Scene *scene,
@@ -321,45 +229,19 @@ void BKE_sequencer_proxy_rebuild(struct SeqIndexBuildContext *context,
short *do_update,
float *progress);
void BKE_sequencer_proxy_rebuild_finish(struct SeqIndexBuildContext *context, bool stop);
-
void BKE_sequencer_proxy_set(struct Sequence *seq, bool value);
+bool BKE_sequencer_check_scene_recursion(struct Scene *scene, struct ReportList *reports);
+bool BKE_sequencer_render_loop_check(struct Sequence *seq_main, struct Sequence *seq);
+int BKE_sequencer_cmp_time_startdisp(const void *a, const void *b);
+double BKE_sequencer_rendersize_to_scale_factor(int size);
+
/* **********************************************************************
- * seqcache.c
+ * image_cache.c
*
* Sequencer memory cache management functions
* ********************************************************************** */
-#define SEQ_CACHE_COST_MAX 10.0f
-
-struct ImBuf *BKE_sequencer_cache_get(const SeqRenderData *context,
- struct Sequence *seq,
- float cfra,
- int type,
- bool skip_disk_cache);
-void BKE_sequencer_cache_put(const SeqRenderData *context,
- struct Sequence *seq,
- float cfra,
- int type,
- struct ImBuf *i,
- float cost,
- bool skip_disk_cache);
-bool BKE_sequencer_cache_put_if_possible(const SeqRenderData *context,
- struct Sequence *seq,
- float cfra,
- int type,
- struct ImBuf *nval,
- float cost,
- bool skip_disk_cache);
-bool BKE_sequencer_cache_recycle_item(struct Scene *scene);
-void BKE_sequencer_cache_free_temp_cache(struct Scene *scene, short id, int cfra);
-void BKE_sequencer_cache_destruct(struct Scene *scene);
-void BKE_sequencer_cache_cleanup_all(struct Main *bmain);
void BKE_sequencer_cache_cleanup(struct Scene *scene);
-void BKE_sequencer_cache_cleanup_sequence(struct Scene *scene,
- struct Sequence *seq,
- struct Sequence *seq_changed,
- int invalidate_types,
- bool force_seq_changed_range);
void BKE_sequencer_cache_iterate(struct Scene *scene,
void *userdata,
bool callback_init(void *userdata, size_t item_count),
@@ -368,48 +250,21 @@ void BKE_sequencer_cache_iterate(struct Scene *scene,
int cfra,
int cache_type,
float cost));
-bool BKE_sequencer_cache_is_full(struct Scene *scene);
/* **********************************************************************
- * seqprefetch.c
+ * prefetch.c
*
* Sequencer frame prefetching
* ********************************************************************** */
-void BKE_sequencer_prefetch_start(const SeqRenderData *context, float cfra, float cost);
+#define SEQ_CACHE_COST_MAX 10.0f
void BKE_sequencer_prefetch_stop_all(void);
void BKE_sequencer_prefetch_stop(struct Scene *scene);
-void BKE_sequencer_prefetch_free(struct Scene *scene);
bool BKE_sequencer_prefetch_need_redraw(struct Main *bmain, struct Scene *scene);
-bool BKE_sequencer_prefetch_job_is_running(struct Scene *scene);
-void BKE_sequencer_prefetch_get_time_range(struct Scene *scene, int *start, int *end);
-SeqRenderData *BKE_sequencer_prefetch_get_original_context(const SeqRenderData *context);
-struct Sequence *BKE_sequencer_prefetch_get_original_sequence(struct Sequence *seq,
- struct Scene *scene);
/* **********************************************************************
- * seqeffects.c
+ * sequencer.c
*
- * Sequencer effect strip management functions
- * **********************************************************************
- */
-
-/* intern */
-struct SeqEffectHandle BKE_sequence_get_blend(struct Sequence *seq);
-void BKE_sequence_effect_speed_rebuild_map(struct Scene *scene, struct Sequence *seq, bool force);
-float BKE_sequencer_speed_effect_target_frame_get(const SeqRenderData *context,
- struct Sequence *seq,
- float cfra,
- int input);
-
-/* extern */
-struct SeqEffectHandle BKE_sequence_get_effect(struct Sequence *seq);
-int BKE_sequence_effect_get_num_inputs(int seq_type);
-int BKE_sequence_effect_get_supports_mask(int seq_type);
-void BKE_sequencer_text_font_unload(struct TextVars *data, const bool do_id_user);
-void BKE_sequencer_text_font_load(struct TextVars *data, const bool do_id_user);
-
-/* **********************************************************************
* Sequencer editing functions
* **********************************************************************
*/
@@ -426,13 +281,8 @@ bool BKE_sequence_single_check(struct Sequence *seq);
void BKE_sequence_single_fix(struct Sequence *seq);
bool BKE_sequence_test_overlap(struct ListBase *seqbasep, struct Sequence *test);
void BKE_sequence_translate(struct Scene *scene, struct Sequence *seq, int delta);
-void BKE_sequence_sound_init(struct Scene *scene, struct Sequence *seq);
const struct Sequence *BKE_sequencer_foreground_frame_get(const struct Scene *scene, int frame);
struct ListBase *BKE_sequence_seqbase(struct ListBase *seqbase, struct Sequence *seq);
-struct Sequence *BKE_sequence_metastrip(ListBase *seqbase /* = ed->seqbase */,
- struct Sequence *meta /* = NULL */,
- struct Sequence *seq);
-
void BKE_sequencer_offset_animdata(struct Scene *scene, struct Sequence *seq, int ofs);
void BKE_sequencer_dupe_animdata(struct Scene *scene, const char *name_src, const char *name_dst);
bool BKE_sequence_base_shuffle_ex(struct ListBase *seqbasep,
@@ -454,26 +304,11 @@ struct Sequence *BKE_sequence_dupli_recursive(const struct Scene *scene_src,
struct Sequence *seq,
int dupe_flag);
int BKE_sequence_swap(struct Sequence *seq_a, struct Sequence *seq_b, const char **error_str);
-
-bool BKE_sequence_check_depend(struct Sequence *seq, struct Sequence *cur);
-void BKE_sequence_invalidate_cache_raw(struct Scene *scene, struct Sequence *seq);
-void BKE_sequence_invalidate_cache_preprocessed(struct Scene *scene, struct Sequence *seq);
-void BKE_sequence_invalidate_cache_composite(struct Scene *scene, struct Sequence *seq);
-void BKE_sequence_invalidate_dependent(struct Scene *scene, struct Sequence *seq);
-void BKE_sequence_invalidate_scene_strips(struct Main *bmain, struct Scene *scene_target);
-void BKE_sequence_invalidate_movieclip_strips(struct Main *bmain, struct MovieClip *clip_target);
-void BKE_sequence_invalidate_cache_in_range(struct Scene *scene,
- struct Sequence *seq,
- struct Sequence *range_mask,
- int invalidate_types);
-
void BKE_sequencer_update_sound_bounds_all(struct Scene *scene);
void BKE_sequencer_update_sound_bounds(struct Scene *scene, struct Sequence *seq);
void BKE_sequencer_update_muting(struct Editing *ed);
void BKE_sequencer_update_sound(struct Scene *scene, struct bSound *sound);
-
void BKE_sequencer_refresh_sound_length(struct Main *bmain, struct Scene *scene);
-
void BKE_sequence_base_unique_name_recursive(ListBase *seqbasep, struct Sequence *seq);
void BKE_sequence_base_dupli_recursive(const struct Scene *scene_src,
struct Scene *scene_dst,
@@ -482,12 +317,39 @@ void BKE_sequence_base_dupli_recursive(const struct Scene *scene_src,
int dupe_flag,
const int flag);
bool BKE_sequence_is_valid_check(struct Sequence *seq);
-
-void BKE_sequencer_clear_scene_in_allseqs(struct Main *bmain, struct Scene *sce);
-
struct Sequence *BKE_sequence_get_by_name(struct ListBase *seqbase,
const char *name,
bool recursive);
+void BKE_sequencer_flag_for_removal(struct Scene *scene,
+ struct ListBase *seqbase,
+ struct Sequence *seq);
+void BKE_sequencer_remove_flagged_sequences(struct Scene *scene, struct ListBase *seqbase);
+
+/* **********************************************************************
+ * sequencer.c
+ *
+ * Cache invalidation
+ * **********************************************************************
+ */
+
+void BKE_sequence_invalidate_cache_raw(struct Scene *scene, struct Sequence *seq);
+void BKE_sequence_invalidate_cache_preprocessed(struct Scene *scene, struct Sequence *seq);
+void BKE_sequence_invalidate_cache_composite(struct Scene *scene, struct Sequence *seq);
+void BKE_sequence_invalidate_dependent(struct Scene *scene, struct Sequence *seq);
+void BKE_sequence_invalidate_scene_strips(struct Main *bmain, struct Scene *scene_target);
+void BKE_sequence_invalidate_movieclip_strips(struct Main *bmain, struct MovieClip *clip_target);
+void BKE_sequence_invalidate_cache_in_range(struct Scene *scene,
+ struct Sequence *seq,
+ struct Sequence *range_mask,
+ int invalidate_types);
+void BKE_sequencer_all_free_anim_ibufs(struct Scene *scene, int cfra);
+
+/* **********************************************************************
+ * sequencer.c
+ *
+ * Add strips
+ * **********************************************************************
+ */
/* api for adding new sequence strips */
typedef struct SeqLoadInfo {
@@ -529,31 +391,6 @@ typedef struct SeqLoadInfo {
typedef struct Sequence *(*SeqLoadFn)(struct bContext *, ListBase *, struct SeqLoadInfo *);
struct Sequence *BKE_sequence_alloc(ListBase *lb, int cfra, int machine, int type);
-
-/* Generate new UUID for the given sequence. */
-void BKE_sequence_session_uuid_generate(struct Sequence *sequence);
-
-void BKE_sequence_alpha_mode_from_extension(struct Sequence *seq);
-void BKE_sequence_init_colorspace(struct Sequence *seq);
-
-float BKE_sequence_get_fps(struct Scene *scene, struct Sequence *seq);
-float BKE_sequencer_give_stripelem_index(struct Sequence *seq, float cfra);
-
-/* RNA enums, just to be more readable */
-enum {
- SEQ_SIDE_NONE = 0,
- SEQ_SIDE_LEFT,
- SEQ_SIDE_RIGHT,
- SEQ_SIDE_BOTH,
- SEQ_SIDE_NO_CHANGE,
-};
-int BKE_sequencer_find_next_prev_edit(struct Scene *scene,
- int cfra,
- const short side,
- const bool do_skip_mute,
- const bool do_center,
- const bool do_unselected);
-
struct Sequence *BKE_sequencer_add_image_strip(struct bContext *C,
ListBase *seqbasep,
struct SeqLoadInfo *seq_load);
@@ -564,11 +401,13 @@ struct Sequence *BKE_sequencer_add_movie_strip(struct bContext *C,
ListBase *seqbasep,
struct SeqLoadInfo *seq_load);
-/* copy/paste */
-extern ListBase seqbase_clipboard;
-extern int seqbase_clipboard_frame;
+/* **********************************************************************
+ * modifier.c
+ *
+ * Modifiers
+ * **********************************************************************
+ */
-/* modifiers */
typedef struct SequenceModifierTypeInfo {
/* default name for the modifier */
char name[64]; /* MAX_NAME */
@@ -596,7 +435,6 @@ typedef struct SequenceModifierTypeInfo {
} SequenceModifierTypeInfo;
const struct SequenceModifierTypeInfo *BKE_sequence_modifier_type_info_get(int type);
-
struct SequenceModifierData *BKE_sequence_modifier_new(struct Sequence *seq,
const char *name,
int type);
@@ -611,34 +449,111 @@ struct ImBuf *BKE_sequence_modifier_apply_stack(const SeqRenderData *context,
struct ImBuf *ibuf,
int cfra);
void BKE_sequence_modifier_list_copy(struct Sequence *seqn, struct Sequence *seq);
-
int BKE_sequence_supports_modifiers(struct Sequence *seq);
-/* internal filters */
-struct ImBuf *BKE_sequencer_render_mask_input(const SeqRenderData *context,
- int mask_input_type,
- struct Sequence *mask_sequence,
- struct Mask *mask_id,
- int cfra,
- int fra_offset,
- bool make_float);
-void BKE_sequencer_color_balance_apply(struct StripColorBalance *cb,
- struct ImBuf *ibuf,
- float mul,
- bool make_float,
- struct ImBuf *mask_input);
+/* **********************************************************************
+ * seqeffects.c
+ *
+ * Sequencer effect strip management functions
+ * **********************************************************************
+ */
-void BKE_sequencer_all_free_anim_ibufs(struct Scene *scene, int cfra);
-bool BKE_sequencer_check_scene_recursion(struct Scene *scene, struct ReportList *reports);
-bool BKE_sequencer_render_loop_check(struct Sequence *seq_main, struct Sequence *seq);
-void BKE_sequencer_flag_for_removal(struct Scene *scene,
- struct ListBase *seqbase,
- struct Sequence *seq);
-void BKE_sequencer_remove_flagged_sequences(struct Scene *scene, struct ListBase *seqbase);
+struct SeqEffectHandle {
+ bool multithreaded;
+ bool supports_mask;
+
+ /* constructors & destructor */
+ /* init is _only_ called on first creation */
+ void (*init)(struct Sequence *seq);
+
+ /* number of input strips needed
+ * (called directly after construction) */
+ int (*num_inputs)(void);
+
+ /* load is called first time after readblenfile in
+ * get_sequence_effect automatically */
+ void (*load)(struct Sequence *seqconst);
+
+ /* duplicate */
+ void (*copy)(struct Sequence *dst, struct Sequence *src, const int flag);
+
+ /* destruct */
+ void (*free)(struct Sequence *seq, const bool do_id_user);
+
+ /* returns: -1: no input needed,
+ * 0: no early out,
+ * 1: out = ibuf1,
+ * 2: out = ibuf2 */
+ int (*early_out)(struct Sequence *seq, float facf0, float facf1);
+
+ /* stores the y-range of the effect IPO */
+ void (*store_icu_yrange)(struct Sequence *seq, short adrcode, float *ymin, float *ymax);
+
+ /* stores the default facf0 and facf1 if no IPO is present */
+ void (*get_default_fac)(struct Sequence *seq, float cfra, float *facf0, float *facf1);
+
+ /* execute the effect
+ * sequence effects are only required to either support
+ * float-rects or byte-rects
+ * (mixed cases are handled one layer up...) */
+
+ struct ImBuf *(*execute)(const SeqRenderData *context,
+ struct Sequence *seq,
+ float cfra,
+ float facf0,
+ float facf1,
+ struct ImBuf *ibuf1,
+ struct ImBuf *ibuf2,
+ struct ImBuf *ibuf3);
+
+ struct ImBuf *(*init_execution)(const SeqRenderData *context,
+ struct ImBuf *ibuf1,
+ struct ImBuf *ibuf2,
+ struct ImBuf *ibuf3);
+
+ void (*execute_slice)(const SeqRenderData *context,
+ struct Sequence *seq,
+ float cfra,
+ float facf0,
+ float facf1,
+ struct ImBuf *ibuf1,
+ struct ImBuf *ibuf2,
+ struct ImBuf *ibuf3,
+ int start_line,
+ int total_lines,
+ struct ImBuf *out);
+};
+
+struct SeqEffectHandle BKE_sequence_get_effect(struct Sequence *seq);
+int BKE_sequence_effect_get_num_inputs(int seq_type);
+void BKE_sequencer_text_font_unload(struct TextVars *data, const bool do_id_user);
+void BKE_sequencer_text_font_load(struct TextVars *data, const bool do_id_user);
+
+/* **********************************************************************
+ * sequencer.c
+ *
+ * Clipboard
+ * **********************************************************************
+ */
+
+extern ListBase seqbase_clipboard;
+extern int seqbase_clipboard_frame;
+void BKE_sequencer_base_clipboard_pointers_store(struct Main *bmain, struct ListBase *seqbase);
+void BKE_sequencer_base_clipboard_pointers_restore(struct ListBase *seqbase, struct Main *bmain);
+void BKE_sequencer_free_clipboard(void);
+
+/* **********************************************************************
+ * sequencer.c
+ *
+ * Depsgraph
+ * **********************************************************************
+ */
/* A debug and development function which checks whether sequences have unique UUIDs.
* Errors will be reported to the console. */
void BKE_sequencer_check_uuids_unique_and_report(const struct Scene *scene);
+/* Generate new UUID for the given sequence. */
+void BKE_sequence_session_uuid_generate(struct Sequence *sequence);
#ifdef __cplusplus
}
diff --git a/source/blender/sequencer/CMakeLists.txt b/source/blender/sequencer/CMakeLists.txt
index 866eba9ca41..84684987ca7 100644
--- a/source/blender/sequencer/CMakeLists.txt
+++ b/source/blender/sequencer/CMakeLists.txt
@@ -20,6 +20,7 @@
set(INC
.
+ intern
../blenkernel
../blenlib
../blentranslation
@@ -42,6 +43,7 @@ set(SRC
BKE_sequencer.h
intern/sequencer.c
+ intern/sequencer.h
intern/image_cache.c
intern/effects.c
intern/modifier.c
diff --git a/source/blender/sequencer/intern/effects.c b/source/blender/sequencer/intern/effects.c
index b4bc2d25155..a05a69a522f 100644
--- a/source/blender/sequencer/intern/effects.c
+++ b/source/blender/sequencer/intern/effects.c
@@ -61,6 +61,8 @@
#include "BLF_api.h"
+#include "sequencer.h"
+
static struct SeqEffectHandle get_sequence_effect_impl(int seq_type);
static void slice_get_byte_buffers(const SeqRenderData *context,
diff --git a/source/blender/sequencer/intern/image_cache.c b/source/blender/sequencer/intern/image_cache.c
index 7d2858050be..ea59625065b 100644
--- a/source/blender/sequencer/intern/image_cache.c
+++ b/source/blender/sequencer/intern/image_cache.c
@@ -49,6 +49,8 @@
#include "BKE_scene.h"
#include "BKE_sequencer.h"
+#include "sequencer.h"
+
/**
* Sequencer Cache Design Notes
* ============================
diff --git a/source/blender/sequencer/intern/modifier.c b/source/blender/sequencer/intern/modifier.c
index a38fe252731..d31be56b036 100644
--- a/source/blender/sequencer/intern/modifier.c
+++ b/source/blender/sequencer/intern/modifier.c
@@ -45,6 +45,8 @@
#include "IMB_imbuf.h"
#include "IMB_imbuf_types.h"
+#include "sequencer.h"
+
static SequenceModifierTypeInfo *modifiersTypes[NUM_SEQUENCE_MODIFIER_TYPES];
static bool modifierTypesInit = false;
diff --git a/source/blender/sequencer/intern/prefetch.c b/source/blender/sequencer/intern/prefetch.c
index 013abb716d4..c22fb3c4ad8 100644
--- a/source/blender/sequencer/intern/prefetch.c
+++ b/source/blender/sequencer/intern/prefetch.c
@@ -54,6 +54,8 @@
#include "DEG_depsgraph_debug.h"
#include "DEG_depsgraph_query.h"
+#include "sequencer.h"
+
typedef struct PrefetchJob {
struct PrefetchJob *next, *prev;
@@ -319,6 +321,7 @@ static void seq_prefetch_update_scene(Scene *scene)
return;
}
+ pfjob->scene = scene;
seq_prefetch_free_depsgraph(pfjob);
seq_prefetch_init_depsgraph(pfjob);
}
@@ -499,15 +502,14 @@ static PrefetchJob *seq_prefetch_start(const SeqRenderData *context, float cfra)
BLI_mutex_init(&pfjob->prefetch_suspend_mutex);
BLI_condition_init(&pfjob->prefetch_suspend_cond);
- pfjob->bmain = context->bmain;
pfjob->bmain_eval = BKE_main_new();
-
pfjob->scene = context->scene;
seq_prefetch_init_depsgraph(pfjob);
}
}
seq_prefetch_update_scene(context->scene);
seq_prefetch_update_context(context);
+ pfjob->bmain = context->bmain;
pfjob->cfra = cfra;
pfjob->num_frames_prefetched = 1;
diff --git a/source/blender/sequencer/intern/sequencer.c b/source/blender/sequencer/intern/sequencer.c
index c8dfb6b886f..acbdc28c6fd 100644
--- a/source/blender/sequencer/intern/sequencer.c
+++ b/source/blender/sequencer/intern/sequencer.c
@@ -96,6 +96,8 @@
#include "RE_engine.h"
+#include "sequencer.h"
+
#ifdef WITH_AUDASPACE
# include <AUD_Special.h>
#endif
@@ -6045,6 +6047,12 @@ static Sequence *sequencer_check_scene_recursion(Scene *scene, ListBase *seqbase
return seq;
}
+ if (seq->type == SEQ_TYPE_SCENE && (seq->flag & SEQ_SCENE_STRIPS)) {
+ if (sequencer_check_scene_recursion(scene, &seq->scene->ed->seqbase)) {
+ return seq;
+ }
+ }
+
if (seq->type == SEQ_TYPE_META && sequencer_check_scene_recursion(scene, &seq->seqbase)) {
return seq;
}
diff --git a/source/blender/sequencer/intern/sequencer.h b/source/blender/sequencer/intern/sequencer.h
new file mode 100644
index 00000000000..55e19f80fcd
--- /dev/null
+++ b/source/blender/sequencer/intern/sequencer.h
@@ -0,0 +1,190 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2004 Blender Foundation.
+ * All rights reserved.
+ */
+
+#pragma once
+
+/** \file
+ * \ingroup sequencer
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct Editing;
+struct ImBuf;
+struct Main;
+struct Mask;
+struct Scene;
+struct Sequence;
+struct StripColorBalance;
+struct StripElem;
+
+#define EARLY_NO_INPUT -1
+#define EARLY_DO_EFFECT 0
+#define EARLY_USE_INPUT_1 1
+#define EARLY_USE_INPUT_2 2
+
+/* **********************************************************************
+ * sequencer.c
+ *
+ * sequencer render functions
+ * ********************************************************************** */
+
+struct ImBuf *BKE_sequencer_give_ibuf_seqbase(const SeqRenderData *context,
+ float cfra,
+ int chan_shown,
+ struct ListBase *seqbasep);
+struct ImBuf *BKE_sequencer_effect_execute_threaded(struct SeqEffectHandle *sh,
+ const SeqRenderData *context,
+ struct Sequence *seq,
+ float cfra,
+ float facf0,
+ float facf1,
+ struct ImBuf *ibuf1,
+ struct ImBuf *ibuf2,
+ struct ImBuf *ibuf3);
+struct ImBuf *BKE_sequencer_render_mask_input(const SeqRenderData *context,
+ int mask_input_type,
+ struct Sequence *mask_sequence,
+ struct Mask *mask_id,
+ int cfra,
+ int fra_offset,
+ bool make_float);
+void BKE_sequencer_color_balance_apply(struct StripColorBalance *cb,
+ struct ImBuf *ibuf,
+ float mul,
+ bool make_float,
+ struct ImBuf *mask_input);
+
+/* **********************************************************************
+ * sequencer.c
+ *
+ * sequencer color space functions
+ * ********************************************************************** */
+
+void BKE_sequencer_imbuf_to_sequencer_space(struct Scene *scene,
+ struct ImBuf *ibuf,
+ bool make_float);
+
+/* **********************************************************************
+ * sequencer.c
+ *
+ * sequencer scene functions
+ * ********************************************************************** */
+
+void BKE_sequencer_base_clipboard_pointers_free(struct ListBase *seqbase);
+int BKE_sequencer_get_shown_sequences(struct ListBase *seqbasep,
+ int cfra,
+ int chanshown,
+ struct Sequence **seq_arr_out);
+bool BKE_sequencer_input_have_to_preprocess(const SeqRenderData *context,
+ struct Sequence *seq,
+ float cfra);
+float BKE_sequencer_give_stripelem_index(struct Sequence *seq, float cfra);
+
+/* **********************************************************************
+ * image_cache.c
+ *
+ * Sequencer memory cache management functions
+ * ********************************************************************** */
+
+struct ImBuf *BKE_sequencer_cache_get(const SeqRenderData *context,
+ struct Sequence *seq,
+ float cfra,
+ int type,
+ bool skip_disk_cache);
+void BKE_sequencer_cache_put(const SeqRenderData *context,
+ struct Sequence *seq,
+ float cfra,
+ int type,
+ struct ImBuf *i,
+ float cost,
+ bool skip_disk_cache);
+bool BKE_sequencer_cache_put_if_possible(const SeqRenderData *context,
+ struct Sequence *seq,
+ float cfra,
+ int type,
+ struct ImBuf *nval,
+ float cost,
+ bool skip_disk_cache);
+bool BKE_sequencer_cache_recycle_item(struct Scene *scene);
+void BKE_sequencer_cache_free_temp_cache(struct Scene *scene, short id, int cfra);
+void BKE_sequencer_cache_destruct(struct Scene *scene);
+void BKE_sequencer_cache_cleanup_all(struct Main *bmain);
+void BKE_sequencer_cache_cleanup_sequence(struct Scene *scene,
+ struct Sequence *seq,
+ struct Sequence *seq_changed,
+ int invalidate_types,
+ bool force_seq_changed_range);
+bool BKE_sequencer_cache_is_full(struct Scene *scene);
+
+/* **********************************************************************
+ * prefetch.c
+ *
+ * Sequencer frame prefetching
+ * ********************************************************************** */
+
+void BKE_sequencer_prefetch_start(const SeqRenderData *context, float cfra, float cost);
+void BKE_sequencer_prefetch_free(struct Scene *scene);
+bool BKE_sequencer_prefetch_job_is_running(struct Scene *scene);
+void BKE_sequencer_prefetch_get_time_range(struct Scene *scene, int *start, int *end);
+SeqRenderData *BKE_sequencer_prefetch_get_original_context(const SeqRenderData *context);
+struct Sequence *BKE_sequencer_prefetch_get_original_sequence(struct Sequence *seq,
+ struct Scene *scene);
+
+/* **********************************************************************
+ * seqeffects.c
+ *
+ * Sequencer effect strip management functions
+ * **********************************************************************
+ */
+
+struct SeqEffectHandle BKE_sequence_get_blend(struct Sequence *seq);
+void BKE_sequence_effect_speed_rebuild_map(struct Scene *scene, struct Sequence *seq, bool force);
+float BKE_sequencer_speed_effect_target_frame_get(const SeqRenderData *context,
+ struct Sequence *seq,
+ float cfra,
+ int input);
+
+/* **********************************************************************
+ * sequencer.c
+ *
+ * Sequencer editing functions
+ * **********************************************************************
+ */
+
+void BKE_sequence_sound_init(struct Scene *scene, struct Sequence *seq);
+struct Sequence *BKE_sequence_metastrip(ListBase *seqbase /* = ed->seqbase */,
+ struct Sequence *meta /* = NULL */,
+ struct Sequence *seq);
+
+/* **********************************************************************
+ * sequencer.c
+ *
+ * Unused
+ * **********************************************************************
+ */
+bool BKE_sequence_check_depend(struct Sequence *seq, struct Sequence *cur);
+void BKE_sequencer_clear_scene_in_allseqs(struct Main *bmain, struct Scene *sce);
+int BKE_sequence_effect_get_supports_mask(int seq_type);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c
index 613de5a9b17..4604f66d866 100644
--- a/source/blender/windowmanager/intern/wm_operators.c
+++ b/source/blender/windowmanager/intern/wm_operators.c
@@ -3771,7 +3771,7 @@ static void gesture_circle_modal_keymap(wmKeyConfig *keyconf)
{GESTURE_MODAL_CIRCLE_SIZE, "SIZE", 0, "Size", ""},
{GESTURE_MODAL_SELECT, "SELECT", 0, "Select", ""},
- {GESTURE_MODAL_DESELECT, "DESELECT", 0, "DeSelect", ""},
+ {GESTURE_MODAL_DESELECT, "DESELECT", 0, "Deselect", ""},
{GESTURE_MODAL_NOP, "NOP", 0, "No Operation", ""},
{0, NULL, 0, NULL, NULL},
@@ -3834,7 +3834,7 @@ static void gesture_box_modal_keymap(wmKeyConfig *keyconf)
static const EnumPropertyItem modal_items[] = {
{GESTURE_MODAL_CANCEL, "CANCEL", 0, "Cancel", ""},
{GESTURE_MODAL_SELECT, "SELECT", 0, "Select", ""},
- {GESTURE_MODAL_DESELECT, "DESELECT", 0, "DeSelect", ""},
+ {GESTURE_MODAL_DESELECT, "DESELECT", 0, "Deselect", ""},
{GESTURE_MODAL_BEGIN, "BEGIN", 0, "Begin", ""},
{GESTURE_MODAL_MOVE, "MOVE", 0, "Move", ""},
{0, NULL, 0, NULL, NULL},