Code cleanup: remove unused includes
[blender.git] / source / blender / blenkernel / intern / tracking_detect.c
1 /*
2  * ***** BEGIN GPL LICENSE BLOCK *****
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  * The Original Code is Copyright (C) 2011 Blender Foundation.
19  * All rights reserved.
20  *
21  * Contributor(s): Blender Foundation,
22  *                 Sergey Sharybin
23  *                 Keir Mierle
24  *
25  * ***** END GPL LICENSE BLOCK *****
26  */
27
28 /** \file blender/blenkernel/intern/tracking_detect.c
29  *  \ingroup bke
30  *
31  * This file contains blender-side implementation of feature detection.
32  */
33
34 #include "DNA_gpencil_types.h"
35 #include "DNA_movieclip_types.h"
36 #include "DNA_object_types.h"   /* SELECT */
37
38 #include "BLI_utildefines.h"
39
40 #include "BKE_tracking.h"
41
42 #include "IMB_imbuf_types.h"
43 #include "IMB_imbuf.h"
44
45 #include "libmv-capi.h"
46
47 /* Check whether point is inside grease pencil stroke. */
48 static bool check_point_in_stroke(bGPDstroke *stroke, float x, float y)
49 {
50         int i, prev;
51         int count = 0;
52         bGPDspoint *points = stroke->points;
53
54         /* Count intersections of horizontal ray coming from the point.
55          * Point will be inside layer if and only if number of intersection
56          * is uneven.
57          *
58          * Well, if layer has got self-intersections, this logic wouldn't
59          * work, but such situation is crappy anyway.
60          */
61
62         prev = stroke->totpoints - 1;
63
64         for (i = 0; i < stroke->totpoints; i++) {
65                 if ((points[i].y < y && points[prev].y >= y) || (points[prev].y < y && points[i].y >= y)) {
66                         float fac = (y - points[i].y) / (points[prev].y - points[i].y);
67
68                         if (points[i].x + fac * (points[prev].x - points[i].x) < x)
69                                 count++;
70                 }
71
72                 prev = i;
73         }
74
75         return (count % 2) ? true : false;
76 }
77
78 /* Check whether point is inside any stroke of grease pencil layer. */
79 static bool check_point_in_layer(bGPDlayer *layer, float x, float y)
80 {
81         bGPDframe *frame = layer->frames.first;
82
83         while (frame) {
84                 bGPDstroke *stroke = frame->strokes.first;
85
86                 while (stroke) {
87                         if (check_point_in_stroke(stroke, x, y))
88                                 return true;
89
90                         stroke = stroke->next;
91                 }
92                 frame = frame->next;
93         }
94
95         return false;
96 }
97
98 /* Get features detected by libmv and create tracks on the clip for them. */
99 static void detect_retrieve_libmv_features(MovieTracking *tracking, ListBase *tracksbase,
100                                            struct libmv_Features *features, int framenr, int width, int height,
101                                            bGPDlayer *layer, bool place_outside_layer)
102 {
103         int a;
104
105         a = libmv_countFeatures(features);
106         while (a--) {
107                 MovieTrackingTrack *track;
108                 double x, y, size, score;
109                 bool ok = true;
110                 float xu, yu;
111
112                 libmv_getFeature(features, a, &x, &y, &score, &size);
113
114                 /* In Libmv integer coordinate points to pixel center, in blender
115                  * it's not. Need to add 0.5px offset to center.
116                  */
117                 xu = (x + 0.5) / width;
118                 yu = (y + 0.5) / height;
119
120                 if (layer)
121                         ok = check_point_in_layer(layer, xu, yu) != place_outside_layer;
122
123                 if (ok) {
124                         track = BKE_tracking_track_add(tracking, tracksbase, xu, yu, framenr, width, height);
125                         track->flag |= SELECT;
126                         track->pat_flag |= SELECT;
127                         track->search_flag |= SELECT;
128                 }
129         }
130 }
131
132 static void run_configured_detector(MovieTracking *tracking, ListBase *tracksbase,
133                                     ImBuf *ibuf, int framenr, bGPDlayer *layer, bool place_outside_layer,
134                                     libmv_DetectOptions *options)
135 {
136         struct libmv_Features *features = NULL;
137
138         if (ibuf->rect_float) {
139                 features = libmv_detectFeaturesFloat(ibuf->rect_float, ibuf->x, ibuf->y, 4, options);
140         }
141         else if (ibuf->rect) {
142                 features = libmv_detectFeaturesByte((unsigned char *) ibuf->rect, ibuf->x, ibuf->y, 4, options);
143         }
144
145         if (features != NULL) {
146                 detect_retrieve_libmv_features(tracking, tracksbase, features,
147                                                framenr, ibuf->x, ibuf->y, layer,
148                                                place_outside_layer);
149
150                 libmv_featuresDestroy(features);
151         }
152 }
153
154 /* Detect features using FAST detector */
155 void BKE_tracking_detect_fast(MovieTracking *tracking, ListBase *tracksbase, ImBuf *ibuf,
156                               int framenr, int margin, int min_trackness, int min_distance, bGPDlayer *layer,
157                               bool place_outside_layer)
158 {
159         libmv_DetectOptions options = {0};
160
161         options.detector = LIBMV_DETECTOR_FAST;
162         options.margin = margin;
163         options.min_distance = min_distance;
164         options.fast_min_trackness = min_trackness;
165
166         run_configured_detector(tracking, tracksbase, ibuf, framenr, layer,
167                                 place_outside_layer, &options);
168 }
169
170 /* Detect features using Harris detector */
171 void BKE_tracking_detect_harris(MovieTracking *tracking, ListBase *tracksbase, ImBuf *ibuf,
172                                 int framenr, int margin, float threshold, int min_distance, bGPDlayer *layer,
173                                 bool place_outside_layer)
174 {
175         libmv_DetectOptions options = {0};
176
177         options.detector = LIBMV_DETECTOR_HARRIS;
178         options.margin = margin;
179         options.min_distance = min_distance;
180         options.harris_threshold = threshold;
181
182         run_configured_detector(tracking, tracksbase, ibuf, framenr, layer,
183                                 place_outside_layer, &options);
184 }