Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Sharybin <sergey@blender.org>2020-12-31 17:13:50 +0300
committerSergey Sharybin <sergey@blender.org>2021-01-21 14:37:50 +0300
commite4feadde90375222858989a600fbc40a4627150b (patch)
tree2a395f9cc75c2349f3305dce483edcf8adbfce64
parent35f379ba26fb6edcde6a9f8248457fc473d114d6 (diff)
Tracking: Implement proportional editingtracking_proportional_editing_v2
Disclaimer: This is a work-in-progress, to find best and optimal workflow, user interface, defaults, and so on. To test the new functionality: 1. Enable proportional editing. 2. Grab marker. The expected behavior is that in this configuration the transform will be smoothly propagated up to keyframe or up to end of tracked segment (whatever happens sooner). Allows to address issue of sudden jump in track when correcting sliding marker. Differential Revision: https://developer.blender.org/D2771
-rw-r--r--release/scripts/presets/keyconfig/keymap_data/blender_default.py2
-rw-r--r--release/scripts/startup/bl_ui/space_clip.py36
-rw-r--r--source/blender/editors/transform/transform.c6
-rw-r--r--source/blender/editors/transform/transform.h33
-rw-r--r--source/blender/editors/transform/transform_constraints.c3
-rw-r--r--source/blender/editors/transform/transform_convert.c4
-rw-r--r--source/blender/editors/transform/transform_convert_tracking.c143
-rw-r--r--source/blender/editors/transform/transform_generics.c16
-rw-r--r--source/blender/editors/transform/transform_mode.c12
-rw-r--r--source/blender/editors/transform/transform_mode_translate.c6
10 files changed, 211 insertions, 50 deletions
diff --git a/release/scripts/presets/keyconfig/keymap_data/blender_default.py b/release/scripts/presets/keyconfig/keymap_data/blender_default.py
index 287322e9a29..86c9efb5851 100644
--- a/release/scripts/presets/keyconfig/keymap_data/blender_default.py
+++ b/release/scripts/presets/keyconfig/keymap_data/blender_default.py
@@ -2897,6 +2897,8 @@ def km_clip_editor(params):
("clip.copy_tracks", {"type": 'C', "value": 'PRESS', "ctrl": True}, None),
("clip.paste_tracks", {"type": 'V', "value": 'PRESS', "ctrl": True}, None),
*_template_items_context_menu("CLIP_MT_tracking_context_menu", params.context_menu_event),
+ *_template_items_proportional_editing(
+ params, connected=False, toggle_data_path='tool_settings.use_proportional_edit'),
])
if not params.legacy:
diff --git a/release/scripts/startup/bl_ui/space_clip.py b/release/scripts/startup/bl_ui/space_clip.py
index 96920af1c7e..3e40eab519d 100644
--- a/release/scripts/startup/bl_ui/space_clip.py
+++ b/release/scripts/startup/bl_ui/space_clip.py
@@ -125,6 +125,21 @@ class CLIP_PT_clip_display(Panel):
col.prop(clip, "display_aspect", text="Display Aspect Ratio")
+class CLIP_PT_proportional_edit(Panel):
+ bl_space_type = 'CLIP_EDITOR'
+ bl_region_type = 'HEADER'
+ bl_label = "Proportional Editing"
+ bl_ui_units_x = 8
+
+ def draw(self, context):
+ layout = self.layout
+ tool_settings = context.tool_settings
+ col = layout.column()
+ col.active = tool_settings.use_proportional_edit
+
+ col.prop(tool_settings, "proportional_edit_falloff", expand=True)
+
+
class CLIP_HT_header(Header):
bl_space_type = 'CLIP_EDITOR'
@@ -181,6 +196,7 @@ class CLIP_HT_header(Header):
if sc.view == 'CLIP':
r = active_object.reconstruction
+ tool_settings = context.tool_settings
if r.is_valid and sc.view == 'CLIP':
layout.label(text="Solve error: %.2f px" %
@@ -188,6 +204,25 @@ class CLIP_HT_header(Header):
row = layout.row()
row.prop(sc, "pivot_point", text="", icon_only=True)
+
+ # Proportional Editing
+ row = layout.row(align=True)
+ row.prop(
+ tool_settings,
+ "use_proportional_edit",
+ icon_only=True,
+ icon='PROP_CON'
+ )
+ sub = row.row(align=True)
+ sub.active = tool_settings.use_proportional_edit
+ sub.prop_with_popover(
+ tool_settings,
+ "proportional_edit_falloff",
+ text="",
+ icon_only=True,
+ panel="CLIP_PT_proportional_edit",
+ )
+
row = layout.row(align=True)
icon = 'LOCKED' if sc.lock_selection else 'UNLOCKED'
row.prop(sc, "lock_selection", icon=icon, text="")
@@ -1869,6 +1904,7 @@ classes = (
CLIP_PT_tools_scenesetup,
CLIP_PT_annotation,
CLIP_PT_tools_grease_pencil_draw,
+ CLIP_PT_proportional_edit,
CLIP_MT_view_zoom,
CLIP_MT_view,
CLIP_MT_clip,
diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c
index 2a7c247ff2b..1afd97545d3 100644
--- a/source/blender/editors/transform/transform.c
+++ b/source/blender/editors/transform/transform.c
@@ -984,7 +984,7 @@ int transformEvent(TransInfo *t, const wmEvent *event)
break;
case TFM_MODAL_PROPSIZE:
/* MOUSEPAN usage... */
- if (t->flag & T_PROP_EDIT) {
+ if ((t->flag & T_PROP_EDIT) && ((t->flag & T_PROP_FIXED_DISTANCE) == 0)) {
float fac = 1.0f + 0.005f * (event->y - event->prevy);
t->prop_size *= fac;
if (t->spacetype == SPACE_VIEW3D && t->persp != RV3D_ORTHO) {
@@ -1000,7 +1000,7 @@ int transformEvent(TransInfo *t, const wmEvent *event)
}
break;
case TFM_MODAL_PROPSIZE_UP:
- if (t->flag & T_PROP_EDIT) {
+ if ((t->flag & T_PROP_EDIT) && ((t->flag & T_PROP_FIXED_DISTANCE) == 0)) {
t->prop_size *= (t->modifiers & MOD_PRECISION) ? 1.01f : 1.1f;
if (t->spacetype == SPACE_VIEW3D && t->persp != RV3D_ORTHO) {
t->prop_size = min_ff(t->prop_size, ((View3D *)t->view)->clip_end);
@@ -1014,7 +1014,7 @@ int transformEvent(TransInfo *t, const wmEvent *event)
}
break;
case TFM_MODAL_PROPSIZE_DOWN:
- if (t->flag & T_PROP_EDIT) {
+ if ((t->flag & T_PROP_EDIT) && ((t->flag & T_PROP_FIXED_DISTANCE) == 0)) {
t->prop_size /= (t->modifiers & MOD_PRECISION) ? 1.01f : 1.1f;
t->prop_size = max_ff(t->prop_size, T_PROP_SIZE_MIN);
calculatePropRatio(t);
diff --git a/source/blender/editors/transform/transform.h b/source/blender/editors/transform/transform.h
index 91bf2bf8aac..8c8f8e3413d 100644
--- a/source/blender/editors/transform/transform.h
+++ b/source/blender/editors/transform/transform.h
@@ -455,45 +455,46 @@ enum {
T_PROP_EDIT = 1 << 10,
T_PROP_CONNECTED = 1 << 11,
T_PROP_PROJECTED = 1 << 12,
- T_PROP_EDIT_ALL = T_PROP_EDIT | T_PROP_CONNECTED | T_PROP_PROJECTED,
+ T_PROP_FIXED_DISTANCE = (1 << 13),
+ T_PROP_EDIT_ALL = T_PROP_EDIT | T_PROP_CONNECTED | T_PROP_PROJECTED | T_PROP_FIXED_DISTANCE,
- T_V3D_ALIGN = 1 << 13,
+ T_V3D_ALIGN = 1 << 14,
/** For 2D views such as UV or f-curve. */
- T_2D_EDIT = 1 << 14,
- T_CLIP_UV = 1 << 15,
+ T_2D_EDIT = 1 << 15,
+ T_CLIP_UV = 1 << 16,
/** Auto-IK is on. */
- T_AUTOIK = 1 << 16,
+ T_AUTOIK = 1 << 17,
/** Don't use mirror even if the data-block option is set. */
- T_NO_MIRROR = 1 << 17,
+ T_NO_MIRROR = 1 << 18,
/** To indicate that the value set in the `value` parameter is the final
* value of the transformation, modified only by the constrain. */
- T_INPUT_IS_VALUES_FINAL = 1 << 18,
+ T_INPUT_IS_VALUES_FINAL = 1 << 19,
/** To specify if we save back settings at the end. */
- T_MODAL = 1 << 19,
+ T_MODAL = 1 << 20,
/** No re-topology (projection). */
- T_NO_PROJECT = 1 << 20,
+ T_NO_PROJECT = 1 << 21,
- T_RELEASE_CONFIRM = 1 << 21,
+ T_RELEASE_CONFIRM = 1 << 22,
/** Alternative transformation. used to add offset to tracking markers. */
- T_ALT_TRANSFORM = 1 << 22,
+ T_ALT_TRANSFORM = 1 << 23,
/** #TransInfo.center has been set, don't change it. */
- T_OVERRIDE_CENTER = 1 << 23,
+ T_OVERRIDE_CENTER = 1 << 24,
- T_MODAL_CURSOR_SET = 1 << 24,
+ T_MODAL_CURSOR_SET = 1 << 25,
- T_CLNOR_REBUILD = 1 << 25,
+ T_CLNOR_REBUILD = 1 << 26,
/** Merges unselected into selected after transforming (runs after transforming). */
- T_AUTOMERGE = 1 << 26,
+ T_AUTOMERGE = 1 << 27,
/** Runs auto-merge & splits. */
- T_AUTOSPLIT = 1 << 27,
+ T_AUTOSPLIT = 1 << 28,
};
/** #TransInfo.modifiers */
diff --git a/source/blender/editors/transform/transform_constraints.c b/source/blender/editors/transform/transform_constraints.c
index 5abe92b385a..f5d67425728 100644
--- a/source/blender/editors/transform/transform_constraints.c
+++ b/source/blender/editors/transform/transform_constraints.c
@@ -824,6 +824,9 @@ void drawPropCircle(const struct bContext *C, TransInfo *t)
else if (t->spacetype == SPACE_IMAGE) {
GPU_matrix_scale_2f(1.0f / t->aspect[0], 1.0f / t->aspect[1]);
}
+ else if (t->spacetype == SPACE_CLIP) {
+ GPU_matrix_scale_2f(1.0f / t->aspect[0], 1.0f / t->aspect[1]);
+ }
else if (ELEM(t->spacetype, SPACE_GRAPH, SPACE_ACTION)) {
/* only scale y */
rcti *mask = &t->region->v2d.mask;
diff --git a/source/blender/editors/transform/transform_convert.c b/source/blender/editors/transform/transform_convert.c
index fb365da6b43..e606e737a80 100644
--- a/source/blender/editors/transform/transform_convert.c
+++ b/source/blender/editors/transform/transform_convert.c
@@ -1258,7 +1258,6 @@ void createTransData(bContext *C, TransInfo *t)
break;
case TC_TRACKING_DATA:
createTransTrackingData(C, t);
- init_prop_edit = false;
break;
case TC_NONE:
default:
@@ -1295,6 +1294,9 @@ void createTransData(bContext *C, TransInfo *t)
else if (convert_type == TC_CURVE_VERTS && t->obedit_type == OB_CURVE) {
set_prop_dist(t, false);
}
+ else if (convert_type == TC_TRACKING_DATA) {
+ set_prop_dist(t, false);
+ }
else {
set_prop_dist(t, true);
}
diff --git a/source/blender/editors/transform/transform_convert_tracking.c b/source/blender/editors/transform/transform_convert_tracking.c
index be8c2aa5ae3..30a341d5e16 100644
--- a/source/blender/editors/transform/transform_convert_tracking.c
+++ b/source/blender/editors/transform/transform_convert_tracking.c
@@ -95,11 +95,13 @@ typedef struct TransformInitContext {
static void markerToTransDataInit(TransformInitContext *init_context,
MovieTrackingTrack *track,
MovieTrackingMarker *marker,
+ const int framenr,
int area,
float loc[2],
const float rel[2],
const float off[2],
- const float aspect[2])
+ const float aspect[2],
+ float distance)
{
TransData *td = init_context->current.td;
TransData2D *td2d = init_context->current.td2d;
@@ -166,8 +168,11 @@ static void markerToTransDataInit(TransformInitContext *init_context,
td->ext = NULL;
td->val = NULL;
- td->flag |= TD_SELECTED;
- td->dist = 0.0;
+ if (marker->framenr == framenr) {
+ td->flag |= TD_SELECTED;
+ marker->flag &= ~(MARKER_DISABLED | MARKER_TRACKED);
+ }
+ td->dist = distance;
unit_m3(td->mtx);
unit_m3(td->smtx);
@@ -177,25 +182,35 @@ static void markerToTransDataInit(TransformInitContext *init_context,
init_context->current.tdt++;
}
-static void trackToTransData(TransformInitContext *init_context,
- const int framenr,
- MovieTrackingTrack *track,
- const float aspect[2])
+static void markerAreasToTransData(TransformInitContext *init_context,
+ MovieTrackingTrack *track,
+ MovieTrackingMarker *marker,
+ const int framenr,
+ const float aspect[2],
+ float distance)
{
- MovieTrackingMarker *marker = BKE_tracking_marker_ensure(track, framenr);
-
markerToTransDataInit(init_context,
track,
marker,
+ framenr,
TRACK_AREA_POINT,
track->offset,
marker->pos,
track->offset,
- aspect);
+ aspect,
+ distance);
if (track->flag & SELECT) {
- markerToTransDataInit(
- init_context, track, marker, TRACK_AREA_POINT, marker->pos, NULL, NULL, aspect);
+ markerToTransDataInit(init_context,
+ track,
+ marker,
+ framenr,
+ TRACK_AREA_POINT,
+ marker->pos,
+ NULL,
+ NULL,
+ aspect,
+ distance);
}
if (track->pat_flag & SELECT) {
@@ -205,11 +220,13 @@ static void trackToTransData(TransformInitContext *init_context,
markerToTransDataInit(init_context,
track,
marker,
+ framenr,
TRACK_AREA_PAT,
marker->pattern_corners[a],
marker->pos,
NULL,
- aspect);
+ aspect,
+ distance);
}
}
@@ -217,24 +234,110 @@ static void trackToTransData(TransformInitContext *init_context,
markerToTransDataInit(init_context,
track,
marker,
+ framenr,
TRACK_AREA_SEARCH,
marker->search_min,
marker->pos,
NULL,
- aspect);
+ aspect,
+ distance);
markerToTransDataInit(init_context,
track,
marker,
+ framenr,
TRACK_AREA_SEARCH,
marker->search_max,
marker->pos,
NULL,
- aspect);
+ aspect,
+ distance);
}
+}
- if (init_context->current.td != NULL) {
- marker->flag &= ~(MARKER_DISABLED | MARKER_TRACKED);
+static void trackToTransData(TransformInitContext *init_context,
+ const int framenr,
+ MovieTrackingTrack *track,
+ const float aspect[2])
+{
+ TransInfo *t = init_context->t;
+
+ MovieTrackingMarker *marker_at_frame = BKE_tracking_marker_ensure(track, framenr);
+ markerAreasToTransData(init_context, track, marker_at_frame, framenr, aspect, 0.0f);
+
+ if ((t->flag & (T_PROP_EDIT)) == 0) {
+ return;
+ }
+ const int marker_at_frame_index = marker_at_frame - track->markers;
+
+ /* TODO(sergey): De-duplicate traversal and counting logic. in both forard and backward
+ * directions. */
+ /* TODO(sergey): De-duplicate logic around which markers are considered stoppers. */
+
+ /* When doing proportional editing with topology enabled, add all markers from the tracked
+ * segment to the transform data, The order of markers is not important, but it is important to
+ * stay within the current segment. This is done as two loops going backward and formward,
+ * starting from the next to the marker which corresponds to the active frame. */
+
+ /* Traverse markers backwards, adding them to the transform data.
+ * Stop when tracked segment is over, or when all markers to the left side of the
+ * `marker_at_frame` has been added. */
+ {
+ int num_markers = 0;
+ for (int marker_index = marker_at_frame_index - 1; marker_index >= 0; marker_index--) {
+ MovieTrackingMarker *marker = &track->markers[marker_index];
+ if (marker->flag & MARKER_DISABLED) {
+ break;
+ }
+ if ((marker->flag & MARKER_TRACKED) == 0) {
+ break;
+ }
+ num_markers++;
+ }
+
+ for (int i = 0, marker_index = marker_at_frame_index - 1; marker_index >= 0;
+ i++, marker_index--) {
+ MovieTrackingMarker *marker = &track->markers[marker_index];
+ if (marker->flag & MARKER_DISABLED) {
+ break;
+ }
+ if ((marker->flag & MARKER_TRACKED) == 0) {
+ break;
+ }
+ const float distance = (float)(i + 1) / (num_markers + 1);
+ markerAreasToTransData(init_context, track, marker, framenr, aspect, distance);
+ }
+ }
+
+ /* Traverse markers forward, adding them to the transform data.
+ * Stop when tracked segment is over, or when all markers to the left side of the
+ * `marker_at_frame` has been added. */
+ {
+ int num_markers = 0;
+ for (int marker_index = marker_at_frame_index + 1; marker_index < track->markersnr;
+ marker_index++) {
+ MovieTrackingMarker *marker = &track->markers[marker_index];
+ if (marker->flag & MARKER_DISABLED) {
+ break;
+ }
+ if ((marker->flag & MARKER_TRACKED) == 0) {
+ break;
+ }
+ num_markers++;
+ }
+
+ for (int i = 0, marker_index = marker_at_frame_index + 1; marker_index < track->markersnr;
+ i++, marker_index++) {
+ MovieTrackingMarker *marker = &track->markers[marker_index];
+ if (marker->flag & MARKER_DISABLED) {
+ break;
+ }
+ if ((marker->flag & MARKER_TRACKED) == 0) {
+ break;
+ }
+ const float distance = (float)(i + 1) / (num_markers + 1);
+ markerAreasToTransData(init_context, track, marker, framenr, aspect, distance);
+ }
}
}
@@ -358,6 +461,10 @@ static void createTransTrackingTracksData(bContext *C, TransInfo *t)
init_context.t = t;
init_context.tc = tc;
+ if ((t->flag & T_PROP_EDIT) == T_PROP_EDIT) {
+ t->flag |= T_PROP_FIXED_DISTANCE | T_PROP_CONNECTED;
+ }
+
/* Count required tranformation data. */
tc->data_len = 0;
@@ -584,7 +691,6 @@ static void cancelTransTracking(TransInfo *t)
MovieTrackingMarker *marker = BKE_tracking_marker_get_exact(track, tdt->framenr);
BLI_assert(marker != NULL);
-
marker->flag = tdt->flag;
if (track->flag & SELECT) {
@@ -623,7 +729,6 @@ static void cancelTransTracking(TransInfo *t)
tdt->framenr);
BLI_assert(plane_marker != NULL);
-
plane_marker->flag = tdt->flag;
i += 3;
}
diff --git a/source/blender/editors/transform/transform_generics.c b/source/blender/editors/transform/transform_generics.c
index 5b41f6b51bf..1f23be0cad6 100644
--- a/source/blender/editors/transform/transform_generics.c
+++ b/source/blender/editors/transform/transform_generics.c
@@ -1285,18 +1285,24 @@ void calculatePropRatio(TransInfo *t)
if (td->flag & TD_SELECTED) {
td->factor = 1.0f;
}
- else if ((connected && (td->flag & TD_NOTCONNECTED || td->dist > t->prop_size)) ||
- (connected == 0 && td->rdist > t->prop_size)) {
+ else if (((t->flag & T_PROP_FIXED_DISTANCE) == 0) &&
+ ((connected && (td->flag & TD_NOTCONNECTED || td->dist > t->prop_size)) ||
+ (connected == 0 && td->rdist > t->prop_size))) {
td->factor = 0.0f;
restoreElement(td);
}
else {
/* Use rdist for falloff calculations, it is the real distance */
- if (connected) {
- dist = (t->prop_size - td->dist) / t->prop_size;
+ if ((t->flag & T_PROP_FIXED_DISTANCE) == 0) {
+ if (connected) {
+ dist = (t->prop_size - td->dist) / t->prop_size;
+ }
+ else {
+ dist = (t->prop_size - td->rdist) / t->prop_size;
+ }
}
else {
- dist = (t->prop_size - td->rdist) / t->prop_size;
+ dist = 1.0f - td->dist;
}
/*
diff --git a/source/blender/editors/transform/transform_mode.c b/source/blender/editors/transform/transform_mode.c
index a4d999b868d..5de2f44f4f4 100644
--- a/source/blender/editors/transform/transform_mode.c
+++ b/source/blender/editors/transform/transform_mode.c
@@ -549,8 +549,10 @@ void headerRotation(TransInfo *t, char str[UI_MAX_DRAW_STR], float final)
}
if (t->flag & T_PROP_EDIT_ALL) {
- ofs += BLI_snprintf(
- str + ofs, UI_MAX_DRAW_STR - ofs, TIP_(" Proportional size: %.2f"), t->prop_size);
+ if ((t->flag & T_PROP_FIXED_DISTANCE) == 0) {
+ ofs += BLI_snprintf(
+ str + ofs, UI_MAX_DRAW_STR - ofs, TIP_(" Proportional size: %.2f"), t->prop_size);
+ }
}
}
@@ -886,8 +888,10 @@ void headerResize(TransInfo *t, const float vec[3], char str[UI_MAX_DRAW_STR])
}
if (t->flag & T_PROP_EDIT_ALL) {
- ofs += BLI_snprintf(
- str + ofs, UI_MAX_DRAW_STR - ofs, TIP_(" Proportional size: %.2f"), t->prop_size);
+ if ((t->flag & T_PROP_FIXED_DISTANCE) == 0) {
+ ofs += BLI_snprintf(
+ str + ofs, UI_MAX_DRAW_STR - ofs, TIP_(" Proportional size: %.2f"), t->prop_size);
+ }
}
}
diff --git a/source/blender/editors/transform/transform_mode_translate.c b/source/blender/editors/transform/transform_mode_translate.c
index 851e0feb5f5..0545bf4f906 100644
--- a/source/blender/editors/transform/transform_mode_translate.c
+++ b/source/blender/editors/transform/transform_mode_translate.c
@@ -201,8 +201,10 @@ static void headerTranslation(TransInfo *t, const float vec[3], char str[UI_MAX_
}
if (t->flag & T_PROP_EDIT_ALL) {
- ofs += BLI_snprintf(
- str + ofs, UI_MAX_DRAW_STR - ofs, TIP_(" Proportional size: %.2f"), t->prop_size);
+ if ((t->flag & T_PROP_FIXED_DISTANCE) == 0) {
+ ofs += BLI_snprintf(
+ str + ofs, UI_MAX_DRAW_STR - ofs, TIP_(" Proportional size: %.2f"), t->prop_size);
+ }
}
if (t->spacetype == SPACE_NODE) {