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