mask_evaluate.c 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923
  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) 2012 Blender Foundation.
  19. * All rights reserved.
  20. *
  21. * Contributor(s): Blender Foundation,
  22. * Sergey Sharybin,
  23. * Campbell Barton
  24. *
  25. * ***** END GPL LICENSE BLOCK *****
  26. */
  27. /** \file blender/blenkernel/intern/mask_evaluate.c
  28. * \ingroup bke
  29. *
  30. * Functions for evaluating the mask beziers into points for the outline and feather.
  31. */
  32. #include <stddef.h>
  33. #include <string.h>
  34. #include "MEM_guardedalloc.h"
  35. #include "BLI_utildefines.h"
  36. #include "BLI_math.h"
  37. #include "DNA_mask_types.h"
  38. #include "BKE_curve.h"
  39. #include "BKE_depsgraph.h"
  40. #include "BKE_global.h"
  41. #include "BKE_mask.h"
  42. unsigned int BKE_mask_spline_resolution(MaskSpline *spline, int width, int height)
  43. {
  44. float max_segment = 0.01f;
  45. unsigned int i, resol = 1;
  46. if (width != 0 && height != 0) {
  47. max_segment = 1.0f / (float)max_ii(width, height);
  48. }
  49. for (i = 0; i < spline->tot_point; i++) {
  50. MaskSplinePoint *point = &spline->points[i];
  51. BezTriple *bezt_curr, *bezt_next;
  52. float a, b, c, len;
  53. unsigned int cur_resol;
  54. bezt_curr = &point->bezt;
  55. bezt_next = BKE_mask_spline_point_next_bezt(spline, spline->points, point);
  56. if (bezt_next == NULL) {
  57. break;
  58. }
  59. a = len_v3v3(bezt_curr->vec[1], bezt_curr->vec[2]);
  60. b = len_v3v3(bezt_curr->vec[2], bezt_next->vec[0]);
  61. c = len_v3v3(bezt_next->vec[0], bezt_next->vec[1]);
  62. len = a + b + c;
  63. cur_resol = len / max_segment;
  64. resol = MAX2(resol, cur_resol);
  65. if (resol >= MASK_RESOL_MAX) {
  66. break;
  67. }
  68. }
  69. return CLAMPIS(resol, 1, MASK_RESOL_MAX);
  70. }
  71. unsigned int BKE_mask_spline_feather_resolution(MaskSpline *spline, int width, int height)
  72. {
  73. const float max_segment = 0.005;
  74. unsigned int resol = BKE_mask_spline_resolution(spline, width, height);
  75. float max_jump = 0.0f;
  76. int i;
  77. /* avoid checking the featrher if we already hit the maximum value */
  78. if (resol >= MASK_RESOL_MAX) {
  79. return MASK_RESOL_MAX;
  80. }
  81. for (i = 0; i < spline->tot_point; i++) {
  82. MaskSplinePoint *point = &spline->points[i];
  83. float prev_u, prev_w;
  84. int j;
  85. prev_u = 0.0f;
  86. prev_w = point->bezt.weight;
  87. for (j = 0; j < point->tot_uw; j++) {
  88. const float w_diff = (point->uw[j].w - prev_w);
  89. const float u_diff = (point->uw[j].u - prev_u);
  90. /* avoid divide by zero and very high values,
  91. * though these get clamped eventually */
  92. if (u_diff > FLT_EPSILON) {
  93. float jump = fabsf(w_diff / u_diff);
  94. max_jump = max_ff(max_jump, jump);
  95. }
  96. prev_u = point->uw[j].u;
  97. prev_w = point->uw[j].w;
  98. }
  99. }
  100. resol += max_jump / max_segment;
  101. return CLAMPIS(resol, 1, MASK_RESOL_MAX);
  102. }
  103. int BKE_mask_spline_differentiate_calc_total(const MaskSpline *spline, const unsigned int resol)
  104. {
  105. if (spline->flag & MASK_SPLINE_CYCLIC) {
  106. return spline->tot_point * resol;
  107. }
  108. else {
  109. return ((spline->tot_point - 1) * resol) + 1;
  110. }
  111. }
  112. float (*BKE_mask_spline_differentiate_with_resolution(MaskSpline *spline,
  113. unsigned int *tot_diff_point,
  114. const unsigned int resol
  115. ))[2]
  116. {
  117. MaskSplinePoint *points_array = BKE_mask_spline_point_array(spline);
  118. MaskSplinePoint *point_curr, *point_prev;
  119. float (*diff_points)[2], (*fp)[2];
  120. const int tot = BKE_mask_spline_differentiate_calc_total(spline, resol);
  121. int a;
  122. if (spline->tot_point <= 1) {
  123. /* nothing to differentiate */
  124. *tot_diff_point = 0;
  125. return NULL;
  126. }
  127. /* len+1 because of 'forward_diff_bezier' function */
  128. *tot_diff_point = tot;
  129. diff_points = fp = MEM_mallocN((tot + 1) * sizeof(*diff_points), "mask spline vets");
  130. a = spline->tot_point - 1;
  131. if (spline->flag & MASK_SPLINE_CYCLIC)
  132. a++;
  133. point_prev = points_array;
  134. point_curr = point_prev + 1;
  135. while (a--) {
  136. BezTriple *bezt_prev;
  137. BezTriple *bezt_curr;
  138. int j;
  139. if (a == 0 && (spline->flag & MASK_SPLINE_CYCLIC))
  140. point_curr = points_array;
  141. bezt_prev = &point_prev->bezt;
  142. bezt_curr = &point_curr->bezt;
  143. for (j = 0; j < 2; j++) {
  144. BKE_curve_forward_diff_bezier(bezt_prev->vec[1][j], bezt_prev->vec[2][j],
  145. bezt_curr->vec[0][j], bezt_curr->vec[1][j],
  146. &(*fp)[j], resol, 2 * sizeof(float));
  147. }
  148. fp += resol;
  149. if (a == 0 && (spline->flag & MASK_SPLINE_CYCLIC) == 0) {
  150. copy_v2_v2(*fp, bezt_curr->vec[1]);
  151. }
  152. point_prev = point_curr;
  153. point_curr++;
  154. }
  155. return diff_points;
  156. }
  157. float (*BKE_mask_spline_differentiate(MaskSpline *spline, int width, int height,
  158. unsigned int *tot_diff_point
  159. ))[2]
  160. {
  161. int unsigned resol = BKE_mask_spline_resolution(spline, width, height);
  162. return BKE_mask_spline_differentiate_with_resolution(spline, tot_diff_point, resol);
  163. }
  164. /* ** feather points self-intersection collapse routine ** */
  165. typedef struct FeatherEdgesBucket {
  166. int tot_segment;
  167. int (*segments)[2];
  168. int alloc_segment;
  169. } FeatherEdgesBucket;
  170. static void feather_bucket_add_edge(FeatherEdgesBucket *bucket, int start, int end)
  171. {
  172. const int alloc_delta = 256;
  173. if (bucket->tot_segment >= bucket->alloc_segment) {
  174. if (!bucket->segments) {
  175. bucket->segments = MEM_callocN(alloc_delta * sizeof(*bucket->segments), "feather bucket segments");
  176. }
  177. else {
  178. bucket->segments = MEM_reallocN(bucket->segments,
  179. (alloc_delta + bucket->tot_segment) * sizeof(*bucket->segments));
  180. }
  181. bucket->alloc_segment += alloc_delta;
  182. }
  183. bucket->segments[bucket->tot_segment][0] = start;
  184. bucket->segments[bucket->tot_segment][1] = end;
  185. bucket->tot_segment++;
  186. }
  187. static void feather_bucket_check_intersect(
  188. float (*feather_points)[2], int tot_feather_point, FeatherEdgesBucket *bucket,
  189. int cur_a, int cur_b)
  190. {
  191. int i;
  192. const float *v1 = (float *) feather_points[cur_a];
  193. const float *v2 = (float *) feather_points[cur_b];
  194. for (i = 0; i < bucket->tot_segment; i++) {
  195. int check_a = bucket->segments[i][0];
  196. int check_b = bucket->segments[i][1];
  197. const float *v3 = (float *) feather_points[check_a];
  198. const float *v4 = (float *) feather_points[check_b];
  199. if (check_a >= cur_a - 1 || cur_b == check_a)
  200. continue;
  201. if (isect_seg_seg_v2_simple(v1, v2, v3, v4)) {
  202. int k;
  203. float p[2];
  204. float min_a[2], max_a[2];
  205. float min_b[2], max_b[2];
  206. isect_seg_seg_v2_point(v1, v2, v3, v4, p);
  207. INIT_MINMAX2(min_a, max_a);
  208. INIT_MINMAX2(min_b, max_b);
  209. /* collapse loop with smaller AABB */
  210. for (k = 0; k < tot_feather_point; k++) {
  211. if (k >= check_b && k <= cur_a) {
  212. minmax_v2v2_v2(min_a, max_a, feather_points[k]);
  213. }
  214. else {
  215. minmax_v2v2_v2(min_b, max_b, feather_points[k]);
  216. }
  217. }
  218. if (max_a[0] - min_a[0] < max_b[0] - min_b[0] ||
  219. max_a[1] - min_a[1] < max_b[1] - min_b[1])
  220. {
  221. for (k = check_b; k <= cur_a; k++) {
  222. copy_v2_v2(feather_points[k], p);
  223. }
  224. }
  225. else {
  226. for (k = 0; k <= check_a; k++) {
  227. copy_v2_v2(feather_points[k], p);
  228. }
  229. if (cur_b != 0) {
  230. for (k = cur_b; k < tot_feather_point; k++) {
  231. copy_v2_v2(feather_points[k], p);
  232. }
  233. }
  234. }
  235. }
  236. }
  237. }
  238. static int feather_bucket_index_from_coord(
  239. const float co[2], const float min[2], const float bucket_scale[2],
  240. const int buckets_per_side)
  241. {
  242. int x = (int) ((co[0] - min[0]) * bucket_scale[0]);
  243. int y = (int) ((co[1] - min[1]) * bucket_scale[1]);
  244. if (x == buckets_per_side)
  245. x--;
  246. if (y == buckets_per_side)
  247. y--;
  248. return y * buckets_per_side + x;
  249. }
  250. static void feather_bucket_get_diagonal(
  251. FeatherEdgesBucket *buckets, int start_bucket_index, int end_bucket_index, int buckets_per_side,
  252. FeatherEdgesBucket **r_diagonal_bucket_a, FeatherEdgesBucket **r_diagonal_bucket_b)
  253. {
  254. int start_bucket_x = start_bucket_index % buckets_per_side;
  255. int start_bucket_y = start_bucket_index / buckets_per_side;
  256. int end_bucket_x = end_bucket_index % buckets_per_side;
  257. int end_bucket_y = end_bucket_index / buckets_per_side;
  258. int diagonal_bucket_a_index = start_bucket_y * buckets_per_side + end_bucket_x;
  259. int diagonal_bucket_b_index = end_bucket_y * buckets_per_side + start_bucket_x;
  260. *r_diagonal_bucket_a = &buckets[diagonal_bucket_a_index];
  261. *r_diagonal_bucket_b = &buckets[diagonal_bucket_b_index];
  262. }
  263. void BKE_mask_spline_feather_collapse_inner_loops(
  264. MaskSpline *spline, float (*feather_points)[2], const unsigned int tot_feather_point)
  265. {
  266. #define BUCKET_INDEX(co) \
  267. feather_bucket_index_from_coord(co, min, bucket_scale, buckets_per_side)
  268. int buckets_per_side, tot_bucket;
  269. float bucket_size, bucket_scale[2];
  270. FeatherEdgesBucket *buckets;
  271. unsigned int i;
  272. float min[2], max[2];
  273. float max_delta_x = -1.0f, max_delta_y = -1.0f, max_delta;
  274. if (tot_feather_point < 4) {
  275. /* self-intersection works only for quads at least,
  276. * in other cases polygon can't be self-intersecting anyway
  277. */
  278. return;
  279. }
  280. /* find min/max corners of mask to build buckets in that space */
  281. INIT_MINMAX2(min, max);
  282. for (i = 0; i < tot_feather_point; i++) {
  283. unsigned int next = i + 1;
  284. float delta;
  285. minmax_v2v2_v2(min, max, feather_points[i]);
  286. if (next == tot_feather_point) {
  287. if (spline->flag & MASK_SPLINE_CYCLIC)
  288. next = 0;
  289. else
  290. break;
  291. }
  292. delta = fabsf(feather_points[i][0] - feather_points[next][0]);
  293. if (delta > max_delta_x)
  294. max_delta_x = delta;
  295. delta = fabsf(feather_points[i][1] - feather_points[next][1]);
  296. if (delta > max_delta_y)
  297. max_delta_y = delta;
  298. }
  299. /* prevent divisionsby zero by ensuring bounding box is not collapsed */
  300. if (max[0] - min[0] < FLT_EPSILON) {
  301. max[0] += 0.01f;
  302. min[0] -= 0.01f;
  303. }
  304. if (max[1] - min[1] < FLT_EPSILON) {
  305. max[1] += 0.01f;
  306. min[1] -= 0.01f;
  307. }
  308. /* use dynamically calculated buckets per side, so we likely wouldn't
  309. * run into a situation when segment doesn't fit two buckets which is
  310. * pain collecting candidates for intersection
  311. */
  312. max_delta_x /= max[0] - min[0];
  313. max_delta_y /= max[1] - min[1];
  314. max_delta = MAX2(max_delta_x, max_delta_y);
  315. buckets_per_side = min_ii(512, 0.9f / max_delta);
  316. if (buckets_per_side == 0) {
  317. /* happens when some segment fills the whole bounding box across some of dimension */
  318. buckets_per_side = 1;
  319. }
  320. tot_bucket = buckets_per_side * buckets_per_side;
  321. bucket_size = 1.0f / buckets_per_side;
  322. /* pre-compute multipliers, to save mathematical operations in loops */
  323. bucket_scale[0] = 1.0f / ((max[0] - min[0]) * bucket_size);
  324. bucket_scale[1] = 1.0f / ((max[1] - min[1]) * bucket_size);
  325. /* fill in buckets' edges */
  326. buckets = MEM_callocN(sizeof(FeatherEdgesBucket) * tot_bucket, "feather buckets");
  327. for (i = 0; i < tot_feather_point; i++) {
  328. int start = i, end = i + 1;
  329. int start_bucket_index, end_bucket_index;
  330. if (end == tot_feather_point) {
  331. if (spline->flag & MASK_SPLINE_CYCLIC)
  332. end = 0;
  333. else
  334. break;
  335. }
  336. start_bucket_index = BUCKET_INDEX(feather_points[start]);
  337. end_bucket_index = BUCKET_INDEX(feather_points[end]);
  338. feather_bucket_add_edge(&buckets[start_bucket_index], start, end);
  339. if (start_bucket_index != end_bucket_index) {
  340. FeatherEdgesBucket *end_bucket = &buckets[end_bucket_index];
  341. FeatherEdgesBucket *diagonal_bucket_a, *diagonal_bucket_b;
  342. feather_bucket_get_diagonal(buckets, start_bucket_index, end_bucket_index, buckets_per_side,
  343. &diagonal_bucket_a, &diagonal_bucket_b);
  344. feather_bucket_add_edge(end_bucket, start, end);
  345. feather_bucket_add_edge(diagonal_bucket_a, start, end);
  346. feather_bucket_add_edge(diagonal_bucket_a, start, end);
  347. }
  348. }
  349. /* check all edges for intersection with edges from their buckets */
  350. for (i = 0; i < tot_feather_point; i++) {
  351. int cur_a = i, cur_b = i + 1;
  352. int start_bucket_index, end_bucket_index;
  353. FeatherEdgesBucket *start_bucket;
  354. if (cur_b == tot_feather_point)
  355. cur_b = 0;
  356. start_bucket_index = BUCKET_INDEX(feather_points[cur_a]);
  357. end_bucket_index = BUCKET_INDEX(feather_points[cur_b]);
  358. start_bucket = &buckets[start_bucket_index];
  359. feather_bucket_check_intersect(feather_points, tot_feather_point, start_bucket, cur_a, cur_b);
  360. if (start_bucket_index != end_bucket_index) {
  361. FeatherEdgesBucket *end_bucket = &buckets[end_bucket_index];
  362. FeatherEdgesBucket *diagonal_bucket_a, *diagonal_bucket_b;
  363. feather_bucket_get_diagonal(buckets, start_bucket_index, end_bucket_index, buckets_per_side,
  364. &diagonal_bucket_a, &diagonal_bucket_b);
  365. feather_bucket_check_intersect(feather_points, tot_feather_point, end_bucket, cur_a, cur_b);
  366. feather_bucket_check_intersect(feather_points, tot_feather_point, diagonal_bucket_a, cur_a, cur_b);
  367. feather_bucket_check_intersect(feather_points, tot_feather_point, diagonal_bucket_b, cur_a, cur_b);
  368. }
  369. }
  370. /* free buckets */
  371. for (i = 0; i < tot_bucket; i++) {
  372. if (buckets[i].segments)
  373. MEM_freeN(buckets[i].segments);
  374. }
  375. MEM_freeN(buckets);
  376. #undef BUCKET_INDEX
  377. }
  378. /** only called from #BKE_mask_spline_feather_differentiated_points_with_resolution() ! */
  379. static float (*mask_spline_feather_differentiated_points_with_resolution__even(
  380. MaskSpline *spline, unsigned int *tot_feather_point,
  381. const unsigned int resol, const bool do_feather_isect))[2]
  382. {
  383. MaskSplinePoint *points_array = BKE_mask_spline_point_array(spline);
  384. MaskSplinePoint *point_curr, *point_prev;
  385. float (*feather)[2], (*fp)[2];
  386. const int tot = BKE_mask_spline_differentiate_calc_total(spline, resol);
  387. int a;
  388. /* tot+1 because of 'forward_diff_bezier' function */
  389. feather = fp = MEM_mallocN((tot + 1) * sizeof(*feather), "mask spline feather diff points");
  390. a = spline->tot_point - 1;
  391. if (spline->flag & MASK_SPLINE_CYCLIC)
  392. a++;
  393. point_prev = points_array;
  394. point_curr = point_prev + 1;
  395. while (a--) {
  396. /* BezTriple *bezt_prev; */ /* UNUSED */
  397. /* BezTriple *bezt_curr; */ /* UNUSED */
  398. int j;
  399. if (a == 0 && (spline->flag & MASK_SPLINE_CYCLIC))
  400. point_curr = points_array;
  401. /* bezt_prev = &point_prev->bezt; */
  402. /* bezt_curr = &point_curr->bezt; */
  403. for (j = 0; j < resol; j++, fp++) {
  404. float u = (float) j / resol, weight;
  405. float co[2], n[2];
  406. /* TODO - these calls all calculate similar things
  407. * could be unified for some speed */
  408. BKE_mask_point_segment_co(spline, point_prev, u, co);
  409. BKE_mask_point_normal(spline, point_prev, u, n);
  410. weight = BKE_mask_point_weight(spline, point_prev, u);
  411. madd_v2_v2v2fl(*fp, co, n, weight);
  412. }
  413. if (a == 0 && (spline->flag & MASK_SPLINE_CYCLIC) == 0) {
  414. float u = 1.0f, weight;
  415. float co[2], n[2];
  416. BKE_mask_point_segment_co(spline, point_prev, u, co);
  417. BKE_mask_point_normal(spline, point_prev, u, n);
  418. weight = BKE_mask_point_weight(spline, point_prev, u);
  419. madd_v2_v2v2fl(*fp, co, n, weight);
  420. }
  421. point_prev = point_curr;
  422. point_curr++;
  423. }
  424. *tot_feather_point = tot;
  425. if ((spline->flag & MASK_SPLINE_NOINTERSECT) && do_feather_isect) {
  426. BKE_mask_spline_feather_collapse_inner_loops(spline, feather, tot);
  427. }
  428. return feather;
  429. }
  430. /** only called from #BKE_mask_spline_feather_differentiated_points_with_resolution() ! */
  431. static float (*mask_spline_feather_differentiated_points_with_resolution__double(
  432. MaskSpline *spline, unsigned int *tot_feather_point,
  433. const unsigned int resol, const bool do_feather_isect))[2]
  434. {
  435. MaskSplinePoint *points_array = BKE_mask_spline_point_array(spline);
  436. MaskSplinePoint *point_curr, *point_prev;
  437. float (*feather)[2], (*fp)[2];
  438. const int tot = BKE_mask_spline_differentiate_calc_total(spline, resol);
  439. int a;
  440. if (spline->tot_point <= 1) {
  441. /* nothing to differentiate */
  442. *tot_feather_point = 0;
  443. return NULL;
  444. }
  445. /* len+1 because of 'forward_diff_bezier' function */
  446. *tot_feather_point = tot;
  447. feather = fp = MEM_mallocN((tot + 1) * sizeof(*feather), "mask spline vets");
  448. a = spline->tot_point - 1;
  449. if (spline->flag & MASK_SPLINE_CYCLIC)
  450. a++;
  451. point_prev = points_array;
  452. point_curr = point_prev + 1;
  453. while (a--) {
  454. BezTriple local_prevbezt;
  455. BezTriple local_bezt;
  456. float point_prev_n[2], point_curr_n[2], tvec[2];
  457. float weight_prev, weight_curr;
  458. float len_base, len_feather, len_scalar;
  459. BezTriple *bezt_prev;
  460. BezTriple *bezt_curr;
  461. int j;
  462. if (a == 0 && (spline->flag & MASK_SPLINE_CYCLIC))
  463. point_curr = points_array;
  464. bezt_prev = &point_prev->bezt;
  465. bezt_curr = &point_curr->bezt;
  466. /* modified copy for feather */
  467. local_prevbezt = *bezt_prev;
  468. local_bezt = *bezt_curr;
  469. bezt_prev = &local_prevbezt;
  470. bezt_curr = &local_bezt;
  471. /* calc the normals */
  472. sub_v2_v2v2(tvec, bezt_prev->vec[1], bezt_prev->vec[0]);
  473. normalize_v2(tvec);
  474. point_prev_n[0] = -tvec[1];
  475. point_prev_n[1] = tvec[0];
  476. sub_v2_v2v2(tvec, bezt_curr->vec[1], bezt_curr->vec[0]);
  477. normalize_v2(tvec);
  478. point_curr_n[0] = -tvec[1];
  479. point_curr_n[1] = tvec[0];
  480. weight_prev = bezt_prev->weight;
  481. weight_curr = bezt_curr->weight;
  482. mul_v2_fl(point_prev_n, weight_prev);
  483. mul_v2_fl(point_curr_n, weight_curr);
  484. /* before we transform verts */
  485. len_base = len_v2v2(bezt_prev->vec[1], bezt_curr->vec[1]);
  486. // add_v2_v2(bezt_prev->vec[0], point_prev_n); // not needed
  487. add_v2_v2(bezt_prev->vec[1], point_prev_n);
  488. add_v2_v2(bezt_prev->vec[2], point_prev_n);
  489. add_v2_v2(bezt_curr->vec[0], point_curr_n);
  490. add_v2_v2(bezt_curr->vec[1], point_curr_n);
  491. // add_v2_v2(bezt_curr->vec[2], point_curr_n); // not needed
  492. len_feather = len_v2v2(bezt_prev->vec[1], bezt_curr->vec[1]);
  493. /* scale by chane in length */
  494. len_scalar = len_feather / len_base;
  495. dist_ensure_v2_v2fl(bezt_prev->vec[2], bezt_prev->vec[1], len_scalar * len_v2v2(bezt_prev->vec[2], bezt_prev->vec[1]));
  496. dist_ensure_v2_v2fl(bezt_curr->vec[0], bezt_curr->vec[1], len_scalar * len_v2v2(bezt_curr->vec[0], bezt_curr->vec[1]));
  497. for (j = 0; j < 2; j++) {
  498. BKE_curve_forward_diff_bezier(bezt_prev->vec[1][j], bezt_prev->vec[2][j],
  499. bezt_curr->vec[0][j], bezt_curr->vec[1][j],
  500. &(*fp)[j], resol, 2 * sizeof(float));
  501. }
  502. /* scale by the uw's */
  503. if (point_prev->tot_uw) {
  504. for (j = 0; j < resol; j++, fp++) {
  505. float u = (float) j / resol;
  506. float weight_uw, weight_scalar;
  507. float co[2];
  508. /* TODO - these calls all calculate similar things
  509. * could be unified for some speed */
  510. BKE_mask_point_segment_co(spline, point_prev, u, co);
  511. weight_uw = BKE_mask_point_weight(spline, point_prev, u);
  512. weight_scalar = BKE_mask_point_weight_scalar(spline, point_prev, u);
  513. dist_ensure_v2_v2fl(*fp, co, len_v2v2(*fp, co) * (weight_uw / weight_scalar));
  514. }
  515. }
  516. else {
  517. fp += resol;
  518. }
  519. if (a == 0 && (spline->flag & MASK_SPLINE_CYCLIC) == 0) {
  520. copy_v2_v2(*fp, bezt_curr->vec[1]);
  521. }
  522. point_prev = point_curr;
  523. point_curr++;
  524. }
  525. if ((spline->flag & MASK_SPLINE_NOINTERSECT) && do_feather_isect) {
  526. BKE_mask_spline_feather_collapse_inner_loops(spline, feather, tot);
  527. }
  528. return feather;
  529. }
  530. /**
  531. * values align with #BKE_mask_spline_differentiate_with_resolution
  532. * when \a resol arguments match.
  533. */
  534. float (*BKE_mask_spline_feather_differentiated_points_with_resolution(
  535. MaskSpline *spline, unsigned int *tot_feather_point,
  536. const unsigned int resol, const bool do_feather_isect))[2]
  537. {
  538. switch (spline->offset_mode) {
  539. case MASK_SPLINE_OFFSET_EVEN:
  540. return mask_spline_feather_differentiated_points_with_resolution__even(spline, tot_feather_point, resol, do_feather_isect);
  541. case MASK_SPLINE_OFFSET_SMOOTH:
  542. default:
  543. return mask_spline_feather_differentiated_points_with_resolution__double(spline, tot_feather_point, resol, do_feather_isect);
  544. }
  545. }
  546. float (*BKE_mask_spline_feather_points(MaskSpline *spline, int *tot_feather_point))[2]
  547. {
  548. MaskSplinePoint *points_array = BKE_mask_spline_point_array(spline);
  549. int i, tot = 0;
  550. float (*feather)[2], (*fp)[2];
  551. /* count */
  552. for (i = 0; i < spline->tot_point; i++) {
  553. MaskSplinePoint *point = &points_array[i];
  554. tot += point->tot_uw + 1;
  555. }
  556. /* create data */
  557. feather = fp = MEM_mallocN(tot * sizeof(*feather), "mask spline feather points");
  558. for (i = 0; i < spline->tot_point; i++) {
  559. MaskSplinePoint *point = &points_array[i];
  560. BezTriple *bezt = &point->bezt;
  561. float weight, n[2];
  562. int j;
  563. BKE_mask_point_normal(spline, point, 0.0f, n);
  564. weight = BKE_mask_point_weight(spline, point, 0.0f);
  565. madd_v2_v2v2fl(*fp, bezt->vec[1], n, weight);
  566. fp++;
  567. for (j = 0; j < point->tot_uw; j++) {
  568. float u = point->uw[j].u;
  569. float co[2];
  570. BKE_mask_point_segment_co(spline, point, u, co);
  571. BKE_mask_point_normal(spline, point, u, n);
  572. weight = BKE_mask_point_weight(spline, point, u);
  573. madd_v2_v2v2fl(*fp, co, n, weight);
  574. fp++;
  575. }
  576. }
  577. *tot_feather_point = tot;
  578. return feather;
  579. }
  580. /* *** mask point functions which involve evaluation *** */
  581. float *BKE_mask_point_segment_feather_diff(MaskSpline *spline, MaskSplinePoint *point,
  582. int width, int height,
  583. unsigned int *tot_feather_point)
  584. {
  585. float *feather, *fp;
  586. unsigned int resol = BKE_mask_spline_feather_resolution(spline, width, height);
  587. unsigned int i;
  588. feather = fp = MEM_callocN(2 * resol * sizeof(float), "mask point spline feather diff points");
  589. for (i = 0; i < resol; i++, fp += 2) {
  590. float u = (float)(i % resol) / resol, weight;
  591. float co[2], n[2];
  592. BKE_mask_point_segment_co(spline, point, u, co);
  593. BKE_mask_point_normal(spline, point, u, n);
  594. weight = BKE_mask_point_weight(spline, point, u);
  595. fp[0] = co[0] + n[0] * weight;
  596. fp[1] = co[1] + n[1] * weight;
  597. }
  598. *tot_feather_point = resol;
  599. return feather;
  600. }
  601. float *BKE_mask_point_segment_diff(MaskSpline *spline, MaskSplinePoint *point,
  602. int width, int height, unsigned int *tot_diff_point)
  603. {
  604. MaskSplinePoint *points_array = BKE_mask_spline_point_array_from_point(spline, point);
  605. BezTriple *bezt, *bezt_next;
  606. float *diff_points, *fp;
  607. int j, resol = BKE_mask_spline_resolution(spline, width, height);
  608. bezt = &point->bezt;
  609. bezt_next = BKE_mask_spline_point_next_bezt(spline, points_array, point);
  610. if (!bezt_next)
  611. return NULL;
  612. /* resol+1 because of 'forward_diff_bezier' function */
  613. *tot_diff_point = resol + 1;
  614. diff_points = fp = MEM_callocN((resol + 1) * 2 * sizeof(float), "mask segment vets");
  615. for (j = 0; j < 2; j++) {
  616. BKE_curve_forward_diff_bezier(bezt->vec[1][j], bezt->vec[2][j],
  617. bezt_next->vec[0][j], bezt_next->vec[1][j],
  618. fp + j, resol, 2 * sizeof(float));
  619. }
  620. copy_v2_v2(fp + 2 * resol, bezt_next->vec[1]);
  621. return diff_points;
  622. }
  623. static void mask_evaluate_apply_point_parent(MaskSplinePoint *point, float ctime)
  624. {
  625. float parent_matrix[3][3];
  626. BKE_mask_point_parent_matrix_get(point, ctime, parent_matrix);
  627. mul_m3_v2(parent_matrix, point->bezt.vec[0]);
  628. mul_m3_v2(parent_matrix, point->bezt.vec[1]);
  629. mul_m3_v2(parent_matrix, point->bezt.vec[2]);
  630. }
  631. void BKE_mask_layer_evaluate_animation(MaskLayer *masklay, const float ctime)
  632. {
  633. /* animation if available */
  634. MaskLayerShape *masklay_shape_a;
  635. MaskLayerShape *masklay_shape_b;
  636. int found;
  637. if ((found = BKE_mask_layer_shape_find_frame_range(
  638. masklay, ctime, &masklay_shape_a, &masklay_shape_b)))
  639. {
  640. if (found == 1) {
  641. #if 0
  642. printf("%s: exact %d %d (%d)\n",
  643. __func__,
  644. (int)ctime,
  645. BLI_listbase_count(&masklay->splines_shapes),
  646. masklay_shape_a->frame);
  647. #endif
  648. BKE_mask_layer_shape_to_mask(masklay, masklay_shape_a);
  649. }
  650. else if (found == 2) {
  651. float w = masklay_shape_b->frame - masklay_shape_a->frame;
  652. #if 0
  653. printf("%s: tween %d %d (%d %d)\n",
  654. __func__,
  655. (int)ctime,
  656. BLI_listbase_count(&masklay->splines_shapes),
  657. masklay_shape_a->frame, masklay_shape_b->frame);
  658. #endif
  659. BKE_mask_layer_shape_to_mask_interp(
  660. masklay,
  661. masklay_shape_a, masklay_shape_b,
  662. (ctime - masklay_shape_a->frame) / w);
  663. }
  664. else {
  665. /* always fail, should never happen */
  666. BLI_assert(found == 2);
  667. }
  668. }
  669. }
  670. void BKE_mask_layer_evaluate_deform(MaskLayer *masklay, const float ctime)
  671. {
  672. BKE_mask_layer_calc_handles(masklay);
  673. for (MaskSpline *spline = masklay->splines.first;
  674. spline != NULL;
  675. spline = spline->next)
  676. {
  677. bool need_handle_recalc = false;
  678. BKE_mask_spline_ensure_deform(spline);
  679. for (int i = 0; i < spline->tot_point; i++) {
  680. MaskSplinePoint *point = &spline->points[i];
  681. MaskSplinePoint *point_deform = &spline->points_deform[i];
  682. BKE_mask_point_free(point_deform);
  683. *point_deform = *point;
  684. point_deform->uw = point->uw ? MEM_dupallocN(point->uw) : NULL;
  685. mask_evaluate_apply_point_parent(point_deform, ctime);
  686. if (ELEM(point->bezt.h1, HD_AUTO, HD_VECT)) {
  687. need_handle_recalc = true;
  688. }
  689. }
  690. /* if the spline has auto or vector handles, these need to be
  691. * recalculated after deformation.
  692. */
  693. if (need_handle_recalc) {
  694. for (int i = 0; i < spline->tot_point; i++) {
  695. MaskSplinePoint *point_deform = &spline->points_deform[i];
  696. if (ELEM(point_deform->bezt.h1, HD_AUTO, HD_VECT)) {
  697. BKE_mask_calc_handle_point(spline, point_deform);
  698. }
  699. }
  700. }
  701. /* end extra calc handles loop */
  702. }
  703. }
  704. #define DEBUG_PRINT if (G.debug & G_DEBUG_DEPSGRAPH) printf
  705. void BKE_mask_eval_animation(struct EvaluationContext *eval_ctx, Mask *mask)
  706. {
  707. DEBUG_PRINT("%s on %s (%p)\n", __func__, mask->id.name, mask);
  708. for (MaskLayer *mask_layer = mask->masklayers.first;
  709. mask_layer != NULL;
  710. mask_layer = mask_layer->next)
  711. {
  712. BKE_mask_layer_evaluate_animation(mask_layer, eval_ctx->ctime);
  713. }
  714. }
  715. void BKE_mask_eval_update(struct EvaluationContext *eval_ctx, Mask *mask)
  716. {
  717. DEBUG_PRINT("%s on %s (%p)\n", __func__, mask->id.name, mask);
  718. for (MaskLayer *mask_layer = mask->masklayers.first;
  719. mask_layer != NULL;
  720. mask_layer = mask_layer->next)
  721. {
  722. BKE_mask_layer_evaluate_deform(mask_layer, eval_ctx->ctime);
  723. }
  724. }