Fix #110108: NLA absolute snapping #111984

Merged
Christoph Lendenfeld merged 9 commits from ChrisLend/blender:fix_nla_marker_snap into main 2023-09-15 09:52:48 +02:00
140 changed files with 2102 additions and 1992 deletions
Showing only changes of commit f9fc90ed3f - Show all commits

View File

@ -514,7 +514,7 @@ check_spelling_shaders: .FORCE
PYTHONIOENCODING=utf_8 $(PYTHON) \
"$(BLENDER_DIR)/tools/check_source/check_spelling.py" \
--cache-file=$(CHECK_SPELLING_CACHE) \
--match=".*\.(osl|msl|glsl)$$" \
--match=".*\.(osl|metal|msl|glsl)$$" \
"$(BLENDER_DIR)/intern/" \
"$(BLENDER_DIR)/source/"

View File

@ -12,6 +12,9 @@ if(DEFINED HIP_ROOT_DIR AND HIP_ROOT_DIR)
# Pass.
elseif(DEFINED ENV{HIP_ROOT_DIR})
set(HIP_ROOT_DIR $ENV{HIP_ROOT_DIR})
elseif(DEFINED ENV{HIP_PATH})
# Built-in environment variable from SDK.
set(HIP_ROOT_DIR $ENV{HIP_PATH})
else()
set(HIP_ROOT_DIR "")
endif()

View File

@ -12,6 +12,9 @@ if(DEFINED HIPRT_ROOT_DIR AND HIPRT_ROOT_DIR)
# Pass.
elseif(DEFINED ENV{HIPRT_ROOT_DIR})
set(HIPRT_ROOT_DIR $ENV{HIPRT_ROOT_DIR})
elseif(DEFINED ENV{HIP_PATH})
# Built-in environment variable from SDK.
set(HIPRT_ROOT_DIR $ENV{HIP_PATH})
else()
set(HIPRT_ROOT_DIR "")
endif()
@ -24,6 +27,7 @@ find_path(HIPRT_INCLUDE_DIR
NAMES
hiprt/hiprt.h
HINTS
${_hiprt_SEARCH_DIRS}/include
${_hiprt_SEARCH_DIRS}
)
@ -36,6 +40,7 @@ if(HIPRT_INCLUDE_DIR)
NAMES
hiprt${_hiprt_version}_amd_lib_win.bc
HINTS
${HIPRT_ROOT_DIR}/bin
${HIPRT_ROOT_DIR}/dist/bin/Release
NO_DEFAULT_PATH
)

View File

@ -21,28 +21,28 @@ extern void *AUD_createSet(void);
/**
* Deletes a set.
* \param set The set to delete.
* \param set: The set to delete.
*/
extern void AUD_destroySet(void *set);
/**
* Removes an entry from a set.
* \param set The set work on.
* \param entry The entry to remove.
* \param set: The set work on.
* \param entry: The entry to remove.
* \return Whether the entry was in the set or not.
*/
extern char AUD_removeSet(void *set, void *entry);
/**
* Adds a new entry to a set.
* \param set The set work on.
* \param entry The entry to add.
* \param set: The set work on.
* \param entry: The entry to add.
*/
extern void AUD_addSet(void *set, void *entry);
/**
* Removes one entry from a set and returns it.
* \param set The set work on.
* \param set: The set work on.
* \return The entry or NULL if the set is empty.
*/
extern void *AUD_getSet(void *set);

View File

