Blender  V2.93
mask_add.c
Go to the documentation of this file.
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 
24 #include "MEM_guardedalloc.h"
25 
26 #include "BLI_math.h"
27 
28 #include "BKE_context.h"
29 #include "BKE_curve.h"
30 #include "BKE_mask.h"
31 
32 #include "DEG_depsgraph.h"
33 
34 #include "DNA_mask_types.h"
35 #include "DNA_scene_types.h"
36 #include "DNA_screen_types.h"
37 
38 #include "WM_api.h"
39 #include "WM_types.h"
40 
41 #include "ED_mask.h" /* own include */
42 #include "ED_screen.h"
43 #include "ED_select_utils.h"
44 
45 #include "RNA_access.h"
46 #include "RNA_define.h"
47 
48 #include "mask_intern.h" /* own include */
49 
50 /******************** add vertex *********************/
51 
53  MaskSpline *spline,
54  MaskSplinePoint *new_point,
55  const float point_co[2],
56  const float u,
57  const float ctime,
58  const MaskSplinePoint *reference_point,
59  const bool reference_adjacent)
60 {
61  const MaskSplinePoint *reference_parent_point = NULL;
62  BezTriple *bezt;
63  float co[3];
64 
65  copy_v2_v2(co, point_co);
66  co[2] = 0.0f;
67 
68  /* point coordinate */
69  bezt = &new_point->bezt;
70 
71  bezt->h1 = bezt->h2 = HD_ALIGN;
72 
73  if (reference_point) {
74  if (reference_point->bezt.h1 == HD_VECT && reference_point->bezt.h2 == HD_VECT) {
75  /* If the reference point is sharp try using some smooth point as reference
76  * for handles.
77  */
78  int point_index = reference_point - spline->points;
79  int delta = new_point == spline->points ? 1 : -1;
80  for (int i = 0; i < spline->tot_point - 1; i++) {
81  MaskSplinePoint *current_point;
82 
83  point_index += delta;
84  if (point_index == -1 || point_index >= spline->tot_point) {
85  if (spline->flag & MASK_SPLINE_CYCLIC) {
86  if (point_index == -1) {
87  point_index = spline->tot_point - 1;
88  }
89  else if (point_index >= spline->tot_point) {
90  point_index = 0;
91  }
92  }
93  else {
94  break;
95  }
96  }
97 
98  current_point = &spline->points[point_index];
99  if (current_point->bezt.h1 != HD_VECT || current_point->bezt.h2 != HD_VECT) {
100  bezt->h1 = bezt->h2 = MAX2(current_point->bezt.h2, current_point->bezt.h1);
101  break;
102  }
103  }
104  }
105  else {
106  bezt->h1 = bezt->h2 = MAX2(reference_point->bezt.h2, reference_point->bezt.h1);
107  }
108 
109  reference_parent_point = reference_point;
110  }
111  else if (reference_adjacent) {
112  if (spline->tot_point != 1) {
113  MaskSplinePoint *prev_point, *next_point, *close_point;
114 
115  const int index = (int)(new_point - spline->points);
116  if (spline->flag & MASK_SPLINE_CYCLIC) {
117  prev_point = &spline->points[mod_i(index - 1, spline->tot_point)];
118  next_point = &spline->points[mod_i(index + 1, spline->tot_point)];
119  }
120  else {
121  prev_point = (index != 0) ? &spline->points[index - 1] : NULL;
122  next_point = (index != spline->tot_point - 1) ? &spline->points[index + 1] : NULL;
123  }
124 
125  if (prev_point && next_point) {
126  close_point = (len_squared_v2v2(new_point->bezt.vec[1], prev_point->bezt.vec[1]) <
127  len_squared_v2v2(new_point->bezt.vec[1], next_point->bezt.vec[1])) ?
128  prev_point :
129  next_point;
130  }
131  else {
132  close_point = prev_point ? prev_point : next_point;
133  }
134 
135  /* handle type */
136  char handle_type = 0;
137  if (prev_point) {
138  handle_type = prev_point->bezt.h2;
139  }
140  if (next_point) {
141  handle_type = MAX2(next_point->bezt.h2, handle_type);
142  }
143  bezt->h1 = bezt->h2 = handle_type;
144 
145  /* parent */
146  reference_parent_point = close_point;
147 
148  /* note, we may want to copy other attributes later, radius? pressure? color? */
149  }
150  }
151 
152  copy_v3_v3(bezt->vec[0], co);
153  copy_v3_v3(bezt->vec[1], co);
154  copy_v3_v3(bezt->vec[2], co);
155 
156  if (reference_parent_point) {
157  new_point->parent = reference_parent_point->parent;
158 
159  if (new_point->parent.id) {
160  float parent_matrix[3][3];
161  BKE_mask_point_parent_matrix_get(new_point, ctime, parent_matrix);
162  invert_m3(parent_matrix);
163  mul_m3_v2(parent_matrix, new_point->bezt.vec[1]);
164  }
165  }
166  else {
167  BKE_mask_parent_init(&new_point->parent);
168  }
169 
170  if (spline->tot_point != 1) {
171  BKE_mask_calc_handle_adjacent_interp(spline, new_point, u);
172  }
173 
174  /* select new point */
175  MASKPOINT_SEL_ALL(new_point);
177 }
178 
179 /* **** add extrude vertex **** */
180 
181 static void finSelectedSplinePoint(MaskLayer *mask_layer,
182  MaskSpline **spline,
183  MaskSplinePoint **point,
184  bool check_active)
185 {
186  MaskSpline *cur_spline = mask_layer->splines.first;
187 
188  *spline = NULL;
189  *point = NULL;
190 
191  if (check_active) {
192  /* TODO, having an active point but no active spline is possible, why? */
193  if (mask_layer->act_spline && mask_layer->act_point &&
194  MASKPOINT_ISSEL_ANY(mask_layer->act_point)) {
195  *spline = mask_layer->act_spline;
196  *point = mask_layer->act_point;
197  return;
198  }
199  }
200 
201  while (cur_spline) {
202  for (int i = 0; i < cur_spline->tot_point; i++) {
203  MaskSplinePoint *cur_point = &cur_spline->points[i];
204 
205  if (MASKPOINT_ISSEL_ANY(cur_point)) {
206  if (!ELEM(*spline, NULL, cur_spline)) {
207  *spline = NULL;
208  *point = NULL;
209  return;
210  }
211  if (*point) {
212  *point = NULL;
213  }
214  else {
215  *spline = cur_spline;
216  *point = cur_point;
217  }
218  }
219  }
220 
221  cur_spline = cur_spline->next;
222  }
223 }
224 
225 /* **** add subdivide vertex **** */
226 
227 static void mask_spline_add_point_at_index(MaskSpline *spline, int point_index)
228 {
229  MaskSplinePoint *new_point_array;
230 
231  new_point_array = MEM_callocN(sizeof(MaskSplinePoint) * (spline->tot_point + 1),
232  "add mask vert points");
233 
234  memcpy(new_point_array, spline->points, sizeof(MaskSplinePoint) * (point_index + 1));
235  memcpy(new_point_array + point_index + 2,
236  spline->points + point_index + 1,
237  sizeof(MaskSplinePoint) * (spline->tot_point - point_index - 1));
238 
239  MEM_freeN(spline->points);
240  spline->points = new_point_array;
241  spline->tot_point++;
242 }
243 
244 static bool add_vertex_subdivide(const bContext *C, Mask *mask, const float co[2])
245 {
246  MaskLayer *mask_layer;
247  MaskSpline *spline;
248  MaskSplinePoint *point = NULL;
249  const float threshold = 9;
250  float tangent[2];
251  float u;
252 
254  mask,
255  co,
256  threshold,
257  false,
258  tangent,
259  true,
260  true,
261  &mask_layer,
262  &spline,
263  &point,
264  &u,
265  NULL)) {
267  const float ctime = CFRA;
268 
269  MaskSplinePoint *new_point;
270  int point_index = point - spline->points;
271 
273 
274  mask_spline_add_point_at_index(spline, point_index);
275 
276  new_point = &spline->points[point_index + 1];
277 
278  setup_vertex_point(mask, spline, new_point, co, u, ctime, NULL, true);
279 
280  /* TODO - we could pass the spline! */
282  BKE_mask_layer_shape_spline_to_index(mask_layer, spline) +
283  point_index + 1,
284  true,
285  true);
286 
287  mask_layer->act_spline = spline;
288  mask_layer->act_point = new_point;
289 
291 
292  return true;
293  }
294 
295  return false;
296 }
297 
298 static bool add_vertex_extrude(const bContext *C,
299  Mask *mask,
300  MaskLayer *mask_layer,
301  const float co[2])
302 {
304  const float ctime = CFRA;
305 
306  MaskSpline *spline;
307  MaskSplinePoint *point;
308  MaskSplinePoint *new_point = NULL, *ref_point = NULL;
309 
310  /* check on which side we want to add the point */
311  int point_index;
312  float tangent_point[2];
313  float tangent_co[2];
314  bool do_cyclic_correct = false;
315  bool do_prev; /* use prev point rather than next?? */
316 
317  if (!mask_layer) {
318  return false;
319  }
320  finSelectedSplinePoint(mask_layer, &spline, &point, true);
321 
323 
324  point_index = (point - spline->points);
325 
326  MASKPOINT_DESEL_ALL(point);
327 
328  if ((spline->flag & MASK_SPLINE_CYCLIC) ||
329  (point_index > 0 && point_index != spline->tot_point - 1)) {
330  BKE_mask_calc_tangent_polyline(spline, point, tangent_point);
331  sub_v2_v2v2(tangent_co, co, point->bezt.vec[1]);
332 
333  if (dot_v2v2(tangent_point, tangent_co) < 0.0f) {
334  do_prev = true;
335  }
336  else {
337  do_prev = false;
338  }
339  }
340  else if (((spline->flag & MASK_SPLINE_CYCLIC) == 0) && (point_index == 0)) {
341  do_prev = true;
342  }
343  else if (((spline->flag & MASK_SPLINE_CYCLIC) == 0) && (point_index == spline->tot_point - 1)) {
344  do_prev = false;
345  }
346  else {
347  do_prev = false; /* quiet warning */
348  /* should never get here */
349  BLI_assert(0);
350  }
351 
352  /* use the point before the active one */
353  if (do_prev) {
354  point_index--;
355  if (point_index < 0) {
356  point_index += spline->tot_point; /* wrap index */
357  if ((spline->flag & MASK_SPLINE_CYCLIC) == 0) {
358  do_cyclic_correct = true;
359  point_index = 0;
360  }
361  }
362  }
363 
364  // print_v2("", tangent_point);
365  // printf("%d\n", point_index);
366 
367  mask_spline_add_point_at_index(spline, point_index);
368 
369  if (do_cyclic_correct) {
370  ref_point = &spline->points[point_index + 1];
371  new_point = &spline->points[point_index];
372  *ref_point = *new_point;
373  memset(new_point, 0, sizeof(*new_point));
374  }
375  else {
376  ref_point = &spline->points[point_index];
377  new_point = &spline->points[point_index + 1];
378  }
379 
380  mask_layer->act_point = new_point;
381 
382  setup_vertex_point(mask, spline, new_point, co, 0.5f, ctime, ref_point, false);
383 
384  if (mask_layer->splines_shapes.first) {
385  point_index = (((int)(new_point - spline->points) + 0) % spline->tot_point);
387  BKE_mask_layer_shape_spline_to_index(mask_layer, spline) +
388  point_index,
389  true,
390  true);
391  }
392 
394 
395  return true;
396 }
397 
398 static bool add_vertex_new(const bContext *C, Mask *mask, MaskLayer *mask_layer, const float co[2])
399 {
401  const float ctime = CFRA;
402 
403  MaskSpline *spline;
404  MaskSplinePoint *new_point = NULL, *ref_point = NULL;
405 
406  if (!mask_layer) {
407  /* if there's no mask layer currently operationg on, create new one */
408  mask_layer = BKE_mask_layer_new(mask, "");
409  mask->masklay_act = mask->masklay_tot - 1;
410  }
411 
413 
414  spline = BKE_mask_spline_add(mask_layer);
415 
416  mask_layer->act_spline = spline;
417  new_point = spline->points;
418 
419  mask_layer->act_point = new_point;
420 
421  setup_vertex_point(mask, spline, new_point, co, 0.5f, ctime, ref_point, false);
422 
423  {
424  int point_index = (((int)(new_point - spline->points) + 0) % spline->tot_point);
426  BKE_mask_layer_shape_spline_to_index(mask_layer, spline) +
427  point_index,
428  true,
429  true);
430  }
431 
433 
434  return true;
435 }
436 
437 /* Convert coordinate from normalized space to pixel one.
438  * TODO(sergey): Make the function more generally available. */
440  const float point_normalized[2],
441  float point_pixel[2])
442 {
444  ARegion *region = CTX_wm_region(C);
445 
446  float scalex, scaley;
447  ED_mask_pixelspace_factor(area, region, &scalex, &scaley);
448 
449  point_pixel[0] = point_normalized[0] * scalex;
450  point_pixel[1] = point_normalized[1] * scaley;
451 }
452 
454  Mask *mask,
455  MaskSpline *spline,
456  MaskSplinePoint *active_point,
457  MaskSplinePoint *other_point,
458  float co[2])
459 {
460  const float tolerance_in_pixels_squared = 4 * 4;
461 
462  if (spline->flag & MASK_SPLINE_CYCLIC) {
463  /* The spline is already cyclic, so there is no need to handle anything here.
464  * Return PASS_THROUGH so that it's possible to add vertices close to the endpoints of the
465  * cyclic spline. */
466  return OPERATOR_PASS_THROUGH;
467  }
468 
469  float co_pixel[2];
470  mask_point_make_pixel_space(C, co, co_pixel);
471 
472  float point_pixel[2];
473  mask_point_make_pixel_space(C, other_point->bezt.vec[1], point_pixel);
474 
475  const float dist_squared = len_squared_v2v2(co_pixel, point_pixel);
476  if (dist_squared > tolerance_in_pixels_squared) {
477  return OPERATOR_PASS_THROUGH;
478  }
479 
480  spline->flag |= MASK_SPLINE_CYCLIC;
481 
482  /* TODO, update keyframes in time. */
483  BKE_mask_calc_handle_point_auto(spline, active_point, false);
484  BKE_mask_calc_handle_point_auto(spline, other_point, false);
485 
487 
489 
490  return OPERATOR_FINISHED;
491 }
492 
494  bContext *C, Mask *mask, MaskSpline *spline, MaskSplinePoint *active_point, float co[2])
495 {
496  MaskSplinePoint *first_point = &spline->points[0];
497  MaskSplinePoint *last_point = &spline->points[spline->tot_point - 1];
498  const bool is_first_point_active = (active_point == first_point);
499  const bool is_last_point_active = (active_point == last_point);
500  if (is_last_point_active) {
501  return add_vertex_handle_cyclic_at_point(C, mask, spline, active_point, first_point, co);
502  }
503  if (is_first_point_active) {
504  return add_vertex_handle_cyclic_at_point(C, mask, spline, active_point, last_point, co);
505  }
506  return OPERATOR_PASS_THROUGH;
507 }
508 
510 {
511  MaskViewLockState lock_state;
512  ED_mask_view_lock_state_store(C, &lock_state);
513 
515  if (mask == NULL) {
516  /* if there's no active mask, create one */
517  mask = ED_mask_new(C, NULL);
518  }
519 
520  MaskLayer *mask_layer = BKE_mask_layer_active(mask);
521 
522  if (mask_layer && mask_layer->restrictflag & (MASK_RESTRICT_VIEW | MASK_RESTRICT_SELECT)) {
523  mask_layer = NULL;
524  }
525 
526  float co[2];
527  RNA_float_get_array(op->ptr, "location", co);
528 
529  /* TODO, having an active point but no active spline is possible, why? */
530  if (mask_layer && mask_layer->act_spline && mask_layer->act_point &&
531  MASKPOINT_ISSEL_ANY(mask_layer->act_point)) {
532  MaskSpline *spline = mask_layer->act_spline;
533  MaskSplinePoint *active_point = mask_layer->act_point;
534  const int cyclic_result = add_vertex_handle_cyclic(C, mask, spline, active_point, co);
535  if (cyclic_result != OPERATOR_PASS_THROUGH) {
536  return cyclic_result;
537  }
538 
539  if (!add_vertex_subdivide(C, mask, co)) {
540  if (!add_vertex_extrude(C, mask, mask_layer, co)) {
541  return OPERATOR_CANCELLED;
542  }
543  }
544  }
545  else {
546  if (!add_vertex_subdivide(C, mask, co)) {
547  if (!add_vertex_new(C, mask, mask_layer, co)) {
548  return OPERATOR_CANCELLED;
549  }
550  }
551  }
552 
554 
556 
557  return OPERATOR_FINISHED;
558 }
559 
560 static int add_vertex_invoke(bContext *C, wmOperator *op, const wmEvent *event)
561 {
563  ARegion *region = CTX_wm_region(C);
564 
565  float co[2];
566 
567  ED_mask_mouse_pos(area, region, event->mval, co);
568 
569  RNA_float_set_array(op->ptr, "location", co);
570 
571  return add_vertex_exec(C, op);
572 }
573 
575 {
576  /* identifiers */
577  ot->name = "Add Vertex";
578  ot->description = "Add vertex to active spline";
579  ot->idname = "MASK_OT_add_vertex";
580 
581  /* api callbacks */
585 
586  /* flags */
588 
589  /* properties */
591  "location",
592  2,
593  NULL,
594  -FLT_MAX,
595  FLT_MAX,
596  "Location",
597  "Location of vertex in normalized space",
598  -1.0f,
599  1.0f);
600 }
601 
602 /******************** add feather vertex *********************/
603 
605 {
607  MaskLayer *mask_layer;
608  MaskSpline *spline;
609  MaskSplinePoint *point = NULL;
610  const float threshold = 9;
611  float co[2], u;
612 
613  RNA_float_get_array(op->ptr, "location", co);
614 
615  point = ED_mask_point_find_nearest(C, mask, co, threshold, NULL, NULL, NULL, NULL);
616  if (point) {
617  return OPERATOR_FINISHED;
618  }
619 
621  mask,
622  co,
623  threshold,
624  true,
625  NULL,
626  true,
627  true,
628  &mask_layer,
629  &spline,
630  &point,
631  &u,
632  NULL)) {
633  float w = BKE_mask_point_weight(spline, point, u);
634  float weight_scalar = BKE_mask_point_weight_scalar(spline, point, u);
635 
636  if (weight_scalar != 0.0f) {
637  w = w / weight_scalar;
638  }
639 
640  BKE_mask_point_add_uw(point, u, w);
641 
643 
645 
646  return OPERATOR_FINISHED;
647  }
648 
649  return OPERATOR_CANCELLED;
650 }
651 
652 static int add_feather_vertex_invoke(bContext *C, wmOperator *op, const wmEvent *event)
653 {
655  ARegion *region = CTX_wm_region(C);
656 
657  float co[2];
658 
659  ED_mask_mouse_pos(area, region, event->mval, co);
660 
661  RNA_float_set_array(op->ptr, "location", co);
662 
663  return add_feather_vertex_exec(C, op);
664 }
665 
667 {
668  /* identifiers */
669  ot->name = "Add Feather Vertex";
670  ot->description = "Add vertex to feather";
671  ot->idname = "MASK_OT_add_feather_vertex";
672 
673  /* api callbacks */
677 
678  /* flags */
680 
681  /* properties */
683  "location",
684  2,
685  NULL,
686  -FLT_MAX,
687  FLT_MAX,
688  "Location",
689  "Location of vertex in normalized space",
690  -1.0f,
691  1.0f);
692 }
693 
694 /******************** common primitive functions *********************/
695 
696 static BezTriple *points_to_bezier(const float (*points)[2],
697  const int num_points,
698  const char handle_type,
699  const float scale,
700  const float location[2])
701 {
702  BezTriple *bezier_points = MEM_calloc_arrayN(num_points, sizeof(BezTriple), __func__);
703  for (int i = 0; i < num_points; i++) {
704  copy_v2_v2(bezier_points[i].vec[1], points[i]);
705  mul_v2_fl(bezier_points[i].vec[1], scale);
706  add_v2_v2(bezier_points[i].vec[1], location);
707 
708  bezier_points[i].h1 = handle_type;
709  bezier_points[i].h2 = handle_type;
710  }
711 
712  for (int i = 0; i < num_points; i++) {
713  BKE_nurb_handle_calc(&bezier_points[i],
714  &bezier_points[(i - 1 + num_points) % num_points],
715  &bezier_points[(i + 1) % num_points],
716  false,
717  false);
718  }
719 
720  return bezier_points;
721 }
722 
724  bContext *C, wmOperator *op, const float (*points)[2], int num_points, char handle_type)
725 {
726  MaskViewLockState lock_state;
727  ED_mask_view_lock_state_store(C, &lock_state);
728 
730  int size = RNA_float_get(op->ptr, "size");
731 
732  int width, height;
734  float scale = (float)size / max_ii(width, height);
735 
736  /* Get location in mask space. */
737  float frame_size[2];
738  frame_size[0] = width;
739  frame_size[1] = height;
740  float location[2];
741  RNA_float_get_array(op->ptr, "location", location);
742  location[0] /= width;
743  location[1] /= height;
744  BKE_mask_coord_from_frame(location, location, frame_size);
745 
746  /* Make it so new primitive is centered to mouse location. */
747  location[0] -= 0.5f * scale;
748  location[1] -= 0.5f * scale;
749 
750  bool added_mask = false;
751  MaskLayer *mask_layer = ED_mask_layer_ensure(C, &added_mask);
753 
755 
756  MaskSpline *new_spline = BKE_mask_spline_add(mask_layer);
757  new_spline->flag = MASK_SPLINE_CYCLIC | SELECT;
758  new_spline->points = MEM_recallocN(new_spline->points, sizeof(MaskSplinePoint) * num_points);
759 
760  mask_layer->act_spline = new_spline;
761  mask_layer->act_point = NULL;
762 
763  const int spline_index = BKE_mask_layer_shape_spline_to_index(mask_layer, new_spline);
764 
765  BezTriple *bezier_points = points_to_bezier(points, num_points, handle_type, scale, location);
766 
767  for (int i = 0; i < num_points; i++) {
768  new_spline->tot_point = i + 1;
769 
770  MaskSplinePoint *new_point = &new_spline->points[i];
771  BKE_mask_parent_init(&new_point->parent);
772 
773  new_point->bezt = bezier_points[i];
774 
775  BKE_mask_point_select_set(new_point, true);
776 
777  if (mask_layer->splines_shapes.first) {
778  BKE_mask_layer_shape_changed_add(mask_layer, spline_index + i, true, false);
779  }
780  }
781 
782  MEM_freeN(bezier_points);
783 
784  if (added_mask) {
786  }
788 
790 
792 
793  return OPERATOR_FINISHED;
794 }
795 
796 static int primitive_add_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
797 {
799  float cursor[2];
800  int width, height;
801 
804 
805  cursor[0] *= width;
806  cursor[1] *= height;
807 
808  RNA_float_set_array(op->ptr, "location", cursor);
809 
810  return op->type->exec(C, op);
811 }
812 
814 {
816  ot->srna, "size", 100, -FLT_MAX, FLT_MAX, "Size", "Size of new circle", -FLT_MAX, FLT_MAX);
818  "location",
819  2,
820  NULL,
821  -FLT_MAX,
822  FLT_MAX,
823  "Location",
824  "Location of new circle",
825  -FLT_MAX,
826  FLT_MAX);
827 }
828 
829 /******************** primitive add circle *********************/
830 
832 {
833  const float points[4][2] = {{0.0f, 0.5f}, {0.5f, 1.0f}, {1.0f, 0.5f}, {0.5f, 0.0f}};
834  int num_points = sizeof(points) / (sizeof(float[2]));
835 
836  create_primitive_from_points(C, op, points, num_points, HD_AUTO);
837 
838  return OPERATOR_FINISHED;
839 }
840 
842 {
843  /* identifiers */
844  ot->name = "Add Circle";
845  ot->description = "Add new circle-shaped spline";
846  ot->idname = "MASK_OT_primitive_circle_add";
847 
848  /* api callbacks */
852 
853  /* flags */
855 
856  /* properties */
858 }
859 
860 /******************** primitive add suqare *********************/
861 
863 {
864  const float points[4][2] = {{0.0f, 0.0f}, {0.0f, 1.0f}, {1.0f, 1.0f}, {1.0f, 0.0f}};
865  int num_points = sizeof(points) / (sizeof(float[2]));
866 
867  create_primitive_from_points(C, op, points, num_points, HD_VECT);
868 
869  return OPERATOR_FINISHED;
870 }
871 
873 {
874  /* identifiers */
875  ot->name = "Add Square";
876  ot->description = "Add new square-shaped spline";
877  ot->idname = "MASK_OT_primitive_square_add";
878 
879  /* api callbacks */
883 
884  /* flags */
886 
887  /* properties */
889 }
typedef float(TangentPoint)[2]
struct ScrArea * CTX_wm_area(const bContext *C)
Definition: context.c:714
struct Scene * CTX_data_scene(const bContext *C)
Definition: context.c:1034
struct Mask * CTX_data_edit_mask(const bContext *C)
Definition: context.c:1316
struct ARegion * CTX_wm_region(const bContext *C)
Definition: context.c:725
void BKE_nurb_handle_calc(struct BezTriple *bezt, struct BezTriple *prev, struct BezTriple *next, const bool is_fcurve, const char smoothing)
Definition: curve.c:4069
void BKE_mask_calc_handle_adjacent_interp(struct MaskSpline *spline, struct MaskSplinePoint *point, const float u)
Definition: mask.c:1471
#define MASKPOINT_ISSEL_ANY(p)
Definition: BKE_mask.h:232
void BKE_mask_layer_shape_changed_add(struct MaskLayer *masklay, int index, bool do_init, bool do_init_interpolate)
Definition: mask.c:1927
void BKE_mask_calc_tangent_polyline(struct MaskSpline *spline, struct MaskSplinePoint *point, float t[2])
Definition: mask.c:1434
void BKE_mask_point_select_set(struct MaskSplinePoint *point, const bool do_select)
Definition: mask.c:971
struct MaskLayer * BKE_mask_layer_new(struct Mask *mask, const char *name)
Definition: mask.c:351
#define MASKPOINT_SEL_ALL(p)
Definition: BKE_mask.h:241
struct MaskLayer * BKE_mask_layer_active(struct Mask *mask)
Definition: mask.c:376
void BKE_mask_point_parent_matrix_get(struct MaskSplinePoint *point, float ctime, float parent_matrix[3][3])
Definition: mask.c:1297
void BKE_mask_calc_handle_point_auto(struct MaskSpline *spline, struct MaskSplinePoint *point, const bool do_recalc_length)
Resets auto handles even for non-auto bezier points.
Definition: mask.c:1522
void BKE_mask_point_add_uw(struct MaskSplinePoint *point, float u, float w)
Definition: mask.c:953
int BKE_mask_layer_shape_spline_to_index(struct MaskLayer *masklay, struct MaskSpline *spline)
Definition: mask.c:1878
void BKE_mask_parent_init(struct MaskParent *parent)
Definition: mask.c:1604
float BKE_mask_point_weight_scalar(struct MaskSpline *spline, struct MaskSplinePoint *point, const float u)
Definition: mask.c:853
#define MASKPOINT_DESEL_ALL(p)
Definition: BKE_mask.h:248
float BKE_mask_point_weight(struct MaskSpline *spline, struct MaskSplinePoint *point, const float u)
Definition: mask.c:873
void BKE_mask_coord_from_frame(float r_co[2], const float co[2], const float frame_size[2])
Definition: mask.c:1203
struct MaskSpline * BKE_mask_spline_add(struct MaskLayer *masklay)
Definition: mask.c:484
#define BLI_assert(a)
Definition: BLI_assert.h:58
MINLINE int max_ii(int a, int b)
MINLINE int mod_i(int i, int n)
void mul_m3_v2(const float m[3][3], float r[2])
Definition: math_matrix.c:727
bool invert_m3(float R[3][3])
Definition: math_matrix.c:1152
MINLINE float len_squared_v2v2(const float a[2], const float b[2]) ATTR_WARN_UNUSED_RESULT
MINLINE void mul_v2_fl(float r[2], float f)
MINLINE void copy_v2_v2(float r[2], const float a[2])
MINLINE void copy_v3_v3(float r[3], const float a[3])
MINLINE void add_v2_v2(float r[2], const float a[2])
MINLINE void sub_v2_v2v2(float r[2], const float a[2], const float b[2])
MINLINE float dot_v2v2(const float a[2], const float b[2]) ATTR_WARN_UNUSED_RESULT
#define UNUSED(x)
#define MAX2(a, b)
#define ELEM(...)
void DEG_id_tag_update(struct ID *id, int flag)
@ ID_RECALC_GEOMETRY
Definition: DNA_ID.h:611
@ HD_VECT
@ HD_AUTO
@ HD_ALIGN
#define MASK_RESTRICT_SELECT
#define MASK_RESTRICT_VIEW
@ MASK_SPLINE_CYCLIC
#define CFRA
@ OPERATOR_CANCELLED
@ OPERATOR_FINISHED
@ OPERATOR_PASS_THROUGH
void ED_mask_mouse_pos(struct ScrArea *area, struct ARegion *region, const int mval[2], float co[2])
Definition: mask_query.c:493
void ED_mask_pixelspace_factor(struct ScrArea *area, struct ARegion *region, float *scalex, float *scaley)
Definition: mask_query.c:788
void ED_mask_cursor_location_get(struct ScrArea *area, float cursor[2])
Definition: mask_query.c:831
void ED_mask_get_size(struct ScrArea *area, int *width, int *height)
Definition: mask_query.c:691
bool ED_operator_mask(struct bContext *C)
Definition: screen_ops.c:616
@ SEL_DESELECT
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei width
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei height
Read Guarded memory(de)allocation.
#define MEM_recallocN(vmemh, len)
#define C
Definition: RandGen.cpp:39
@ OPTYPE_UNDO
Definition: WM_types.h:155
@ OPTYPE_REGISTER
Definition: WM_types.h:153
#define NA_ADDED
Definition: WM_types.h:464
#define NA_EDITED
Definition: WM_types.h:462
#define NC_MASK
Definition: WM_types.h:299
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
Definition: btDbvt.cpp:52
SIMD_FORCE_INLINE const btScalar & w() const
Return the w value.
Definition: btQuadWord.h:119
#define SELECT
Scene scene
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:41
void *(* MEM_calloc_arrayN)(size_t len, size_t size, const char *str)
Definition: mallocn.c:46
void *(* MEM_callocN)(size_t len, const char *str)
Definition: mallocn.c:45
void MASK_OT_add_feather_vertex(wmOperatorType *ot)
Definition: mask_add.c:666
static int create_primitive_from_points(bContext *C, wmOperator *op, const float(*points)[2], int num_points, char handle_type)
Definition: mask_add.c:723
static int add_vertex_exec(bContext *C, wmOperator *op)
Definition: mask_add.c:509
static int primitive_circle_add_exec(bContext *C, wmOperator *op)
Definition: mask_add.c:831
static BezTriple * points_to_bezier(const float(*points)[2], const int num_points, const char handle_type, const float scale, const float location[2])
Definition: mask_add.c:696
static int primitive_square_add_exec(bContext *C, wmOperator *op)
Definition: mask_add.c:862
static bool add_vertex_extrude(const bContext *C, Mask *mask, MaskLayer *mask_layer, const float co[2])
Definition: mask_add.c:298
static void setup_vertex_point(Mask *mask, MaskSpline *spline, MaskSplinePoint *new_point, const float point_co[2], const float u, const float ctime, const MaskSplinePoint *reference_point, const bool reference_adjacent)
Definition: mask_add.c:52
void MASK_OT_primitive_square_add(wmOperatorType *ot)
Definition: mask_add.c:872
static int add_feather_vertex_invoke(bContext *C, wmOperator *op, const wmEvent *event)
Definition: mask_add.c:652
static int add_feather_vertex_exec(bContext *C, wmOperator *op)
Definition: mask_add.c:604
void MASK_OT_primitive_circle_add(wmOperatorType *ot)
Definition: mask_add.c:841
static void define_primitive_add_properties(wmOperatorType *ot)
Definition: mask_add.c:813
static int add_vertex_handle_cyclic(bContext *C, Mask *mask, MaskSpline *spline, MaskSplinePoint *active_point, float co[2])
Definition: mask_add.c:493
static void mask_point_make_pixel_space(bContext *C, const float point_normalized[2], float point_pixel[2])
Definition: mask_add.c:439
static int primitive_add_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
Definition: mask_add.c:796
static bool add_vertex_new(const bContext *C, Mask *mask, MaskLayer *mask_layer, const float co[2])
Definition: mask_add.c:398
static int add_vertex_handle_cyclic_at_point(bContext *C, Mask *mask, MaskSpline *spline, MaskSplinePoint *active_point, MaskSplinePoint *other_point, float co[2])
Definition: mask_add.c:453
static bool add_vertex_subdivide(const bContext *C, Mask *mask, const float co[2])
Definition: mask_add.c:244
void MASK_OT_add_vertex(wmOperatorType *ot)
Definition: mask_add.c:574
static int add_vertex_invoke(bContext *C, wmOperator *op, const wmEvent *event)
Definition: mask_add.c:560
static void finSelectedSplinePoint(MaskLayer *mask_layer, MaskSpline **spline, MaskSplinePoint **point, bool check_active)
Definition: mask_add.c:181
static void mask_spline_add_point_at_index(MaskSpline *spline, int point_index)
Definition: mask_add.c:227
void ED_mask_view_lock_state_restore_no_jump(const bContext *C, const MaskViewLockState *state)
Definition: mask_edit.c:200
bool ED_maskedit_mask_poll(bContext *C)
Definition: mask_edit.c:61
void ED_mask_view_lock_state_store(const bContext *C, MaskViewLockState *state)
Definition: mask_edit.c:192
void ED_mask_select_flush_all(struct Mask *mask)
Definition: mask_select.c:165
struct MaskSplinePoint * ED_mask_point_find_nearest(const struct bContext *C, struct Mask *mask, const float normal_co[2], const float threshold, struct MaskLayer **r_mask_layer, struct MaskSpline **r_spline, eMaskWhichHandle *r_which_handle, float *r_score)
struct Mask * ED_mask_new(struct bContext *C, const char *name)
Definition: mask_ops.c:57
bool ED_mask_find_nearest_diff_point(const struct bContext *C, struct Mask *mask, const float normal_co[2], int threshold, bool feather, float tangent[2], const bool use_deform, const bool use_project, struct MaskLayer **r_mask_layer, struct MaskSpline **r_spline, struct MaskSplinePoint **r_point, float *r_u, float *r_score)
void ED_mask_select_toggle_all(struct Mask *mask, int action)
Definition: mask_select.c:128
struct MaskLayer * ED_mask_layer_ensure(struct bContext *C, bool *r_added_mask)
Definition: mask_ops.c:88
static void area(int d1, int d2, int e1, int e2, float weights[2])
void RNA_float_get_array(PointerRNA *ptr, const char *name, float *values)
Definition: rna_access.c:6378
float RNA_float_get(PointerRNA *ptr, const char *name)
Definition: rna_access.c:6355
void RNA_float_set_array(PointerRNA *ptr, const char *name, const float *values)
Definition: rna_access.c:6390
PropertyRNA * RNA_def_float(StructOrFunctionRNA *cont_, const char *identifier, float default_value, float hardmin, float hardmax, const char *ui_name, const char *ui_description, float softmin, float softmax)
Definition: rna_define.c:3825
PropertyRNA * RNA_def_float_vector(StructOrFunctionRNA *cont_, const char *identifier, int len, const float *default_value, float hardmin, float hardmax, const char *ui_name, const char *ui_description, float softmin, float softmax)
Definition: rna_define.c:3851
float vec[3][3]
void * first
Definition: DNA_listBase.h:47
ListBase splines_shapes
ListBase splines
struct MaskSplinePoint * act_point
char restrictflag
struct MaskSpline * act_spline
MaskParent parent
struct MaskSpline * next
MaskSplinePoint * points
int mval[2]
Definition: WM_types.h:583
int(* invoke)(struct bContext *, struct wmOperator *, const struct wmEvent *) ATTR_WARN_UNUSED_RESULT
Definition: WM_types.h:752
const char * name
Definition: WM_types.h:721
const char * idname
Definition: WM_types.h:723
bool(* poll)(struct bContext *) ATTR_WARN_UNUSED_RESULT
Definition: WM_types.h:776
struct StructRNA * srna
Definition: WM_types.h:802
const char * description
Definition: WM_types.h:726
int(* exec)(struct bContext *, struct wmOperator *) ATTR_WARN_UNUSED_RESULT
Definition: WM_types.h:736
struct wmOperatorType * type
struct PointerRNA * ptr
ccl_device_inline float4 mask(const int4 &mask, const float4 &a)
void WM_event_add_notifier(const bContext *C, uint type, void *reference)
wmOperatorType * ot
Definition: wm_files.c:3156