diff options
author | Hans Goudey <h.goudey@me.com> | 2020-10-26 18:41:51 +0300 |
---|---|---|
committer | Hans Goudey <h.goudey@me.com> | 2020-10-26 18:41:51 +0300 |
commit | 5288298cfa6fe735204350f4826daeed52375c43 (patch) | |
tree | 45714678f3ffb98b69df884eddb29c7df1de2644 | |
parent | 3c02fdb2c87bf8b1a8f46360d2c168ad59198d8f (diff) | |
parent | e04491073d91434a5c3a93ec36d94efd3b540eec (diff) |
Merge branch 'geometry-nodes' into geometry-nodes-boolean-node
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}, |