1 /*
2 * This program is free software; you can redistribute it and/or
3 * modify it under the terms of the GNU General Public License
4 * as published by the Free Software Foundation; either version 2
5 * of the License, or (at your option) any later version.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software Foundation,
14 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15 *
16 * The Original Code is Copyright (C) 2012 Blender Foundation.
17 * All rights reserved.
18 */
19
20 /** \file
21 * \ingroup edmask
22 */
23
24 #include "BLI_listbase.h"
25 #include "BLI_math.h"
26 #include "BLI_string.h"
27
28 #include "BKE_context.h"
29 #include "BKE_mask.h"
30 #include "BKE_tracking.h"
31
32 #include "DEG_depsgraph.h"
33
34 #include "DNA_mask_types.h"
35
36 #include "WM_api.h"
37 #include "WM_types.h"
38
39 #include "ED_clip.h" /* frame remapping functions */
40 #include "ED_screen.h"
41
42 #include "mask_intern.h" /* own include */
43
mask_parent_clear_exec(bContext * C,wmOperator * UNUSED (op))44 static int mask_parent_clear_exec(bContext *C, wmOperator *UNUSED(op))
45 {
46 Mask *mask = CTX_data_edit_mask(C);
47
48 LISTBASE_FOREACH (MaskLayer *, mask_layer, &mask->masklayers) {
49 if (mask_layer->restrictflag & (MASK_RESTRICT_VIEW | MASK_RESTRICT_SELECT)) {
50 continue;
51 }
52
53 LISTBASE_FOREACH (MaskSpline *, spline, &mask_layer->splines) {
54 for (int i = 0; i < spline->tot_point; i++) {
55 MaskSplinePoint *point = &spline->points[i];
56
57 if (MASKPOINT_ISSEL_ANY(point)) {
58 point->parent.id = NULL;
59 }
60 }
61 }
62 }
63
64 WM_event_add_notifier(C, NC_MASK | ND_DATA, mask);
65 DEG_id_tag_update(&mask->id, 0);
66
67 return OPERATOR_FINISHED;
68 }
69
MASK_OT_parent_clear(wmOperatorType * ot)70 void MASK_OT_parent_clear(wmOperatorType *ot)
71 {
72 /* identifiers */
73 ot->name = "Clear Parent";
74 ot->description = "Clear the mask's parenting";
75 ot->idname = "MASK_OT_parent_clear";
76
77 /* api callbacks */
78 ot->exec = mask_parent_clear_exec;
79
80 ot->poll = ED_maskedit_mask_poll;
81
82 /* flags */
83 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
84 }
85
mask_parent_set_exec(bContext * C,wmOperator * UNUSED (op))86 static int mask_parent_set_exec(bContext *C, wmOperator *UNUSED(op))
87 {
88 Mask *mask = CTX_data_edit_mask(C);
89
90 /* parent info */
91 SpaceClip *sc = CTX_wm_space_clip(C);
92 MovieClip *clip = ED_space_clip_get_clip(sc);
93 MovieTracking *tracking;
94 MovieTrackingTrack *track;
95 MovieTrackingPlaneTrack *plane_track;
96 MovieTrackingObject *tracking_object;
97 /* done */
98
99 int framenr, parent_type;
100 float parmask_pos[2], orig_corners[4][2];
101 const char *sub_parent_name;
102
103 if (ELEM(NULL, sc, clip)) {
104 return OPERATOR_CANCELLED;
105 }
106
107 framenr = ED_space_clip_get_clip_frame_number(sc);
108
109 tracking = &clip->tracking;
110 tracking_object = BKE_tracking_object_get_active(&clip->tracking);
111
112 if (tracking_object == NULL) {
113 return OPERATOR_CANCELLED;
114 }
115
116 if ((track = BKE_tracking_track_get_active(tracking)) != NULL) {
117 MovieTrackingMarker *marker = BKE_tracking_marker_get(track, framenr);
118 float marker_pos_ofs[2];
119
120 add_v2_v2v2(marker_pos_ofs, marker->pos, track->offset);
121
122 BKE_mask_coord_from_movieclip(clip, &sc->user, parmask_pos, marker_pos_ofs);
123
124 sub_parent_name = track->name;
125 parent_type = MASK_PARENT_POINT_TRACK;
126 memset(orig_corners, 0, sizeof(orig_corners));
127 }
128 else if ((plane_track = BKE_tracking_plane_track_get_active(tracking)) != NULL) {
129 MovieTrackingPlaneMarker *plane_marker = BKE_tracking_plane_marker_get(plane_track, framenr);
130
131 zero_v2(parmask_pos);
132 sub_parent_name = plane_track->name;
133 parent_type = MASK_PARENT_PLANE_TRACK;
134 memcpy(orig_corners, plane_marker->corners, sizeof(orig_corners));
135 }
136 else {
137 return OPERATOR_CANCELLED;
138 }
139
140 LISTBASE_FOREACH (MaskLayer *, mask_layer, &mask->masklayers) {
141 if (mask_layer->restrictflag & (MASK_RESTRICT_VIEW | MASK_RESTRICT_SELECT)) {
142 continue;
143 }
144
145 LISTBASE_FOREACH (MaskSpline *, spline, &mask_layer->splines) {
146 for (int i = 0; i < spline->tot_point; i++) {
147 MaskSplinePoint *point = &spline->points[i];
148
149 if (MASKPOINT_ISSEL_ANY(point)) {
150 point->parent.id_type = ID_MC;
151 point->parent.id = &clip->id;
152 point->parent.type = parent_type;
153 BLI_strncpy(point->parent.parent, tracking_object->name, sizeof(point->parent.parent));
154 BLI_strncpy(point->parent.sub_parent, sub_parent_name, sizeof(point->parent.sub_parent));
155
156 copy_v2_v2(point->parent.parent_orig, parmask_pos);
157 memcpy(point->parent.parent_corners_orig,
158 orig_corners,
159 sizeof(point->parent.parent_corners_orig));
160 }
161 }
162 }
163 }
164
165 WM_event_add_notifier(C, NC_MASK | ND_DATA, mask);
166 DEG_id_tag_update(&mask->id, 0);
167
168 return OPERATOR_FINISHED;
169 }
170
171 /** based on #OBJECT_OT_parent_set */
MASK_OT_parent_set(wmOperatorType * ot)172 void MASK_OT_parent_set(wmOperatorType *ot)
173 {
174 /* identifiers */
175 ot->name = "Make Parent";
176 ot->description = "Set the mask's parenting";
177 ot->idname = "MASK_OT_parent_set";
178
179 /* api callbacks */
180 // ot->invoke = mask_parent_set_invoke;
181 ot->exec = mask_parent_set_exec;
182
183 ot->poll = ED_space_clip_maskedit_mask_poll;
184
185 /* flags */
186 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
187 }
188