Merge branch 'master' into sculpt-dev
This commit is contained in:
commit
65cea9523e
|
@ -151,8 +151,6 @@ string device_opencl_capabilities()
|
|||
platform_ids.resize(num_platforms);
|
||||
opencl_assert(clGetPlatformIDs(num_platforms, &platform_ids[0], NULL));
|
||||
|
||||
typedef char cl_string[1024];
|
||||
|
||||
# define APPEND_INFO(func, id, name, what, type) \
|
||||
do { \
|
||||
type data; \
|
||||
|
@ -160,22 +158,33 @@ string device_opencl_capabilities()
|
|||
opencl_assert(func(id, what, sizeof(data), &data, NULL)); \
|
||||
result += string_printf("%s: %s\n", name, to_string(data).c_str()); \
|
||||
} while (false)
|
||||
# define APPEND_STRING_EXTENSION_INFO(func, id, name, what) \
|
||||
# define APPEND_STRING_INFO_IMPL(func, id, name, what, is_optional) \
|
||||
do { \
|
||||
char data[1024] = "\0"; \
|
||||
string value; \
|
||||
size_t length = 0; \
|
||||
if (func(id, what, sizeof(data), &data, &length) == CL_SUCCESS) { \
|
||||
if (length != 0 && data[0] != '\0') { \
|
||||
result += string_printf("%s: %s\n", name, data); \
|
||||
if (func(id, what, 0, NULL, &length) == CL_SUCCESS) { \
|
||||
vector<char> buffer(length + 1); \
|
||||
if (func(id, what, buffer.size(), buffer.data(), NULL) == CL_SUCCESS) { \
|
||||
value = string(buffer.data()); \
|
||||
} \
|
||||
} \
|
||||
if (is_optional && !(length != 0 && value[0] != '\0')) { \
|
||||
break; \
|
||||
} \
|
||||
result += string_printf("%s: %s\n", name, value.c_str()); \
|
||||
} while (false)
|
||||
# define APPEND_PLATFORM_STRING_INFO(id, name, what) \
|
||||
APPEND_STRING_INFO_IMPL(clGetPlatformInfo, id, "\tPlatform " name, what, false)
|
||||
# define APPEND_STRING_EXTENSION_INFO(func, id, name, what) \
|
||||
APPEND_STRING_INFO_IMPL(clGetPlatformInfo, id, "\tPlatform " name, what, true)
|
||||
# define APPEND_PLATFORM_INFO(id, name, what, type) \
|
||||
APPEND_INFO(clGetPlatformInfo, id, "\tPlatform " name, what, type)
|
||||
# define APPEND_DEVICE_INFO(id, name, what, type) \
|
||||
APPEND_INFO(clGetDeviceInfo, id, "\t\t\tDevice " name, what, type)
|
||||
# define APPEND_DEVICE_STRING_INFO(id, name, what) \
|
||||
APPEND_STRING_INFO_IMPL(clGetDeviceInfo, id, "\t\t\tDevice " name, what, false)
|
||||
# define APPEND_DEVICE_STRING_EXTENSION_INFO(id, name, what) \
|
||||
APPEND_STRING_EXTENSION_INFO(clGetDeviceInfo, id, "\t\t\tDevice " name, what)
|
||||
APPEND_STRING_INFO_IMPL(clGetDeviceInfo, id, "\t\t\tDevice " name, what, true)
|
||||
|
||||
vector<cl_device_id> device_ids;
|
||||
for (cl_uint platform = 0; platform < num_platforms; ++platform) {
|
||||
|
@ -183,11 +192,11 @@ string device_opencl_capabilities()
|
|||
|
||||
result += string_printf("Platform #%u\n", platform);
|
||||
|
||||
APPEND_PLATFORM_INFO(platform_id, "Name", CL_PLATFORM_NAME, cl_string);
|
||||
APPEND_PLATFORM_INFO(platform_id, "Vendor", CL_PLATFORM_VENDOR, cl_string);
|
||||
APPEND_PLATFORM_INFO(platform_id, "Version", CL_PLATFORM_VERSION, cl_string);
|
||||
APPEND_PLATFORM_INFO(platform_id, "Profile", CL_PLATFORM_PROFILE, cl_string);
|
||||
APPEND_PLATFORM_INFO(platform_id, "Extensions", CL_PLATFORM_EXTENSIONS, cl_string);
|
||||
APPEND_PLATFORM_STRING_INFO(platform_id, "Name", CL_PLATFORM_NAME);
|
||||
APPEND_PLATFORM_STRING_INFO(platform_id, "Vendor", CL_PLATFORM_VENDOR);
|
||||
APPEND_PLATFORM_STRING_INFO(platform_id, "Version", CL_PLATFORM_VERSION);
|
||||
APPEND_PLATFORM_STRING_INFO(platform_id, "Profile", CL_PLATFORM_PROFILE);
|
||||
APPEND_PLATFORM_STRING_INFO(platform_id, "Extensions", CL_PLATFORM_EXTENSIONS);
|
||||
|
||||
cl_uint num_devices = 0;
|
||||
opencl_assert(
|
||||
|
@ -202,13 +211,13 @@ string device_opencl_capabilities()
|
|||
|
||||
result += string_printf("\t\tDevice: #%u\n", device);
|
||||
|
||||
APPEND_DEVICE_INFO(device_id, "Name", CL_DEVICE_NAME, cl_string);
|
||||
APPEND_DEVICE_STRING_INFO(device_id, "Name", CL_DEVICE_NAME);
|
||||
APPEND_DEVICE_STRING_EXTENSION_INFO(device_id, "Board Name", CL_DEVICE_BOARD_NAME_AMD);
|
||||
APPEND_DEVICE_INFO(device_id, "Vendor", CL_DEVICE_VENDOR, cl_string);
|
||||
APPEND_DEVICE_INFO(device_id, "OpenCL C Version", CL_DEVICE_OPENCL_C_VERSION, cl_string);
|
||||
APPEND_DEVICE_INFO(device_id, "Profile", CL_DEVICE_PROFILE, cl_string);
|
||||
APPEND_DEVICE_INFO(device_id, "Version", CL_DEVICE_VERSION, cl_string);
|
||||
APPEND_DEVICE_INFO(device_id, "Extensions", CL_DEVICE_EXTENSIONS, cl_string);
|
||||
APPEND_DEVICE_STRING_INFO(device_id, "Vendor", CL_DEVICE_VENDOR);
|
||||
APPEND_DEVICE_STRING_INFO(device_id, "OpenCL C Version", CL_DEVICE_OPENCL_C_VERSION);
|
||||
APPEND_DEVICE_STRING_INFO(device_id, "Profile", CL_DEVICE_PROFILE);
|
||||
APPEND_DEVICE_STRING_INFO(device_id, "Version", CL_DEVICE_VERSION);
|
||||
APPEND_DEVICE_STRING_INFO(device_id, "Extensions", CL_DEVICE_EXTENSIONS);
|
||||
APPEND_DEVICE_INFO(
|
||||
device_id, "Max clock frequency (MHz)", CL_DEVICE_MAX_CLOCK_FREQUENCY, cl_uint);
|
||||
APPEND_DEVICE_INFO(device_id, "Max compute units", CL_DEVICE_MAX_COMPUTE_UNITS, cl_uint);
|
||||
|
@ -216,9 +225,14 @@ string device_opencl_capabilities()
|
|||
}
|
||||
}
|
||||
|
||||
# undef APPEND_STRING_INFO
|
||||
# undef APPEND_INFO
|
||||
# undef APPEND_STRING_INFO_IMPL
|
||||
# undef APPEND_PLATFORM_STRING_INFO
|
||||
# undef APPEND_STRING_EXTENSION_INFO
|
||||
# undef APPEND_PLATFORM_INFO
|
||||
# undef APPEND_DEVICE_INFO
|
||||
# undef APPEND_DEVICE_STRING_INFO
|
||||
# undef APPEND_DEVICE_STRING_EXTENSION_INFO
|
||||
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -459,7 +459,11 @@ bool Session::acquire_tile(RenderTile &rtile, Device *tile_device, uint tile_typ
|
|||
int device_num = device->device_number(tile_device);
|
||||
|
||||
while (!tile_manager.next_tile(tile, device_num, tile_types)) {
|
||||
if (steal_tile(rtile, tile_device, tile_lock)) {
|
||||
/* Can only steal tiles on devices that support rendering
|
||||
* This is because denoising tiles cannot be stolen (see below)
|
||||
*/
|
||||
if ((tile_types & (RenderTile::PATH_TRACE | RenderTile::BAKE)) &&
|
||||
steal_tile(rtile, tile_device, tile_lock)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -119,6 +119,7 @@ _km_hierarchy = [
|
|||
|
||||
('Object Non-modal', 'EMPTY', 'WINDOW', []), # mode change
|
||||
|
||||
('View3D Placement Modal', 'EMPTY', 'WINDOW', []),
|
||||
('View3D Walk Modal', 'EMPTY', 'WINDOW', []),
|
||||
('View3D Fly Modal', 'EMPTY', 'WINDOW', []),
|
||||
('View3D Rotate Modal', 'EMPTY', 'WINDOW', []),
|
||||
|
|
|
@ -5087,10 +5087,10 @@ def km_transform_modal_map(_params):
|
|||
return keymap
|
||||
|
||||
|
||||
def km_view3d_interactive_add_tool_modal_map(_params):
|
||||
def km_view3d_interactive_add_tool_modal(_params):
|
||||
items = []
|
||||
keymap = (
|
||||
"View3D Placement Modal Map",
|
||||
"View3D Placement Modal",
|
||||
{"space_type": 'EMPTY', "region_type": 'WINDOW', "modal": True},
|
||||
{"items": items},
|
||||
)
|
||||
|
@ -7041,7 +7041,7 @@ def generate_keymaps(params=None):
|
|||
km_eyedropper_modal_map(params),
|
||||
km_eyedropper_colorramp_pointsampling_map(params),
|
||||
km_transform_modal_map(params),
|
||||
km_view3d_interactive_add_tool_modal_map(params),
|
||||
km_view3d_interactive_add_tool_modal(params),
|
||||
km_view3d_gesture_circle(params),
|
||||
km_gesture_border(params),
|
||||
km_gesture_zoom_border(params),
|
||||
|
|
|
@ -133,7 +133,6 @@ class DATA_PT_bone_groups(ArmatureButtonsPanel, Panel):
|
|||
)
|
||||
|
||||
col = row.column(align=True)
|
||||
col.active = (ob.proxy is None)
|
||||
col.operator("pose.group_add", icon='ADD', text="")
|
||||
col.operator("pose.group_remove", icon='REMOVE', text="")
|
||||
col.menu("DATA_MT_bone_group_context_menu", icon='DOWNARROW_HLT', text="")
|
||||
|
@ -156,7 +155,6 @@ class DATA_PT_bone_groups(ArmatureButtonsPanel, Panel):
|
|||
sub.prop(group.colors, "active", text="")
|
||||
|
||||
row = layout.row()
|
||||
row.active = (ob.proxy is None)
|
||||
|
||||
sub = row.row(align=True)
|
||||
sub.operator("pose.group_assign", text="Assign")
|
||||
|
|
|
@ -759,6 +759,16 @@ class GreasePencilLayerAdjustmentsPanel:
|
|||
col = layout.row(align=True)
|
||||
col.prop(gpl, "lock_material")
|
||||
|
||||
# Transforms
|
||||
row = layout.row(align=True)
|
||||
row.prop(gpl, "location")
|
||||
|
||||
row = layout.row(align=True)
|
||||
row.prop(gpl, "rotation")
|
||||
|
||||
row = layout.row(align=True)
|
||||
row.prop(gpl, "scale")
|
||||
|
||||
|
||||
class GPENCIL_UL_masks(UIList):
|
||||
def draw_item(self, _context, layout, _data, item, icon, _active_data, _active_propname, _index):
|
||||
|
|
|
@ -502,7 +502,9 @@ class CLIP_PT_tools_tracking(CLIP_PT_tracking_panel, Panel):
|
|||
col = layout.column(align=True)
|
||||
row = col.row(align=True)
|
||||
row.label(text="Merge:")
|
||||
row.operator("clip.join_tracks", text="Join Tracks")
|
||||
sub = row.column()
|
||||
sub.operator("clip.join_tracks", text="Join Tracks")
|
||||
sub.operator("clip.average_tracks", text="Average Tracks")
|
||||
|
||||
|
||||
class CLIP_PT_tools_plane_tracking(CLIP_PT_tracking_panel, Panel):
|
||||
|
@ -1482,6 +1484,7 @@ class CLIP_MT_track(Menu):
|
|||
layout.separator()
|
||||
|
||||
layout.operator("clip.join_tracks")
|
||||
layout.operator("clip.average_tracks")
|
||||
|
||||
layout.separator()
|
||||
|
||||
|
@ -1608,6 +1611,7 @@ class CLIP_MT_tracking_context_menu(Menu):
|
|||
layout.separator()
|
||||
|
||||
layout.operator("clip.join_tracks")
|
||||
layout.operator("clip.average_tracks")
|
||||
|
||||
layout.separator()
|
||||
|
||||
|
|
|
@ -451,38 +451,90 @@ class _defs_view3d_select:
|
|||
|
||||
class _defs_view3d_add:
|
||||
|
||||
@staticmethod
|
||||
def description_interactive_add(context, _item, _km, *, prefix):
|
||||
km = context.window_manager.keyconfigs.user.keymaps["View3D Placement Modal"]
|
||||
|
||||
def keymap_item_from_propvalue(propvalue):
|
||||
for item in km.keymap_items:
|
||||
if item.propvalue == propvalue:
|
||||
return item
|
||||
|
||||
if km is not None:
|
||||
kmi_snap = keymap_item_from_propvalue('SNAP_ON')
|
||||
kmi_center = keymap_item_from_propvalue('PIVOT_CENTER_ON')
|
||||
kmi_fixed_aspect = keymap_item_from_propvalue('FIXED_ASPECT_ON')
|
||||
else:
|
||||
kmi_snap = None
|
||||
kmi_center = None
|
||||
kmi_fixed_aspect = None
|
||||
return tip_(
|
||||
"%s\n"
|
||||
"\u2022 %s toggles snap while dragging.\n"
|
||||
"\u2022 %s toggles dragging from the center.\n"
|
||||
"\u2022 %s toggles fixed aspect"
|
||||
) % (
|
||||
prefix,
|
||||
kmi_to_string_or_none(kmi_snap),
|
||||
kmi_to_string_or_none(kmi_center),
|
||||
kmi_to_string_or_none(kmi_fixed_aspect),
|
||||
)
|
||||
|
||||
# Layout tweaks here would be good to avoid,
|
||||
# this shows limits in layout engine, as buttons are using a lot of space.
|
||||
@staticmethod
|
||||
def draw_settings_interactive_add(layout, tool):
|
||||
def draw_settings_interactive_add(layout, tool, extra):
|
||||
show_extra = False
|
||||
props = tool.operator_properties("view3d.interactive_add")
|
||||
row = layout.row()
|
||||
row.scale_x = 0.8
|
||||
row.label(text="Depth:")
|
||||
row = layout.row()
|
||||
row.scale_x = 0.9
|
||||
row.prop(props, "plane_depth", text="")
|
||||
row = layout.row()
|
||||
row.prop(props, "plane_axis", text="")
|
||||
row = layout.row()
|
||||
row.scale_x = 0.8
|
||||
row.label(text="Orientation:")
|
||||
row = layout.row()
|
||||
row.prop(props, "plane_orientation", text="")
|
||||
row = layout.row()
|
||||
row.scale_x = 0.7
|
||||
row.prop(props, "plane_origin")
|
||||
if not extra:
|
||||
row = layout.row()
|
||||
row.scale_x = 0.8
|
||||
row.label(text="Depth:")
|
||||
row = layout.row()
|
||||
row.scale_x = 0.9
|
||||
row.prop(props, "plane_depth", text="")
|
||||
row = layout.row()
|
||||
row.scale_x = 0.8
|
||||
row.label(text="Orientation:")
|
||||
row = layout.row()
|
||||
row.prop(props, "plane_orientation", text="")
|
||||
row = layout.row()
|
||||
row.scale_x = 0.8
|
||||
row.prop(props, "snap_target")
|
||||
|
||||
region_is_header = bpy.context.region.type == 'TOOL_HEADER'
|
||||
|
||||
if region_is_header:
|
||||
# Don't draw the "extra" popover here as we might have other settings & this should be last.
|
||||
show_extra = True
|
||||
else:
|
||||
extra = True
|
||||
|
||||
if extra:
|
||||
layout.use_property_split = True
|
||||
layout.row().prop(props, "plane_axis", expand=True)
|
||||
|
||||
layout.label(text="Base")
|
||||
layout.row().prop(props, "plane_origin_base", expand=True)
|
||||
layout.row().prop(props, "plane_aspect_base", expand=True)
|
||||
layout.label(text="Height")
|
||||
layout.row().prop(props, "plane_origin_depth", expand=True)
|
||||
layout.row().prop(props, "plane_aspect_depth", expand=True)
|
||||
return show_extra
|
||||
|
||||
@ToolDef.from_fn
|
||||
def cube_add():
|
||||
def draw_settings(_context, layout, tool):
|
||||
_defs_view3d_add.draw_settings_interactive_add(layout, tool)
|
||||
def draw_settings(_context, layout, tool, *, extra=False):
|
||||
show_extra = _defs_view3d_add.draw_settings_interactive_add(layout, tool, extra)
|
||||
if show_extra:
|
||||
layout.popover("TOPBAR_PT_tool_settings_extra", text="...")
|
||||
|
||||
return dict(
|
||||
idname="builtin.primitive_cube_add",
|
||||
label="Add Cube",
|
||||
icon="ops.mesh.primitive_cube_add_gizmo",
|
||||
description=(
|
||||
"Add cube to mesh interactively"
|
||||
description=lambda *args: _defs_view3d_add.description_interactive_add(
|
||||
*args, prefix=tip_("Add cube to mesh interactively"),
|
||||
),
|
||||
widget="VIEW3D_GGT_placement",
|
||||
keymap="3D View Tool: Object, Add Primitive",
|
||||
|
@ -491,18 +543,24 @@ class _defs_view3d_add:
|
|||
|
||||
@ToolDef.from_fn
|
||||
def cone_add():
|
||||
def draw_settings(_context, layout, tool):
|
||||
_defs_view3d_add.draw_settings_interactive_add(layout, tool)
|
||||
def draw_settings(_context, layout, tool, *, extra=False):
|
||||
show_extra = _defs_view3d_add.draw_settings_interactive_add(layout, tool, extra)
|
||||
if extra:
|
||||
return
|
||||
|
||||
props = tool.operator_properties("mesh.primitive_cone_add")
|
||||
layout.prop(props, "vertices")
|
||||
layout.prop(props, "end_fill_type")
|
||||
|
||||
if show_extra:
|
||||
layout.popover("TOPBAR_PT_tool_settings_extra", text="...")
|
||||
|
||||
return dict(
|
||||
idname="builtin.primitive_cone_add",
|
||||
label="Add Cone",
|
||||
icon="ops.mesh.primitive_cone_add_gizmo",
|
||||
description=(
|
||||
"Add cone to mesh interactively"
|
||||
description=lambda *args: _defs_view3d_add.description_interactive_add(
|
||||
*args, prefix=tip_("Add cone to mesh interactively"),
|
||||
),
|
||||
widget="VIEW3D_GGT_placement",
|
||||
keymap="3D View Tool: Object, Add Primitive",
|
||||
|
@ -511,18 +569,23 @@ class _defs_view3d_add:
|
|||
|
||||
@ToolDef.from_fn
|
||||
def cylinder_add():
|
||||
def draw_settings(_context, layout, tool):
|
||||
_defs_view3d_add.draw_settings_interactive_add(layout, tool)
|
||||
def draw_settings(_context, layout, tool, *, extra=False):
|
||||
show_extra = _defs_view3d_add.draw_settings_interactive_add(layout, tool, extra)
|
||||
if extra:
|
||||
return
|
||||
|
||||
props = tool.operator_properties("mesh.primitive_cylinder_add")
|
||||
layout.prop(props, "vertices")
|
||||
layout.prop(props, "end_fill_type")
|
||||
|
||||
if show_extra:
|
||||
layout.popover("TOPBAR_PT_tool_settings_extra", text="...")
|
||||
return dict(
|
||||
idname="builtin.primitive_cylinder_add",
|
||||
label="Add Cylinder",
|
||||
icon="ops.mesh.primitive_cylinder_add_gizmo",
|
||||
description=(
|
||||
"Add cylinder to mesh interactively"
|
||||
description=lambda *args: _defs_view3d_add.description_interactive_add(
|
||||
*args, prefix=tip_("Add cylinder to mesh interactively"),
|
||||
),
|
||||
widget="VIEW3D_GGT_placement",
|
||||
keymap="3D View Tool: Object, Add Primitive",
|
||||
|
@ -531,18 +594,23 @@ class _defs_view3d_add:
|
|||
|
||||
@ToolDef.from_fn
|
||||
def uv_sphere_add():
|
||||
def draw_settings(_context, layout, tool):
|
||||
_defs_view3d_add.draw_settings_interactive_add(layout, tool)
|
||||
def draw_settings(_context, layout, tool, *, extra=False):
|
||||
show_extra = _defs_view3d_add.draw_settings_interactive_add(layout, tool, extra)
|
||||
if extra:
|
||||
return
|
||||
|
||||
props = tool.operator_properties("mesh.primitive_uv_sphere_add")
|
||||
layout.prop(props, "segments")
|
||||
layout.prop(props, "ring_count")
|
||||
|
||||
if show_extra:
|
||||
layout.popover("TOPBAR_PT_tool_settings_extra", text="...")
|
||||
return dict(
|
||||
idname="builtin.primitive_uv_sphere_add",
|
||||
label="Add UV Sphere",
|
||||
icon="ops.mesh.primitive_sphere_add_gizmo",
|
||||
description=(
|
||||
"Add cylinder to mesh interactively"
|
||||
description=lambda *args: _defs_view3d_add.description_interactive_add(
|
||||
*args, prefix=tip_("Add sphere to mesh interactively"),
|
||||
),
|
||||
widget="VIEW3D_GGT_placement",
|
||||
keymap="3D View Tool: Object, Add Primitive",
|
||||
|
@ -551,17 +619,22 @@ class _defs_view3d_add:
|
|||
|
||||
@ToolDef.from_fn
|
||||
def ico_sphere_add():
|
||||
def draw_settings(_context, layout, tool):
|
||||
_defs_view3d_add.draw_settings_interactive_add(layout, tool)
|
||||
def draw_settings(_context, layout, tool, *, extra=False):
|
||||
show_extra = _defs_view3d_add.draw_settings_interactive_add(layout, tool, extra)
|
||||
if extra:
|
||||
return
|
||||
|
||||
props = tool.operator_properties("mesh.primitive_ico_sphere_add")
|
||||
layout.prop(props, "subdivisions")
|
||||
|
||||
if show_extra:
|
||||
layout.popover("TOPBAR_PT_tool_settings_extra", text="...")
|
||||
return dict(
|
||||
idname="builtin.primitive_ico_sphere_add",
|
||||
label="Add Ico Sphere",
|
||||
icon="ops.mesh.primitive_sphere_add_gizmo",
|
||||
description=(
|
||||
"Add cylinder to mesh interactively"
|
||||
description=lambda *args: _defs_view3d_add.description_interactive_add(
|
||||
*args, prefix=tip_("Add sphere to mesh interactively"),
|
||||
),
|
||||
widget="VIEW3D_GGT_placement",
|
||||
keymap="3D View Tool: Object, Add Primitive",
|
||||
|
@ -2614,12 +2687,8 @@ class VIEW3D_PT_tools_active(ToolSelectPanelHelper, Panel):
|
|||
],
|
||||
'OBJECT': [
|
||||
*_tools_default,
|
||||
# Currently experimental.
|
||||
# None, _tools_view3d_add,
|
||||
lambda context: (
|
||||
(None, VIEW3D_PT_tools_active._tools_view3d_add)
|
||||
if (context is None or context.preferences.experimental.use_object_add_tool) else ()
|
||||
),
|
||||
None,
|
||||
_tools_view3d_add,
|
||||
],
|
||||
'POSE': [
|
||||
*_tools_default,
|
||||
|
@ -2648,12 +2717,8 @@ class VIEW3D_PT_tools_active(ToolSelectPanelHelper, Panel):
|
|||
'EDIT_MESH': [
|
||||
*_tools_default,
|
||||
|
||||
# Currently experimental.
|
||||
# None, _tools_view3d_add,
|
||||
lambda context: (
|
||||
(None, VIEW3D_PT_tools_active._tools_view3d_add)
|
||||
if (context is None or context.preferences.experimental.use_object_add_tool) else ()
|
||||
),
|
||||
None,
|
||||
_tools_view3d_add,
|
||||
None,
|
||||
(
|
||||
_defs_edit_mesh.extrude,
|
||||
|
|
|
@ -2236,7 +2236,6 @@ class USERPREF_PT_experimental_new_features(ExperimentalPanel, Panel):
|
|||
({"property": "use_sculpt_vertex_colors"}, "T71947"),
|
||||
({"property": "use_switch_object_operator"}, "T80402"),
|
||||
({"property": "use_sculpt_tools_tilt"}, "T82877"),
|
||||
({"property": "use_object_add_tool"}, "T57210"),
|
||||
({"property": "use_asset_browser"}, ("project/profile/124/", "Milestone 1")),
|
||||
),
|
||||
)
|
||||
|
|
|
@ -280,12 +280,12 @@ void BKE_gpencil_frame_original_pointers_update(const struct bGPDframe *gpf_orig
|
|||
const struct bGPDframe *gpf_eval);
|
||||
void BKE_gpencil_update_orig_pointers(const struct Object *ob_orig, const struct Object *ob_eval);
|
||||
|
||||
void BKE_gpencil_parent_matrix_get(const struct Depsgraph *depsgraph,
|
||||
struct Object *obact,
|
||||
struct bGPDlayer *gpl,
|
||||
float diff_mat[4][4]);
|
||||
void BKE_gpencil_layer_transform_matrix_get(const struct Depsgraph *depsgraph,
|
||||
struct Object *obact,
|
||||
struct bGPDlayer *gpl,
|
||||
float diff_mat[4][4]);
|
||||
|
||||
void BKE_gpencil_update_layer_parent(const struct Depsgraph *depsgraph, struct Object *ob);
|
||||
void BKE_gpencil_update_layer_transforms(const struct Depsgraph *depsgraph, struct Object *ob);
|
||||
|
||||
int BKE_gpencil_material_find_index_by_name_prefix(struct Object *ob, const char *name_prefix);
|
||||
|
||||
|
|
|
@ -89,6 +89,23 @@ struct MovieTrackingTrack *BKE_tracking_track_duplicate(struct MovieTrackingTrac
|
|||
void BKE_tracking_track_unique_name(struct ListBase *tracksbase, struct MovieTrackingTrack *track);
|
||||
void BKE_tracking_track_free(struct MovieTrackingTrack *track);
|
||||
|
||||
void BKE_tracking_track_first_last_frame_get(const struct MovieTrackingTrack *track,
|
||||
int *r_first_frame,
|
||||
int *r_last_frame);
|
||||
|
||||
void BKE_tracking_tracks_first_last_frame_minmax(/*const*/ struct MovieTrackingTrack **tracks,
|
||||
const int num_tracks,
|
||||
int *r_first_frame,
|
||||
int *r_last_frame);
|
||||
|
||||
int BKE_tracking_count_selected_tracks_in_list(const struct ListBase *tracks_list);
|
||||
int BKE_tracking_count_selected_tracks_in_active_object(/*const*/ struct MovieTracking *tracking);
|
||||
|
||||
/* Get array of selected tracks from the current active object in the tracking structure.
|
||||
* If nothing is selected then the result is nullptr and `r_num_tracks` is set to 0. */
|
||||
struct MovieTrackingTrack **BKE_tracking_selected_tracks_in_active_object(
|
||||
struct MovieTracking *tracking, int *r_num_tracks);
|
||||
|
||||
void BKE_tracking_track_flag_set(struct MovieTrackingTrack *track, int area, int flag);
|
||||
void BKE_tracking_track_flag_clear(struct MovieTrackingTrack *track, int area, int flag);
|
||||
|
||||
|
@ -96,10 +113,15 @@ bool BKE_tracking_track_has_marker_at_frame(struct MovieTrackingTrack *track, in
|
|||
bool BKE_tracking_track_has_enabled_marker_at_frame(struct MovieTrackingTrack *track, int framenr);
|
||||
|
||||
void BKE_tracking_track_path_clear(struct MovieTrackingTrack *track, int ref_frame, int action);
|
||||
|
||||
void BKE_tracking_tracks_join(struct MovieTracking *tracking,
|
||||
struct MovieTrackingTrack *dst_track,
|
||||
struct MovieTrackingTrack *src_track);
|
||||
|
||||
void BKE_tracking_tracks_average(struct MovieTrackingTrack *dst_track,
|
||||
/*const*/ struct MovieTrackingTrack **src_tracks,
|
||||
const int num_src_tracks);
|
||||
|
||||
struct MovieTrackingTrack *BKE_tracking_track_get_named(struct MovieTracking *tracking,
|
||||
struct MovieTrackingObject *object,
|
||||
const char *name);
|
||||
|
@ -139,6 +161,17 @@ struct MovieTrackingMarker *BKE_tracking_marker_get_exact(struct MovieTrackingTr
|
|||
struct MovieTrackingMarker *BKE_tracking_marker_ensure(struct MovieTrackingTrack *track,
|
||||
int framenr);
|
||||
|
||||
/* Get marker position, possibly interpolating interpolating gap between keyframed/tracked markers.
|
||||
*
|
||||
* The result marker frame number is set to the requested frame number. Its flags are 0 if the
|
||||
* marker is interpolated, and is set to original marker flag if there were no interpolation
|
||||
* involved.
|
||||
*
|
||||
* Returns truth if the result is usable. */
|
||||
bool BKE_tracking_marker_get_interpolated(struct MovieTrackingTrack *track,
|
||||
const int framenr,
|
||||
struct MovieTrackingMarker *r_marker);
|
||||
|
||||
void BKE_tracking_marker_pattern_minmax(const struct MovieTrackingMarker *marker,
|
||||
float min[2],
|
||||
float max[2]);
|
||||
|
|
|
@ -1462,7 +1462,11 @@ void BKE_pchan_bbone_segments_cache_compute(bPoseChannel *pchan)
|
|||
tmat,
|
||||
b_bone_mats[0].mat);
|
||||
|
||||
mat4_to_dquat(&b_bone_dual_quats[a], bone->arm_mat, b_bone_mats[a + 1].mat);
|
||||
/* Compute the orthonormal object space rest matrix of the segment. */
|
||||
mul_m4_m4m4(tmat, bone->arm_mat, b_bone_rest[a].mat);
|
||||
normalize_m4(tmat);
|
||||
|
||||
mat4_to_dquat(&b_bone_dual_quats[a], tmat, b_bone_mats[a + 1].mat);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1202,6 +1202,11 @@ WriteAttributePtr MeshComponent::attribute_try_get_for_write(const StringRef att
|
|||
if (mesh_->dvert == nullptr) {
|
||||
BKE_object_defgroup_data_create(&mesh_->id);
|
||||
}
|
||||
else {
|
||||
/* Copy the data layer if it is shared with some other mesh. */
|
||||
mesh_->dvert = (MDeformVert *)CustomData_duplicate_referenced_layer(
|
||||
&mesh_->vdata, CD_MDEFORMVERT, mesh_->totvert);
|
||||
}
|
||||
return std::make_unique<blender::bke::VertexWeightWriteAttribute>(
|
||||
mesh_->dvert, mesh_->totvert, vertex_group_index);
|
||||
}
|
||||
|
|
|
@ -2539,9 +2539,14 @@ static void armdef_accumulate_matrix(const float obmat[4][4],
|
|||
|
||||
/* Accumulate the transformation. */
|
||||
if (r_sum_dq != NULL) {
|
||||
float basemat_world[4][4];
|
||||
DualQuat tmpdq;
|
||||
|
||||
mat4_to_dquat(&tmpdq, basemat, mat);
|
||||
/* Compute the orthonormal rest matrix in world space. */
|
||||
mul_m4_m4m4(basemat_world, obmat, basemat);
|
||||
orthogonalize_m4_stable(basemat_world, 1, true);
|
||||
|
||||
mat4_to_dquat(&tmpdq, basemat_world, mat);
|
||||
add_weighted_dq_dq(r_sum_dq, &tmpdq, weight);
|
||||
}
|
||||
else {
|
||||
|
@ -2558,7 +2563,7 @@ static void armdef_accumulate_bone(bConstraintTarget *ct,
|
|||
float r_sum_mat[4][4],
|
||||
DualQuat *r_sum_dq)
|
||||
{
|
||||
float iobmat[4][4], basemat[4][4], co[3];
|
||||
float iobmat[4][4], co[3];
|
||||
Bone *bone = pchan->bone;
|
||||
float weight = ct->weight;
|
||||
|
||||
|
@ -2572,15 +2577,12 @@ static void armdef_accumulate_bone(bConstraintTarget *ct,
|
|||
co, bone->arm_head, bone->arm_tail, bone->rad_head, bone->rad_tail, bone->dist);
|
||||
}
|
||||
|
||||
/* Compute the quaternion base matrix. */
|
||||
if (r_sum_dq != NULL) {
|
||||
mul_m4_series(basemat, ct->tar->obmat, bone->arm_mat, iobmat);
|
||||
}
|
||||
|
||||
/* Find the correct bone transform matrix in world space. */
|
||||
if (bone->segments > 1 && bone->segments == pchan->runtime.bbone_segments) {
|
||||
Mat4 *b_bone_mats = pchan->runtime.bbone_deform_mats;
|
||||
Mat4 *b_bone_rest_mats = pchan->runtime.bbone_rest_mats;
|
||||
float(*iamat)[4] = b_bone_mats[0].mat;
|
||||
float basemat[4][4];
|
||||
|
||||
/* The target is a B-Bone:
|
||||
* FIRST: find the segment (see b_bone_deform in armature.c)
|
||||
|
@ -2592,6 +2594,11 @@ static void armdef_accumulate_bone(bConstraintTarget *ct,
|
|||
float blend;
|
||||
BKE_pchan_bbone_deform_segment_index(pchan, y / bone->length, &index, &blend);
|
||||
|
||||
if (r_sum_dq != NULL) {
|
||||
/* Compute the object space rest matrix of the segment. */
|
||||
mul_m4_m4m4(basemat, bone->arm_mat, b_bone_rest_mats[index].mat);
|
||||
}
|
||||
|
||||
armdef_accumulate_matrix(ct->tar->obmat,
|
||||
iobmat,
|
||||
basemat,
|
||||
|
@ -2599,6 +2606,12 @@ static void armdef_accumulate_bone(bConstraintTarget *ct,
|
|||
weight * (1.0f - blend),
|
||||
r_sum_mat,
|
||||
r_sum_dq);
|
||||
|
||||
if (r_sum_dq != NULL) {
|
||||
/* Compute the object space rest matrix of the segment. */
|
||||
mul_m4_m4m4(basemat, bone->arm_mat, b_bone_rest_mats[index + 1].mat);
|
||||
}
|
||||
|
||||
armdef_accumulate_matrix(ct->tar->obmat,
|
||||
iobmat,
|
||||
basemat,
|
||||
|
@ -2610,7 +2623,7 @@ static void armdef_accumulate_bone(bConstraintTarget *ct,
|
|||
else {
|
||||
/* Simple bone. This requires DEG_OPCODE_BONE_DONE dependency due to chan_mat. */
|
||||
armdef_accumulate_matrix(
|
||||
ct->tar->obmat, iobmat, basemat, pchan->chan_mat, weight, r_sum_mat, r_sum_dq);
|
||||
ct->tar->obmat, iobmat, bone->arm_mat, pchan->chan_mat, weight, r_sum_mat, r_sum_dq);
|
||||
}
|
||||
|
||||
/* Accumulate the weight. */
|
||||
|
|
|
@ -40,6 +40,7 @@
|
|||
|
||||
#include "MEM_guardedalloc.h"
|
||||
|
||||
#include <cctype>
|
||||
#include <cstring>
|
||||
#include <iomanip>
|
||||
#include <sstream>
|
||||
|
|
|
@ -95,6 +95,32 @@ static void greasepencil_copy_data(Main *UNUSED(bmain),
|
|||
/* TODO here too could add unused flags... */
|
||||
bGPDlayer *gpl_dst = BKE_gpencil_layer_duplicate(gpl_src);
|
||||
|
||||
/* Apply local layer transform to all frames. Calc the active frame is not enough
|
||||
* because onion skin can use more frames. This is more slow but required here. */
|
||||
if (gpl_dst->actframe != NULL) {
|
||||
bool transfomed = ((!is_zero_v3(gpl_dst->location)) || (!is_zero_v3(gpl_dst->rotation)) ||
|
||||
(!is_one_v3(gpl_dst->scale)));
|
||||
if (transfomed) {
|
||||
loc_eul_size_to_mat4(
|
||||
gpl_dst->layer_mat, gpl_dst->location, gpl_dst->rotation, gpl_dst->scale);
|
||||
bool do_onion = ((gpl_dst->onion_flag & GP_LAYER_ONIONSKIN) != 0);
|
||||
bGPDframe *init_gpf = (do_onion) ? gpl_dst->frames.first : gpl_dst->actframe;
|
||||
for (bGPDframe *gpf = init_gpf; gpf; gpf = gpf->next) {
|
||||
LISTBASE_FOREACH (bGPDstroke *, gps, &gpf->strokes) {
|
||||
bGPDspoint *pt;
|
||||
int i;
|
||||
for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) {
|
||||
mul_m4_v3(gpl_dst->layer_mat, &pt->x);
|
||||
}
|
||||
}
|
||||
/* if not onion, exit loop. */
|
||||
if (!do_onion) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BLI_addtail(&gpd_dst->layers, gpl_dst);
|
||||
}
|
||||
}
|
||||
|
@ -686,6 +712,14 @@ bGPDlayer *BKE_gpencil_layer_addnew(bGPdata *gpd, const char *name, bool setacti
|
|||
|
||||
/* Enable always affected by scene lights. */
|
||||
gpl->flag |= GP_LAYER_USE_LIGHTS;
|
||||
|
||||
/* Init transform. */
|
||||
zero_v3(gpl->location);
|
||||
zero_v3(gpl->rotation);
|
||||
copy_v3_fl(gpl->scale, 1.0f);
|
||||
loc_eul_size_to_mat4(gpl->layer_mat, gpl->location, gpl->rotation, gpl->scale);
|
||||
invert_m4_m4(gpl->layer_invmat, gpl->layer_mat);
|
||||
|
||||
/* make this one the active one */
|
||||
if (setactive) {
|
||||
BKE_gpencil_layer_active_set(gpd, gpl);
|
||||
|
@ -2541,6 +2575,11 @@ void BKE_gpencil_visible_stroke_iter(ViewLayer *view_layer,
|
|||
continue;
|
||||
}
|
||||
|
||||
/* If scale to 0 the layer must be invisible. */
|
||||
if (is_zero_v3(gpl->scale)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Hide the layer if it's defined a view layer filter. This is used to
|
||||
* generate renders, putting only selected GP layers for each View Layer.
|
||||
* This is used only in final render and never in Viewport. */
|
||||
|
@ -2759,10 +2798,10 @@ void BKE_gpencil_update_orig_pointers(const Object *ob_orig, const Object *ob_ev
|
|||
* \param gpl: Grease pencil layer
|
||||
* \param diff_mat: Result parent matrix
|
||||
*/
|
||||
void BKE_gpencil_parent_matrix_get(const Depsgraph *depsgraph,
|
||||
Object *obact,
|
||||
bGPDlayer *gpl,
|
||||
float diff_mat[4][4])
|
||||
void BKE_gpencil_layer_transform_matrix_get(const Depsgraph *depsgraph,
|
||||
Object *obact,
|
||||
bGPDlayer *gpl,
|
||||
float diff_mat[4][4])
|
||||
{
|
||||
Object *ob_eval = depsgraph != NULL ? DEG_get_evaluated_object(depsgraph, obact) : obact;
|
||||
Object *obparent = gpl->parent;
|
||||
|
@ -2771,11 +2810,10 @@ void BKE_gpencil_parent_matrix_get(const Depsgraph *depsgraph,
|
|||
|
||||
/* if not layer parented, try with object parented */
|
||||
if (obparent_eval == NULL) {
|
||||
if (ob_eval != NULL) {
|
||||
if (ob_eval->type == OB_GPENCIL) {
|
||||
copy_m4_m4(diff_mat, ob_eval->obmat);
|
||||
return;
|
||||
}
|
||||
if ((ob_eval != NULL) && (ob_eval->type == OB_GPENCIL)) {
|
||||
copy_m4_m4(diff_mat, ob_eval->obmat);
|
||||
mul_m4_m4m4(diff_mat, diff_mat, gpl->layer_mat);
|
||||
return;
|
||||
}
|
||||
/* not gpencil object */
|
||||
unit_m4(diff_mat);
|
||||
|
@ -2785,6 +2823,7 @@ void BKE_gpencil_parent_matrix_get(const Depsgraph *depsgraph,
|
|||
if (ELEM(gpl->partype, PAROBJECT, PARSKEL)) {
|
||||
mul_m4_m4m4(diff_mat, obparent_eval->obmat, gpl->inverse);
|
||||
add_v3_v3(diff_mat[3], ob_eval->obmat[3]);
|
||||
mul_m4_m4m4(diff_mat, diff_mat, gpl->layer_mat);
|
||||
return;
|
||||
}
|
||||
if (gpl->partype == PARBONE) {
|
||||
|
@ -2800,6 +2839,7 @@ void BKE_gpencil_parent_matrix_get(const Depsgraph *depsgraph,
|
|||
mul_m4_m4m4(diff_mat, obparent_eval->obmat, gpl->inverse);
|
||||
add_v3_v3(diff_mat[3], ob_eval->obmat[3]);
|
||||
}
|
||||
mul_m4_m4m4(diff_mat, diff_mat, gpl->layer_mat);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -2807,11 +2847,11 @@ void BKE_gpencil_parent_matrix_get(const Depsgraph *depsgraph,
|
|||
}
|
||||
|
||||
/**
|
||||
* Update parent matrix.
|
||||
* Update parent matrix and local transforms.
|
||||
* \param depsgraph: Depsgraph
|
||||
* \param ob: Grease pencil object
|
||||
*/
|
||||
void BKE_gpencil_update_layer_parent(const Depsgraph *depsgraph, Object *ob)
|
||||
void BKE_gpencil_update_layer_transforms(const Depsgraph *depsgraph, Object *ob)
|
||||
{
|
||||
if (ob->type != OB_GPENCIL) {
|
||||
return;
|
||||
|
@ -2820,31 +2860,50 @@ void BKE_gpencil_update_layer_parent(const Depsgraph *depsgraph, Object *ob)
|
|||
bGPdata *gpd = (bGPdata *)ob->data;
|
||||
float cur_mat[4][4];
|
||||
|
||||
bool changed = false;
|
||||
LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) {
|
||||
if ((gpl->parent != NULL) && (gpl->actframe != NULL)) {
|
||||
Object *ob_parent = DEG_get_evaluated_object(depsgraph, gpl->parent);
|
||||
/* calculate new matrix */
|
||||
if (ELEM(gpl->partype, PAROBJECT, PARSKEL)) {
|
||||
copy_m4_m4(cur_mat, ob_parent->obmat);
|
||||
}
|
||||
else if (gpl->partype == PARBONE) {
|
||||
bPoseChannel *pchan = BKE_pose_channel_find_name(ob_parent->pose, gpl->parsubstr);
|
||||
if (pchan != NULL) {
|
||||
copy_m4_m4(cur_mat, ob->imat);
|
||||
mul_m4_m4m4(cur_mat, ob_parent->obmat, pchan->pose_mat);
|
||||
unit_m4(cur_mat);
|
||||
if (gpl->actframe != NULL) {
|
||||
if (gpl->parent != NULL) {
|
||||
Object *ob_parent = DEG_get_evaluated_object(depsgraph, gpl->parent);
|
||||
/* calculate new matrix */
|
||||
if (ELEM(gpl->partype, PAROBJECT, PARSKEL)) {
|
||||
copy_m4_m4(cur_mat, ob_parent->obmat);
|
||||
}
|
||||
else {
|
||||
unit_m4(cur_mat);
|
||||
else if (gpl->partype == PARBONE) {
|
||||
bPoseChannel *pchan = BKE_pose_channel_find_name(ob_parent->pose, gpl->parsubstr);
|
||||
if (pchan != NULL) {
|
||||
copy_m4_m4(cur_mat, ob->imat);
|
||||
mul_m4_m4m4(cur_mat, ob_parent->obmat, pchan->pose_mat);
|
||||
}
|
||||
else {
|
||||
unit_m4(cur_mat);
|
||||
}
|
||||
}
|
||||
changed = !equals_m4m4(gpl->inverse, cur_mat);
|
||||
}
|
||||
|
||||
/* Calc local layer transform. */
|
||||
bool transfomed = ((!is_zero_v3(gpl->location)) || (!is_zero_v3(gpl->rotation)) ||
|
||||
(!is_one_v3(gpl->scale)));
|
||||
if (transfomed) {
|
||||
loc_eul_size_to_mat4(gpl->layer_mat, gpl->location, gpl->rotation, gpl->scale);
|
||||
}
|
||||
|
||||
/* only redo if any change */
|
||||
if (!equals_m4m4(gpl->inverse, cur_mat)) {
|
||||
if (changed || transfomed) {
|
||||
LISTBASE_FOREACH (bGPDstroke *, gps, &gpl->actframe->strokes) {
|
||||
bGPDspoint *pt;
|
||||
int i;
|
||||
for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) {
|
||||
mul_m4_v3(gpl->inverse, &pt->x);
|
||||
mul_m4_v3(cur_mat, &pt->x);
|
||||
if (changed) {
|
||||
mul_m4_v3(gpl->inverse, &pt->x);
|
||||
mul_m4_v3(cur_mat, &pt->x);
|
||||
}
|
||||
|
||||
if (transfomed) {
|
||||
mul_m4_v3(gpl->layer_mat, &pt->x);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -701,13 +701,18 @@ void BKE_gpencil_prepare_eval_data(Depsgraph *depsgraph, Scene *scene, Object *o
|
|||
Object *ob_orig = (Object *)DEG_get_original_id(&ob->id);
|
||||
bGPdata *gpd_orig = (bGPdata *)ob_orig->data;
|
||||
|
||||
/* Need check if some layer is parented. */
|
||||
/* Need check if some layer is parented or transformed. */
|
||||
bool do_parent = false;
|
||||
bool do_transform = false;
|
||||
LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd_orig->layers) {
|
||||
if (gpl->parent != NULL) {
|
||||
do_parent = true;
|
||||
break;
|
||||
}
|
||||
if ((!is_zero_v3(gpl->location)) || (!is_zero_v3(gpl->rotation)) || (!is_one_v3(gpl->scale))) {
|
||||
do_transform = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
const bool is_multiedit = (bool)GPENCIL_MULTIEDIT_SESSIONS_ON(gpd_eval);
|
||||
|
@ -715,7 +720,7 @@ void BKE_gpencil_prepare_eval_data(Depsgraph *depsgraph, Scene *scene, Object *o
|
|||
const bool do_modifiers = (bool)((!is_multiedit) && (!is_curve_edit) &&
|
||||
(ob->greasepencil_modifiers.first != NULL) &&
|
||||
(!GPENCIL_SIMPLIFY_MODIF(scene)));
|
||||
if ((!do_modifiers) && (!do_parent)) {
|
||||
if ((!do_modifiers) && (!do_parent) && (!do_transform)) {
|
||||
return;
|
||||
}
|
||||
DEG_debug_print_eval(depsgraph, __func__, gpd_eval->id.name, gpd_eval);
|
||||
|
|
|
@ -225,7 +225,7 @@ void BKE_object_handle_data_update(Depsgraph *depsgraph, Scene *scene, Object *o
|
|||
case OB_GPENCIL: {
|
||||
BKE_gpencil_prepare_eval_data(depsgraph, scene, ob);
|
||||
BKE_gpencil_modifiers_calc(depsgraph, scene, ob);
|
||||
BKE_gpencil_update_layer_parent(depsgraph, ob);
|
||||
BKE_gpencil_update_layer_transforms(depsgraph, ob);
|
||||
break;
|
||||
}
|
||||
case OB_HAIR:
|
||||
|
|
|
@ -587,15 +587,15 @@ MovieTrackingTrack *BKE_tracking_track_add(MovieTracking *tracking,
|
|||
{
|
||||
const MovieTrackingSettings *settings = &tracking->settings;
|
||||
|
||||
MovieTrackingTrack *track = BKE_tracking_track_add_empty(tracking, tracksbase);
|
||||
MovieTrackingMarker marker;
|
||||
|
||||
const float half_pattern_px = settings->default_pattern_size / 2.0f;
|
||||
const float half_search_px = settings->default_search_size / 2.0f;
|
||||
|
||||
const float pattern_size[2] = {half_pattern_px / width, half_pattern_px / height};
|
||||
const float search_size[2] = {half_search_px / width, half_search_px / height};
|
||||
|
||||
MovieTrackingTrack *track = BKE_tracking_track_add_empty(tracking, tracksbase);
|
||||
|
||||
MovieTrackingMarker marker;
|
||||
memset(&marker, 0, sizeof(marker));
|
||||
marker.pos[0] = x;
|
||||
marker.pos[1] = y;
|
||||
|
@ -665,6 +665,86 @@ void BKE_tracking_track_free(MovieTrackingTrack *track)
|
|||
}
|
||||
}
|
||||
|
||||
/* Get frame numbers of the very first and last markers.
|
||||
* There is no check on whether the marker is enabled or not. */
|
||||
void BKE_tracking_track_first_last_frame_get(const MovieTrackingTrack *track,
|
||||
int *r_first_frame,
|
||||
int *r_last_frame)
|
||||
{
|
||||
BLI_assert(track->markersnr > 0);
|
||||
const int last_marker_index = track->markersnr - 1;
|
||||
*r_first_frame = track->markers[0].framenr;
|
||||
*r_last_frame = track->markers[last_marker_index].framenr;
|
||||
}
|
||||
|
||||
/* Find the minimum starting frame and maximum ending frame within given set of
|
||||
* tracks.
|
||||
*/
|
||||
void BKE_tracking_tracks_first_last_frame_minmax(/*const*/ MovieTrackingTrack **tracks,
|
||||
const int num_tracks,
|
||||
int *r_first_frame,
|
||||
int *r_last_frame)
|
||||
{
|
||||
*r_first_frame = INT_MAX;
|
||||
*r_last_frame = INT_MIN;
|
||||
for (int i = 0; i < num_tracks; ++i) {
|
||||
const struct MovieTrackingTrack *track = tracks[i];
|
||||
int track_first_frame, track_last_frame;
|
||||
BKE_tracking_track_first_last_frame_get(track, &track_first_frame, &track_last_frame);
|
||||
*r_first_frame = min_ii(*r_first_frame, track_first_frame);
|
||||
*r_last_frame = max_ii(*r_last_frame, track_last_frame);
|
||||
}
|
||||
}
|
||||
|
||||
int BKE_tracking_count_selected_tracks_in_list(const ListBase *tracks_list)
|
||||
{
|
||||
int num_selected_tracks = 0;
|
||||
LISTBASE_FOREACH (const MovieTrackingTrack *, track, tracks_list) {
|
||||
if (TRACK_SELECTED(track)) {
|
||||
++num_selected_tracks;
|
||||
}
|
||||
}
|
||||
return num_selected_tracks;
|
||||
}
|
||||
|
||||
int BKE_tracking_count_selected_tracks_in_active_object(/*const*/ MovieTracking *tracking)
|
||||
{
|
||||
ListBase *tracks_list = BKE_tracking_get_active_tracks(tracking);
|
||||
return BKE_tracking_count_selected_tracks_in_list(tracks_list);
|
||||
}
|
||||
|
||||
MovieTrackingTrack **BKE_tracking_selected_tracks_in_active_object(MovieTracking *tracking,
|
||||
int *r_num_tracks)
|
||||
{
|
||||
*r_num_tracks = 0;
|
||||
|
||||
ListBase *tracks_list = BKE_tracking_get_active_tracks(tracking);
|
||||
if (tracks_list == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Initialize input. */
|
||||
const int num_selected_tracks = BKE_tracking_count_selected_tracks_in_active_object(tracking);
|
||||
if (num_selected_tracks == 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
MovieTrackingTrack **source_tracks = MEM_malloc_arrayN(
|
||||
num_selected_tracks, sizeof(MovieTrackingTrack *), "selected tracks array");
|
||||
int source_track_index = 0;
|
||||
LISTBASE_FOREACH (MovieTrackingTrack *, track, tracks_list) {
|
||||
if (!TRACK_SELECTED(track)) {
|
||||
continue;
|
||||
}
|
||||
source_tracks[source_track_index] = track;
|
||||
++source_track_index;
|
||||
}
|
||||
|
||||
*r_num_tracks = num_selected_tracks;
|
||||
|
||||
return source_tracks;
|
||||
}
|
||||
|
||||
/* Set flag for all specified track's areas.
|
||||
*
|
||||
* area - which part of marker should be selected. see TRACK_AREA_* constants.
|
||||
|
@ -918,6 +998,96 @@ void BKE_tracking_tracks_join(MovieTracking *tracking,
|
|||
BKE_tracking_dopesheet_tag_update(tracking);
|
||||
}
|
||||
|
||||
static void accumulate_marker(MovieTrackingMarker *dst_marker,
|
||||
const MovieTrackingMarker *src_marker)
|
||||
{
|
||||
BLI_assert(dst_marker->framenr == src_marker->framenr);
|
||||
|
||||
if (src_marker->flag & MARKER_DISABLED) {
|
||||
return;
|
||||
}
|
||||
|
||||
add_v2_v2(dst_marker->pos, src_marker->pos);
|
||||
for (int corner = 0; corner < 4; ++corner) {
|
||||
add_v2_v2(dst_marker->pattern_corners[corner], src_marker->pattern_corners[corner]);
|
||||
}
|
||||
add_v2_v2(dst_marker->search_min, src_marker->search_min);
|
||||
add_v2_v2(dst_marker->search_max, src_marker->search_max);
|
||||
|
||||
BLI_assert(is_finite_v2(src_marker->search_min));
|
||||
BLI_assert(is_finite_v2(src_marker->search_max));
|
||||
|
||||
dst_marker->flag &= ~MARKER_DISABLED;
|
||||
if ((src_marker->flag & MARKER_TRACKED) == 0) {
|
||||
dst_marker->flag &= ~MARKER_TRACKED;
|
||||
}
|
||||
}
|
||||
|
||||
static void multiply_marker(MovieTrackingMarker *marker, const float multiplier)
|
||||
{
|
||||
mul_v2_fl(marker->pos, multiplier);
|
||||
for (int corner = 0; corner < 4; ++corner) {
|
||||
mul_v2_fl(marker->pattern_corners[corner], multiplier);
|
||||
}
|
||||
mul_v2_fl(marker->search_min, multiplier);
|
||||
mul_v2_fl(marker->search_max, multiplier);
|
||||
}
|
||||
|
||||
void BKE_tracking_tracks_average(MovieTrackingTrack *dst_track,
|
||||
/*const*/ MovieTrackingTrack **src_tracks,
|
||||
const int num_src_tracks)
|
||||
{
|
||||
/* Get global range of frames within which averaging would happen. */
|
||||
int first_frame, last_frame;
|
||||
BKE_tracking_tracks_first_last_frame_minmax(
|
||||
src_tracks, num_src_tracks, &first_frame, &last_frame);
|
||||
if (last_frame < first_frame) {
|
||||
return;
|
||||
}
|
||||
const int num_frames = last_frame - first_frame + 1;
|
||||
|
||||
/* Allocate temporary array where averaging will happen into. */
|
||||
MovieTrackingMarker *accumulator = MEM_calloc_arrayN(
|
||||
num_frames, sizeof(MovieTrackingMarker), "tracks average accumulator");
|
||||
int *counters = MEM_calloc_arrayN(num_frames, sizeof(int), "tracks accumulator counters");
|
||||
for (int frame = first_frame; frame <= last_frame; ++frame) {
|
||||
const int frame_index = frame - first_frame;
|
||||
accumulator[frame_index].framenr = frame;
|
||||
accumulator[frame_index].flag |= (MARKER_DISABLED | MARKER_TRACKED);
|
||||
}
|
||||
|
||||
/* Accumulate track markers. */
|
||||
for (int track_index = 0; track_index < num_src_tracks; ++track_index) {
|
||||
/*const*/ MovieTrackingTrack *track = src_tracks[track_index];
|
||||
for (int frame = first_frame; frame <= last_frame; ++frame) {
|
||||
MovieTrackingMarker interpolated_marker;
|
||||
if (!BKE_tracking_marker_get_interpolated(track, frame, &interpolated_marker)) {
|
||||
continue;
|
||||
}
|
||||
const int frame_index = frame - first_frame;
|
||||
accumulate_marker(&accumulator[frame_index], &interpolated_marker);
|
||||
++counters[frame_index];
|
||||
}
|
||||
}
|
||||
|
||||
/* Average and store the result. */
|
||||
for (int frame = first_frame; frame <= last_frame; ++frame) {
|
||||
/* Average. */
|
||||
const int frame_index = frame - first_frame;
|
||||
if (!counters[frame_index]) {
|
||||
continue;
|
||||
}
|
||||
const float multiplier = 1.0f / (float)counters[frame_index];
|
||||
multiply_marker(&accumulator[frame_index], multiplier);
|
||||
/* Store the result. */
|
||||
BKE_tracking_marker_insert(dst_track, &accumulator[frame_index]);
|
||||
}
|
||||
|
||||
/* Free memory. */
|
||||
MEM_freeN(accumulator);
|
||||
MEM_freeN(counters);
|
||||
}
|
||||
|
||||
MovieTrackingTrack *BKE_tracking_track_get_named(MovieTracking *tracking,
|
||||
MovieTrackingObject *object,
|
||||
const char *name)
|
||||
|
@ -1224,8 +1394,6 @@ MovieTrackingMarker *BKE_tracking_marker_insert(MovieTrackingTrack *track,
|
|||
/* put new marker */
|
||||
track->markers[a + 1] = *marker;
|
||||
|
||||
track->last_marker = a + 1;
|
||||
|
||||
return &track->markers[a + 1];
|
||||
}
|
||||
|
||||
|
@ -1314,51 +1482,45 @@ void BKE_tracking_marker_clamp(MovieTrackingMarker *marker, int event)
|
|||
}
|
||||
}
|
||||
|
||||
/* Get marker closest to the given frame number.
|
||||
*
|
||||
* If there is maker with exact frame number it returned.
|
||||
* Otherwise, marker with higherst frame number but lower than the requested
|
||||
* frame is returned if such marker exists. Otherwise, the marker with lowest
|
||||
* frame number greater than the requested frame number is returned.
|
||||
*
|
||||
* This function has complexity of O(log number_of_markers). */
|
||||
MovieTrackingMarker *BKE_tracking_marker_get(MovieTrackingTrack *track, int framenr)
|
||||
{
|
||||
int a = track->markersnr - 1;
|
||||
const int num_markers = track->markersnr;
|
||||
|
||||
if (!track->markersnr) {
|
||||
if (num_markers == 0) {
|
||||
BLI_assert(!"Detected degenerated track, should never happen.");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* approximate pre-first framenr marker with first marker */
|
||||
if (framenr < track->markers[0].framenr) {
|
||||
return &track->markers[0];
|
||||
}
|
||||
int left_boundary = 0;
|
||||
int right_boundary = num_markers;
|
||||
while (left_boundary < right_boundary) {
|
||||
const int median_index = (left_boundary + right_boundary) / 2;
|
||||
MovieTrackingMarker *marker = &track->markers[median_index];
|
||||
|
||||
if (track->last_marker < track->markersnr) {
|
||||
a = track->last_marker;
|
||||
}
|
||||
|
||||
if (track->markers[a].framenr <= framenr) {
|
||||
while (a < track->markersnr && track->markers[a].framenr <= framenr) {
|
||||
if (track->markers[a].framenr == framenr) {
|
||||
track->last_marker = a;
|
||||
|
||||
return &track->markers[a];
|
||||
}
|
||||
a++;
|
||||
if (marker->framenr == framenr) {
|
||||
return marker;
|
||||
}
|
||||
|
||||
/* if there's no marker for exact position, use nearest marker from left side */
|
||||
return &track->markers[a - 1];
|
||||
}
|
||||
|
||||
while (a >= 0 && track->markers[a].framenr >= framenr) {
|
||||
if (track->markers[a].framenr == framenr) {
|
||||
track->last_marker = a;
|
||||
|
||||
return &track->markers[a];
|
||||
if (marker->framenr < framenr) {
|
||||
left_boundary = median_index + 1;
|
||||
}
|
||||
else {
|
||||
BLI_assert(marker->framenr > framenr);
|
||||
right_boundary = median_index - 1;
|
||||
}
|
||||
|
||||
a--;
|
||||
}
|
||||
|
||||
/* if there's no marker for exact position, use nearest marker from left side */
|
||||
return &track->markers[a];
|
||||
const int closest_index = clamp_i(right_boundary, 0, num_markers - 1);
|
||||
|
||||
return NULL;
|
||||
return &track->markers[closest_index];
|
||||
}
|
||||
|
||||
MovieTrackingMarker *BKE_tracking_marker_get_exact(MovieTrackingTrack *track, int framenr)
|
||||
|
@ -1389,6 +1551,84 @@ MovieTrackingMarker *BKE_tracking_marker_ensure(MovieTrackingTrack *track, int f
|
|||
return marker;
|
||||
}
|
||||
|
||||
static const MovieTrackingMarker *get_usable_marker_for_interpolation(
|
||||
struct MovieTrackingTrack *track,
|
||||
const MovieTrackingMarker *anchor_marker,
|
||||
const int direction)
|
||||
{
|
||||
BLI_assert(direction == -1 || direction == 1);
|
||||
|
||||
const MovieTrackingMarker *last_marker = track->markers + track->markersnr - 1;
|
||||
const MovieTrackingMarker *current_marker = anchor_marker;
|
||||
|
||||
while (current_marker >= track->markers && current_marker <= last_marker) {
|
||||
if ((current_marker->flag & MARKER_DISABLED) == 0) {
|
||||
return current_marker;
|
||||
}
|
||||
current_marker += direction;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bool BKE_tracking_marker_get_interpolated(struct MovieTrackingTrack *track,
|
||||
const int framenr,
|
||||
struct MovieTrackingMarker *r_marker)
|
||||
{
|
||||
const MovieTrackingMarker *closest_marker = BKE_tracking_marker_get(track, framenr);
|
||||
if (closest_marker == NULL) {
|
||||
return false;
|
||||
}
|
||||
if (closest_marker->framenr == framenr && (closest_marker->flag & MARKER_DISABLED) == 0) {
|
||||
*r_marker = *closest_marker;
|
||||
return true;
|
||||
}
|
||||
|
||||
const MovieTrackingMarker *left_marker = get_usable_marker_for_interpolation(
|
||||
track, closest_marker, -1);
|
||||
if (left_marker == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const MovieTrackingMarker *right_marker = get_usable_marker_for_interpolation(
|
||||
track, closest_marker + 1, 1);
|
||||
if (right_marker == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (left_marker == right_marker) {
|
||||
*r_marker = *left_marker;
|
||||
return true;
|
||||
}
|
||||
|
||||
const float factor = (float)(framenr - left_marker->framenr) /
|
||||
(right_marker->framenr - left_marker->framenr);
|
||||
|
||||
interp_v2_v2v2(r_marker->pos, left_marker->pos, right_marker->pos, factor);
|
||||
|
||||
for (int i = 0; i < 4; i++) {
|
||||
interp_v2_v2v2(r_marker->pattern_corners[i],
|
||||
left_marker->pattern_corners[i],
|
||||
right_marker->pattern_corners[i],
|
||||
factor);
|
||||
}
|
||||
|
||||
interp_v2_v2v2(r_marker->search_min, left_marker->search_min, right_marker->search_min, factor);
|
||||
interp_v2_v2v2(r_marker->search_max, left_marker->search_max, right_marker->search_max, factor);
|
||||
|
||||
r_marker->framenr = framenr;
|
||||
r_marker->flag = 0;
|
||||
|
||||
if (framenr == left_marker->framenr) {
|
||||
r_marker->flag = left_marker->flag;
|
||||
}
|
||||
else if (framenr == right_marker->framenr) {
|
||||
r_marker->flag = right_marker->flag;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void BKE_tracking_marker_pattern_minmax(const MovieTrackingMarker *marker,
|
||||
float min[2],
|
||||
float max[2])
|
||||
|
@ -1683,7 +1923,6 @@ MovieTrackingPlaneMarker *BKE_tracking_plane_marker_insert(MovieTrackingPlaneTra
|
|||
|
||||
/* Put new marker to an array. */
|
||||
plane_track->markers[a + 1] = *plane_marker;
|
||||
plane_track->last_marker = a + 1;
|
||||
|
||||
return &plane_track->markers[a + 1];
|
||||
}
|
||||
|
|
|
@ -311,11 +311,7 @@ static void retrieve_next_lower_usable_frame(
|
|||
* translation stabilization, which has an enabled tracking marker at this very
|
||||
* frame. We search both for the next lower and next higher position, to allow
|
||||
* the caller to interpolate gaps and to extrapolate at the ends of the
|
||||
* definition range.
|
||||
*
|
||||
* NOTE: Regarding performance note that the individual tracks will cache the
|
||||
* last search position.
|
||||
*/
|
||||
* definition range. */
|
||||
static void find_next_working_frames(StabContext *ctx,
|
||||
int framenr,
|
||||
int *next_lower,
|
||||
|
|
|
@ -5,15 +5,23 @@
|
|||
#include "DNA_tracking_types.h"
|
||||
|
||||
#include "BKE_tracking.h"
|
||||
#include "BLI_float2.hh"
|
||||
|
||||
namespace blender {
|
||||
|
||||
namespace {
|
||||
|
||||
class TrackingTest : public ::testing::Test {
|
||||
protected:
|
||||
MovieTrackingMarker *addMarkerToTrack(MovieTrackingTrack *track, int frame_number)
|
||||
MovieTrackingMarker *addMarkerToTrack(MovieTrackingTrack *track,
|
||||
int frame_number,
|
||||
const float2 &position = float2(0.0f, 0.0f),
|
||||
int flag = 0)
|
||||
{
|
||||
MovieTrackingMarker marker = {{0.0f}};
|
||||
copy_v2_v2(marker.pos, position);
|
||||
marker.framenr = frame_number;
|
||||
marker.flag = flag;
|
||||
return BKE_tracking_marker_insert(track, &marker);
|
||||
}
|
||||
};
|
||||
|
@ -22,24 +30,58 @@ class TrackingTest : public ::testing::Test {
|
|||
|
||||
TEST_F(TrackingTest, BKE_tracking_marker_get)
|
||||
{
|
||||
MovieTrackingTrack track = {nullptr};
|
||||
|
||||
addMarkerToTrack(&track, 1);
|
||||
addMarkerToTrack(&track, 10);
|
||||
|
||||
{
|
||||
const MovieTrackingMarker *marker = BKE_tracking_marker_get(&track, 1);
|
||||
EXPECT_NE(marker, nullptr);
|
||||
EXPECT_EQ(marker->framenr, 1);
|
||||
MovieTrackingTrack track = {nullptr};
|
||||
|
||||
addMarkerToTrack(&track, 10);
|
||||
|
||||
EXPECT_EQ(BKE_tracking_marker_get(&track, 0), &track.markers[0]);
|
||||
EXPECT_EQ(BKE_tracking_marker_get(&track, 10), &track.markers[0]);
|
||||
EXPECT_EQ(BKE_tracking_marker_get(&track, 20), &track.markers[0]);
|
||||
|
||||
BKE_tracking_track_free(&track);
|
||||
}
|
||||
|
||||
{
|
||||
const MovieTrackingMarker *marker = BKE_tracking_marker_get(&track, 5);
|
||||
EXPECT_NE(marker, nullptr);
|
||||
EXPECT_EQ(marker->framenr, 1);
|
||||
MovieTrackingTrack track = {nullptr};
|
||||
|
||||
addMarkerToTrack(&track, 1);
|
||||
addMarkerToTrack(&track, 10);
|
||||
|
||||
{
|
||||
const MovieTrackingMarker *marker = BKE_tracking_marker_get(&track, 1);
|
||||
EXPECT_NE(marker, nullptr);
|
||||
EXPECT_EQ(marker->framenr, 1);
|
||||
}
|
||||
|
||||
{
|
||||
const MovieTrackingMarker *marker = BKE_tracking_marker_get(&track, 5);
|
||||
EXPECT_NE(marker, nullptr);
|
||||
EXPECT_EQ(marker->framenr, 1);
|
||||
}
|
||||
|
||||
BKE_tracking_track_free(&track);
|
||||
}
|
||||
|
||||
BKE_tracking_track_free(&track);
|
||||
{
|
||||
{
|
||||
MovieTrackingTrack track = {nullptr};
|
||||
|
||||
addMarkerToTrack(&track, 1);
|
||||
addMarkerToTrack(&track, 2);
|
||||
addMarkerToTrack(&track, 10);
|
||||
|
||||
EXPECT_EQ(BKE_tracking_marker_get(&track, 0), &track.markers[0]);
|
||||
EXPECT_EQ(BKE_tracking_marker_get(&track, 1), &track.markers[0]);
|
||||
EXPECT_EQ(BKE_tracking_marker_get(&track, 2), &track.markers[1]);
|
||||
EXPECT_EQ(BKE_tracking_marker_get(&track, 3), &track.markers[1]);
|
||||
EXPECT_EQ(BKE_tracking_marker_get(&track, 9), &track.markers[1]);
|
||||
EXPECT_EQ(BKE_tracking_marker_get(&track, 10), &track.markers[2]);
|
||||
EXPECT_EQ(BKE_tracking_marker_get(&track, 11), &track.markers[2]);
|
||||
|
||||
BKE_tracking_track_free(&track);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(TrackingTest, BKE_tracking_marker_get_exact)
|
||||
|
@ -62,3 +104,107 @@ TEST_F(TrackingTest, BKE_tracking_marker_get_exact)
|
|||
|
||||
BKE_tracking_track_free(&track);
|
||||
}
|
||||
|
||||
TEST_F(TrackingTest, BKE_tracking_marker_get_interpolated)
|
||||
{
|
||||
/* Simple case, no disabled markers in a way. */
|
||||
{
|
||||
MovieTrackingTrack track = {nullptr};
|
||||
|
||||
addMarkerToTrack(&track, 1, float2(1.0f, 5.0f));
|
||||
addMarkerToTrack(&track, 10, float2(2.0f, 1.0f));
|
||||
|
||||
{
|
||||
MovieTrackingMarker interpolated_marker;
|
||||
EXPECT_TRUE(BKE_tracking_marker_get_interpolated(&track, 1, &interpolated_marker));
|
||||
EXPECT_EQ(interpolated_marker.framenr, 1);
|
||||
EXPECT_V2_NEAR(interpolated_marker.pos, float2(1.0f, 5.0f), 1e-6f);
|
||||
}
|
||||
|
||||
{
|
||||
MovieTrackingMarker interpolated_marker;
|
||||
EXPECT_TRUE(BKE_tracking_marker_get_interpolated(&track, 10, &interpolated_marker));
|
||||
EXPECT_EQ(interpolated_marker.framenr, 10);
|
||||
EXPECT_V2_NEAR(interpolated_marker.pos, float2(2.0f, 1.0f), 1e-6f);
|
||||
}
|
||||
|
||||
{
|
||||
MovieTrackingMarker interpolated_marker;
|
||||
EXPECT_TRUE(BKE_tracking_marker_get_interpolated(&track, 4, &interpolated_marker));
|
||||
EXPECT_EQ(interpolated_marker.framenr, 4);
|
||||
EXPECT_V2_NEAR(interpolated_marker.pos, float2(1.3333333f, 3.6666666f), 1e-6f);
|
||||
}
|
||||
|
||||
BKE_tracking_track_free(&track);
|
||||
}
|
||||
|
||||
/* More comprehensive test, which resembles real life trackign scenario better. */
|
||||
{
|
||||
MovieTrackingTrack track = {nullptr};
|
||||
|
||||
addMarkerToTrack(&track, 1, float2(1.0f, 5.0f));
|
||||
addMarkerToTrack(&track, 2, float2(0.0f, 0.0f), MARKER_DISABLED);
|
||||
addMarkerToTrack(&track, 9, float2(0.0f, 0.0f), MARKER_DISABLED);
|
||||
addMarkerToTrack(&track, 10, float2(2.0f, 1.0f));
|
||||
|
||||
{
|
||||
MovieTrackingMarker interpolated_marker;
|
||||
EXPECT_TRUE(BKE_tracking_marker_get_interpolated(&track, 1, &interpolated_marker));
|
||||
EXPECT_EQ(interpolated_marker.framenr, 1);
|
||||
EXPECT_V2_NEAR(interpolated_marker.pos, float2(1.0f, 5.0f), 1e-6f);
|
||||
}
|
||||
|
||||
{
|
||||
MovieTrackingMarker interpolated_marker;
|
||||
EXPECT_TRUE(BKE_tracking_marker_get_interpolated(&track, 10, &interpolated_marker));
|
||||
EXPECT_EQ(interpolated_marker.framenr, 10);
|
||||
EXPECT_V2_NEAR(interpolated_marker.pos, float2(2.0f, 1.0f), 1e-6f);
|
||||
}
|
||||
|
||||
{
|
||||
MovieTrackingMarker interpolated_marker;
|
||||
EXPECT_TRUE(BKE_tracking_marker_get_interpolated(&track, 4, &interpolated_marker));
|
||||
EXPECT_EQ(interpolated_marker.framenr, 4);
|
||||
EXPECT_V2_NEAR(interpolated_marker.pos, float2(1.3333333f, 3.6666666f), 1e-6f);
|
||||
}
|
||||
|
||||
{
|
||||
MovieTrackingMarker interpolated_marker;
|
||||
EXPECT_TRUE(BKE_tracking_marker_get_interpolated(&track, 9, &interpolated_marker));
|
||||
EXPECT_EQ(interpolated_marker.framenr, 9);
|
||||
EXPECT_V2_NEAR(interpolated_marker.pos, float2(1.888888f, 1.4444444f), 1e-6f);
|
||||
}
|
||||
|
||||
BKE_tracking_track_free(&track);
|
||||
}
|
||||
|
||||
/* Tracked/keyframed flag check. */
|
||||
{
|
||||
MovieTrackingTrack track = {nullptr};
|
||||
|
||||
addMarkerToTrack(&track, 1, float2(1.0f, 5.0f), MARKER_TRACKED);
|
||||
addMarkerToTrack(&track, 10, float2(2.0f, 1.0f), MARKER_TRACKED);
|
||||
|
||||
{
|
||||
MovieTrackingMarker interpolated_marker;
|
||||
EXPECT_TRUE(BKE_tracking_marker_get_interpolated(&track, 1, &interpolated_marker));
|
||||
EXPECT_EQ(interpolated_marker.flag, MARKER_TRACKED);
|
||||
}
|
||||
|
||||
{
|
||||
MovieTrackingMarker interpolated_marker;
|
||||
EXPECT_TRUE(BKE_tracking_marker_get_interpolated(&track, 10, &interpolated_marker));
|
||||
EXPECT_EQ(interpolated_marker.flag, MARKER_TRACKED);
|
||||
}
|
||||
|
||||
{
|
||||
MovieTrackingMarker interpolated_marker;
|
||||
EXPECT_TRUE(BKE_tracking_marker_get_interpolated(&track, 4, &interpolated_marker));
|
||||
EXPECT_EQ(interpolated_marker.flag, 0);
|
||||
}
|
||||
|
||||
BKE_tracking_track_free(&track);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace blender
|
||||
|
|
|
@ -1245,20 +1245,6 @@ void blo_do_versions_290(FileData *fd, Library *UNUSED(lib), Main *bmain)
|
|||
part->phystype = PART_PHYS_NO;
|
||||
}
|
||||
}
|
||||
/* Init grease pencil default curve resolution. */
|
||||
if (!DNA_struct_elem_find(fd->filesdna, "bGPdata", "int", "curve_edit_resolution")) {
|
||||
LISTBASE_FOREACH (bGPdata *, gpd, &bmain->gpencils) {
|
||||
gpd->curve_edit_resolution = GP_DEFAULT_CURVE_RESOLUTION;
|
||||
gpd->flag |= GP_DATA_CURVE_ADAPTIVE_RESOLUTION;
|
||||
}
|
||||
}
|
||||
/* Init grease pencil curve editing error threshold. */
|
||||
if (!DNA_struct_elem_find(fd->filesdna, "bGPdata", "float", "curve_edit_threshold")) {
|
||||
LISTBASE_FOREACH (bGPdata *, gpd, &bmain->gpencils) {
|
||||
gpd->curve_edit_threshold = GP_DEFAULT_CURVE_ERROR;
|
||||
gpd->curve_edit_corner_angle = GP_DEFAULT_CURVE_EDIT_CORNER_ANGLE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!MAIN_VERSION_ATLEAST(bmain, 291, 9)) {
|
||||
|
@ -1570,6 +1556,21 @@ void blo_do_versions_290(FileData *fd, Library *UNUSED(lib), Main *bmain)
|
|||
}
|
||||
}
|
||||
FOREACH_NODETREE_END;
|
||||
|
||||
/* Init grease pencil default curve resolution. */
|
||||
if (!DNA_struct_elem_find(fd->filesdna, "bGPdata", "int", "curve_edit_resolution")) {
|
||||
LISTBASE_FOREACH (bGPdata *, gpd, &bmain->gpencils) {
|
||||
gpd->curve_edit_resolution = GP_DEFAULT_CURVE_RESOLUTION;
|
||||
gpd->flag |= GP_DATA_CURVE_ADAPTIVE_RESOLUTION;
|
||||
}
|
||||
}
|
||||
/* Init grease pencil curve editing error threshold. */
|
||||
if (!DNA_struct_elem_find(fd->filesdna, "bGPdata", "float", "curve_edit_threshold")) {
|
||||
LISTBASE_FOREACH (bGPdata *, gpd, &bmain->gpencils) {
|
||||
gpd->curve_edit_threshold = GP_DEFAULT_CURVE_ERROR;
|
||||
gpd->curve_edit_corner_angle = GP_DEFAULT_CURVE_EDIT_CORNER_ANGLE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1588,5 +1589,24 @@ void blo_do_versions_290(FileData *fd, Library *UNUSED(lib), Main *bmain)
|
|||
BKE_brush_default_input_curves_set(br);
|
||||
}
|
||||
}
|
||||
|
||||
/* Grease pencil layer transform matrix. */
|
||||
if (!DNA_struct_elem_find(fd->filesdna, "bGPDlayer", "float", "location[0]")) {
|
||||
LISTBASE_FOREACH (bGPdata *, gpd, &bmain->gpencils) {
|
||||
LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) {
|
||||
zero_v3(gpl->location);
|
||||
zero_v3(gpl->rotation);
|
||||
copy_v3_fl(gpl->scale, 1.0f);
|
||||
loc_eul_size_to_mat4(gpl->layer_mat, gpl->location, gpl->rotation, gpl->scale);
|
||||
invert_m4_m4(gpl->layer_invmat, gpl->layer_mat);
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Fix Fill factor for grease pencil fill brushes. */
|
||||
LISTBASE_FOREACH (Brush *, brush, &bmain->brushes) {
|
||||
if ((brush->gpencil_settings) && (brush->gpencil_settings->fill_factor == 0.0f)) {
|
||||
brush->gpencil_settings->fill_factor = 1.0f;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1712,12 +1712,17 @@ void DepsgraphRelationBuilder::build_world(World *world)
|
|||
/* animation */
|
||||
build_animdata(&world->id);
|
||||
build_parameters(&world->id);
|
||||
|
||||
/* Animated / driven parameters (without nodetree). */
|
||||
OperationKey world_key(&world->id, NodeType::SHADING, OperationCode::WORLD_UPDATE);
|
||||
ComponentKey parameters_key(&world->id, NodeType::PARAMETERS);
|
||||
add_relation(parameters_key, world_key, "World's parameters");
|
||||
|
||||
/* world's nodetree */
|
||||
if (world->nodetree != nullptr) {
|
||||
build_nodetree(world->nodetree);
|
||||
OperationKey ntree_key(
|
||||
&world->nodetree->id, NodeType::SHADING, OperationCode::MATERIAL_UPDATE);
|
||||
OperationKey world_key(&world->id, NodeType::SHADING, OperationCode::WORLD_UPDATE);
|
||||
add_relation(ntree_key, world_key, "World's NTree");
|
||||
build_nested_nodetree(&world->id, world->nodetree);
|
||||
}
|
||||
|
@ -2470,12 +2475,17 @@ void DepsgraphRelationBuilder::build_material(Material *material)
|
|||
/* animation */
|
||||
build_animdata(&material->id);
|
||||
build_parameters(&material->id);
|
||||
|
||||
/* Animated / driven parameters (without nodetree). */
|
||||
OperationKey material_key(&material->id, NodeType::SHADING, OperationCode::MATERIAL_UPDATE);
|
||||
ComponentKey parameters_key(&material->id, NodeType::PARAMETERS);
|
||||
add_relation(parameters_key, material_key, "Material's paramters");
|
||||
|
||||
/* material's nodetree */
|
||||
if (material->nodetree != nullptr) {
|
||||
build_nodetree(material->nodetree);
|
||||
OperationKey ntree_key(
|
||||
&material->nodetree->id, NodeType::SHADING, OperationCode::MATERIAL_UPDATE);
|
||||
OperationKey material_key(&material->id, NodeType::SHADING, OperationCode::MATERIAL_UPDATE);
|
||||
add_relation(ntree_key, material_key, "Material's NTree");
|
||||
build_nested_nodetree(&material->id, material->nodetree);
|
||||
}
|
||||
|
|
|
@ -258,6 +258,16 @@ void OVERLAY_gpencil_cache_init(OVERLAY_Data *vedata)
|
|||
|
||||
copy_m4_m4(mat, ob->obmat);
|
||||
|
||||
/* Rotate and scale except align to cursor. */
|
||||
bGPDlayer *gpl = BKE_gpencil_layer_active_get(gpd);
|
||||
if (gpl != NULL) {
|
||||
if (ts->gp_sculpt.lock_axis != GP_LOCKAXIS_CURSOR) {
|
||||
float matrot[3][3];
|
||||
copy_m3_m4(matrot, gpl->layer_mat);
|
||||
mul_m4_m4m3(mat, mat, matrot);
|
||||
}
|
||||
}
|
||||
|
||||
float viewinv[4][4];
|
||||
/* Set the grid in the selected axis */
|
||||
switch (ts->gp_sculpt.lock_axis) {
|
||||
|
@ -294,6 +304,11 @@ void OVERLAY_gpencil_cache_init(OVERLAY_Data *vedata)
|
|||
mul_v2_v2fl(size, gpd->grid.scale, 2.0f * ED_scene_grid_scale(scene, &grid_unit));
|
||||
rescale_m4(mat, (float[3]){size[0], size[1], 0.0f});
|
||||
|
||||
/* Apply layer loc transform, except cursor mode. */
|
||||
if ((gpl != NULL) && (ts->gpencil_v3d_align & GP_PROJECT_CURSOR) == 0) {
|
||||
add_v3_v3(mat[3], gpl->layer_mat[3]);
|
||||
}
|
||||
|
||||
const int gridlines = (gpd->grid.lines <= 0) ? 1 : gpd->grid.lines;
|
||||
int line_ct = gridlines * 4 + 2;
|
||||
|
||||
|
|
|
@ -800,20 +800,20 @@ static void gpencil_edit_curve_stroke_iter_cb(bGPDlayer *gpl,
|
|||
};
|
||||
|
||||
/* First segment. */
|
||||
copy_v3_v3(vert_ptr->pos, bezt->vec[0]);
|
||||
mul_v3_m4v3(vert_ptr->pos, gpl->layer_mat, bezt->vec[0]);
|
||||
vert_ptr->data = vflag[0];
|
||||
vert_ptr++;
|
||||
|
||||
copy_v3_v3(vert_ptr->pos, bezt->vec[1]);
|
||||
mul_v3_m4v3(vert_ptr->pos, gpl->layer_mat, bezt->vec[1]);
|
||||
vert_ptr->data = vflag[1];
|
||||
vert_ptr++;
|
||||
|
||||
/* Second segment. */
|
||||
copy_v3_v3(vert_ptr->pos, bezt->vec[1]);
|
||||
mul_v3_m4v3(vert_ptr->pos, gpl->layer_mat, bezt->vec[1]);
|
||||
vert_ptr->data = vflag[1];
|
||||
vert_ptr++;
|
||||
|
||||
copy_v3_v3(vert_ptr->pos, bezt->vec[2]);
|
||||
mul_v3_m4v3(vert_ptr->pos, gpl->layer_mat, bezt->vec[2]);
|
||||
vert_ptr->data = vflag[2];
|
||||
vert_ptr++;
|
||||
}
|
||||
|
|
|
@ -1580,6 +1580,7 @@ static int animchannels_rearrange_exec(bContext *C, wmOperator *op)
|
|||
|
||||
/* send notifier that things have changed */
|
||||
WM_event_add_notifier(C, NC_ANIMATION | ND_ANIMCHAN | NA_EDITED, NULL);
|
||||
WM_event_add_notifier(C, NC_ANIMATION | ND_NLA_ORDER, NULL);
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
@ -2900,6 +2901,7 @@ static int animchannels_rename_invoke(bContext *C, wmOperator *UNUSED(op), const
|
|||
|
||||
/* handle click */
|
||||
if (rename_anim_channels(&ac, channel_index)) {
|
||||
WM_event_add_notifier(C, NC_ANIMATION | ND_ANIMCHAN | NA_RENAME, NULL);
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
|
|
|
@ -55,6 +55,21 @@
|
|||
/* ********************************************** */
|
||||
/* Bone Groups */
|
||||
|
||||
static bool pose_group_poll(bContext *C)
|
||||
{
|
||||
if (!ED_operator_posemode_context(C)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Object *obpose = ED_pose_object_from_context(C);
|
||||
if ((obpose->proxy != NULL) || (obpose->proxy_group != NULL) || ID_IS_OVERRIDE_LIBRARY(obpose)) {
|
||||
CTX_wm_operator_poll_msg_set(C, "Cannot edit bonegroups for proxies or library overrides");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static int pose_group_add_exec(bContext *C, wmOperator *UNUSED(op))
|
||||
{
|
||||
Object *ob = ED_pose_object_from_context(C);
|
||||
|
@ -82,7 +97,7 @@ void POSE_OT_group_add(wmOperatorType *ot)
|
|||
|
||||
/* api callbacks */
|
||||
ot->exec = pose_group_add_exec;
|
||||
ot->poll = ED_operator_posemode_context;
|
||||
ot->poll = pose_group_poll;
|
||||
|
||||
/* flags */
|
||||
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
|
||||
|
@ -116,7 +131,7 @@ void POSE_OT_group_remove(wmOperatorType *ot)
|
|||
|
||||
/* api callbacks */
|
||||
ot->exec = pose_group_remove_exec;
|
||||
ot->poll = ED_operator_posemode_context;
|
||||
ot->poll = pose_group_poll;
|
||||
|
||||
/* flags */
|
||||
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
|
||||
|
@ -233,7 +248,7 @@ void POSE_OT_group_assign(wmOperatorType *ot)
|
|||
/* api callbacks */
|
||||
ot->invoke = pose_groups_menu_invoke;
|
||||
ot->exec = pose_group_assign_exec;
|
||||
ot->poll = ED_operator_posemode_context;
|
||||
ot->poll = pose_group_poll;
|
||||
|
||||
/* flags */
|
||||
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
|
||||
|
@ -281,7 +296,7 @@ void POSE_OT_group_unassign(wmOperatorType *ot)
|
|||
|
||||
/* api callbacks */
|
||||
ot->exec = pose_group_unassign_exec;
|
||||
ot->poll = ED_operator_posemode_context;
|
||||
ot->poll = pose_group_poll;
|
||||
|
||||
/* flags */
|
||||
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
|
||||
|
@ -346,7 +361,7 @@ void POSE_OT_group_move(wmOperatorType *ot)
|
|||
|
||||
/* api callbacks */
|
||||
ot->exec = group_move_exec;
|
||||
ot->poll = ED_operator_posemode_context;
|
||||
ot->poll = pose_group_poll;
|
||||
|
||||
/* flags */
|
||||
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
|
||||
|
@ -437,7 +452,7 @@ void POSE_OT_group_sort(wmOperatorType *ot)
|
|||
|
||||
/* api callbacks */
|
||||
ot->exec = group_sort_exec;
|
||||
ot->poll = ED_operator_posemode_context;
|
||||
ot->poll = pose_group_poll;
|
||||
|
||||
/* flags */
|
||||
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
|
||||
|
|
|
@ -934,6 +934,18 @@ static void pchan_clear_scale(bPoseChannel *pchan)
|
|||
pchan->scale_in_x = pchan->scale_in_y = 1.0f;
|
||||
pchan->scale_out_x = pchan->scale_out_y = 1.0f;
|
||||
}
|
||||
/* Clear the scale. When X-mirror is enabled,
|
||||
* also clear the scale of the mirrored pose channel. */
|
||||
static void pchan_clear_scale_with_mirrored(const bPose *pose, bPoseChannel *pchan)
|
||||
{
|
||||
if (pose->flag & POSE_MIRROR_EDIT) {
|
||||
bPoseChannel *pchan_mirror = BKE_pose_channel_get_mirrored(pose, pchan->name);
|
||||
if (pchan_mirror != NULL) {
|
||||
pchan_clear_scale(pchan_mirror);
|
||||
}
|
||||
}
|
||||
pchan_clear_scale(pchan);
|
||||
}
|
||||
|
||||
/* clear location of pose-channel */
|
||||
static void pchan_clear_loc(bPoseChannel *pchan)
|
||||
|
@ -948,6 +960,18 @@ static void pchan_clear_loc(bPoseChannel *pchan)
|
|||
pchan->loc[2] = 0.0f;
|
||||
}
|
||||
}
|
||||
/* Clear the Location. When X-mirror is enabled,
|
||||
* also clear the location of the mirrored pose channel. */
|
||||
static void pchan_clear_loc_with_mirrored(const bPose *pose, bPoseChannel *pchan)
|
||||
{
|
||||
if (pose->flag & POSE_MIRROR_EDIT) {
|
||||
bPoseChannel *pchan_mirror = BKE_pose_channel_get_mirrored(pose, pchan->name);
|
||||
if (pchan_mirror != NULL) {
|
||||
pchan_clear_loc(pchan_mirror);
|
||||
}
|
||||
}
|
||||
pchan_clear_loc(pchan);
|
||||
}
|
||||
|
||||
/* clear rotation of pose-channel */
|
||||
static void pchan_clear_rot(bPoseChannel *pchan)
|
||||
|
@ -1075,13 +1099,25 @@ static void pchan_clear_rot(bPoseChannel *pchan)
|
|||
pchan->curve_out_x = 0.0f;
|
||||
pchan->curve_out_y = 0.0f;
|
||||
}
|
||||
/* Clear the rotation. When X-mirror is enabled,
|
||||
* also clear the rotation of the mirrored pose channel. */
|
||||
static void pchan_clear_rot_with_mirrored(const bPose *pose, bPoseChannel *pchan)
|
||||
{
|
||||
if (pose->flag & POSE_MIRROR_EDIT) {
|
||||
bPoseChannel *pchan_mirror = BKE_pose_channel_get_mirrored(pose, pchan->name);
|
||||
if (pchan_mirror != NULL) {
|
||||
pchan_clear_rot(pchan_mirror);
|
||||
}
|
||||
}
|
||||
pchan_clear_rot(pchan);
|
||||
}
|
||||
|
||||
/* clear loc/rot/scale of pose-channel */
|
||||
static void pchan_clear_transforms(bPoseChannel *pchan)
|
||||
static void pchan_clear_transforms(const bPose *pose, bPoseChannel *pchan)
|
||||
{
|
||||
pchan_clear_loc(pchan);
|
||||
pchan_clear_rot(pchan);
|
||||
pchan_clear_scale(pchan);
|
||||
pchan_clear_loc_with_mirrored(pose, pchan);
|
||||
pchan_clear_rot_with_mirrored(pose, pchan);
|
||||
pchan_clear_scale_with_mirrored(pose, pchan);
|
||||
}
|
||||
|
||||
/* --------------- */
|
||||
|
@ -1089,7 +1125,7 @@ static void pchan_clear_transforms(bPoseChannel *pchan)
|
|||
/* generic exec for clear-pose operators */
|
||||
static int pose_clear_transform_generic_exec(bContext *C,
|
||||
wmOperator *op,
|
||||
void (*clear_func)(bPoseChannel *),
|
||||
void (*clear_func)(const bPose *, bPoseChannel *),
|
||||
const char default_ksName[])
|
||||
{
|
||||
Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
|
||||
|
@ -1115,7 +1151,7 @@ static int pose_clear_transform_generic_exec(bContext *C,
|
|||
|
||||
FOREACH_PCHAN_SELECTED_IN_OBJECT_BEGIN (ob_iter, pchan) {
|
||||
/* run provided clearing function */
|
||||
clear_func(pchan);
|
||||
clear_func(ob_iter->pose, pchan);
|
||||
changed = true;
|
||||
|
||||
/* do auto-keyframing as appropriate */
|
||||
|
@ -1129,7 +1165,7 @@ static int pose_clear_transform_generic_exec(bContext *C,
|
|||
|
||||
#if 1 /* XXX: Ugly Hack - Run clearing function on evaluated copy of pchan */
|
||||
bPoseChannel *pchan_eval = BKE_pose_channel_find_name(ob_eval->pose, pchan->name);
|
||||
clear_func(pchan_eval);
|
||||
clear_func(ob_iter->pose, pchan_eval);
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
|
@ -1175,7 +1211,8 @@ static int pose_clear_transform_generic_exec(bContext *C,
|
|||
|
||||
static int pose_clear_scale_exec(bContext *C, wmOperator *op)
|
||||
{
|
||||
return pose_clear_transform_generic_exec(C, op, pchan_clear_scale, ANIM_KS_SCALING_ID);
|
||||
return pose_clear_transform_generic_exec(
|
||||
C, op, pchan_clear_scale_with_mirrored, ANIM_KS_SCALING_ID);
|
||||
}
|
||||
|
||||
void POSE_OT_scale_clear(wmOperatorType *ot)
|
||||
|
@ -1195,7 +1232,8 @@ void POSE_OT_scale_clear(wmOperatorType *ot)
|
|||
|
||||
static int pose_clear_rot_exec(bContext *C, wmOperator *op)
|
||||
{
|
||||
return pose_clear_transform_generic_exec(C, op, pchan_clear_rot, ANIM_KS_ROTATION_ID);
|
||||
return pose_clear_transform_generic_exec(
|
||||
C, op, pchan_clear_rot_with_mirrored, ANIM_KS_ROTATION_ID);
|
||||
}
|
||||
|
||||
void POSE_OT_rot_clear(wmOperatorType *ot)
|
||||
|
@ -1215,7 +1253,8 @@ void POSE_OT_rot_clear(wmOperatorType *ot)
|
|||
|
||||
static int pose_clear_loc_exec(bContext *C, wmOperator *op)
|
||||
{
|
||||
return pose_clear_transform_generic_exec(C, op, pchan_clear_loc, ANIM_KS_LOCATION_ID);
|
||||
return pose_clear_transform_generic_exec(
|
||||
C, op, pchan_clear_loc_with_mirrored, ANIM_KS_LOCATION_ID);
|
||||
}
|
||||
|
||||
void POSE_OT_loc_clear(wmOperatorType *ot)
|
||||
|
|
|
@ -80,6 +80,9 @@ typedef struct SnapGizmo3D {
|
|||
#endif
|
||||
int use_snap_override;
|
||||
short snap_elem;
|
||||
|
||||
/** Enabled when snap is activated, even if it didn't find anything. */
|
||||
bool is_enabled;
|
||||
} SnapGizmo3D;
|
||||
|
||||
/* Checks if the current event is different from the one captured in the last update. */
|
||||
|
@ -284,6 +287,12 @@ void ED_gizmotypes_snap_3d_toggle_clear(wmGizmo *gz)
|
|||
snap_gizmo->use_snap_override = -1;
|
||||
}
|
||||
|
||||
bool ED_gizmotypes_snap_3d_is_enabled(wmGizmo *gz)
|
||||
{
|
||||
SnapGizmo3D *snap_gizmo = (SnapGizmo3D *)gz;
|
||||
return snap_gizmo->is_enabled;
|
||||
}
|
||||
|
||||
short ED_gizmotypes_snap_3d_update(wmGizmo *gz,
|
||||
struct Depsgraph *depsgraph,
|
||||
const ARegion *region,
|
||||
|
@ -294,6 +303,8 @@ short ED_gizmotypes_snap_3d_update(wmGizmo *gz,
|
|||
float r_nor[3])
|
||||
{
|
||||
SnapGizmo3D *snap_gizmo = (SnapGizmo3D *)gz;
|
||||
snap_gizmo->is_enabled = false;
|
||||
|
||||
if (snap_gizmo->use_snap_override != -1) {
|
||||
if (snap_gizmo->use_snap_override == false) {
|
||||
snap_gizmo->snap_elem = 0;
|
||||
|
@ -318,6 +329,8 @@ short ED_gizmotypes_snap_3d_update(wmGizmo *gz,
|
|||
}
|
||||
#endif
|
||||
|
||||
snap_gizmo->is_enabled = true;
|
||||
|
||||
float co[3], no[3];
|
||||
short snap_elem = 0;
|
||||
int snap_elem_index[3] = {-1, -1, -1};
|
||||
|
|
|
@ -178,7 +178,7 @@ static void gpencil_strokepoint_convertcoords(bContext *C,
|
|||
|
||||
/* apply parent transform */
|
||||
float fpt[3];
|
||||
BKE_gpencil_parent_matrix_get(depsgraph, obact, gpl, diff_mat);
|
||||
BKE_gpencil_layer_transform_matrix_get(depsgraph, obact, gpl, diff_mat);
|
||||
mul_v3_m4v3(fpt, diff_mat, &source_pt->x);
|
||||
copy_v3_v3(&pt->x, fpt);
|
||||
|
||||
|
|
|
@ -1560,7 +1560,7 @@ static int gpencil_stroke_arrange_exec(bContext *C, wmOperator *op)
|
|||
continue;
|
||||
}
|
||||
/* check if the color is editable */
|
||||
if (ED_gpencil_stroke_color_use(ob, gpl, gps) == false) {
|
||||
if (ED_gpencil_stroke_material_editable(ob, gpl, gps) == false) {
|
||||
continue;
|
||||
}
|
||||
/* some stroke is already at front*/
|
||||
|
@ -1725,7 +1725,7 @@ static int gpencil_stroke_change_color_exec(bContext *C, wmOperator *op)
|
|||
continue;
|
||||
}
|
||||
/* check if the color is editable */
|
||||
if (ED_gpencil_stroke_color_use(ob, gpl, gps) == false) {
|
||||
if (ED_gpencil_stroke_material_editable(ob, gpl, gps) == false) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -2854,7 +2854,7 @@ int ED_gpencil_join_objects_exec(bContext *C, wmOperator *op)
|
|||
float inverse_diff_mat[4][4];
|
||||
|
||||
/* recalculate all stroke points */
|
||||
BKE_gpencil_parent_matrix_get(depsgraph, ob_iter, gpl_src, diff_mat);
|
||||
BKE_gpencil_layer_transform_matrix_get(depsgraph, ob_iter, gpl_src, diff_mat);
|
||||
invert_m4_m4_safe_ortho(inverse_diff_mat, diff_mat);
|
||||
|
||||
Material *ma_src = NULL;
|
||||
|
@ -3388,7 +3388,7 @@ static int gpencil_material_select_exec(bContext *C, wmOperator *op)
|
|||
continue;
|
||||
}
|
||||
/* check if the color is editable */
|
||||
if (ED_gpencil_stroke_color_use(ob, gpl, gps) == false) {
|
||||
if (ED_gpencil_stroke_material_editable(ob, gpl, gps) == false) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
|
@ -1867,7 +1867,7 @@ static int gpencil_move_to_layer_exec(bContext *C, wmOperator *op)
|
|||
}
|
||||
|
||||
/* Check if the color is editable. */
|
||||
if (ED_gpencil_stroke_color_use(ob, gpl, gps) == false) {
|
||||
if (ED_gpencil_stroke_material_editable(ob, gpl, gps) == false) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -2610,7 +2610,7 @@ static int gpencil_delete_selected_points(bContext *C)
|
|||
continue;
|
||||
}
|
||||
/* check if the color is editable */
|
||||
if (ED_gpencil_stroke_color_use(ob, gpl, gps) == false) {
|
||||
if (ED_gpencil_stroke_material_editable(ob, gpl, gps) == false) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -2800,7 +2800,7 @@ static int gpencil_snap_to_grid(bContext *C, wmOperator *UNUSED(op))
|
|||
float diff_mat[4][4];
|
||||
|
||||
/* calculate difference matrix object */
|
||||
BKE_gpencil_parent_matrix_get(depsgraph, obact, gpl, diff_mat);
|
||||
BKE_gpencil_layer_transform_matrix_get(depsgraph, obact, gpl, diff_mat);
|
||||
|
||||
LISTBASE_FOREACH (bGPDstroke *, gps, &gpf->strokes) {
|
||||
/* skip strokes that are invalid for current view */
|
||||
|
@ -2808,7 +2808,7 @@ static int gpencil_snap_to_grid(bContext *C, wmOperator *UNUSED(op))
|
|||
continue;
|
||||
}
|
||||
/* check if the color is editable */
|
||||
if (ED_gpencil_stroke_color_use(obact, gpl, gps) == false) {
|
||||
if (ED_gpencil_stroke_material_editable(obact, gpl, gps) == false) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -2935,7 +2935,7 @@ static int gpencil_snap_to_cursor(bContext *C, wmOperator *op)
|
|||
float diff_mat[4][4];
|
||||
|
||||
/* calculate difference matrix */
|
||||
BKE_gpencil_parent_matrix_get(depsgraph, obact, gpl, diff_mat);
|
||||
BKE_gpencil_layer_transform_matrix_get(depsgraph, obact, gpl, diff_mat);
|
||||
|
||||
LISTBASE_FOREACH (bGPDstroke *, gps, &gpf->strokes) {
|
||||
bGPDspoint *pt;
|
||||
|
@ -2946,7 +2946,7 @@ static int gpencil_snap_to_cursor(bContext *C, wmOperator *op)
|
|||
continue;
|
||||
}
|
||||
/* check if the color is editable */
|
||||
if (ED_gpencil_stroke_color_use(obact, gpl, gps) == false) {
|
||||
if (ED_gpencil_stroke_material_editable(obact, gpl, gps) == false) {
|
||||
continue;
|
||||
}
|
||||
/* only continue if this stroke is selected (editable doesn't guarantee this)... */
|
||||
|
@ -3039,7 +3039,7 @@ static bool gpencil_stroke_points_centroid(Depsgraph *depsgraph,
|
|||
float diff_mat[4][4];
|
||||
|
||||
/* calculate difference matrix */
|
||||
BKE_gpencil_parent_matrix_get(depsgraph, obact, gpl, diff_mat);
|
||||
BKE_gpencil_layer_transform_matrix_get(depsgraph, obact, gpl, diff_mat);
|
||||
|
||||
LISTBASE_FOREACH (bGPDstroke *, gps, &gpf->strokes) {
|
||||
bGPDspoint *pt;
|
||||
|
@ -3050,7 +3050,7 @@ static bool gpencil_stroke_points_centroid(Depsgraph *depsgraph,
|
|||
continue;
|
||||
}
|
||||
/* check if the color is editable */
|
||||
if (ED_gpencil_stroke_color_use(obact, gpl, gps) == false) {
|
||||
if (ED_gpencil_stroke_material_editable(obact, gpl, gps) == false) {
|
||||
continue;
|
||||
}
|
||||
/* only continue if this stroke is selected (editable doesn't guarantee this)... */
|
||||
|
@ -3565,7 +3565,7 @@ static int gpencil_stroke_join_exec(bContext *C, wmOperator *op)
|
|||
continue;
|
||||
}
|
||||
/* check if the color is editable. */
|
||||
if (ED_gpencil_stroke_color_use(ob, gpl, gps) == false) {
|
||||
if (ED_gpencil_stroke_material_editable(ob, gpl, gps) == false) {
|
||||
continue;
|
||||
}
|
||||
elem = &strokes_list[tot_strokes];
|
||||
|
@ -3697,7 +3697,7 @@ static int gpencil_stroke_flip_exec(bContext *C, wmOperator *op)
|
|||
continue;
|
||||
}
|
||||
/* check if the color is editable */
|
||||
if (ED_gpencil_stroke_color_use(ob, gpl, gps) == false) {
|
||||
if (ED_gpencil_stroke_material_editable(ob, gpl, gps) == false) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -4516,7 +4516,7 @@ static int gpencil_stroke_separate_exec(bContext *C, wmOperator *op)
|
|||
continue;
|
||||
}
|
||||
/* check if the color is editable */
|
||||
if (ED_gpencil_stroke_color_use(ob, gpl, gps) == false) {
|
||||
if (ED_gpencil_stroke_material_editable(ob, gpl, gps) == false) {
|
||||
continue;
|
||||
}
|
||||
/* Separate selected strokes. */
|
||||
|
@ -4717,7 +4717,7 @@ static int gpencil_stroke_split_exec(bContext *C, wmOperator *op)
|
|||
continue;
|
||||
}
|
||||
/* check if the color is editable */
|
||||
if (ED_gpencil_stroke_color_use(ob, gpl, gps) == false) {
|
||||
if (ED_gpencil_stroke_material_editable(ob, gpl, gps) == false) {
|
||||
continue;
|
||||
}
|
||||
/* Split selected strokes. */
|
||||
|
|
|
@ -263,14 +263,14 @@ static void gpencil_draw_datablock(tGPDfill *tgpf, const float ink[4])
|
|||
BLI_assert(gpl_active_index >= 0);
|
||||
|
||||
LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) {
|
||||
/* calculate parent position */
|
||||
BKE_gpencil_parent_matrix_get(tgpw.depsgraph, ob, gpl, tgpw.diff_mat);
|
||||
|
||||
/* do not draw layer if hidden */
|
||||
if (gpl->flag & GP_LAYER_HIDE) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* calculate parent position */
|
||||
BKE_gpencil_layer_transform_matrix_get(tgpw.depsgraph, ob, gpl, tgpw.diff_mat);
|
||||
|
||||
/* Decide if the strokes of layers are included or not depending on the layer mode.
|
||||
* Cannot skip the layer because it can use boundary strokes and must be used. */
|
||||
bool skip = false;
|
||||
|
@ -1275,7 +1275,7 @@ static void gpencil_stroke_from_buffer(tGPDfill *tgpf)
|
|||
float origin[3];
|
||||
ED_gpencil_drawing_reference_get(tgpf->scene, tgpf->ob, ts->gpencil_v3d_align, origin);
|
||||
ED_gpencil_project_stroke_to_plane(
|
||||
tgpf->scene, tgpf->ob, tgpf->rv3d, gps, origin, tgpf->lock_axis - 1);
|
||||
tgpf->scene, tgpf->ob, tgpf->rv3d, tgpf->gpl, gps, origin, tgpf->lock_axis - 1);
|
||||
}
|
||||
|
||||
/* if parented change position relative to parent object */
|
||||
|
|
|
@ -667,7 +667,8 @@ struct GP_EditableStrokes_Iter {
|
|||
bGPDframe *init_gpf_ = (is_multiedit_) ? gpl->frames.first : gpl->actframe; \
|
||||
for (bGPDframe *gpf_ = init_gpf_; gpf_; gpf_ = gpf_->next) { \
|
||||
if ((gpf_ == gpl->actframe) || ((gpf_->flag & GP_FRAME_SELECT) && is_multiedit_)) { \
|
||||
BKE_gpencil_parent_matrix_get(depsgraph_, obact_, gpl, gpstroke_iter.diff_mat); \
|
||||
BKE_gpencil_layer_transform_matrix_get( \
|
||||
depsgraph_, obact_, gpl, gpstroke_iter.diff_mat); \
|
||||
invert_m4_m4(gpstroke_iter.inverse_diff_mat, gpstroke_iter.diff_mat); \
|
||||
/* loop over strokes */ \
|
||||
bGPDstroke *gpsn_; \
|
||||
|
@ -678,7 +679,7 @@ struct GP_EditableStrokes_Iter {
|
|||
continue; \
|
||||
} \
|
||||
/* check if the color is editable */ \
|
||||
if (ED_gpencil_stroke_color_use(obact_, gpl, gps) == false) { \
|
||||
if (ED_gpencil_stroke_material_editable(obact_, gpl, gps) == false) { \
|
||||
continue; \
|
||||
} \
|
||||
/* ... Do Stuff With Strokes ... */
|
||||
|
@ -718,7 +719,8 @@ struct GP_EditableStrokes_Iter {
|
|||
bGPDframe *init_gpf_ = (is_multiedit_) ? gpl->frames.first : gpl->actframe; \
|
||||
for (bGPDframe *gpf_ = init_gpf_; gpf_; gpf_ = gpf_->next) { \
|
||||
if ((gpf_ == gpl->actframe) || ((gpf_->flag & GP_FRAME_SELECT) && is_multiedit_)) { \
|
||||
BKE_gpencil_parent_matrix_get(depsgraph_, obact_, gpl, gpstroke_iter.diff_mat); \
|
||||
BKE_gpencil_layer_transform_matrix_get( \
|
||||
depsgraph_, obact_, gpl, gpstroke_iter.diff_mat); \
|
||||
invert_m4_m4(gpstroke_iter.inverse_diff_mat, gpstroke_iter.diff_mat); \
|
||||
/* loop over strokes */ \
|
||||
bGPDstroke *gpsn_; \
|
||||
|
@ -767,8 +769,10 @@ struct GP_EditableStrokes_Iter {
|
|||
bGPDframe *init_gpf_ = (is_multiedit_) ? gpl->frames.first : gpl->actframe; \
|
||||
for (bGPDframe *gpf_ = init_gpf_; gpf_; gpf_ = gpf_->next) { \
|
||||
if ((gpf_ == gpl->actframe) || ((gpf_->flag & GP_FRAME_SELECT) && is_multiedit_)) { \
|
||||
BKE_gpencil_parent_matrix_get(depsgraph_, obact_, gpl, gpstroke_iter.diff_mat); \
|
||||
invert_m4_m4(gpstroke_iter.inverse_diff_mat, gpstroke_iter.diff_mat); \
|
||||
BKE_gpencil_layer_transform_matrix_get( \
|
||||
depsgraph_, obact_, gpl, gpstroke_iter.diff_mat); \
|
||||
/* Undo layer transform. */ \
|
||||
mul_m4_m4m4(gpstroke_iter.diff_mat, gpstroke_iter.diff_mat, gpl->layer_invmat); \
|
||||
/* loop over strokes */ \
|
||||
LISTBASE_FOREACH (bGPDstroke *, gps, &gpf_->strokes) { \
|
||||
/* skip strokes that are invalid for current view */ \
|
||||
|
@ -776,7 +780,7 @@ struct GP_EditableStrokes_Iter {
|
|||
continue; \
|
||||
} \
|
||||
/* check if the color is editable */ \
|
||||
if (ED_gpencil_stroke_color_use(obact_, gpl, gps) == false) { \
|
||||
if (ED_gpencil_stroke_material_editable(obact_, gpl, gps) == false) { \
|
||||
continue; \
|
||||
} \
|
||||
/* ... Do Stuff With Strokes ... */
|
||||
|
|
|
@ -229,7 +229,7 @@ static bool gpencil_interpolate_check_todo(bContext *C, bGPdata *gpd)
|
|||
continue;
|
||||
}
|
||||
/* check if the color is editable */
|
||||
if (ED_gpencil_stroke_color_use(ob, gpl, gps_from) == false) {
|
||||
if (ED_gpencil_stroke_material_editable(ob, gpl, gps_from) == false) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -315,7 +315,7 @@ static void gpencil_interpolate_set_points(bContext *C, tGPDinterpolate *tgpi)
|
|||
}
|
||||
|
||||
/* check if the color is editable */
|
||||
if (ED_gpencil_stroke_color_use(ob, tgpil->gpl, gps_from) == false) {
|
||||
if (ED_gpencil_stroke_material_editable(ob, tgpil->gpl, gps_from) == false) {
|
||||
valid = false;
|
||||
}
|
||||
|
||||
|
@ -1038,7 +1038,7 @@ static int gpencil_interpolate_seq_exec(bContext *C, wmOperator *op)
|
|||
continue;
|
||||
}
|
||||
/* check if the color is editable */
|
||||
if (ED_gpencil_stroke_color_use(ob, gpl, gps_from) == false) {
|
||||
if (ED_gpencil_stroke_material_editable(ob, gpl, gps_from) == false) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
|
@ -426,7 +426,7 @@ static void gpencil_reproject_toplane(tGPsdata *p, bGPDstroke *gps)
|
|||
|
||||
/* get drawing origin */
|
||||
gpencil_get_3d_reference(p, origin);
|
||||
ED_gpencil_project_stroke_to_plane(p->scene, obact, rv3d, gps, origin, p->lock_axis - 1);
|
||||
ED_gpencil_project_stroke_to_plane(p->scene, obact, rv3d, p->gpl, gps, origin, p->lock_axis - 1);
|
||||
}
|
||||
|
||||
/* convert screen-coordinates to buffer-coordinates */
|
||||
|
@ -887,11 +887,13 @@ static short gpencil_stroke_addpoint(tGPsdata *p,
|
|||
gpencil_get_3d_reference(p, origin);
|
||||
/* reproject current */
|
||||
ED_gpencil_tpoint_to_point(p->region, origin, pt, &spt);
|
||||
ED_gpencil_project_point_to_plane(p->scene, obact, rv3d, origin, p->lock_axis - 1, &spt);
|
||||
ED_gpencil_project_point_to_plane(
|
||||
p->scene, obact, p->gpl, rv3d, origin, p->lock_axis - 1, &spt);
|
||||
|
||||
/* reproject previous */
|
||||
ED_gpencil_tpoint_to_point(p->region, origin, ptb, &spt2);
|
||||
ED_gpencil_project_point_to_plane(p->scene, obact, rv3d, origin, p->lock_axis - 1, &spt2);
|
||||
ED_gpencil_project_point_to_plane(
|
||||
p->scene, obact, p->gpl, rv3d, origin, p->lock_axis - 1, &spt2);
|
||||
p->totpixlen += len_v3v3(&spt.x, &spt2.x);
|
||||
pt->uv_fac = p->totpixlen;
|
||||
}
|
||||
|
@ -1349,7 +1351,7 @@ static bool gpencil_stroke_eraser_is_occluded(tGPsdata *p,
|
|||
|
||||
float diff_mat[4][4];
|
||||
/* calculate difference matrix if parent object */
|
||||
BKE_gpencil_parent_matrix_get(p->depsgraph, obact, gpl, diff_mat);
|
||||
BKE_gpencil_layer_transform_matrix_get(p->depsgraph, obact, gpl, diff_mat);
|
||||
|
||||
if (ED_view3d_autodist_simple(p->region, mval_i, mval_3d, 0, NULL)) {
|
||||
const float depth_mval = view3d_point_depth(rv3d, mval_3d);
|
||||
|
@ -1731,12 +1733,12 @@ static void gpencil_stroke_doeraser(tGPsdata *p)
|
|||
continue;
|
||||
}
|
||||
/* calculate difference matrix */
|
||||
BKE_gpencil_parent_matrix_get(p->depsgraph, p->ob, gpl, p->diff_mat);
|
||||
BKE_gpencil_layer_transform_matrix_get(p->depsgraph, p->ob, gpl, p->diff_mat);
|
||||
|
||||
/* loop over strokes, checking segments for intersections */
|
||||
LISTBASE_FOREACH_MUTABLE (bGPDstroke *, gps, &gpf->strokes) {
|
||||
/* check if the color is editable */
|
||||
if (ED_gpencil_stroke_color_use(p->ob, gpl, gps) == false) {
|
||||
if (ED_gpencil_stroke_material_editable(p->ob, gpl, gps) == false) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -2103,6 +2105,11 @@ static void gpencil_paint_initstroke(tGPsdata *p,
|
|||
copy_v3_v3(p->gpl->color, p->custom_color);
|
||||
}
|
||||
}
|
||||
|
||||
/* Recalculate layer transform matrix to avoid problems if props are animated. */
|
||||
loc_eul_size_to_mat4(p->gpl->layer_mat, p->gpl->location, p->gpl->rotation, p->gpl->scale);
|
||||
invert_m4_m4(p->gpl->layer_invmat, p->gpl->layer_mat);
|
||||
|
||||
if ((paintmode != GP_PAINTMODE_ERASER) && (p->gpl->flag & GP_LAYER_LOCKED)) {
|
||||
p->status = GP_STATUS_ERROR;
|
||||
if (G.debug & G_DEBUG) {
|
||||
|
|
|
@ -317,6 +317,10 @@ static void gpencil_primitive_set_initdata(bContext *C, tGPDprimitive *tgpi)
|
|||
}
|
||||
tgpi->gpl = gpl;
|
||||
|
||||
/* Recalculate layer transform matrix to avoid problems if props are animated. */
|
||||
loc_eul_size_to_mat4(gpl->layer_mat, gpl->location, gpl->rotation, gpl->scale);
|
||||
invert_m4_m4(gpl->layer_invmat, gpl->layer_mat);
|
||||
|
||||
/* create a new temporary frame */
|
||||
tgpi->gpf = MEM_callocN(sizeof(bGPDframe), "Temp bGPDframe");
|
||||
tgpi->gpf->framenum = tgpi->cframe = cfra;
|
||||
|
@ -1004,12 +1008,12 @@ static void gpencil_primitive_update_strokes(bContext *C, tGPDprimitive *tgpi)
|
|||
/* reproject current */
|
||||
ED_gpencil_tpoint_to_point(tgpi->region, origin, tpt, &spt);
|
||||
ED_gpencil_project_point_to_plane(
|
||||
tgpi->scene, tgpi->ob, tgpi->rv3d, origin, tgpi->lock_axis - 1, &spt);
|
||||
tgpi->scene, tgpi->ob, tgpi->gpl, tgpi->rv3d, origin, tgpi->lock_axis - 1, &spt);
|
||||
|
||||
/* reproject previous */
|
||||
ED_gpencil_tpoint_to_point(tgpi->region, origin, tptb, &spt2);
|
||||
ED_gpencil_project_point_to_plane(
|
||||
tgpi->scene, tgpi->ob, tgpi->rv3d, origin, tgpi->lock_axis - 1, &spt2);
|
||||
tgpi->scene, tgpi->ob, tgpi->gpl, tgpi->rv3d, origin, tgpi->lock_axis - 1, &spt2);
|
||||
tgpi->totpixlen += len_v3v3(&spt.x, &spt2.x);
|
||||
tpt->uv_fac = tgpi->totpixlen;
|
||||
}
|
||||
|
@ -1067,7 +1071,7 @@ static void gpencil_primitive_update_strokes(bContext *C, tGPDprimitive *tgpi)
|
|||
float origin[3];
|
||||
ED_gpencil_drawing_reference_get(tgpi->scene, tgpi->ob, ts->gpencil_v3d_align, origin);
|
||||
ED_gpencil_project_stroke_to_plane(
|
||||
tgpi->scene, tgpi->ob, tgpi->rv3d, gps, origin, ts->gp_sculpt.lock_axis - 1);
|
||||
tgpi->scene, tgpi->ob, tgpi->rv3d, tgpi->gpl, gps, origin, ts->gp_sculpt.lock_axis - 1);
|
||||
}
|
||||
|
||||
/* if parented change position relative to parent object */
|
||||
|
|
|
@ -1441,11 +1441,6 @@ static bool gpencil_sculpt_brush_do_stroke(tGP_BrushEditData *gso,
|
|||
bool changed = false;
|
||||
float rot_eval = 0.0f;
|
||||
|
||||
/* Check if the stroke collide with brush. */
|
||||
if (!ED_gpencil_stroke_check_collision(gsc, gps, gso->mval, radius, diff_mat)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (gps->totpoints == 1) {
|
||||
bGPDspoint pt_temp;
|
||||
pt = &gps->points[0];
|
||||
|
@ -1577,6 +1572,13 @@ static bool gpencil_sculpt_brush_do_frame(bContext *C,
|
|||
Object *ob = gso->object;
|
||||
bGPdata *gpd = ob->data;
|
||||
char tool = gso->brush->gpencil_sculpt_tool;
|
||||
GP_SpaceConversion *gsc = &gso->gsc;
|
||||
Brush *brush = gso->brush;
|
||||
const int radius = (brush->flag & GP_BRUSH_USE_PRESSURE) ? gso->brush->size * gso->pressure :
|
||||
gso->brush->size;
|
||||
/* Calc bound box matrix. */
|
||||
float bound_mat[4][4];
|
||||
BKE_gpencil_layer_transform_matrix_get(gso->depsgraph, gso->object, gpl, bound_mat);
|
||||
|
||||
LISTBASE_FOREACH (bGPDstroke *, gps, &gpf->strokes) {
|
||||
/* skip strokes that are invalid for current view */
|
||||
|
@ -1584,7 +1586,12 @@ static bool gpencil_sculpt_brush_do_frame(bContext *C,
|
|||
continue;
|
||||
}
|
||||
/* check if the color is editable */
|
||||
if (ED_gpencil_stroke_color_use(ob, gpl, gps) == false) {
|
||||
if (ED_gpencil_stroke_material_editable(ob, gpl, gps) == false) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Check if the stroke collide with brush. */
|
||||
if (!ED_gpencil_stroke_check_collision(gsc, gps, gso->mval, radius, bound_mat)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -1742,7 +1749,8 @@ static bool gpencil_sculpt_brush_apply_standard(bContext *C, tGP_BrushEditData *
|
|||
|
||||
/* calculate difference matrix */
|
||||
float diff_mat[4][4];
|
||||
BKE_gpencil_parent_matrix_get(depsgraph, obact, gpl, diff_mat);
|
||||
BKE_gpencil_layer_transform_matrix_get(depsgraph, obact, gpl, diff_mat);
|
||||
mul_m4_m4m4(diff_mat, diff_mat, gpl->layer_invmat);
|
||||
|
||||
/* Active Frame or MultiFrame? */
|
||||
if (gso->is_multiframe) {
|
||||
|
|
|
@ -2473,7 +2473,7 @@ static void gpencil_selected_hue_table(bContext *C,
|
|||
if (ED_gpencil_stroke_can_use(C, gps) == false) {
|
||||
continue;
|
||||
}
|
||||
if (ED_gpencil_stroke_color_use(ob, gpl, gps) == false) {
|
||||
if (ED_gpencil_stroke_material_editable(ob, gpl, gps) == false) {
|
||||
continue;
|
||||
}
|
||||
if ((gps->flag & GP_STROKE_SELECT) == 0) {
|
||||
|
|
|
@ -579,7 +579,7 @@ bool ED_gpencil_stroke_can_use(const bContext *C, const bGPDstroke *gps)
|
|||
}
|
||||
|
||||
/* Check whether given stroke can be edited for the current color */
|
||||
bool ED_gpencil_stroke_color_use(Object *ob, const bGPDlayer *gpl, const bGPDstroke *gps)
|
||||
bool ED_gpencil_stroke_material_editable(Object *ob, const bGPDlayer *gpl, const bGPDstroke *gps)
|
||||
{
|
||||
/* check if the color is editable */
|
||||
MaterialGPencilStyle *gp_style = BKE_gpencil_material_settings(ob, gps->mat_nr + 1);
|
||||
|
@ -674,7 +674,7 @@ void gpencil_apply_parent(Depsgraph *depsgraph, Object *obact, bGPDlayer *gpl, b
|
|||
float inverse_diff_mat[4][4];
|
||||
float fpt[3];
|
||||
|
||||
BKE_gpencil_parent_matrix_get(depsgraph, obact, gpl, diff_mat);
|
||||
BKE_gpencil_layer_transform_matrix_get(depsgraph, obact, gpl, diff_mat);
|
||||
invert_m4_m4(inverse_diff_mat, diff_mat);
|
||||
|
||||
for (i = 0; i < gps->totpoints; i++) {
|
||||
|
@ -697,10 +697,11 @@ void gpencil_apply_parent_point(Depsgraph *depsgraph,
|
|||
float inverse_diff_mat[4][4];
|
||||
float fpt[3];
|
||||
|
||||
BKE_gpencil_parent_matrix_get(depsgraph, obact, gpl, diff_mat);
|
||||
BKE_gpencil_layer_transform_matrix_get(depsgraph, obact, gpl, diff_mat);
|
||||
invert_m4_m4(inverse_diff_mat, diff_mat);
|
||||
|
||||
mul_v3_m4v3(fpt, inverse_diff_mat, &pt->x);
|
||||
|
||||
copy_v3_v3(&pt->x, fpt);
|
||||
}
|
||||
|
||||
|
@ -997,6 +998,12 @@ void ED_gpencil_drawing_reference_get(const Scene *scene,
|
|||
else {
|
||||
/* use object location */
|
||||
copy_v3_v3(r_vec, ob->obmat[3]);
|
||||
/* Apply layer offset. */
|
||||
bGPdata *gpd = ob->data;
|
||||
bGPDlayer *gpl = BKE_gpencil_layer_active_get(gpd);
|
||||
if (gpl != NULL) {
|
||||
add_v3_v3(r_vec, gpl->layer_mat[3]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1021,7 +1028,7 @@ void ED_gpencil_project_stroke_to_view(bContext *C, bGPDlayer *gpl, bGPDstroke *
|
|||
/* init space conversion stuff */
|
||||
gpencil_point_conversion_init(C, &gsc);
|
||||
|
||||
BKE_gpencil_parent_matrix_get(depsgraph, ob, gpl, diff_mat);
|
||||
BKE_gpencil_layer_transform_matrix_get(depsgraph, ob, gpl, diff_mat);
|
||||
invert_m4_m4(inverse_diff_mat, diff_mat);
|
||||
|
||||
/* Adjust each point */
|
||||
|
@ -1046,6 +1053,7 @@ void ED_gpencil_project_stroke_to_view(bContext *C, bGPDlayer *gpl, bGPDstroke *
|
|||
void ED_gpencil_project_stroke_to_plane(const Scene *scene,
|
||||
const Object *ob,
|
||||
const RegionView3D *rv3d,
|
||||
bGPDlayer *gpl,
|
||||
bGPDstroke *gps,
|
||||
const float origin[3],
|
||||
const int axis)
|
||||
|
@ -1058,6 +1066,10 @@ void ED_gpencil_project_stroke_to_plane(const Scene *scene,
|
|||
float ray[3];
|
||||
float rpoint[3];
|
||||
|
||||
/* Recalculate layer transform matrix. */
|
||||
loc_eul_size_to_mat4(gpl->layer_mat, gpl->location, gpl->rotation, gpl->scale);
|
||||
invert_m4_m4(gpl->layer_invmat, gpl->layer_mat);
|
||||
|
||||
/* normal vector for a plane locked to axis */
|
||||
zero_v3(plane_normal);
|
||||
if (axis < 0) {
|
||||
|
@ -1074,24 +1086,27 @@ void ED_gpencil_project_stroke_to_plane(const Scene *scene,
|
|||
copy_m4_m4(mat, ob->obmat);
|
||||
|
||||
/* move origin to cursor */
|
||||
if ((ts->gpencil_v3d_align & GP_PROJECT_CURSOR) == 0) {
|
||||
if (gpl != NULL) {
|
||||
add_v3_v3(mat[3], gpl->location);
|
||||
}
|
||||
}
|
||||
if (ts->gpencil_v3d_align & GP_PROJECT_CURSOR) {
|
||||
copy_v3_v3(mat[3], cursor->location);
|
||||
}
|
||||
|
||||
mul_mat3_m4_v3(mat, plane_normal);
|
||||
}
|
||||
|
||||
if ((gpl != NULL) && (ts->gp_sculpt.lock_axis != GP_LOCKAXIS_CURSOR)) {
|
||||
mul_mat3_m4_v3(gpl->layer_mat, plane_normal);
|
||||
}
|
||||
}
|
||||
else {
|
||||
const float scale[3] = {1.0f, 1.0f, 1.0f};
|
||||
plane_normal[2] = 1.0f;
|
||||
float mat[4][4];
|
||||
loc_eul_size_to_mat4(mat, cursor->location, cursor->rotation_euler, scale);
|
||||
|
||||
/* move origin to object */
|
||||
if ((ts->gpencil_v3d_align & GP_PROJECT_CURSOR) == 0) {
|
||||
copy_v3_v3(mat[3], ob->obmat[3]);
|
||||
}
|
||||
|
||||
mul_mat3_m4_v3(mat, plane_normal);
|
||||
}
|
||||
|
||||
|
@ -1127,8 +1142,12 @@ void ED_gpencil_stroke_reproject(Depsgraph *depsgraph,
|
|||
ARegion *region = gsc->region;
|
||||
RegionView3D *rv3d = region->regiondata;
|
||||
|
||||
/* Recalculate layer transform matrix. */
|
||||
loc_eul_size_to_mat4(gpl->layer_mat, gpl->location, gpl->rotation, gpl->scale);
|
||||
invert_m4_m4(gpl->layer_invmat, gpl->layer_mat);
|
||||
|
||||
float diff_mat[4][4], inverse_diff_mat[4][4];
|
||||
BKE_gpencil_parent_matrix_get(depsgraph, gsc->ob, gpl, diff_mat);
|
||||
BKE_gpencil_layer_transform_matrix_get(depsgraph, gsc->ob, gpl, diff_mat);
|
||||
invert_m4_m4(inverse_diff_mat, diff_mat);
|
||||
|
||||
float origin[3];
|
||||
|
@ -1194,7 +1213,7 @@ void ED_gpencil_stroke_reproject(Depsgraph *depsgraph,
|
|||
}
|
||||
}
|
||||
|
||||
ED_gpencil_project_point_to_plane(gsc->scene, gsc->ob, rv3d, origin, axis, &pt2);
|
||||
ED_gpencil_project_point_to_plane(gsc->scene, gsc->ob, gpl, rv3d, origin, axis, &pt2);
|
||||
|
||||
copy_v3_v3(&pt->x, &pt2.x);
|
||||
|
||||
|
@ -1250,6 +1269,7 @@ void ED_gpencil_stroke_reproject(Depsgraph *depsgraph,
|
|||
*/
|
||||
void ED_gpencil_project_point_to_plane(const Scene *scene,
|
||||
const Object *ob,
|
||||
bGPDlayer *gpl,
|
||||
const RegionView3D *rv3d,
|
||||
const float origin[3],
|
||||
const int axis,
|
||||
|
@ -1277,6 +1297,11 @@ void ED_gpencil_project_point_to_plane(const Scene *scene,
|
|||
if (ob && (ob->type == OB_GPENCIL)) {
|
||||
float mat[4][4];
|
||||
copy_m4_m4(mat, ob->obmat);
|
||||
if ((ts->gpencil_v3d_align & GP_PROJECT_CURSOR) == 0) {
|
||||
if (gpl != NULL) {
|
||||
add_v3_v3(mat[3], gpl->location);
|
||||
}
|
||||
}
|
||||
|
||||
/* move origin to cursor */
|
||||
if (ts->gpencil_v3d_align & GP_PROJECT_CURSOR) {
|
||||
|
@ -1284,6 +1309,10 @@ void ED_gpencil_project_point_to_plane(const Scene *scene,
|
|||
}
|
||||
|
||||
mul_mat3_m4_v3(mat, plane_normal);
|
||||
/* Apply layer rotation (local transform). */
|
||||
if ((gpl != NULL) && (ts->gp_sculpt.lock_axis != GP_LOCKAXIS_CURSOR)) {
|
||||
mul_mat3_m4_v3(gpl->layer_mat, plane_normal);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
@ -1449,7 +1478,7 @@ void ED_gpencil_reset_layers_parent(Depsgraph *depsgraph, Object *obact, bGPdata
|
|||
/* only redo if any change */
|
||||
if (!equals_m4m4(gpl->inverse, cur_mat)) {
|
||||
/* first apply current transformation to all strokes */
|
||||
BKE_gpencil_parent_matrix_get(depsgraph, obact, gpl, diff_mat);
|
||||
BKE_gpencil_layer_transform_matrix_get(depsgraph, obact, gpl, diff_mat);
|
||||
/* undo local object */
|
||||
sub_v3_v3(diff_mat[3], gpl_loc);
|
||||
|
||||
|
@ -2144,7 +2173,7 @@ void ED_gpencil_update_color_uv(Main *bmain, Material *mat)
|
|||
LISTBASE_FOREACH (bGPDframe *, gpf, &gpl->frames) {
|
||||
LISTBASE_FOREACH (bGPDstroke *, gps, &gpf->strokes) {
|
||||
/* check if it is editable */
|
||||
if (ED_gpencil_stroke_color_use(ob, gpl, gps) == false) {
|
||||
if (ED_gpencil_stroke_material_editable(ob, gpl, gps) == false) {
|
||||
continue;
|
||||
}
|
||||
gps_ma = BKE_gpencil_material(ob, gps->mat_nr + 1);
|
||||
|
@ -3126,7 +3155,7 @@ bGPDstroke *ED_gpencil_stroke_nearest_to_ends(bContext *C,
|
|||
|
||||
/* calculate difference matrix object */
|
||||
float diff_mat[4][4];
|
||||
BKE_gpencil_parent_matrix_get(depsgraph, ob, gpl, diff_mat);
|
||||
BKE_gpencil_layer_transform_matrix_get(depsgraph, ob, gpl, diff_mat);
|
||||
|
||||
/* Calculate the extremes of the stroke in 2D. */
|
||||
bGPDspoint pt_parent;
|
||||
|
@ -3144,15 +3173,13 @@ bGPDstroke *ED_gpencil_stroke_nearest_to_ends(bContext *C,
|
|||
float dist_min = FLT_MAX;
|
||||
LISTBASE_FOREACH (bGPDstroke *, gps_target, &gpf->strokes) {
|
||||
/* Check if the color is editable. */
|
||||
if ((gps_target == gps) || (ED_gpencil_stroke_color_use(ob, gpl, gps) == false)) {
|
||||
if ((gps_target == gps) || (ED_gpencil_stroke_material_editable(ob, gpl, gps) == false)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Check if one of the ends is inside target stroke bounding box. */
|
||||
if (!ED_gpencil_stroke_check_collision(gsc, gps, pt2d_start, radius, diff_mat)) {
|
||||
continue;
|
||||
}
|
||||
if (!ED_gpencil_stroke_check_collision(gsc, gps, pt2d_end, radius, diff_mat)) {
|
||||
if ((!ED_gpencil_stroke_check_collision(gsc, gps_target, pt2d_start, radius, diff_mat)) &&
|
||||
(!ED_gpencil_stroke_check_collision(gsc, gps_target, pt2d_end, radius, diff_mat))) {
|
||||
continue;
|
||||
}
|
||||
/* Check the distance of the ends with the ends of target stroke to avoid middle contact.
|
||||
|
|
|
@ -674,7 +674,7 @@ static bool gpencil_extract_palette_from_vertex(bContext *C,
|
|||
if (ED_gpencil_stroke_can_use(C, gps) == false) {
|
||||
continue;
|
||||
}
|
||||
if (ED_gpencil_stroke_color_use(ob, gpl, gps) == false) {
|
||||
if (ED_gpencil_stroke_material_editable(ob, gpl, gps) == false) {
|
||||
continue;
|
||||
}
|
||||
MaterialGPencilStyle *gp_style = BKE_gpencil_material_settings(ob, gps->mat_nr + 1);
|
||||
|
@ -859,7 +859,7 @@ static int gpencil_material_to_vertex_exec(bContext *C, wmOperator *op)
|
|||
if (ED_gpencil_stroke_can_use(C, gps) == false) {
|
||||
continue;
|
||||
}
|
||||
if (ED_gpencil_stroke_color_use(ob, gpl, gps) == false) {
|
||||
if (ED_gpencil_stroke_material_editable(ob, gpl, gps) == false) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
|
@ -825,7 +825,8 @@ static void gpencil_save_selected_point(tGP_BrushVertexpaintData *gso,
|
|||
static bool gpencil_vertexpaint_select_stroke(tGP_BrushVertexpaintData *gso,
|
||||
bGPDstroke *gps,
|
||||
const char tool,
|
||||
const float diff_mat[4][4])
|
||||
const float diff_mat[4][4],
|
||||
const float bound_mat[4][4])
|
||||
{
|
||||
GP_SpaceConversion *gsc = &gso->gsc;
|
||||
rcti *rect = &gso->brush_rect;
|
||||
|
@ -846,7 +847,7 @@ static bool gpencil_vertexpaint_select_stroke(tGP_BrushVertexpaintData *gso,
|
|||
bool saved = false;
|
||||
|
||||
/* Check if the stroke collide with brush. */
|
||||
if (!ED_gpencil_stroke_check_collision(gsc, gps, gso->mval, radius, diff_mat)) {
|
||||
if (!ED_gpencil_stroke_check_collision(gsc, gps, gso->mval, radius, bound_mat)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -991,7 +992,8 @@ static bool gpencil_vertexpaint_brush_do_frame(bContext *C,
|
|||
tGP_BrushVertexpaintData *gso,
|
||||
bGPDlayer *gpl,
|
||||
bGPDframe *gpf,
|
||||
const float diff_mat[4][4])
|
||||
const float diff_mat[4][4],
|
||||
const float bound_mat[4][4])
|
||||
{
|
||||
Object *ob = CTX_data_active_object(C);
|
||||
const char tool = ob->mode == OB_MODE_VERTEX_GPENCIL ? gso->brush->gpencil_vertex_tool :
|
||||
|
@ -1013,12 +1015,12 @@ static bool gpencil_vertexpaint_brush_do_frame(bContext *C,
|
|||
continue;
|
||||
}
|
||||
/* Check if the color is editable. */
|
||||
if (ED_gpencil_stroke_color_use(ob, gpl, gps) == false) {
|
||||
if (ED_gpencil_stroke_material_editable(ob, gpl, gps) == false) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Check points below the brush. */
|
||||
bool hit = gpencil_vertexpaint_select_stroke(gso, gps, tool, diff_mat);
|
||||
bool hit = gpencil_vertexpaint_select_stroke(gso, gps, tool, diff_mat, bound_mat);
|
||||
|
||||
/* If stroke was hit and has an editcurve the curve needs an update. */
|
||||
bGPDstroke *gps_active = (gps->runtime.gps_orig) ? gps->runtime.gps_orig : gps;
|
||||
|
@ -1123,9 +1125,11 @@ static bool gpencil_vertexpaint_brush_apply_to_layers(bContext *C, tGP_BrushVert
|
|||
continue;
|
||||
}
|
||||
|
||||
/* calculate difference matrix */
|
||||
float diff_mat[4][4];
|
||||
BKE_gpencil_parent_matrix_get(depsgraph, obact, gpl, diff_mat);
|
||||
/* Calculate transform matrix. */
|
||||
float diff_mat[4][4], bound_mat[4][4];
|
||||
BKE_gpencil_layer_transform_matrix_get(depsgraph, obact, gpl, diff_mat);
|
||||
copy_m4_m4(bound_mat, diff_mat);
|
||||
mul_m4_m4m4(diff_mat, diff_mat, gpl->layer_invmat);
|
||||
|
||||
/* Active Frame or MultiFrame? */
|
||||
if (gso->is_multiframe) {
|
||||
|
@ -1152,7 +1156,7 @@ static bool gpencil_vertexpaint_brush_apply_to_layers(bContext *C, tGP_BrushVert
|
|||
}
|
||||
|
||||
/* affect strokes in this frame */
|
||||
changed |= gpencil_vertexpaint_brush_do_frame(C, gso, gpl, gpf, diff_mat);
|
||||
changed |= gpencil_vertexpaint_brush_do_frame(C, gso, gpl, gpf, diff_mat, bound_mat);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1160,7 +1164,8 @@ static bool gpencil_vertexpaint_brush_apply_to_layers(bContext *C, tGP_BrushVert
|
|||
/* Apply to active frame's strokes */
|
||||
if (gpl->actframe != NULL) {
|
||||
gso->mf_falloff = 1.0f;
|
||||
changed |= gpencil_vertexpaint_brush_do_frame(C, gso, gpl, gpl->actframe, diff_mat);
|
||||
changed |= gpencil_vertexpaint_brush_do_frame(
|
||||
C, gso, gpl, gpl->actframe, diff_mat, bound_mat);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -383,7 +383,8 @@ static void gpencil_save_selected_point(tGP_BrushWeightpaintData *gso,
|
|||
/* Select points in this stroke and add to an array to be used later. */
|
||||
static void gpencil_weightpaint_select_stroke(tGP_BrushWeightpaintData *gso,
|
||||
bGPDstroke *gps,
|
||||
const float diff_mat[4][4])
|
||||
const float diff_mat[4][4],
|
||||
const float bound_mat[4][4])
|
||||
{
|
||||
GP_SpaceConversion *gsc = &gso->gsc;
|
||||
rcti *rect = &gso->brush_rect;
|
||||
|
@ -402,7 +403,7 @@ static void gpencil_weightpaint_select_stroke(tGP_BrushWeightpaintData *gso,
|
|||
bool include_last = false;
|
||||
|
||||
/* Check if the stroke collide with brush. */
|
||||
if (!ED_gpencil_stroke_check_collision(gsc, gps, gso->mval, radius, diff_mat)) {
|
||||
if (!ED_gpencil_stroke_check_collision(gsc, gps, gso->mval, radius, bound_mat)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -505,7 +506,8 @@ static bool gpencil_weightpaint_brush_do_frame(bContext *C,
|
|||
tGP_BrushWeightpaintData *gso,
|
||||
bGPDlayer *gpl,
|
||||
bGPDframe *gpf,
|
||||
const float diff_mat[4][4])
|
||||
const float diff_mat[4][4],
|
||||
const float bound_mat[4][4])
|
||||
{
|
||||
Object *ob = CTX_data_active_object(C);
|
||||
char tool = gso->brush->gpencil_weight_tool;
|
||||
|
@ -526,12 +528,12 @@ static bool gpencil_weightpaint_brush_do_frame(bContext *C,
|
|||
continue;
|
||||
}
|
||||
/* Check if the color is editable. */
|
||||
if (ED_gpencil_stroke_color_use(ob, gpl, gps) == false) {
|
||||
if (ED_gpencil_stroke_material_editable(ob, gpl, gps) == false) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Check points below the brush. */
|
||||
gpencil_weightpaint_select_stroke(gso, gps, diff_mat);
|
||||
gpencil_weightpaint_select_stroke(gso, gps, diff_mat, bound_mat);
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------
|
||||
|
@ -578,9 +580,11 @@ static bool gpencil_weightpaint_brush_apply_to_layers(bContext *C, tGP_BrushWeig
|
|||
continue;
|
||||
}
|
||||
|
||||
/* calculate difference matrix */
|
||||
float diff_mat[4][4];
|
||||
BKE_gpencil_parent_matrix_get(depsgraph, obact, gpl, diff_mat);
|
||||
/* Calculate transform matrix. */
|
||||
float diff_mat[4][4], bound_mat[4][4];
|
||||
BKE_gpencil_layer_transform_matrix_get(depsgraph, obact, gpl, diff_mat);
|
||||
copy_m4_m4(bound_mat, diff_mat);
|
||||
mul_m4_m4m4(diff_mat, diff_mat, gpl->layer_invmat);
|
||||
|
||||
/* Active Frame or MultiFrame? */
|
||||
if (gso->is_multiframe) {
|
||||
|
@ -608,7 +612,7 @@ static bool gpencil_weightpaint_brush_apply_to_layers(bContext *C, tGP_BrushWeig
|
|||
}
|
||||
|
||||
/* affect strokes in this frame */
|
||||
changed |= gpencil_weightpaint_brush_do_frame(C, gso, gpl, gpf, diff_mat);
|
||||
changed |= gpencil_weightpaint_brush_do_frame(C, gso, gpl, gpf, diff_mat, bound_mat);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -616,7 +620,8 @@ static bool gpencil_weightpaint_brush_apply_to_layers(bContext *C, tGP_BrushWeig
|
|||
if (gpl->actframe != NULL) {
|
||||
/* Apply to active frame's strokes */
|
||||
gso->mf_falloff = 1.0f;
|
||||
changed |= gpencil_weightpaint_brush_do_frame(C, gso, gpl, gpl->actframe, diff_mat);
|
||||
changed |= gpencil_weightpaint_brush_do_frame(
|
||||
C, gso, gpl, gpl->actframe, diff_mat, bound_mat);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -264,6 +264,7 @@ struct SnapObjectContext *ED_gizmotypes_snap_3d_context_ensure(struct Scene *sce
|
|||
bool ED_gizmotypes_snap_3d_invert_snap_get(struct wmGizmo *gz);
|
||||
void ED_gizmotypes_snap_3d_toggle_set(struct wmGizmo *gz, bool enable);
|
||||
void ED_gizmotypes_snap_3d_toggle_clear(struct wmGizmo *gz);
|
||||
bool ED_gizmotypes_snap_3d_is_enabled(struct wmGizmo *gz);
|
||||
|
||||
short ED_gizmotypes_snap_3d_update(struct wmGizmo *gz,
|
||||
struct Depsgraph *depsgraph,
|
||||
|
|
|
@ -147,9 +147,9 @@ bool ED_gpencil_has_keyframe_v3d(struct Scene *scene, struct Object *ob, int cfr
|
|||
|
||||
bool ED_gpencil_stroke_can_use_direct(const struct ScrArea *area, const struct bGPDstroke *gps);
|
||||
bool ED_gpencil_stroke_can_use(const struct bContext *C, const struct bGPDstroke *gps);
|
||||
bool ED_gpencil_stroke_color_use(struct Object *ob,
|
||||
const struct bGPDlayer *gpl,
|
||||
const struct bGPDstroke *gps);
|
||||
bool ED_gpencil_stroke_material_editable(struct Object *ob,
|
||||
const struct bGPDlayer *gpl,
|
||||
const struct bGPDstroke *gps);
|
||||
|
||||
/* ----------- Grease Pencil Operators ----------------- */
|
||||
|
||||
|
@ -263,11 +263,13 @@ bool ED_object_gpencil_exit(struct Main *bmain, struct Object *ob);
|
|||
void ED_gpencil_project_stroke_to_plane(const struct Scene *scene,
|
||||
const struct Object *ob,
|
||||
const struct RegionView3D *rv3d,
|
||||
struct bGPDlayer *gpl,
|
||||
struct bGPDstroke *gps,
|
||||
const float origin[3],
|
||||
const int axis);
|
||||
void ED_gpencil_project_point_to_plane(const struct Scene *scene,
|
||||
const struct Object *ob,
|
||||
struct bGPDlayer *gpl,
|
||||
const struct RegionView3D *rv3d,
|
||||
const float origin[3],
|
||||
const int axis,
|
||||
|
|
|
@ -101,7 +101,7 @@ struct ListBase *ED_image_paint_tile_list_get(void);
|
|||
|
||||
/* paint_curve_undo.c */
|
||||
void ED_paintcurve_undo_push_begin(const char *name);
|
||||
void ED_paintcurve_undo_push_end(void);
|
||||
void ED_paintcurve_undo_push_end(struct bContext *C);
|
||||
|
||||
void ED_paintcurve_undosys_type(struct UndoType *ut);
|
||||
|
||||
|
|
|
@ -1730,7 +1730,7 @@ static int object_speaker_add_exec(bContext *C, wmOperator *op)
|
|||
BLI_strncpy(nlt->name, DATA_("SoundTrack"), sizeof(nlt->name));
|
||||
BKE_nlastrip_validate_name(adt, strip);
|
||||
|
||||
WM_event_add_notifier(C, NC_ANIMATION | ND_NLA | NA_EDITED, NULL);
|
||||
WM_event_add_notifier(C, NC_ANIMATION | ND_NLA | NA_ADDED, NULL);
|
||||
}
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
|
|
|
@ -1394,7 +1394,7 @@ static int object_origin_set_exec(bContext *C, wmOperator *op)
|
|||
* (all layers are considered without evaluating lock attributes) */
|
||||
LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) {
|
||||
/* calculate difference matrix */
|
||||
BKE_gpencil_parent_matrix_get(depsgraph, obact, gpl, diff_mat);
|
||||
BKE_gpencil_layer_transform_matrix_get(depsgraph, obact, gpl, diff_mat);
|
||||
/* undo matrix */
|
||||
invert_m4_m4(inverse_diff_mat, diff_mat);
|
||||
LISTBASE_FOREACH (bGPDframe *, gpf, &gpl->frames) {
|
||||
|
|
|
@ -866,7 +866,7 @@ static eContextResult screen_ctx_editable_gpencil_strokes(const bContext *C,
|
|||
LISTBASE_FOREACH (bGPDstroke *, gps, &gpf->strokes) {
|
||||
if (ED_gpencil_stroke_can_use_direct(area, gps)) {
|
||||
/* check if the color is editable */
|
||||
if (ED_gpencil_stroke_color_use(obact, gpl, gps) == false) {
|
||||
if (ED_gpencil_stroke_material_editable(obact, gpl, gps) == false) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
|
@ -241,7 +241,7 @@ static void paintcurve_point_add(bContext *C, wmOperator *op, const int loc[2])
|
|||
pcp[add_index].bez.h1 = HD_ALIGN;
|
||||
}
|
||||
|
||||
ED_paintcurve_undo_push_end();
|
||||
ED_paintcurve_undo_push_end(C);
|
||||
|
||||
WM_paint_cursor_tag_redraw(window, region);
|
||||
}
|
||||
|
@ -352,7 +352,7 @@ static int paintcurve_delete_point_exec(bContext *C, wmOperator *op)
|
|||
|
||||
#undef DELETE_TAG
|
||||
|
||||
ED_paintcurve_undo_push_end();
|
||||
ED_paintcurve_undo_push_end(C);
|
||||
|
||||
WM_paint_cursor_tag_redraw(window, region);
|
||||
|
||||
|
@ -463,12 +463,12 @@ static bool paintcurve_point_select(
|
|||
}
|
||||
|
||||
if (!pcp) {
|
||||
ED_paintcurve_undo_push_end();
|
||||
ED_paintcurve_undo_push_end(C);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
ED_paintcurve_undo_push_end();
|
||||
ED_paintcurve_undo_push_end(C);
|
||||
|
||||
WM_paint_cursor_tag_redraw(window, region);
|
||||
|
||||
|
@ -614,7 +614,7 @@ static int paintcurve_slide_modal(bContext *C, wmOperator *op, const wmEvent *ev
|
|||
if (event->type == psd->event && event->val == KM_RELEASE) {
|
||||
MEM_freeN(psd);
|
||||
ED_paintcurve_undo_push_begin(op->type->name);
|
||||
ED_paintcurve_undo_push_end();
|
||||
ED_paintcurve_undo_push_end(C);
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
|
|
|
@ -177,10 +177,10 @@ void ED_paintcurve_undo_push_begin(const char *name)
|
|||
BKE_undosys_step_push_init_with_type(ustack, C, name, BKE_UNDOSYS_TYPE_PAINTCURVE);
|
||||
}
|
||||
|
||||
void ED_paintcurve_undo_push_end(void)
|
||||
void ED_paintcurve_undo_push_end(bContext *C)
|
||||
{
|
||||
UndoStack *ustack = ED_undo_stack_get();
|
||||
BKE_undosys_step_push(ustack, NULL, NULL);
|
||||
BKE_undosys_step_push(ustack, C, NULL);
|
||||
BKE_undosys_stack_limit_steps_and_memory_defaults(ustack);
|
||||
WM_file_tag_modified();
|
||||
}
|
||||
|
|
|
@ -191,6 +191,7 @@ void CLIP_OT_clear_solution(struct wmOperatorType *ot);
|
|||
|
||||
void CLIP_OT_clear_track_path(struct wmOperatorType *ot);
|
||||
void CLIP_OT_join_tracks(struct wmOperatorType *ot);
|
||||
void CLIP_OT_average_tracks(struct wmOperatorType *ot);
|
||||
|
||||
void CLIP_OT_disable_markers(struct wmOperatorType *ot);
|
||||
void CLIP_OT_hide_tracks(struct wmOperatorType *ot);
|
||||
|
|
|
@ -514,6 +514,7 @@ static void clip_operatortypes(void)
|
|||
/* clean-up */
|
||||
WM_operatortype_append(CLIP_OT_clear_track_path);
|
||||
WM_operatortype_append(CLIP_OT_join_tracks);
|
||||
WM_operatortype_append(CLIP_OT_average_tracks);
|
||||
WM_operatortype_append(CLIP_OT_track_copy_color);
|
||||
|
||||
WM_operatortype_append(CLIP_OT_clean_tracks);
|
||||
|
|
|
@ -1490,6 +1490,97 @@ void CLIP_OT_join_tracks(wmOperatorType *ot)
|
|||
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
|
||||
}
|
||||
|
||||
/********************** Average tracks operator *********************/
|
||||
|
||||
static int average_tracks_exec(bContext *C, wmOperator *op)
|
||||
{
|
||||
SpaceClip *space_clip = CTX_wm_space_clip(C);
|
||||
MovieClip *clip = ED_space_clip_get_clip(space_clip);
|
||||
MovieTracking *tracking = &clip->tracking;
|
||||
|
||||
/* Collect source tracks. */
|
||||
int num_source_tracks;
|
||||
MovieTrackingTrack **source_tracks = BKE_tracking_selected_tracks_in_active_object(
|
||||
tracking, &num_source_tracks);
|
||||
if (num_source_tracks == 0) {
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
|
||||
/* Create new empty track, which will be the averaged result.
|
||||
* Makes it simple to average all selection to it. */
|
||||
ListBase *tracks_list = BKE_tracking_get_active_tracks(tracking);
|
||||
MovieTrackingTrack *result_track = BKE_tracking_track_add_empty(tracking, tracks_list);
|
||||
|
||||
/* Perform averaging. */
|
||||
BKE_tracking_tracks_average(result_track, source_tracks, num_source_tracks);
|
||||
|
||||
const bool keep_original = RNA_boolean_get(op->ptr, "keep_original");
|
||||
if (!keep_original) {
|
||||
for (int i = 0; i < num_source_tracks; i++) {
|
||||
clip_delete_track(C, clip, source_tracks[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/* Update selection, making the result track active and selected. */
|
||||
/* TODO(sergey): Should become some sort of utility function available for all operators. */
|
||||
|
||||
BKE_tracking_track_select(tracks_list, result_track, TRACK_AREA_ALL, 0);
|
||||
ListBase *plane_tracks_list = BKE_tracking_get_active_plane_tracks(tracking);
|
||||
BKE_tracking_plane_tracks_deselect_all(plane_tracks_list);
|
||||
|
||||
clip->tracking.act_track = result_track;
|
||||
clip->tracking.act_plane_track = NULL;
|
||||
|
||||
/* Inform the dependency graph and interface about changes. */
|
||||
DEG_id_tag_update(&clip->id, 0);
|
||||
WM_event_add_notifier(C, NC_MOVIECLIP | NA_EDITED, clip);
|
||||
|
||||
/* Free memory. */
|
||||
MEM_freeN(source_tracks);
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
static int average_tracks_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
|
||||
{
|
||||
PropertyRNA *prop_keep_original = RNA_struct_find_property(op->ptr, "keep_original");
|
||||
if (!RNA_property_is_set(op->ptr, prop_keep_original)) {
|
||||
SpaceClip *space_clip = CTX_wm_space_clip(C);
|
||||
MovieClip *clip = ED_space_clip_get_clip(space_clip);
|
||||
MovieTracking *tracking = &clip->tracking;
|
||||
|
||||
const int num_selected_tracks = BKE_tracking_count_selected_tracks_in_active_object(tracking);
|
||||
|
||||
if (num_selected_tracks == 1) {
|
||||
RNA_property_boolean_set(op->ptr, prop_keep_original, false);
|
||||
}
|
||||
}
|
||||
|
||||
return average_tracks_exec(C, op);
|
||||
}
|
||||
|
||||
void CLIP_OT_average_tracks(wmOperatorType *ot)
|
||||
{
|
||||
/* Identifiers. */
|
||||
ot->name = "Average Tracks";
|
||||
ot->description = "Average selected tracks into active";
|
||||
ot->idname = "CLIP_OT_average_tracks";
|
||||
|
||||
/* API callbacks. */
|
||||
ot->exec = average_tracks_exec;
|
||||
ot->invoke = average_tracks_invoke;
|
||||
ot->poll = ED_space_clip_tracking_poll;
|
||||
|
||||
/* Flags. */
|
||||
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
|
||||
|
||||
/* Properties. */
|
||||
PropertyRNA *prop;
|
||||
|
||||
prop = RNA_def_boolean(ot->srna, "keep_original", 1, "Keep Original", "Keep original tracks");
|
||||
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
|
||||
}
|
||||
|
||||
/********************** lock tracks operator *********************/
|
||||
|
||||
enum {
|
||||
|
|
|
@ -735,7 +735,7 @@ static int nlaedit_add_tracks_exec(bContext *C, wmOperator *op)
|
|||
DEG_relations_tag_update(CTX_data_main(C));
|
||||
|
||||
/* set notifier that things have changed */
|
||||
WM_event_add_notifier(C, NC_ANIMATION | ND_NLA | NA_EDITED, NULL);
|
||||
WM_event_add_notifier(C, NC_ANIMATION | ND_NLA | NA_ADDED, NULL);
|
||||
|
||||
/* done */
|
||||
return OPERATOR_FINISHED;
|
||||
|
@ -823,7 +823,7 @@ static int nlaedit_delete_tracks_exec(bContext *C, wmOperator *UNUSED(op))
|
|||
DEG_relations_tag_update(ac.bmain);
|
||||
|
||||
/* set notifier that things have changed */
|
||||
WM_event_add_notifier(C, NC_ANIMATION | ND_NLA | NA_EDITED, NULL);
|
||||
WM_event_add_notifier(C, NC_ANIMATION | ND_NLA | NA_REMOVED, NULL);
|
||||
|
||||
/* done */
|
||||
return OPERATOR_FINISHED;
|
||||
|
|
|
@ -693,7 +693,7 @@ static int nlaedit_add_actionclip_exec(bContext *C, wmOperator *op)
|
|||
DEG_relations_tag_update(ac.bmain);
|
||||
|
||||
/* set notifier that things have changed */
|
||||
WM_event_add_notifier(C, NC_ANIMATION | ND_NLA | NA_EDITED, NULL);
|
||||
WM_event_add_notifier(C, NC_ANIMATION | ND_NLA | NA_ADDED, NULL);
|
||||
|
||||
/* done */
|
||||
return OPERATOR_FINISHED;
|
||||
|
@ -823,7 +823,7 @@ static int nlaedit_add_transition_exec(bContext *C, wmOperator *op)
|
|||
ED_nla_postop_refresh(&ac);
|
||||
|
||||
/* set notifier that things have changed */
|
||||
WM_event_add_notifier(C, NC_ANIMATION | ND_NLA | NA_EDITED, NULL);
|
||||
WM_event_add_notifier(C, NC_ANIMATION | ND_NLA | NA_ADDED, NULL);
|
||||
|
||||
/* done */
|
||||
return OPERATOR_FINISHED;
|
||||
|
@ -920,7 +920,7 @@ static int nlaedit_add_sound_exec(bContext *C, wmOperator *UNUSED(op))
|
|||
ED_nla_postop_refresh(&ac);
|
||||
|
||||
/* set notifier that things have changed */
|
||||
WM_event_add_notifier(C, NC_ANIMATION | ND_NLA | NA_EDITED, NULL);
|
||||
WM_event_add_notifier(C, NC_ANIMATION | ND_NLA | NA_ADDED, NULL);
|
||||
|
||||
/* done */
|
||||
return OPERATOR_FINISHED;
|
||||
|
@ -992,7 +992,7 @@ static int nlaedit_add_meta_exec(bContext *C, wmOperator *UNUSED(op))
|
|||
ANIM_animdata_freelist(&anim_data);
|
||||
|
||||
/* set notifier that things have changed */
|
||||
WM_event_add_notifier(C, NC_ANIMATION | ND_NLA | NA_EDITED, NULL);
|
||||
WM_event_add_notifier(C, NC_ANIMATION | ND_NLA | NA_ADDED, NULL);
|
||||
|
||||
/* done */
|
||||
return OPERATOR_FINISHED;
|
||||
|
@ -1053,7 +1053,7 @@ static int nlaedit_remove_meta_exec(bContext *C, wmOperator *UNUSED(op))
|
|||
ANIM_animdata_freelist(&anim_data);
|
||||
|
||||
/* set notifier that things have changed */
|
||||
WM_event_add_notifier(C, NC_ANIMATION | ND_NLA | NA_EDITED, NULL);
|
||||
WM_event_add_notifier(C, NC_ANIMATION | ND_NLA | NA_REMOVED, NULL);
|
||||
|
||||
/* done */
|
||||
return OPERATOR_FINISHED;
|
||||
|
@ -1155,7 +1155,7 @@ static int nlaedit_duplicate_exec(bContext *C, wmOperator *op)
|
|||
}
|
||||
|
||||
/* set notifier that things have changed */
|
||||
WM_event_add_notifier(C, NC_ANIMATION | ND_NLA | NA_EDITED, NULL);
|
||||
WM_event_add_notifier(C, NC_ANIMATION | ND_NLA | NA_ADDED, NULL);
|
||||
|
||||
/* done */
|
||||
return OPERATOR_FINISHED;
|
||||
|
@ -1260,7 +1260,7 @@ static int nlaedit_delete_exec(bContext *C, wmOperator *UNUSED(op))
|
|||
DEG_relations_tag_update(ac.bmain);
|
||||
|
||||
/* set notifier that things have changed */
|
||||
WM_event_add_notifier(C, NC_ANIMATION | ND_NLA | NA_EDITED, NULL);
|
||||
WM_event_add_notifier(C, NC_ANIMATION | ND_NLA | NA_REMOVED, NULL);
|
||||
|
||||
/* done */
|
||||
return OPERATOR_FINISHED;
|
||||
|
@ -1415,7 +1415,7 @@ static int nlaedit_split_exec(bContext *C, wmOperator *UNUSED(op))
|
|||
ED_nla_postop_refresh(&ac);
|
||||
|
||||
/* set notifier that things have changed */
|
||||
WM_event_add_notifier(C, NC_ANIMATION | ND_NLA | NA_EDITED, NULL);
|
||||
WM_event_add_notifier(C, NC_ANIMATION | ND_NLA | NA_ADDED, NULL);
|
||||
|
||||
/* done */
|
||||
return OPERATOR_FINISHED;
|
||||
|
@ -1659,6 +1659,7 @@ static int nlaedit_swap_exec(bContext *C, wmOperator *op)
|
|||
|
||||
/* set notifier that things have changed */
|
||||
WM_event_add_notifier(C, NC_ANIMATION | ND_NLA | NA_EDITED, NULL);
|
||||
WM_event_add_notifier(C, NC_ANIMATION | ND_NLA_ORDER, NULL);
|
||||
|
||||
/* done */
|
||||
return OPERATOR_FINISHED;
|
||||
|
@ -1744,6 +1745,7 @@ static int nlaedit_move_up_exec(bContext *C, wmOperator *UNUSED(op))
|
|||
|
||||
/* set notifier that things have changed */
|
||||
WM_event_add_notifier(C, NC_ANIMATION | ND_NLA | NA_EDITED, NULL);
|
||||
WM_event_add_notifier(C, NC_ANIMATION | ND_NLA_ORDER, NULL);
|
||||
|
||||
/* done */
|
||||
return OPERATOR_FINISHED;
|
||||
|
@ -1829,6 +1831,7 @@ static int nlaedit_move_down_exec(bContext *C, wmOperator *UNUSED(op))
|
|||
|
||||
/* set notifier that things have changed */
|
||||
WM_event_add_notifier(C, NC_ANIMATION | ND_NLA | NA_EDITED, NULL);
|
||||
WM_event_add_notifier(C, NC_ANIMATION | ND_NLA_ORDER, NULL);
|
||||
|
||||
/* done */
|
||||
return OPERATOR_FINISHED;
|
||||
|
@ -2002,7 +2005,7 @@ static int nlaedit_make_single_user_exec(bContext *C, wmOperator *UNUSED(op))
|
|||
}
|
||||
|
||||
/* set notifier that things have changed */
|
||||
WM_event_add_notifier(C, NC_ANIMATION | ND_NLA | NA_EDITED, NULL);
|
||||
WM_event_add_notifier(C, NC_ANIMATION | ND_NLA | NA_ADDED, NULL);
|
||||
|
||||
/* done */
|
||||
return OPERATOR_FINISHED;
|
||||
|
@ -2241,6 +2244,8 @@ static int nlaedit_snap_exec(bContext *C, wmOperator *op)
|
|||
scene = ac.scene;
|
||||
secf = (float)FPS;
|
||||
|
||||
bool any_added = false;
|
||||
|
||||
/* since we may add tracks, perform this in reverse order */
|
||||
for (ale = anim_data.last; ale; ale = ale->prev) {
|
||||
ListBase tmp_strips = {NULL, NULL};
|
||||
|
@ -2314,6 +2319,8 @@ static int nlaedit_snap_exec(bContext *C, wmOperator *op)
|
|||
/* clear temp meta-strips on this new track,
|
||||
* as we may not be able to get back to it */
|
||||
BKE_nlastrips_clear_metas(&track->strips, 0, 1);
|
||||
|
||||
any_added = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2333,6 +2340,9 @@ static int nlaedit_snap_exec(bContext *C, wmOperator *op)
|
|||
|
||||
/* set notifier that things have changed */
|
||||
WM_event_add_notifier(C, NC_ANIMATION | ND_NLA | NA_EDITED, NULL);
|
||||
if (any_added) {
|
||||
WM_event_add_notifier(C, NC_ANIMATION | ND_NLA | NA_ADDED, NULL);
|
||||
}
|
||||
|
||||
/* done */
|
||||
return OPERATOR_FINISHED;
|
||||
|
|
|
@ -222,10 +222,18 @@ static void outliner_main_region_listener(wmWindow *UNUSED(win),
|
|||
ED_region_tag_redraw(region);
|
||||
break;
|
||||
case ND_ANIMCHAN:
|
||||
if (wmn->action == NA_SELECTED) {
|
||||
if (ELEM(wmn->action, NA_SELECTED, NA_RENAME)) {
|
||||
ED_region_tag_redraw(region);
|
||||
}
|
||||
break;
|
||||
case ND_NLA:
|
||||
if (ELEM(wmn->action, NA_ADDED, NA_REMOVED)) {
|
||||
ED_region_tag_redraw(region);
|
||||
}
|
||||
break;
|
||||
case ND_NLA_ORDER:
|
||||
ED_region_tag_redraw(region);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case NC_GPENCIL:
|
||||
|
|
|
@ -91,6 +91,11 @@ enum ePlace_Origin {
|
|||
PLACE_ORIGIN_CENTER = 2,
|
||||
};
|
||||
|
||||
enum ePlace_Aspect {
|
||||
PLACE_ASPECT_FREE = 1,
|
||||
PLACE_ASPECT_FIXED = 2,
|
||||
};
|
||||
|
||||
enum ePlace_Depth {
|
||||
PLACE_DEPTH_SURFACE = 1,
|
||||
PLACE_DEPTH_CURSOR_PLANE = 2,
|
||||
|
@ -102,6 +107,11 @@ enum ePlace_Orient {
|
|||
PLACE_ORIENT_DEFAULT = 2,
|
||||
};
|
||||
|
||||
enum ePlace_SnapTo {
|
||||
PLACE_SNAP_TO_GEOMETRY = 1,
|
||||
PLACE_SNAP_TO_DEFAULT = 2,
|
||||
};
|
||||
|
||||
struct InteractivePlaceData {
|
||||
/* Window manager variables (set these even when waiting for input). */
|
||||
Scene *scene;
|
||||
|
@ -116,8 +126,17 @@ struct InteractivePlaceData {
|
|||
|
||||
/** Primary & secondary steps. */
|
||||
struct {
|
||||
bool is_centered;
|
||||
bool is_fixed_aspect;
|
||||
/**
|
||||
* When centered, drag out the shape from the center.
|
||||
* Toggling the setting flips the value from it's initial state.
|
||||
*/
|
||||
bool is_centered, is_centered_init;
|
||||
/**
|
||||
* When fixed, constrain the X/Y aspect for the initial #STEP_BASE drag.
|
||||
* For #STEP_DEPTH match the maximum X/Y dimension.
|
||||
* Toggling the setting flips the value from it's initial state.
|
||||
*/
|
||||
bool is_fixed_aspect, is_fixed_aspect_init;
|
||||
float plane[4];
|
||||
float co_dst[3];
|
||||
|
||||
|
@ -159,9 +178,6 @@ struct InteractivePlaceData {
|
|||
float matrix_orient[3][3];
|
||||
int orient_axis;
|
||||
|
||||
/** The tool option, if we start centered, invert toggling behavior. */
|
||||
bool is_centered_init;
|
||||
|
||||
bool use_snap, is_snap_found, is_snap_invert;
|
||||
float snap_co[3];
|
||||
|
||||
|
@ -184,6 +200,8 @@ struct InteractivePlaceData {
|
|||
|
||||
/** Optional snap gizmo, needed for snapping. */
|
||||
wmGizmo *snap_gizmo;
|
||||
|
||||
enum ePlace_SnapTo snap_to;
|
||||
};
|
||||
|
||||
/** \} */
|
||||
|
@ -359,6 +377,56 @@ static wmGizmoGroup *idp_gizmogroup_from_region(ARegion *region)
|
|||
return gzmap ? WM_gizmomap_group_find(gzmap, view3d_gzgt_placement_id) : NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate 3D view incremental (grid) snapping.
|
||||
*
|
||||
* \note This could be moved to a public function.
|
||||
*/
|
||||
static bool idp_snap_calc_incremental(
|
||||
Scene *scene, View3D *v3d, ARegion *region, const float co_relative[3], float co[3])
|
||||
{
|
||||
if ((scene->toolsettings->snap_mode & SCE_SNAP_MODE_INCREMENT) == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const float grid_size = ED_view3d_grid_view_scale(scene, v3d, region, NULL);
|
||||
if (UNLIKELY(grid_size == 0.0f)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (scene->toolsettings->snap_flag & SCE_SNAP_ABS_GRID) {
|
||||
co_relative = NULL;
|
||||
}
|
||||
|
||||
if (co_relative != NULL) {
|
||||
sub_v3_v3(co, co_relative);
|
||||
}
|
||||
mul_v3_fl(co, 1.0f / grid_size);
|
||||
co[0] = roundf(co[0]);
|
||||
co[1] = roundf(co[1]);
|
||||
co[2] = roundf(co[2]);
|
||||
mul_v3_fl(co, grid_size);
|
||||
if (co_relative != NULL) {
|
||||
add_v3_v3(co, co_relative);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void idp_snap_gizmo_update_snap_elements(Scene *scene,
|
||||
enum ePlace_SnapTo snap_to,
|
||||
wmGizmo *gizmo)
|
||||
{
|
||||
const int snap_mode =
|
||||
(snap_to == PLACE_SNAP_TO_GEOMETRY) ?
|
||||
(SCE_SNAP_MODE_VERTEX | SCE_SNAP_MODE_EDGE | SCE_SNAP_MODE_FACE |
|
||||
/* SCE_SNAP_MODE_VOLUME | SCE_SNAP_MODE_GRID | SCE_SNAP_MODE_INCREMENT | */
|
||||
SCE_SNAP_MODE_EDGE_PERPENDICULAR | SCE_SNAP_MODE_EDGE_MIDPOINT) :
|
||||
scene->toolsettings->snap_mode;
|
||||
|
||||
RNA_enum_set(gizmo->ptr, "snap_elements_force", snap_mode);
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
|
@ -784,8 +852,9 @@ static void view3d_interactive_add_calc_plane(bContext *C,
|
|||
Scene *scene,
|
||||
View3D *v3d,
|
||||
ARegion *region,
|
||||
wmGizmo *snap_gizmo,
|
||||
const float mval_fl[2],
|
||||
wmGizmo *snap_gizmo,
|
||||
const enum ePlace_SnapTo snap_to,
|
||||
const enum ePlace_Depth plane_depth,
|
||||
const enum ePlace_Orient plane_orient,
|
||||
const int plane_axis,
|
||||
|
@ -795,6 +864,12 @@ static void view3d_interactive_add_calc_plane(bContext *C,
|
|||
const RegionView3D *rv3d = region->regiondata;
|
||||
ED_transform_calc_orientation_from_type(C, r_matrix_orient);
|
||||
|
||||
/* Non-orthogonal matrices cause the preview and final result not to match.
|
||||
*
|
||||
* While making orthogonal doesn't always work well (especially with gimbal orientation for e.g.)
|
||||
* it's a corner case, without better alternatives as objects don't support shear. */
|
||||
orthogonalize_m3(r_matrix_orient, plane_axis);
|
||||
|
||||
SnapObjectContext *snap_context = NULL;
|
||||
bool snap_context_free = false;
|
||||
|
||||
|
@ -908,6 +983,12 @@ static void view3d_interactive_add_calc_plane(bContext *C,
|
|||
}
|
||||
}
|
||||
|
||||
if (!is_snap_found && ((snap_gizmo != NULL) && ED_gizmotypes_snap_3d_is_enabled(snap_gizmo))) {
|
||||
if (snap_to == PLACE_SNAP_TO_DEFAULT) {
|
||||
idp_snap_calc_incremental(scene, v3d, region, NULL, r_co_src);
|
||||
}
|
||||
}
|
||||
|
||||
if (snap_context_free) {
|
||||
ED_transform_snap_object_context_destroy(snap_context);
|
||||
}
|
||||
|
@ -923,8 +1004,16 @@ static void view3d_interactive_add_begin(bContext *C, wmOperator *op, const wmEv
|
|||
{
|
||||
|
||||
const int plane_axis = RNA_enum_get(op->ptr, "plane_axis");
|
||||
const enum ePlace_SnapTo snap_to = RNA_enum_get(op->ptr, "snap_target");
|
||||
const enum ePlace_Depth plane_depth = RNA_enum_get(op->ptr, "plane_depth");
|
||||
const enum ePlace_Origin plane_origin = RNA_enum_get(op->ptr, "plane_origin");
|
||||
const enum ePlace_Origin plane_origin[2] = {
|
||||
RNA_enum_get(op->ptr, "plane_origin_base"),
|
||||
RNA_enum_get(op->ptr, "plane_origin_depth"),
|
||||
};
|
||||
const enum ePlace_Aspect plane_aspect[2] = {
|
||||
RNA_enum_get(op->ptr, "plane_aspect_base"),
|
||||
RNA_enum_get(op->ptr, "plane_aspect_depth"),
|
||||
};
|
||||
const enum ePlace_Orient plane_orient = RNA_enum_get(op->ptr, "plane_orientation");
|
||||
|
||||
const float mval_fl[2] = {UNPACK2(event->mval)};
|
||||
|
@ -970,8 +1059,9 @@ static void view3d_interactive_add_begin(bContext *C, wmOperator *op, const wmEv
|
|||
ipd->scene,
|
||||
ipd->v3d,
|
||||
ipd->region,
|
||||
ipd->snap_gizmo,
|
||||
mval_fl,
|
||||
ipd->snap_gizmo,
|
||||
snap_to,
|
||||
plane_depth,
|
||||
plane_orient,
|
||||
plane_axis,
|
||||
|
@ -979,10 +1069,16 @@ static void view3d_interactive_add_begin(bContext *C, wmOperator *op, const wmEv
|
|||
ipd->matrix_orient);
|
||||
|
||||
ipd->orient_axis = plane_axis;
|
||||
ipd->is_centered_init = (plane_origin == PLACE_ORIGIN_CENTER);
|
||||
ipd->step[0].is_centered = ipd->is_centered_init;
|
||||
ipd->step[1].is_centered = ipd->is_centered_init;
|
||||
for (int i = 0; i < 2; i++) {
|
||||
ipd->step[i].is_centered_init = (plane_origin[i] == PLACE_ORIGIN_CENTER);
|
||||
ipd->step[i].is_centered = ipd->step[i].is_centered_init;
|
||||
|
||||
ipd->step[i].is_fixed_aspect_init = (plane_aspect[i] == PLACE_ASPECT_FIXED);
|
||||
ipd->step[i].is_fixed_aspect = ipd->step[i].is_fixed_aspect_init;
|
||||
}
|
||||
|
||||
ipd->step_index = STEP_BASE;
|
||||
ipd->snap_to = snap_to;
|
||||
|
||||
plane_from_point_normal_v3(ipd->step[0].plane, ipd->co_src, ipd->matrix_orient[plane_axis]);
|
||||
|
||||
|
@ -1174,7 +1270,7 @@ void viewplace_modal_keymap(wmKeyConfig *keyconf)
|
|||
{0, NULL, 0, NULL, NULL},
|
||||
};
|
||||
|
||||
const char *keymap_name = "View3D Placement Modal Map";
|
||||
const char *keymap_name = "View3D Placement Modal";
|
||||
wmKeyMap *keymap = WM_modalkeymap_find(keyconf, keymap_name);
|
||||
|
||||
/* This function is called for each space-type, only needs to add map once. */
|
||||
|
@ -1206,7 +1302,8 @@ static int view3d_interactive_add_modal(bContext *C, wmOperator *op, const wmEve
|
|||
ATTR_FALLTHROUGH;
|
||||
}
|
||||
case PLACE_MODAL_FIXED_ASPECT_OFF: {
|
||||
ipd->step[ipd->step_index].is_fixed_aspect = is_fallthrough;
|
||||
ipd->step[ipd->step_index].is_fixed_aspect =
|
||||
is_fallthrough ^ ipd->step[ipd->step_index].is_fixed_aspect_init;
|
||||
do_redraw = true;
|
||||
break;
|
||||
}
|
||||
|
@ -1215,7 +1312,8 @@ static int view3d_interactive_add_modal(bContext *C, wmOperator *op, const wmEve
|
|||
ATTR_FALLTHROUGH;
|
||||
}
|
||||
case PLACE_MODAL_PIVOT_CENTER_OFF: {
|
||||
ipd->step[ipd->step_index].is_centered = is_fallthrough;
|
||||
ipd->step[ipd->step_index].is_centered = is_fallthrough ^
|
||||
ipd->step[ipd->step_index].is_centered_init;
|
||||
do_redraw = true;
|
||||
break;
|
||||
}
|
||||
|
@ -1278,9 +1376,13 @@ static int view3d_interactive_add_modal(bContext *C, wmOperator *op, const wmEve
|
|||
copy_v3_v3(ipd->step[1].co_dst, ipd->step[0].co_dst);
|
||||
ipd->step_index = STEP_DEPTH;
|
||||
|
||||
/* Keep these values from the previous step. */
|
||||
ipd->step[1].is_centered = ipd->step[0].is_centered;
|
||||
ipd->step[1].is_fixed_aspect = ipd->step[0].is_fixed_aspect;
|
||||
/* Use the toggle from the previous step. */
|
||||
if (ipd->step[0].is_centered != ipd->step[0].is_centered_init) {
|
||||
ipd->step[1].is_centered = !ipd->step[1].is_centered;
|
||||
}
|
||||
if (ipd->step[0].is_fixed_aspect != ipd->step[0].is_fixed_aspect_init) {
|
||||
ipd->step[1].is_fixed_aspect = !ipd->step[1].is_fixed_aspect;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1354,7 +1456,9 @@ static int view3d_interactive_add_modal(bContext *C, wmOperator *op, const wmEve
|
|||
RNA_float_set_array(&op_props, "location", location);
|
||||
RNA_float_set_array(&op_props, "scale", scale);
|
||||
/* Always use default size here. */
|
||||
RNA_float_set(&op_props, "size", 2.0f);
|
||||
if (ipd->primitive_type == PLACE_PRIMITIVE_TYPE_CUBE) {
|
||||
RNA_float_set(&op_props, "size", 2.0f);
|
||||
}
|
||||
WM_operator_name_call_ptr(C, ot, WM_OP_EXEC_DEFAULT, &op_props);
|
||||
WM_operator_properties_free(&op_props);
|
||||
}
|
||||
|
@ -1407,6 +1511,12 @@ static int view3d_interactive_add_modal(bContext *C, wmOperator *op, const wmEve
|
|||
ipd->step[STEP_BASE].co_dst)) {
|
||||
/* pass */
|
||||
}
|
||||
|
||||
if (ipd->use_snap && (ipd->snap_to == PLACE_SNAP_TO_DEFAULT)) {
|
||||
if (idp_snap_calc_incremental(
|
||||
ipd->scene, ipd->v3d, ipd->region, ipd->co_src, ipd->step[STEP_BASE].co_dst)) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (ipd->step_index == STEP_DEPTH) {
|
||||
|
@ -1423,6 +1533,12 @@ static int view3d_interactive_add_modal(bContext *C, wmOperator *op, const wmEve
|
|||
ipd->step[STEP_DEPTH].co_dst)) {
|
||||
/* pass */
|
||||
}
|
||||
|
||||
if (ipd->use_snap && (ipd->snap_to == PLACE_SNAP_TO_DEFAULT)) {
|
||||
if (idp_snap_calc_incremental(
|
||||
ipd->scene, ipd->v3d, ipd->region, ipd->co_src, ipd->step[STEP_DEPTH].co_dst)) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Correct the point so it's aligned with the 'ipd->step[0].co_dst'. */
|
||||
|
@ -1497,13 +1613,13 @@ void VIEW3D_OT_interactive_add(struct wmOperatorType *ot)
|
|||
{PLACE_DEPTH_CURSOR_PLANE,
|
||||
"CURSOR_PLANE",
|
||||
0,
|
||||
"3D Cursor Plane",
|
||||
"Cursor Plane",
|
||||
"Start placement using a point projected onto the selected axis at the 3D cursor position"},
|
||||
{PLACE_DEPTH_CURSOR_VIEW,
|
||||
"CURSOR_VIEW",
|
||||
0,
|
||||
"3D Cursor View",
|
||||
"Start placement using the mouse cursor projected onto the view plane"},
|
||||
"Cursor View",
|
||||
"Start placement using the 3D cursor projected onto the view plane"},
|
||||
{0, NULL, 0, NULL, NULL},
|
||||
};
|
||||
prop = RNA_def_property(ot->srna, "plane_depth", PROP_ENUM, PROP_NONE);
|
||||
|
@ -1512,17 +1628,6 @@ void VIEW3D_OT_interactive_add(struct wmOperatorType *ot)
|
|||
RNA_def_property_enum_items(prop, plane_depth_items);
|
||||
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
|
||||
|
||||
static const EnumPropertyItem origin_items[] = {
|
||||
{PLACE_ORIGIN_BASE, "BASE", 0, "Base", "Start placing the corner position"},
|
||||
{PLACE_ORIGIN_CENTER, "CENTER", 0, "Center", "Start placing the center position"},
|
||||
{0, NULL, 0, NULL, NULL},
|
||||
};
|
||||
prop = RNA_def_property(ot->srna, "plane_origin", PROP_ENUM, PROP_NONE);
|
||||
RNA_def_property_ui_text(prop, "Origin", "The initial position for placement");
|
||||
RNA_def_property_enum_default(prop, PLACE_ORIGIN_BASE);
|
||||
RNA_def_property_enum_items(prop, origin_items);
|
||||
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
|
||||
|
||||
static const EnumPropertyItem plane_orientation_items[] = {
|
||||
{PLACE_ORIENT_SURFACE,
|
||||
"SURFACE",
|
||||
|
@ -1542,6 +1647,49 @@ void VIEW3D_OT_interactive_add(struct wmOperatorType *ot)
|
|||
RNA_def_property_enum_items(prop, plane_orientation_items);
|
||||
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
|
||||
|
||||
static const EnumPropertyItem snap_to_items[] = {
|
||||
{PLACE_SNAP_TO_GEOMETRY, "GEOMETRY", 0, "Geometry", "Snap to all geometry"},
|
||||
{PLACE_SNAP_TO_DEFAULT, "DEFAULT", 0, "Default", "Use the current snap settings"},
|
||||
{0, NULL, 0, NULL, NULL},
|
||||
};
|
||||
prop = RNA_def_property(ot->srna, "snap_target", PROP_ENUM, PROP_NONE);
|
||||
RNA_def_property_ui_text(prop, "Snap to", "The target to use while snapping");
|
||||
RNA_def_property_enum_default(prop, PLACE_SNAP_TO_GEOMETRY);
|
||||
RNA_def_property_enum_items(prop, snap_to_items);
|
||||
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
|
||||
|
||||
{ /* Plane Origin. */
|
||||
static const EnumPropertyItem items[] = {
|
||||
{PLACE_ORIGIN_BASE, "EDGE", 0, "Edge", "Start placing the edge position"},
|
||||
{PLACE_ORIGIN_CENTER, "CENTER", 0, "Center", "Start placing the center position"},
|
||||
{0, NULL, 0, NULL, NULL},
|
||||
};
|
||||
const char *identifiers[2] = {"plane_origin_base", "plane_origin_depth"};
|
||||
for (int i = 0; i < 2; i++) {
|
||||
prop = RNA_def_property(ot->srna, identifiers[i], PROP_ENUM, PROP_NONE);
|
||||
RNA_def_property_ui_text(prop, "Origin", "The initial position for placement");
|
||||
RNA_def_property_enum_default(prop, PLACE_ORIGIN_BASE);
|
||||
RNA_def_property_enum_items(prop, items);
|
||||
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
|
||||
}
|
||||
}
|
||||
|
||||
{ /* Plane Aspect. */
|
||||
static const EnumPropertyItem items[] = {
|
||||
{PLACE_ASPECT_FREE, "FREE", 0, "Free", "Use an unconstrained aspect"},
|
||||
{PLACE_ASPECT_FIXED, "FIXED", 0, "Fixed", "Use a fixed 1:1 aspect"},
|
||||
{0, NULL, 0, NULL, NULL},
|
||||
};
|
||||
const char *identifiers[2] = {"plane_aspect_base", "plane_aspect_depth"};
|
||||
for (int i = 0; i < 2; i++) {
|
||||
prop = RNA_def_property(ot->srna, identifiers[i], PROP_ENUM, PROP_NONE);
|
||||
RNA_def_property_ui_text(prop, "Aspect", "The initial aspect setting");
|
||||
RNA_def_property_enum_default(prop, PLACE_ASPECT_FREE);
|
||||
RNA_def_property_enum_items(prop, items);
|
||||
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
|
||||
}
|
||||
}
|
||||
|
||||
/* When not accessed via a tool. */
|
||||
prop = RNA_def_boolean(ot->srna, "wait_for_input", true, "Wait for Input", "");
|
||||
RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
|
||||
|
@ -1565,11 +1713,6 @@ static void WIDGETGROUP_placement_setup(const bContext *UNUSED(C), wmGizmoGroup
|
|||
const wmGizmoType *gzt_snap;
|
||||
gzt_snap = WM_gizmotype_find("GIZMO_GT_snap_3d", true);
|
||||
gizmo = WM_gizmo_new_ptr(gzt_snap, gzgroup, NULL);
|
||||
RNA_enum_set(gizmo->ptr,
|
||||
"snap_elements_force",
|
||||
(SCE_SNAP_MODE_VERTEX | SCE_SNAP_MODE_EDGE | SCE_SNAP_MODE_FACE |
|
||||
/* SCE_SNAP_MODE_VOLUME | SCE_SNAP_MODE_GRID | SCE_SNAP_MODE_INCREMENT | */
|
||||
SCE_SNAP_MODE_EDGE_PERPENDICULAR | SCE_SNAP_MODE_EDGE_MIDPOINT));
|
||||
|
||||
WM_gizmo_set_color(gizmo, (float[4]){1.0f, 1.0f, 1.0f, 1.0f});
|
||||
|
||||
|
@ -1622,6 +1765,7 @@ static void gizmo_plane_update_cursor(const bContext *C,
|
|||
bToolRef *tref = area->runtime.tool;
|
||||
WM_toolsystem_ref_properties_ensure_from_operator(tref, ot, &ptr);
|
||||
|
||||
const enum ePlace_SnapTo snap_to = RNA_enum_get(&ptr, "snap_target");
|
||||
const int plane_axis = RNA_enum_get(&ptr, "plane_axis");
|
||||
const enum ePlace_Depth plane_depth = RNA_enum_get(&ptr, "plane_depth");
|
||||
const enum ePlace_Orient plane_orient = RNA_enum_get(&ptr, "plane_orientation");
|
||||
|
@ -1640,12 +1784,19 @@ static void gizmo_plane_update_cursor(const bContext *C,
|
|||
}
|
||||
}
|
||||
|
||||
/* This ensures the snap gizmo has settings from this tool.
|
||||
* This function call could be moved a more appropriate place,
|
||||
* responding to the setting being changed for example,
|
||||
* however setting the value isn't expensive, so do it here. */
|
||||
idp_snap_gizmo_update_snap_elements(scene, snap_to, snap_gizmo);
|
||||
|
||||
view3d_interactive_add_calc_plane((bContext *)C,
|
||||
scene,
|
||||
v3d,
|
||||
region,
|
||||
snap_gizmo,
|
||||
mval_fl,
|
||||
snap_gizmo,
|
||||
snap_to,
|
||||
plane_depth,
|
||||
plane_orient,
|
||||
plane_axis,
|
||||
|
@ -1827,7 +1978,27 @@ static void cursor_plane_draw(bContext *C, int x, int y, void *customdata)
|
|||
}
|
||||
|
||||
/* Draw */
|
||||
const float pixel_size = ED_view3d_pixel_size(rv3d, plc->matrix[3]);
|
||||
float pixel_size;
|
||||
|
||||
/* Arbitrary, 1.0 is a little too strong though. */
|
||||
float color_alpha = 0.75f;
|
||||
|
||||
if (rv3d->is_persp) {
|
||||
float center[3];
|
||||
negate_v3_v3(center, rv3d->ofs);
|
||||
pixel_size = ED_view3d_pixel_size(rv3d, center);
|
||||
|
||||
/* Scale down the alpha when this is drawn very small,
|
||||
* since the add shader causes the small size to show too dense & bright. */
|
||||
const float relative_pixel_scale = pixel_size / ED_view3d_pixel_size(rv3d, plc->matrix[3]);
|
||||
if (relative_pixel_scale < 1.0f) {
|
||||
color_alpha *= max_ff(square_f(relative_pixel_scale), 0.3f);
|
||||
}
|
||||
}
|
||||
else {
|
||||
pixel_size = ED_view3d_pixel_size(rv3d, plc->matrix[3]);
|
||||
}
|
||||
|
||||
if (pixel_size > FLT_EPSILON) {
|
||||
|
||||
/* Setup viewport & matrix. */
|
||||
|
@ -1837,7 +2008,7 @@ static void cursor_plane_draw(bContext *C, int x, int y, void *customdata)
|
|||
GPU_matrix_projection_set(rv3d->winmat);
|
||||
GPU_matrix_set(rv3d->viewmat);
|
||||
|
||||
const float scale_mod = U.gizmo_size * U.dpi_fac;
|
||||
const float scale_mod = U.gizmo_size * 2 * U.dpi_fac;
|
||||
|
||||
float final_scale = (scale_mod * pixel_size);
|
||||
|
||||
|
@ -1849,13 +2020,18 @@ static void cursor_plane_draw(bContext *C, int x, int y, void *customdata)
|
|||
|
||||
float fac = final_scale_fade / final_scale;
|
||||
|
||||
float color[4] = {1, 1, 1, 1};
|
||||
color[3] = square_f(1.0f - fac);
|
||||
gizmo_plane_draw_grid(
|
||||
lines * lines_subdiv, final_scale, final_scale_fade, plc->matrix, plc->plane_axis, color);
|
||||
float color[4] = {1, 1, 1, color_alpha};
|
||||
color[3] *= square_f(1.0f - fac);
|
||||
if (color[3] > 0.0f) {
|
||||
gizmo_plane_draw_grid(lines * lines_subdiv,
|
||||
final_scale,
|
||||
final_scale_fade,
|
||||
plc->matrix,
|
||||
plc->plane_axis,
|
||||
color);
|
||||
}
|
||||
|
||||
/* Arbitrary, 1.0 is a little too strong though. */
|
||||
color[3] = 0.75f;
|
||||
color[3] = color_alpha;
|
||||
/* When the grid is large, we only need the 2x lines in the middle. */
|
||||
if (fac < 0.2f) {
|
||||
lines = 1;
|
||||
|
|
|
@ -135,7 +135,7 @@ static void createTransGPencil_curves(bContext *C,
|
|||
continue;
|
||||
}
|
||||
/* Check if the color is editable. */
|
||||
if (ED_gpencil_stroke_color_use(obact, gpl, gps) == false) {
|
||||
if (ED_gpencil_stroke_material_editable(obact, gpl, gps) == false) {
|
||||
continue;
|
||||
}
|
||||
/* Check if stroke has an editcurve */
|
||||
|
@ -242,7 +242,7 @@ static void createTransGPencil_curves(bContext *C,
|
|||
}
|
||||
|
||||
/* Calculate difference matrix. */
|
||||
BKE_gpencil_parent_matrix_get(depsgraph, obact, gpl, diff_mat);
|
||||
BKE_gpencil_layer_transform_matrix_get(depsgraph, obact, gpl, diff_mat);
|
||||
copy_m3_m4(mtx, diff_mat);
|
||||
pseudoinverse_m3_m3(smtx, mtx, PSEUDOINVERSE_EPSILON);
|
||||
|
||||
|
@ -263,7 +263,7 @@ static void createTransGPencil_curves(bContext *C,
|
|||
continue;
|
||||
}
|
||||
/* Check if the color is editable. */
|
||||
if (ED_gpencil_stroke_color_use(obact, gpl, gps) == false) {
|
||||
if (ED_gpencil_stroke_material_editable(obact, gpl, gps) == false) {
|
||||
continue;
|
||||
}
|
||||
/* Check if stroke has an editcurve */
|
||||
|
@ -436,7 +436,7 @@ static void createTransGPencil_strokes(bContext *C,
|
|||
continue;
|
||||
}
|
||||
/* Check if the color is editable. */
|
||||
if (ED_gpencil_stroke_color_use(obact, gpl, gps) == false) {
|
||||
if (ED_gpencil_stroke_material_editable(obact, gpl, gps) == false) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -507,7 +507,7 @@ static void createTransGPencil_strokes(bContext *C,
|
|||
}
|
||||
|
||||
/* Calculate difference matrix. */
|
||||
BKE_gpencil_parent_matrix_get(depsgraph, obact, gpl, diff_mat);
|
||||
BKE_gpencil_layer_transform_matrix_get(depsgraph, obact, gpl, diff_mat);
|
||||
/* Undo matrix. */
|
||||
invert_m4_m4(inverse_diff_mat, diff_mat);
|
||||
|
||||
|
@ -551,7 +551,7 @@ static void createTransGPencil_strokes(bContext *C,
|
|||
continue;
|
||||
}
|
||||
/* check if the color is editable */
|
||||
if (ED_gpencil_stroke_color_use(obact, gpl, gps) == false) {
|
||||
if (ED_gpencil_stroke_material_editable(obact, gpl, gps) == false) {
|
||||
continue;
|
||||
}
|
||||
/* What we need to include depends on proportional editing settings... */
|
||||
|
|
|
@ -55,9 +55,7 @@ static float *mesh_skin_transdata_center(const struct TransIslandData *island_da
|
|||
if (island_data->center && island_index != -1) {
|
||||
return island_data->center[island_index];
|
||||
}
|
||||
else {
|
||||
return eve->co;
|
||||
}
|
||||
return eve->co;
|
||||
}
|
||||
|
||||
static void mesh_skin_transdata_create(TransDataBasic *td,
|
||||
|
|
|
@ -36,6 +36,7 @@
|
|||
#include "ED_markers.h"
|
||||
|
||||
#include "WM_api.h"
|
||||
#include "WM_types.h"
|
||||
|
||||
#include "RNA_access.h"
|
||||
|
||||
|
@ -554,6 +555,12 @@ void special_aftertrans_update__nla(bContext *C, TransInfo *UNUSED(t))
|
|||
BKE_nlastrips_clear_metas(&nlt->strips, 0, 1);
|
||||
}
|
||||
|
||||
/* General refresh for the outliner because the following might have happened:
|
||||
* - strips moved between tracks
|
||||
* - strips swapped order
|
||||
* - duplicate-move moves to different track. */
|
||||
WM_event_add_notifier(C, NC_ANIMATION | ND_NLA | NA_ADDED, NULL);
|
||||
|
||||
/* free temp memory */
|
||||
ANIM_animdata_freelist(&anim_data);
|
||||
|
||||
|
|
|
@ -704,7 +704,7 @@ int ED_transform_calc_gizmo_stats(const bContext *C,
|
|||
if (BKE_gpencil_layer_is_editable(gpl) && (gpl->actframe != NULL)) {
|
||||
|
||||
/* calculate difference matrix */
|
||||
BKE_gpencil_parent_matrix_get(depsgraph, ob, gpl, diff_mat);
|
||||
BKE_gpencil_layer_transform_matrix_get(depsgraph, ob, gpl, diff_mat);
|
||||
|
||||
LISTBASE_FOREACH (bGPDstroke *, gps, &gpl->actframe->strokes) {
|
||||
/* skip strokes that are invalid for current view */
|
||||
|
|
|
@ -500,6 +500,15 @@ void ED_transform_calc_orientation_from_type(const bContext *C, float r_mat[3][3
|
|||
C, r_mat, scene, rv3d, ob, obedit, orientation_type, orientation_index_custom, pivot_point);
|
||||
}
|
||||
|
||||
/**
|
||||
* \note The resulting matrix may not be orthogonal,
|
||||
* callers that depend on `r_mat` to be orthogonal should use #orthogonalize_m3.
|
||||
*
|
||||
* A non orthogonal matrix may be returned when:
|
||||
* - #V3D_ORIENT_GIMBAL the result won't be orthogonal unless the object has no rotation.
|
||||
* - #V3D_ORIENT_LOCAL may contain shear from non-uniform scale in parent/child relationships.
|
||||
* - #V3D_ORIENT_CUSTOM may have been created from #V3D_ORIENT_LOCAL.
|
||||
*/
|
||||
short ED_transform_calc_orientation_from_type_ex(const bContext *C,
|
||||
float r_mat[3][3],
|
||||
/* extra args (can be accessed from context) */
|
||||
|
|
|
@ -299,83 +299,93 @@ eRedrawFlag handleSnapping(TransInfo *t, const wmEvent *event)
|
|||
|
||||
void applyProject(TransInfo *t)
|
||||
{
|
||||
if (!t->tsnap.project) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!activeSnap(t) || (t->flag & T_NO_PROJECT)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (doForceIncrementSnap(t)) {
|
||||
return;
|
||||
}
|
||||
|
||||
float tvec[3];
|
||||
int i;
|
||||
|
||||
/* XXX FLICKER IN OBJECT MODE */
|
||||
if ((t->tsnap.project) && activeSnap(t) && (t->flag & T_NO_PROJECT) == 0) {
|
||||
float tvec[3];
|
||||
int i;
|
||||
FOREACH_TRANS_DATA_CONTAINER (t, tc) {
|
||||
TransData *td = tc->data;
|
||||
for (i = 0; i < tc->data_len; i++, td++) {
|
||||
float iloc[3], loc[3], no[3];
|
||||
float mval_fl[2];
|
||||
if (td->flag & TD_SKIP) {
|
||||
continue;
|
||||
}
|
||||
|
||||
FOREACH_TRANS_DATA_CONTAINER (t, tc) {
|
||||
TransData *td = tc->data;
|
||||
for (i = 0; i < tc->data_len; i++, td++) {
|
||||
float iloc[3], loc[3], no[3];
|
||||
float mval_fl[2];
|
||||
if (td->flag & TD_SKIP) {
|
||||
continue;
|
||||
}
|
||||
if ((t->flag & T_PROP_EDIT) && (td->factor == 0.0f)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((t->flag & T_PROP_EDIT) && (td->factor == 0.0f)) {
|
||||
continue;
|
||||
}
|
||||
copy_v3_v3(iloc, td->loc);
|
||||
if (tc->use_local_mat) {
|
||||
mul_m4_v3(tc->mat, iloc);
|
||||
}
|
||||
else if (t->flag & T_OBJECT) {
|
||||
BKE_object_eval_transform_all(t->depsgraph, t->scene, td->ob);
|
||||
copy_v3_v3(iloc, td->ob->obmat[3]);
|
||||
}
|
||||
|
||||
copy_v3_v3(iloc, td->loc);
|
||||
if (tc->use_local_mat) {
|
||||
mul_m4_v3(tc->mat, iloc);
|
||||
}
|
||||
else if (t->flag & T_OBJECT) {
|
||||
BKE_object_eval_transform_all(t->depsgraph, t->scene, td->ob);
|
||||
copy_v3_v3(iloc, td->ob->obmat[3]);
|
||||
}
|
||||
|
||||
if (ED_view3d_project_float_global(t->region, iloc, mval_fl, V3D_PROJ_TEST_NOP) ==
|
||||
V3D_PROJ_RET_OK) {
|
||||
if (ED_transform_snap_object_project_view3d(
|
||||
t->tsnap.object_context,
|
||||
t->depsgraph,
|
||||
SCE_SNAP_MODE_FACE,
|
||||
&(const struct SnapObjectParams){
|
||||
.snap_select = t->tsnap.modeSelect,
|
||||
.use_object_edit_cage = (t->flag & T_EDIT) != 0,
|
||||
.use_occlusion_test = false,
|
||||
.use_backface_culling = t->tsnap.use_backface_culling,
|
||||
},
|
||||
mval_fl,
|
||||
NULL,
|
||||
0,
|
||||
loc,
|
||||
no)) {
|
||||
if (ED_view3d_project_float_global(t->region, iloc, mval_fl, V3D_PROJ_TEST_NOP) ==
|
||||
V3D_PROJ_RET_OK) {
|
||||
if (ED_transform_snap_object_project_view3d(
|
||||
t->tsnap.object_context,
|
||||
t->depsgraph,
|
||||
SCE_SNAP_MODE_FACE,
|
||||
&(const struct SnapObjectParams){
|
||||
.snap_select = t->tsnap.modeSelect,
|
||||
.use_object_edit_cage = (t->flag & T_EDIT) != 0,
|
||||
.use_occlusion_test = false,
|
||||
.use_backface_culling = t->tsnap.use_backface_culling,
|
||||
},
|
||||
mval_fl,
|
||||
NULL,
|
||||
0,
|
||||
loc,
|
||||
no)) {
|
||||
#if 0
|
||||
if (tc->use_local_mat) {
|
||||
mul_m4_v3(tc->imat, loc);
|
||||
}
|
||||
#endif
|
||||
|
||||
sub_v3_v3v3(tvec, loc, iloc);
|
||||
sub_v3_v3v3(tvec, loc, iloc);
|
||||
|
||||
mul_m3_v3(td->smtx, tvec);
|
||||
mul_m3_v3(td->smtx, tvec);
|
||||
|
||||
add_v3_v3(td->loc, tvec);
|
||||
add_v3_v3(td->loc, tvec);
|
||||
|
||||
if (t->tsnap.align && (t->flag & T_OBJECT)) {
|
||||
/* handle alignment as well */
|
||||
const float *original_normal;
|
||||
float mat[3][3];
|
||||
if (t->tsnap.align && (t->flag & T_OBJECT)) {
|
||||
/* handle alignment as well */
|
||||
const float *original_normal;
|
||||
float mat[3][3];
|
||||
|
||||
/* In pose mode, we want to align normals with Y axis of bones... */
|
||||
original_normal = td->axismtx[2];
|
||||
/* In pose mode, we want to align normals with Y axis of bones... */
|
||||
original_normal = td->axismtx[2];
|
||||
|
||||
rotation_between_vecs_to_mat3(mat, original_normal, no);
|
||||
rotation_between_vecs_to_mat3(mat, original_normal, no);
|
||||
|
||||
transform_data_ext_rotate(td, mat, true);
|
||||
transform_data_ext_rotate(td, mat, true);
|
||||
|
||||
/* TODO support constraints for rotation too? see ElementRotation */
|
||||
}
|
||||
/* TODO support constraints for rotation too? see ElementRotation */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if 0 /* TODO: sipport this? */
|
||||
constraintTransLim(t, td);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -515,7 +515,7 @@ typedef enum ID_Type {
|
|||
((const ID *)(_id))->override_library->reference != NULL)
|
||||
|
||||
#define ID_IS_OVERRIDE_LIBRARY_VIRTUAL(_id) \
|
||||
((((const ID *)(_id))->flag & (LIB_EMBEDDED_DATA_LIB_OVERRIDE | LIB_EMBEDDED_DATA)) != 0)
|
||||
((((const ID *)(_id))->flag & LIB_EMBEDDED_DATA_LIB_OVERRIDE) != 0)
|
||||
|
||||
#define ID_IS_OVERRIDE_LIBRARY(_id) \
|
||||
(ID_IS_OVERRIDE_LIBRARY_REAL(_id) || ID_IS_OVERRIDE_LIBRARY_VIRTUAL(_id))
|
||||
|
|
|
@ -512,6 +512,11 @@ typedef struct bGPDlayer {
|
|||
int act_mask;
|
||||
char _pad2[4];
|
||||
|
||||
/** Layer transforms. */
|
||||
float location[3], rotation[3], scale[3];
|
||||
float layer_mat[4][4], layer_invmat[4][4];
|
||||
char _pad3[4];
|
||||
|
||||
bGPDlayer_Runtime runtime;
|
||||
} bGPDlayer;
|
||||
|
||||
|
|
|
@ -141,7 +141,7 @@ typedef struct MovieTrackingTrack {
|
|||
/** Count of markers in track. */
|
||||
int markersnr;
|
||||
/** Most recently used marker. */
|
||||
int last_marker;
|
||||
int _pad;
|
||||
/** Markers in track. */
|
||||
MovieTrackingMarker *markers;
|
||||
|
||||
|
@ -251,8 +251,6 @@ typedef struct MovieTrackingPlaneTrack {
|
|||
} MovieTrackingPlaneTrack;
|
||||
|
||||
typedef struct MovieTrackingSettings {
|
||||
int flag;
|
||||
|
||||
/* ** default tracker settings */
|
||||
/** Model of the motion for this track. */
|
||||
short default_motion_model;
|
||||
|
@ -309,8 +307,6 @@ typedef struct MovieTrackingSettings {
|
|||
/* set object scale */
|
||||
/** Distance between two bundles used for object scaling. */
|
||||
float object_distance;
|
||||
|
||||
char _pad3[4];
|
||||
} MovieTrackingSettings;
|
||||
|
||||
typedef struct MovieTrackingStabilization {
|
||||
|
@ -526,11 +522,6 @@ typedef enum eTrackFrameMatch {
|
|||
TRACK_MATCH_PREVIOS_FRAME = 1,
|
||||
} eTrackFrameMatch;
|
||||
|
||||
/* MovieTrackingSettings->flag */
|
||||
enum {
|
||||
TRACKING_SETTINGS_SHOW_DEFAULT_EXPANDED = (1 << 0),
|
||||
TRACKING_SETTINGS_SHOW_EXTRA_EXPANDED = (1 << 1),
|
||||
};
|
||||
|
||||
/* MovieTrackingSettings->motion_flag */
|
||||
enum {
|
||||
|
|
|
@ -643,9 +643,8 @@ typedef struct UserDef_Experimental {
|
|||
char use_sculpt_vertex_colors;
|
||||
char use_switch_object_operator;
|
||||
char use_sculpt_tools_tilt;
|
||||
char use_object_add_tool;
|
||||
char use_asset_browser;
|
||||
char _pad[6];
|
||||
char _pad[7];
|
||||
/** `makesdna` does not allow empty structs. */
|
||||
} UserDef_Experimental;
|
||||
|
||||
|
|
|
@ -566,7 +566,6 @@ static void rna_def_attribute(BlenderRNA *brna)
|
|||
RNA_def_struct_path_func(srna, "rna_Attribute_path");
|
||||
|
||||
prop = RNA_def_property(srna, "name", PROP_STRING, PROP_NONE);
|
||||
RNA_def_struct_name_property(srna, prop);
|
||||
RNA_def_property_string_funcs(prop, NULL, NULL, "rna_Attribute_name_set");
|
||||
RNA_def_property_editable_func(prop, "rna_Attribute_name_editable");
|
||||
RNA_def_property_ui_text(prop, "Name", "Name of the Attribute");
|
||||
|
|
|
@ -1125,6 +1125,11 @@ void RNA_def_struct_name_property(struct StructRNA *srna, struct PropertyRNA *pr
|
|||
CLOG_ERROR(&LOG, "\"%s.%s\", must be a string property.", srna->identifier, prop->identifier);
|
||||
DefRNA.error = true;
|
||||
}
|
||||
else if (srna->nameproperty != NULL) {
|
||||
CLOG_ERROR(
|
||||
&LOG, "\"%s.%s\", name property is already set.", srna->identifier, prop->identifier);
|
||||
DefRNA.error = true;
|
||||
}
|
||||
else {
|
||||
srna->nameproperty = prop;
|
||||
}
|
||||
|
|
|
@ -182,6 +182,16 @@ static void rna_GPencil_update(Main *UNUSED(bmain), Scene *UNUSED(scene), Pointe
|
|||
WM_main_add_notifier(NC_GPENCIL | NA_EDITED, NULL);
|
||||
}
|
||||
|
||||
static void rna_GpencilLayerMatrix_update(Main *bmain, Scene *scene, PointerRNA *ptr)
|
||||
{
|
||||
bGPDlayer *gpl = (bGPDlayer *)ptr->data;
|
||||
|
||||
loc_eul_size_to_mat4(gpl->layer_mat, gpl->location, gpl->rotation, gpl->scale);
|
||||
invert_m4_m4(gpl->layer_invmat, gpl->layer_mat);
|
||||
|
||||
rna_GPencil_update(bmain, scene, ptr);
|
||||
}
|
||||
|
||||
static void rna_GPencil_curve_edit_mode_toggle(Main *bmain, Scene *scene, PointerRNA *ptr)
|
||||
{
|
||||
ToolSettings *ts = scene->toolsettings;
|
||||
|
@ -2012,6 +2022,45 @@ static void rna_def_gpencil_layer(BlenderRNA *brna)
|
|||
RNA_def_property_ui_text(prop, "Blend Mode", "Blend mode");
|
||||
RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update");
|
||||
|
||||
/* Layer transforms. */
|
||||
prop = RNA_def_property(srna, "location", PROP_FLOAT, PROP_TRANSLATION);
|
||||
RNA_def_property_float_sdna(prop, NULL, "location");
|
||||
RNA_def_property_ui_text(prop, "Location", "Values for change location");
|
||||
RNA_def_property_ui_range(prop, -FLT_MAX, FLT_MAX, 1, RNA_TRANSLATION_PREC_DEFAULT);
|
||||
RNA_def_property_update(prop, 0, "rna_GpencilLayerMatrix_update");
|
||||
|
||||
prop = RNA_def_property(srna, "rotation", PROP_FLOAT, PROP_EULER);
|
||||
RNA_def_property_float_sdna(prop, NULL, "rotation");
|
||||
RNA_def_property_ui_text(prop, "Rotation", "Values for changes in rotation");
|
||||
RNA_def_property_ui_range(prop, -FLT_MAX, FLT_MAX, 1, RNA_TRANSLATION_PREC_DEFAULT);
|
||||
RNA_def_property_update(prop, 0, "rna_GpencilLayerMatrix_update");
|
||||
|
||||
prop = RNA_def_property(srna, "scale", PROP_FLOAT, PROP_XYZ);
|
||||
RNA_def_property_float_sdna(prop, NULL, "scale");
|
||||
RNA_def_property_float_default(prop, 1.0f);
|
||||
RNA_def_property_ui_text(prop, "Scale", "Values for changes in scale");
|
||||
RNA_def_property_ui_range(prop, -FLT_MAX, FLT_MAX, 1, RNA_TRANSLATION_PREC_DEFAULT);
|
||||
RNA_def_property_update(prop, 0, "rna_GpencilLayerMatrix_update");
|
||||
|
||||
/* Layer matrix. */
|
||||
prop = RNA_def_property(srna, "matrix_layer", PROP_FLOAT, PROP_MATRIX);
|
||||
RNA_def_property_float_sdna(prop, NULL, "layer_mat");
|
||||
RNA_def_property_multi_array(prop, 2, rna_matrix_dimsize_4x4);
|
||||
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
|
||||
RNA_def_property_override_flag(prop, PROPOVERRIDE_NO_COMPARISON);
|
||||
RNA_def_property_override_clear_flag(prop, PROPOVERRIDE_OVERRIDABLE_LIBRARY);
|
||||
RNA_def_property_ui_text(prop, "Matrix Layer", "Local Layer transformation matrix");
|
||||
|
||||
/* Layer inverse matrix. */
|
||||
prop = RNA_def_property(srna, "matrix_inverse_layer", PROP_FLOAT, PROP_MATRIX);
|
||||
RNA_def_property_float_sdna(prop, NULL, "layer_invmat");
|
||||
RNA_def_property_multi_array(prop, 2, rna_matrix_dimsize_4x4);
|
||||
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
|
||||
RNA_def_property_override_flag(prop, PROPOVERRIDE_NO_COMPARISON);
|
||||
RNA_def_property_override_clear_flag(prop, PROPOVERRIDE_OVERRIDABLE_LIBRARY);
|
||||
RNA_def_property_ui_text(
|
||||
prop, "Matrix Layer Inverse", "Local Layer transformation inverse matrix");
|
||||
|
||||
/* Flags */
|
||||
prop = RNA_def_property(srna, "hide", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_LAYER_HIDE);
|
||||
|
|
|
@ -138,8 +138,22 @@ static char *rna_PoseBone_path(PointerRNA *ptr)
|
|||
|
||||
/* Bone groups only. */
|
||||
|
||||
static bActionGroup *rna_bone_group_new(ID *id, bPose *pose, const char *name)
|
||||
static bool rna_bone_group_poll(Object *ob, ReportList *reports)
|
||||
{
|
||||
if ((ob->proxy != NULL) || (ob->proxy_group != NULL) || ID_IS_OVERRIDE_LIBRARY(ob)) {
|
||||
BKE_report(reports, RPT_ERROR, "Cannot edit bonegroups for proxies or library overrides");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bActionGroup *rna_bone_group_new(ID *id, bPose *pose, ReportList *reports, const char *name)
|
||||
{
|
||||
if (!rna_bone_group_poll((Object *)id, reports)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bActionGroup *grp = BKE_pose_add_group(pose, name);
|
||||
WM_main_add_notifier(NC_OBJECT | ND_POSE | NA_ADDED, id);
|
||||
return grp;
|
||||
|
@ -147,6 +161,10 @@ static bActionGroup *rna_bone_group_new(ID *id, bPose *pose, const char *name)
|
|||
|
||||
static void rna_bone_group_remove(ID *id, bPose *pose, ReportList *reports, PointerRNA *grp_ptr)
|
||||
{
|
||||
if (!rna_bone_group_poll((Object *)id, reports)) {
|
||||
return;
|
||||
}
|
||||
|
||||
bActionGroup *grp = grp_ptr->data;
|
||||
const int grp_idx = BLI_findindex(&pose->agroups, grp);
|
||||
|
||||
|
@ -163,6 +181,11 @@ static void rna_bone_group_remove(ID *id, bPose *pose, ReportList *reports, Poin
|
|||
|
||||
void rna_ActionGroup_colorset_set(PointerRNA *ptr, int value)
|
||||
{
|
||||
Object *ob = (Object *)ptr->owner_id;
|
||||
if (!rna_bone_group_poll(ob, NULL)) {
|
||||
return;
|
||||
}
|
||||
|
||||
bActionGroup *grp = ptr->data;
|
||||
|
||||
/* ensure only valid values get set */
|
||||
|
@ -184,6 +207,10 @@ bool rna_ActionGroup_is_custom_colorset_get(PointerRNA *ptr)
|
|||
static void rna_BoneGroup_name_set(PointerRNA *ptr, const char *value)
|
||||
{
|
||||
Object *ob = (Object *)ptr->owner_id;
|
||||
if (!rna_bone_group_poll(ob, NULL)) {
|
||||
return;
|
||||
}
|
||||
|
||||
bActionGroup *agrp = ptr->data;
|
||||
|
||||
/* copy the new name into the name slot */
|
||||
|
@ -1619,7 +1646,7 @@ static void rna_def_bone_groups(BlenderRNA *brna, PropertyRNA *cprop)
|
|||
|
||||
func = RNA_def_function(srna, "new", "rna_bone_group_new");
|
||||
RNA_def_function_ui_description(func, "Add a new bone group to the object");
|
||||
RNA_def_function_flag(func, FUNC_USE_SELF_ID); /* ID needed for refresh */
|
||||
RNA_def_function_flag(func, FUNC_USE_SELF_ID | FUNC_USE_REPORTS); /* ID needed for refresh */
|
||||
RNA_def_string(func, "name", "Group", MAX_NAME, "", "Name of the new group");
|
||||
/* return type */
|
||||
parm = RNA_def_pointer(func, "group", "BoneGroup", "", "New bone group");
|
||||
|
|
|
@ -1081,7 +1081,6 @@ static void rna_def_render_pass(BlenderRNA *brna)
|
|||
prop = RNA_def_property(srna, "fullname", PROP_STRING, PROP_NONE);
|
||||
RNA_def_property_string_sdna(prop, NULL, "fullname");
|
||||
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
|
||||
RNA_def_struct_name_property(srna, prop);
|
||||
|
||||
prop = RNA_def_property(srna, "name", PROP_STRING, PROP_NONE);
|
||||
RNA_def_property_string_sdna(prop, NULL, "name");
|
||||
|
|
|
@ -976,22 +976,6 @@ static void rna_def_trackingSettings(BlenderRNA *brna)
|
|||
RNA_def_property_enum_items(prop, cleanup_items);
|
||||
RNA_def_property_ui_text(prop, "Action", "Cleanup action to execute");
|
||||
|
||||
/* ** default tracker settings ** */
|
||||
prop = RNA_def_property(srna, "show_default_expanded", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "flag", TRACKING_SETTINGS_SHOW_DEFAULT_EXPANDED);
|
||||
RNA_def_property_ui_text(
|
||||
prop, "Show Expanded", "Show default options expanded in the user interface");
|
||||
RNA_def_property_ui_icon(prop, ICON_DISCLOSURE_TRI_RIGHT, 1);
|
||||
|
||||
/* ** extra tracker settings ** */
|
||||
prop = RNA_def_property(srna, "show_extra_expanded", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "flag", TRACKING_SETTINGS_SHOW_EXTRA_EXPANDED);
|
||||
RNA_def_property_ui_text(
|
||||
prop, "Show Expanded", "Show extra options expanded in the user interface");
|
||||
RNA_def_property_ui_icon(prop, ICON_DISCLOSURE_TRI_RIGHT, 1);
|
||||
|
||||
/* solver settings */
|
||||
prop = RNA_def_property(srna, "use_tripod_solver", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
|
||||
|
|
|
@ -6225,11 +6225,6 @@ static void rna_def_userdef_experimental(BlenderRNA *brna)
|
|||
RNA_def_property_ui_text(
|
||||
prop, "Sculpt Mode Tilt Support", "Support for pen tablet tilt events in Sculpt Mode");
|
||||
|
||||
prop = RNA_def_property(srna, "use_object_add_tool", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "use_object_add_tool", 1);
|
||||
RNA_def_property_ui_text(
|
||||
prop, "Add Object Tool", "Show add object tool in the toolbar in Object Mode and Edit Mode");
|
||||
|
||||
prop = RNA_def_property(srna, "use_asset_browser", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "use_asset_browser", 1);
|
||||
RNA_def_property_ui_text(
|
||||
|
|
|
@ -272,7 +272,6 @@ static void rna_def_workspace_tool(BlenderRNA *brna)
|
|||
|
||||
prop = RNA_def_property(srna, "idname_fallback", PROP_STRING, PROP_NONE);
|
||||
RNA_def_property_ui_text(prop, "Identifier Fallback", "");
|
||||
RNA_def_struct_name_property(srna, prop);
|
||||
|
||||
prop = RNA_def_property(srna, "index", PROP_INT, PROP_NONE);
|
||||
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
|
||||
|
|
|
@ -32,6 +32,8 @@
|
|||
|
||||
#include "RNA_access.h"
|
||||
|
||||
#include "node_common.h"
|
||||
|
||||
bNodeTreeType *ntreeType_Geometry;
|
||||
|
||||
static void geometry_node_tree_get_from_context(const bContext *C,
|
||||
|
@ -63,6 +65,12 @@ static void geometry_node_tree_get_from_context(const bContext *C,
|
|||
}
|
||||
}
|
||||
|
||||
static void geometry_node_tree_update(bNodeTree *ntree)
|
||||
{
|
||||
/* Needed to give correct types to reroutes. */
|
||||
ntree_update_reroute_nodes(ntree);
|
||||
}
|
||||
|
||||
void register_node_tree_type_geo(void)
|
||||
{
|
||||
bNodeTreeType *tt = ntreeType_Geometry = static_cast<bNodeTreeType *>(
|
||||
|
@ -73,7 +81,7 @@ void register_node_tree_type_geo(void)
|
|||
tt->ui_icon = 0; /* defined in drawnode.c */
|
||||
strcpy(tt->ui_description, N_("Geometry nodes"));
|
||||
tt->rna_ext.srna = &RNA_GeometryNodeTree;
|
||||
|
||||
tt->update = geometry_node_tree_update;
|
||||
tt->get_from_context = geometry_node_tree_get_from_context;
|
||||
|
||||
ntreeTypeAdd(tt);
|
||||
|
|
|
@ -392,6 +392,7 @@ typedef struct wmNotifier {
|
|||
#define ND_NLA (73 << 16)
|
||||
#define ND_NLA_ACTCHANGE (74 << 16)
|
||||
#define ND_FCURVES_ORDER (75 << 16)
|
||||
#define ND_NLA_ORDER (76 << 16)
|
||||
|
||||
/* NC_GPENCIL */
|
||||
#define ND_GPENCIL_EDITMODE (85 << 16)
|
||||
|
|
Loading…
Reference in New Issue