Fix #110108: NLA absolute snapping #111984
|
@ -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/"
|
||||
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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
|
||||
)
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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"),
|
||||
|
|
|
@ -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):
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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),
|
||||
]},
|
||||
)
|
||||
|
||||
|
|
|
@ -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'}
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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"
|
||||
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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):
|
||||
|
|
|
@ -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")
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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]);
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
});
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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 */]);
|
||||
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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);
|
||||
|
||||
/** \} */
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
|
||||
/** \file
|
||||
* \ingroup eevee
|
||||
*
|
||||
*/
|
||||
|
||||
#include "BLI_vector.hh"
|
||||
|
@ -18,7 +17,6 @@ namespace blender::eevee {
|
|||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Subsurface
|
||||
*
|
||||
* \{ */
|
||||
|
||||
void SubsurfaceModule::end_sync()
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
|
||||
/** \file
|
||||
* \ingroup draw_engine
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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, ¶ms)) {
|
||||
cpd->acted = delete_point_under_mouse(&vc, event);
|
||||
if (ED_curve_editnurb_select_pick(C, event->mval, threshold_dist_px, ¶ms)) {
|
||||
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, ¶ms);
|
||||
ED_curve_editnurb_select_pick(C, event->mval, threshold_dist_px, ¶ms);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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",
|
||||
"");
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
* \{ */
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)) {
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -70,7 +70,7 @@
|
|||
#include "DEG_depsgraph_build.h"
|
||||
|
||||
/* Own include. */
|
||||
#include "sequencer_intern.h"
|
||||
#include "sequencer_intern.hh"
|
||||
|
||||
struct SequencerAddData {
|
||||
ImageFormatData im_format;
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
#include "IMB_imbuf.h"
|
||||
#include "IMB_imbuf_types.h"
|
||||
|
||||
#include "sequencer_intern.h"
|
||||
#include "sequencer_intern.hh"
|
||||
|
||||
/* **************************** buttons ********************************* */
|
||||
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -47,7 +47,7 @@
|
|||
#endif
|
||||
|
||||
/* Own include. */
|
||||
#include "sequencer_intern.h"
|
||||
#include "sequencer_intern.hh"
|
||||
|
||||
struct SeqDropCoords {
|
||||
float start_frame, channel;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -51,7 +51,7 @@
|
|||
#include "SEQ_time.h"
|
||||
|
||||
/* Own include. */
|
||||
#include "sequencer_intern.h"
|
||||
#include "sequencer_intern.hh"
|
||||
|
||||
using blender::MutableSpan;
|
||||
|
||||
|
|
|
@ -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
|
|
@ -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);
|
|
@ -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);
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
|
||||
#include "ED_sequencer.hh"
|
||||
|
||||
#include "sequencer_intern.h"
|
||||
#include "sequencer_intern.hh"
|
||||
|
||||
/* ************************** registration **********************************/
|
||||
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
|
||||
#include "MEM_guardedalloc.h"
|
||||
|
||||
#include "sequencer_intern.h"
|
||||
#include "sequencer_intern.hh"
|
||||
|
||||
struct PreviewJob {
|
||||
ListBase previews;
|
||||
|
|
|
@ -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, ®ion->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, ®ion->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 = ®ion->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(®ion->winrct) / float(BLI_rcti_size_y(®ion->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 = ®ion->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);
|
||||
}
|
|
@ -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
|
||||
|
|
|
@ -35,7 +35,7 @@
|
|||
#include "DEG_depsgraph.h"
|
||||
|
||||
/* Own include. */
|
||||
#include "sequencer_intern.h"
|
||||
#include "sequencer_intern.hh"
|
||||
|
||||
using blender::MutableSpan;
|
||||
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -46,7 +46,7 @@
|
|||
#include "UI_view2d.hh"
|
||||
|
||||
/* Own include. */
|
||||
#include "sequencer_intern.h"
|
||||
#include "sequencer_intern.hh"
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Selection Utilities
|
||||
|
|
|
@ -31,7 +31,7 @@
|
|||
#include "MEM_guardedalloc.h"
|
||||
|
||||
/* Own include. */
|
||||
#include "sequencer_intern.h"
|
||||
#include "sequencer_intern.hh"
|
||||
|
||||
struct ThumbnailDrawJob {
|
||||
SeqRenderData context;
|
||||
|
|
|
@ -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, ®ion->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, ®ion->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 = ®ion->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(®ion->winrct) / float(BLI_rcti_size_y(®ion->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 = ®ion->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);
|
|
@ -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
Loading…
Reference in New Issue