@ -202,7 +202,7 @@ bool metalrt_shadow_all_hit(constant KernelParamsMetal &launch_params_metal,
type = segment.type;
prim = segment.prim;
/* Filter out curve endcaps */
/* Filter out curve end-caps. */
if (u == 0.0f || u == 1.0f) {
/* continue search */
return true;
@ -349,7 +349,7 @@ inline TReturnType metalrt_visibility_test(
if (intersection_type == METALRT_HIT_BOUNDING_BOX &&
(type == PRIMITIVE_CURVE_THICK || type == PRIMITIVE_CURVE_RIBBON))
{
/* Filter out curve endcaps. */
/* Filter out curve end-caps. */
if (u == 0.0f || u == 1.0f) {
result.accept = false;
result.continue_search = true;

View File

@ -473,7 +473,6 @@ class GHOST_ISystem {
/**
* Returns the selection buffer
* \return "unsigned char" from X11 XA_CUT_BUFFER0 buffer
*
*/
virtual char *getClipboard(bool selection) const = 0;

View File

@ -327,7 +327,6 @@ class GHOST_System : public GHOST_ISystem {
* Returns the selection buffer
* \param selection: Only used on X11.
* \return Returns the clipboard data
*
*/
virtual char *getClipboard(bool selection) const = 0;

View File

@ -19,7 +19,7 @@
47:Slovak (Slovenčina):sk_SK
#
0:In Progress:
11:Czech (Český):cs_CZ
11:Czech (Čeština):cs_CZ
5:German (Deutsch):de_DE
4:Italian (Italiano):it_IT
48:Georgian (ქართული):ka

View File

@ -44,7 +44,7 @@ LANGUAGES = (
(8, "French (Français)", "fr_FR"),
(9, "Spanish (Español)", "es"),
(10, "Catalan (Català)", "ca_AD"),
(11, "Czech (Český)", "cs_CZ"),
(11, "Czech (Čeština)", "cs_CZ"),
(12, "Portuguese (Português)", "pt_PT"),
(13, "Simplified Chinese (简体中文)", "zh_CN"),
(14, "Traditional Chinese (繁體中文)", "zh_TW"),

View File

@ -83,7 +83,7 @@ class _BPyOpsSubModOp:
return _op_poll(self.idname_py(), C_exec)
def idname(self):
# submod.foo -> SUBMOD_OT_foo
# `submod.foo` -> `SUBMOD_OT_foo`.
return self._module.upper() + "_OT_" + self._func
def idname_py(self):

View File

@ -199,8 +199,8 @@ def load_scripts(*, reload_scripts=False, refresh_scripts=False, extensions=True
:arg refresh_scripts: only load scripts which are not already loaded
as modules.
:type refresh_scripts: bool
:arg: extensions: Loads additional scripts (add-ons & app-templates).
:type: extensions: bool
:arg extensions: Loads additional scripts (add-ons & app-templates).
:type extensions: bool
"""
use_time = use_class_register_check = _bpy.app.debug_python
use_user = not _is_factory_startup

View File

@ -362,15 +362,15 @@ def _template_items_transform_actions(
("transform.translate", {"type": params.select_mouse, "value": 'CLICK_DRAG'}, None),
op_tool_optional(
("transform.translate", {"type": 'G', "value": 'PRESS'},
{"properties": [("alt_navigation", params.use_alt_navigation)]}),
{"properties": [("alt_navigation", params.use_alt_navigation)]}),
(op_tool_cycle, "builtin.move"), params),
op_tool_optional(
("transform.rotate", {"type": 'R', "value": 'PRESS'},
{"properties": [("alt_navigation", params.use_alt_navigation)]}),
{"properties": [("alt_navigation", params.use_alt_navigation)]}),
(op_tool_cycle, "builtin.rotate"), params),
op_tool_optional(
("transform.resize", {"type": 'S', "value": 'PRESS'},
{"properties": [("alt_navigation", params.use_alt_navigation)]}),
{"properties": [("alt_navigation", params.use_alt_navigation)]}),
(op_tool_cycle, "builtin.scale"), params),
]
@ -568,7 +568,6 @@ def _template_items_tool_select(
# Always use the cursor operator where possible,
# needed for time-line views where we always want to be able to scrub time.
cursor_prioritize=False,
operator_props=(),
fallback=False,
):
if not params.legacy and not fallback:
@ -585,11 +584,11 @@ def _template_items_tool_select(
if select_passthrough:
return [
(operator, {"type": 'LEFTMOUSE', "value": 'PRESS'},
{"properties": [("deselect_all", True), ("select_passthrough", True), *operator_props]}),
{"properties": [("deselect_all", True), ("select_passthrough", True)]}),
(operator, {"type": 'LEFTMOUSE', "value": 'CLICK'},
{"properties": [("deselect_all", True), *operator_props]}),
{"properties": [("deselect_all", True)]}),
(operator, {"type": 'LEFTMOUSE', "value": 'PRESS', "shift": True},
{"properties": [("deselect_all", False), ("toggle", True), *operator_props]}),
{"properties": [("deselect_all", False), ("toggle", True)]}),
("transform.translate", {"type": 'LEFTMOUSE', "value": 'CLICK_DRAG'},
{"properties": [("release_confirm", True)]}),
]
@ -600,9 +599,9 @@ def _template_items_tool_select(
# unless it is expected that the tool should operate on the selection (click-drag to rip for e.g.).
return [
(operator, {"type": 'LEFTMOUSE', "value": 'PRESS'},
{"properties": [("deselect_all", True), *operator_props]}),
{"properties": [("deselect_all", True)]}),
(operator, {"type": 'LEFTMOUSE', "value": 'PRESS', "shift": True},
{"properties": [("toggle", True), *operator_props]}),
{"properties": [("toggle", True)]}),
# Fallback key-map must transform as the primary tool is expected
# to be accessed via gizmos in this case. See: #96885.
@ -1895,7 +1894,7 @@ def km_graph_editor(params):
("graph.easing_type", {"type": 'E', "value": 'PRESS', "ctrl": True}, None),
("graph.smooth", {"type": 'O', "value": 'PRESS', "alt": True}, None),
("graph.sample", {"type": 'O', "value": 'PRESS', "shift": True, "alt": True}, None),
("graph.bake", {"type": 'C', "value": 'PRESS', "alt": True}, None),
("graph.keys_to_samples", {"type": 'C', "value": 'PRESS', "alt": True}, None),
op_menu("GRAPH_MT_delete", {"type": 'X', "value": 'PRESS'}),
("graph.delete", {"type": 'DEL', "value": 'PRESS'}, {"properties": [("confirm", False)]}),
("graph.duplicate_move", {"type": 'D', "value": 'PRESS', "shift": True}, None),
@ -2121,16 +2120,29 @@ def km_node_editor(params):
)
if not params.legacy:
items.extend(_template_node_select(type=params.select_mouse,
value=params.select_mouse_value, select_passthrough=True))
items.extend(_template_node_select(
type=params.select_mouse,
value=params.select_mouse_value,
select_passthrough=True,
))
# Allow node selection with both for RMB select.
if params.select_mouse == 'RIGHTMOUSE':
items.extend(_template_node_select(type='LEFTMOUSE', value='PRESS', select_passthrough=True))
else:
items.extend([
op_tool_cycle("builtin.select_box", {"type": 'W', "value": 'PRESS'}),
])
else:
items.extend(_template_node_select(
type='RIGHTMOUSE', value=params.select_mouse_value, select_passthrough=True))
type='RIGHTMOUSE',
value=params.select_mouse_value,
select_passthrough=True,
))
items.extend(_template_node_select(
type='LEFTMOUSE', value='PRESS', select_passthrough=True))
type='LEFTMOUSE',
value='PRESS',
select_passthrough=True,
))
items.extend([
("node.select_box", {"type": params.select_mouse, "value": 'CLICK_DRAG'},
@ -4043,8 +4055,10 @@ def km_grease_pencil_stroke_sculpt_mode(params):
# Context menu
*_template_items_context_panel("VIEW3D_PT_gpencil_sculpt_context_menu", params.context_menu_event),
# Auto-masking Pie menu.
op_menu_pie("VIEW3D_MT_sculpt_gpencil_automasking_pie", {
"type": 'A', "shift": True, "alt": True, "value": 'PRESS'}),
op_menu_pie(
"VIEW3D_MT_sculpt_gpencil_automasking_pie",
{"type": 'A', "shift": True, "alt": True, "value": 'PRESS'},
),
])
return keymap
@ -4882,10 +4896,6 @@ def _template_view3d_select(*, type, value, legacy, select_passthrough, exclude_
# NOTE: `exclude_mod` is needed since we don't want this tool to exclude Control-RMB actions when this is used
# as a tool key-map with RMB-select and `use_fallback_tool` is enabled with RMB select. See #92467.
props_vert_without_handles = ()
if select_passthrough:
props_vert_without_handles = ("vert_without_handles",)
# See: `use_tweak_select_passthrough` doc-string.
if select_passthrough and (value in {'CLICK', 'RELEASE'}):
select_passthrough = False
@ -4895,9 +4905,9 @@ def _template_view3d_select(*, type, value, legacy, select_passthrough, exclude_
{"type": type, "value": value, **{m: True for m in mods}},
{"properties": [(c, True) for c in props]},
) for props, mods in (
((("deselect_all", "select_passthrough", *props_vert_without_handles) if select_passthrough else
("deselect_all", *props_vert_without_handles)) if not legacy else (), ()),
(("toggle", *props_vert_without_handles), ("shift",)),
((("deselect_all", "select_passthrough") if select_passthrough else
("deselect_all",)) if not legacy else (), ()),
(("toggle",), ("shift",)),
(("center", "object"), ("ctrl",)),
(("enumerate",), ("alt",)),
(("toggle", "center"), ("shift", "ctrl")),
@ -4914,7 +4924,7 @@ def _template_view3d_select(*, type, value, legacy, select_passthrough, exclude_
{"type": type, "value": 'CLICK'},
{"properties": [
(c, True)
for c in ("deselect_all", *props_vert_without_handles)
for c in ("deselect_all",)
]},
))
@ -7070,17 +7080,12 @@ def km_3d_view_tool_text_select(_params):
def km_3d_view_tool_select(params, *, fallback):
if params.use_tweak_select_passthrough:
operator_props = (("vert_without_handles", True),)
else:
operator_props = ()
return (
_fallback_id("3D View Tool: Tweak", fallback),
{"space_type": 'VIEW_3D', "region_type": 'WINDOW'},
{"items": [
*([] if (fallback and (params.select_mouse == 'RIGHTMOUSE')) else _template_items_tool_select(
params, "view3d.select", "view3d.cursor3d", operator_props=operator_props, fallback=fallback)),
params, "view3d.select", "view3d.cursor3d", fallback=fallback)),
*([] if params.use_fallback_tool_select_handled else
_template_view3d_select(
type=params.select_mouse,
@ -7895,8 +7900,8 @@ def km_3d_view_tool_paint_gpencil_line(params):
("gpencil.primitive_line", {"type": 'LEFTMOUSE', "value": 'PRESS', "alt": True},
{"properties": [("wait_for_input", False)]}),
# Lasso select
("gpencil.select_lasso", {"type": params.action_mouse,
"value": 'CLICK_DRAG', "ctrl": True, "alt": True}, None),
("gpencil.select_lasso",
{"type": params.action_mouse, "value": 'CLICK_DRAG', "ctrl": True, "alt": True}, None),
]},
)
@ -7911,8 +7916,8 @@ def km_3d_view_tool_paint_gpencil_polyline(params):
("gpencil.primitive_polyline", {"type": 'LEFTMOUSE', "value": 'PRESS', "shift": True},
{"properties": [("wait_for_input", False)]}),
# Lasso select
("gpencil.select_lasso", {"type": params.action_mouse,
"value": 'CLICK_DRAG', "ctrl": True, "alt": True}, None),
("gpencil.select_lasso",
{"type": params.action_mouse, "value": 'CLICK_DRAG', "ctrl": True, "alt": True}, None),
]},
)
@ -7929,8 +7934,8 @@ def km_3d_view_tool_paint_gpencil_box(params):
("gpencil.primitive_box", {"type": 'LEFTMOUSE', "value": 'PRESS', "alt": True},
{"properties": [("wait_for_input", False)]}),
# Lasso select
("gpencil.select_lasso", {"type": params.action_mouse,
"value": 'CLICK_DRAG', "ctrl": True, "alt": True}, None),
("gpencil.select_lasso",
{"type": params.action_mouse, "value": 'CLICK_DRAG', "ctrl": True, "alt": True}, None),
]},
)
@ -7947,8 +7952,8 @@ def km_3d_view_tool_paint_gpencil_circle(params):
("gpencil.primitive_circle", {"type": 'LEFTMOUSE', "value": 'PRESS', "alt": True},
{"properties": [("wait_for_input", False)]}),
# Lasso select
("gpencil.select_lasso", {"type": params.action_mouse,
"value": 'CLICK_DRAG', "ctrl": True, "alt": True}, None),
("gpencil.select_lasso",
{"type": params.action_mouse, "value": 'CLICK_DRAG', "ctrl": True, "alt": True}, None),
]},
)
@ -7965,8 +7970,8 @@ def km_3d_view_tool_paint_gpencil_arc(params):
("gpencil.primitive_curve", {"type": 'LEFTMOUSE', "value": 'PRESS', "alt": True},
{"properties": [("type", 'ARC'), ("wait_for_input", False)]}),
# Lasso select
("gpencil.select_lasso", {"type": params.action_mouse,
"value": 'CLICK_DRAG', "ctrl": True, "alt": True}, None),
("gpencil.select_lasso",
{"type": params.action_mouse, "value": 'CLICK_DRAG', "ctrl": True, "alt": True}, None),
]},
)
@ -7979,8 +7984,8 @@ def km_3d_view_tool_paint_gpencil_curve(params):
("gpencil.primitive_curve", params.tool_maybe_tweak_event,
{"properties": [("type", 'CURVE'), ("wait_for_input", False)]}),
# Lasso select
("gpencil.select_lasso", {"type": params.action_mouse,
"value": 'CLICK_DRAG', "ctrl": True, "alt": True}, None),
("gpencil.select_lasso",
{"type": params.action_mouse, "value": 'CLICK_DRAG', "ctrl": True, "alt": True}, None),
]},
)
@ -7992,8 +7997,8 @@ def km_3d_view_tool_paint_gpencil_cutter(params):
{"items": [
("gpencil.stroke_cutter", {"type": params.tool_mouse, "value": 'PRESS'}, None),
# Lasso select
("gpencil.select_lasso", {"type": params.action_mouse,
"value": 'CLICK_DRAG', "ctrl": True, "alt": True}, None),
("gpencil.select_lasso",
{"type": params.action_mouse, "value": 'CLICK_DRAG', "ctrl": True, "alt": True}, None),
]},
)

View File

@ -35,6 +35,29 @@ def geometry_node_group_empty_new():
return group
def geometry_node_group_empty_tool_new(context):
group = build_default_empty_geometry_node_group(data_("Tool"))
group.links.new(group.nodes[data_("Group Input")].outputs[0], group.nodes[data_("Group Output")].inputs[0])
group.asset_mark()
group.is_tool = True
ob_type = context.object.type if context.object else 'MESH'
if ob_type == 'CURVES':
group.is_type_curve = True
elif ob_type == 'POINTCLOUD':
group.is_type_point_cloud = True
else:
group.is_type_mesh = True
mode = context.object.mode if context.object else 'EDIT'
if mode in {'SCULPT', 'SCULPT_CURVES'}:
group.is_mode_sculpt = True
else:
group.is_mode_edit = True
return group
def geometry_modifier_poll(context):
ob = context.object
@ -276,9 +299,7 @@ class NewGeometryNodeGroupTool(Operator):
return space and space.type == 'NODE_EDITOR' and space.geometry_nodes_type == 'TOOL'
def execute(self, context):
group = geometry_node_group_empty_new()
group.asset_mark()
group.is_tool = True
group = geometry_node_group_empty_tool_new(context)
context.space_data.node_tree = group
return {'FINISHED'}

View File

@ -66,7 +66,7 @@ class DATA_PT_display(ArmatureButtonsPanel, Panel):
col = layout.column(heading="Show")
col.prop(arm, "show_names", text="Names")
col.prop(arm, "show_bone_custom_shapes", text="Shapes")
col.prop(arm, "show_group_colors", text="Group Colors")
col.prop(arm, "show_bone_colors", text="Bone Colors")
if ob:
col.prop(ob, "show_in_front", text="In Front")
@ -96,16 +96,10 @@ class DATA_UL_bone_collections(UIList):
class DATA_PT_bone_collections(ArmatureButtonsPanel, Panel):
bl_label = "Bone Collections"
@classmethod
def poll(cls, context):
ob = context.object
return (ob and ob.type == 'ARMATURE' and ob.pose)
def draw(self, context):
layout = self.layout
ob = context.object
arm = ob.data
arm = context.armature
active_bcoll = arm.collections.active
row = layout.row()
@ -243,6 +237,17 @@ class DATA_PT_custom_props_arm(ArmatureButtonsPanel, PropertyPanel, Panel):
_property_type = bpy.types.Armature
class DATA_PT_custom_props_bcoll(ArmatureButtonsPanel, PropertyPanel, Panel):
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH'}
_context_path = "armature.collections.active"
_property_type = bpy.types.BoneCollection
bl_parent_id = "DATA_PT_bone_collections"
@classmethod
def poll(cls, context):
return context.armature and context.armature.collections.active
classes = (
DATA_PT_context_arm,
DATA_PT_skeleton,
@ -253,6 +258,7 @@ classes = (
DATA_PT_display,
DATA_PT_iksolver_itasc,
DATA_PT_custom_props_arm,
DATA_PT_custom_props_bcoll,
)
if __name__ == "__main__": # only for live edit.

View File

@ -232,7 +232,6 @@ class BONE_PT_relations(BoneButtonsPanel, Panel):
if ob and pchan:
col.prop(bone, "use_relative_parent")
col.prop_search(pchan, "bone_group", ob.pose, "bone_groups", text="Bone Group")
sub = col.column()
sub.active = (bone.parent is not None)

View File

@ -36,7 +36,7 @@ class OBJECT_MT_modifier_add(Menu):
ob_type = context.object.type
geometry_nodes_supported = ob_type in {'MESH', 'CURVE', 'CURVES', 'FONT', 'SURFACE', 'VOLUME', 'POINTCLOUD'}
if geometry_nodes_supported:
layout.operator("object.modifier_add", text="Empty Modifier").type = 'NODES'
layout.operator("object.modifier_add", icon='GEOMETRY_NODES', text="Geometry Nodes").type = 'NODES'
layout.separator()
if ob_type in {'MESH', 'CURVE', 'FONT', 'SURFACE', 'LATTICE'}:
layout.menu("OBJECT_MT_modifier_add_edit")
@ -227,6 +227,7 @@ class AddModifierMenu(Operator):
@classmethod
def poll(cls, context):
# NOTE: This operator only exists to add a poll to the add modifier shortcut in the property editor.
space = context.space_data
return space and space.type == 'PROPERTIES' and space.context == "MODIFIER"

View File

@ -481,6 +481,7 @@ class RENDER_PT_eevee_next_volumetric_lighting(RenderButtonsPanel, Panel):
layout.active = props.use_volumetric_lights
layout.prop(props, "volumetric_light_clamp", text="Light Clamping")
class RENDER_PT_eevee_next_volumetric_shadows(RenderButtonsPanel, Panel):
bl_label = "Volumetric Shadows"
bl_parent_id = "RENDER_PT_eevee_next_volumetric"

View File

@ -283,8 +283,8 @@ class GRAPH_MT_channel(Menu):
layout.operator("anim.channels_fcurves_enable")
layout.separator()
layout.operator("graph.bake")
layout.operator("graph.unbake")
layout.operator("graph.keys_to_samples")
layout.operator("graph.samples_to_keys")
layout.operator("graph.sound_bake")
layout.separator()
@ -325,6 +325,7 @@ class GRAPH_MT_key_blending(Menu):
layout.operator("graph.blend_to_ease", text="Blend to Ease")
layout.operator("graph.match_slope", text="Match Slope")
layout.operator("graph.shear", text="Shear Keys")
layout.operator("graph.scale_average", text="Scale Average")
class GRAPH_MT_key_smoothing(Menu):

View File

@ -966,15 +966,9 @@ class SEQUENCER_MT_strip(Menu):
if has_sequencer:
if strip:
strip_type = strip.type
if strip_type != 'SOUND':
layout.separator()
layout.operator_menu_enum("sequencer.strip_video_modifier_add", "type", text="Add Modifier")
layout.operator("sequencer.strip_modifier_copy", text="Copy Modifiers to Selection")
else:
layout.separator()
layout.operator_menu_enum("sequencer.strip_sound_modifier_add", "type", text="Add Modifier")
layout.operator("sequencer.strip_modifier_copy", text="Copy Modifiers to Selection")
layout.separator()
layout.operator_menu_enum("sequencer.strip_modifier_add", "type", text="Add Modifier")
layout.operator("sequencer.strip_modifier_copy", text="Copy Modifiers to Selection")
if strip_type in {
'CROSS', 'ADD', 'SUBTRACT', 'ALPHA_OVER', 'ALPHA_UNDER',
@ -1112,18 +1106,16 @@ class SEQUENCER_MT_context_menu(Menu):
strip_type = strip.type
selected_sequences_count = selected_sequences_len(context)
layout.separator()
layout.operator_menu_enum("sequencer.strip_modifier_add", "type", text="Add Modifier")
layout.operator("sequencer.strip_modifier_copy", text="Copy Modifiers to Selection")
if strip_type != 'SOUND':
layout.separator()
layout.operator_menu_enum("sequencer.strip_video_modifier_add", "type", text="Add Modifier")
layout.operator("sequencer.strip_modifier_copy", text="Copy Modifiers to Selection")
if selected_sequences_count >= 2:
layout.separator()
col = layout.column()
col.menu("SEQUENCER_MT_add_transitions", text="Add Transition")
else:
layout.separator()
layout.operator_menu_enum("sequencer.strip_sound_modifier_add", "type", text="Add Modifier")
layout.operator("sequencer.strip_modifier_copy", text="Copy Modifiers to Selection")
if selected_sequences_count >= 2:
layout.separator()
layout.operator("sequencer.crossfade_sounds", text="Crossfade Sounds")

View File

@ -867,7 +867,7 @@ class VIEW3D_PT_tools_weight_gradient(Panel, View3DPaintPanel):
@classmethod
def poll(cls, context):
# since we dont give context above, check mode here (to not show in other modes like sculpt)
# since we don't give context above, check mode here (to not show in other modes like sculpt).
if context.mode != 'PAINT_WEIGHT':
return False
settings = context.tool_settings.weight_paint

View File

@ -49,10 +49,10 @@ bool BKE_blender_version_is_alpha(void);
* Fill in given string buffer with user-readable formatted file version and subversion (if
* provided).
*
* \param str_buff a char buffer where the formatted string is written, minimal recommended size is
* 8, or 16 if subversion is provided.
* \param str_buff: a char buffer where the formatted string is written,
* minimal recommended size is 8, or 16 if subversion is provided.
*
* \param file_subversion the file subversion, if given value < 0, it is ignored, and only the
* \param file_subversion: the file subversion, if given value < 0, it is ignored, and only the
* `file_version` is used.
*/
void BKE_blender_version_blendfile_string_from_values(char *str_buff,

View File

@ -179,7 +179,7 @@ void BKE_constraints_copy_ex(struct ListBase *dst,
/**
* Run the given callback on all ID-blocks in list of constraints.
*
* \param flag the `IDWALK_` flags controlling the behavior of the foreach_id code, see
* \param flag: the `IDWALK_` flags controlling the behavior of the foreach_id code, see
* `BKE_lib_query.h`
*/
void BKE_constraints_id_loop(struct ListBase *list,

View File

@ -259,6 +259,15 @@ inline int2 face_find_adjecent_verts(const IndexRange face,
corner_verts[face_corner_next(face, corner)]};
}
/**
* Return the number of triangles needed to tessellate a face with \a face_size corners.
*/
inline int face_triangles_num(const int face_size)
{
BLI_assert(face_size > 2);
return face_size - 2;
}
/**
* Return the index of the edge's vertex that is not the \a vert.
* If neither edge vertex is equal to \a v, returns -1.

View File

@ -275,7 +275,6 @@ bool BKE_pbvh_bmesh_node_raycast_detail(PBVHNode *node,
* projecting the far clipping plane into the local object space. This works out to
* dividing view3d->clip_end by the object scale, which for small object and large
* clip_end's can easily lead to floating-point overflows.
*
*/
void BKE_pbvh_clip_ray_ortho(
PBVH *pbvh, bool original, float ray_start[3], float ray_end[3], float ray_normal[3]);

View File

@ -2879,7 +2879,7 @@ static void nlastrip_evaluate_meta(const int evaluation_mode,
/* Assert currently supported modes. If new mode added, then assertion marks potentially missed
* area.
*
* NOTE: In the future if support is ever added to metastrips to support nested tracks, then
* NOTE: In the future if support is ever added to meta-strips to support nested tracks, then
* STRIP_EVAL_BLEND and STRIP_EVAL_BLEND_GET_INVERTED_LOWER_SNAPSHOT cases are no longer
* equivalent. The output of nlastrips_ctime_get_strip() may return a list of strips. The only
* case difference should be the evaluation order.

View File

@ -485,8 +485,10 @@ static bool rule_follow_leader(BoidRule *rule,
BoidRuleFollowLeader *flbr = (BoidRuleFollowLeader *)rule;
float vec[3] = {0.0f, 0.0f, 0.0f}, loc[3] = {0.0f, 0.0f, 0.0f};
float mul, len;
int n = (flbr->queue_size <= 1) ? bbd->sim->psys->totpart : flbr->queue_size;
int i, p = pa - bbd->sim->psys->particles;
const int n = (flbr->queue_size <= 1) ? bbd->sim->psys->totpart : flbr->queue_size;
BLI_assert(ARRAY_HAS_ITEM(pa, bbd->sim->psys->particles, bbd->sim->psys->totpart));
const int p = int(pa - bbd->sim->psys->particles);
int i;
bool ret = false;
if (flbr->ob) {

View File

@ -1104,7 +1104,7 @@ static BitVector<> looptri_no_hidden_map_get(const blender::OffsetIndices<int> f
int looptri_no_hidden_len = 0;
int looptri_index = 0;
for (const int64_t i : faces.index_range()) {
const int triangles_num = ME_FACE_TRI_TOT(faces[i].size());
const int triangles_num = blender::bke::mesh::face_triangles_num(faces[i].size());
if (hide_poly[i]) {
looptri_index += triangles_num;
}

View File

@ -4286,10 +4286,11 @@ void BKE_nurbList_handles_set(ListBase *editnurb,
bezt = nu->bezt;
a = nu->pntsu;
while (a--) {
if (bezt->f1 & SELECT) {
const short flag = BKE_nurb_bezt_handle_test_calc_flag(bezt, SELECT, handle_mode);
if (flag & (1 << 0)) {
bezt->h1 = h_new;
}
if (bezt->f3 & SELECT) {
if (flag & (1 << 2)) {
bezt->h2 = h_new;
}

View File

@ -833,33 +833,34 @@ void BKE_defvert_add_index_notest(MDeformVert *dvert, const int defgroup, const
void BKE_defvert_remove_group(MDeformVert *dvert, MDeformWeight *dw)
{
if (dvert && dw) {
int i = dw - dvert->dw;
if (UNLIKELY(!dvert || !dw)) {
return;
}
/* Ensure `dw` is part of `dvert` (security check). */
if (UNLIKELY(uintptr_t(dw - dvert->dw) >= uintptr_t(dvert->totweight))) {
/* Assert as an invalid `dw` (while supported) isn't likely to do what the caller expected. */
BLI_assert_unreachable();
return;
}
/* Security check! */
if (i < 0 || i >= dvert->totweight) {
return;
const int i = dw - dvert->dw;
dvert->totweight--;
/* If there are still other deform weights attached to this vert then remove
* this deform weight, and reshuffle the others. */
if (dvert->totweight) {
BLI_assert(dvert->dw != nullptr);
if (i != dvert->totweight) {
dvert->dw[i] = dvert->dw[dvert->totweight];
}
dvert->totweight--;
/* If there are still other deform weights attached to this vert then remove
* this deform weight, and reshuffle the others.
*/
if (dvert->totweight) {
BLI_assert(dvert->dw != nullptr);
if (i != dvert->totweight) {
dvert->dw[i] = dvert->dw[dvert->totweight];
}
dvert->dw = static_cast<MDeformWeight *>(
MEM_reallocN(dvert->dw, sizeof(MDeformWeight) * dvert->totweight));
}
else {
/* If there are no other deform weights left then just remove this one. */
MEM_freeN(dvert->dw);
dvert->dw = nullptr;
}
dvert->dw = static_cast<MDeformWeight *>(
MEM_reallocN(dvert->dw, sizeof(MDeformWeight) * dvert->totweight));
}
else {
/* If there are no other deform weights left then just remove this one. */
MEM_freeN(dvert->dw);
dvert->dw = nullptr;
}
}
@ -1067,25 +1068,25 @@ void BKE_defvert_extract_vgroup_to_edgeweights(const MDeformVert *dvert,
const bool invert_vgroup,
float *r_weights)
{
if (dvert && defgroup != -1) {
int i = edges_num;
float *tmp_weights = static_cast<float *>(
MEM_mallocN(sizeof(*tmp_weights) * size_t(verts_num), __func__));
BKE_defvert_extract_vgroup_to_vertweights(
dvert, defgroup, verts_num, invert_vgroup, tmp_weights);
while (i--) {
const blender::int2 &edge = edges[i];
r_weights[i] = (tmp_weights[edge[0]] + tmp_weights[edge[1]]) * 0.5f;
}
MEM_freeN(tmp_weights);
}
else {
if (UNLIKELY(!dvert || defgroup == -1)) {
copy_vn_fl(r_weights, edges_num, 0.0f);
return;
}
int i = edges_num;
float *tmp_weights = static_cast<float *>(
MEM_mallocN(sizeof(*tmp_weights) * size_t(verts_num), __func__));
BKE_defvert_extract_vgroup_to_vertweights(
dvert, defgroup, verts_num, invert_vgroup, tmp_weights);
while (i--) {
const blender::int2 &edge = edges[i];
r_weights[i] = (tmp_weights[edge[0]] + tmp_weights[edge[1]]) * 0.5f;
}
MEM_freeN(tmp_weights);
}
void BKE_defvert_extract_vgroup_to_loopweights(const MDeformVert *dvert,
@ -1096,23 +1097,23 @@ void BKE_defvert_extract_vgroup_to_loopweights(const MDeformVert *dvert,
const bool invert_vgroup,
float *r_weights)
{
if (dvert && defgroup != -1) {
int i = loops_num;
float *tmp_weights = static_cast<float *>(
MEM_mallocN(sizeof(*tmp_weights) * size_t(verts_num), __func__));
BKE_defvert_extract_vgroup_to_vertweights(
dvert, defgroup, verts_num, invert_vgroup, tmp_weights);
while (i--) {
r_weights[i] = tmp_weights[corner_verts[i]];
}
MEM_freeN(tmp_weights);
}
else {
if (UNLIKELY(!dvert || defgroup == -1)) {
copy_vn_fl(r_weights, loops_num, 0.0f);
return;
}
int i = loops_num;
float *tmp_weights = static_cast<float *>(
MEM_mallocN(sizeof(*tmp_weights) * size_t(verts_num), __func__));
BKE_defvert_extract_vgroup_to_vertweights(
dvert, defgroup, verts_num, invert_vgroup, tmp_weights);
while (i--) {
r_weights[i] = tmp_weights[corner_verts[i]];
}
MEM_freeN(tmp_weights);
}
void BKE_defvert_extract_vgroup_to_faceweights(const MDeformVert *dvert,
@ -1124,31 +1125,31 @@ void BKE_defvert_extract_vgroup_to_faceweights(const MDeformVert *dvert,
const bool invert_vgroup,
float *r_weights)
{
if (dvert && defgroup != -1) {
int i = faces.size();
float *tmp_weights = static_cast<float *>(
MEM_mallocN(sizeof(*tmp_weights) * size_t(verts_num), __func__));
BKE_defvert_extract_vgroup_to_vertweights(
dvert, defgroup, verts_num, invert_vgroup, tmp_weights);
while (i--) {
const blender::IndexRange face = faces[i];
const int *corner_vert = &corner_verts[face.start()];
int j = face.size();
float w = 0.0f;
for (; j--; corner_vert++) {
w += tmp_weights[*corner_vert];
}
r_weights[i] = w / float(face.size());
}
MEM_freeN(tmp_weights);
}
else {
if (UNLIKELY(!dvert || defgroup == -1)) {
copy_vn_fl(r_weights, faces.size(), 0.0f);
return;
}
int i = faces.size();
float *tmp_weights = static_cast<float *>(
MEM_mallocN(sizeof(*tmp_weights) * size_t(verts_num), __func__));
BKE_defvert_extract_vgroup_to_vertweights(
dvert, defgroup, verts_num, invert_vgroup, tmp_weights);
while (i--) {
const blender::IndexRange face = faces[i];
const int *corner_vert = &corner_verts[face.start()];
int j = face.size();
float w = 0.0f;
for (; j--; corner_vert++) {
w += tmp_weights[*corner_vert];
}
r_weights[i] = w / float(face.size());
}
MEM_freeN(tmp_weights);
}
/** \} */

View File

@ -286,7 +286,7 @@ void BKE_mesh_origindex_map_create_looptri(MeshElemMap **r_map,
index_step = indices;
for (const int64_t i : faces.index_range()) {
map[i].indices = index_step;
index_step += ME_FACE_TRI_TOT(faces[i].size());
index_step += blender::bke::mesh::face_triangles_num(int(faces[i].size()));
}
/* Assign face-tessellation users. */

View File

@ -306,7 +306,7 @@ void looptris_calc_face_indices(const OffsetIndices<int> faces, MutableSpan<int>
for (const int64_t i : range) {
const IndexRange face = faces[i];
const int start = poly_to_tri_count(int(i), int(face.start()));
const int num = ME_FACE_TRI_TOT(int(face.size()));
const int num = face_triangles_num(int(face.size()));
looptri_faces.slice(start, num).fill(int(i));
}
});

View File

@ -369,9 +369,43 @@ static void socket_data_foreach_id(LibraryForeachIDData *data, bNodeTreeInterfac
namespace item_types {
using UidGeneratorFn = blender::FunctionRef<int()>;
static void item_copy(bNodeTreeInterfaceItem &dst,
const bNodeTreeInterfaceItem &src,
const int flag)
int flag,
UidGeneratorFn generate_uid);
/**
* Copy the source items and give each a new unique identifier.
* \param generate_uid: Optional generator function for new item UIDs, copies existing identifiers
* if null.
*/
static void panel_init(bNodeTreeInterfacePanel &panel,
const Span<const bNodeTreeInterfaceItem *> items_src,
const int flag,
UidGeneratorFn generate_uid)
{
panel.items_num = items_src.size();
panel.items_array = MEM_cnew_array<bNodeTreeInterfaceItem *>(panel.items_num, __func__);
/* Copy buffers. */
for (const int i : items_src.index_range()) {
const bNodeTreeInterfaceItem *item_src = items_src[i];
panel.items_array[i] = static_cast<bNodeTreeInterfaceItem *>(MEM_dupallocN(item_src));
item_types::item_copy(*panel.items_array[i], *item_src, flag, generate_uid);
}
}
/**
* Copy data from a source item.
* \param generate_uid: Optional generator function for new item UIDs, copies existing identifiers
* if null.
*/
static void item_copy(bNodeTreeInterfaceItem &dst,
const bNodeTreeInterfaceItem &src,
const int flag,
UidGeneratorFn generate_uid)
{
switch (dst.item_type) {
case NODE_INTERFACE_SOCKET: {
@ -385,7 +419,8 @@ static void item_copy(bNodeTreeInterfaceItem &dst,
dst_socket.description = BLI_strdup_null(src_socket.description);
dst_socket.socket_type = BLI_strdup(src_socket.socket_type);
dst_socket.default_attribute_name = BLI_strdup_null(src_socket.default_attribute_name);
dst_socket.identifier = BLI_strdup(src_socket.identifier);
dst_socket.identifier = generate_uid ? BLI_sprintfN("Socket_%d", generate_uid()) :
BLI_strdup(src_socket.identifier);
if (src_socket.properties) {
dst_socket.properties = IDP_CopyProperty_ex(src_socket.properties, flag);
}
@ -402,24 +437,9 @@ static void item_copy(bNodeTreeInterfaceItem &dst,
dst_panel.name = BLI_strdup(src_panel.name);
dst_panel.description = BLI_strdup_null(src_panel.description);
dst_panel.copy_from(src_panel.items(), flag);
break;
}
}
}
dst_panel.identifier = generate_uid ? generate_uid() : src_panel.identifier;
static void item_set_unique_identifier(const int uid, bNodeTreeInterfaceItem &item)
{
switch (item.item_type) {
case NODE_INTERFACE_SOCKET: {
bNodeTreeInterfaceSocket &socket = reinterpret_cast<bNodeTreeInterfaceSocket &>(item);
MEM_SAFE_FREE(socket.identifier);
socket.identifier = BLI_sprintfN("Socket_%d", uid);
break;
}
case NODE_INTERFACE_PANEL: {
bNodeTreeInterfacePanel &panel = reinterpret_cast<bNodeTreeInterfacePanel &>(item);
panel.identifier = uid;
panel_init(dst_panel, src_panel.items(), flag, generate_uid);
break;
}
}
@ -999,20 +1019,6 @@ static bNodeTreeInterfacePanel *make_panel(const int uid,
return new_panel;
}
void bNodeTreeInterfacePanel::copy_from(
const blender::Span<const bNodeTreeInterfaceItem *> items_src, int flag)
{
items_num = items_src.size();
items_array = MEM_cnew_array<bNodeTreeInterfaceItem *>(items_num, __func__);
/* Copy buffers. */
for (const int i : items_src.index_range()) {
const bNodeTreeInterfaceItem *item_src = items_src[i];
items_array[i] = static_cast<bNodeTreeInterfaceItem *>(MEM_dupallocN(item_src));
item_types::item_copy(*items_array[i], *item_src, flag);
}
}
void bNodeTreeInterface::init_data()
{
/* Root panel is allowed to contain child panels. */
@ -1021,7 +1027,7 @@ void bNodeTreeInterface::init_data()
void bNodeTreeInterface::copy_data(const bNodeTreeInterface &src, int flag)
{
this->root_panel.copy_from(src.root_panel.items(), flag);
item_types::panel_init(this->root_panel, src.root_panel.items(), flag, nullptr);
this->active_index = src.active_index;
}
@ -1188,8 +1194,7 @@ bNodeTreeInterfaceItem *bNodeTreeInterface::add_item_copy(const bNodeTreeInterfa
}
bNodeTreeInterfaceItem *citem = static_cast<bNodeTreeInterfaceItem *>(MEM_dupallocN(&item));
item_types::item_copy(*citem, item, 0);
item_types::item_set_unique_identifier(next_uid++, *citem);
item_types::item_copy(*citem, item, 0, [&]() { return this->next_uid++; });
parent->add_item(*citem);
return citem;
@ -1213,8 +1218,7 @@ bNodeTreeInterfaceItem *bNodeTreeInterface::insert_item_copy(const bNodeTreeInte
}
bNodeTreeInterfaceItem *citem = static_cast<bNodeTreeInterfaceItem *>(MEM_dupallocN(&item));
item_types::item_copy(*citem, item, 0);
item_types::item_set_unique_identifier(next_uid++, *citem);
item_types::item_copy(*citem, item, 0, [&]() { return this->next_uid++; });
parent->insert_item(*citem, position);
return citem;

View File

@ -61,6 +61,10 @@
# include "BPY_extern.h"
#endif
/* -------------------------------------------------------------------- */
/** \name ID Type Implementation
* \{ */
static void screen_free_data(ID *id)
{
bScreen *screen = (bScreen *)id;
@ -189,7 +193,11 @@ IDTypeInfo IDType_ID_SCR = {
/*lib_override_apply_post*/ nullptr,
};
/* ************ Space-type/region-type handling ************** */
/** \} */
/* -------------------------------------------------------------------- */
/** \name Space-type/region-type handling
* \{ */
/** Keep global; this has to be accessible outside of window-manager. */
static ListBase spacetypes = {nullptr, nullptr};
@ -277,7 +285,11 @@ bool BKE_spacetype_exists(int spaceid)
return BKE_spacetype_from_id(spaceid) != nullptr;
}
/* ***************** Space handling ********************** */
/** \} */
/* -------------------------------------------------------------------- */
/** \name Space handling
* \{ */
void BKE_spacedata_freelist(ListBase *lb)
{
@ -570,7 +582,11 @@ void BKE_screen_free_data(bScreen *screen)
screen_free_data(&screen->id);
}
/* ***************** Screen edges & verts ***************** */
/** \} */
/* -------------------------------------------------------------------- */
/** \name Screen edges & verts
* \{ */
ScrEdge *BKE_screen_find_edge(const bScreen *screen, ScrVert *v1, ScrVert *v2)
{
@ -725,7 +741,11 @@ void BKE_screen_remove_unused_scrverts(bScreen *screen)
}
}
/* ***************** Utilities ********************** */
/** \} */
/* -------------------------------------------------------------------- */
/** \name Utilities
* \{ */
ARegion *BKE_region_find_in_listbase_by_type(const ListBase *regionbase, const int region_type)
{
@ -945,6 +965,12 @@ void BKE_screen_header_alignment_reset(bScreen *screen)
screen->do_refresh = true;
}
/** \} */
/* -------------------------------------------------------------------- */
/** \name Blend File IO (Screen & Related Data)
* \{ */
void BKE_screen_view3d_shading_blend_write(BlendWriter *writer, View3DShading *shading)
{
if (shading->prop) {

View File

@ -21,7 +21,6 @@ extern "C" {
* \return The number of indices in r_points.
*
* \note Performance is `O(n.log(n))`, same as `qsort`.
*
*/
int BLI_convexhull_2d(const float (*points)[2], int n, int r_points[/* n */]);

View File

@ -161,7 +161,6 @@ using IndexMaskSegment = OffsetSpan<int64_t, int16_t>;
*
* Extraction:
* An #IndexMask can be converted into various other forms using the `to_*` methods.
*
*/
class IndexMask : private IndexMaskData {
public:

View File

@ -203,7 +203,8 @@ void BLO_blendfiledata_free(BlendFileData *bfd);
*
* Called at the end of #setup_add_data from BKE's `blendfile.cc`.
*
* \param new_bmain the newly read Main data-base. */
* \param new_bmain: the newly read Main data-base.
*/
void BLO_read_do_version_after_setup(struct Main *new_bmain, struct BlendFileReadReport *reports);
/** \} */

View File

@ -3317,7 +3317,7 @@ static void lib_link_all(FileData *fd, Main *bmain)
/* Some data that should be persistent, like the 3DCursor or the tool settings, are
* stored in IDs affected by undo, like Scene. So this requires some specific handling. */
/* NOTE: even though the ID may have been detected as unchanged, the 'undo_preserve' may have
* to actually change some of its ID pointers, it's e.g. the case with Scene's toolsettings
* to actually change some of its ID pointers, it's e.g. the case with Scene's tool-settings
* Brush/Palette pointers. This is the case where both new and old ID may be the same. */
if (id_type->blend_read_undo_preserve != nullptr) {
BLI_assert(fd->flags & FD_FLAGS_IS_MEMFILE);

View File

@ -205,10 +205,9 @@ bool BLO_memfile_write_file(MemFile *memfile, const char *filepath)
int file, oflags;
/* NOTE: This is currently used for auto-save and `quit.blend`,
* where _not_ following symlinks is OK,
* where _not_ following symbolic-links is OK,
* however if this is ever executed explicitly by the user,
* we may want to allow writing to symlinks.
*/
* we may want to allow writing to symbolic-links. */
oflags = O_BINARY | O_WRONLY | O_CREAT | O_TRUNC;
#ifdef O_NOFOLLOW

View File

@ -1060,7 +1060,7 @@ static bNodeSocket *version_make_socket_stub(const char *idname,
/* Note: technically socket values can store ref-counted ID pointers, but at this stage the
* refcount can be ignored. It gets recomputed after lib-linking for all ID pointers. Socket
* values don't have allocated data, so a simple dupalloc works here. */
* values don't have allocated data, so a simple duplication works here. */
socket->default_value = default_value ? MEM_dupallocN(default_value) : nullptr;
socket->prop = prop ? IDP_CopyProperty(prop) : nullptr;

View File

@ -626,7 +626,7 @@ void do_versions_after_linking_290(FileData * /*fd*/, Main *bmain)
}
if (!MAIN_VERSION_FILE_ATLEAST(bmain, 292, 8)) {
/* Systematically rebuild posebones to ensure consistent ordering matching the one of bones in
/* Systematically rebuild pose-bones to ensure consistent ordering matching the one of bones in
* Armature obdata. */
LISTBASE_FOREACH (Object *, ob, &bmain->objects) {
if (ob->type == OB_ARMATURE) {

View File

@ -73,7 +73,7 @@ static void version_composite_nodetree_null_id(bNodeTree *ntree, Scene *scene)
}
}
/* Move bonegroup color to the individual bones. */
/* Move bone-group color to the individual bones. */
static void version_bonegroup_migrate_color(Main *bmain)
{
using PoseSet = blender::Set<bPose *>;
@ -91,14 +91,14 @@ static void version_bonegroup_migrate_color(Main *bmain)
/* There is no guarantee that the current state of poses is in sync with the Armature data.
*
* NOTE: No need to handle user refcounting in readfile code. */
* NOTE: No need to handle user reference-counting in readfile code. */
BKE_pose_ensure(bmain, ob, arm, false);
PoseSet &pose_set = armature_poses.lookup_or_add_default(arm);
pose_set.add(ob->pose);
}
/* Move colors from the pose's bonegroup to either the armature bones or the
/* Move colors from the pose's bone-group to either the armature bones or the
* pose bones, depending on how many poses use the Armature. */
for (const PoseSet &pose_set : armature_poses.values()) {
/* If the Armature is shared, the bone group colors might be different, and thus they have to

View File

@ -50,6 +50,9 @@ BMUVOffsets BM_uv_map_get_offsets_from_layer(const BMesh *bm, const int layer)
BMUVOffsets BM_uv_map_get_offsets(const BMesh *bm)
{
const int layer = CustomData_get_active_layer(&bm->ldata, CD_PROP_FLOAT2);
if (layer == -1) {
return {-1, -1, -1, -1};
}
return BM_uv_map_get_offsets_from_layer(bm, layer);
}

View File

@ -129,7 +129,8 @@ void Evaluator::map_node_operation_inputs_to_their_results(DNode node,
* origin is the input socket itself or the input is connected to an unlinked input of a group
* input node and the origin is the input of the group input node. So map the input to the
* result of a newly created Input Single Value Operation. */
auto *input_operation = new InputSingleValueOperation(context_, DInputSocket(dorigin));
InputSingleValueOperation *input_operation = new InputSingleValueOperation(
context_, DInputSocket(dorigin));
operation->map_input_to_result(input->identifier, &input_operation->get_result());
operations_stream_.append(std::unique_ptr<InputSingleValueOperation>(input_operation));

View File

@ -58,7 +58,6 @@ int compute_number_of_diagonals(ivec2 size)
* all share the same maximum value, that is, the longest length:
*
* Length => min(Longest Length, index + 1, Number Of Diagonals - index)
*
*/
int compute_diagonal_length(ivec2 size, int diagonal_index)
{
@ -94,7 +93,6 @@ int compute_diagonal_length(ivec2 size, int diagonal_index)
* while other indices are zero. Which can be described using the compact equation:
*
* Y => max(0, (height - 1) - index)
*
*/
ivec2 compute_diagonal_start(ivec2 size, int index)
{
@ -158,7 +156,6 @@ int compute_anti_diagonal_length(ivec2 size, int diagonal_index)
* from zero to (height - 1). Which can be described using the compact equation:
*
* Y => max(0, index - (width - 1))
*
*/
ivec2 compute_anti_diagonal_start(ivec2 size, int index)
{

View File

@ -10,7 +10,6 @@
* Based on Practical Realtime Strategies for Accurate Indirect Occlusion
* http://blog.selfshadow.com/publications/s2016-shading-course/activision/s2016_pbs_activision_occlusion.pdf
* http://blog.selfshadow.com/publications/s2016-shading-course/activision/s2016_pbs_activision_occlusion.pptx
*
*/
#pragma once

View File

@ -405,11 +405,14 @@ struct VelocityObjectIndex {
BLI_STATIC_ASSERT_ALIGN(VelocityObjectIndex, 16)
struct VelocityGeometryIndex {
/** Offset inside #VelocityGeometryBuf for each timestep. Indexed using eVelocityStep. */
/** Offset inside #VelocityGeometryBuf for each time-step. Indexed using eVelocityStep. */
packed_int3 ofs;
/** If true, compute deformation motion blur. */
bool1 do_deform;
/** Length of data inside #VelocityGeometryBuf for each timestep. Indexed using eVelocityStep. */
/**
* Length of data inside #VelocityGeometryBuf for each time-step.
* Indexed using eVelocityStep.
*/
packed_int3 len;
int _pad0;
@ -861,9 +864,9 @@ struct ShadowPagesInfoData {
int page_alloc_count;
/** Index of the next cache page in the cached page buffer. */
uint page_cached_next;
/** Index of the first page in the buffer since the last defrag. */
/** Index of the first page in the buffer since the last defragment. */
uint page_cached_start;
/** Index of the last page in the buffer since the last defrag. */
/** Index of the last page in the buffer since the last defragment. */
uint page_cached_end;
int _pad0;

View File

@ -4,7 +4,6 @@
/** \file
* \ingroup eevee
*
*/
#include "BLI_vector.hh"
@ -18,7 +17,6 @@ namespace blender::eevee {
/* -------------------------------------------------------------------- */
/** \name Subsurface
*
* \{ */
void SubsurfaceModule::end_sync()

View File

@ -8,7 +8,6 @@
* Volumetric effects rendering using Frostbite's Physically-based & Unified Volumetric Rendering
* approach.
* https://www.ea.com/frostbite/news/physically-based-unified-volumetric-rendering-in-frostbite
*
*/
#include "DNA_volume_types.h"

View File

@ -1,6 +1,9 @@
/* SPDX-FileCopyrightText: 2023 Blender Authors
*
* SPDX-License-Identifier: GPL-2.0-or-later */
/**
* Virtual shadowmapping: Usage tagging
* Virtual shadow-mapping: Usage tagging
*
* Shadow pages are only allocated if they are visible.
* This pass scans all volume froxels and tags tiles needed for shadowing.

View File

@ -763,7 +763,7 @@ static void OVERLAY_engine_free()
static void OVERLAY_instance_free(void *instance_)
{
auto *instance = (Instance *)instance_;
Instance *instance = (Instance *)instance_;
if (instance != nullptr) {
delete instance;
}

View File

@ -96,7 +96,7 @@ static void OVERLAY_next_draw_scene(void *vedata)
static void OVERLAY_next_instance_free(void *instance_)
{
auto *instance = (Instance *)instance_;
Instance *instance = (Instance *)instance_;
if (instance != nullptr) {
delete instance;
}

View File

@ -90,7 +90,7 @@ static void SELECT_next_draw_scene(void *vedata)
static void SELECT_next_instance_free(void *instance_)
{
auto *instance = (Instance *)instance_;
Instance *instance = (Instance *)instance_;
if (instance != nullptr) {
delete instance;
}

View File

@ -4,7 +4,6 @@
/** \file
* \ingroup draw_engine
*
*/
#pragma once

View File

@ -201,14 +201,14 @@ static void accumululate_material_counts_mesh(
for (const int i : range) {
if (!mr.hide_poly[i]) {
const int mat = std::clamp(material_indices[i], 0, last_index);
tri_counts[mat] += ME_FACE_TRI_TOT(faces[i].size());
tri_counts[mat] += bke::mesh::face_triangles_num(faces[i].size());
}
}
}
else {
for (const int i : range) {
const int mat = std::clamp(material_indices[i], 0, last_index);
tri_counts[mat] += ME_FACE_TRI_TOT(faces[i].size());
tri_counts[mat] += bke::mesh::face_triangles_num(faces[i].size());
}
}
});

View File

@ -1301,7 +1301,7 @@ static void drw_add_attributes_vbo(GPUBatch *batch,
#ifdef DEBUG
/* Sanity check function to test if all requested batches are available. */
static void drw_mesh_batch_cache_check_available(struct TaskGraph *task_graph, Mesh *me)
static void drw_mesh_batch_cache_check_available(TaskGraph *task_graph, Mesh *me)
{
MeshBatchCache *cache = mesh_batch_cache_get(me);
/* Make sure all requested batches have been setup. */

View File

@ -390,6 +390,25 @@ void blend_to_default_fcurve(PointerRNA *id_ptr, FCurve *fcu, const float factor
/* ---------------- */
void scale_average_fcurve_segment(FCurve *fcu, FCurveSegment *segment, const float factor)
{
float y = 0;
/* Find first the average of the y values to then use it in the final calculation. */
for (int i = segment->start_index; i < segment->start_index + segment->length; i++) {
y += fcu->bezt[i].vec[1][1];
}
const float y_average = y / segment->length;
for (int i = segment->start_index; i < segment->start_index + segment->length; i++) {
const float key_y_value = interpf(y_average, fcu->bezt[i].vec[1][1], 1 - factor);
BKE_fcurve_keyframe_move_value_with_handles(&fcu->bezt[i], key_y_value);
}
}
/* ---------------- */
struct ButterworthCoefficients {
double *A, *d1, *d2;
int filter_order;

View File

@ -4789,7 +4789,6 @@ void CURVE_OT_make_segment(wmOperatorType *ot)
bool ED_curve_editnurb_select_pick(bContext *C,
const int mval[2],
const int dist_px,
const bool vert_without_handles,
const SelectPick_Params *params)
{
Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
@ -4805,8 +4804,7 @@ bool ED_curve_editnurb_select_pick(bContext *C,
ED_view3d_viewcontext_init(C, &vc, depsgraph);
copy_v2_v2_int(vc.mval, mval);
const bool use_handle_select = vert_without_handles &&
(vc.v3d->overlay.handle_display != CURVE_HANDLE_NONE);
const bool use_handle_select = (vc.v3d->overlay.handle_display != CURVE_HANDLE_NONE);
bool found = ED_curve_pick_vert_ex(&vc, true, dist_px, &nu, &bezt, &bp, &hand, &basact);

View File

@ -96,7 +96,7 @@ struct CurvePenData {
/* Whether a segment is being altered by click and drag. */
bool spline_nearby;
/* Whether some action was done. Used for select. */
bool acted;
bool changed;
/* Whether a point was found underneath the mouse. */
bool found_point;
/* Whether multiple selected points should be moved. */
@ -649,7 +649,7 @@ static void insert_bezt_to_nurb(Nurb *nu, const CutData *data, Curve *cu)
nu->bezt = new_bezt_array;
ED_curve_deselect_all(editnurb);
BKE_nurb_handles_calc(nu);
BEZT_SEL_ALL(new_bezt);
BEZT_SEL_IDX(new_bezt, 1);
}
/**
@ -960,6 +960,13 @@ static void extrude_vertices_from_selected_endpoints(EditNurb *editnurb,
MEM_freeN(nu1->bezt);
nu1->bezt = new_bezt;
nu1->pntsu += 2;
/* Set the new points selection. */
BEZT_DESEL_ALL(new_bezt);
BEZT_SEL_IDX(new_bezt, 0);
BEZT_DESEL_ALL(new_bezt + (nu1->pntsu - 1));
BEZT_SEL_IDX(new_bezt + (nu1->pntsu - 1), 2);
}
else {
BezTriple *new_bezt = (BezTriple *)MEM_mallocN((nu1->pntsu + 1) * sizeof(BezTriple),
@ -971,6 +978,10 @@ static void extrude_vertices_from_selected_endpoints(EditNurb *editnurb,
MEM_freeN(nu1->bezt);
nu1->bezt = new_bezt;
nu1->pntsu++;
/* Set the new points selection. */
BEZT_DESEL_ALL(new_bezt);
BEZT_SEL_IDX(new_bezt, 0);
}
cu->actnu = nu_index;
cu->actvert = 0;
@ -987,6 +998,10 @@ static void extrude_vertices_from_selected_endpoints(EditNurb *editnurb,
nu1->pntsu++;
cu->actnu = nu_index;
cu->actvert = nu1->pntsu - 1;
/* Set the new points selection. */
BEZT_DESEL_ALL(new_bezt + (nu1->pntsu - 1));
BEZT_SEL_IDX(new_bezt + (nu1->pntsu - 1), 2);
}
}
else {
@ -1421,21 +1436,11 @@ static void init_selected_bezt_handles(ListBase *nurbs)
static void toggle_select_bezt(BezTriple *bezt, const int bezt_idx, Curve *cu, Nurb *nu)
{
if (bezt_idx == 1) {
if (BEZT_ISSEL_IDX(bezt, 1)) {
BEZT_DESEL_ALL(bezt);
}
else {
BEZT_SEL_ALL(bezt);
}
if (BEZT_ISSEL_IDX(bezt, bezt_idx)) {
BEZT_DESEL_IDX(bezt, bezt_idx);
}
else {
if (BEZT_ISSEL_IDX(bezt, bezt_idx)) {
BEZT_DESEL_IDX(bezt, bezt_idx);
}
else {
BEZT_SEL_IDX(bezt, bezt_idx);
}
BEZT_SEL_IDX(bezt, bezt_idx);
}
if (BEZT_ISSEL_ANY(bezt)) {
@ -1466,7 +1471,7 @@ static void toggle_handle_types(BezTriple *bezt, int bezt_idx, CurvePenData *cpd
bezt->h2 = HD_FREE;
}
}
cpd->acted = true;
cpd->changed = true;
}
else if (bezt_idx == 2) {
if (bezt->h2 == HD_VECT) {
@ -1478,7 +1483,7 @@ static void toggle_handle_types(BezTriple *bezt, int bezt_idx, CurvePenData *cpd
bezt->h1 = HD_FREE;
}
}
cpd->acted = true;
cpd->changed = true;
}
}
@ -1643,59 +1648,60 @@ static int curve_pen_modal(bContext *C, wmOperator *op, const wmEvent *event)
if (cpd->spline_nearby && move_seg && cpd->msd != nullptr) {
MoveSegmentData *seg_data = cpd->msd;
move_segment(&vc, seg_data, event);
cpd->acted = true;
cpd->changed = true;
if (seg_data->nu && seg_data->nu->type == CU_BEZIER) {
BKE_nurb_handles_calc(seg_data->nu);
}
}
else if (cpd->move_adjacent) {
move_adjacent_handle(&vc, event, nurbs);
cpd->acted = true;
cpd->changed = true;
}
else if (cpd->new_point || (move_point && !cpd->spline_nearby && cpd->found_point)) {
/* Move only the bezt handles if it's a new point. */
move_all_selected_points(&vc, event, cpd, nurbs, cpd->new_point);
cpd->acted = true;
cpd->changed = true;
}
}
}
else if (ELEM(event->type, LEFTMOUSE)) {
if (ELEM(event->val, KM_RELEASE, KM_DBL_CLICK)) {
if (delete_point && !cpd->new_point && !cpd->dragging) {
if (ED_curve_editnurb_select_pick(C, event->mval, threshold_dist_px, false, &params)) {
cpd->acted = delete_point_under_mouse(&vc, event);
if (ED_curve_editnurb_select_pick(C, event->mval, threshold_dist_px, &params)) {
cpd->changed = delete_point_under_mouse(&vc, event);
}
}
/* Close spline on Click, if enabled. */
if (!cpd->acted && close_spline && close_spline_method == ON_CLICK && cpd->found_point &&
if (!cpd->changed && close_spline && close_spline_method == ON_CLICK && cpd->found_point &&
!cpd->dragging)
{
if (cpd->nu && !is_cyclic(cpd->nu)) {
copy_v2_v2_int(vc.mval, event->mval);
cpd->acted = make_cyclic_if_endpoints(&vc, cpd->nu, cpd->bezt, cpd->bp);
cpd->changed = make_cyclic_if_endpoints(&vc, cpd->nu, cpd->bezt, cpd->bp);
}
}
if (!cpd->acted && (insert_point || extrude_point) && cpd->spline_nearby && !cpd->dragging) {
if (!cpd->changed && (insert_point || extrude_point) && cpd->spline_nearby && !cpd->dragging)
{
if (insert_point) {
insert_point_to_segment(&vc, event);
cpd->new_point = true;
cpd->acted = true;
cpd->changed = true;
}
else if (extrude_point) {
extrude_points_from_selected_vertices(&vc, event, extrude_handle);
cpd->acted = true;
cpd->changed = true;
}
}
if (!cpd->acted && toggle_vector) {
if (!cpd->changed && toggle_vector) {
int bezt_idx;
get_closest_vertex_to_point_in_nurbs(&vc, nurbs, mval_fl, &nu, &bezt, &bp, &bezt_idx);
if (bezt) {
if (bezt_idx == 1 && cycle_handle_type) {
cycle_handles(bezt);
cpd->acted = true;
cpd->changed = true;
}
else {
toggle_handle_types(bezt, bezt_idx, cpd);
@ -1707,7 +1713,7 @@ static int curve_pen_modal(bContext *C, wmOperator *op, const wmEvent *event)
}
}
if (!cpd->selection_made && !cpd->acted) {
if (!cpd->selection_made && !cpd->changed) {
if (cpd->select_multi) {
int bezt_idx;
get_closest_vertex_to_point_in_nurbs(&vc, nurbs, mval_fl, &nu, &bezt, &bp, &bezt_idx);
@ -1722,7 +1728,7 @@ static int curve_pen_modal(bContext *C, wmOperator *op, const wmEvent *event)
}
}
else if (select_point) {
ED_curve_editnurb_select_pick(C, event->mval, threshold_dist_px, false, &params);
ED_curve_editnurb_select_pick(C, event->mval, threshold_dist_px, &params);
}
}
@ -1790,12 +1796,7 @@ static int curve_pen_invoke(bContext *C, wmOperator *op, const wmEvent *event)
/* Select the closest bezt or bp. */
ED_curve_deselect_all(cu->editnurb);
if (bezt1) {
if (bezt_idx == 1) {
BEZT_SEL_ALL(bezt1);
}
else {
BEZT_SEL_IDX(bezt1, bezt_idx);
}
BEZT_SEL_IDX(bezt1, bezt_idx);
BKE_curve_nurb_vert_active_set(cu, nu1, bezt1);
}
else if (bp1) {
@ -1809,11 +1810,11 @@ static int curve_pen_invoke(bContext *C, wmOperator *op, const wmEvent *event)
/* Close the spline on press. */
if (close_spline && close_spline_method == ON_PRESS && cpd->nu && !is_cyclic(cpd->nu)) {
copy_v2_v2_int(vc.mval, event->mval);
cpd->new_point = cpd->acted = cpd->link_handles = make_cyclic_if_endpoints(
cpd->new_point = cpd->changed = cpd->link_handles = make_cyclic_if_endpoints(
&vc, cpd->nu, cpd->bezt, cpd->bp);
}
}
else if (!cpd->acted) {
else if (!cpd->changed) {
if (is_spline_nearby(&vc, op, event, threshold_dist_px)) {
cpd->spline_nearby = true;
@ -1821,12 +1822,12 @@ static int curve_pen_invoke(bContext *C, wmOperator *op, const wmEvent *event)
* "new_point" to true so that the new point's handles can be controlled. */
if (insert_point && !move_seg) {
insert_point_to_segment(&vc, event);
cpd->new_point = cpd->acted = cpd->link_handles = true;
cpd->new_point = cpd->changed = cpd->link_handles = true;
}
}
else if (extrude_point) {
extrude_points_from_selected_vertices(&vc, event, extrude_handle);
cpd->new_point = cpd->acted = cpd->link_handles = true;
cpd->new_point = cpd->changed = cpd->link_handles = true;
}
}
}

View File

@ -47,12 +47,10 @@ void ED_curve_editnurb_free(Object *obedit);
/**
* \param dist_px: Maximum distance to pick (in pixels).
* \param vert_without_handles: When true, selecting the knot doesn't select the handles.
*/
bool ED_curve_editnurb_select_pick(bContext *C,
const int mval[2],
int dist_px,
bool vert_without_handles,
const SelectPick_Params *params);
Nurb *ED_curve_add_nurbs_primitive(

View File

@ -430,6 +430,7 @@ ListBase find_fcurve_segments(FCurve *fcu);
void clean_fcurve(bAnimContext *ac, bAnimListElem *ale, float thresh, bool cleardefault);
void blend_to_neighbor_fcurve_segment(FCurve *fcu, FCurveSegment *segment, float factor);
void breakdown_fcurve_segment(FCurve *fcu, FCurveSegment *segment, float factor);
void scale_average_fcurve_segment(struct FCurve *fcu, struct FCurveSegment *segment, float factor);
/**
* Get a 1D gauss kernel. Since the kernel is symmetrical, only calculates the positive side.
@ -470,7 +471,7 @@ void shear_fcurve_segment(struct FCurve *fcu,
* Shift the FCurve segment up/down so that it aligns with the key before/after
* the segment.
*
* \param factor blend factor from -1.0 to 1.0. The sign determines whether the
* \param factor: blend factor from -1.0 to 1.0. The sign determines whether the
* segment is aligned with the key before or after the segment.
*/
void blend_offset_fcurve_segment(FCurve *fcu, FCurveSegment *segment, float factor);

View File

@ -623,9 +623,9 @@ bool ED_autokeyframe_pchan(
bContext *C, Scene *scene, Object *ob, bPoseChannel *pchan, KeyingSet *ks);
/**
* Use for auto-key-framing
* Use for auto-key-framing.
* \param only_if_property_keyed: if true, auto-key-framing only creates keyframes on already keyed
* properties. This is by design when using buttons. For other callers such as gizmos or VSE
* properties. This is by design when using buttons. For other callers such as gizmos or sequencer
* preview transform, creating new animation/keyframes also on non-keyed properties is desired.
*/
bool ED_autokeyframe_property(bContext *C,

View File

@ -124,7 +124,6 @@ struct DragInfo {
* #wmDropBox is needed to request instances of it from a UI element and call its functions. For
* example the drop box using "UI_OT_view_drop" implements dropping for views and view items via
* this interface. To support other kinds of UI elements, similar drop boxes would be necessary.
*
*/
class DropTargetInterface {
public:

View File

@ -9115,11 +9115,6 @@ void ui_but_activate_event(bContext *C, ARegion *region, uiBut *but)
void ui_but_activate_over(bContext *C, ARegion *region, uiBut *but)
{
/* If there is an active button then add UI_SELECT_DRAW to the to-be-activated one. */
if (ui_region_find_active_but(CTX_wm_region(C))) {
but->flag |= UI_SELECT_DRAW;
}
button_activate_init(C, region, but, BUTTON_ACTIVATE_OVER);
}

View File

@ -344,6 +344,11 @@ static uiBlock *ui_block_func_POPUP(bContext *C, uiPopupBlockHandle *handle, voi
* to be within the window bounds may move it away from the mouse,
* This ensures we set an item to be active. */
if (but_activate) {
ARegion *region = CTX_wm_region(C);
if (region && region->regiontype == RGN_TYPE_TOOLS) {
/* In Toolbars, highlight the button with select color. */
but_activate->flag |= UI_SELECT_DRAW;
}
ui_but_activate_over(C, handle->region, but_activate);
}

View File

@ -219,6 +219,9 @@ static int modifier_add_asset_exec(bContext *C, wmOperator *op)
id_us_plus(&node_group->id);
MOD_nodes_update_interface(object, nmd);
/* By default, don't show the data-block selector since it's not usually necessary for assets. */
nmd->flag |= NODES_MODIFIER_HIDE_DATABLOCK_SELECTOR;
STRNCPY(nmd->modifier.name, DATA_(node_group->id.name + 2));
WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, object);

View File

@ -1449,7 +1449,7 @@ static int constraint_delete_exec(bContext *C, wmOperator *op)
/* free the constraint */
if (BKE_constraint_remove_ex(lb, ob, con, true)) {
/* needed to set the flags on posebones correctly */
/* Needed to set the flags on pose-bones correctly. */
ED_object_constraint_update(bmain, ob);
/* relations */
@ -1539,7 +1539,7 @@ static int constraint_apply_exec(bContext *C, wmOperator *op)
/* Update for any children that may get moved. */
DEG_id_tag_update(&ob->id, ID_RECALC_TRANSFORM);
/* Needed to set the flags on posebones correctly. */
/* Needed to set the flags on pose-bones correctly. */
ED_object_constraint_update(bmain, ob);
DEG_relations_tag_update(bmain);
@ -1639,7 +1639,7 @@ static int constraint_copy_exec(bContext *C, wmOperator *op)
BLI_assert(current_index >= 0);
BLI_listbase_link_move(constraints, copy_con, new_index - current_index);
/* Needed to set the flags on posebones correctly. */
/* Needed to set the flags on pose-bones correctly. */
ED_object_constraint_update(bmain, ob);
DEG_relations_tag_update(bmain);

View File

@ -3027,6 +3027,10 @@ static int drop_geometry_nodes_invoke(bContext *C, wmOperator *op, const wmEvent
return OPERATOR_CANCELLED;
}
if (!RNA_boolean_get(op->ptr, "show_datablock_in_modifier")) {
nmd->flag |= NODES_MODIFIER_HIDE_DATABLOCK_SELECTOR;
}
nmd->node_group = node_tree;
id_us_plus(&node_tree->id);
MOD_nodes_update_interface(ob, nmd);
@ -3057,6 +3061,11 @@ void OBJECT_OT_drop_geometry_nodes(wmOperatorType *ot)
INT32_MIN,
INT32_MAX);
RNA_def_property_flag(prop, (PropertyFlag)(PROP_HIDDEN | PROP_SKIP_SAVE));
RNA_def_boolean(ot->srna,
"show_datablock_in_modifier",
true,
"Show the datablock selector in the modifier",
"");
}
/** \} */

View File

@ -1006,8 +1006,8 @@ float ED_vgroup_vert_weight(Object *ob, bDeformGroup *dg, int vertnum)
void ED_vgroup_select_by_name(Object *ob, const char *name)
{
/* NOTE: actdef==0 signals on painting to create a new one,
* if a bone in posemode is selected */
/* NOTE: `actdef == 0` signals on painting to create a new one,
* if a bone in pose-mode is selected. */
BKE_object_defgroup_active_index_set(ob, BKE_object_defgroup_name_index(ob, name) + 1);
}

View File

@ -376,7 +376,6 @@ struct EraseOperationExecutor {
* source geometry, with the given \a factor.
* A point in the destination is a \a cut if it splits the source curves geometry, meaning it is
* the first point of a new curve in the destination.
*
*/
struct PointTransferData {
int src_point;

View File

@ -162,7 +162,7 @@ static void fsmenu_xdg_insert_entry(GHash *xdg_map,
#ifdef WIN32
/* Add Windows Quick Access items to the System list. */
static void fsmenu_add_windows_quick_access(struct FSMenu *fsmenu,
static void fsmenu_add_windows_quick_access(FSMenu *fsmenu,
FSMenuCategory category,
FSMenuInsert flag)
{

View File

@ -56,6 +56,20 @@ static float fcurve_display_alpha(FCurve *fcu)
return (fcu->flag & FCURVE_SELECTED) ? 1.0f : U.fcu_inactive_alpha;
}
/** Get the first and last index to the bezt array that are just outside min and max. */
static blender::int2 get_bounding_bezt_indices(FCurve *fcu, const float min, const float max)
{
bool replace;
int first, last;
first = BKE_fcurve_bezt_binarysearch_index(fcu->bezt, min, fcu->totvert, &replace);
first = clamp_i(first - 1, 0, fcu->totvert - 1);
last = BKE_fcurve_bezt_binarysearch_index(fcu->bezt, max, fcu->totvert, &replace);
last = replace ? last + 1 : last;
last = clamp_i(last, 0, fcu->totvert - 1);
return {first, last};
}
/** \} */
/* -------------------------------------------------------------------- */
@ -314,7 +328,8 @@ static void draw_fcurve_keyframe_vertices(
static void draw_fcurve_selected_handle_vertices(
FCurve *fcu, View2D *v2d, bool sel, bool sel_handle_only, uint pos)
{
(void)v2d; /* TODO: use this to draw only points in view */
const blender::int2 bounding_indices = get_bounding_bezt_indices(
fcu, v2d->cur.xmin, v2d->cur.xmax);
/* set handle color */
float hcolor[3];
@ -324,9 +339,9 @@ static void draw_fcurve_selected_handle_vertices(
immBeginAtMost(GPU_PRIM_POINTS, fcu->totvert * 2);
BezTriple *bezt = fcu->bezt;
BezTriple *prevbezt = nullptr;
for (int i = 0; i < fcu->totvert; i++, prevbezt = bezt, bezt++) {
for (int i = bounding_indices[0] + 1; i <= bounding_indices[1]; i++) {
BezTriple *prevbezt = &fcu->bezt[i - 1];
BezTriple *bezt = &fcu->bezt[i];
/* Draw the editmode handles for a bezier curve (others don't have handles)
* if their selection status matches the selection status we're drawing for
* - first handle only if previous beztriple was bezier-mode
@ -464,9 +479,9 @@ static bool draw_fcurve_handles_check(SpaceGraph *sipo, FCurve *fcu)
/* draw lines for F-Curve handles only (this is only done in EditMode)
* NOTE: draw_fcurve_handles_check must be checked before running this. */
static void draw_fcurve_handles(SpaceGraph *sipo, FCurve *fcu)
static void draw_fcurve_handles(SpaceGraph *sipo, ARegion *region, FCurve *fcu)
{
int sel, b;
using namespace blender;
GPUVertFormat *format = immVertexFormat();
uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
@ -480,15 +495,19 @@ static void draw_fcurve_handles(SpaceGraph *sipo, FCurve *fcu)
immBeginAtMost(GPU_PRIM_LINES, 4 * 2 * fcu->totvert);
const int2 bounding_indices = get_bounding_bezt_indices(
fcu, region->v2d.cur.xmin, region->v2d.cur.xmax);
/* slightly hacky, but we want to draw unselected points before selected ones
* so that selected points are clearly visible
*/
for (sel = 0; sel < 2; sel++) {
BezTriple *bezt = fcu->bezt, *prevbezt = nullptr;
for (int sel = 0; sel < 2; sel++) {
int basecol = (sel) ? TH_HANDLE_SEL_FREE : TH_HANDLE_FREE;
uchar col[4];
for (b = 0; b < fcu->totvert; b++, prevbezt = bezt, bezt++) {
for (int i = bounding_indices[0] + 1; i <= bounding_indices[1]; i++) {
BezTriple *prevbezt = &fcu->bezt[i - 1];
BezTriple *bezt = &fcu->bezt[i];
/* if only selected keyframes can get their handles shown,
* check that keyframe is selected
*/
@ -865,8 +884,8 @@ static int calculate_bezt_draw_resolution(BezTriple *bezt,
}
/**
* Add points on the bezier between \param prevbezt and \param bezt to \param curve_vertices. The
* amount of points added is based on the given \param resolution.
* Add points on the bezier between `prevbezt` and `bezt` to `curve_vertices`.
* The amount of points added is based on the given `resolution`.
*/
static void add_bezt_vertices(BezTriple *bezt,
BezTriple *prevbezt,
@ -923,20 +942,6 @@ static void add_bezt_vertices(BezTriple *bezt,
MEM_freeN(bezier_diff_points);
}
/** Get the first and last index to the bezt array that are just outside min and max. */
static blender::int2 get_bounding_bezt_indices(FCurve *fcu, const float min, const float max)
{
bool replace;
int first, last;
first = BKE_fcurve_bezt_binarysearch_index(fcu->bezt, min, fcu->totvert, &replace);
first = clamp_i(first - 1, 0, fcu->totvert - 1);
last = BKE_fcurve_bezt_binarysearch_index(fcu->bezt, max, fcu->totvert, &replace);
last = replace ? last + 1 : last;
last = clamp_i(last, 0, fcu->totvert - 1);
return {first, last};
}
static void add_extrapolation_point_left(FCurve *fcu,
const float v2d_xmin,
blender::Vector<blender::float2> &curve_vertices)
@ -1316,7 +1321,7 @@ static void draw_fcurve(bAnimContext *ac, SpaceGraph *sipo, ARegion *region, bAn
if (do_handles) {
/* only draw handles/vertices on keyframes */
draw_fcurve_handles(sipo, fcu);
draw_fcurve_handles(sipo, region, fcu);
}
draw_fcurve_vertices(

View File

@ -894,13 +894,13 @@ void GRAPH_OT_clean(wmOperatorType *ot)
/** \} */
/* -------------------------------------------------------------------- */
/** \name Bake F-Curve Operator
/** \name Keys to Samples Operator
*
* This operator bakes the data of the selected F-Curves to F-Points.
* \{ */
/* Bake each F-Curve into a set of samples. */
static void bake_graph_curves(bAnimContext *ac, int start, int end)
static void convert_keys_to_samples(bAnimContext *ac, int start, int end)
{
ListBase anim_data = {nullptr, nullptr};
int filter;
@ -934,7 +934,7 @@ static void bake_graph_curves(bAnimContext *ac, int start, int end)
/* ------------------- */
static int graphkeys_bake_exec(bContext *C, wmOperator * /*op*/)
static int graphkeys_keys_to_samples_exec(bContext *C, wmOperator * /*op*/)
{
bAnimContext ac;
Scene *scene = nullptr;
@ -951,8 +951,8 @@ static int graphkeys_bake_exec(bContext *C, wmOperator * /*op*/)
start = PSFRA;
end = PEFRA;
/* Bake keyframes. */
bake_graph_curves(&ac, start, end);
/* Sample keyframes. */
convert_keys_to_samples(&ac, start, end);
/* Set notifier that keyframes have changed. */
/* NOTE: some distinction between order/number of keyframes and type should be made? */
@ -961,16 +961,17 @@ static int graphkeys_bake_exec(bContext *C, wmOperator * /*op*/)
return OPERATOR_FINISHED;
}
void GRAPH_OT_bake(wmOperatorType *ot)
void GRAPH_OT_keys_to_samples(wmOperatorType *ot)
{
/* Identifiers */
ot->name = "Bake Curve";
ot->idname = "GRAPH_OT_bake";
ot->description = "Bake selected F-Curves to a set of sampled points defining a similar curve";
ot->name = "Keys to Samples";
ot->idname = "GRAPH_OT_keys_to_samples";
ot->description =
"Convert selected channels to an uneditable set of samples to save storage space";
/* API callbacks */
ot->invoke = WM_operator_confirm_or_exec;
ot->exec = graphkeys_bake_exec;
ot->exec = graphkeys_keys_to_samples_exec;
ot->poll = graphop_selected_fcurve_poll;
/* Flags */
@ -983,13 +984,13 @@ void GRAPH_OT_bake(wmOperatorType *ot)
/** \} */
/* -------------------------------------------------------------------- */
/** \name Un-Bake F-Curve Operator
/** \name Samples to Keys Operator
*
* This operator un-bakes the data of the selected F-Points to F-Curves.
* This operator converts the data of the selected F-Points to F-Curves.
* \{ */
/* Un-Bake F-Points into F-Curves. */
static void unbake_graph_curves(bAnimContext *ac, int start, int end)
/* Convert F-Points into F-Curves. */
static void convert_samples_to_keys(bAnimContext *ac, int start, int end)
{
ListBase anim_data = {nullptr, nullptr};
@ -1014,7 +1015,7 @@ static void unbake_graph_curves(bAnimContext *ac, int start, int end)
/* ------------------- */
static int graphkeys_unbake_exec(bContext *C, wmOperator * /*op*/)
static int graphkeys_samples_to_keys_exec(bContext *C, wmOperator * /*op*/)
{
bAnimContext ac;
Scene *scene = nullptr;
@ -1029,8 +1030,7 @@ static int graphkeys_unbake_exec(bContext *C, wmOperator * /*op*/)
start = PSFRA;
end = PEFRA;
/* Unbake keyframes. */
unbake_graph_curves(&ac, start, end);
convert_samples_to_keys(&ac, start, end);
/* Set notifier that keyframes have changed. */
/* NOTE: some distinction between order/number of keyframes and type should be made? */
@ -1039,15 +1039,15 @@ static int graphkeys_unbake_exec(bContext *C, wmOperator * /*op*/)
return OPERATOR_FINISHED;
}
void GRAPH_OT_unbake(wmOperatorType *ot)
void GRAPH_OT_samples_to_keys(wmOperatorType *ot)
{
/* Identifiers */
ot->name = "Un-Bake Curve";
ot->idname = "GRAPH_OT_unbake";
ot->description = "Un-Bake selected F-Points to F-Curves";
ot->name = "Samples to Keys";
ot->idname = "GRAPH_OT_samples_to_keys";
ot->description = "Convert selected channels from samples to keyframes";
/* API callbacks */
ot->exec = graphkeys_unbake_exec;
ot->exec = graphkeys_samples_to_keys_exec;
ot->poll = graphop_selected_fcurve_poll;
/* Flags */
@ -1059,9 +1059,9 @@ void GRAPH_OT_unbake(wmOperatorType *ot)
/** \} */
/* -------------------------------------------------------------------- */
/** \name Sound Bake F-Curve Operator
/** \name Sound to Samples Operator
*
* This operator bakes the given sound to the selected F-Curves.
* This operator converts the given sound to samples on the selected F-Curves.
* \{ */
/* ------------------- */
@ -1094,7 +1094,7 @@ static float fcurve_samplingcb_sound(FCurve * /*fcu*/, void *data, float evaltim
/* ------------------- */
static int graphkeys_sound_bake_exec(bContext *C, wmOperator *op)
static int graphkeys_sound_to_samples_exec(bContext *C, wmOperator *op)
{
bAnimContext ac;
ListBase anim_data = {nullptr, nullptr};
@ -1175,7 +1175,7 @@ static int graphkeys_sound_bake_exec(bContext *C, wmOperator *op)
#else /* WITH_AUDASPACE */
static int graphkeys_sound_bake_exec(bContext * /*C*/, wmOperator *op)
static int graphkeys_sound_to_samples_exec(bContext * /*C*/, wmOperator *op)
{
BKE_report(op->reports, RPT_ERROR, "Compiled without sound support");
@ -1184,7 +1184,7 @@ static int graphkeys_sound_bake_exec(bContext * /*C*/, wmOperator *op)
#endif /* WITH_AUDASPACE */
static int graphkeys_sound_bake_invoke(bContext *C, wmOperator *op, const wmEvent *event)
static int graphkeys_sound_to_samples_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
bAnimContext ac;
@ -1196,16 +1196,16 @@ static int graphkeys_sound_bake_invoke(bContext *C, wmOperator *op, const wmEven
return WM_operator_filesel(C, op, event);
}
void GRAPH_OT_sound_bake(wmOperatorType *ot)
void GRAPH_OT_sound_to_samples(wmOperatorType *ot)
{
/* Identifiers */
ot->name = "Bake Sound to F-Curves";
ot->idname = "GRAPH_OT_sound_bake";
ot->description = "Bakes a sound wave to selected F-Curves";
ot->name = "Sound to Samples";
ot->idname = "GRAPH_OT_sound_to_samples";
ot->description = "Bakes a sound wave to samples on selected channels";
/* API callbacks */
ot->invoke = graphkeys_sound_bake_invoke;
ot->exec = graphkeys_sound_bake_exec;
ot->invoke = graphkeys_sound_to_samples_invoke;
ot->exec = graphkeys_sound_to_samples_exec;
ot->poll = graphop_selected_fcurve_poll;
/* Flags */

View File

@ -123,14 +123,15 @@ void GRAPH_OT_blend_offset(struct wmOperatorType *ot);
void GRAPH_OT_blend_to_ease(struct wmOperatorType *ot);
void GRAPH_OT_match_slope(struct wmOperatorType *ot);
void GRAPH_OT_shear(struct wmOperatorType *ot);
void GRAPH_OT_scale_average(struct wmOperatorType *ot);
void GRAPH_OT_decimate(struct wmOperatorType *ot);
void GRAPH_OT_blend_to_default(struct wmOperatorType *ot);
void GRAPH_OT_butterworth_smooth(struct wmOperatorType *ot);
void GRAPH_OT_gaussian_smooth(struct wmOperatorType *ot);
void GRAPH_OT_sample(struct wmOperatorType *ot);
void GRAPH_OT_bake(struct wmOperatorType *ot);
void GRAPH_OT_unbake(struct wmOperatorType *ot);
void GRAPH_OT_sound_bake(struct wmOperatorType *ot);
void GRAPH_OT_keys_to_samples(struct wmOperatorType *ot);
void GRAPH_OT_samples_to_keys(struct wmOperatorType *ot);
void GRAPH_OT_sound_to_samples(struct wmOperatorType *ot);
void GRAPH_OT_smooth(struct wmOperatorType *ot);
void GRAPH_OT_euler_filter(struct wmOperatorType *ot);

View File

@ -460,9 +460,9 @@ void graphedit_operatortypes()
WM_operatortype_append(GRAPH_OT_extrapolation_type);
WM_operatortype_append(GRAPH_OT_easing_type);
WM_operatortype_append(GRAPH_OT_sample);
WM_operatortype_append(GRAPH_OT_bake);
WM_operatortype_append(GRAPH_OT_unbake);
WM_operatortype_append(GRAPH_OT_sound_bake);
WM_operatortype_append(GRAPH_OT_keys_to_samples);
WM_operatortype_append(GRAPH_OT_samples_to_keys);
WM_operatortype_append(GRAPH_OT_sound_to_samples);
WM_operatortype_append(GRAPH_OT_smooth);
WM_operatortype_append(GRAPH_OT_clean);
WM_operatortype_append(GRAPH_OT_decimate);
@ -470,6 +470,7 @@ void graphedit_operatortypes()
WM_operatortype_append(GRAPH_OT_breakdown);
WM_operatortype_append(GRAPH_OT_ease);
WM_operatortype_append(GRAPH_OT_shear);
WM_operatortype_append(GRAPH_OT_scale_average);
WM_operatortype_append(GRAPH_OT_blend_offset);
WM_operatortype_append(GRAPH_OT_blend_to_ease);
WM_operatortype_append(GRAPH_OT_match_slope);

View File

@ -1289,6 +1289,8 @@ void GRAPH_OT_match_slope(wmOperatorType *ot)
1.0f);
}
/** \} */
/* -------------------------------------------------------------------- */
/** \name Shear Operator
* \{ */
@ -1457,7 +1459,96 @@ void GRAPH_OT_shear(wmOperatorType *ot)
"Which end of the segment to use as a reference to shear from");
}
/* -------------------------------------------------------------------- */
/** \name Scale Average Operator
* \{ */
static void scale_average_graph_keys(bAnimContext *ac, const float factor)
{
apply_fcu_segment_function(ac, factor, scale_average_fcurve_segment);
}
static void scale_average_modal_update(bContext *C, wmOperator *op)
{
tGraphSliderOp *gso = static_cast<tGraphSliderOp *>(op->customdata);
common_draw_status_header(C, gso, "Scale to Average");
/* Reset keyframes to the state at invoke. */
reset_bezts(gso);
const float factor = slider_factor_get_and_remember(op);
scale_average_graph_keys(&gso->ac, factor);
WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, NULL);
}
static int scale_average_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
const int invoke_result = graph_slider_invoke(C, op, event);
if (invoke_result == OPERATOR_CANCELLED) {
return invoke_result;
}
tGraphSliderOp *gso = static_cast<tGraphSliderOp *>(op->customdata);
gso->modal_update = scale_average_modal_update;
gso->factor_prop = RNA_struct_find_property(op->ptr, "factor");
common_draw_status_header(C, gso, "Scale to Average");
ED_slider_factor_bounds_set(gso->slider, 0, 2);
ED_slider_factor_set(gso->slider, 1.0f);
return invoke_result;
}
static int scale_average_exec(bContext *C, wmOperator *op)
{
bAnimContext ac;
/* Get editor data. */
if (ANIM_animdata_get_context(C, &ac) == 0) {
return OPERATOR_CANCELLED;
}
const float factor = RNA_float_get(op->ptr, "factor");
scale_average_graph_keys(&ac, factor);
/* Set notifier that keyframes have changed. */
WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, NULL);
return OPERATOR_FINISHED;
}
void GRAPH_OT_scale_average(wmOperatorType *ot)
{
/* Identifiers. */
ot->name = "Scale Average Keyframes";
ot->idname = "GRAPH_OT_scale_average";
ot->description =
"Increase or decrease the value of selected keys \n\
in relationship to their average";
/* API callbacks. */
ot->invoke = scale_average_invoke;
ot->modal = graph_slider_modal;
ot->exec = scale_average_exec;
ot->poll = graphop_editable_keyframes_poll;
/* Flags. */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_BLOCKING | OPTYPE_GRAB_CURSOR_X;
RNA_def_float_factor(ot->srna,
"factor",
1.0f,
-FLT_MAX,
FLT_MAX,
"Scale Factor",
"The scale factor applied to the curve segments",
0.0f,
2.0f);
}
/** \} */
/* -------------------------------------------------------------------- */
/** \name Gauss Smooth Operator
* \{ */

View File

@ -526,7 +526,6 @@ static void node_update_basis_from_declaration(
if (!is_parent_collapsed) {
locy -= NODE_DY;
is_first = false;
need_spacer_after_item = true;
}
SET_FLAG_FROM_TEST(
@ -1758,6 +1757,12 @@ static void node_draw_panels_background(const bNode &node, uiBlock &block)
const nodes::NodeDeclaration &decl = *node.declaration();
const rctf &rct = node.runtime->totr;
float color_panel[4];
UI_GetThemeColorBlend4f(TH_BACK, TH_NODE, 0.2f, color_panel);
/* True if the last panel is open, draw bottom gap as background. */
bool is_last_panel_visible = false;
float last_panel_content_y = 0.0f;
int panel_i = 0;
for (const nodes::ItemDeclarationPtr &item_decl : decl.items) {
@ -1769,25 +1774,21 @@ static void node_draw_panels_background(const bNode &node, uiBlock &block)
}
const bNodePanelState &state = node.panel_states()[panel_i];
const bke::bNodePanelRuntime &runtime = node.runtime->panels[panel_i];
/* Don't draw hidden or collapsed panels. */
if (state.is_collapsed() || state.is_parent_collapsed()) {
const bool is_visible = !(state.is_collapsed() || state.is_parent_collapsed());
is_last_panel_visible = is_visible;
last_panel_content_y = runtime.max_content_y;
if (!is_visible) {
++panel_i;
continue;
}
const bke::bNodePanelRuntime &runtime = node.runtime->panels[panel_i];
const rctf content_rect = {
rct.xmin,
rct.xmax,
runtime.min_content_y,
runtime.max_content_y,
};
UI_block_emboss_set(&block, UI_EMBOSS_NONE);
/* Panel background. */
float color_panel[4];
UI_GetThemeColorBlend4f(TH_BACK, TH_NODE, 0.2f, color_panel);
const rctf content_rect = {rct.xmin, rct.xmax, runtime.min_content_y, runtime.max_content_y};
UI_draw_roundbox_corner_set(UI_CNR_NONE);
UI_draw_roundbox_4fv(&content_rect, true, BASIS_RAD, color_panel);
@ -1795,6 +1796,17 @@ static void node_draw_panels_background(const bNode &node, uiBlock &block)
++panel_i;
}
/* If last item is an open panel, extend the panel background to cover the bottom border. */
if (is_last_panel_visible) {
UI_block_emboss_set(&block, UI_EMBOSS_NONE);
const rctf content_rect = {rct.xmin, rct.xmax, rct.ymin, last_panel_content_y};
UI_draw_roundbox_corner_set(UI_CNR_BOTTOM_RIGHT | UI_CNR_BOTTOM_LEFT);
UI_draw_roundbox_4fv(&content_rect, true, BASIS_RAD, color_panel);
UI_block_emboss_set(&block, UI_EMBOSS);
}
}
static void node_draw_panels(bNodeTree &ntree, const bNode &node, uiBlock &block)
@ -2568,31 +2580,7 @@ static void node_draw_basis(const bContext &C,
/* Show/hide icons. */
float iconofs = rct.xmax - 0.35f * U.widget_unit;
/* Preview. */
if (node_is_previewable(snode, ntree, node)) {
iconofs -= iconbutw;
UI_block_emboss_set(&block, UI_EMBOSS_NONE);
uiBut *but = uiDefIconBut(&block,
UI_BTYPE_BUT_TOGGLE,
0,
ICON_MATERIAL,
iconofs,
rct.ymax - NODE_DY,
iconbutw,
UI_UNIT_Y,
nullptr,
0,
0,
0,
0,
"");
UI_but_func_set(but,
node_toggle_button_cb,
POINTER_FROM_INT(node.identifier),
(void *)"NODE_OT_preview_toggle");
UI_block_emboss_set(&block, UI_EMBOSS);
}
/* Group edit. */
/* Group edit. This icon should be the first for the node groups. */
if (node.type == NODE_GROUP) {
iconofs -= iconbutw;
UI_block_emboss_set(&block, UI_EMBOSS_NONE);
@ -2619,6 +2607,30 @@ static void node_draw_basis(const bContext &C,
}
UI_block_emboss_set(&block, UI_EMBOSS);
}
/* Preview. */
if (node_is_previewable(snode, ntree, node)) {
iconofs -= iconbutw;
UI_block_emboss_set(&block, UI_EMBOSS_NONE);
uiBut *but = uiDefIconBut(&block,
UI_BTYPE_BUT_TOGGLE,
0,
ICON_MATERIAL,
iconofs,
rct.ymax - NODE_DY,
iconbutw,
UI_UNIT_Y,
nullptr,
0,
0,
0,
0,
"");
UI_but_func_set(but,
node_toggle_button_cb,
POINTER_FROM_INT(node.identifier),
(void *)"NODE_OT_preview_toggle");
UI_block_emboss_set(&block, UI_EMBOSS);
}
if (node.type == NODE_CUSTOM && node.typeinfo->ui_icon != ICON_NONE) {
iconofs -= iconbutw;
UI_block_emboss_set(&block, UI_EMBOSS_NONE);

View File

@ -1022,6 +1022,7 @@ static void node_group_make_insert_selected(const bContext &C,
Map<int32_t, int32_t> node_identifier_map;
ntree.ensure_topology_cache();
/* Add all outputs first. */
for (bNode *node : nodes_to_move) {
for (bNodeSocket *output_socket : node->output_sockets()) {
for (bNodeLink *link : output_socket->directly_linked_links()) {
@ -1047,6 +1048,9 @@ static void node_group_make_insert_selected(const bContext &C,
}
}
}
}
/* Now add all inputs. */
for (bNode *node : nodes_to_move) {
for (bNodeSocket *input_socket : node->input_sockets()) {
for (bNodeLink *link : input_socket->directly_linked_links()) {
if (nodeLinkIsHidden(link)) {

View File

@ -36,7 +36,7 @@ void TreeElementIDArmature::expand(SpaceOutliner &space_outliner) const
expand_edit_bones();
}
else {
/* do not extend Armature when we have posemode */
/* Do not extend Armature when we have pose-mode. */
TreeStoreElem *tselem = TREESTORE(legacy_te_.parent);
if (TSE_IS_REAL_ID(tselem) && GS(tselem->id->name) == ID_OB &&
((Object *)tselem->id)->mode & OB_MODE_POSE)

View File

@ -29,22 +29,23 @@ set(SRC
sequencer_channels_draw.cc
sequencer_channels_edit.cc
sequencer_drag_drop.cc
sequencer_draw.cc
sequencer_edit.cc
sequencer_gizmo_retime.cc
sequencer_gizmo_retime_type.cc
sequencer_modifier.cc
sequencer_ops.cc
sequencer_preview.cc
sequencer_preview_draw.cc
sequencer_proxy.cc
sequencer_retiming.cc
sequencer_scopes.cc
sequencer_select.cc
sequencer_thumbnails.cc
sequencer_timeline_draw.cc
sequencer_view.cc
space_sequencer.cc
sequencer_intern.h
sequencer_intern.hh
)
set(LIB

View File

@ -70,7 +70,7 @@
#include "DEG_depsgraph_build.h"
/* Own include. */
#include "sequencer_intern.h"
#include "sequencer_intern.hh"
struct SequencerAddData {
ImageFormatData im_format;

View File

@ -27,7 +27,7 @@
#include "IMB_imbuf.h"
#include "IMB_imbuf_types.h"
#include "sequencer_intern.h"
#include "sequencer_intern.hh"
/* **************************** buttons ********************************* */

View File

@ -41,7 +41,7 @@
#include "WM_api.hh"
/* Own include. */
#include "sequencer_intern.h"
#include "sequencer_intern.hh"
static float draw_offset_get(const View2D *timeline_region_v2d)
{

View File

@ -29,7 +29,7 @@
#include "RNA_enum_types.hh"
/* Own include. */
#include "sequencer_intern.h"
#include "sequencer_intern.hh"
static int sequencer_rename_channel_invoke(bContext *C, wmOperator * /*op*/, const wmEvent *event)
{

View File

@ -47,7 +47,7 @@
#endif
/* Own include. */
#include "sequencer_intern.h"
#include "sequencer_intern.hh"
struct SeqDropCoords {
float start_frame, channel;

View File

@ -72,7 +72,7 @@
#include "DEG_depsgraph_build.h"
/* Own include. */
#include "sequencer_intern.h"
#include "sequencer_intern.hh"
/* -------------------------------------------------------------------- */
/** \name Structs & Enums
@ -3313,9 +3313,9 @@ static int sequencer_set_range_to_strips_exec(bContext *C, wmOperator *op)
if (seq->flag & SELECT) {
selected = true;
sfra = min_ii(sfra, SEQ_time_left_handle_frame_get(scene, seq));
/* Offset of -1 is needed because in VSE every frame has width. Range from 1 to 1 is drawn
* as range 1 to 2, because 1 frame long strip starts at frame 1 and ends at frame 2.
* See #106480. */
/* Offset of -1 is needed because in the sequencer every frame has width.
* Range from 1 to 1 is drawn as range 1 to 2, because 1 frame long strip starts at frame 1
* and ends at frame 2. See #106480. */
efra = max_ii(efra, SEQ_time_right_handle_frame_get(scene, seq) - 1);
}
}

View File

@ -31,7 +31,7 @@
#include "SEQ_sequencer.h"
/* Own include. */
#include "sequencer_intern.h"
#include "sequencer_intern.hh"
struct GizmoGroup_retime {
wmGizmo *add_handle_gizmo;

View File

@ -51,7 +51,7 @@
#include "SEQ_time.h"
/* Own include. */
#include "sequencer_intern.h"
#include "sequencer_intern.hh"
using blender::MutableSpan;

View File

@ -1,329 +0,0 @@
/* SPDX-FileCopyrightText: 2008 Blender Authors
*
* SPDX-License-Identifier: GPL-2.0-or-later */
/** \file
* \ingroup spseq
*/
#pragma once
#include "DNA_sequence_types.h"
#include "RNA_access.hh"
#ifdef __cplusplus
extern "C" {
#endif
/* Internal exports only. */
struct ARegion;
struct ARegionType;
struct Depsgraph;
struct wmGizmoGroupType;
struct wmGizmoType;
struct Main;
struct Scene;
struct SeqCollection;
struct Sequence;
struct SpaceSeq;
struct StripElem;
struct View2D;
struct bContext;
struct rctf;
struct wmOperator;
struct ScrArea;
struct Editing;
struct ListBase;
#define DEFAULT_IMG_STRIP_LENGTH 25 /* XXX arbitrary but ok for now. */
#define OVERLAP_ALPHA 180
typedef struct SeqChannelDrawContext {
const struct bContext *C;
struct ScrArea *area;
struct ARegion *region;
struct ARegion *timeline_region;
struct View2D *v2d;
struct View2D *timeline_region_v2d;
struct Scene *scene;
struct Editing *ed;
struct ListBase *seqbase; /* Displayed seqbase. */
struct ListBase *channels; /* Displayed channels. */
float draw_offset;
float channel_height;
float frame_width;
float scale;
} SeqChannelDrawContext;
/* `sequencer_draw.cc` */
void draw_timeline_seq(const struct bContext *C, struct ARegion *region);
void draw_timeline_seq_display(const struct bContext *C, struct ARegion *region);
void sequencer_draw_preview(const struct bContext *C,
struct Scene *scene,
struct ARegion *region,
struct SpaceSeq *sseq,
int timeline_frame,
int offset,
bool draw_overlay,
bool draw_backdrop);
void color3ubv_from_seq(const struct Scene *curscene,
const struct Sequence *seq,
bool show_strip_color_tag,
uchar r_col[3]);
void sequencer_special_update_set(Sequence *seq);
/* Get handle width in 2d-View space. */
float sequence_handle_size_get_clamped(const struct Scene *scene,
struct Sequence *seq,
float pixelx);
/* UNUSED */
/* void seq_reset_imageofs(struct SpaceSeq *sseq); */
/**
* Rendering using opengl will change the current viewport/context.
* This is why we need the \a region, to set back the render area.
*
* TODO: do not rely on such hack and just update the \a ibuf outside of
* the UI drawing code.
*/
struct ImBuf *sequencer_ibuf_get(struct Main *bmain,
struct ARegion *region,
struct Depsgraph *depsgraph,
struct Scene *scene,
struct SpaceSeq *sseq,
int timeline_frame,
int frame_ofs,
const char *viewname);
/* `sequencer_thumbnails.cc` */
void last_displayed_thumbnails_list_free(void *val);
void draw_seq_strip_thumbnail(struct View2D *v2d,
const struct bContext *C,
struct Scene *scene,
struct Sequence *seq,
float y1,
float y2,
float pixelx,
float pixely);
/* sequencer_draw_channels.c */
void draw_channels(const struct bContext *C, struct ARegion *region);
void channel_draw_context_init(const struct bContext *C,
struct ARegion *region,
struct SeqChannelDrawContext *r_context);
/* `sequencer_edit.cc` */
struct View2D;
void seq_rectf(const struct Scene *scene, struct Sequence *seq, struct rctf *rectf);
struct Sequence *find_nearest_seq(struct Scene *scene,
struct View2D *v2d,
int *hand,
const int mval[2]);
struct Sequence *find_neighboring_sequence(struct Scene *scene,
struct Sequence *test,
int lr,
int sel);
void recurs_sel_seq(struct Sequence *seq_meta);
int seq_effect_find_selected(struct Scene *scene,
struct Sequence *activeseq,
int type,
struct Sequence **r_selseq1,
struct Sequence **r_selseq2,
struct Sequence **r_selseq3,
const char **r_error_str);
/* Operator helpers. */
bool sequencer_edit_poll(struct bContext *C);
bool sequencer_edit_with_channel_region_poll(struct bContext *C);
bool sequencer_editing_initialized_and_active(struct bContext *C);
/* UNUSED */
/* bool sequencer_strip_poll(struct bContext *C); */
bool sequencer_strip_has_path_poll(struct bContext *C);
bool sequencer_view_has_preview_poll(struct bContext *C);
bool sequencer_view_preview_only_poll(const struct bContext *C);
bool sequencer_view_strips_poll(struct bContext *C);
/**
* Returns collection with all strips presented to user. If operation is done in preview,
* collection is limited to all presented strips that can produce image output.
*
* \param C: context
* \return collection of strips (`Sequence`)
*/
struct SeqCollection *all_strips_from_context(struct bContext *C);
/**
* Returns collection with selected strips presented to user. If operation is done in preview,
* collection is limited to selected presented strips, that can produce image output at current
* frame.
*
* \param C: context
* \return collection of strips (`Sequence`)
*/
struct SeqCollection *selected_strips_from_context(struct bContext *C);
/* Externs. */
extern EnumPropertyItem sequencer_prop_effect_types[];
extern EnumPropertyItem prop_side_types[];
/* Operators. */
struct wmKeyConfig;
struct wmOperatorType;
void SEQUENCER_OT_split(struct wmOperatorType *ot);
void SEQUENCER_OT_slip(struct wmOperatorType *ot);
void SEQUENCER_OT_mute(struct wmOperatorType *ot);
void SEQUENCER_OT_unmute(struct wmOperatorType *ot);
void SEQUENCER_OT_lock(struct wmOperatorType *ot);
void SEQUENCER_OT_unlock(struct wmOperatorType *ot);
void SEQUENCER_OT_reload(struct wmOperatorType *ot);
void SEQUENCER_OT_refresh_all(struct wmOperatorType *ot);
void SEQUENCER_OT_reassign_inputs(struct wmOperatorType *ot);
void SEQUENCER_OT_swap_inputs(struct wmOperatorType *ot);
void SEQUENCER_OT_duplicate(struct wmOperatorType *ot);
void SEQUENCER_OT_delete(struct wmOperatorType *ot);
void SEQUENCER_OT_offset_clear(struct wmOperatorType *ot);
void SEQUENCER_OT_images_separate(struct wmOperatorType *ot);
void SEQUENCER_OT_meta_toggle(struct wmOperatorType *ot);
void SEQUENCER_OT_meta_make(struct wmOperatorType *ot);
void SEQUENCER_OT_meta_separate(struct wmOperatorType *ot);
void SEQUENCER_OT_gap_remove(struct wmOperatorType *ot);
void SEQUENCER_OT_gap_insert(struct wmOperatorType *ot);
void SEQUENCER_OT_snap(struct wmOperatorType *ot);
void SEQUENCER_OT_strip_jump(struct wmOperatorType *ot);
void SEQUENCER_OT_swap(struct wmOperatorType *ot);
void SEQUENCER_OT_swap_data(struct wmOperatorType *ot);
void SEQUENCER_OT_rendersize(struct wmOperatorType *ot);
void SEQUENCER_OT_change_effect_input(struct wmOperatorType *ot);
void SEQUENCER_OT_change_effect_type(struct wmOperatorType *ot);
void SEQUENCER_OT_change_path(struct wmOperatorType *ot);
void SEQUENCER_OT_change_scene(struct wmOperatorType *ot);
void SEQUENCER_OT_copy(struct wmOperatorType *ot);
void SEQUENCER_OT_paste(struct wmOperatorType *ot);
void SEQUENCER_OT_rebuild_proxy(struct wmOperatorType *ot);
void SEQUENCER_OT_enable_proxies(struct wmOperatorType *ot);
void SEQUENCER_OT_export_subtitles(struct wmOperatorType *ot);
void SEQUENCER_OT_set_range_to_strips(struct wmOperatorType *ot);
void SEQUENCER_OT_strip_transform_clear(struct wmOperatorType *ot);
void SEQUENCER_OT_strip_transform_fit(struct wmOperatorType *ot);
void SEQUENCER_OT_strip_color_tag_set(struct wmOperatorType *ot);
void SEQUENCER_OT_cursor_set(struct wmOperatorType *ot);
void SEQUENCER_OT_scene_frame_range_update(struct wmOperatorType *ot);
/* `sequencer_select.cc` */
void SEQUENCER_OT_select_all(struct wmOperatorType *ot);
void SEQUENCER_OT_select(struct wmOperatorType *ot);
void SEQUENCER_OT_select_side_of_frame(struct wmOperatorType *ot);
void SEQUENCER_OT_select_more(struct wmOperatorType *ot);
void SEQUENCER_OT_select_less(struct wmOperatorType *ot);
void SEQUENCER_OT_select_linked(struct wmOperatorType *ot);
void SEQUENCER_OT_select_linked_pick(struct wmOperatorType *ot);
void SEQUENCER_OT_select_handles(struct wmOperatorType *ot);
void SEQUENCER_OT_select_side(struct wmOperatorType *ot);
void SEQUENCER_OT_select_box(struct wmOperatorType *ot);
void SEQUENCER_OT_select_inverse(struct wmOperatorType *ot);
void SEQUENCER_OT_select_grouped(struct wmOperatorType *ot);
/* `sequencer_add.cc` */
void SEQUENCER_OT_scene_strip_add(struct wmOperatorType *ot);
void SEQUENCER_OT_scene_strip_add_new(struct wmOperatorType *ot);
void SEQUENCER_OT_movie_strip_add(struct wmOperatorType *ot);
void SEQUENCER_OT_movieclip_strip_add(struct wmOperatorType *ot);
void SEQUENCER_OT_mask_strip_add(struct wmOperatorType *ot);
void SEQUENCER_OT_sound_strip_add(struct wmOperatorType *ot);
void SEQUENCER_OT_image_strip_add(struct wmOperatorType *ot);
void SEQUENCER_OT_effect_strip_add(struct wmOperatorType *ot);
/* `sequencer_drag_drop.cc` */
void sequencer_dropboxes(void);
/* `sequencer_ops.cc` */
void sequencer_operatortypes(void);
void sequencer_keymap(struct wmKeyConfig *keyconf);
/* sequencer_scope.c */
struct ImBuf *make_waveform_view_from_ibuf(struct ImBuf *ibuf);
struct ImBuf *make_sep_waveform_view_from_ibuf(struct ImBuf *ibuf);
struct ImBuf *make_vectorscope_view_from_ibuf(struct ImBuf *ibuf);
struct ImBuf *make_zebra_view_from_ibuf(struct ImBuf *ibuf, float perc);
struct ImBuf *make_histogram_view_from_ibuf(struct ImBuf *ibuf);
/* `sequencer_buttons.cc` */
void sequencer_buttons_register(struct ARegionType *art);
/* sequencer_modifiers.c */
void SEQUENCER_OT_strip_modifier_add(struct wmOperatorType *ot);
void SEQUENCER_OT_strip_modifier_remove(struct wmOperatorType *ot);
void SEQUENCER_OT_strip_modifier_move(struct wmOperatorType *ot);
void SEQUENCER_OT_strip_modifier_copy(struct wmOperatorType *ot);
void SEQUENCER_OT_strip_modifier_equalizer_redefine(struct wmOperatorType *ot);
/* `sequencer_view.cc` */
void SEQUENCER_OT_sample(struct wmOperatorType *ot);
void SEQUENCER_OT_view_all(struct wmOperatorType *ot);
void SEQUENCER_OT_view_frame(struct wmOperatorType *ot);
void SEQUENCER_OT_view_all_preview(struct wmOperatorType *ot);
void SEQUENCER_OT_view_zoom_ratio(struct wmOperatorType *ot);
void SEQUENCER_OT_view_selected(struct wmOperatorType *ot);
void SEQUENCER_OT_view_ghost_border(struct wmOperatorType *ot);
/* `sequencer_channels_edit.cc` */
void SEQUENCER_OT_rename_channel(struct wmOperatorType *ot);
/* `sequencer_preview.cc` */
void sequencer_preview_add_sound(const struct bContext *C, struct Sequence *seq);
/* `sequencer_add.cc` */
int sequencer_image_seq_get_minmax_frame(struct wmOperator *op,
int sfra,
int *r_minframe,
int *r_numdigits);
void sequencer_image_seq_reserve_frames(
struct wmOperator *op, struct StripElem *se, int len, int minframe, int numdigits);
/* `sequencer_retiming.cc` */
void SEQUENCER_OT_retiming_reset(struct wmOperatorType *ot);
void SEQUENCER_OT_retiming_handle_move(struct wmOperatorType *ot);
void SEQUENCER_OT_retiming_handle_add(struct wmOperatorType *ot);
void SEQUENCER_OT_retiming_handle_remove(struct wmOperatorType *ot);
void SEQUENCER_OT_retiming_segment_speed_set(struct wmOperatorType *ot);
/* `sequencer_gizmo_retime.cc` */
void SEQUENCER_GGT_gizmo_retime(struct wmGizmoGroupType *gzgt);
/* `sequencer_gizmo_retime_type.cc` */
void GIZMO_GT_retime_handle_add(struct wmGizmoType *gzt);
void GIZMO_GT_retime_handle(struct wmGizmoType *gzt);
void GIZMO_GT_retime_remove(struct wmGizmoType *gzt);
void GIZMO_GT_speed_set_remove(struct wmGizmoType *gzt);
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,317 @@
/* SPDX-FileCopyrightText: 2008 Blender Authors
*
* SPDX-License-Identifier: GPL-2.0-or-later */
/** \file
* \ingroup spseq
*/
#pragma once
#include "DNA_sequence_types.h"
#include "RNA_access.hh"
/* Internal exports only. */
struct ARegion;
struct ARegionType;
struct Depsgraph;
struct wmGizmoGroupType;
struct wmGizmoType;
struct Main;
struct Scene;
struct SeqCollection;
struct Sequence;
struct SpaceSeq;
struct StripElem;
struct View2D;
struct bContext;
struct rctf;
struct wmKeyConfig;
struct wmOperator;
struct wmOperatorType;
struct ScrArea;
struct Editing;
struct ListBase;
#define DEFAULT_IMG_STRIP_LENGTH 25 /* XXX arbitrary but ok for now. */
#define OVERLAP_ALPHA 180
struct SeqChannelDrawContext {
const bContext *C;
ScrArea *area;
ARegion *region;
ARegion *timeline_region;
View2D *v2d;
View2D *timeline_region_v2d;
Scene *scene;
Editing *ed;
ListBase *seqbase; /* Displayed seqbase. */
ListBase *channels; /* Displayed channels. */
float draw_offset;
float channel_height;
float frame_width;
float scale;
};
/* `sequencer_timeline_draw.cc` */
void draw_timeline_seq(const bContext *C, ARegion *region);
void draw_timeline_seq_display(const bContext *C, ARegion *region);
void color3ubv_from_seq(const Scene *curscene,
const Sequence *seq,
bool show_strip_color_tag,
uchar r_col[3]);
/* `sequencer_preview_draw.cc` */
void sequencer_draw_preview(const bContext *C,
Scene *scene,
ARegion *region,
SpaceSeq *sseq,
int timeline_frame,
int offset,
bool draw_overlay,
bool draw_backdrop);
bool sequencer_draw_get_transform_preview(SpaceSeq *sseq, Scene *scene);
int sequencer_draw_get_transform_preview_frame(Scene *scene);
void sequencer_special_update_set(Sequence *seq);
/* Get handle width in 2d-View space. */
float sequence_handle_size_get_clamped(const Scene *scene, Sequence *seq, float pixelx);
/* UNUSED */
/* void seq_reset_imageofs(SpaceSeq *sseq); */
/**
* Rendering using opengl will change the current viewport/context.
* This is why we need the \a region, to set back the render area.
*
* TODO: do not rely on such hack and just update the \a ibuf outside of
* the UI drawing code.
*/
ImBuf *sequencer_ibuf_get(Main *bmain,
ARegion *region,
Depsgraph *depsgraph,
Scene *scene,
SpaceSeq *sseq,
int timeline_frame,
int frame_ofs,
const char *viewname);
/* `sequencer_thumbnails.cc` */
void last_displayed_thumbnails_list_free(void *val);
void draw_seq_strip_thumbnail(View2D *v2d,
const bContext *C,
Scene *scene,
Sequence *seq,
float y1,
float y2,
float pixelx,
float pixely);
/* sequencer_draw_channels.c */
void draw_channels(const bContext *C, ARegion *region);
void channel_draw_context_init(const bContext *C,
ARegion *region,
SeqChannelDrawContext *r_context);
/* `sequencer_edit.cc` */
void seq_rectf(const Scene *scene, Sequence *seq, rctf *rectf);
Sequence *find_nearest_seq(Scene *scene, View2D *v2d, int *hand, const int mval[2]);
Sequence *find_neighboring_sequence(Scene *scene, Sequence *test, int lr, int sel);
void recurs_sel_seq(Sequence *seq_meta);
int seq_effect_find_selected(Scene *scene,
Sequence *activeseq,
int type,
Sequence **r_selseq1,
Sequence **r_selseq2,
Sequence **r_selseq3,
const char **r_error_str);
/* Operator helpers. */
bool sequencer_edit_poll(bContext *C);
bool sequencer_edit_with_channel_region_poll(bContext *C);
bool sequencer_editing_initialized_and_active(bContext *C);
/* UNUSED */
/* bool sequencer_strip_poll( bContext *C); */
bool sequencer_strip_has_path_poll(bContext *C);
bool sequencer_view_has_preview_poll(bContext *C);
bool sequencer_view_preview_only_poll(const bContext *C);
bool sequencer_view_strips_poll(bContext *C);
/**
* Returns collection with all strips presented to user. If operation is done in preview,
* collection is limited to all presented strips that can produce image output.
*
* \param C: context
* \return collection of strips (`Sequence`)
*/
SeqCollection *all_strips_from_context(bContext *C);
/**
* Returns collection with selected strips presented to user. If operation is done in preview,
* collection is limited to selected presented strips, that can produce image output at current
* frame.
*
* \param C: context
* \return collection of strips (`Sequence`)
*/
SeqCollection *selected_strips_from_context(bContext *C);
/* Externs. */
extern EnumPropertyItem sequencer_prop_effect_types[];
extern EnumPropertyItem prop_side_types[];
/* Operators. */
void SEQUENCER_OT_split(wmOperatorType *ot);
void SEQUENCER_OT_slip(wmOperatorType *ot);
void SEQUENCER_OT_mute(wmOperatorType *ot);
void SEQUENCER_OT_unmute(wmOperatorType *ot);
void SEQUENCER_OT_lock(wmOperatorType *ot);
void SEQUENCER_OT_unlock(wmOperatorType *ot);
void SEQUENCER_OT_reload(wmOperatorType *ot);
void SEQUENCER_OT_refresh_all(wmOperatorType *ot);
void SEQUENCER_OT_reassign_inputs(wmOperatorType *ot);
void SEQUENCER_OT_swap_inputs(wmOperatorType *ot);
void SEQUENCER_OT_duplicate(wmOperatorType *ot);
void SEQUENCER_OT_delete(wmOperatorType *ot);
void SEQUENCER_OT_offset_clear(wmOperatorType *ot);
void SEQUENCER_OT_images_separate(wmOperatorType *ot);
void SEQUENCER_OT_meta_toggle(wmOperatorType *ot);
void SEQUENCER_OT_meta_make(wmOperatorType *ot);
void SEQUENCER_OT_meta_separate(wmOperatorType *ot);
void SEQUENCER_OT_gap_remove(wmOperatorType *ot);
void SEQUENCER_OT_gap_insert(wmOperatorType *ot);
void SEQUENCER_OT_snap(wmOperatorType *ot);
void SEQUENCER_OT_strip_jump(wmOperatorType *ot);
void SEQUENCER_OT_swap(wmOperatorType *ot);
void SEQUENCER_OT_swap_data(wmOperatorType *ot);
void SEQUENCER_OT_rendersize(wmOperatorType *ot);
void SEQUENCER_OT_change_effect_input(wmOperatorType *ot);
void SEQUENCER_OT_change_effect_type(wmOperatorType *ot);
void SEQUENCER_OT_change_path(wmOperatorType *ot);
void SEQUENCER_OT_change_scene(wmOperatorType *ot);
void SEQUENCER_OT_copy(wmOperatorType *ot);
void SEQUENCER_OT_paste(wmOperatorType *ot);
void SEQUENCER_OT_rebuild_proxy(wmOperatorType *ot);
void SEQUENCER_OT_enable_proxies(wmOperatorType *ot);
void SEQUENCER_OT_export_subtitles(wmOperatorType *ot);
void SEQUENCER_OT_set_range_to_strips(wmOperatorType *ot);
void SEQUENCER_OT_strip_transform_clear(wmOperatorType *ot);
void SEQUENCER_OT_strip_transform_fit(wmOperatorType *ot);
void SEQUENCER_OT_strip_color_tag_set(wmOperatorType *ot);
void SEQUENCER_OT_cursor_set(wmOperatorType *ot);
void SEQUENCER_OT_scene_frame_range_update(wmOperatorType *ot);
/* `sequencer_select.cc` */
void SEQUENCER_OT_select_all(wmOperatorType *ot);
void SEQUENCER_OT_select(wmOperatorType *ot);
void SEQUENCER_OT_select_side_of_frame(wmOperatorType *ot);
void SEQUENCER_OT_select_more(wmOperatorType *ot);
void SEQUENCER_OT_select_less(wmOperatorType *ot);
void SEQUENCER_OT_select_linked(wmOperatorType *ot);
void SEQUENCER_OT_select_linked_pick(wmOperatorType *ot);
void SEQUENCER_OT_select_handles(wmOperatorType *ot);
void SEQUENCER_OT_select_side(wmOperatorType *ot);
void SEQUENCER_OT_select_box(wmOperatorType *ot);
void SEQUENCER_OT_select_inverse(wmOperatorType *ot);
void SEQUENCER_OT_select_grouped(wmOperatorType *ot);
/* `sequencer_add.cc` */
void SEQUENCER_OT_scene_strip_add(wmOperatorType *ot);
void SEQUENCER_OT_scene_strip_add_new(wmOperatorType *ot);
void SEQUENCER_OT_movie_strip_add(wmOperatorType *ot);
void SEQUENCER_OT_movieclip_strip_add(wmOperatorType *ot);
void SEQUENCER_OT_mask_strip_add(wmOperatorType *ot);
void SEQUENCER_OT_sound_strip_add(wmOperatorType *ot);
void SEQUENCER_OT_image_strip_add(wmOperatorType *ot);
void SEQUENCER_OT_effect_strip_add(wmOperatorType *ot);
/* `sequencer_drag_drop.cc` */
void sequencer_dropboxes();
/* `sequencer_ops.cc` */
void sequencer_operatortypes();
void sequencer_keymap(wmKeyConfig *keyconf);
/* sequencer_scope.c */
ImBuf *make_waveform_view_from_ibuf(ImBuf *ibuf);
ImBuf *make_sep_waveform_view_from_ibuf(ImBuf *ibuf);
ImBuf *make_vectorscope_view_from_ibuf(ImBuf *ibuf);
ImBuf *make_zebra_view_from_ibuf(ImBuf *ibuf, float perc);
ImBuf *make_histogram_view_from_ibuf(ImBuf *ibuf);
/* `sequencer_buttons.cc` */
void sequencer_buttons_register(ARegionType *art);
/* sequencer_modifiers.c */
void SEQUENCER_OT_strip_modifier_add(wmOperatorType *ot);
void SEQUENCER_OT_strip_modifier_remove(wmOperatorType *ot);
void SEQUENCER_OT_strip_modifier_move(wmOperatorType *ot);
void SEQUENCER_OT_strip_modifier_copy(wmOperatorType *ot);
void SEQUENCER_OT_strip_modifier_equalizer_redefine(wmOperatorType *ot);
/* `sequencer_view.cc` */
void SEQUENCER_OT_sample(wmOperatorType *ot);
void SEQUENCER_OT_view_all(wmOperatorType *ot);
void SEQUENCER_OT_view_frame(wmOperatorType *ot);
void SEQUENCER_OT_view_all_preview(wmOperatorType *ot);
void SEQUENCER_OT_view_zoom_ratio(wmOperatorType *ot);
void SEQUENCER_OT_view_selected(wmOperatorType *ot);
void SEQUENCER_OT_view_ghost_border(wmOperatorType *ot);
/* `sequencer_channels_edit.cc` */
void SEQUENCER_OT_rename_channel(wmOperatorType *ot);
/* `sequencer_preview.cc` */
void sequencer_preview_add_sound(const bContext *C, Sequence *seq);
/* `sequencer_add.cc` */
int sequencer_image_seq_get_minmax_frame(wmOperator *op,
int sfra,
int *r_minframe,
int *r_numdigits);
void sequencer_image_seq_reserve_frames(
wmOperator *op, StripElem *se, int len, int minframe, int numdigits);
/* `sequencer_retiming.cc` */
void SEQUENCER_OT_retiming_reset(wmOperatorType *ot);
void SEQUENCER_OT_retiming_handle_move(wmOperatorType *ot);
void SEQUENCER_OT_retiming_handle_add(wmOperatorType *ot);
void SEQUENCER_OT_retiming_handle_remove(wmOperatorType *ot);
void SEQUENCER_OT_retiming_segment_speed_set(wmOperatorType *ot);
/* `sequencer_gizmo_retime.cc` */
void SEQUENCER_GGT_gizmo_retime(wmGizmoGroupType *gzgt);
/* `sequencer_gizmo_retime_type.cc` */
void GIZMO_GT_retime_handle_add(wmGizmoType *gzt);
void GIZMO_GT_retime_handle(wmGizmoType *gzt);
void GIZMO_GT_retime_remove(wmGizmoType *gzt);
void GIZMO_GT_speed_set_remove(wmGizmoType *gzt);

View File

@ -29,9 +29,11 @@
#include "SEQ_sound.h"
/* Own include. */
#include "sequencer_intern.h"
#include "sequencer_intern.hh"
/*********************** Add modifier operator *************************/
/* -------------------------------------------------------------------- */
/** \name Add modifier operator
* \{ */
static int strip_modifier_add_exec(bContext *C, wmOperator *op)
{
@ -87,7 +89,11 @@ void SEQUENCER_OT_strip_modifier_add(wmOperatorType *ot)
ot->prop = prop;
}
/*********************** Remove modifier operator *************************/
/** \} */
/* -------------------------------------------------------------------- */
/** \name Remove Modifier Operator
* \{ */
static int strip_modifier_remove_exec(bContext *C, wmOperator *op)
{
@ -140,7 +146,11 @@ void SEQUENCER_OT_strip_modifier_remove(wmOperatorType *ot)
RNA_def_property_flag(prop, PROP_HIDDEN);
}
/*********************** Move operator *************************/
/** \} */
/* -------------------------------------------------------------------- */
/** \name Move Operator
* \{ */
enum {
SEQ_MODIFIER_MOVE_UP = 0,
@ -220,7 +230,11 @@ void SEQUENCER_OT_strip_modifier_move(wmOperatorType *ot)
RNA_def_property_flag(prop, PROP_HIDDEN);
}
/*********************** Copy to selected operator *************************/
/** \} */
/* -------------------------------------------------------------------- */
/** \name Copy to Selected Operator
* \{ */
enum {
SEQ_MODIFIER_COPY_REPLACE = 0,
@ -313,6 +327,12 @@ void SEQUENCER_OT_strip_modifier_copy(wmOperatorType *ot)
ot->prop = RNA_def_enum(ot->srna, "type", type_items, SEQ_MODIFIER_COPY_REPLACE, "Type", "");
}
/** \} */
/* -------------------------------------------------------------------- */
/** \name Redefine Equalizer Graphs Operator
* \{ */
static int strip_modifier_equalizer_redefine_exec(bContext *C, wmOperator *op)
{
Scene *scene = CTX_data_scene(C);
@ -369,3 +389,5 @@ void SEQUENCER_OT_strip_modifier_equalizer_redefine(wmOperatorType *ot)
ot->srna, "name", "Name", MAX_NAME, "Name", "Name of modifier to redefine");
RNA_def_property_flag(prop, PROP_HIDDEN);
}
/** \} */

View File

@ -16,7 +16,7 @@
#include "ED_sequencer.hh"
#include "sequencer_intern.h"
#include "sequencer_intern.hh"
/* ************************** registration **********************************/

View File

@ -24,7 +24,7 @@
#include "MEM_guardedalloc.h"
#include "sequencer_intern.h"
#include "sequencer_intern.hh"
struct PreviewJob {
ListBase previews;

View File

@ -0,0 +1,829 @@
/* SPDX-FileCopyrightText: 2001-2002 NaN Holding BV. All rights reserved.
*
* SPDX-License-Identifier: GPL-2.0-or-later */
/** \file
* \ingroup spseq
*/
#include <cmath>
#include <cstring>
#include "BLI_blenlib.h"
#include "BLI_utildefines.h"
#include "IMB_imbuf_types.h"
#include "DNA_scene_types.h"
#include "DNA_screen_types.h"
#include "DNA_space_types.h"
#include "BKE_context.h"
#include "BKE_global.h"
#include "BKE_scene.h"
#include "IMB_colormanagement.h"
#include "IMB_imbuf.h"
#include "GPU_framebuffer.h"
#include "GPU_immediate.h"
#include "GPU_immediate_util.h"
#include "GPU_matrix.h"
#include "GPU_viewport.h"
#include "ED_gpencil_legacy.hh"
#include "ED_screen.hh"
#include "ED_sequencer.hh"
#include "ED_space_api.hh"
#include "ED_util.hh"
#include "BIF_glutil.hh"
#include "SEQ_channels.h"
#include "SEQ_iterator.h"
#include "SEQ_prefetch.h"
#include "SEQ_proxy.h"
#include "SEQ_render.h"
#include "SEQ_select.h"
#include "SEQ_sequencer.h"
#include "SEQ_time.h"
#include "SEQ_transform.h"
#include "UI_interface.hh"
#include "UI_resources.hh"
#include "UI_view2d.hh"
#include "WM_api.hh"
#include "WM_types.hh"
/* Own include. */
#include "sequencer_intern.hh"
static Sequence *special_seq_update = nullptr;
void sequencer_special_update_set(Sequence *seq)
{
special_seq_update = seq;
}
Sequence *ED_sequencer_special_preview_get()
{
return special_seq_update;
}
void ED_sequencer_special_preview_set(bContext *C, const int mval[2])
{
Scene *scene = CTX_data_scene(C);
ARegion *region = CTX_wm_region(C);
int hand;
Sequence *seq;
seq = find_nearest_seq(scene, &region->v2d, &hand, mval);
sequencer_special_update_set(seq);
}
void ED_sequencer_special_preview_clear()
{
sequencer_special_update_set(nullptr);
}
ImBuf *sequencer_ibuf_get(Main *bmain,
ARegion *region,
Depsgraph *depsgraph,
Scene *scene,
SpaceSeq *sseq,
int timeline_frame,
int frame_ofs,
const char *viewname)
{
SeqRenderData context = {nullptr};
ImBuf *ibuf;
int rectx, recty;
double render_size;
short is_break = G.is_break;
if (sseq->render_size == SEQ_RENDER_SIZE_NONE) {
return nullptr;
}
if (sseq->render_size == SEQ_RENDER_SIZE_SCENE) {
render_size = scene->r.size / 100.0;
}
else {
render_size = SEQ_rendersize_to_scale_factor(sseq->render_size);
}
rectx = roundf(render_size * scene->r.xsch);
recty = roundf(render_size * scene->r.ysch);
SEQ_render_new_render_data(
bmain, depsgraph, scene, rectx, recty, sseq->render_size, false, &context);
context.view_id = BKE_scene_multiview_view_id_get(&scene->r, viewname);
context.use_proxies = (sseq->flag & SEQ_USE_PROXIES) != 0;
/* Sequencer could start rendering, in this case we need to be sure it wouldn't be canceled
* by Escape pressed somewhere in the past. */
G.is_break = false;
GPUViewport *viewport = WM_draw_region_get_bound_viewport(region);
GPUFrameBuffer *fb = GPU_framebuffer_active_get();
if (viewport) {
/* Unbind viewport to release the DRW context. */
GPU_viewport_unbind(viewport);
}
else {
/* Rendering can change OGL context. Save & Restore frame-buffer. */
GPU_framebuffer_restore();
}
if (special_seq_update) {
ibuf = SEQ_render_give_ibuf_direct(&context, timeline_frame + frame_ofs, special_seq_update);
}
else {
ibuf = SEQ_render_give_ibuf(&context, timeline_frame + frame_ofs, sseq->chanshown);
}
if (viewport) {
/* Follows same logic as wm_draw_window_offscreen to make sure to restore the same
* viewport. */
int view = (sseq->multiview_eye == STEREO_RIGHT_ID) ? 1 : 0;
GPU_viewport_bind(viewport, view, &region->winrct);
}
else if (fb) {
GPU_framebuffer_bind(fb);
}
/* Restore state so real rendering would be canceled if needed. */
G.is_break = is_break;
return ibuf;
}
static void sequencer_check_scopes(SequencerScopes *scopes, ImBuf *ibuf)
{
if (scopes->reference_ibuf != ibuf) {
if (scopes->zebra_ibuf) {
IMB_freeImBuf(scopes->zebra_ibuf);
scopes->zebra_ibuf = nullptr;
}
if (scopes->waveform_ibuf) {
IMB_freeImBuf(scopes->waveform_ibuf);
scopes->waveform_ibuf = nullptr;
}
if (scopes->sep_waveform_ibuf) {
IMB_freeImBuf(scopes->sep_waveform_ibuf);
scopes->sep_waveform_ibuf = nullptr;
}
if (scopes->vector_ibuf) {
IMB_freeImBuf(scopes->vector_ibuf);
scopes->vector_ibuf = nullptr;
}
if (scopes->histogram_ibuf) {
IMB_freeImBuf(scopes->histogram_ibuf);
scopes->histogram_ibuf = nullptr;
}
}
}
static ImBuf *sequencer_make_scope(Scene *scene, ImBuf *ibuf, ImBuf *(*make_scope_fn)(ImBuf *ibuf))
{
ImBuf *display_ibuf = IMB_dupImBuf(ibuf);
ImBuf *scope;
IMB_colormanagement_imbuf_make_display_space(
display_ibuf, &scene->view_settings, &scene->display_settings);
scope = make_scope_fn(display_ibuf);
IMB_freeImBuf(display_ibuf);
return scope;
}
static void sequencer_display_size(Scene *scene, float r_viewrect[2])
{
r_viewrect[0] = float(scene->r.xsch);
r_viewrect[1] = float(scene->r.ysch);
r_viewrect[0] *= scene->r.xasp / scene->r.yasp;
}
static void sequencer_draw_gpencil_overlay(const bContext *C)
{
/* Draw grease-pencil (image aligned). */
ED_annotation_draw_2dimage(C);
/* Orthographic at pixel level. */
UI_view2d_view_restore(C);
/* Draw grease-pencil (screen aligned). */
ED_annotation_draw_view2d(C, false);
}
/**
* Draw content and safety borders.
*/
static void sequencer_draw_borders_overlay(const SpaceSeq *sseq,
const View2D *v2d,
const Scene *scene)
{
float x1 = v2d->tot.xmin;
float y1 = v2d->tot.ymin;
float x2 = v2d->tot.xmax;
float y2 = v2d->tot.ymax;
GPU_line_width(1.0f);
/* Draw border. */
const uint shdr_pos = GPU_vertformat_attr_add(
immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_3D_LINE_DASHED_UNIFORM_COLOR);
float viewport_size[4];
GPU_viewport_size_get_f(viewport_size);
immUniform2f("viewport_size", viewport_size[2] / UI_SCALE_FAC, viewport_size[3] / UI_SCALE_FAC);
immUniformThemeColor(TH_BACK);
immUniform1i("colors_len", 0); /* Simple dashes. */
immUniform1f("dash_width", 6.0f);
immUniform1f("udash_factor", 0.5f);
imm_draw_box_wire_2d(shdr_pos, x1 - 0.5f, y1 - 0.5f, x2 + 0.5f, y2 + 0.5f);
/* Draw safety border. */
if (sseq->preview_overlay.flag & SEQ_PREVIEW_SHOW_SAFE_MARGINS) {
immUniformThemeColorBlend(TH_VIEW_OVERLAY, TH_BACK, 0.25f);
rctf rect;
rect.xmin = x1;
rect.xmax = x2;
rect.ymin = y1;
rect.ymax = y2;
UI_draw_safe_areas(shdr_pos, &rect, scene->safe_areas.title, scene->safe_areas.action);
if (sseq->preview_overlay.flag & SEQ_PREVIEW_SHOW_SAFE_CENTER) {
UI_draw_safe_areas(
shdr_pos, &rect, scene->safe_areas.title_center, scene->safe_areas.action_center);
}
}
immUnbindProgram();
}
#if 0
void sequencer_draw_maskedit(const bContext *C, Scene *scene, ARegion *region, SpaceSeq *sseq)
{
/* NOTE: sequencer mask editing isn't finished, the draw code is working but editing not.
* For now just disable drawing since the strip frame will likely be offset. */
// if (sc->mode == SC_MODE_MASKEDIT)
if (0 && sseq->mainb == SEQ_DRAW_IMG_IMBUF) {
Mask *mask = SEQ_active_mask_get(scene);
if (mask) {
int width, height;
float aspx = 1.0f, aspy = 1.0f;
// ED_mask_get_size(C, &width, &height);
// Scene *scene = CTX_data_scene(C);
BKE_render_resolution(&scene->r, false, &width, &height);
ED_mask_draw_region(mask,
region,
0,
0,
0, /* TODO */
width,
height,
aspx,
aspy,
false,
true,
nullptr,
C);
}
}
}
#endif
/* Force redraw, when prefetching and using cache view. */
static void seq_prefetch_wm_notify(const bContext *C, Scene *scene)
{
if (SEQ_prefetch_need_redraw(CTX_data_main(C), scene)) {
WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, nullptr);
}
}
static void *sequencer_OCIO_transform_ibuf(const bContext *C,
ImBuf *ibuf,
bool *r_glsl_used,
eGPUTextureFormat *r_format,
eGPUDataFormat *r_data,
void **r_buffer_cache_handle)
{
void *display_buffer;
bool force_fallback = false;
*r_glsl_used = false;
force_fallback |= (ED_draw_imbuf_method(ibuf) != IMAGE_DRAW_METHOD_GLSL);
force_fallback |= (ibuf->dither != 0.0f);
/* Default */
*r_format = GPU_RGBA8;
*r_data = GPU_DATA_UBYTE;
/* Fallback to CPU based color space conversion. */
if (force_fallback) {
*r_glsl_used = false;
display_buffer = nullptr;
}
else if (ibuf->float_buffer.data) {
display_buffer = ibuf->float_buffer.data;
*r_data = GPU_DATA_FLOAT;
if (ibuf->channels == 4) {
*r_format = GPU_RGBA16F;
}
else if (ibuf->channels == 3) {
/* Alpha is implicitly 1. */
*r_format = GPU_RGB16F;
}
else {
BLI_assert_msg(0, "Incompatible number of channels for float buffer in sequencer");
*r_format = GPU_RGBA16F;
display_buffer = nullptr;
}
if (ibuf->float_buffer.colorspace) {
*r_glsl_used = IMB_colormanagement_setup_glsl_draw_from_space_ctx(
C, ibuf->float_buffer.colorspace, ibuf->dither, true);
}
else {
*r_glsl_used = IMB_colormanagement_setup_glsl_draw_ctx(C, ibuf->dither, true);
}
}
else if (ibuf->byte_buffer.data) {
display_buffer = ibuf->byte_buffer.data;
*r_glsl_used = IMB_colormanagement_setup_glsl_draw_from_space_ctx(
C, ibuf->byte_buffer.colorspace, ibuf->dither, false);
}
else {
display_buffer = nullptr;
}
/* There is data to be displayed, but GLSL is not initialized
* properly, in this case we fallback to CPU-based display transform. */
if ((ibuf->byte_buffer.data || ibuf->float_buffer.data) && !*r_glsl_used) {
display_buffer = IMB_display_buffer_acquire_ctx(C, ibuf, r_buffer_cache_handle);
*r_format = GPU_RGBA8;
*r_data = GPU_DATA_UBYTE;
}
return display_buffer;
}
static void sequencer_stop_running_jobs(const bContext *C, Scene *scene)
{
if (G.is_rendering == false && (scene->r.seq_prev_type) == OB_RENDER) {
/* Stop all running jobs, except screen one. Currently previews frustrate Render.
* Need to make so sequencers rendering doesn't conflict with compositor. */
WM_jobs_kill_type(CTX_wm_manager(C), nullptr, WM_JOB_TYPE_COMPOSITE);
/* In case of final rendering used for preview, kill all previews,
* otherwise threading conflict will happen in rendering module. */
WM_jobs_kill_type(CTX_wm_manager(C), nullptr, WM_JOB_TYPE_RENDER_PREVIEW);
}
}
static void sequencer_preview_clear()
{
UI_ThemeClearColor(TH_SEQ_PREVIEW);
}
static void sequencer_preview_get_rect(rctf *preview,
Scene *scene,
ARegion *region,
SpaceSeq *sseq,
bool draw_overlay,
bool draw_backdrop)
{
View2D *v2d = &region->v2d;
float viewrect[2];
sequencer_display_size(scene, viewrect);
BLI_rctf_init(preview, -1.0f, 1.0f, -1.0f, 1.0f);
if (draw_overlay && (sseq->overlay_frame_type == SEQ_OVERLAY_FRAME_TYPE_RECT)) {
preview->xmax = v2d->tot.xmin +
(fabsf(BLI_rctf_size_x(&v2d->tot)) * scene->ed->overlay_frame_rect.xmax);
preview->xmin = v2d->tot.xmin +
(fabsf(BLI_rctf_size_x(&v2d->tot)) * scene->ed->overlay_frame_rect.xmin);
preview->ymax = v2d->tot.ymin +
(fabsf(BLI_rctf_size_y(&v2d->tot)) * scene->ed->overlay_frame_rect.ymax);
preview->ymin = v2d->tot.ymin +
(fabsf(BLI_rctf_size_y(&v2d->tot)) * scene->ed->overlay_frame_rect.ymin);
}
else if (draw_backdrop) {
float aspect = BLI_rcti_size_x(&region->winrct) / float(BLI_rcti_size_y(&region->winrct));
float image_aspect = viewrect[0] / viewrect[1];
if (aspect >= image_aspect) {
preview->xmax = image_aspect / aspect;
preview->xmin = -preview->xmax;
}
else {
preview->ymax = aspect / image_aspect;
preview->ymin = -preview->ymax;
}
}
else {
*preview = v2d->tot;
}
}
static void sequencer_draw_display_buffer(const bContext *C,
Scene *scene,
ARegion *region,
SpaceSeq *sseq,
ImBuf *ibuf,
ImBuf *scope,
bool draw_overlay,
bool draw_backdrop)
{
void *display_buffer;
void *buffer_cache_handle = nullptr;
if (sseq->mainb == SEQ_DRAW_IMG_IMBUF && sseq->flag & SEQ_USE_ALPHA) {
GPU_blend(GPU_BLEND_ALPHA);
}
/* Format needs to be created prior to any #immBindShader call.
* Do it here because OCIO binds its own shader. */
eGPUTextureFormat format;
eGPUDataFormat data;
bool glsl_used = false;
GPUVertFormat *imm_format = immVertexFormat();
uint pos = GPU_vertformat_attr_add(imm_format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
uint texCoord = GPU_vertformat_attr_add(
imm_format, "texCoord", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
if (scope) {
ibuf = scope;
if (ibuf->float_buffer.data && ibuf->byte_buffer.data == nullptr) {
IMB_rect_from_float(ibuf);
}
display_buffer = ibuf->byte_buffer.data;
format = GPU_RGBA8;
data = GPU_DATA_UBYTE;
}
else {
display_buffer = sequencer_OCIO_transform_ibuf(
C, ibuf, &glsl_used, &format, &data, &buffer_cache_handle);
}
if (draw_backdrop) {
GPU_matrix_push();
GPU_matrix_identity_set();
GPU_matrix_push_projection();
GPU_matrix_identity_projection_set();
}
eGPUTextureUsage usage = GPU_TEXTURE_USAGE_SHADER_READ | GPU_TEXTURE_USAGE_ATTACHMENT;
GPUTexture *texture = GPU_texture_create_2d(
"seq_display_buf", ibuf->x, ibuf->y, 1, format, usage, nullptr);
GPU_texture_update(texture, data, display_buffer);
GPU_texture_filter_mode(texture, false);
GPU_texture_bind(texture, 0);
if (!glsl_used) {
immBindBuiltinProgram(GPU_SHADER_3D_IMAGE_COLOR);
immUniformColor3f(1.0f, 1.0f, 1.0f);
}
immBegin(GPU_PRIM_TRI_FAN, 4);
rctf preview;
rctf canvas;
sequencer_preview_get_rect(&preview, scene, region, sseq, draw_overlay, draw_backdrop);
if (draw_overlay && (sseq->overlay_frame_type == SEQ_OVERLAY_FRAME_TYPE_RECT)) {
canvas = scene->ed->overlay_frame_rect;
}
else {
BLI_rctf_init(&canvas, 0.0f, 1.0f, 0.0f, 1.0f);
}
immAttr2f(texCoord, canvas.xmin, canvas.ymin);
immVertex2f(pos, preview.xmin, preview.ymin);
immAttr2f(texCoord, canvas.xmin, canvas.ymax);
immVertex2f(pos, preview.xmin, preview.ymax);
immAttr2f(texCoord, canvas.xmax, canvas.ymax);
immVertex2f(pos, preview.xmax, preview.ymax);
immAttr2f(texCoord, canvas.xmax, canvas.ymin);
immVertex2f(pos, preview.xmax, preview.ymin);
immEnd();
GPU_texture_unbind(texture);
GPU_texture_free(texture);
if (!glsl_used) {
immUnbindProgram();
}
else {
IMB_colormanagement_finish_glsl_draw();
}
if (buffer_cache_handle) {
IMB_display_buffer_release(buffer_cache_handle);
}
if (sseq->mainb == SEQ_DRAW_IMG_IMBUF && sseq->flag & SEQ_USE_ALPHA) {
GPU_blend(GPU_BLEND_NONE);
}
if (draw_backdrop) {
GPU_matrix_pop();
GPU_matrix_pop_projection();
}
}
static ImBuf *sequencer_get_scope(Scene *scene, SpaceSeq *sseq, ImBuf *ibuf, bool draw_backdrop)
{
ImBuf *scope = nullptr;
SequencerScopes *scopes = &sseq->scopes;
if (!draw_backdrop && (sseq->mainb != SEQ_DRAW_IMG_IMBUF || sseq->zebra != 0)) {
sequencer_check_scopes(scopes, ibuf);
switch (sseq->mainb) {
case SEQ_DRAW_IMG_IMBUF:
if (!scopes->zebra_ibuf) {
ImBuf *display_ibuf = IMB_dupImBuf(ibuf);
if (display_ibuf->float_buffer.data) {
IMB_colormanagement_imbuf_make_display_space(
display_ibuf, &scene->view_settings, &scene->display_settings);
}
scopes->zebra_ibuf = make_zebra_view_from_ibuf(display_ibuf, sseq->zebra);
IMB_freeImBuf(display_ibuf);
}
scope = scopes->zebra_ibuf;
break;
case SEQ_DRAW_IMG_WAVEFORM:
if ((sseq->flag & SEQ_DRAW_COLOR_SEPARATED) != 0) {
if (!scopes->sep_waveform_ibuf) {
scopes->sep_waveform_ibuf = sequencer_make_scope(
scene, ibuf, make_sep_waveform_view_from_ibuf);
}
scope = scopes->sep_waveform_ibuf;
}
else {
if (!scopes->waveform_ibuf) {
scopes->waveform_ibuf = sequencer_make_scope(
scene, ibuf, make_waveform_view_from_ibuf);
}
scope = scopes->waveform_ibuf;
}
break;
case SEQ_DRAW_IMG_VECTORSCOPE:
if (!scopes->vector_ibuf) {
scopes->vector_ibuf = sequencer_make_scope(scene, ibuf, make_vectorscope_view_from_ibuf);
}
scope = scopes->vector_ibuf;
break;
case SEQ_DRAW_IMG_HISTOGRAM:
if (!scopes->histogram_ibuf) {
scopes->histogram_ibuf = sequencer_make_scope(
scene, ibuf, make_histogram_view_from_ibuf);
}
scope = scopes->histogram_ibuf;
break;
}
/* Future files may have new scopes we don't catch above. */
if (scope) {
scopes->reference_ibuf = ibuf;
}
}
return scope;
}
bool sequencer_draw_get_transform_preview(SpaceSeq *sseq, Scene *scene)
{
Sequence *last_seq = SEQ_select_active_get(scene);
if (last_seq == nullptr) {
return false;
}
return (G.moving & G_TRANSFORM_SEQ) && (last_seq->flag & SELECT) &&
((last_seq->flag & SEQ_LEFTSEL) || (last_seq->flag & SEQ_RIGHTSEL)) &&
(sseq->draw_flag & SEQ_DRAW_TRANSFORM_PREVIEW);
}
int sequencer_draw_get_transform_preview_frame(Scene *scene)
{
Sequence *last_seq = SEQ_select_active_get(scene);
/* #sequencer_draw_get_transform_preview must already have been called. */
BLI_assert(last_seq != nullptr);
int preview_frame;
if (last_seq->flag & SEQ_RIGHTSEL) {
preview_frame = SEQ_time_right_handle_frame_get(scene, last_seq) - 1;
}
else {
preview_frame = SEQ_time_left_handle_frame_get(scene, last_seq);
}
return preview_frame;
}
static void seq_draw_image_origin_and_outline(const bContext *C, Sequence *seq, bool is_active_seq)
{
SpaceSeq *sseq = CTX_wm_space_seq(C);
const ARegion *region = CTX_wm_region(C);
if (region->regiontype == RGN_TYPE_PREVIEW && !sequencer_view_preview_only_poll(C)) {
return;
}
if ((seq->flag & SELECT) == 0) {
return;
}
if (ED_screen_animation_no_scrub(CTX_wm_manager(C))) {
return;
}
if ((sseq->flag & SEQ_SHOW_OVERLAY) == 0 ||
(sseq->preview_overlay.flag & SEQ_PREVIEW_SHOW_OUTLINE_SELECTED) == 0)
{
return;
}
if (ELEM(sseq->mainb, SEQ_DRAW_IMG_WAVEFORM, SEQ_DRAW_IMG_VECTORSCOPE, SEQ_DRAW_IMG_HISTOGRAM)) {
return;
}
float origin[2];
SEQ_image_transform_origin_offset_pixelspace_get(CTX_data_scene(C), seq, origin);
/* Origin. */
GPUVertFormat *format = immVertexFormat();
uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_POINT_UNIFORM_SIZE_UNIFORM_COLOR_OUTLINE_AA);
immUniform1f("outlineWidth", 1.5f);
immUniformColor3f(1.0f, 1.0f, 1.0f);
immUniform4f("outlineColor", 0.0f, 0.0f, 0.0f, 1.0f);
immUniform1f("size", 15.0f * U.pixelsize);
immBegin(GPU_PRIM_POINTS, 1);
immVertex2f(pos, origin[0], origin[1]);
immEnd();
immUnbindProgram();
/* Outline. */
float seq_image_quad[4][2];
SEQ_image_transform_final_quad_get(CTX_data_scene(C), seq, seq_image_quad);
GPU_line_smooth(true);
GPU_blend(GPU_BLEND_ALPHA);
GPU_line_width(2);
immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
float col[3];
if (is_active_seq) {
UI_GetThemeColor3fv(TH_SEQ_ACTIVE, col);
}
else {
UI_GetThemeColor3fv(TH_SEQ_SELECTED, col);
}
immUniformColor3fv(col);
immUniform1f("lineWidth", U.pixelsize);
immBegin(GPU_PRIM_LINE_LOOP, 4);
immVertex2f(pos, seq_image_quad[0][0], seq_image_quad[0][1]);
immVertex2f(pos, seq_image_quad[1][0], seq_image_quad[1][1]);
immVertex2f(pos, seq_image_quad[2][0], seq_image_quad[2][1]);
immVertex2f(pos, seq_image_quad[3][0], seq_image_quad[3][1]);
immEnd();
immUnbindProgram();
GPU_line_width(1);
GPU_blend(GPU_BLEND_NONE);
GPU_line_smooth(false);
}
void sequencer_draw_preview(const bContext *C,
Scene *scene,
ARegion *region,
SpaceSeq *sseq,
int timeline_frame,
int offset,
bool draw_overlay,
bool draw_backdrop)
{
Main *bmain = CTX_data_main(C);
Depsgraph *depsgraph = CTX_data_expect_evaluated_depsgraph(C);
View2D *v2d = &region->v2d;
ImBuf *ibuf = nullptr;
ImBuf *scope = nullptr;
float viewrect[2];
const bool show_imbuf = ED_space_sequencer_check_show_imbuf(sseq);
const bool draw_gpencil = ((sseq->preview_overlay.flag & SEQ_PREVIEW_SHOW_GPENCIL) && sseq->gpd);
const char *names[2] = {STEREO_LEFT_NAME, STEREO_RIGHT_NAME};
sequencer_stop_running_jobs(C, scene);
if (G.is_rendering) {
return;
}
int preview_frame = timeline_frame;
if (sequencer_draw_get_transform_preview(sseq, scene)) {
preview_frame = sequencer_draw_get_transform_preview_frame(scene);
}
/* Get image. */
ibuf = sequencer_ibuf_get(
bmain, region, depsgraph, scene, sseq, preview_frame, offset, names[sseq->multiview_eye]);
/* Setup off-screen buffers. */
GPUViewport *viewport = WM_draw_region_get_viewport(region);
GPUFrameBuffer *framebuffer_overlay = GPU_viewport_framebuffer_overlay_get(viewport);
GPU_framebuffer_bind_no_srgb(framebuffer_overlay);
GPU_depth_test(GPU_DEPTH_NONE);
if (sseq->render_size == SEQ_RENDER_SIZE_NONE) {
sequencer_preview_clear();
return;
}
/* Setup view. */
sequencer_display_size(scene, viewrect);
UI_view2d_totRect_set(v2d, roundf(viewrect[0] + 0.5f), roundf(viewrect[1] + 0.5f));
UI_view2d_curRect_validate(v2d);
UI_view2d_view_ortho(v2d);
/* Draw background. */
if (!draw_backdrop &&
(!draw_overlay || (sseq->overlay_frame_type == SEQ_OVERLAY_FRAME_TYPE_REFERENCE)))
{
sequencer_preview_clear();
if (sseq->flag & SEQ_USE_ALPHA) {
imm_draw_box_checker_2d(v2d->tot.xmin, v2d->tot.ymin, v2d->tot.xmax, v2d->tot.ymax);
}
}
if (ibuf) {
scope = sequencer_get_scope(scene, sseq, ibuf, draw_backdrop);
/* Draw image. */
sequencer_draw_display_buffer(
C, scene, region, sseq, ibuf, scope, draw_overlay, draw_backdrop);
/* Draw over image. */
if (sseq->preview_overlay.flag & SEQ_PREVIEW_SHOW_METADATA && sseq->flag & SEQ_SHOW_OVERLAY) {
ED_region_image_metadata_draw(0.0, 0.0, ibuf, &v2d->tot, 1.0, 1.0);
}
}
if (show_imbuf && (sseq->flag & SEQ_SHOW_OVERLAY)) {
sequencer_draw_borders_overlay(sseq, v2d, scene);
}
if (!draw_backdrop && scene->ed != nullptr) {
Editing *ed = SEQ_editing_get(scene);
ListBase *channels = SEQ_channels_displayed_get(ed);
SeqCollection *collection = SEQ_query_rendered_strips(
scene, channels, ed->seqbasep, timeline_frame, 0);
Sequence *seq;
Sequence *active_seq = SEQ_select_active_get(scene);
SEQ_ITERATOR_FOREACH (seq, collection) {
seq_draw_image_origin_and_outline(C, seq, seq == active_seq);
}
SEQ_collection_free(collection);
}
if (draw_gpencil && show_imbuf && (sseq->flag & SEQ_SHOW_OVERLAY)) {
sequencer_draw_gpencil_overlay(C);
}
#if 0
sequencer_draw_maskedit(C, scene, region, sseq);
#endif
/* Draw registered callbacks. */
GPU_framebuffer_bind(framebuffer_overlay);
ED_region_draw_cb_draw(C, region, REGION_DRAW_POST_VIEW);
GPU_framebuffer_bind_no_srgb(framebuffer_overlay);
/* Scope is freed in sequencer_check_scopes when `ibuf` changes and redraw is needed. */
if (ibuf) {
IMB_freeImBuf(ibuf);
}
UI_view2d_view_restore(C);
seq_prefetch_wm_notify(C, scene);
}

View File

@ -32,7 +32,7 @@
#include "ED_screen.hh"
/* Own include. */
#include "sequencer_intern.h"
#include "sequencer_intern.hh"
/* -------------------------------------------------------------------- */
/** \name Rebuild Proxy and Timecode Indices Operator

View File

@ -35,7 +35,7 @@
#include "DEG_depsgraph.h"
/* Own include. */
#include "sequencer_intern.h"
#include "sequencer_intern.hh"
using blender::MutableSpan;

View File

@ -16,7 +16,7 @@
#include "IMB_imbuf.h"
#include "IMB_imbuf_types.h"
#include "sequencer_intern.h"
#include "sequencer_intern.hh"
/* XXX(@ideasman42): why is this function better than BLI_math version?
* only difference is it does some normalize after, need to double check on this. */

View File

@ -46,7 +46,7 @@
#include "UI_view2d.hh"
/* Own include. */
#include "sequencer_intern.h"
#include "sequencer_intern.hh"
/* -------------------------------------------------------------------- */
/** \name Selection Utilities

View File

@ -31,7 +31,7 @@
#include "MEM_guardedalloc.h"
/* Own include. */
#include "sequencer_intern.h"
#include "sequencer_intern.hh"
struct ThumbnailDrawJob {
SeqRenderData context;

View File

@ -14,11 +14,6 @@
#include "BLI_threads.h"
#include "BLI_utildefines.h"
#include "IMB_imbuf_types.h"
#include "DNA_anim_types.h"
#include "DNA_mask_types.h"
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
#include "DNA_screen_types.h"
#include "DNA_sound_types.h"
@ -34,16 +29,12 @@
#include "IMB_colormanagement.h"
#include "IMB_imbuf.h"
#include "GPU_framebuffer.h"
#include "GPU_immediate.h"
#include "GPU_immediate_util.h"
#include "GPU_matrix.h"
#include "GPU_state.h"
#include "GPU_vertex_buffer.h"
#include "GPU_viewport.h"
#include "ED_anim_api.hh"
#include "ED_gpencil_legacy.hh"
#include "ED_markers.hh"
#include "ED_mask.hh"
#include "ED_screen.hh"
@ -52,15 +43,12 @@
#include "ED_time_scrub_ui.hh"
#include "ED_util.hh"
#include "BIF_glutil.hh"
#include "RNA_prototypes.h"
#include "SEQ_channels.h"
#include "SEQ_effects.h"
#include "SEQ_iterator.h"
#include "SEQ_prefetch.h"
#include "SEQ_proxy.h"
#include "SEQ_relations.h"
#include "SEQ_render.h"
#include "SEQ_select.h"
@ -81,7 +69,7 @@
#include "MEM_guardedalloc.h"
/* Own include. */
#include "sequencer_intern.h"
#include "sequencer_intern.hh"
#define SEQ_LEFTHANDLE 1
#define SEQ_RIGHTHANDLE 2
@ -1540,255 +1528,6 @@ static void draw_effect_inputs_highlight(const Scene *scene, Sequence *seq)
GPU_blend(GPU_BLEND_NONE);
}
void sequencer_special_update_set(Sequence *seq)
{
special_seq_update = seq;
}
Sequence *ED_sequencer_special_preview_get()
{
return special_seq_update;
}
void ED_sequencer_special_preview_set(bContext *C, const int mval[2])
{
Scene *scene = CTX_data_scene(C);
ARegion *region = CTX_wm_region(C);
int hand;
Sequence *seq;
seq = find_nearest_seq(scene, &region->v2d, &hand, mval);
sequencer_special_update_set(seq);
}
void ED_sequencer_special_preview_clear()
{
sequencer_special_update_set(nullptr);
}
ImBuf *sequencer_ibuf_get(Main *bmain,
ARegion *region,
Depsgraph *depsgraph,
Scene *scene,
SpaceSeq *sseq,
int timeline_frame,
int frame_ofs,
const char *viewname)
{
SeqRenderData context = {nullptr};
ImBuf *ibuf;
int rectx, recty;
double render_size;
short is_break = G.is_break;
if (sseq->render_size == SEQ_RENDER_SIZE_NONE) {
return nullptr;
}
if (sseq->render_size == SEQ_RENDER_SIZE_SCENE) {
render_size = scene->r.size / 100.0;
}
else {
render_size = SEQ_rendersize_to_scale_factor(sseq->render_size);
}
rectx = roundf(render_size * scene->r.xsch);
recty = roundf(render_size * scene->r.ysch);
SEQ_render_new_render_data(
bmain, depsgraph, scene, rectx, recty, sseq->render_size, false, &context);
context.view_id = BKE_scene_multiview_view_id_get(&scene->r, viewname);
context.use_proxies = (sseq->flag & SEQ_USE_PROXIES) != 0;
/* Sequencer could start rendering, in this case we need to be sure it wouldn't be canceled
* by Escape pressed somewhere in the past. */
G.is_break = false;
GPUViewport *viewport = WM_draw_region_get_bound_viewport(region);
GPUFrameBuffer *fb = GPU_framebuffer_active_get();
if (viewport) {
/* Unbind viewport to release the DRW context. */
GPU_viewport_unbind(viewport);
}
else {
/* Rendering can change OGL context. Save & Restore frame-buffer. */
GPU_framebuffer_restore();
}
if (special_seq_update) {
ibuf = SEQ_render_give_ibuf_direct(&context, timeline_frame + frame_ofs, special_seq_update);
}
else {
ibuf = SEQ_render_give_ibuf(&context, timeline_frame + frame_ofs, sseq->chanshown);
}
if (viewport) {
/* Follows same logic as wm_draw_window_offscreen to make sure to restore the same
* viewport. */
int view = (sseq->multiview_eye == STEREO_RIGHT_ID) ? 1 : 0;
GPU_viewport_bind(viewport, view, &region->winrct);
}
else if (fb) {
GPU_framebuffer_bind(fb);
}
/* Restore state so real rendering would be canceled if needed. */
G.is_break = is_break;
return ibuf;
}
static void sequencer_check_scopes(SequencerScopes *scopes, ImBuf *ibuf)
{
if (scopes->reference_ibuf != ibuf) {
if (scopes->zebra_ibuf) {
IMB_freeImBuf(scopes->zebra_ibuf);
scopes->zebra_ibuf = nullptr;
}
if (scopes->waveform_ibuf) {
IMB_freeImBuf(scopes->waveform_ibuf);
scopes->waveform_ibuf = nullptr;
}
if (scopes->sep_waveform_ibuf) {
IMB_freeImBuf(scopes->sep_waveform_ibuf);
scopes->sep_waveform_ibuf = nullptr;
}
if (scopes->vector_ibuf) {
IMB_freeImBuf(scopes->vector_ibuf);
scopes->vector_ibuf = nullptr;
}
if (scopes->histogram_ibuf) {
IMB_freeImBuf(scopes->histogram_ibuf);
scopes->histogram_ibuf = nullptr;
}
}
}
static ImBuf *sequencer_make_scope(Scene *scene, ImBuf *ibuf, ImBuf *(*make_scope_fn)(ImBuf *ibuf))
{
ImBuf *display_ibuf = IMB_dupImBuf(ibuf);
ImBuf *scope;
IMB_colormanagement_imbuf_make_display_space(
display_ibuf, &scene->view_settings, &scene->display_settings);
scope = make_scope_fn(display_ibuf);
IMB_freeImBuf(display_ibuf);
return scope;
}
static void sequencer_display_size(Scene *scene, float r_viewrect[2])
{
r_viewrect[0] = float(scene->r.xsch);
r_viewrect[1] = float(scene->r.ysch);
r_viewrect[0] *= scene->r.xasp / scene->r.yasp;
}
static void sequencer_draw_gpencil_overlay(const bContext *C)
{
/* Draw grease-pencil (image aligned). */
ED_annotation_draw_2dimage(C);
/* Orthographic at pixel level. */
UI_view2d_view_restore(C);
/* Draw grease-pencil (screen aligned). */
ED_annotation_draw_view2d(C, false);
}
/**
* Draw content and safety borders.
*/
static void sequencer_draw_borders_overlay(const SpaceSeq *sseq,
const View2D *v2d,
const Scene *scene)
{
float x1 = v2d->tot.xmin;
float y1 = v2d->tot.ymin;
float x2 = v2d->tot.xmax;
float y2 = v2d->tot.ymax;
GPU_line_width(1.0f);
/* Draw border. */
const uint shdr_pos = GPU_vertformat_attr_add(
immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_3D_LINE_DASHED_UNIFORM_COLOR);
float viewport_size[4];
GPU_viewport_size_get_f(viewport_size);
immUniform2f("viewport_size", viewport_size[2] / UI_SCALE_FAC, viewport_size[3] / UI_SCALE_FAC);
immUniformThemeColor(TH_BACK);
immUniform1i("colors_len", 0); /* Simple dashes. */
immUniform1f("dash_width", 6.0f);
immUniform1f("udash_factor", 0.5f);
imm_draw_box_wire_2d(shdr_pos, x1 - 0.5f, y1 - 0.5f, x2 + 0.5f, y2 + 0.5f);
/* Draw safety border. */
if (sseq->preview_overlay.flag & SEQ_PREVIEW_SHOW_SAFE_MARGINS) {
immUniformThemeColorBlend(TH_VIEW_OVERLAY, TH_BACK, 0.25f);
rctf rect;
rect.xmin = x1;
rect.xmax = x2;
rect.ymin = y1;
rect.ymax = y2;
UI_draw_safe_areas(shdr_pos, &rect, scene->safe_areas.title, scene->safe_areas.action);
if (sseq->preview_overlay.flag & SEQ_PREVIEW_SHOW_SAFE_CENTER) {
UI_draw_safe_areas(
shdr_pos, &rect, scene->safe_areas.title_center, scene->safe_areas.action_center);
}
}
immUnbindProgram();
}
#if 0
void sequencer_draw_maskedit(const bContext *C, Scene *scene, ARegion *region, SpaceSeq *sseq)
{
/* NOTE: sequencer mask editing isn't finished, the draw code is working but editing not.
* For now just disable drawing since the strip frame will likely be offset. */
// if (sc->mode == SC_MODE_MASKEDIT)
if (0 && sseq->mainb == SEQ_DRAW_IMG_IMBUF) {
Mask *mask = SEQ_active_mask_get(scene);
if (mask) {
int width, height;
float aspx = 1.0f, aspy = 1.0f;
// ED_mask_get_size(C, &width, &height);
// Scene *scene = CTX_data_scene(C);
BKE_render_resolution(&scene->r, false, &width, &height);
ED_mask_draw_region(mask,
region,
0,
0,
0, /* TODO */
width,
height,
aspx,
aspy,
false,
true,
nullptr,
C);
}
}
}
#endif
/* Force redraw, when prefetching and using cache view. */
static void seq_prefetch_wm_notify(const bContext *C, Scene *scene)
{
@ -1797,516 +1536,6 @@ static void seq_prefetch_wm_notify(const bContext *C, Scene *scene)
}
}
static void *sequencer_OCIO_transform_ibuf(const bContext *C,
ImBuf *ibuf,
bool *r_glsl_used,
eGPUTextureFormat *r_format,
eGPUDataFormat *r_data,
void **r_buffer_cache_handle)
{
void *display_buffer;
bool force_fallback = false;
*r_glsl_used = false;
force_fallback |= (ED_draw_imbuf_method(ibuf) != IMAGE_DRAW_METHOD_GLSL);
force_fallback |= (ibuf->dither != 0.0f);
/* Default */
*r_format = GPU_RGBA8;
*r_data = GPU_DATA_UBYTE;
/* Fallback to CPU based color space conversion. */
if (force_fallback) {
*r_glsl_used = false;
display_buffer = nullptr;
}
else if (ibuf->float_buffer.data) {
display_buffer = ibuf->float_buffer.data;
*r_data = GPU_DATA_FLOAT;
if (ibuf->channels == 4) {
*r_format = GPU_RGBA16F;
}
else if (ibuf->channels == 3) {
/* Alpha is implicitly 1. */
*r_format = GPU_RGB16F;
}
else {
BLI_assert_msg(0, "Incompatible number of channels for float buffer in sequencer");
*r_format = GPU_RGBA16F;
display_buffer = nullptr;
}
if (ibuf->float_buffer.colorspace) {
*r_glsl_used = IMB_colormanagement_setup_glsl_draw_from_space_ctx(
C, ibuf->float_buffer.colorspace, ibuf->dither, true);
}
else {
*r_glsl_used = IMB_colormanagement_setup_glsl_draw_ctx(C, ibuf->dither, true);
}
}
else if (ibuf->byte_buffer.data) {
display_buffer = ibuf->byte_buffer.data;
*r_glsl_used = IMB_colormanagement_setup_glsl_draw_from_space_ctx(
C, ibuf->byte_buffer.colorspace, ibuf->dither, false);
}
else {
display_buffer = nullptr;
}
/* There is data to be displayed, but GLSL is not initialized
* properly, in this case we fallback to CPU-based display transform. */
if ((ibuf->byte_buffer.data || ibuf->float_buffer.data) && !*r_glsl_used) {
display_buffer = IMB_display_buffer_acquire_ctx(C, ibuf, r_buffer_cache_handle);
*r_format = GPU_RGBA8;
*r_data = GPU_DATA_UBYTE;
}
return display_buffer;
}
static void sequencer_stop_running_jobs(const bContext *C, Scene *scene)
{
if (G.is_rendering == false && (scene->r.seq_prev_type) == OB_RENDER) {
/* Stop all running jobs, except screen one. Currently previews frustrate Render.
* Need to make so sequencers rendering doesn't conflict with compositor. */
WM_jobs_kill_type(CTX_wm_manager(C), nullptr, WM_JOB_TYPE_COMPOSITE);
/* In case of final rendering used for preview, kill all previews,
* otherwise threading conflict will happen in rendering module. */
WM_jobs_kill_type(CTX_wm_manager(C), nullptr, WM_JOB_TYPE_RENDER_PREVIEW);
}
}
static void sequencer_preview_clear()
{
UI_ThemeClearColor(TH_SEQ_PREVIEW);
}
static void sequencer_preview_get_rect(rctf *preview,
Scene *scene,
ARegion *region,
SpaceSeq *sseq,
bool draw_overlay,
bool draw_backdrop)
{
View2D *v2d = &region->v2d;
float viewrect[2];
sequencer_display_size(scene, viewrect);
BLI_rctf_init(preview, -1.0f, 1.0f, -1.0f, 1.0f);
if (draw_overlay && (sseq->overlay_frame_type == SEQ_OVERLAY_FRAME_TYPE_RECT)) {
preview->xmax = v2d->tot.xmin +
(fabsf(BLI_rctf_size_x(&v2d->tot)) * scene->ed->overlay_frame_rect.xmax);
preview->xmin = v2d->tot.xmin +
(fabsf(BLI_rctf_size_x(&v2d->tot)) * scene->ed->overlay_frame_rect.xmin);
preview->ymax = v2d->tot.ymin +
(fabsf(BLI_rctf_size_y(&v2d->tot)) * scene->ed->overlay_frame_rect.ymax);
preview->ymin = v2d->tot.ymin +
(fabsf(BLI_rctf_size_y(&v2d->tot)) * scene->ed->overlay_frame_rect.ymin);
}
else if (draw_backdrop) {
float aspect = BLI_rcti_size_x(&region->winrct) / float(BLI_rcti_size_y(&region->winrct));
float image_aspect = viewrect[0] / viewrect[1];
if (aspect >= image_aspect) {
preview->xmax = image_aspect / aspect;
preview->xmin = -preview->xmax;
}
else {
preview->ymax = aspect / image_aspect;
preview->ymin = -preview->ymax;
}
}
else {
*preview = v2d->tot;
}
}
static void sequencer_draw_display_buffer(const bContext *C,
Scene *scene,
ARegion *region,
SpaceSeq *sseq,
ImBuf *ibuf,
ImBuf *scope,
bool draw_overlay,
bool draw_backdrop)
{
void *display_buffer;
void *buffer_cache_handle = nullptr;
if (sseq->mainb == SEQ_DRAW_IMG_IMBUF && sseq->flag & SEQ_USE_ALPHA) {
GPU_blend(GPU_BLEND_ALPHA);
}
/* Format needs to be created prior to any #immBindShader call.
* Do it here because OCIO binds its own shader. */
eGPUTextureFormat format;
eGPUDataFormat data;
bool glsl_used = false;
GPUVertFormat *imm_format = immVertexFormat();
uint pos = GPU_vertformat_attr_add(imm_format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
uint texCoord = GPU_vertformat_attr_add(
imm_format, "texCoord", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
if (scope) {
ibuf = scope;
if (ibuf->float_buffer.data && ibuf->byte_buffer.data == nullptr) {
IMB_rect_from_float(ibuf);
}
display_buffer = ibuf->byte_buffer.data;
format = GPU_RGBA8;
data = GPU_DATA_UBYTE;
}
else {
display_buffer = sequencer_OCIO_transform_ibuf(
C, ibuf, &glsl_used, &format, &data, &buffer_cache_handle);
}
if (draw_backdrop) {
GPU_matrix_push();
GPU_matrix_identity_set();
GPU_matrix_push_projection();
GPU_matrix_identity_projection_set();
}
eGPUTextureUsage usage = GPU_TEXTURE_USAGE_SHADER_READ | GPU_TEXTURE_USAGE_ATTACHMENT;
GPUTexture *texture = GPU_texture_create_2d(
"seq_display_buf", ibuf->x, ibuf->y, 1, format, usage, nullptr);
GPU_texture_update(texture, data, display_buffer);
GPU_texture_filter_mode(texture, false);
GPU_texture_bind(texture, 0);
if (!glsl_used) {
immBindBuiltinProgram(GPU_SHADER_3D_IMAGE_COLOR);
immUniformColor3f(1.0f, 1.0f, 1.0f);
}
immBegin(GPU_PRIM_TRI_FAN, 4);
rctf preview;
rctf canvas;
sequencer_preview_get_rect(&preview, scene, region, sseq, draw_overlay, draw_backdrop);
if (draw_overlay && (sseq->overlay_frame_type == SEQ_OVERLAY_FRAME_TYPE_RECT)) {
canvas = scene->ed->overlay_frame_rect;
}
else {
BLI_rctf_init(&canvas, 0.0f, 1.0f, 0.0f, 1.0f);
}
immAttr2f(texCoord, canvas.xmin, canvas.ymin);
immVertex2f(pos, preview.xmin, preview.ymin);
immAttr2f(texCoord, canvas.xmin, canvas.ymax);
immVertex2f(pos, preview.xmin, preview.ymax);
immAttr2f(texCoord, canvas.xmax, canvas.ymax);
immVertex2f(pos, preview.xmax, preview.ymax);
immAttr2f(texCoord, canvas.xmax, canvas.ymin);
immVertex2f(pos, preview.xmax, preview.ymin);
immEnd();
GPU_texture_unbind(texture);
GPU_texture_free(texture);
if (!glsl_used) {
immUnbindProgram();
}
else {
IMB_colormanagement_finish_glsl_draw();
}
if (buffer_cache_handle) {
IMB_display_buffer_release(buffer_cache_handle);
}
if (sseq->mainb == SEQ_DRAW_IMG_IMBUF && sseq->flag & SEQ_USE_ALPHA) {
GPU_blend(GPU_BLEND_NONE);
}
if (draw_backdrop) {
GPU_matrix_pop();
GPU_matrix_pop_projection();
}
}
static ImBuf *sequencer_get_scope(Scene *scene, SpaceSeq *sseq, ImBuf *ibuf, bool draw_backdrop)
{
ImBuf *scope = nullptr;
SequencerScopes *scopes = &sseq->scopes;
if (!draw_backdrop && (sseq->mainb != SEQ_DRAW_IMG_IMBUF || sseq->zebra != 0)) {
sequencer_check_scopes(scopes, ibuf);
switch (sseq->mainb) {
case SEQ_DRAW_IMG_IMBUF:
if (!scopes->zebra_ibuf) {
ImBuf *display_ibuf = IMB_dupImBuf(ibuf);
if (display_ibuf->float_buffer.data) {
IMB_colormanagement_imbuf_make_display_space(
display_ibuf, &scene->view_settings, &scene->display_settings);
}
scopes->zebra_ibuf = make_zebra_view_from_ibuf(display_ibuf, sseq->zebra);
IMB_freeImBuf(display_ibuf);
}
scope = scopes->zebra_ibuf;
break;
case SEQ_DRAW_IMG_WAVEFORM:
if ((sseq->flag & SEQ_DRAW_COLOR_SEPARATED) != 0) {
if (!scopes->sep_waveform_ibuf) {
scopes->sep_waveform_ibuf = sequencer_make_scope(
scene, ibuf, make_sep_waveform_view_from_ibuf);
}
scope = scopes->sep_waveform_ibuf;
}
else {
if (!scopes->waveform_ibuf) {
scopes->waveform_ibuf = sequencer_make_scope(
scene, ibuf, make_waveform_view_from_ibuf);
}
scope = scopes->waveform_ibuf;
}
break;
case SEQ_DRAW_IMG_VECTORSCOPE:
if (!scopes->vector_ibuf) {
scopes->vector_ibuf = sequencer_make_scope(scene, ibuf, make_vectorscope_view_from_ibuf);
}
scope = scopes->vector_ibuf;
break;
case SEQ_DRAW_IMG_HISTOGRAM:
if (!scopes->histogram_ibuf) {
scopes->histogram_ibuf = sequencer_make_scope(
scene, ibuf, make_histogram_view_from_ibuf);
}
scope = scopes->histogram_ibuf;
break;
}
/* Future files may have new scopes we don't catch above. */
if (scope) {
scopes->reference_ibuf = ibuf;
}
}
return scope;
}
static bool sequencer_draw_get_transform_preview(SpaceSeq *sseq, Scene *scene)
{
Sequence *last_seq = SEQ_select_active_get(scene);
if (last_seq == nullptr) {
return false;
}
return (G.moving & G_TRANSFORM_SEQ) && (last_seq->flag & SELECT) &&
((last_seq->flag & SEQ_LEFTSEL) || (last_seq->flag & SEQ_RIGHTSEL)) &&
(sseq->draw_flag & SEQ_DRAW_TRANSFORM_PREVIEW);
}
static int sequencer_draw_get_transform_preview_frame(Scene *scene)
{
Sequence *last_seq = SEQ_select_active_get(scene);
/* #sequencer_draw_get_transform_preview must already have been called. */
BLI_assert(last_seq != nullptr);
int preview_frame;
if (last_seq->flag & SEQ_RIGHTSEL) {
preview_frame = SEQ_time_right_handle_frame_get(scene, last_seq) - 1;
}
else {
preview_frame = SEQ_time_left_handle_frame_get(scene, last_seq);
}
return preview_frame;
}
static void seq_draw_image_origin_and_outline(const bContext *C, Sequence *seq, bool is_active_seq)
{
SpaceSeq *sseq = CTX_wm_space_seq(C);
const ARegion *region = CTX_wm_region(C);
if (region->regiontype == RGN_TYPE_PREVIEW && !sequencer_view_preview_only_poll(C)) {
return;
}
if ((seq->flag & SELECT) == 0) {
return;
}
if (ED_screen_animation_no_scrub(CTX_wm_manager(C))) {
return;
}
if ((sseq->flag & SEQ_SHOW_OVERLAY) == 0 ||
(sseq->preview_overlay.flag & SEQ_PREVIEW_SHOW_OUTLINE_SELECTED) == 0)
{
return;
}
if (ELEM(sseq->mainb, SEQ_DRAW_IMG_WAVEFORM, SEQ_DRAW_IMG_VECTORSCOPE, SEQ_DRAW_IMG_HISTOGRAM)) {
return;
}
float origin[2];
SEQ_image_transform_origin_offset_pixelspace_get(CTX_data_scene(C), seq, origin);
/* Origin. */
GPUVertFormat *format = immVertexFormat();
uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_POINT_UNIFORM_SIZE_UNIFORM_COLOR_OUTLINE_AA);
immUniform1f("outlineWidth", 1.5f);
immUniformColor3f(1.0f, 1.0f, 1.0f);
immUniform4f("outlineColor", 0.0f, 0.0f, 0.0f, 1.0f);
immUniform1f("size", 15.0f * U.pixelsize);
immBegin(GPU_PRIM_POINTS, 1);
immVertex2f(pos, origin[0], origin[1]);
immEnd();
immUnbindProgram();
/* Outline. */
float seq_image_quad[4][2];
SEQ_image_transform_final_quad_get(CTX_data_scene(C), seq, seq_image_quad);
GPU_line_smooth(true);
GPU_blend(GPU_BLEND_ALPHA);
GPU_line_width(2);
immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
float col[3];
if (is_active_seq) {
UI_GetThemeColor3fv(TH_SEQ_ACTIVE, col);
}
else {
UI_GetThemeColor3fv(TH_SEQ_SELECTED, col);
}
immUniformColor3fv(col);
immUniform1f("lineWidth", U.pixelsize);
immBegin(GPU_PRIM_LINE_LOOP, 4);
immVertex2f(pos, seq_image_quad[0][0], seq_image_quad[0][1]);
immVertex2f(pos, seq_image_quad[1][0], seq_image_quad[1][1]);
immVertex2f(pos, seq_image_quad[2][0], seq_image_quad[2][1]);
immVertex2f(pos, seq_image_quad[3][0], seq_image_quad[3][1]);
immEnd();
immUnbindProgram();
GPU_line_width(1);
GPU_blend(GPU_BLEND_NONE);
GPU_line_smooth(false);
}
void sequencer_draw_preview(const bContext *C,
Scene *scene,
ARegion *region,
SpaceSeq *sseq,
int timeline_frame,
int offset,
bool draw_overlay,
bool draw_backdrop)
{
Main *bmain = CTX_data_main(C);
Depsgraph *depsgraph = CTX_data_expect_evaluated_depsgraph(C);
View2D *v2d = &region->v2d;
ImBuf *ibuf = nullptr;
ImBuf *scope = nullptr;
float viewrect[2];
const bool show_imbuf = ED_space_sequencer_check_show_imbuf(sseq);
const bool draw_gpencil = ((sseq->preview_overlay.flag & SEQ_PREVIEW_SHOW_GPENCIL) && sseq->gpd);
const char *names[2] = {STEREO_LEFT_NAME, STEREO_RIGHT_NAME};
sequencer_stop_running_jobs(C, scene);
if (G.is_rendering) {
return;
}
int preview_frame = timeline_frame;
if (sequencer_draw_get_transform_preview(sseq, scene)) {
preview_frame = sequencer_draw_get_transform_preview_frame(scene);
}
/* Get image. */
ibuf = sequencer_ibuf_get(
bmain, region, depsgraph, scene, sseq, preview_frame, offset, names[sseq->multiview_eye]);
/* Setup off-screen buffers. */
GPUViewport *viewport = WM_draw_region_get_viewport(region);
GPUFrameBuffer *framebuffer_overlay = GPU_viewport_framebuffer_overlay_get(viewport);
GPU_framebuffer_bind_no_srgb(framebuffer_overlay);
GPU_depth_test(GPU_DEPTH_NONE);
if (sseq->render_size == SEQ_RENDER_SIZE_NONE) {
sequencer_preview_clear();
return;
}
/* Setup view. */
sequencer_display_size(scene, viewrect);
UI_view2d_totRect_set(v2d, roundf(viewrect[0] + 0.5f), roundf(viewrect[1] + 0.5f));
UI_view2d_curRect_validate(v2d);
UI_view2d_view_ortho(v2d);
/* Draw background. */
if (!draw_backdrop &&
(!draw_overlay || (sseq->overlay_frame_type == SEQ_OVERLAY_FRAME_TYPE_REFERENCE)))
{
sequencer_preview_clear();
if (sseq->flag & SEQ_USE_ALPHA) {
imm_draw_box_checker_2d(v2d->tot.xmin, v2d->tot.ymin, v2d->tot.xmax, v2d->tot.ymax);
}
}
if (ibuf) {
scope = sequencer_get_scope(scene, sseq, ibuf, draw_backdrop);
/* Draw image. */
sequencer_draw_display_buffer(
C, scene, region, sseq, ibuf, scope, draw_overlay, draw_backdrop);
/* Draw over image. */
if (sseq->preview_overlay.flag & SEQ_PREVIEW_SHOW_METADATA && sseq->flag & SEQ_SHOW_OVERLAY) {
ED_region_image_metadata_draw(0.0, 0.0, ibuf, &v2d->tot, 1.0, 1.0);
}
}
if (show_imbuf && (sseq->flag & SEQ_SHOW_OVERLAY)) {
sequencer_draw_borders_overlay(sseq, v2d, scene);
}
if (!draw_backdrop && scene->ed != nullptr) {
Editing *ed = SEQ_editing_get(scene);
ListBase *channels = SEQ_channels_displayed_get(ed);
SeqCollection *collection = SEQ_query_rendered_strips(
scene, channels, ed->seqbasep, timeline_frame, 0);
Sequence *seq;
Sequence *active_seq = SEQ_select_active_get(scene);
SEQ_ITERATOR_FOREACH (seq, collection) {
seq_draw_image_origin_and_outline(C, seq, seq == active_seq);
}
SEQ_collection_free(collection);
}
if (draw_gpencil && show_imbuf && (sseq->flag & SEQ_SHOW_OVERLAY)) {
sequencer_draw_gpencil_overlay(C);
}
#if 0
sequencer_draw_maskedit(C, scene, region, sseq);
#endif
/* Draw registered callbacks. */
GPU_framebuffer_bind(framebuffer_overlay);
ED_region_draw_cb_draw(C, region, REGION_DRAW_POST_VIEW);
GPU_framebuffer_bind_no_srgb(framebuffer_overlay);
/* Scope is freed in sequencer_check_scopes when `ibuf` changes and redraw is needed. */
if (ibuf) {
IMB_freeImBuf(ibuf);
}
UI_view2d_view_restore(C);
seq_prefetch_wm_notify(C, scene);
}
static void draw_seq_timeline_channels(View2D *v2d)
{
uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);

View File

@ -34,7 +34,7 @@
#include "ED_util_imbuf.hh"
/* Own include. */
#include "sequencer_intern.h"
#include "sequencer_intern.hh"
/* -------------------------------------------------------------------- */
/** \name Sequencer Sample Backdrop Operator

Some files were not shown because too many files have changed in this diff Show More