Blender V5.0
mask_add.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2012 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
8
9#include <algorithm>
10
11#include "MEM_guardedalloc.h"
12
13#include "BKE_context.hh"
14#include "BKE_curve.hh"
15#include "BKE_mask.h"
16
17#include "BLI_math_matrix.h"
18#include "BLI_math_vector.h"
19
20#include "DEG_depsgraph.hh"
21
22#include "DNA_mask_types.h"
23#include "DNA_scene_types.h"
24#include "DNA_screen_types.h"
25
26#include "WM_api.hh"
27#include "WM_types.hh"
28
29#include "ED_mask.hh" /* own include */
30#include "ED_select_utils.hh"
31
32#include "RNA_access.hh"
33#include "RNA_define.hh"
34
35#include "mask_intern.hh" /* own include */
36
37/* -------------------------------------------------------------------- */
40
42 MaskSpline *spline,
43 MaskSplinePoint *new_point,
44 const float point_co[2],
45 const float u,
46 const float ctime,
47 const MaskSplinePoint *reference_point,
48 const bool reference_adjacent)
49{
50 const MaskSplinePoint *reference_parent_point = nullptr;
51 BezTriple *bezt;
52 float co[3];
53
54 copy_v2_v2(co, point_co);
55 co[2] = 0.0f;
56
57 /* point coordinate */
58 bezt = &new_point->bezt;
59
60 bezt->h1 = bezt->h2 = HD_ALIGN;
61
62 if (reference_point) {
63 if (reference_point->bezt.h1 == HD_VECT && reference_point->bezt.h2 == HD_VECT) {
64 /* If the reference point is sharp try using some smooth point as reference
65 * for handles.
66 */
67 int point_index = reference_point - spline->points;
68 int delta = new_point == spline->points ? 1 : -1;
69 for (int i = 0; i < spline->tot_point - 1; i++) {
70 MaskSplinePoint *current_point;
71
72 point_index += delta;
73 if (point_index == -1 || point_index >= spline->tot_point) {
74 if (spline->flag & MASK_SPLINE_CYCLIC) {
75 if (point_index == -1) {
76 point_index = spline->tot_point - 1;
77 }
78 else if (point_index >= spline->tot_point) {
79 point_index = 0;
80 }
81 }
82 else {
83 break;
84 }
85 }
86
87 current_point = &spline->points[point_index];
88 if (current_point->bezt.h1 != HD_VECT || current_point->bezt.h2 != HD_VECT) {
89 bezt->h1 = bezt->h2 = std::max(current_point->bezt.h2, current_point->bezt.h1);
90 break;
91 }
92 }
93 }
94 else {
95 bezt->h1 = bezt->h2 = std::max(reference_point->bezt.h2, reference_point->bezt.h1);
96 }
97
98 reference_parent_point = reference_point;
99 }
100 else if (reference_adjacent) {
101 if (spline->tot_point != 1) {
102 MaskSplinePoint *prev_point, *next_point, *close_point;
103
104 const int index = int(new_point - spline->points);
105 if (spline->flag & MASK_SPLINE_CYCLIC) {
106 prev_point = &spline->points[mod_i(index - 1, spline->tot_point)];
107 next_point = &spline->points[mod_i(index + 1, spline->tot_point)];
108 }
109 else {
110 prev_point = (index != 0) ? &spline->points[index - 1] : nullptr;
111 next_point = (index != spline->tot_point - 1) ? &spline->points[index + 1] : nullptr;
112 }
113
114 if (prev_point && next_point) {
115 close_point = (len_squared_v2v2(new_point->bezt.vec[1], prev_point->bezt.vec[1]) <
116 len_squared_v2v2(new_point->bezt.vec[1], next_point->bezt.vec[1])) ?
117 prev_point :
118 next_point;
119 }
120 else {
121 close_point = prev_point ? prev_point : next_point;
122 }
123
124 /* handle type */
125 uint8_t handle_type = 0;
126 if (prev_point) {
127 handle_type = prev_point->bezt.h2;
128 }
129 if (next_point) {
130 handle_type = std::max(next_point->bezt.h2, handle_type);
131 }
132 bezt->h1 = bezt->h2 = handle_type;
133
134 /* parent */
135 reference_parent_point = close_point;
136
137 /* NOTE: we may want to copy other attributes later, radius? pressure? color? */
138 }
139 }
140
141 copy_v3_v3(bezt->vec[0], co);
142 copy_v3_v3(bezt->vec[1], co);
143 copy_v3_v3(bezt->vec[2], co);
144
145 if (reference_parent_point) {
146 new_point->parent = reference_parent_point->parent;
147
148 if (new_point->parent.id) {
149 float parent_matrix[3][3];
150 BKE_mask_point_parent_matrix_get(new_point, ctime, parent_matrix);
151 invert_m3(parent_matrix);
152 mul_m3_v2(parent_matrix, new_point->bezt.vec[1]);
153 }
154 }
155 else {
156 BKE_mask_parent_init(&new_point->parent);
157 }
158
159 if (spline->tot_point != 1) {
160 BKE_mask_calc_handle_adjacent_interp(spline, new_point, u);
161 }
162
163 /* select new point */
164 MASKPOINT_SEL_ALL(new_point);
166}
167
169
170/* -------------------------------------------------------------------- */
173
174static void finSelectedSplinePoint(MaskLayer *mask_layer,
175 MaskSpline **spline,
176 MaskSplinePoint **point,
177 bool check_active)
178{
179 MaskSpline *cur_spline = static_cast<MaskSpline *>(mask_layer->splines.first);
180
181 *spline = nullptr;
182 *point = nullptr;
183
184 if (check_active) {
185 /* TODO: having an active point but no active spline is possible, why? */
186 if (mask_layer->act_spline && mask_layer->act_point &&
187 MASKPOINT_ISSEL_ANY(mask_layer->act_point))
188 {
189 *spline = mask_layer->act_spline;
190 *point = mask_layer->act_point;
191 return;
192 }
193 }
194
195 while (cur_spline) {
196 for (int i = 0; i < cur_spline->tot_point; i++) {
197 MaskSplinePoint *cur_point = &cur_spline->points[i];
198
199 if (MASKPOINT_ISSEL_ANY(cur_point)) {
200 if (!ELEM(*spline, nullptr, cur_spline)) {
201 *spline = nullptr;
202 *point = nullptr;
203 return;
204 }
205 if (*point) {
206 *point = nullptr;
207 }
208 else {
209 *spline = cur_spline;
210 *point = cur_point;
211 }
212 }
213 }
214
215 cur_spline = cur_spline->next;
216 }
217}
218
220
221/* -------------------------------------------------------------------- */
224
225static void mask_spline_add_point_at_index(MaskSpline *spline, int point_index)
226{
227 MaskSplinePoint *new_point_array;
228
229 new_point_array = MEM_calloc_arrayN<MaskSplinePoint>(spline->tot_point + 1,
230 "add mask vert points");
231
232 memcpy(new_point_array, spline->points, sizeof(MaskSplinePoint) * (point_index + 1));
233 memcpy(new_point_array + point_index + 2,
234 spline->points + point_index + 1,
235 sizeof(MaskSplinePoint) * (spline->tot_point - point_index - 1));
236
237 MEM_freeN(spline->points);
238 spline->points = new_point_array;
239 spline->tot_point++;
240}
241
242static bool add_vertex_subdivide(const bContext *C, Mask *mask, const float co[2])
243{
244 MaskLayer *mask_layer;
245 MaskSpline *spline;
246 MaskSplinePoint *point = nullptr;
247 const float threshold = 12;
248 float tangent[2];
249 float u;
250
252 mask,
253 co,
254 threshold,
255 false,
256 tangent,
257 true,
258 true,
259 &mask_layer,
260 &spline,
261 &point,
262 &u,
263 nullptr))
264 {
265 Scene *scene = CTX_data_scene(C);
266 const float ctime = scene->r.cfra;
267
268 MaskSplinePoint *new_point;
269 int point_index = point - spline->points;
270
272
273 mask_spline_add_point_at_index(spline, point_index);
274
275 new_point = &spline->points[point_index + 1];
276
277 setup_vertex_point(mask, spline, new_point, co, u, ctime, nullptr, true);
278
279 /* TODO: we could pass the spline! */
281 BKE_mask_layer_shape_spline_to_index(mask_layer, spline) +
282 point_index + 1,
283 true,
284 true);
285
286 mask_layer->act_spline = spline;
287 mask_layer->act_point = new_point;
288
290
291 return true;
292 }
293
294 return false;
295}
296
297static bool add_vertex_extrude(const bContext *C,
298 Mask *mask,
299 MaskLayer *mask_layer,
300 const float co[2])
301{
302 Scene *scene = CTX_data_scene(C);
303 const float ctime = scene->r.cfra;
304
305 MaskSpline *spline;
306 MaskSplinePoint *point;
307 MaskSplinePoint *new_point = nullptr, *ref_point = nullptr;
308
309 /* check on which side we want to add the point */
310 int point_index;
311 float tangent_point[2];
312 float tangent_co[2];
313 bool do_cyclic_correct = false;
314 bool do_prev; /* use prev point rather than next?? */
315
316 if (!mask_layer) {
317 return false;
318 }
319 finSelectedSplinePoint(mask_layer, &spline, &point, true);
320
322
323 point_index = (point - spline->points);
324
325 MASKPOINT_DESEL_ALL(point);
326
327 if ((spline->flag & MASK_SPLINE_CYCLIC) ||
328 (point_index > 0 && point_index != spline->tot_point - 1))
329 {
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#if 0
365 print_v2("", tangent_point);
366 printf("%d\n", point_index);
367#endif
368
369 mask_spline_add_point_at_index(spline, point_index);
370
371 if (do_cyclic_correct) {
372 ref_point = &spline->points[point_index + 1];
373 new_point = &spline->points[point_index];
374 *ref_point = *new_point;
375 *new_point = MaskSplinePoint{};
376 }
377 else {
378 ref_point = &spline->points[point_index];
379 new_point = &spline->points[point_index + 1];
380 }
381
382 mask_layer->act_point = new_point;
383
384 setup_vertex_point(mask, spline, new_point, co, 0.5f, ctime, ref_point, false);
385
386 if (mask_layer->splines_shapes.first) {
387 point_index = ((int(new_point - spline->points) + 0) % spline->tot_point);
389 BKE_mask_layer_shape_spline_to_index(mask_layer, spline) +
390 point_index,
391 true,
392 true);
393 }
394
396
397 return true;
398}
399
400static bool add_vertex_new(const bContext *C, Mask *mask, MaskLayer *mask_layer, const float co[2])
401{
402 Scene *scene = CTX_data_scene(C);
403 const float ctime = scene->r.cfra;
404
405 MaskSpline *spline;
406 MaskSplinePoint *new_point = nullptr, *ref_point = nullptr;
407
408 if (!mask_layer) {
409 /* If there's no mask layer currently operating on, create new one. */
410 mask_layer = BKE_mask_layer_new(mask, "");
411 mask->masklay_act = mask->masklay_tot - 1;
412 }
413
415
416 spline = BKE_mask_spline_add(mask_layer);
417
418 mask_layer->act_spline = spline;
419 new_point = spline->points;
420
421 mask_layer->act_point = new_point;
422
423 setup_vertex_point(mask, spline, new_point, co, 0.5f, ctime, ref_point, false);
424
425 {
426 int point_index = ((int(new_point - spline->points) + 0) % spline->tot_point);
428 BKE_mask_layer_shape_spline_to_index(mask_layer, spline) +
429 point_index,
430 true,
431 true);
432 }
433
435
436 return true;
437}
438
439/* Convert coordinate from normalized space to pixel one.
440 * TODO(sergey): Make the function more generally available. */
442 const float point_normalized[2],
443 float point_pixel[2])
444{
445 ScrArea *area = CTX_wm_area(C);
446 ARegion *region = CTX_wm_region(C);
447
448 float scalex, scaley;
449 ED_mask_pixelspace_factor(area, region, &scalex, &scaley);
450
451 point_pixel[0] = point_normalized[0] * scalex;
452 point_pixel[1] = point_normalized[1] * scaley;
453}
454
456 Mask *mask,
457 MaskSpline *spline,
458 MaskSplinePoint *active_point,
459 MaskSplinePoint *other_point,
460 float co[2])
461{
462 const float tolerance_in_pixels_squared = 4 * 4;
463
464 if (spline->flag & MASK_SPLINE_CYCLIC) {
465 /* The spline is already cyclic, so there is no need to handle anything here.
466 * Return PASS_THROUGH so that it's possible to add vertices close to the endpoints of the
467 * cyclic spline. */
469 }
470
471 float co_pixel[2];
472 mask_point_make_pixel_space(C, co, co_pixel);
473
474 float point_pixel[2];
475 mask_point_make_pixel_space(C, other_point->bezt.vec[1], point_pixel);
476
477 const float dist_squared = len_squared_v2v2(co_pixel, point_pixel);
478 if (dist_squared > tolerance_in_pixels_squared) {
480 }
481
482 spline->flag |= MASK_SPLINE_CYCLIC;
483
484 /* TODO: update keyframes in time. */
485 BKE_mask_calc_handle_point_auto(spline, active_point, false);
486 BKE_mask_calc_handle_point_auto(spline, other_point, false);
487
489
491
492 return OPERATOR_FINISHED;
493}
494
496 bContext *C, Mask *mask, MaskSpline *spline, MaskSplinePoint *active_point, float co[2])
497{
498 MaskSplinePoint *first_point = &spline->points[0];
499 MaskSplinePoint *last_point = &spline->points[spline->tot_point - 1];
500 const bool is_first_point_active = (active_point == first_point);
501 const bool is_last_point_active = (active_point == last_point);
502 if (is_last_point_active) {
503 return add_vertex_handle_cyclic_at_point(C, mask, spline, active_point, first_point, co);
504 }
505 if (is_first_point_active) {
506 return add_vertex_handle_cyclic_at_point(C, mask, spline, active_point, last_point, co);
507 }
509}
510
512
513/* -------------------------------------------------------------------- */
516
518{
519 MaskViewLockState lock_state;
520 ED_mask_view_lock_state_store(C, &lock_state);
521
523 if (mask == nullptr) {
524 /* if there's no active mask, create one */
525 mask = ED_mask_new(C, nullptr);
526 }
527
528 MaskLayer *mask_layer = BKE_mask_layer_active(mask);
529
530 if (mask_layer && mask_layer->visibility_flag & (MASK_HIDE_VIEW | MASK_HIDE_SELECT)) {
531 mask_layer = nullptr;
532 }
533
534 float co[2];
535 RNA_float_get_array(op->ptr, "location", co);
536
537 /* TODO: having an active point but no active spline is possible, why? */
538 if (mask_layer && mask_layer->act_spline && mask_layer->act_point &&
539 MASKPOINT_ISSEL_ANY(mask_layer->act_point))
540 {
541 MaskSpline *spline = mask_layer->act_spline;
542 MaskSplinePoint *active_point = mask_layer->act_point;
543 const wmOperatorStatus cyclic_result = add_vertex_handle_cyclic(
544 C, mask, spline, active_point, co);
545 if (cyclic_result != OPERATOR_PASS_THROUGH) {
546 return cyclic_result;
547 }
548
549 if (!add_vertex_subdivide(C, mask, co)) {
550 if (!add_vertex_extrude(C, mask, mask_layer, co)) {
551 return OPERATOR_CANCELLED;
552 }
553 }
554 }
555 else {
556 if (!add_vertex_subdivide(C, mask, co)) {
557 if (!add_vertex_new(C, mask, mask_layer, co)) {
558 return OPERATOR_CANCELLED;
559 }
560 }
561 }
562
564
566
567 return OPERATOR_FINISHED;
568}
569
571{
572 ScrArea *area = CTX_wm_area(C);
573 ARegion *region = CTX_wm_region(C);
574
575 float co[2];
576
577 ED_mask_mouse_pos(area, region, event->mval, co);
578
579 RNA_float_set_array(op->ptr, "location", co);
580
581 return add_vertex_exec(C, op);
582}
583
585{
586 /* identifiers */
587 ot->name = "Add Vertex";
588 ot->description = "Add vertex to active spline";
589 ot->idname = "MASK_OT_add_vertex";
590
591 /* API callbacks. */
592 ot->exec = add_vertex_exec;
593 ot->invoke = add_vertex_invoke;
595
596 /* flags */
598
599 /* properties */
601 "location",
602 2,
603 nullptr,
604 -FLT_MAX,
605 FLT_MAX,
606 "Location",
607 "Location of vertex in normalized space",
608 -1.0f,
609 1.0f);
610}
611
613
614/* -------------------------------------------------------------------- */
617
619{
621 MaskLayer *mask_layer;
622 MaskSpline *spline;
623 MaskSplinePoint *point = nullptr;
624 const float threshold = 12;
625 float co[2], u;
626
627 RNA_float_get_array(op->ptr, "location", co);
628
629 point = ED_mask_point_find_nearest(C, mask, co, threshold, nullptr, nullptr, nullptr, nullptr);
630 if (point) {
631 return OPERATOR_FINISHED;
632 }
633
635 mask,
636 co,
637 threshold,
638 true,
639 nullptr,
640 true,
641 true,
642 &mask_layer,
643 &spline,
644 &point,
645 &u,
646 nullptr))
647 {
648 float w = BKE_mask_point_weight(spline, point, u);
649 float weight_scalar = BKE_mask_point_weight_scalar(spline, point, u);
650
651 if (weight_scalar != 0.0f) {
652 w = w / weight_scalar;
653 }
654
655 BKE_mask_point_add_uw(point, u, w);
656
658
660
661 return OPERATOR_FINISHED;
662 }
663
664 return OPERATOR_CANCELLED;
665}
666
668 wmOperator *op,
669 const wmEvent *event)
670{
671 ScrArea *area = CTX_wm_area(C);
672 ARegion *region = CTX_wm_region(C);
673
674 float co[2];
675
676 ED_mask_mouse_pos(area, region, event->mval, co);
677
678 RNA_float_set_array(op->ptr, "location", co);
679
680 return add_feather_vertex_exec(C, op);
681}
682
684{
685 /* identifiers */
686 ot->name = "Add Feather Vertex";
687 ot->description = "Add vertex to feather";
688 ot->idname = "MASK_OT_add_feather_vertex";
689
690 /* API callbacks. */
694
695 /* flags */
697
698 /* properties */
700 "location",
701 2,
702 nullptr,
703 -FLT_MAX,
704 FLT_MAX,
705 "Location",
706 "Location of vertex in normalized space",
707 -1.0f,
708 1.0f);
709}
710
712
713/* -------------------------------------------------------------------- */
716
717static BezTriple *points_to_bezier(const float (*points)[2],
718 const int num_points,
719 const char handle_type,
720 const float scale,
721 const float location[2])
722{
723 BezTriple *bezier_points = MEM_calloc_arrayN<BezTriple>(num_points, __func__);
724 for (int i = 0; i < num_points; i++) {
725 copy_v2_v2(bezier_points[i].vec[1], points[i]);
726 mul_v2_fl(bezier_points[i].vec[1], scale);
727 add_v2_v2(bezier_points[i].vec[1], location);
728
729 bezier_points[i].h1 = handle_type;
730 bezier_points[i].h2 = handle_type;
731 }
732
733 for (int i = 0; i < num_points; i++) {
734 BKE_nurb_handle_calc(&bezier_points[i],
735 &bezier_points[(i - 1 + num_points) % num_points],
736 &bezier_points[(i + 1) % num_points],
737 false,
738 false);
739 }
740
741 return bezier_points;
742}
743
745 bContext *C, wmOperator *op, const float (*points)[2], int num_points, char handle_type)
746{
747 MaskViewLockState lock_state;
748 ED_mask_view_lock_state_store(C, &lock_state);
749
750 ScrArea *area = CTX_wm_area(C);
751 int size = RNA_float_get(op->ptr, "size");
752
753 int width, height;
754 ED_mask_get_size(area, &width, &height);
755 float scale = float(size) / max_ii(width, height);
756
757 /* Get location in mask space. */
758 float frame_size[2];
759 frame_size[0] = width;
760 frame_size[1] = height;
761 float location[2];
762 RNA_float_get_array(op->ptr, "location", location);
763 location[0] /= width;
764 location[1] /= height;
765 BKE_mask_coord_from_frame(location, location, frame_size);
766
767 /* Make it so new primitive is centered to mouse location. */
768 location[0] -= 0.5f * scale;
769 location[1] -= 0.5f * scale;
770
771 bool added_mask = false;
772 MaskLayer *mask_layer = ED_mask_layer_ensure(C, &added_mask);
774
776
777 MaskSpline *new_spline = BKE_mask_spline_add(mask_layer);
778 new_spline->flag = MASK_SPLINE_CYCLIC | SELECT;
779 new_spline->points = static_cast<MaskSplinePoint *>(
780 MEM_recallocN(new_spline->points, sizeof(MaskSplinePoint) * num_points));
781
782 mask_layer->act_spline = new_spline;
783 mask_layer->act_point = nullptr;
784
785 const int spline_index = BKE_mask_layer_shape_spline_to_index(mask_layer, new_spline);
786
787 BezTriple *bezier_points = points_to_bezier(points, num_points, handle_type, scale, location);
788
789 for (int i = 0; i < num_points; i++) {
790 new_spline->tot_point = i + 1;
791
792 MaskSplinePoint *new_point = &new_spline->points[i];
793 BKE_mask_parent_init(&new_point->parent);
794
795 new_point->bezt = bezier_points[i];
796
797 BKE_mask_point_select_set(new_point, true);
798
799 if (mask_layer->splines_shapes.first) {
800 BKE_mask_layer_shape_changed_add(mask_layer, spline_index + i, true, false);
801 }
802 }
803
804 MEM_freeN(bezier_points);
805
806 if (added_mask) {
808 }
810
812
814
815 return OPERATOR_FINISHED;
816}
817
819 wmOperator *op,
820 const wmEvent * /*event*/)
821{
822 ScrArea *area = CTX_wm_area(C);
823 float cursor[2];
824 int width, height;
825
826 ED_mask_get_size(area, &width, &height);
827 ED_mask_cursor_location_get(area, cursor);
828
829 cursor[0] *= width;
830 cursor[1] *= height;
831
832 RNA_float_set_array(op->ptr, "location", cursor);
833
834 return op->type->exec(C, op);
835}
836
838{
840 ot->srna, "size", 100, -FLT_MAX, FLT_MAX, "Size", "Size of new circle", -FLT_MAX, FLT_MAX);
842 "location",
843 2,
844 nullptr,
845 -FLT_MAX,
846 FLT_MAX,
847 "Location",
848 "Location of new circle",
849 -FLT_MAX,
850 FLT_MAX);
851}
852
854
855/* -------------------------------------------------------------------- */
858
860{
861 const float points[4][2] = {{0.0f, 0.5f}, {0.5f, 1.0f}, {1.0f, 0.5f}, {0.5f, 0.0f}};
862 int num_points = ARRAY_SIZE(points);
863
864 create_primitive_from_points(C, op, points, num_points, HD_AUTO);
865
866 return OPERATOR_FINISHED;
867}
868
870{
871 /* identifiers */
872 ot->name = "Add Circle";
873 ot->description = "Add new circle-shaped spline";
874 ot->idname = "MASK_OT_primitive_circle_add";
875
876 /* API callbacks. */
878 ot->invoke = primitive_add_invoke;
880
881 /* flags */
883
884 /* properties */
886}
887
889
890/* -------------------------------------------------------------------- */
893
895{
896 const float points[4][2] = {{0.0f, 0.0f}, {0.0f, 1.0f}, {1.0f, 1.0f}, {1.0f, 0.0f}};
897 int num_points = ARRAY_SIZE(points);
898
899 create_primitive_from_points(C, op, points, num_points, HD_VECT);
900
901 return OPERATOR_FINISHED;
902}
903
905{
906 /* identifiers */
907 ot->name = "Add Square";
908 ot->description = "Add new square-shaped spline";
909 ot->idname = "MASK_OT_primitive_square_add";
910
911 /* API callbacks. */
913 ot->invoke = primitive_add_invoke;
915
916 /* flags */
918
919 /* properties */
921}
922
Mask * CTX_data_edit_mask(const bContext *C)
ScrArea * CTX_wm_area(const bContext *C)
Scene * CTX_data_scene(const bContext *C)
ARegion * CTX_wm_region(const bContext *C)
void BKE_nurb_handle_calc(BezTriple *bezt, BezTriple *prev, BezTriple *next, bool is_fcurve, char smoothing)
Definition curve.cc:3940
#define MASKPOINT_ISSEL_ANY(p)
Definition BKE_mask.h:292
void BKE_mask_layer_shape_changed_add(struct MaskLayer *masklay, int index, bool do_init, bool do_init_interpolate)
void BKE_mask_calc_tangent_polyline(struct MaskSpline *spline, struct MaskSplinePoint *point, float t[2])
void BKE_mask_point_select_set(struct MaskSplinePoint *point, bool do_select)
void BKE_mask_calc_handle_point_auto(struct MaskSpline *spline, struct MaskSplinePoint *point, bool do_recalc_length)
Resets auto handles even for non-auto bezier points.
struct MaskSpline * BKE_mask_spline_add(struct MaskLayer *masklay)
#define MASKPOINT_SEL_ALL(p)
Definition BKE_mask.h:301
float BKE_mask_point_weight(struct MaskSpline *spline, struct MaskSplinePoint *point, float u)
struct MaskLayer * BKE_mask_layer_new(struct Mask *mask, const char *name)
float BKE_mask_point_weight_scalar(struct MaskSpline *spline, struct MaskSplinePoint *point, float u)
void BKE_mask_calc_handle_adjacent_interp(struct MaskSpline *spline, struct MaskSplinePoint *point, float u)
void BKE_mask_point_parent_matrix_get(struct MaskSplinePoint *point, float ctime, float parent_matrix[3][3])
void BKE_mask_point_add_uw(struct MaskSplinePoint *point, float u, float w)
int BKE_mask_layer_shape_spline_to_index(struct MaskLayer *masklay, struct MaskSpline *spline)
void BKE_mask_parent_init(struct MaskParent *parent)
#define MASKPOINT_DESEL_ALL(p)
Definition BKE_mask.h:308
struct MaskLayer * BKE_mask_layer_active(struct Mask *mask)
void BKE_mask_coord_from_frame(float r_co[2], const float co[2], const float frame_size[2])
#define BLI_assert(a)
Definition BLI_assert.h:46
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])
bool invert_m3(float mat[3][3])
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])
void print_v2(const char *str, const float v[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 ARRAY_SIZE(arr)
#define ELEM(...)
void DEG_id_tag_update(ID *id, unsigned int flags)
@ ID_RECALC_GEOMETRY
Definition DNA_ID.h:1074
@ HD_VECT
@ HD_AUTO
@ HD_ALIGN
@ MASK_HIDE_SELECT
@ MASK_HIDE_VIEW
@ MASK_SPLINE_CYCLIC
@ OPERATOR_CANCELLED
@ OPERATOR_FINISHED
@ OPERATOR_PASS_THROUGH
void ED_mask_mouse_pos(ScrArea *area, ARegion *region, const int mval[2], float r_co[2])
void ED_mask_get_size(ScrArea *area, int *r_width, int *r_height)
void ED_mask_cursor_location_get(ScrArea *area, float cursor[2])
bool ED_maskedit_visible_splines_poll(bContext *C)
Definition mask_edit.cc:44
void ED_mask_pixelspace_factor(ScrArea *area, ARegion *region, float *r_scalex, float *r_scaley)
bool ED_maskedit_mask_poll(bContext *C)
Definition mask_edit.cc:60
@ SEL_DESELECT
Read Guarded memory(de)allocation.
#define MEM_recallocN(vmemh, len)
#define C
Definition RandGen.cpp:29
#define NA_ADDED
Definition WM_types.hh:586
@ OPTYPE_UNDO
Definition WM_types.hh:182
@ OPTYPE_REGISTER
Definition WM_types.hh:180
#define NA_EDITED
Definition WM_types.hh:584
#define NC_MASK
Definition WM_types.hh:398
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
nullptr float
#define SELECT
static wmOperatorStatus add_vertex_exec(bContext *C, wmOperator *op)
static wmOperatorStatus add_vertex_invoke(bContext *C, wmOperator *op, const wmEvent *event)
#define printf(...)
void * MEM_calloc_arrayN(size_t len, size_t size, const char *str)
Definition mallocn.cc:123
void MEM_freeN(void *vmemh)
Definition mallocn.cc:113
static wmOperatorStatus add_feather_vertex_exec(bContext *C, wmOperator *op)
Definition mask_add.cc:618
void MASK_OT_add_feather_vertex(wmOperatorType *ot)
Definition mask_add.cc:683
static int create_primitive_from_points(bContext *C, wmOperator *op, const float(*points)[2], int num_points, char handle_type)
Definition mask_add.cc:744
static wmOperatorStatus add_vertex_handle_cyclic(bContext *C, Mask *mask, MaskSpline *spline, MaskSplinePoint *active_point, float co[2])
Definition mask_add.cc:495
static wmOperatorStatus primitive_add_invoke(bContext *C, wmOperator *op, const wmEvent *)
Definition mask_add.cc:818
static wmOperatorStatus add_vertex_exec(bContext *C, wmOperator *op)
Definition mask_add.cc:517
static bool add_vertex_extrude(const bContext *C, Mask *mask, MaskLayer *mask_layer, const float co[2])
Definition mask_add.cc:297
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.cc:41
void MASK_OT_primitive_square_add(wmOperatorType *ot)
Definition mask_add.cc:904
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.cc:717
void MASK_OT_primitive_circle_add(wmOperatorType *ot)
Definition mask_add.cc:869
static void define_primitive_add_properties(wmOperatorType *ot)
Definition mask_add.cc:837
static wmOperatorStatus add_vertex_handle_cyclic_at_point(bContext *C, Mask *mask, MaskSpline *spline, MaskSplinePoint *active_point, MaskSplinePoint *other_point, float co[2])
Definition mask_add.cc:455
static wmOperatorStatus primitive_square_add_exec(bContext *C, wmOperator *op)
Definition mask_add.cc:894
static wmOperatorStatus add_vertex_invoke(bContext *C, wmOperator *op, const wmEvent *event)
Definition mask_add.cc:570
static wmOperatorStatus primitive_circle_add_exec(bContext *C, wmOperator *op)
Definition mask_add.cc:859
static void mask_point_make_pixel_space(bContext *C, const float point_normalized[2], float point_pixel[2])
Definition mask_add.cc:441
static bool add_vertex_new(const bContext *C, Mask *mask, MaskLayer *mask_layer, const float co[2])
Definition mask_add.cc:400
static wmOperatorStatus add_feather_vertex_invoke(bContext *C, wmOperator *op, const wmEvent *event)
Definition mask_add.cc:667
static bool add_vertex_subdivide(const bContext *C, Mask *mask, const float co[2])
Definition mask_add.cc:242
void MASK_OT_add_vertex(wmOperatorType *ot)
Definition mask_add.cc:584
static void finSelectedSplinePoint(MaskLayer *mask_layer, MaskSpline **spline, MaskSplinePoint **point, bool check_active)
Definition mask_add.cc:174
static void mask_spline_add_point_at_index(MaskSpline *spline, int point_index)
Definition mask_add.cc:225
void ED_mask_view_lock_state_restore_no_jump(const bContext *C, const MaskViewLockState *state)
Definition mask_edit.cc:215
void ED_mask_view_lock_state_store(const bContext *C, MaskViewLockState *state)
Definition mask_edit.cc:207
MaskSplinePoint * ED_mask_point_find_nearest(const bContext *C, Mask *mask_orig, const float normal_co[2], float threshold, MaskLayer **r_mask_layer, MaskSpline **r_spline, eMaskWhichHandle *r_which_handle, float *r_score)
MaskLayer * ED_mask_layer_ensure(bContext *C, bool *r_added_mask)
Definition mask_ops.cc:78
Mask * ED_mask_new(bContext *C, const char *name)
Definition mask_ops.cc:48
void ED_mask_select_flush_all(Mask *mask)
void ED_mask_select_toggle_all(Mask *mask, int action)
bool ED_mask_find_nearest_diff_point(const bContext *C, Mask *mask_orig, const float normal_co[2], int threshold, bool feather, float tangent[2], bool use_deform, bool use_project, MaskLayer **r_mask_layer, MaskSpline **r_spline, MaskSplinePoint **r_point, float *r_u, float *r_score)
Definition mask_query.cc:36
ccl_device_inline float2 mask(const MaskType mask, const float2 a)
void RNA_float_get_array(PointerRNA *ptr, const char *name, float *values)
float RNA_float_get(PointerRNA *ptr, const char *name)
void RNA_float_set_array(PointerRNA *ptr, const char *name, const float *values)
PropertyRNA * RNA_def_float(StructOrFunctionRNA *cont_, const char *identifier, const float default_value, const float hardmin, const float hardmax, const char *ui_name, const char *ui_description, const float softmin, const float softmax)
PropertyRNA * RNA_def_float_vector(StructOrFunctionRNA *cont_, const char *identifier, const int len, const float *default_value, const float hardmin, const float hardmax, const char *ui_name, const char *ui_description, const float softmin, const float softmax)
#define FLT_MAX
Definition stdcycles.h:14
float vec[3][3]
void * first
ListBase splines_shapes
char visibility_flag
ListBase splines
struct MaskSplinePoint * act_point
struct MaskSpline * act_spline
MaskParent parent
struct MaskSpline * next
MaskSplinePoint * points
struct RenderData r
int mval[2]
Definition WM_types.hh:763
wmOperatorStatus(* exec)(bContext *C, wmOperator *op) ATTR_WARN_UNUSED_RESULT
Definition WM_types.hh:1049
struct wmOperatorType * type
struct PointerRNA * ptr
i
Definition text_draw.cc:230
void WM_event_add_notifier(const bContext *C, uint type, void *reference)
wmOperatorType * ot
Definition wm_files.cc:4237