Blender V4.3
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
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/* -------------------------------------------------------------------- */
41static void setup_vertex_point(Mask *mask,
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
170/* -------------------------------------------------------------------- */
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
221/* -------------------------------------------------------------------- */
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_cnew_array<MaskSplinePoint>(spline->tot_point + 1, "add mask vert points");
230
231 memcpy(new_point_array, spline->points, sizeof(MaskSplinePoint) * (point_index + 1));
232 memcpy(new_point_array + point_index + 2,
233 spline->points + point_index + 1,
234 sizeof(MaskSplinePoint) * (spline->tot_point - point_index - 1));
235
236 MEM_freeN(spline->points);
237 spline->points = new_point_array;
238 spline->tot_point++;
239}
240
241static bool add_vertex_subdivide(const bContext *C, Mask *mask, const float co[2])
242{
243 MaskLayer *mask_layer;
244 MaskSpline *spline;
245 MaskSplinePoint *point = nullptr;
246 const float threshold = 12;
247 float tangent[2];
248 float u;
249
251 mask,
252 co,
253 threshold,
254 false,
255 tangent,
256 true,
257 true,
258 &mask_layer,
259 &spline,
260 &point,
261 &u,
262 nullptr))
263 {
264 Scene *scene = CTX_data_scene(C);
265 const float ctime = scene->r.cfra;
266
267 MaskSplinePoint *new_point;
268 int point_index = point - spline->points;
269
271
272 mask_spline_add_point_at_index(spline, point_index);
273
274 new_point = &spline->points[point_index + 1];
275
276 setup_vertex_point(mask, spline, new_point, co, u, ctime, nullptr, true);
277
278 /* TODO: we could pass the spline! */
280 BKE_mask_layer_shape_spline_to_index(mask_layer, spline) +
281 point_index + 1,
282 true,
283 true);
284
285 mask_layer->act_spline = spline;
286 mask_layer->act_point = new_point;
287
289
290 return true;
291 }
292
293 return false;
294}
295
296static bool add_vertex_extrude(const bContext *C,
297 Mask *mask,
298 MaskLayer *mask_layer,
299 const float co[2])
300{
301 Scene *scene = CTX_data_scene(C);
302 const float ctime = scene->r.cfra;
303
304 MaskSpline *spline;
306 MaskSplinePoint *new_point = nullptr, *ref_point = nullptr;
307
308 /* check on which side we want to add the point */
309 int point_index;
310 float tangent_point[2];
311 float tangent_co[2];
312 bool do_cyclic_correct = false;
313 bool do_prev; /* use prev point rather than next?? */
314
315 if (!mask_layer) {
316 return false;
317 }
318 finSelectedSplinePoint(mask_layer, &spline, &point, true);
319
321
322 point_index = (point - spline->points);
323
324 MASKPOINT_DESEL_ALL(point);
325
326 if ((spline->flag & MASK_SPLINE_CYCLIC) ||
327 (point_index > 0 && point_index != spline->tot_point - 1))
328 {
329 BKE_mask_calc_tangent_polyline(spline, point, tangent_point);
330 sub_v2_v2v2(tangent_co, co, point->bezt.vec[1]);
331
332 if (dot_v2v2(tangent_point, tangent_co) < 0.0f) {
333 do_prev = true;
334 }
335 else {
336 do_prev = false;
337 }
338 }
339 else if (((spline->flag & MASK_SPLINE_CYCLIC) == 0) && (point_index == 0)) {
340 do_prev = true;
341 }
342 else if (((spline->flag & MASK_SPLINE_CYCLIC) == 0) && (point_index == spline->tot_point - 1)) {
343 do_prev = false;
344 }
345 else {
346 do_prev = false; /* quiet warning */
347 /* should never get here */
348 BLI_assert(0);
349 }
350
351 /* use the point before the active one */
352 if (do_prev) {
353 point_index--;
354 if (point_index < 0) {
355 point_index += spline->tot_point; /* wrap index */
356 if ((spline->flag & MASK_SPLINE_CYCLIC) == 0) {
357 do_cyclic_correct = true;
358 point_index = 0;
359 }
360 }
361 }
362
363#if 0
364 print_v2("", tangent_point);
365 printf("%d\n", point_index);
366#endif
367
368 mask_spline_add_point_at_index(spline, point_index);
369
370 if (do_cyclic_correct) {
371 ref_point = &spline->points[point_index + 1];
372 new_point = &spline->points[point_index];
373 *ref_point = *new_point;
374 memset(new_point, 0, sizeof(*new_point));
375 }
376 else {
377 ref_point = &spline->points[point_index];
378 new_point = &spline->points[point_index + 1];
379 }
380
381 mask_layer->act_point = new_point;
382
383 setup_vertex_point(mask, spline, new_point, co, 0.5f, ctime, ref_point, false);
384
385 if (mask_layer->splines_shapes.first) {
386 point_index = ((int(new_point - spline->points) + 0) % spline->tot_point);
388 BKE_mask_layer_shape_spline_to_index(mask_layer, spline) +
389 point_index,
390 true,
391 true);
392 }
393
395
396 return true;
397}
398
399static bool add_vertex_new(const bContext *C, Mask *mask, MaskLayer *mask_layer, const float co[2])
400{
401 Scene *scene = CTX_data_scene(C);
402 const float ctime = scene->r.cfra;
403
404 MaskSpline *spline;
405 MaskSplinePoint *new_point = nullptr, *ref_point = nullptr;
406
407 if (!mask_layer) {
408 /* If there's no mask layer currently operating on, create new one. */
409 mask_layer = BKE_mask_layer_new(mask, "");
410 mask->masklay_act = mask->masklay_tot - 1;
411 }
412
414
415 spline = BKE_mask_spline_add(mask_layer);
416
417 mask_layer->act_spline = spline;
418 new_point = spline->points;
419
420 mask_layer->act_point = new_point;
421
422 setup_vertex_point(mask, spline, new_point, co, 0.5f, ctime, ref_point, false);
423
424 {
425 int point_index = ((int(new_point - spline->points) + 0) % spline->tot_point);
427 BKE_mask_layer_shape_spline_to_index(mask_layer, spline) +
428 point_index,
429 true,
430 true);
431 }
432
434
435 return true;
436}
437
438/* Convert coordinate from normalized space to pixel one.
439 * TODO(sergey): Make the function more generally available. */
441 const float point_normalized[2],
442 float point_pixel[2])
443{
444 ScrArea *area = CTX_wm_area(C);
445 ARegion *region = CTX_wm_region(C);
446
447 float scalex, scaley;
448 ED_mask_pixelspace_factor(area, region, &scalex, &scaley);
449
450 point_pixel[0] = point_normalized[0] * scalex;
451 point_pixel[1] = point_normalized[1] * scaley;
452}
453
455 Mask *mask,
456 MaskSpline *spline,
457 MaskSplinePoint *active_point,
458 MaskSplinePoint *other_point,
459 float co[2])
460{
461 const float tolerance_in_pixels_squared = 4 * 4;
462
463 if (spline->flag & MASK_SPLINE_CYCLIC) {
464 /* The spline is already cyclic, so there is no need to handle anything here.
465 * Return PASS_THROUGH so that it's possible to add vertices close to the endpoints of the
466 * cyclic spline. */
468 }
469
470 float co_pixel[2];
471 mask_point_make_pixel_space(C, co, co_pixel);
472
473 float point_pixel[2];
474 mask_point_make_pixel_space(C, other_point->bezt.vec[1], point_pixel);
475
476 const float dist_squared = len_squared_v2v2(co_pixel, point_pixel);
477 if (dist_squared > tolerance_in_pixels_squared) {
479 }
480
481 spline->flag |= MASK_SPLINE_CYCLIC;
482
483 /* TODO: update keyframes in time. */
484 BKE_mask_calc_handle_point_auto(spline, active_point, false);
485 BKE_mask_calc_handle_point_auto(spline, other_point, false);
486
488
490
491 return OPERATOR_FINISHED;
492}
493
495 bContext *C, Mask *mask, MaskSpline *spline, MaskSplinePoint *active_point, float co[2])
496{
497 MaskSplinePoint *first_point = &spline->points[0];
498 MaskSplinePoint *last_point = &spline->points[spline->tot_point - 1];
499 const bool is_first_point_active = (active_point == first_point);
500 const bool is_last_point_active = (active_point == last_point);
501 if (is_last_point_active) {
502 return add_vertex_handle_cyclic_at_point(C, mask, spline, active_point, first_point, co);
503 }
504 if (is_first_point_active) {
505 return add_vertex_handle_cyclic_at_point(C, mask, spline, active_point, last_point, co);
506 }
508}
509
512/* -------------------------------------------------------------------- */
517{
518 MaskViewLockState lock_state;
519 ED_mask_view_lock_state_store(C, &lock_state);
520
521 Mask *mask = CTX_data_edit_mask(C);
522 if (mask == nullptr) {
523 /* if there's no active mask, create one */
524 mask = ED_mask_new(C, nullptr);
525 }
526
527 MaskLayer *mask_layer = BKE_mask_layer_active(mask);
528
529 if (mask_layer && mask_layer->visibility_flag & (MASK_HIDE_VIEW | MASK_HIDE_SELECT)) {
530 mask_layer = nullptr;
531 }
532
533 float co[2];
534 RNA_float_get_array(op->ptr, "location", co);
535
536 /* TODO: having an active point but no active spline is possible, why? */
537 if (mask_layer && mask_layer->act_spline && mask_layer->act_point &&
538 MASKPOINT_ISSEL_ANY(mask_layer->act_point))
539 {
540 MaskSpline *spline = mask_layer->act_spline;
541 MaskSplinePoint *active_point = mask_layer->act_point;
542 const int cyclic_result = add_vertex_handle_cyclic(C, mask, spline, active_point, co);
543 if (cyclic_result != OPERATOR_PASS_THROUGH) {
544 return cyclic_result;
545 }
546
547 if (!add_vertex_subdivide(C, mask, co)) {
548 if (!add_vertex_extrude(C, mask, mask_layer, co)) {
549 return OPERATOR_CANCELLED;
550 }
551 }
552 }
553 else {
554 if (!add_vertex_subdivide(C, mask, co)) {
555 if (!add_vertex_new(C, mask, mask_layer, co)) {
556 return OPERATOR_CANCELLED;
557 }
558 }
559 }
560
562
564
565 return OPERATOR_FINISHED;
566}
567
568static int add_vertex_invoke(bContext *C, wmOperator *op, const wmEvent *event)
569{
570 ScrArea *area = CTX_wm_area(C);
571 ARegion *region = CTX_wm_region(C);
572
573 float co[2];
574
575 ED_mask_mouse_pos(area, region, event->mval, co);
576
577 RNA_float_set_array(op->ptr, "location", co);
578
579 return add_vertex_exec(C, op);
580}
581
583{
584 /* identifiers */
585 ot->name = "Add Vertex";
586 ot->description = "Add vertex to active spline";
587 ot->idname = "MASK_OT_add_vertex";
588
589 /* api callbacks */
593
594 /* flags */
596
597 /* properties */
599 "location",
600 2,
601 nullptr,
602 -FLT_MAX,
603 FLT_MAX,
604 "Location",
605 "Location of vertex in normalized space",
606 -1.0f,
607 1.0f);
608}
609
612/* -------------------------------------------------------------------- */
617{
618 Mask *mask = CTX_data_edit_mask(C);
619 MaskLayer *mask_layer;
620 MaskSpline *spline;
621 MaskSplinePoint *point = nullptr;
622 const float threshold = 12;
623 float co[2], u;
624
625 RNA_float_get_array(op->ptr, "location", co);
626
627 point = ED_mask_point_find_nearest(C, mask, co, threshold, nullptr, nullptr, nullptr, nullptr);
628 if (point) {
629 return OPERATOR_FINISHED;
630 }
631
633 mask,
634 co,
635 threshold,
636 true,
637 nullptr,
638 true,
639 true,
640 &mask_layer,
641 &spline,
642 &point,
643 &u,
644 nullptr))
645 {
646 float w = BKE_mask_point_weight(spline, point, u);
647 float weight_scalar = BKE_mask_point_weight_scalar(spline, point, u);
648
649 if (weight_scalar != 0.0f) {
650 w = w / weight_scalar;
651 }
652
653 BKE_mask_point_add_uw(point, u, w);
654
656
658
659 return OPERATOR_FINISHED;
660 }
661
662 return OPERATOR_CANCELLED;
663}
664
665static int add_feather_vertex_invoke(bContext *C, wmOperator *op, const wmEvent *event)
666{
667 ScrArea *area = CTX_wm_area(C);
668 ARegion *region = CTX_wm_region(C);
669
670 float co[2];
671
672 ED_mask_mouse_pos(area, region, event->mval, co);
673
674 RNA_float_set_array(op->ptr, "location", co);
675
676 return add_feather_vertex_exec(C, op);
677}
678
680{
681 /* identifiers */
682 ot->name = "Add Feather Vertex";
683 ot->description = "Add vertex to feather";
684 ot->idname = "MASK_OT_add_feather_vertex";
685
686 /* api callbacks */
690
691 /* flags */
693
694 /* properties */
696 "location",
697 2,
698 nullptr,
699 -FLT_MAX,
700 FLT_MAX,
701 "Location",
702 "Location of vertex in normalized space",
703 -1.0f,
704 1.0f);
705}
706
709/* -------------------------------------------------------------------- */
713static BezTriple *points_to_bezier(const float (*points)[2],
714 const int num_points,
715 const char handle_type,
716 const float scale,
717 const float location[2])
718{
719 BezTriple *bezier_points = MEM_cnew_array<BezTriple>(num_points, __func__);
720 for (int i = 0; i < num_points; i++) {
721 copy_v2_v2(bezier_points[i].vec[1], points[i]);
722 mul_v2_fl(bezier_points[i].vec[1], scale);
723 add_v2_v2(bezier_points[i].vec[1], location);
724
725 bezier_points[i].h1 = handle_type;
726 bezier_points[i].h2 = handle_type;
727 }
728
729 for (int i = 0; i < num_points; i++) {
730 BKE_nurb_handle_calc(&bezier_points[i],
731 &bezier_points[(i - 1 + num_points) % num_points],
732 &bezier_points[(i + 1) % num_points],
733 false,
734 false);
735 }
736
737 return bezier_points;
738}
739
741 bContext *C, wmOperator *op, const float (*points)[2], int num_points, char handle_type)
742{
743 MaskViewLockState lock_state;
744 ED_mask_view_lock_state_store(C, &lock_state);
745
746 ScrArea *area = CTX_wm_area(C);
747 int size = RNA_float_get(op->ptr, "size");
748
749 int width, height;
750 ED_mask_get_size(area, &width, &height);
751 float scale = float(size) / max_ii(width, height);
752
753 /* Get location in mask space. */
754 float frame_size[2];
755 frame_size[0] = width;
756 frame_size[1] = height;
757 float location[2];
758 RNA_float_get_array(op->ptr, "location", location);
759 location[0] /= width;
760 location[1] /= height;
761 BKE_mask_coord_from_frame(location, location, frame_size);
762
763 /* Make it so new primitive is centered to mouse location. */
764 location[0] -= 0.5f * scale;
765 location[1] -= 0.5f * scale;
766
767 bool added_mask = false;
768 MaskLayer *mask_layer = ED_mask_layer_ensure(C, &added_mask);
769 Mask *mask = CTX_data_edit_mask(C);
770
772
773 MaskSpline *new_spline = BKE_mask_spline_add(mask_layer);
774 new_spline->flag = MASK_SPLINE_CYCLIC | SELECT;
775 new_spline->points = static_cast<MaskSplinePoint *>(
776 MEM_recallocN(new_spline->points, sizeof(MaskSplinePoint) * num_points));
777
778 mask_layer->act_spline = new_spline;
779 mask_layer->act_point = nullptr;
780
781 const int spline_index = BKE_mask_layer_shape_spline_to_index(mask_layer, new_spline);
782
783 BezTriple *bezier_points = points_to_bezier(points, num_points, handle_type, scale, location);
784
785 for (int i = 0; i < num_points; i++) {
786 new_spline->tot_point = i + 1;
787
788 MaskSplinePoint *new_point = &new_spline->points[i];
789 BKE_mask_parent_init(&new_point->parent);
790
791 new_point->bezt = bezier_points[i];
792
793 BKE_mask_point_select_set(new_point, true);
794
795 if (mask_layer->splines_shapes.first) {
796 BKE_mask_layer_shape_changed_add(mask_layer, spline_index + i, true, false);
797 }
798 }
799
800 MEM_freeN(bezier_points);
801
802 if (added_mask) {
804 }
806
808
810
811 return OPERATOR_FINISHED;
812}
813
814static int primitive_add_invoke(bContext *C, wmOperator *op, const wmEvent * /*event*/)
815{
816 ScrArea *area = CTX_wm_area(C);
817 float cursor[2];
818 int width, height;
819
820 ED_mask_get_size(area, &width, &height);
821 ED_mask_cursor_location_get(area, cursor);
822
823 cursor[0] *= width;
824 cursor[1] *= height;
825
826 RNA_float_set_array(op->ptr, "location", cursor);
827
828 return op->type->exec(C, op);
829}
830
832{
834 ot->srna, "size", 100, -FLT_MAX, FLT_MAX, "Size", "Size of new circle", -FLT_MAX, FLT_MAX);
836 "location",
837 2,
838 nullptr,
839 -FLT_MAX,
840 FLT_MAX,
841 "Location",
842 "Location of new circle",
843 -FLT_MAX,
844 FLT_MAX);
845}
846
849/* -------------------------------------------------------------------- */
854{
855 const float points[4][2] = {{0.0f, 0.5f}, {0.5f, 1.0f}, {1.0f, 0.5f}, {0.5f, 0.0f}};
856 int num_points = ARRAY_SIZE(points);
857
858 create_primitive_from_points(C, op, points, num_points, HD_AUTO);
859
860 return OPERATOR_FINISHED;
861}
862
864{
865 /* identifiers */
866 ot->name = "Add Circle";
867 ot->description = "Add new circle-shaped spline";
868 ot->idname = "MASK_OT_primitive_circle_add";
869
870 /* api callbacks */
874
875 /* flags */
877
878 /* properties */
880}
881
884/* -------------------------------------------------------------------- */
889{
890 const float points[4][2] = {{0.0f, 0.0f}, {0.0f, 1.0f}, {1.0f, 1.0f}, {1.0f, 0.0f}};
891 int num_points = ARRAY_SIZE(points);
892
893 create_primitive_from_points(C, op, points, num_points, HD_VECT);
894
895 return OPERATOR_FINISHED;
896}
897
899{
900 /* identifiers */
901 ot->name = "Add Square";
902 ot->description = "Add new square-shaped spline";
903 ot->idname = "MASK_OT_primitive_square_add";
904
905 /* api callbacks */
909
910 /* flags */
912
913 /* properties */
915}
916
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:3938
#define MASKPOINT_ISSEL_ANY(p)
Definition BKE_mask.h:297
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:306
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:313
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:50
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:1041
@ HD_VECT
@ HD_AUTO
@ HD_ALIGN
@ MASK_SPLINE_CYCLIC
@ MASK_HIDE_SELECT
@ MASK_HIDE_VIEW
@ 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:46
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:62
@ SEL_DESELECT
Read Guarded memory(de)allocation.
#define MEM_recallocN(vmemh, len)
in reality light always falls off quadratically Particle Retrieve the data of the particle that spawned the object for example to give variation to multiple instances of an object Point Retrieve information about points in a point cloud Retrieve the edges of an object as it appears to Cycles topology will always appear triangulated Convert a blackbody temperature to an RGB value Normal Generate a perturbed normal from an RGB normal map image Typically used for faking highly detailed surfaces Generate an OSL shader from a file or text data block Image Sample an image file as a texture Gabor Generate Gabor noise Gradient Generate interpolated color and intensity values based on the input vector Magic Generate a psychedelic color texture Voronoi Generate Worley noise based on the distance to random points Typically used to generate textures such as or biological cells Brick Generate a procedural texture producing bricks Texture Retrieve multiple types of texture coordinates nTypically used as inputs for texture nodes Vector Convert a point
@ OPTYPE_UNDO
Definition WM_types.hh:162
@ OPTYPE_REGISTER
Definition WM_types.hh:160
#define NA_ADDED
Definition WM_types.hh:552
#define NA_EDITED
Definition WM_types.hh:550
#define NC_MASK
Definition WM_types.hh:365
SIMD_FORCE_INLINE const btScalar & w() const
Return the w value.
Definition btQuadWord.h:119
#define printf
#define SELECT
draw_view in_light_buf[] float
draw_view push_constant(Type::INT, "radiance_src") .push_constant(Type capture_info_buf storage_buf(1, Qualifier::READ, "ObjectBounds", "bounds_buf[]") .push_constant(Type draw_view int
void MEM_freeN(void *vmemh)
Definition mallocn.cc:105
void MASK_OT_add_feather_vertex(wmOperatorType *ot)
Definition mask_add.cc:679
static int create_primitive_from_points(bContext *C, wmOperator *op, const float(*points)[2], int num_points, char handle_type)
Definition mask_add.cc:740
static int add_vertex_exec(bContext *C, wmOperator *op)
Definition mask_add.cc:516
static int primitive_circle_add_exec(bContext *C, wmOperator *op)
Definition mask_add.cc:853
static int primitive_square_add_exec(bContext *C, wmOperator *op)
Definition mask_add.cc:888
static bool add_vertex_extrude(const bContext *C, Mask *mask, MaskLayer *mask_layer, const float co[2])
Definition mask_add.cc:296
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:898
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:713
static int add_feather_vertex_invoke(bContext *C, wmOperator *op, const wmEvent *event)
Definition mask_add.cc:665
static int add_feather_vertex_exec(bContext *C, wmOperator *op)
Definition mask_add.cc:616
void MASK_OT_primitive_circle_add(wmOperatorType *ot)
Definition mask_add.cc:863
static void define_primitive_add_properties(wmOperatorType *ot)
Definition mask_add.cc:831
static int add_vertex_handle_cyclic(bContext *C, Mask *mask, MaskSpline *spline, MaskSplinePoint *active_point, float co[2])
Definition mask_add.cc:494
static void mask_point_make_pixel_space(bContext *C, const float point_normalized[2], float point_pixel[2])
Definition mask_add.cc:440
static bool add_vertex_new(const bContext *C, Mask *mask, MaskLayer *mask_layer, const float co[2])
Definition mask_add.cc:399
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.cc:454
static bool add_vertex_subdivide(const bContext *C, Mask *mask, const float co[2])
Definition mask_add.cc:241
void MASK_OT_add_vertex(wmOperatorType *ot)
Definition mask_add.cc:582
static int primitive_add_invoke(bContext *C, wmOperator *op, const wmEvent *)
Definition mask_add.cc:814
static int add_vertex_invoke(bContext *C, wmOperator *op, const wmEvent *event)
Definition mask_add.cc:568
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:217
void ED_mask_view_lock_state_store(const bContext *C, MaskViewLockState *state)
Definition mask_edit.cc:209
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:76
Mask * ED_mask_new(bContext *C, const char *name)
Definition mask_ops.cc:46
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
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
unsigned char uint8_t
Definition stdint.h:78
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
int mval[2]
Definition WM_types.hh:728
const char * name
Definition WM_types.hh:990
bool(* poll)(bContext *C) ATTR_WARN_UNUSED_RESULT
Definition WM_types.hh:1042
const char * idname
Definition WM_types.hh:992
int(* invoke)(bContext *C, wmOperator *op, const wmEvent *event) ATTR_WARN_UNUSED_RESULT
Definition WM_types.hh:1022
int(* exec)(bContext *C, wmOperator *op) ATTR_WARN_UNUSED_RESULT
Definition WM_types.hh:1006
const char * description
Definition WM_types.hh:996
StructRNA * srna
Definition WM_types.hh:1080
struct wmOperatorType * type
struct PointerRNA * ptr
void WM_event_add_notifier(const bContext *C, uint type, void *reference)
wmOperatorType * ot
Definition wm_files.cc:4125