void ED_mask_draw_frames(Mask *mask, ARegion *ar, const int cfra, const int sfra, const int efra) { const float framelen = ar->winx / (float)(efra - sfra + 1); MaskLayer *masklay = BKE_mask_layer_active(mask); glBegin(GL_LINES); glColor4ub(255, 175, 0, 255); if (masklay) { MaskLayerShape *masklay_shape; for (masklay_shape = masklay->splines_shapes.first; masklay_shape; masklay_shape = masklay_shape->next) { int frame = masklay_shape->frame; /* draw_keyframe(i, CFRA, sfra, framelen, 1); */ int height = (frame == cfra) ? 22 : 10; int x = (frame - sfra) * framelen; glVertex2i(x, 0); glVertex2i(x, height); } } glEnd(); }
static PointerRNA rna_Mask_layer_active_get(PointerRNA *ptr) { Mask *mask = (Mask *)ptr->id.data; MaskLayer *masklay = BKE_mask_layer_active(mask); return rna_pointer_inherit_refine(ptr, &RNA_MaskLayer, masklay); }
static int mask_hide_view_set_exec(bContext *C, wmOperator *op) { Mask *mask = CTX_data_edit_mask(C); MaskLayer *masklay; const int unselected = RNA_boolean_get(op->ptr, "unselected"); bool changed = false; for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) { if (masklay->restrictflag & MASK_RESTRICT_SELECT) { continue; } if (!unselected) { if (ED_mask_layer_select_check(masklay)) { ED_mask_layer_select_set(masklay, FALSE); masklay->restrictflag |= OB_RESTRICT_VIEW; changed = true; if (masklay == BKE_mask_layer_active(mask)) { BKE_mask_layer_active_set(mask, NULL); } } } else { if (!ED_mask_layer_select_check(masklay)) { masklay->restrictflag |= OB_RESTRICT_VIEW; changed = true; if (masklay == BKE_mask_layer_active(mask)) { BKE_mask_layer_active_set(mask, NULL); } } } } if (changed) { WM_event_add_notifier(C, NC_MASK | ND_DRAW, mask); DAG_id_tag_update(&mask->id, 0); return OPERATOR_FINISHED; } else { return OPERATOR_CANCELLED; } }
static int copy_splines_exec(bContext *C, wmOperator *UNUSED(op)) { Mask *mask = CTX_data_edit_mask(C); MaskLayer *mask_layer = BKE_mask_layer_active(mask); BKE_mask_clipboard_copy_from_layer(mask_layer); return OPERATOR_FINISHED; }
static int masklay_remove_exec(bContext *C, wmOperator *UNUSED(op)) { Mask *mask = CTX_data_edit_mask(C); MaskLayer *masklay = BKE_mask_layer_active(mask); if (masklay) { BKE_mask_layer_remove(mask, masklay); WM_event_add_notifier(C, NC_MASK | NA_EDITED, mask); } return OPERATOR_FINISHED; }
static int paste_splines_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); BKE_mask_clipboard_paste_to_layer(CTX_data_main(C), mask_layer); /* TODO: only update edited splines */ BKE_mask_update_display(mask, CFRA); WM_event_add_notifier(C, NC_MASK | NA_EDITED, mask); return OPERATOR_FINISHED; }
/* Get ative layer. Will create mask/layer to be sure there's an active layer. */ MaskLayer *ED_mask_layer_ensure(bContext *C) { Mask *mask = CTX_data_edit_mask(C); MaskLayer *mask_layer; if (mask == NULL) { /* If there's no active mask, create one. */ mask = ED_mask_new(C, NULL); } mask_layer = BKE_mask_layer_active(mask); if (mask_layer == NULL) { /* If there's no active mask layer, create one. */ mask_layer = BKE_mask_layer_new(mask, ""); } return mask_layer; }
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; }
static int add_vertex_exec(bContext *C, wmOperator *op) { Scene *scene = CTX_data_scene(C); Mask *mask = CTX_data_edit_mask(C); MaskLayer *masklay; float co[2]; if (mask == NULL) { /* if there's no active mask, create one */ mask = ED_mask_new(C, NULL); } masklay = BKE_mask_layer_active(mask); if (masklay && masklay->restrictflag & (MASK_RESTRICT_VIEW | MASK_RESTRICT_SELECT)) { masklay = NULL; } RNA_float_get_array(op->ptr, "location", co); /* TODO, having an active point but no active spline is possible, why? */ if (masklay && masklay->act_spline && masklay->act_point && MASKPOINT_ISSEL_ANY(masklay->act_point)) { /* cheap trick - double click for cyclic */ MaskSpline *spline = masklay->act_spline; MaskSplinePoint *point = masklay->act_point; const bool is_sta = (point == spline->points); const bool is_end = (point == &spline->points[spline->tot_point - 1]); /* then check are we overlapping the mouse */ if ((is_sta || is_end) && equals_v2v2(co, point->bezt.vec[1])) { if (spline->flag & MASK_SPLINE_CYCLIC) { /* nothing to do */ return OPERATOR_CANCELLED; } else { /* recalc the connecting point as well to make a nice even curve */ MaskSplinePoint *point_other = is_end ? spline->points : &spline->points[spline->tot_point - 1]; spline->flag |= MASK_SPLINE_CYCLIC; /* TODO, update keyframes in time */ BKE_mask_calc_handle_point_auto(spline, point, false); BKE_mask_calc_handle_point_auto(spline, point_other, false); /* TODO: only update this spline */ BKE_mask_update_display(mask, CFRA); WM_event_add_notifier(C, NC_MASK | NA_EDITED, mask); return OPERATOR_FINISHED; } } if (!add_vertex_subdivide(C, mask, co)) { if (!add_vertex_extrude(C, mask, masklay, co)) { return OPERATOR_CANCELLED; } } } else { if (!add_vertex_subdivide(C, mask, co)) { if (!add_vertex_new(C, mask, masklay, co)) { return OPERATOR_CANCELLED; } } } /* TODO: only update this spline */ BKE_mask_update_display(mask, CFRA); return OPERATOR_FINISHED; }
static void draw_movieclip_cache(SpaceClip *sc, ARegion *ar, MovieClip *clip, Scene *scene) { float x; int *points, totseg, i, a; float sfra = SFRA, efra = EFRA, framelen = ar->winx / (efra - sfra + 1); MovieTrackingTrack *act_track = BKE_tracking_track_get_active(&clip->tracking); MovieTrackingReconstruction *reconstruction = BKE_tracking_get_active_reconstruction(&clip->tracking); glEnable(GL_BLEND); /* cache background */ glColor4ub(128, 128, 255, 64); glRecti(0, 0, ar->winx, 8); /* cached segments -- could be usefu lto debug caching strategies */ BKE_movieclip_get_cache_segments(clip, &sc->user, &totseg, &points); if (totseg) { glColor4ub(128, 128, 255, 128); for (a = 0; a < totseg; a++) { float x1, x2; x1 = (points[a * 2] - sfra) / (efra - sfra + 1) * ar->winx; x2 = (points[a * 2 + 1] - sfra + 1) / (efra - sfra + 1) * ar->winx; glRecti(x1, 0, x2, 8); } } /* track */ if (act_track) { MovieTrackingTrack *track = act_track; for (i = sfra - clip->start_frame + 1, a = 0; i <= efra - clip->start_frame + 1; i++) { int framenr; MovieTrackingMarker *marker; while (a < track->markersnr) { if (track->markers[a].framenr >= i) break; if (a < track->markersnr - 1 && track->markers[a + 1].framenr > i) break; a++; } if (a < track->markersnr) marker = &track->markers[a]; else marker = &track->markers[track->markersnr - 1]; if ((marker->flag & MARKER_DISABLED) == 0) { framenr = marker->framenr; if (framenr != i) glColor4ub(128, 128, 0, 96); else if ((marker->flag & MARKER_TRACKED) == 0) glColor4ub(255, 255, 0, 196); else glColor4ub(255, 255, 0, 96); glRecti((i - sfra + clip->start_frame - 1) * framelen, 0, (i - sfra + clip->start_frame) * framelen, 4); } } } /* failed frames */ if (reconstruction->flag & TRACKING_RECONSTRUCTED) { int n = reconstruction->camnr; MovieReconstructedCamera *cameras = reconstruction->cameras; glColor4ub(255, 0, 0, 96); for (i = sfra, a = 0; i <= efra; i++) { int ok = FALSE; while (a < n) { if (cameras[a].framenr == i) { ok = TRUE; break; } else if (cameras[a].framenr > i) { break; } a++; } if (!ok) glRecti((i - sfra + clip->start_frame - 1) * framelen, 0, (i - sfra + clip->start_frame) * framelen, 8); } } glDisable(GL_BLEND); /* current frame */ x = (sc->user.framenr - sfra) / (efra - sfra + 1) * ar->winx; UI_ThemeColor(TH_CFRAME); glRecti(x, 0, x + framelen, 8); clip_draw_curfra_label(sc, x, 8.0f); /* movie clip animation */ if ((sc->mode == SC_MODE_MASKEDIT) && sc->mask_info.mask) { MaskLayer *masklay = BKE_mask_layer_active(sc->mask_info.mask); if (masklay) { MaskLayerShape *masklay_shape; glColor4ub(255, 175, 0, 255); glBegin(GL_LINES); for (masklay_shape = masklay->splines_shapes.first; masklay_shape; masklay_shape = masklay_shape->next) { i = masklay_shape->frame; /* glRecti((i - sfra) * framelen, 0, (i - sfra + 1) * framelen, 4); */ /* use a line so we always see the keyframes */ glVertex2i((i - sfra) * framelen, 0); glVertex2i((i - sfra) * framelen, (i == CFRA) ? 22 : 10); } glEnd(); } } }
static bool find_prev_next_keyframes(struct bContext *C, int *nextfra, int *prevfra) { Scene *scene = CTX_data_scene(C); Object *ob = CTX_data_active_object(C); bGPdata *gpd = CTX_data_gpencil_data(C); Mask *mask = CTX_data_edit_mask(C); bDopeSheet ads = {NULL}; DLRBT_Tree keys; ActKeyColumn *aknext, *akprev; float cfranext, cfraprev; bool donenext = false, doneprev = false; int nextcount = 0, prevcount = 0; cfranext = cfraprev = (float)(CFRA); /* init binarytree-list for getting keyframes */ BLI_dlrbTree_init(&keys); /* seed up dummy dopesheet context with flags to perform necessary filtering */ if ((scene->flag & SCE_KEYS_NO_SELONLY) == 0) { /* only selected channels are included */ ads.filterflag |= ADS_FILTER_ONLYSEL; } /* populate tree with keyframe nodes */ scene_to_keylist(&ads, scene, &keys, NULL); if (ob) ob_to_keylist(&ads, ob, &keys, NULL); gpencil_to_keylist(&ads, gpd, &keys); if (mask) { MaskLayer *masklay = BKE_mask_layer_active(mask); mask_to_keylist(&ads, masklay, &keys); } /* build linked-list for searching */ BLI_dlrbTree_linkedlist_sync(&keys); /* find matching keyframe in the right direction */ do { aknext = (ActKeyColumn *)BLI_dlrbTree_search_next(&keys, compare_ak_cfraPtr, &cfranext); if (aknext) { if (CFRA == (int)aknext->cfra) { /* make this the new starting point for the search and ignore */ cfranext = aknext->cfra; } else { /* this changes the frame, so set the frame and we're done */ if (++nextcount == U.view_frame_keyframes) donenext = true; } cfranext = aknext->cfra; } } while ((aknext != NULL) && (donenext == false)); do { akprev = (ActKeyColumn *)BLI_dlrbTree_search_prev(&keys, compare_ak_cfraPtr, &cfraprev); if (akprev) { if (CFRA == (int)akprev->cfra) { /* make this the new starting point for the search */ } else { /* this changes the frame, so set the frame and we're done */ if (++prevcount == U.view_frame_keyframes) doneprev = true; } cfraprev = akprev->cfra; } } while ((akprev != NULL) && (doneprev == false)); /* free temp stuff */ BLI_dlrbTree_free(&keys); /* any success? */ if (doneprev || donenext) { if (doneprev) *prevfra = cfraprev; else *prevfra = CFRA - (cfranext - CFRA); if (donenext) *nextfra = cfranext; else *nextfra = CFRA + (CFRA - cfraprev); return true; } return false; }