static int create_primitive_from_points(bContext *C, wmOperator *op, const float (*points)[2], int num_points, char handle_type) { ScrArea *sa = CTX_wm_area(C); Scene *scene = CTX_data_scene(C); Mask *mask; MaskLayer *mask_layer; MaskSpline *new_spline; float scale, location[2], frame_size[2]; int i, width, height; int size = RNA_float_get(op->ptr, "size"); ED_mask_get_size(sa, &width, &height); scale = (float)size / max_ii(width, height); /* Get location in mask space. */ frame_size[0] = width; frame_size[1] = height; RNA_float_get_array(op->ptr, "location", location); location[0] /= width; location[1] /= height; BKE_mask_coord_from_frame(location, location, frame_size); /* Make it so new primitive is centered to mouse location. */ location[0] -= 0.5f * scale; location[1] -= 0.5f * scale; mask_layer = ED_mask_layer_ensure(C); mask = CTX_data_edit_mask(C); ED_mask_select_toggle_all(mask, SEL_DESELECT); new_spline = BKE_mask_spline_add(mask_layer); new_spline->flag = MASK_SPLINE_CYCLIC | SELECT; new_spline->tot_point = num_points; new_spline->points = MEM_recallocN(new_spline->points, sizeof(MaskSplinePoint) * new_spline->tot_point); mask_layer->act_spline = new_spline; mask_layer->act_point = NULL; for (i = 0; i < num_points; i++) { MaskSplinePoint *new_point = &new_spline->points[i]; copy_v2_v2(new_point->bezt.vec[1], points[i]); mul_v2_fl(new_point->bezt.vec[1], scale); add_v2_v2(new_point->bezt.vec[1], location); new_point->bezt.h1 = handle_type; new_point->bezt.h2 = handle_type; BKE_mask_point_select_set(new_point, true); } WM_event_add_notifier(C, NC_MASK | NA_EDITED, mask); /* TODO: only update this spline */ BKE_mask_update_display(mask, CFRA); return OPERATOR_FINISHED; }
static bool add_vertex_new(const bContext *C, Mask *mask, MaskLayer *masklay, const float co[2]) { Scene *scene = CTX_data_scene(C); const float ctime = CFRA; MaskSpline *spline; MaskSplinePoint *new_point = NULL, *ref_point = NULL; if (!masklay) { /* if there's no masklay currently operationg on, create new one */ masklay = BKE_mask_layer_new(mask, ""); mask->masklay_act = mask->masklay_tot - 1; } ED_mask_select_toggle_all(mask, SEL_DESELECT); spline = BKE_mask_spline_add(masklay); masklay->act_spline = spline; new_point = spline->points; masklay->act_point = new_point; setup_vertex_point(mask, spline, new_point, co, 0.5f, ctime, ref_point, false); { int point_index = (((int)(new_point - spline->points) + 0) % spline->tot_point); BKE_mask_layer_shape_changed_add(masklay, BKE_mask_layer_shape_spline_to_index(masklay, spline) + point_index, true, true); } WM_event_add_notifier(C, NC_MASK | NA_EDITED, mask); return true; }
static int add_vertex_new(const bContext *C, Mask *mask, MaskLayer *masklay, const float co[2]) { MaskSpline *spline; MaskSplinePoint *point; MaskSplinePoint *new_point = NULL, *ref_point = NULL; float view_zoom; if (!masklay) { /* if there's no masklay currently operationg on, create new one */ masklay = BKE_mask_layer_new(mask, ""); mask->masklay_act = mask->masklay_tot - 1; spline = NULL; point = NULL; } else { finSelectedSplinePoint(masklay, &spline, &point, TRUE); } ED_mask_select_toggle_all(mask, SEL_DESELECT); if (!spline) { /* no selected splines in active masklay, create new spline */ spline = BKE_mask_spline_add(masklay); } masklay->act_spline = spline; new_point = spline->points; masklay->act_point = new_point; { ScrArea *sa = CTX_wm_area(C); ARegion *ar = CTX_wm_region(C); float zoom_x, zoom_y; /* calc view zoom in a simplistic way */ ED_mask_zoom(sa, ar, &zoom_x, &zoom_y); view_zoom = zoom_x + zoom_y / 2.0f; view_zoom = 1.0f / view_zoom; /* arbitrary but gives good results */ view_zoom /= 500.0f; } setup_vertex_point(mask, spline, new_point, co, NULL, 0.5f, ref_point, FALSE, view_zoom); { int point_index = (((int)(new_point - spline->points) + 0) % spline->tot_point); BKE_mask_layer_shape_changed_add(masklay, BKE_mask_layer_shape_spline_to_index(masklay, spline) + point_index, TRUE, TRUE); } WM_event_add_notifier(C, NC_MASK | NA_EDITED, mask); return TRUE; }
static void rna_MaskLayer_spline_add(ID *id, MaskLayer *masklay, int number) { Mask *mask = (Mask *) id; int i; for (i = 0; i < number; i++) BKE_mask_spline_add(masklay); WM_main_add_notifier(NC_MASK | NA_EDITED, mask); }
static MaskSpline *rna_MaskLayer_spline_new(ID *id, MaskLayer *mask_layer) { Mask *mask = (Mask *) id; MaskSpline *new_spline; new_spline = BKE_mask_spline_add(mask_layer); WM_main_add_notifier(NC_MASK | NA_EDITED, mask); return new_spline; }
static int mask_duplicate_exec(bContext *C, wmOperator *UNUSED(op)) { Scene *scene = CTX_data_scene(C); Mask *mask = CTX_data_edit_mask(C); MaskLayer *mask_layer = BKE_mask_layer_active(mask); MaskSpline *spline; if (mask_layer == NULL) { return OPERATOR_CANCELLED; } for (spline = mask_layer->splines.last; spline; spline = spline->prev) { MaskSplinePoint *point = spline->points; int i = 0; while (i < spline->tot_point) { int start = i, end = -1; /* Find next selected segment. */ while (MASKPOINT_ISSEL_ANY(point)) { BKE_mask_point_select_set(point, false); end = i; if (i >= spline->tot_point - 1) { break; } i++; point++; } if (end >= start) { MaskSpline *new_spline = BKE_mask_spline_add(mask_layer); MaskSplinePoint *new_point; int b; /* BKE_mask_spline_add might allocate the points, need to free them in this case. */ if (new_spline->points) { MEM_freeN(new_spline->points); } /* Copy options from old spline. */ new_spline->flag = spline->flag; new_spline->offset_mode = spline->offset_mode; new_spline->weight_interp = spline->weight_interp; new_spline->parent = spline->parent; /* Allocate new points and copy them from old spline. */ new_spline->tot_point = end - start + 1; new_spline->points = MEM_mallocN(sizeof(MaskSplinePoint) * new_spline->tot_point, "duplicated mask points"); memcpy(new_spline->points, spline->points + start, new_spline->tot_point * sizeof(MaskSplinePoint)); /* Select points and duplicate their UWs (if needed). */ for (b = 0, new_point = new_spline->points; b < new_spline->tot_point; b++, new_point++) { if (new_point->uw) { new_point->uw = MEM_dupallocN(new_point->uw); } BKE_mask_point_select_set(new_point, true); } /* Clear cyclic flag if we didn't copy the whole spline. */ if (new_spline->flag & MASK_SPLINE_CYCLIC) { if (start != 0 || end != spline->tot_point - 1) { new_spline->flag &= ~MASK_SPLINE_CYCLIC; } } /* Flush selection to splines. */ new_spline->flag |= SELECT; spline->flag &= ~SELECT; mask_layer->act_spline = new_spline; } i++; point++; } } /* TODO: only update edited splines */ BKE_mask_update_display(mask, CFRA); WM_event_add_notifier(C, NC_MASK | NA_EDITED, mask); return OPERATOR_FINISHED; }