Merge branch 'master' into sculpt-dev

This commit is contained in:
Pablo Dobarro 2021-01-18 22:26:46 +01:00
commit 65cea9523e
78 changed files with 1623 additions and 478 deletions

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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', []),

View File

@ -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),

View File

@ -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")

View File

@ -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):

View File

@ -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()

View File

@ -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,

View File

@ -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")),
),
)

View File

@ -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);

View File

@ -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]);

View File

@ -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);
}
}

View File

@ -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);
}

View File

@ -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. */

View File

@ -40,6 +40,7 @@
#include "MEM_guardedalloc.h"
#include <cctype>
#include <cstring>
#include <iomanip>
#include <sstream>

View File

@ -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);
}
}
}
}

View File

@ -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);

View File

@ -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:

View File

@ -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];
}

View File

@ -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,

View File

@ -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

View File

@ -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;
}
}
}
}

View File

@ -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);
}

View File

@ -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;

View File

@ -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++;
}

View File

@ -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;
}

View File

@ -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;

View File

@ -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)

View File

@ -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};

View File

@ -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);

View File

@ -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;
}

View File

@ -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. */

View File

@ -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 */

View File

@ -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 ... */

View File

@ -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;
}

View File

@ -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) {

View File

@ -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 */

View File

@ -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) {

View File

@ -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) {

View File

@ -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.

View File

@ -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;
}

View File

@ -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);
}
}
}

View File

@ -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);
}
}
}

View File

@ -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,

View File

@ -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,

View File

@ -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);

View File

@ -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;

View File

@ -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) {

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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();
}

View File

@ -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);

View File

@ -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);

View File

@ -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 {

View File

@ -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;

View File

@ -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;

View File

@ -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:

View File

@ -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;

View File

@ -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... */

View File

@ -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,

View File

@ -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);

View File

@ -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 */

View File

@ -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) */

View File

@ -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
}
}
}
}

View File

@ -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))

View File

@ -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;

View File

@ -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 {

View File

@ -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;

View File

@ -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");

View File

@ -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;
}

View File

@ -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);

View File

@ -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");

View File

@ -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");

View File

@ -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);

View File

@ -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(

View File

@ -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);

View File

@ -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);

View File

@ -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)