From 4a328a76895c4f03b528b3c7e251475e76c68351 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 8 Jul 2015 23:24:16 +1000 Subject: EditCurve: move selection into own file --- source/blender/editors/curve/CMakeLists.txt | 1 + source/blender/editors/curve/curve_intern.h | 50 +- source/blender/editors/curve/editcurve.c | 1133 +--------------------- source/blender/editors/curve/editcurve_select.c | 1156 +++++++++++++++++++++++ source/blender/editors/include/ED_curve.h | 13 +- 5 files changed, 1214 insertions(+), 1139 deletions(-) create mode 100644 source/blender/editors/curve/editcurve_select.c diff --git a/source/blender/editors/curve/CMakeLists.txt b/source/blender/editors/curve/CMakeLists.txt index 1b877c0fba9..66c281df5fa 100644 --- a/source/blender/editors/curve/CMakeLists.txt +++ b/source/blender/editors/curve/CMakeLists.txt @@ -37,6 +37,7 @@ set(SRC curve_ops.c editcurve.c editcurve_add.c + editcurve_select.c editfont.c curve_intern.h diff --git a/source/blender/editors/curve/curve_intern.h b/source/blender/editors/curve/curve_intern.h index 579f149ea8b..bb0abf44744 100644 --- a/source/blender/editors/curve/curve_intern.h +++ b/source/blender/editors/curve/curve_intern.h @@ -37,6 +37,7 @@ struct ListBase; struct EditNurb; struct Object; struct wmOperatorType; +struct ViewContext; /* editfont.c */ enum { DEL_ALL, DEL_NEXT_CHAR, DEL_PREV_CHAR, DEL_SELECTION, DEL_NEXT_SEL, DEL_PREV_SEL }; @@ -44,6 +45,25 @@ enum { CASE_LOWER, CASE_UPPER }; enum { LINE_BEGIN, LINE_END, PREV_CHAR, NEXT_CHAR, PREV_WORD, NEXT_WORD, PREV_LINE, NEXT_LINE, PREV_PAGE, NEXT_PAGE }; +typedef enum eVisible_Types { + HIDDEN = true, + VISIBLE = false, +} eVisible_Types; + +typedef enum eEndPoint_Types { + FIRST = true, + LAST = false, +} eEndPoint_Types; + +typedef enum eCurveElem_Types { + CURVE_VERTEX = 0, + CURVE_SEGMENT, +} eCurveElem_Types; + +/* internal select utils */ +bool select_beztriple(BezTriple *bezt, bool selstatus, short flag, eVisible_Types hidden); +bool select_bpoint(BPoint *bp, bool selstatus, short flag, bool hidden); + void FONT_OT_text_insert(struct wmOperatorType *ot); void FONT_OT_line_break(struct wmOperatorType *ot); void FONT_OT_insert_lorem(struct wmOperatorType *ot); @@ -98,19 +118,6 @@ void CURVE_OT_smooth_weight(struct wmOperatorType *ot); void CURVE_OT_smooth_radius(struct wmOperatorType *ot); void CURVE_OT_smooth_tilt(struct wmOperatorType *ot); -void CURVE_OT_de_select_first(struct wmOperatorType *ot); -void CURVE_OT_de_select_last(struct wmOperatorType *ot); -void CURVE_OT_select_all(struct wmOperatorType *ot); -void CURVE_OT_select_linked(struct wmOperatorType *ot); -void CURVE_OT_select_linked_pick(struct wmOperatorType *ot); -void CURVE_OT_select_row(struct wmOperatorType *ot); -void CURVE_OT_select_next(struct wmOperatorType *ot); -void CURVE_OT_select_previous(struct wmOperatorType *ot); -void CURVE_OT_select_more(struct wmOperatorType *ot); -void CURVE_OT_select_less(struct wmOperatorType *ot); -void CURVE_OT_select_random(struct wmOperatorType *ot); -void CURVE_OT_select_nth(struct wmOperatorType *ot); - void CURVE_OT_switch_direction(struct wmOperatorType *ot); void CURVE_OT_subdivide(struct wmOperatorType *ot); void CURVE_OT_make_segment(struct wmOperatorType *ot); @@ -121,11 +128,28 @@ void CURVE_OT_cyclic_toggle(struct wmOperatorType *ot); void CURVE_OT_match_texture_space(struct wmOperatorType *ot); +bool ED_curve_pick_vert( + struct ViewContext *vc, short sel, const int mval[2], + struct Nurb **r_nurb, struct BezTriple **r_bezt, struct BPoint **r_bp, short *r_handle); + /* helper functions */ void ed_editnurb_translate_flag(struct ListBase *editnurb, short flag, const float vec[3]); bool ed_editnurb_extrude_flag(struct EditNurb *editnurb, short flag); bool ed_editnurb_spin(float viewmat[4][4], struct Object *obedit, const float axis[3], const float cent[3]); +/* editcurve_select.c */ +void CURVE_OT_de_select_first(struct wmOperatorType *ot); +void CURVE_OT_de_select_last(struct wmOperatorType *ot); +void CURVE_OT_select_all(struct wmOperatorType *ot); +void CURVE_OT_select_linked(struct wmOperatorType *ot); +void CURVE_OT_select_linked_pick(struct wmOperatorType *ot); +void CURVE_OT_select_row(struct wmOperatorType *ot); +void CURVE_OT_select_next(struct wmOperatorType *ot); +void CURVE_OT_select_previous(struct wmOperatorType *ot); +void CURVE_OT_select_more(struct wmOperatorType *ot); +void CURVE_OT_select_less(struct wmOperatorType *ot); +void CURVE_OT_select_random(struct wmOperatorType *ot); +void CURVE_OT_select_nth(struct wmOperatorType *ot); /* editcurve_add.c */ void CURVE_OT_primitive_bezier_curve_add(struct wmOperatorType *ot); diff --git a/source/blender/editors/curve/editcurve.c b/source/blender/editors/curve/editcurve.c index 1a10814bbf1..d17c05a4491 100644 --- a/source/blender/editors/curve/editcurve.c +++ b/source/blender/editors/curve/editcurve.c @@ -37,9 +37,7 @@ #include "MEM_guardedalloc.h" #include "BLI_blenlib.h" -#include "BLI_bitmap.h" #include "BLI_math.h" -#include "BLI_rand.h" #include "BLI_ghash.h" #include "BLF_translation.h" @@ -96,23 +94,7 @@ typedef struct { Nurb *orig_nu; } CVKeyIndex; -typedef enum eVisible_Types { - HIDDEN = true, - VISIBLE = false, -} eVisible_Types; - -typedef enum eEndPoint_Types { - FIRST = true, - LAST = false, -} eEndPoint_Types; - -typedef enum eCurveElem_Types { - CURVE_VERTEX = 0, - CURVE_SEGMENT, -} eCurveElem_Types; - void selectend_nurb(Object *obedit, enum eEndPoint_Types selfirst, bool doswap, bool selstatus); -static void select_adjacent_cp(ListBase *editnurb, short next, const bool cont, const bool selstatus); static void adduplicateflagNurb(Object *obedit, ListBase *newnurb, const short flag, const bool split); static int curve_delete_segments(Object *obedit, const bool split); @@ -127,61 +109,6 @@ ListBase *object_editcurve_get(Object *ob) /* ******************* SELECTION FUNCTIONS ********************* */ - -/* returns 1 in case (de)selection was successful */ -static bool select_beztriple(BezTriple *bezt, bool selstatus, short flag, eVisible_Types hidden) -{ - if ((bezt->hide == 0) || (hidden == HIDDEN)) { - if (selstatus == SELECT) { /* selects */ - bezt->f1 |= flag; - bezt->f2 |= flag; - bezt->f3 |= flag; - return true; - } - else { /* deselects */ - bezt->f1 &= ~flag; - bezt->f2 &= ~flag; - bezt->f3 &= ~flag; - return true; - } - } - - return false; -} - -/* returns 1 in case (de)selection was successful */ -static bool select_bpoint(BPoint *bp, bool selstatus, short flag, bool hidden) -{ - if ((bp->hide == 0) || (hidden == 1)) { - if (selstatus == SELECT) { - bp->f1 |= flag; - return true; - } - else { - bp->f1 &= ~flag; - return true; - } - } - - return false; -} - -static bool swap_selection_beztriple(BezTriple *bezt) -{ - if (bezt->f2 & SELECT) - return select_beztriple(bezt, DESELECT, SELECT, VISIBLE); - else - return select_beztriple(bezt, SELECT, SELECT, VISIBLE); -} - -static bool swap_selection_bpoint(BPoint *bp) -{ - if (bp->f1 & SELECT) - return select_bpoint(bp, DESELECT, SELECT, VISIBLE); - else - return select_bpoint(bp, SELECT, SELECT, VISIBLE); -} - int isNurbsel(Nurb *nu) { BezTriple *bezt; @@ -1407,64 +1334,6 @@ void ED_curve_deselect_all(EditNurb *editnurb) } } -void ED_curve_select_all(EditNurb *editnurb) -{ - Nurb *nu; - int a; - for (nu = editnurb->nurbs.first; nu; nu = nu->next) { - if (nu->bezt) { - BezTriple *bezt; - for (bezt = nu->bezt, a = 0; a < nu->pntsu; a++, bezt++) { - if (bezt->hide == 0) { - bezt->f1 |= SELECT; - bezt->f2 |= SELECT; - bezt->f3 |= SELECT; - } - } - } - else if (nu->bp) { - BPoint *bp; - for (bp = nu->bp, a = 0; a < nu->pntsu * nu->pntsv; a++, bp++) { - if (bp->hide == 0) - bp->f1 |= SELECT; - } - } - } -} - -void ED_curve_select_swap(EditNurb *editnurb, bool hide_handles) -{ - Nurb *nu; - BPoint *bp; - BezTriple *bezt; - int a; - - for (nu = editnurb->nurbs.first; nu; nu = nu->next) { - if (nu->type == CU_BEZIER) { - bezt = nu->bezt; - a = nu->pntsu; - while (a--) { - if (bezt->hide == 0) { - bezt->f2 ^= SELECT; /* always do the center point */ - if (!hide_handles) { - bezt->f1 ^= SELECT; - bezt->f3 ^= SELECT; - } - } - bezt++; - } - } - else { - bp = nu->bp; - a = nu->pntsu * nu->pntsv; - while (a--) { - swap_selection_bpoint(bp); - bp++; - } - } - } -} - /******************** separate operator ***********************/ static int separate_exec(bContext *C, wmOperator *op) @@ -2925,274 +2794,6 @@ void CURVE_OT_smooth_tilt(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; } -/***************** selection utility *************************/ - -/* next == 1 -> select next */ -/* next == -1 -> select previous */ -/* cont == 1 -> select continuously */ -/* selstatus, inverts behavior */ -static void select_adjacent_cp(ListBase *editnurb, short next, - const bool cont, const bool selstatus) -{ - Nurb *nu; - BezTriple *bezt; - BPoint *bp; - int a; - bool lastsel = false; - - if (next == 0) return; - - for (nu = editnurb->first; nu; nu = nu->next) { - lastsel = false; - if (nu->type == CU_BEZIER) { - a = nu->pntsu; - bezt = nu->bezt; - if (next < 0) bezt = &nu->bezt[a - 1]; - while (a--) { - if (a - abs(next) < 0) break; - if ((lastsel == 0) && (bezt->hide == 0) && ((bezt->f2 & SELECT) || (selstatus == DESELECT))) { - bezt += next; - if (!(bezt->f2 & SELECT) || (selstatus == DESELECT)) { - short sel = select_beztriple(bezt, selstatus, SELECT, VISIBLE); - if ((sel == 1) && (cont == 0)) lastsel = true; - } - } - else { - bezt += next; - lastsel = false; - } - /* move around in zigzag way so that we go through each */ - bezt -= (next - next / abs(next)); - } - } - else { - a = nu->pntsu * nu->pntsv; - bp = nu->bp; - if (next < 0) bp = &nu->bp[a - 1]; - while (a--) { - if (a - abs(next) < 0) break; - if ((lastsel == 0) && (bp->hide == 0) && ((bp->f1 & SELECT) || (selstatus == DESELECT))) { - bp += next; - if (!(bp->f1 & SELECT) || (selstatus == DESELECT)) { - short sel = select_bpoint(bp, selstatus, SELECT, VISIBLE); - if ((sel == 1) && (cont == 0)) lastsel = true; - } - } - else { - bp += next; - lastsel = false; - } - /* move around in zigzag way so that we go through each */ - bp -= (next - next / abs(next)); - } - } - } -} - -/**************** select start/end operators **************/ - -/* (de)selects first or last of visible part of each Nurb depending on selFirst - * selFirst: defines the end of which to select - * doswap: defines if selection state of each first/last control point is swapped - * selstatus: selection status in case doswap is false - */ -void selectend_nurb(Object *obedit, eEndPoint_Types selfirst, bool doswap, bool selstatus) -{ - ListBase *editnurb = object_editcurve_get(obedit); - Nurb *nu; - BPoint *bp; - BezTriple *bezt; - Curve *cu; - int a; - - if (obedit == NULL) return; - - cu = (Curve *)obedit->data; - cu->actvert = CU_ACT_NONE; - - for (nu = editnurb->first; nu; nu = nu->next) { - if (nu->type == CU_BEZIER) { - a = nu->pntsu; - - /* which point? */ - if (selfirst == LAST) { /* select last */ - bezt = &nu->bezt[a - 1]; - } - else { /* select first */ - bezt = nu->bezt; - } - - while (a--) { - bool sel; - if (doswap) sel = swap_selection_beztriple(bezt); - else sel = select_beztriple(bezt, selstatus, SELECT, VISIBLE); - - if (sel == true) break; - } - } - else { - a = nu->pntsu * nu->pntsv; - - /* which point? */ - if (selfirst == LAST) { /* select last */ - bp = &nu->bp[a - 1]; - } - else { /* select first */ - bp = nu->bp; - } - - while (a--) { - if (bp->hide == 0) { - bool sel; - if (doswap) sel = swap_selection_bpoint(bp); - else sel = select_bpoint(bp, selstatus, SELECT, VISIBLE); - - if (sel == true) break; - } - } - } - } -} - -static int de_select_first_exec(bContext *C, wmOperator *UNUSED(op)) -{ - Object *obedit = CTX_data_edit_object(C); - - selectend_nurb(obedit, FIRST, true, DESELECT); - WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data); - BKE_curve_nurb_vert_active_validate(obedit->data); - - return OPERATOR_FINISHED; -} - -void CURVE_OT_de_select_first(wmOperatorType *ot) -{ - /* identifiers */ - ot->name = "(De)select First"; - ot->idname = "CURVE_OT_de_select_first"; - ot->description = "(De)select first of visible part of each NURBS"; - - /* api cfirstbacks */ - ot->exec = de_select_first_exec; - ot->poll = ED_operator_editcurve; - - /* flags */ - ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; -} - -static int de_select_last_exec(bContext *C, wmOperator *UNUSED(op)) -{ - Object *obedit = CTX_data_edit_object(C); - - selectend_nurb(obedit, LAST, true, DESELECT); - WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data); - BKE_curve_nurb_vert_active_validate(obedit->data); - - return OPERATOR_FINISHED; -} - -void CURVE_OT_de_select_last(wmOperatorType *ot) -{ - /* identifiers */ - ot->name = "(De)select Last"; - ot->idname = "CURVE_OT_de_select_last"; - ot->description = "(De)select last of visible part of each NURBS"; - - /* api clastbacks */ - ot->exec = de_select_last_exec; - ot->poll = ED_operator_editcurve; - - /* flags */ - ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; -} - -/******************* de select all operator ***************/ - -static bool nurb_has_selected_cps(ListBase *editnurb) -{ - Nurb *nu; - BezTriple *bezt; - BPoint *bp; - int a; - - for (nu = editnurb->first; nu; nu = nu->next) { - if (nu->type == CU_BEZIER) { - a = nu->pntsu; - bezt = nu->bezt; - while (a--) { - if (bezt->hide == 0) { - if ((bezt->f1 & SELECT) || - (bezt->f2 & SELECT) || - (bezt->f3 & SELECT)) - { - return 1; - } - } - bezt++; - } - } - else { - a = nu->pntsu * nu->pntsv; - bp = nu->bp; - while (a--) { - if ((bp->hide == 0) && (bp->f1 & SELECT)) return 1; - bp++; - } - } - } - - return 0; -} - -static int de_select_all_exec(bContext *C, wmOperator *op) -{ - Object *obedit = CTX_data_edit_object(C); - Curve *cu = obedit->data; - ListBase *editnurb = object_editcurve_get(obedit); - int action = RNA_enum_get(op->ptr, "action"); - - if (action == SEL_TOGGLE) { - action = SEL_SELECT; - if (nurb_has_selected_cps(editnurb)) - action = SEL_DESELECT; - } - - switch (action) { - case SEL_SELECT: - ED_curve_select_all(cu->editnurb); - break; - case SEL_DESELECT: - ED_curve_deselect_all(cu->editnurb); - break; - case SEL_INVERT: - ED_curve_select_swap(cu->editnurb, (cu->drawflag & CU_HIDE_HANDLES) != 0); - break; - } - - WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data); - BKE_curve_nurb_vert_active_validate(cu); - - return OPERATOR_FINISHED; -} - -void CURVE_OT_select_all(wmOperatorType *ot) -{ - /* identifiers */ - ot->name = "(De)select All"; - ot->idname = "CURVE_OT_select_all"; - ot->description = "(De)select all control points"; - - /* api callbacks */ - ot->exec = de_select_all_exec; - ot->poll = ED_operator_editsurfcurve; - - /* flags */ - ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; - - /* properties */ - WM_operator_properties_select_all(ot); -} - /********************** hide operator *********************/ static int hide_exec(bContext *C, wmOperator *op) @@ -3754,7 +3355,7 @@ void CURVE_OT_subdivide(wmOperatorType *ot) /******************** find nearest ************************/ -static void findnearestNurbvert__doClosest(void *userData, Nurb *nu, BPoint *bp, BezTriple *bezt, int beztindex, const float screen_co[2]) +static void ED_curve_pick_vert__doClosest(void *userData, Nurb *nu, BPoint *bp, BezTriple *bezt, int beztindex, const float screen_co[2]) { struct { BPoint *bp; BezTriple *bezt; Nurb *nurb; float dist; int hpoint, select; float mval_fl[2]; } *data = userData; @@ -3790,7 +3391,9 @@ static void findnearestNurbvert__doClosest(void *userData, Nurb *nu, BPoint *bp, } } -static short findnearestNurbvert(ViewContext *vc, short sel, const int mval[2], Nurb **nurb, BezTriple **bezt, BPoint **bp) +bool ED_curve_pick_vert( + ViewContext *vc, short sel, const int mval[2], + Nurb **r_nurb, BezTriple **r_bezt, BPoint **r_bp, short *r_handle) { /* (sel == 1): selected gets a disadvantage */ /* in nurb and bezt or bp the nearest is written */ @@ -3804,13 +3407,17 @@ static short findnearestNurbvert(ViewContext *vc, short sel, const int mval[2], data.mval_fl[1] = mval[1]; ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); - nurbs_foreachScreenVert(vc, findnearestNurbvert__doClosest, &data, V3D_PROJ_TEST_CLIP_DEFAULT); + nurbs_foreachScreenVert(vc, ED_curve_pick_vert__doClosest, &data, V3D_PROJ_TEST_CLIP_DEFAULT); - *nurb = data.nurb; - *bezt = data.bezt; - *bp = data.bp; + *r_nurb = data.nurb; + *r_bezt = data.bezt; + *r_bp = data.bp; + + if (r_handle) { + *r_handle = data.hpoint; + } - return data.hpoint; + return (data.bezt || data.bp); } static void findselectedNurbvert(ListBase *editnurb, Nurb **nu, BezTriple **bezt, BPoint **bp) @@ -4637,9 +4244,8 @@ bool mouse_nurb(bContext *C, const int mval[2], bool extend, bool deselect, bool location[0] = mval[0]; location[1] = mval[1]; - hand = findnearestNurbvert(&vc, 1, location, &nu, &bezt, &bp); - if (bezt || bp) { + if (ED_curve_pick_vert(&vc, 1, location, &nu, &bezt, &bp, &hand)) { if (extend) { if (bezt) { if (hand == 1) { @@ -5545,717 +5151,6 @@ void CURVE_OT_cyclic_toggle(wmOperatorType *ot) RNA_def_enum(ot->srna, "direction", direction_items, 0, "Direction", "Direction to make surface cyclic in"); } -/***************** select linked operator ******************/ - -static int select_linked_exec(bContext *C, wmOperator *UNUSED(op)) -{ - Object *obedit = CTX_data_edit_object(C); - Curve *cu = (Curve *)obedit->data; - EditNurb *editnurb = cu->editnurb; - ListBase *nurbs = &editnurb->nurbs; - Nurb *nu; - BezTriple *bezt; - BPoint *bp; - int a; - - for (nu = nurbs->first; nu; nu = nu->next) { - if (nu->type == CU_BEZIER) { - bezt = nu->bezt; - a = nu->pntsu; - while (a--) { - if ((bezt->f1 & SELECT) || (bezt->f2 & SELECT) || (bezt->f3 & SELECT)) { - a = nu->pntsu; - bezt = nu->bezt; - while (a--) { - select_beztriple(bezt, SELECT, SELECT, VISIBLE); - bezt++; - } - break; - } - bezt++; - } - } - else { - bp = nu->bp; - a = nu->pntsu * nu->pntsv; - while (a--) { - if (bp->f1 & SELECT) { - a = nu->pntsu * nu->pntsv; - bp = nu->bp; - while (a--) { - select_bpoint(bp, SELECT, SELECT, VISIBLE); - bp++; - } - break; - } - bp++; - } - } - } - - WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data); - - return OPERATOR_FINISHED; -} - -static int select_linked_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event)) -{ - return select_linked_exec(C, op); -} - -void CURVE_OT_select_linked(wmOperatorType *ot) -{ - /* identifiers */ - ot->name = "Select Linked All"; - ot->idname = "CURVE_OT_select_linked"; - ot->description = "Select all control points linked to active one"; - - /* api callbacks */ - ot->exec = select_linked_exec; - ot->invoke = select_linked_invoke; - ot->poll = ED_operator_editsurfcurve; - - /* flags */ - ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; - - /* properties */ -} - - -/***************** select linked pick operator ******************/ - -static int select_linked_pick_invoke(bContext *C, wmOperator *op, const wmEvent *event) -{ - Object *obedit = CTX_data_edit_object(C); - ViewContext vc; - Nurb *nu; - BezTriple *bezt; - BPoint *bp; - int a; - const bool select = !RNA_boolean_get(op->ptr, "deselect"); - - view3d_operator_needs_opengl(C); - view3d_set_viewcontext(C, &vc); - - findnearestNurbvert(&vc, 1, event->mval, &nu, &bezt, &bp); - - if (bezt) { - a = nu->pntsu; - bezt = nu->bezt; - while (a--) { - select_beztriple(bezt, select, SELECT, VISIBLE); - bezt++; - } - } - else if (bp) { - a = nu->pntsu * nu->pntsv; - bp = nu->bp; - while (a--) { - select_bpoint(bp, select, SELECT, VISIBLE); - bp++; - } - } - - WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data); - if (!select) { - BKE_curve_nurb_vert_active_validate(obedit->data); - } - - return OPERATOR_FINISHED; -} - -void CURVE_OT_select_linked_pick(wmOperatorType *ot) -{ - /* identifiers */ - ot->name = "Select Linked"; - ot->idname = "CURVE_OT_select_linked_pick"; - ot->description = "Select all control points linked to already selected ones"; - - /* api callbacks */ - ot->invoke = select_linked_pick_invoke; - ot->poll = ED_operator_editsurfcurve_region_view3d; - - /* flags */ - ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; - - /* properties */ - RNA_def_boolean(ot->srna, "deselect", 0, "Deselect", "Deselect linked control points rather than selecting them"); -} - -/***************** select row operator **********************/ - -static int select_row_exec(bContext *C, wmOperator *UNUSED(op)) -{ - Object *obedit = CTX_data_edit_object(C); - Curve *cu = obedit->data; - ListBase *editnurb = object_editcurve_get(obedit); - static BPoint *last = NULL; - static int direction = 0; - Nurb *nu = NULL; - BPoint *bp = NULL; - int u = 0, v = 0, a, b; - - if (!BKE_curve_nurb_vert_active_get(cu, &nu, (void *)&bp)) - return OPERATOR_CANCELLED; - - if (last == bp) { - direction = 1 - direction; - BKE_nurbList_flag_set(editnurb, 0); - } - last = bp; - - u = cu->actvert % nu->pntsu; - v = cu->actvert / nu->pntsu; - bp = nu->bp; - for (a = 0; a < nu->pntsv; a++) { - for (b = 0; b < nu->pntsu; b++, bp++) { - if (direction) { - if (a == v) select_bpoint(bp, SELECT, SELECT, VISIBLE); - } - else { - if (b == u) select_bpoint(bp, SELECT, SELECT, VISIBLE); - } - } - } - - WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data); - - return OPERATOR_FINISHED; -} - -void CURVE_OT_select_row(wmOperatorType *ot) -{ - /* identifiers */ - ot->name = "Select Control Point Row"; - ot->idname = "CURVE_OT_select_row"; - ot->description = "Select a row of control points including active one"; - - /* api callbacks */ - ot->exec = select_row_exec; - ot->poll = ED_operator_editsurf; - - /* flags */ - ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; -} - -/***************** select next operator **********************/ - -static int select_next_exec(bContext *C, wmOperator *UNUSED(op)) -{ - Object *obedit = CTX_data_edit_object(C); - ListBase *editnurb = object_editcurve_get(obedit); - - select_adjacent_cp(editnurb, 1, 0, SELECT); - WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data); - - return OPERATOR_FINISHED; -} - -void CURVE_OT_select_next(wmOperatorType *ot) -{ - /* identifiers */ - ot->name = "Select Next"; - ot->idname = "CURVE_OT_select_next"; - ot->description = "Select control points following already selected ones along the curves"; - - /* api callbacks */ - ot->exec = select_next_exec; - ot->poll = ED_operator_editcurve; - - /* flags */ - ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; -} - -/***************** select previous operator **********************/ - -static int select_previous_exec(bContext *C, wmOperator *UNUSED(op)) -{ - Object *obedit = CTX_data_edit_object(C); - ListBase *editnurb = object_editcurve_get(obedit); - - select_adjacent_cp(editnurb, -1, 0, SELECT); - WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data); - - return OPERATOR_FINISHED; -} - -void CURVE_OT_select_previous(wmOperatorType *ot) -{ - /* identifiers */ - ot->name = "Select Previous"; - ot->idname = "CURVE_OT_select_previous"; - ot->description = "Select control points preceding already selected ones along the curves"; - - /* api callbacks */ - ot->exec = select_previous_exec; - ot->poll = ED_operator_editcurve; - - /* flags */ - ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; -} - -/***************** select more operator **********************/ - -static int select_more_exec(bContext *C, wmOperator *UNUSED(op)) -{ - Object *obedit = CTX_data_edit_object(C); - ListBase *editnurb = object_editcurve_get(obedit); - Nurb *nu; - BPoint *bp, *tempbp; - int a; - short sel = 0; - - /* note that NURBS surface is a special case because we mimic */ - /* the behavior of "select more" of mesh tools. */ - /* The algorithm is designed to work in planar cases so it */ - /* may not be optimal always (example: end of NURBS sphere) */ - if (obedit->type == OB_SURF) { - for (nu = editnurb->first; nu; nu = nu->next) { - BLI_bitmap *selbpoints; - a = nu->pntsu * nu->pntsv; - bp = nu->bp; - selbpoints = BLI_BITMAP_NEW(a, "selectlist"); - while (a > 0) { - if ((!BLI_BITMAP_TEST(selbpoints, a)) && (bp->hide == 0) && (bp->f1 & SELECT)) { - /* upper control point */ - if (a % nu->pntsu != 0) { - tempbp = bp - 1; - if (!(tempbp->f1 & SELECT)) select_bpoint(tempbp, SELECT, SELECT, VISIBLE); - } - - /* left control point. select only if it is not selected already */ - if (a - nu->pntsu > 0) { - sel = 0; - tempbp = bp + nu->pntsu; - if (!(tempbp->f1 & SELECT)) sel = select_bpoint(tempbp, SELECT, SELECT, VISIBLE); - /* make sure selected bpoint is discarded */ - if (sel == 1) BLI_BITMAP_ENABLE(selbpoints, a - nu->pntsu); - } - - /* right control point */ - if (a + nu->pntsu < nu->pntsu * nu->pntsv) { - tempbp = bp - nu->pntsu; - if (!(tempbp->f1 & SELECT)) select_bpoint(tempbp, SELECT, SELECT, VISIBLE); - } - - /* lower control point. skip next bp in case selection was made */ - if (a % nu->pntsu != 1) { - sel = 0; - tempbp = bp + 1; - if (!(tempbp->f1 & SELECT)) sel = select_bpoint(tempbp, SELECT, SELECT, VISIBLE); - if (sel) { - bp++; - a--; - } - } - } - - bp++; - a--; - } - - MEM_freeN(selbpoints); - } - } - else { - select_adjacent_cp(editnurb, 1, 0, SELECT); - select_adjacent_cp(editnurb, -1, 0, SELECT); - } - - WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data); - - return OPERATOR_FINISHED; -} - -void CURVE_OT_select_more(wmOperatorType *ot) -{ - /* identifiers */ - ot->name = "Select More"; - ot->idname = "CURVE_OT_select_more"; - ot->description = "Select control points directly linked to already selected ones"; - - /* api callbacks */ - ot->exec = select_more_exec; - ot->poll = ED_operator_editsurfcurve; - - /* flags */ - ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; -} - -/******************** select less operator *****************/ - -/* basic method: deselect if control point doesn't have all neighbors selected */ -static int select_less_exec(bContext *C, wmOperator *UNUSED(op)) -{ - Object *obedit = CTX_data_edit_object(C); - ListBase *editnurb = object_editcurve_get(obedit); - Nurb *nu; - BPoint *bp; - BezTriple *bezt; - int a; - int sel = 0; - short lastsel = false; - - if (obedit->type == OB_SURF) { - for (nu = editnurb->first; nu; nu = nu->next) { - BLI_bitmap *selbpoints; - a = nu->pntsu * nu->pntsv; - bp = nu->bp; - selbpoints = BLI_BITMAP_NEW(a, "selectlist"); - while (a--) { - if ((bp->hide == 0) && (bp->f1 & SELECT)) { - sel = 0; - - /* check if neighbors have been selected */ - /* edges of surface are an exception */ - if ((a + 1) % nu->pntsu == 0) { - sel++; - } - else { - bp--; - if (BLI_BITMAP_TEST(selbpoints, a + 1) || ((bp->hide == 0) && (bp->f1 & SELECT))) sel++; - bp++; - } - - if ((a + 1) % nu->pntsu == 1) { - sel++; - } - else { - bp++; - if ((bp->hide == 0) && (bp->f1 & SELECT)) sel++; - bp--; - } - - if (a + 1 > nu->pntsu * nu->pntsv - nu->pntsu) { - sel++; - } - else { - bp -= nu->pntsu; - if (BLI_BITMAP_TEST(selbpoints, a + nu->pntsu) || ((bp->hide == 0) && (bp->f1 & SELECT))) sel++; - bp += nu->pntsu; - } - - if (a < nu->pntsu) { - sel++; - } - else { - bp += nu->pntsu; - if ((bp->hide == 0) && (bp->f1 & SELECT)) sel++; - bp -= nu->pntsu; - } - - if (sel != 4) { - select_bpoint(bp, DESELECT, SELECT, VISIBLE); - BLI_BITMAP_ENABLE(selbpoints, a); - } - } - else { - lastsel = false; - } - - bp++; - } - - MEM_freeN(selbpoints); - } - } - else { - for (nu = editnurb->first; nu; nu = nu->next) { - lastsel = false; - /* check what type of curve/nurb it is */ - if (nu->type == CU_BEZIER) { - a = nu->pntsu; - bezt = nu->bezt; - while (a--) { - if ((bezt->hide == 0) && (bezt->f2 & SELECT)) { - sel = (lastsel == 1); - - /* check if neighbors have been selected */ - /* first and last are exceptions */ - if (a == nu->pntsu - 1) { - sel++; - } - else { - bezt--; - if ((bezt->hide == 0) && (bezt->f2 & SELECT)) sel++; - bezt++; - } - - if (a == 0) { - sel++; - } - else { - bezt++; - if ((bezt->hide == 0) && (bezt->f2 & SELECT)) sel++; - bezt--; - } - - if (sel != 2) { - select_beztriple(bezt, DESELECT, SELECT, VISIBLE); - lastsel = true; - } - else { - lastsel = false; - } - } - else { - lastsel = false; - } - - bezt++; - } - } - else { - a = nu->pntsu * nu->pntsv; - bp = nu->bp; - while (a--) { - if ((lastsel == 0) && (bp->hide == 0) && (bp->f1 & SELECT)) { - if (lastsel != 0) sel = 1; - else sel = 0; - - /* first and last are exceptions */ - if (a == nu->pntsu * nu->pntsv - 1) { - sel++; - } - else { - bp--; - if ((bp->hide == 0) && (bp->f1 & SELECT)) sel++; - bp++; - } - - if (a == 0) { - sel++; - } - else { - bp++; - if ((bp->hide == 0) && (bp->f1 & SELECT)) sel++; - bp--; - } - - if (sel != 2) { - select_bpoint(bp, DESELECT, SELECT, VISIBLE); - lastsel = true; - } - else { - lastsel = false; - } - } - else { - lastsel = false; - } - - bp++; - } - } - } - } - - WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data); - BKE_curve_nurb_vert_active_validate(obedit->data); - - return OPERATOR_FINISHED; -} - -void CURVE_OT_select_less(wmOperatorType *ot) -{ - /* identifiers */ - ot->name = "Select Less"; - ot->idname = "CURVE_OT_select_less"; - ot->description = "Reduce current selection by deselecting boundary elements"; - - /* api callbacks */ - ot->exec = select_less_exec; - ot->poll = ED_operator_editsurfcurve; - - /* flags */ - ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; -} - -/********************** select random *********************/ - -static void curve_select_random(ListBase *editnurb, float randfac, bool select) -{ - Nurb *nu; - BezTriple *bezt; - BPoint *bp; - int a; - - for (nu = editnurb->first; nu; nu = nu->next) { - if (nu->type == CU_BEZIER) { - bezt = nu->bezt; - a = nu->pntsu; - while (a--) { - if (!bezt->hide) { - if (BLI_frand() < randfac) { - select_beztriple(bezt, select, SELECT, VISIBLE); - } - } - bezt++; - } - } - else { - bp = nu->bp; - a = nu->pntsu * nu->pntsv; - - while (a--) { - if (!bp->hide) { - if (BLI_frand() < randfac) { - select_bpoint(bp, select, SELECT, VISIBLE); - } - } - bp++; - } - } - } -} - -static int curve_select_random_exec(bContext *C, wmOperator *op) -{ - Object *obedit = CTX_data_edit_object(C); - ListBase *editnurb = object_editcurve_get(obedit); - const bool select = (RNA_enum_get(op->ptr, "action") == SEL_SELECT); - const float randfac = RNA_float_get(op->ptr, "percent") / 100.0f; - - curve_select_random(editnurb, randfac, select); - BKE_curve_nurb_vert_active_validate(obedit->data); - - WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data); - - return OPERATOR_FINISHED; -} - -void CURVE_OT_select_random(wmOperatorType *ot) -{ - /* identifiers */ - ot->name = "Select Random"; - ot->idname = "CURVE_OT_select_random"; - ot->description = "Randomly select some control points"; - - /* api callbacks */ - ot->exec = curve_select_random_exec; - ot->poll = ED_operator_editsurfcurve; - - /* flags */ - ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; - - /* properties */ - RNA_def_float_percentage(ot->srna, "percent", 50.f, 0.0f, 100.0f, - "Percent", "Percentage of elements to select randomly", 0.0f, 100.0f); - WM_operator_properties_select_action_simple(ot, SEL_SELECT); -} - -/********************* every nth number of point *******************/ - -static void select_nth_bezt(Nurb *nu, BezTriple *bezt, int nth, int skip, int offset) -{ - int a, start; - - start = bezt - nu->bezt; - a = nu->pntsu; - bezt = &nu->bezt[a - 1]; - - while (a--) { - const int depth = abs(start - a); - if ((offset + depth) % (skip + nth) >= skip) { - select_beztriple(bezt, DESELECT, SELECT, HIDDEN); - } - - bezt--; - } -} - -static void select_nth_bp(Nurb *nu, BPoint *bp, int nth, int skip, int offset) -{ - int a, startrow, startpnt; - int row, pnt; - - startrow = (bp - nu->bp) / nu->pntsu; - startpnt = (bp - nu->bp) % nu->pntsu; - - a = nu->pntsu * nu->pntsv; - bp = &nu->bp[a - 1]; - row = nu->pntsv - 1; - pnt = nu->pntsu - 1; - - while (a--) { - const int depth = abs(pnt - startpnt) + abs(row - startrow); - if ((offset + depth) % (skip + nth) >= skip) { - select_bpoint(bp, DESELECT, SELECT, HIDDEN); - } - - pnt--; - if (pnt < 0) { - pnt = nu->pntsu - 1; - row--; - } - - bp--; - } -} - -bool ED_curve_select_nth(Curve *cu, int nth, int skip, int offset) -{ - Nurb *nu = NULL; - void *vert = NULL; - - if (!BKE_curve_nurb_vert_active_get(cu, &nu, &vert)) - return false; - - if (nu->bezt) { - select_nth_bezt(nu, vert, nth, skip, offset); - } - else { - select_nth_bp(nu, vert, nth, skip, offset); - } - - return true; -} - -static int select_nth_exec(bContext *C, wmOperator *op) -{ - Object *obedit = CTX_data_edit_object(C); - const int nth = RNA_int_get(op->ptr, "nth") - 1; - const int skip = RNA_int_get(op->ptr, "skip"); - int offset = RNA_int_get(op->ptr, "offset"); - - /* so input of offset zero ends up being (nth - 1) */ - offset = mod_i(offset, nth + skip); - - if (!ED_curve_select_nth(obedit->data, nth, skip, offset)) { - if (obedit->type == OB_SURF) { - BKE_report(op->reports, RPT_ERROR, "Surface has not got active point"); - } - else { - BKE_report(op->reports, RPT_ERROR, "Curve has not got active point"); - } - - return OPERATOR_CANCELLED; - } - - WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data); - - return OPERATOR_FINISHED; -} - -void CURVE_OT_select_nth(wmOperatorType *ot) -{ - /* identifiers */ - ot->name = "Checker Deselect"; - ot->description = "Deselect every other vertex"; - ot->idname = "CURVE_OT_select_nth"; - - /* api callbacks */ - ot->exec = select_nth_exec; - ot->poll = ED_operator_editsurfcurve; - - /* flags */ - ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; - - RNA_def_int(ot->srna, "nth", 2, 2, INT_MAX, "Nth Selection", "", 2, 100); - RNA_def_int(ot->srna, "skip", 1, 1, INT_MAX, "Skip", "", 1, 100); - RNA_def_int(ot->srna, "offset", 0, INT_MIN, INT_MAX, "Offset", "", -100, 100); -} - /********************** add duplicate operator *********************/ static int duplicate_exec(bContext *C, wmOperator *op) diff --git a/source/blender/editors/curve/editcurve_select.c b/source/blender/editors/curve/editcurve_select.c new file mode 100644 index 00000000000..0a8c05ba16d --- /dev/null +++ b/source/blender/editors/curve/editcurve_select.c @@ -0,0 +1,1156 @@ +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/editors/curve/editcurve_select.c + * \ingroup edcurve + */ + +#include "DNA_object_types.h" +#include "DNA_scene_types.h" + +#include "MEM_guardedalloc.h" + +#include "BLI_bitmap.h" +#include "BLI_math.h" +#include "BLI_rand.h" + + +#include "BKE_context.h" +#include "BKE_curve.h" +#include "BKE_fcurve.h" +#include "BKE_report.h" + +#include "WM_api.h" +#include "WM_types.h" + +#include "ED_screen.h" +#include "ED_types.h" +#include "ED_view3d.h" +#include "ED_curve.h" + +#include "curve_intern.h" + + +#include "RNA_access.h" +#include "RNA_define.h" + + +/* returns 1 in case (de)selection was successful */ +bool select_beztriple(BezTriple *bezt, bool selstatus, short flag, eVisible_Types hidden) +{ + if ((bezt->hide == 0) || (hidden == HIDDEN)) { + if (selstatus == SELECT) { /* selects */ + bezt->f1 |= flag; + bezt->f2 |= flag; + bezt->f3 |= flag; + return true; + } + else { /* deselects */ + bezt->f1 &= ~flag; + bezt->f2 &= ~flag; + bezt->f3 &= ~flag; + return true; + } + } + + return false; +} + +/* returns 1 in case (de)selection was successful */ +bool select_bpoint(BPoint *bp, bool selstatus, short flag, bool hidden) +{ + if ((bp->hide == 0) || (hidden == 1)) { + if (selstatus == SELECT) { + bp->f1 |= flag; + return true; + } + else { + bp->f1 &= ~flag; + return true; + } + } + + return false; +} + +static bool swap_selection_beztriple(BezTriple *bezt) +{ + if (bezt->f2 & SELECT) + return select_beztriple(bezt, DESELECT, SELECT, VISIBLE); + else + return select_beztriple(bezt, SELECT, SELECT, VISIBLE); +} + +static bool swap_selection_bpoint(BPoint *bp) +{ + if (bp->f1 & SELECT) + return select_bpoint(bp, DESELECT, SELECT, VISIBLE); + else + return select_bpoint(bp, SELECT, SELECT, VISIBLE); +} + + +void ED_curve_select_all(EditNurb *editnurb) +{ + Nurb *nu; + int a; + for (nu = editnurb->nurbs.first; nu; nu = nu->next) { + if (nu->bezt) { + BezTriple *bezt; + for (bezt = nu->bezt, a = 0; a < nu->pntsu; a++, bezt++) { + if (bezt->hide == 0) { + bezt->f1 |= SELECT; + bezt->f2 |= SELECT; + bezt->f3 |= SELECT; + } + } + } + else if (nu->bp) { + BPoint *bp; + for (bp = nu->bp, a = 0; a < nu->pntsu * nu->pntsv; a++, bp++) { + if (bp->hide == 0) + bp->f1 |= SELECT; + } + } + } +} + +void ED_curve_select_swap(EditNurb *editnurb, bool hide_handles) +{ + Nurb *nu; + BPoint *bp; + BezTriple *bezt; + int a; + + for (nu = editnurb->nurbs.first; nu; nu = nu->next) { + if (nu->type == CU_BEZIER) { + bezt = nu->bezt; + a = nu->pntsu; + while (a--) { + if (bezt->hide == 0) { + bezt->f2 ^= SELECT; /* always do the center point */ + if (!hide_handles) { + bezt->f1 ^= SELECT; + bezt->f3 ^= SELECT; + } + } + bezt++; + } + } + else { + bp = nu->bp; + a = nu->pntsu * nu->pntsv; + while (a--) { + swap_selection_bpoint(bp); + bp++; + } + } + } +} + +/** + * \param next: -1/1 for prev/next + * \param cont: when true select continuously + * \param selstatus: inverts behavior + */ +static void select_adjacent_cp( + ListBase *editnurb, short next, + const bool cont, const bool selstatus) +{ + Nurb *nu; + BezTriple *bezt; + BPoint *bp; + int a; + bool lastsel = false; + + if (next == 0) return; + + for (nu = editnurb->first; nu; nu = nu->next) { + lastsel = false; + if (nu->type == CU_BEZIER) { + a = nu->pntsu; + bezt = nu->bezt; + if (next < 0) bezt = &nu->bezt[a - 1]; + while (a--) { + if (a - abs(next) < 0) break; + if ((lastsel == 0) && (bezt->hide == 0) && ((bezt->f2 & SELECT) || (selstatus == DESELECT))) { + bezt += next; + if (!(bezt->f2 & SELECT) || (selstatus == DESELECT)) { + short sel = select_beztriple(bezt, selstatus, SELECT, VISIBLE); + if ((sel == 1) && (cont == 0)) lastsel = true; + } + } + else { + bezt += next; + lastsel = false; + } + /* move around in zigzag way so that we go through each */ + bezt -= (next - next / abs(next)); + } + } + else { + a = nu->pntsu * nu->pntsv; + bp = nu->bp; + if (next < 0) bp = &nu->bp[a - 1]; + while (a--) { + if (a - abs(next) < 0) break; + if ((lastsel == 0) && (bp->hide == 0) && ((bp->f1 & SELECT) || (selstatus == DESELECT))) { + bp += next; + if (!(bp->f1 & SELECT) || (selstatus == DESELECT)) { + short sel = select_bpoint(bp, selstatus, SELECT, VISIBLE); + if ((sel == 1) && (cont == 0)) lastsel = true; + } + } + else { + bp += next; + lastsel = false; + } + /* move around in zigzag way so that we go through each */ + bp -= (next - next / abs(next)); + } + } + } +} + +/**************** select start/end operators **************/ + +/* (de)selects first or last of visible part of each Nurb depending on selFirst + * selFirst: defines the end of which to select + * doswap: defines if selection state of each first/last control point is swapped + * selstatus: selection status in case doswap is false + */ +static void selectend_nurb(Object *obedit, eEndPoint_Types selfirst, bool doswap, bool selstatus) +{ + ListBase *editnurb = object_editcurve_get(obedit); + Nurb *nu; + BPoint *bp; + BezTriple *bezt; + Curve *cu; + int a; + + if (obedit == NULL) return; + + cu = (Curve *)obedit->data; + cu->actvert = CU_ACT_NONE; + + for (nu = editnurb->first; nu; nu = nu->next) { + if (nu->type == CU_BEZIER) { + a = nu->pntsu; + + /* which point? */ + if (selfirst == LAST) { /* select last */ + bezt = &nu->bezt[a - 1]; + } + else { /* select first */ + bezt = nu->bezt; + } + + while (a--) { + bool sel; + if (doswap) sel = swap_selection_beztriple(bezt); + else sel = select_beztriple(bezt, selstatus, SELECT, VISIBLE); + + if (sel == true) break; + } + } + else { + a = nu->pntsu * nu->pntsv; + + /* which point? */ + if (selfirst == LAST) { /* select last */ + bp = &nu->bp[a - 1]; + } + else { /* select first */ + bp = nu->bp; + } + + while (a--) { + if (bp->hide == 0) { + bool sel; + if (doswap) sel = swap_selection_bpoint(bp); + else sel = select_bpoint(bp, selstatus, SELECT, VISIBLE); + + if (sel == true) break; + } + } + } + } +} + +static int de_select_first_exec(bContext *C, wmOperator *UNUSED(op)) +{ + Object *obedit = CTX_data_edit_object(C); + + selectend_nurb(obedit, FIRST, true, DESELECT); + WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data); + BKE_curve_nurb_vert_active_validate(obedit->data); + + return OPERATOR_FINISHED; +} + +void CURVE_OT_de_select_first(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "(De)select First"; + ot->idname = "CURVE_OT_de_select_first"; + ot->description = "(De)select first of visible part of each NURBS"; + + /* api cfirstbacks */ + ot->exec = de_select_first_exec; + ot->poll = ED_operator_editcurve; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; +} + +static int de_select_last_exec(bContext *C, wmOperator *UNUSED(op)) +{ + Object *obedit = CTX_data_edit_object(C); + + selectend_nurb(obedit, LAST, true, DESELECT); + WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data); + BKE_curve_nurb_vert_active_validate(obedit->data); + + return OPERATOR_FINISHED; +} + +void CURVE_OT_de_select_last(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "(De)select Last"; + ot->idname = "CURVE_OT_de_select_last"; + ot->description = "(De)select last of visible part of each NURBS"; + + /* api clastbacks */ + ot->exec = de_select_last_exec; + ot->poll = ED_operator_editcurve; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; +} + +/******************* de select all operator ***************/ + +static bool nurb_has_selected_cps(ListBase *editnurb) +{ + Nurb *nu; + BezTriple *bezt; + BPoint *bp; + int a; + + for (nu = editnurb->first; nu; nu = nu->next) { + if (nu->type == CU_BEZIER) { + a = nu->pntsu; + bezt = nu->bezt; + while (a--) { + if (bezt->hide == 0) { + if ((bezt->f1 & SELECT) || + (bezt->f2 & SELECT) || + (bezt->f3 & SELECT)) + { + return 1; + } + } + bezt++; + } + } + else { + a = nu->pntsu * nu->pntsv; + bp = nu->bp; + while (a--) { + if ((bp->hide == 0) && (bp->f1 & SELECT)) return 1; + bp++; + } + } + } + + return 0; +} + +static int de_select_all_exec(bContext *C, wmOperator *op) +{ + Object *obedit = CTX_data_edit_object(C); + Curve *cu = obedit->data; + ListBase *editnurb = object_editcurve_get(obedit); + int action = RNA_enum_get(op->ptr, "action"); + + if (action == SEL_TOGGLE) { + action = SEL_SELECT; + if (nurb_has_selected_cps(editnurb)) + action = SEL_DESELECT; + } + + switch (action) { + case SEL_SELECT: + ED_curve_select_all(cu->editnurb); + break; + case SEL_DESELECT: + ED_curve_deselect_all(cu->editnurb); + break; + case SEL_INVERT: + ED_curve_select_swap(cu->editnurb, (cu->drawflag & CU_HIDE_HANDLES) != 0); + break; + } + + WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data); + BKE_curve_nurb_vert_active_validate(cu); + + return OPERATOR_FINISHED; +} + +void CURVE_OT_select_all(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "(De)select All"; + ot->idname = "CURVE_OT_select_all"; + ot->description = "(De)select all control points"; + + /* api callbacks */ + ot->exec = de_select_all_exec; + ot->poll = ED_operator_editsurfcurve; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + /* properties */ + WM_operator_properties_select_all(ot); +} + + + +/***************** select linked operator ******************/ + +static int select_linked_exec(bContext *C, wmOperator *UNUSED(op)) +{ + Object *obedit = CTX_data_edit_object(C); + Curve *cu = (Curve *)obedit->data; + EditNurb *editnurb = cu->editnurb; + ListBase *nurbs = &editnurb->nurbs; + Nurb *nu; + BezTriple *bezt; + BPoint *bp; + int a; + + for (nu = nurbs->first; nu; nu = nu->next) { + if (nu->type == CU_BEZIER) { + bezt = nu->bezt; + a = nu->pntsu; + while (a--) { + if ((bezt->f1 & SELECT) || (bezt->f2 & SELECT) || (bezt->f3 & SELECT)) { + a = nu->pntsu; + bezt = nu->bezt; + while (a--) { + select_beztriple(bezt, SELECT, SELECT, VISIBLE); + bezt++; + } + break; + } + bezt++; + } + } + else { + bp = nu->bp; + a = nu->pntsu * nu->pntsv; + while (a--) { + if (bp->f1 & SELECT) { + a = nu->pntsu * nu->pntsv; + bp = nu->bp; + while (a--) { + select_bpoint(bp, SELECT, SELECT, VISIBLE); + bp++; + } + break; + } + bp++; + } + } + } + + WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data); + + return OPERATOR_FINISHED; +} + +static int select_linked_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event)) +{ + return select_linked_exec(C, op); +} + +void CURVE_OT_select_linked(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Select Linked All"; + ot->idname = "CURVE_OT_select_linked"; + ot->description = "Select all control points linked to active one"; + + /* api callbacks */ + ot->exec = select_linked_exec; + ot->invoke = select_linked_invoke; + ot->poll = ED_operator_editsurfcurve; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + /* properties */ +} + + +/***************** select linked pick operator ******************/ + +static int select_linked_pick_invoke(bContext *C, wmOperator *op, const wmEvent *event) +{ + Object *obedit = CTX_data_edit_object(C); + ViewContext vc; + Nurb *nu; + BezTriple *bezt; + BPoint *bp; + int a; + const bool select = !RNA_boolean_get(op->ptr, "deselect"); + + view3d_operator_needs_opengl(C); + view3d_set_viewcontext(C, &vc); + + if (!ED_curve_pick_vert(&vc, 1, event->mval, &nu, &bezt, &bp, NULL)) { + return OPERATOR_CANCELLED; + } + + if (bezt) { + a = nu->pntsu; + bezt = nu->bezt; + while (a--) { + select_beztriple(bezt, select, SELECT, VISIBLE); + bezt++; + } + } + else if (bp) { + a = nu->pntsu * nu->pntsv; + bp = nu->bp; + while (a--) { + select_bpoint(bp, select, SELECT, VISIBLE); + bp++; + } + } + + WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data); + if (!select) { + BKE_curve_nurb_vert_active_validate(obedit->data); + } + + return OPERATOR_FINISHED; +} + +void CURVE_OT_select_linked_pick(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Select Linked"; + ot->idname = "CURVE_OT_select_linked_pick"; + ot->description = "Select all control points linked to already selected ones"; + + /* api callbacks */ + ot->invoke = select_linked_pick_invoke; + ot->poll = ED_operator_editsurfcurve_region_view3d; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + /* properties */ + RNA_def_boolean(ot->srna, "deselect", 0, "Deselect", "Deselect linked control points rather than selecting them"); +} + +/***************** select row operator **********************/ + +static int select_row_exec(bContext *C, wmOperator *UNUSED(op)) +{ + Object *obedit = CTX_data_edit_object(C); + Curve *cu = obedit->data; + ListBase *editnurb = object_editcurve_get(obedit); + static BPoint *last = NULL; + static int direction = 0; + Nurb *nu = NULL; + BPoint *bp = NULL; + int u = 0, v = 0, a, b; + + if (!BKE_curve_nurb_vert_active_get(cu, &nu, (void *)&bp)) + return OPERATOR_CANCELLED; + + if (last == bp) { + direction = 1 - direction; + BKE_nurbList_flag_set(editnurb, 0); + } + last = bp; + + u = cu->actvert % nu->pntsu; + v = cu->actvert / nu->pntsu; + bp = nu->bp; + for (a = 0; a < nu->pntsv; a++) { + for (b = 0; b < nu->pntsu; b++, bp++) { + if (direction) { + if (a == v) select_bpoint(bp, SELECT, SELECT, VISIBLE); + } + else { + if (b == u) select_bpoint(bp, SELECT, SELECT, VISIBLE); + } + } + } + + WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data); + + return OPERATOR_FINISHED; +} + +void CURVE_OT_select_row(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Select Control Point Row"; + ot->idname = "CURVE_OT_select_row"; + ot->description = "Select a row of control points including active one"; + + /* api callbacks */ + ot->exec = select_row_exec; + ot->poll = ED_operator_editsurf; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; +} + +/***************** select next operator **********************/ + +static int select_next_exec(bContext *C, wmOperator *UNUSED(op)) +{ + Object *obedit = CTX_data_edit_object(C); + ListBase *editnurb = object_editcurve_get(obedit); + + select_adjacent_cp(editnurb, 1, 0, SELECT); + WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data); + + return OPERATOR_FINISHED; +} + +void CURVE_OT_select_next(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Select Next"; + ot->idname = "CURVE_OT_select_next"; + ot->description = "Select control points following already selected ones along the curves"; + + /* api callbacks */ + ot->exec = select_next_exec; + ot->poll = ED_operator_editcurve; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; +} + +/***************** select previous operator **********************/ + +static int select_previous_exec(bContext *C, wmOperator *UNUSED(op)) +{ + Object *obedit = CTX_data_edit_object(C); + ListBase *editnurb = object_editcurve_get(obedit); + + select_adjacent_cp(editnurb, -1, 0, SELECT); + WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data); + + return OPERATOR_FINISHED; +} + +void CURVE_OT_select_previous(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Select Previous"; + ot->idname = "CURVE_OT_select_previous"; + ot->description = "Select control points preceding already selected ones along the curves"; + + /* api callbacks */ + ot->exec = select_previous_exec; + ot->poll = ED_operator_editcurve; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; +} + +/***************** select more operator **********************/ + +static int select_more_exec(bContext *C, wmOperator *UNUSED(op)) +{ + Object *obedit = CTX_data_edit_object(C); + ListBase *editnurb = object_editcurve_get(obedit); + Nurb *nu; + BPoint *bp, *tempbp; + int a; + short sel = 0; + + /* note that NURBS surface is a special case because we mimic */ + /* the behavior of "select more" of mesh tools. */ + /* The algorithm is designed to work in planar cases so it */ + /* may not be optimal always (example: end of NURBS sphere) */ + if (obedit->type == OB_SURF) { + for (nu = editnurb->first; nu; nu = nu->next) { + BLI_bitmap *selbpoints; + a = nu->pntsu * nu->pntsv; + bp = nu->bp; + selbpoints = BLI_BITMAP_NEW(a, "selectlist"); + while (a > 0) { + if ((!BLI_BITMAP_TEST(selbpoints, a)) && (bp->hide == 0) && (bp->f1 & SELECT)) { + /* upper control point */ + if (a % nu->pntsu != 0) { + tempbp = bp - 1; + if (!(tempbp->f1 & SELECT)) select_bpoint(tempbp, SELECT, SELECT, VISIBLE); + } + + /* left control point. select only if it is not selected already */ + if (a - nu->pntsu > 0) { + sel = 0; + tempbp = bp + nu->pntsu; + if (!(tempbp->f1 & SELECT)) sel = select_bpoint(tempbp, SELECT, SELECT, VISIBLE); + /* make sure selected bpoint is discarded */ + if (sel == 1) BLI_BITMAP_ENABLE(selbpoints, a - nu->pntsu); + } + + /* right control point */ + if (a + nu->pntsu < nu->pntsu * nu->pntsv) { + tempbp = bp - nu->pntsu; + if (!(tempbp->f1 & SELECT)) select_bpoint(tempbp, SELECT, SELECT, VISIBLE); + } + + /* lower control point. skip next bp in case selection was made */ + if (a % nu->pntsu != 1) { + sel = 0; + tempbp = bp + 1; + if (!(tempbp->f1 & SELECT)) sel = select_bpoint(tempbp, SELECT, SELECT, VISIBLE); + if (sel) { + bp++; + a--; + } + } + } + + bp++; + a--; + } + + MEM_freeN(selbpoints); + } + } + else { + select_adjacent_cp(editnurb, 1, 0, SELECT); + select_adjacent_cp(editnurb, -1, 0, SELECT); + } + + WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data); + + return OPERATOR_FINISHED; +} + +void CURVE_OT_select_more(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Select More"; + ot->idname = "CURVE_OT_select_more"; + ot->description = "Select control points directly linked to already selected ones"; + + /* api callbacks */ + ot->exec = select_more_exec; + ot->poll = ED_operator_editsurfcurve; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; +} + +/******************** select less operator *****************/ + +/* basic method: deselect if control point doesn't have all neighbors selected */ +static int select_less_exec(bContext *C, wmOperator *UNUSED(op)) +{ + Object *obedit = CTX_data_edit_object(C); + ListBase *editnurb = object_editcurve_get(obedit); + Nurb *nu; + BPoint *bp; + BezTriple *bezt; + int a; + int sel = 0; + short lastsel = false; + + if (obedit->type == OB_SURF) { + for (nu = editnurb->first; nu; nu = nu->next) { + BLI_bitmap *selbpoints; + a = nu->pntsu * nu->pntsv; + bp = nu->bp; + selbpoints = BLI_BITMAP_NEW(a, "selectlist"); + while (a--) { + if ((bp->hide == 0) && (bp->f1 & SELECT)) { + sel = 0; + + /* check if neighbors have been selected */ + /* edges of surface are an exception */ + if ((a + 1) % nu->pntsu == 0) { + sel++; + } + else { + bp--; + if (BLI_BITMAP_TEST(selbpoints, a + 1) || ((bp->hide == 0) && (bp->f1 & SELECT))) sel++; + bp++; + } + + if ((a + 1) % nu->pntsu == 1) { + sel++; + } + else { + bp++; + if ((bp->hide == 0) && (bp->f1 & SELECT)) sel++; + bp--; + } + + if (a + 1 > nu->pntsu * nu->pntsv - nu->pntsu) { + sel++; + } + else { + bp -= nu->pntsu; + if (BLI_BITMAP_TEST(selbpoints, a + nu->pntsu) || ((bp->hide == 0) && (bp->f1 & SELECT))) sel++; + bp += nu->pntsu; + } + + if (a < nu->pntsu) { + sel++; + } + else { + bp += nu->pntsu; + if ((bp->hide == 0) && (bp->f1 & SELECT)) sel++; + bp -= nu->pntsu; + } + + if (sel != 4) { + select_bpoint(bp, DESELECT, SELECT, VISIBLE); + BLI_BITMAP_ENABLE(selbpoints, a); + } + } + else { + lastsel = false; + } + + bp++; + } + + MEM_freeN(selbpoints); + } + } + else { + for (nu = editnurb->first; nu; nu = nu->next) { + lastsel = false; + /* check what type of curve/nurb it is */ + if (nu->type == CU_BEZIER) { + a = nu->pntsu; + bezt = nu->bezt; + while (a--) { + if ((bezt->hide == 0) && (bezt->f2 & SELECT)) { + sel = (lastsel == 1); + + /* check if neighbors have been selected */ + /* first and last are exceptions */ + if (a == nu->pntsu - 1) { + sel++; + } + else { + bezt--; + if ((bezt->hide == 0) && (bezt->f2 & SELECT)) sel++; + bezt++; + } + + if (a == 0) { + sel++; + } + else { + bezt++; + if ((bezt->hide == 0) && (bezt->f2 & SELECT)) sel++; + bezt--; + } + + if (sel != 2) { + select_beztriple(bezt, DESELECT, SELECT, VISIBLE); + lastsel = true; + } + else { + lastsel = false; + } + } + else { + lastsel = false; + } + + bezt++; + } + } + else { + a = nu->pntsu * nu->pntsv; + bp = nu->bp; + while (a--) { + if ((lastsel == 0) && (bp->hide == 0) && (bp->f1 & SELECT)) { + if (lastsel != 0) sel = 1; + else sel = 0; + + /* first and last are exceptions */ + if (a == nu->pntsu * nu->pntsv - 1) { + sel++; + } + else { + bp--; + if ((bp->hide == 0) && (bp->f1 & SELECT)) sel++; + bp++; + } + + if (a == 0) { + sel++; + } + else { + bp++; + if ((bp->hide == 0) && (bp->f1 & SELECT)) sel++; + bp--; + } + + if (sel != 2) { + select_bpoint(bp, DESELECT, SELECT, VISIBLE); + lastsel = true; + } + else { + lastsel = false; + } + } + else { + lastsel = false; + } + + bp++; + } + } + } + } + + WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data); + BKE_curve_nurb_vert_active_validate(obedit->data); + + return OPERATOR_FINISHED; +} + +void CURVE_OT_select_less(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Select Less"; + ot->idname = "CURVE_OT_select_less"; + ot->description = "Reduce current selection by deselecting boundary elements"; + + /* api callbacks */ + ot->exec = select_less_exec; + ot->poll = ED_operator_editsurfcurve; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; +} + +/********************** select random *********************/ + +static void curve_select_random(ListBase *editnurb, float randfac, bool select) +{ + Nurb *nu; + BezTriple *bezt; + BPoint *bp; + int a; + + for (nu = editnurb->first; nu; nu = nu->next) { + if (nu->type == CU_BEZIER) { + bezt = nu->bezt; + a = nu->pntsu; + while (a--) { + if (!bezt->hide) { + if (BLI_frand() < randfac) { + select_beztriple(bezt, select, SELECT, VISIBLE); + } + } + bezt++; + } + } + else { + bp = nu->bp; + a = nu->pntsu * nu->pntsv; + + while (a--) { + if (!bp->hide) { + if (BLI_frand() < randfac) { + select_bpoint(bp, select, SELECT, VISIBLE); + } + } + bp++; + } + } + } +} + +static int curve_select_random_exec(bContext *C, wmOperator *op) +{ + Object *obedit = CTX_data_edit_object(C); + ListBase *editnurb = object_editcurve_get(obedit); + const bool select = (RNA_enum_get(op->ptr, "action") == SEL_SELECT); + const float randfac = RNA_float_get(op->ptr, "percent") / 100.0f; + + curve_select_random(editnurb, randfac, select); + BKE_curve_nurb_vert_active_validate(obedit->data); + + WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data); + + return OPERATOR_FINISHED; +} + +void CURVE_OT_select_random(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Select Random"; + ot->idname = "CURVE_OT_select_random"; + ot->description = "Randomly select some control points"; + + /* api callbacks */ + ot->exec = curve_select_random_exec; + ot->poll = ED_operator_editsurfcurve; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + /* properties */ + RNA_def_float_percentage(ot->srna, "percent", 50.f, 0.0f, 100.0f, + "Percent", "Percentage of elements to select randomly", 0.0f, 100.0f); + WM_operator_properties_select_action_simple(ot, SEL_SELECT); +} + +/********************* every nth number of point *******************/ + +static void select_nth_bezt(Nurb *nu, BezTriple *bezt, int nth, int skip, int offset) +{ + int a, start; + + start = bezt - nu->bezt; + a = nu->pntsu; + bezt = &nu->bezt[a - 1]; + + while (a--) { + const int depth = abs(start - a); + if ((offset + depth) % (skip + nth) >= skip) { + select_beztriple(bezt, DESELECT, SELECT, HIDDEN); + } + + bezt--; + } +} + +static void select_nth_bp(Nurb *nu, BPoint *bp, int nth, int skip, int offset) +{ + int a, startrow, startpnt; + int row, pnt; + + startrow = (bp - nu->bp) / nu->pntsu; + startpnt = (bp - nu->bp) % nu->pntsu; + + a = nu->pntsu * nu->pntsv; + bp = &nu->bp[a - 1]; + row = nu->pntsv - 1; + pnt = nu->pntsu - 1; + + while (a--) { + const int depth = abs(pnt - startpnt) + abs(row - startrow); + if ((offset + depth) % (skip + nth) >= skip) { + select_bpoint(bp, DESELECT, SELECT, HIDDEN); + } + + pnt--; + if (pnt < 0) { + pnt = nu->pntsu - 1; + row--; + } + + bp--; + } +} + +bool ED_curve_select_nth(Curve *cu, int nth, int skip, int offset) +{ + Nurb *nu = NULL; + void *vert = NULL; + + if (!BKE_curve_nurb_vert_active_get(cu, &nu, &vert)) + return false; + + if (nu->bezt) { + select_nth_bezt(nu, vert, nth, skip, offset); + } + else { + select_nth_bp(nu, vert, nth, skip, offset); + } + + return true; +} + +static int select_nth_exec(bContext *C, wmOperator *op) +{ + Object *obedit = CTX_data_edit_object(C); + const int nth = RNA_int_get(op->ptr, "nth") - 1; + const int skip = RNA_int_get(op->ptr, "skip"); + int offset = RNA_int_get(op->ptr, "offset"); + + /* so input of offset zero ends up being (nth - 1) */ + offset = mod_i(offset, nth + skip); + + if (!ED_curve_select_nth(obedit->data, nth, skip, offset)) { + if (obedit->type == OB_SURF) { + BKE_report(op->reports, RPT_ERROR, "Surface has not got active point"); + } + else { + BKE_report(op->reports, RPT_ERROR, "Curve has not got active point"); + } + + return OPERATOR_CANCELLED; + } + + WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data); + + return OPERATOR_FINISHED; +} + +void CURVE_OT_select_nth(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Checker Deselect"; + ot->description = "Deselect every other vertex"; + ot->idname = "CURVE_OT_select_nth"; + + /* api callbacks */ + ot->exec = select_nth_exec; + ot->poll = ED_operator_editsurfcurve; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + RNA_def_int(ot->srna, "nth", 2, 2, INT_MAX, "Nth Selection", "", 2, 100); + RNA_def_int(ot->srna, "skip", 1, 1, INT_MAX, "Skip", "", 1, 100); + RNA_def_int(ot->srna, "offset", 0, INT_MIN, INT_MAX, "Offset", "", -100, 100); +} diff --git a/source/blender/editors/include/ED_curve.h b/source/blender/editors/include/ED_curve.h index fee3d44b8eb..1718fe691d7 100644 --- a/source/blender/editors/include/ED_curve.h +++ b/source/blender/editors/include/ED_curve.h @@ -48,11 +48,6 @@ void ED_operatormacros_curve(void); void ED_keymap_curve(struct wmKeyConfig *keyconf); /* editcurve.c */ -void ED_curve_deselect_all(struct EditNurb *editnurb); -void ED_curve_select_all(struct EditNurb *editnurb); -void ED_curve_select_swap(struct EditNurb *editnurb, bool hide_handles); - - void undo_push_curve(struct bContext *C, const char *name); ListBase *object_editcurve_get(struct Object *ob); @@ -68,6 +63,12 @@ int isNurbsel(struct Nurb *nu); int join_curve_exec(struct bContext *C, struct wmOperator *op); +/* editcurve_select.c */ +void ED_curve_deselect_all(struct EditNurb *editnurb); +void ED_curve_select_all(struct EditNurb *editnurb); +void ED_curve_select_swap(struct EditNurb *editnurb, bool hide_handles); +bool ED_curve_select_nth(struct Curve *cu, int nth, int skip, int offset); + /* editfont.h */ void undo_push_font(struct bContext *C, const char *name); void make_editText(struct Object *obedit); @@ -76,8 +77,6 @@ void free_editText(struct Object *obedit); void ED_text_to_object(struct bContext *C, struct Text *text, const bool split_lines); -bool ED_curve_select_nth(struct Curve *cu, int nth, int skip, int offset); - void ED_curve_beztcpy(struct EditNurb *editnurb, struct BezTriple *dst, struct BezTriple *src, int count); void ED_curve_bpcpy(struct EditNurb *editnurb, struct BPoint *dst, struct BPoint *src, int count); -- cgit v1.2.3