Index: release/scripts/startup/bl_ui/space_view3d.py =================================================================== --- release/scripts/startup/bl_ui/space_view3d.py (revision 57762) +++ release/scripts/startup/bl_ui/space_view3d.py (working copy) @@ -720,6 +720,11 @@ layout.operator("view3d.select_circle") layout.separator() + + layout.operator("lattice.select_less", text="Less") + layout.operator("lattice.select_more", text="More") + + layout.separator() layout.operator("lattice.select_all").action = 'TOGGLE' layout.operator("lattice.select_all", text="Inverse").action = 'INVERT' Index: source/blender/makesdna/DNA_lattice_types.h =================================================================== --- source/blender/makesdna/DNA_lattice_types.h (revision 57762) +++ source/blender/makesdna/DNA_lattice_types.h (working copy) @@ -77,12 +77,15 @@ /* ***************** LATTICE ********************* */ + /* flag */ #define LT_GRID 1 #define LT_OUTSIDE 2 #define LT_DS_EXPAND 4 +#define LT_INDEX(lt, u, v, w) ((w) * ((lt)->pntsu * (lt)->pntsv) + ((v) * (lt)->pntsu) + (u)) + #define LT_ACTBP_NONE -1 #endif Index: source/blender/blenkernel/intern/lattice.c =================================================================== --- source/blender/blenkernel/intern/lattice.c (revision 57762) +++ source/blender/blenkernel/intern/lattice.c (working copy) @@ -39,6 +39,7 @@ #include "BLI_blenlib.h" #include "BLI_math.h" #include "BLI_utildefines.h" +#include "BLI_bitmap.h" #include "DNA_mesh_types.h" #include "DNA_meshdata_types.h" @@ -1107,3 +1108,81 @@ } } +LatticeSelectionMap *BKE_lattice_selection_map_new(Lattice *lt) +{ + int u, v, w, index; + LatticeSelectionMap * ret; + BPoint *bp = lt->def; + + ret = MEM_mallocN(sizeof(LatticeSelectionMap), "Lattice selection map"); + + ret->lt = lt; + + ret->selectionmap = BLI_BITMAP_NEW(lt->pntsu * lt->pntsv * lt->pntsw, "lattice selection bitmap"); + + //Set in the bitmap vertices currently selected + for (w = 0; w < lt->pntsw; w++){ + for (v = 0; v < lt->pntsv; v++){ + for (u = 0; u < lt->pntsu; u++){ + index = LT_INDEX(lt, u, v, w); + if (bp[index].f1 & SELECT) { + BLI_BITMAP_SET((unsigned int *)ret->selectionmap, index); + } + } + } + } + + return ret; +} + +inline int BKE_lattice_selection_map_query(LatticeSelectionMap *lsm, int index){ + return BLI_BITMAP_GET_BOOL((unsigned int *)lsm->selectionmap, index); +} + +inline int BKE_lattice_selection_map_query_uvw(LatticeSelectionMap *lsm, int u, int v, int w){ + return BKE_lattice_selection_map_query(lsm, LT_INDEX(lsm->lt, u, v, w)); +} + +void BKE_lattice_selection_map_free(LatticeSelectionMap *lsm){ + + MEM_freeN(lsm->selectionmap); + MEM_freeN(lsm); +} + +LatticeSelectionIter *BKE_lattice_selection_begin_iter() +{ + LatticeSelectionIter *ret = MEM_mallocN(sizeof(LatticeSelectionIter), "Lattice selection iterator"); + ret->u = 0; ret->v = 0; ret->w = 0; + ret->begin_with = 0; + return ret; +} + +int BKE_lattice_selection_iter_through(LatticeSelectionMap *lsm, LatticeSelectionIter *lsi, int selection_flag) +{ + int count, max, selected, ended = 0; + short b1, b2; //boolean variables + + count = lsi->begin_with; + + max = lsm->lt->pntsu * lsm->lt->pntsv * lsm->lt->pntsw; + while (count < max && !ended){ + selected = BKE_lattice_selection_map_query(lsm, count); + b1 = selection_flag == SELECT && selected; + b2 = selection_flag != SELECT && !selected; + + if ( b1 || b2 ){ + ended = 1; + BKE_lattice_index_to_uvw(lsm->lt, count, &(lsi->u), &(lsi->v), &(lsi->w)); + } + count++; + } + + lsi->begin_with = count; + + return ended; +} + +void BKE_lattice_selection_free_iter(LatticeSelectionIter *lsi) +{ + MEM_freeN(lsi); +} Index: source/blender/blenkernel/BKE_lattice.h =================================================================== --- source/blender/blenkernel/BKE_lattice.h (revision 57762) +++ source/blender/blenkernel/BKE_lattice.h (working copy) @@ -42,6 +42,20 @@ struct BPoint; struct MDeformVert; +//The following two structures are not meant to be saved on disc, so they are not declared in DNA file + +/*Stores the selection status of a Lattice object*/ +typedef struct LatticeSelectionMap { + void *selectionmap; //Actually, this field is a BLI_bitmap, but because that header is not included in this file, we declare it as void + struct Lattice *lt; +} LatticeSelectionMap; + +/*Used to traverse the selection saved on a LatticeSelectionMap*/ +typedef struct LatticeSelectionIter { + int u, v, w; + int begin_with; +} LatticeSelectionIter; + void BKE_lattice_resize(struct Lattice *lt, int u, int v, int w, struct Object *ltOb); struct Lattice *BKE_lattice_add(struct Main *bmain, const char *name); struct Lattice *BKE_lattice_copy(struct Lattice *lt); @@ -82,6 +96,14 @@ void BKE_lattice_center_bounds(struct Lattice *lt, float cent[3]); void BKE_lattice_translate(struct Lattice *lt, float offset[3], int do_keys); +LatticeSelectionMap *BKE_lattice_selection_map_new(struct Lattice *lt); +int BKE_lattice_selection_map_query_uvw(LatticeSelectionMap* lsm, int u, int v, int w); +int BKE_lattice_selection_map_query(LatticeSelectionMap* lsm, int index); +void BKE_lattice_selection_map_free(LatticeSelectionMap *lsm); +LatticeSelectionIter *BKE_lattice_selection_begin_iter(void); +int BKE_lattice_selection_iter_through(LatticeSelectionMap *lsm, LatticeSelectionIter *lsi, int selection_flag); +void BKE_lattice_selection_free_iter(struct LatticeSelectionIter *lsi); + int BKE_lattice_index_from_uvw(struct Lattice *lt, const int u, const int v, const int w); void BKE_lattice_index_to_uvw(struct Lattice *lt, const int index, int *r_u, int *r_v, int *r_w); Index: source/blender/blenlib/BLI_bitmap.h =================================================================== --- source/blender/blenlib/BLI_bitmap.h (revision 57762) +++ source/blender/blenlib/BLI_bitmap.h (working copy) @@ -56,6 +56,10 @@ ((_bitmap)[(_index) >> BLI_BITMAP_POWER] & \ (1 << ((_index) & BLI_BITMAP_MASK))) +/* Returns 1 if the bit pointed by index is set, and 0 otherwise */ +#define BLI_BITMAP_GET_BOOL(_bitmap, _index) \ + (!(BLI_BITMAP_GET(_bitmap, _index) == 0)) + /* set the value of a single bit at '_index' */ #define BLI_BITMAP_SET(_bitmap, _index) \ ((_bitmap)[(_index) >> BLI_BITMAP_POWER] |= \ Index: source/blender/editors/object/object_ops.c =================================================================== --- source/blender/editors/object/object_ops.c (revision 57762) +++ source/blender/editors/object/object_ops.c (working copy) @@ -217,6 +217,8 @@ WM_operatortype_append(LATTICE_OT_select_all); WM_operatortype_append(LATTICE_OT_select_ungrouped); + WM_operatortype_append(LATTICE_OT_select_more); + WM_operatortype_append(LATTICE_OT_select_less); WM_operatortype_append(LATTICE_OT_make_regular); WM_operatortype_append(LATTICE_OT_flip); @@ -431,6 +433,9 @@ WM_keymap_add_item(keymap, "LATTICE_OT_flip", FKEY, KM_PRESS, KM_CTRL, 0); + WM_keymap_add_item(keymap, "LATTICE_OT_select_more", PADPLUSKEY, KM_PRESS, KM_CTRL, 0); + WM_keymap_add_item(keymap, "LATTICE_OT_select_less", PADMINUS, KM_PRESS, KM_CTRL, 0); + /* menus */ WM_keymap_add_menu(keymap, "VIEW3D_MT_hook", HKEY, KM_PRESS, KM_CTRL, 0); Index: source/blender/editors/object/object_lattice.c =================================================================== --- source/blender/editors/object/object_lattice.c (revision 57762) +++ source/blender/editors/object/object_lattice.c (working copy) @@ -35,6 +35,7 @@ #include "MEM_guardedalloc.h" #include "BLI_listbase.h" +#include "BLI_bitmap.h" #include "BLI_math.h" #include "BLI_utildefines.h" @@ -204,7 +205,8 @@ bp = lt->editlatt->latt->def; a = lt->editlatt->latt->pntsu * lt->editlatt->latt->pntsv * lt->editlatt->latt->pntsw; - + + //There are as many points in the bp-pointed array as "a" value while (a--) { if (bp->hide == 0) { if (bp->f1 & SELECT) { @@ -259,6 +261,129 @@ WM_operator_properties_select_all(ot); } +/* Helper macro for accessing item at index (u, v, w) + * < lt: (Lattice) + * < U: (int) u-axis coordinate of point + * < V: (int) v-axis coordinate of point + * < W: (int) w-axis coordinate of point + * < dimU: (int) number of points per row or number of columns (U-Axis) + * < dimV: (int) number of rows (V-Axis) + * > returns: (BPoint *) pointer to BPoint at this index + */ +#define LATTICE_PT(lt, U, V, W, dimU, dimV) \ +( (lt)->def + \ +((dimU) * (dimV)) * (W) + \ +(dimU) * (V) + \ +(U) \ +) + +/************************** Select more/less Operators *************************/ + +static void __select_neighbours(Lattice *lt, int u, int v, int w) +{ + + if (u - 1 >= 0) LATTICE_PT(lt, u - 1, v, w, lt->pntsu, lt->pntsv )->f1 |= SELECT; + if (u + 1 < lt->pntsu) LATTICE_PT(lt, u + 1, v, w, lt->pntsu, lt->pntsv )->f1 |= SELECT; + + if (v - 1 >= 0) LATTICE_PT(lt, u, v - 1, w, lt->pntsu, lt->pntsv )->f1 |= SELECT; + if (v + 1 < lt->pntsv) LATTICE_PT(lt, u, v + 1, w, lt->pntsu, lt->pntsv )->f1 |= SELECT; + + if (w - 1 >= 0) LATTICE_PT(lt, u, v, w - 1, lt->pntsu, lt->pntsv )->f1 |= SELECT; + if (w + 1 < lt->pntsw) LATTICE_PT(lt, u, v, w + 1, lt->pntsu, lt->pntsv )->f1 |= SELECT; + +} + +static int lattice_select_more_exec(bContext *C, wmOperator *op) +{ + Object *obedit = CTX_data_edit_object(C); + Lattice *lt = ((Lattice *)(obedit->data))->editlatt->latt; + + LatticeSelectionMap *lsm = BKE_lattice_selection_map_new(lt); + LatticeSelectionIter *lsi = BKE_lattice_selection_begin_iter(); + + while (BKE_lattice_selection_iter_through(lsm, lsi, SELECT)){ + __select_neighbours(lt, lsi->u, lsi->v, lsi->w); + } + + BKE_lattice_selection_free_iter(lsi); + BKE_lattice_selection_map_free(lsm); + + WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data); + + return OPERATOR_FINISHED; +} + +void LATTICE_OT_select_more(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Select More"; + ot->idname = "LATTICE_OT_select_more"; + ot->description = "Select more vertices connected to initial selection"; + + /* api callbacks */ + ot->exec = lattice_select_more_exec; + ot->poll = ED_operator_editlattice; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + +} + +static int __unselectable_vertex_on_less(LatticeSelectionMap *lsm, int u, int v, int w) +{ + Lattice *lt = lsm->lt; + + if (u + 1 < lt->pntsu && !(BKE_lattice_selection_map_query_uvw(lsm, u + 1, v, w))) return 1; + if (u - 1 >= 0 && !(BKE_lattice_selection_map_query_uvw(lsm, u - 1, v, w))) return 1; + + if (v + 1 < lt->pntsv && !(BKE_lattice_selection_map_query_uvw(lsm, u, v + 1, w))) return 1; + if (v - 1 >= 0 && !(BKE_lattice_selection_map_query_uvw(lsm, u, v - 1, w))) return 1; + + if (w + 1 < lt->pntsw && !(BKE_lattice_selection_map_query_uvw(lsm, u, v, w + 1))) return 1; + if (w - 1 >= 0 && !(BKE_lattice_selection_map_query_uvw(lsm, u, v, w - 1))) return 1; + + return 0; +} + +static int lattice_select_less_exec(bContext *C, wmOperator *op){ + Object *obedit = CTX_data_edit_object(C); + Lattice *lt = ((Lattice *)(obedit->data))->editlatt->latt; + + LatticeSelectionMap *lsm = BKE_lattice_selection_map_new(lt); + LatticeSelectionIter *lsi = BKE_lattice_selection_begin_iter(); + + BPoint *bp = lt->def; + + while (BKE_lattice_selection_iter_through(lsm, lsi, SELECT)){ + if(__unselectable_vertex_on_less(lsm, lsi->u, lsi->v, lsi->w)){ + bp[LT_INDEX(lt, lsi->u, lsi->v, lsi->w)].f1 ^= SELECT; + } + } + + BKE_lattice_selection_free_iter(lsi); + BKE_lattice_selection_map_free(lsm); + + WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data); + + return OPERATOR_FINISHED; +} + +void LATTICE_OT_select_less(struct wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Select Less"; + ot->idname = "LATTICE_OT_select_less"; + ot->description = "Deselect vertices at the boundary of each selection region"; + + /* api callbacks */ + ot->exec = lattice_select_less_exec; + ot->poll = ED_operator_editlattice; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + +} + /************************** Select Ungrouped Verts Operator *************************/ static int lattice_select_ungrouped_exec(bContext *C, wmOperator *op) @@ -368,21 +493,6 @@ LATTICE_FLIP_W = 2 } eLattice_FlipAxes; -/* Helper macro for accessing item at index (u, v, w) - * < lt: (Lattice) - * < U: (int) u-axis coordinate of point - * < V: (int) v-axis coordinate of point - * < W: (int) w-axis coordinate of point - * < dimU: (int) number of points per row or number of columns (U-Axis) - * < dimV: (int) number of rows (V-Axis) - * > returns: (BPoint *) pointer to BPoint at this index - */ -#define LATTICE_PT(lt, U, V, W, dimU, dimV) \ - ( (lt)->def + \ - ((dimU) * (dimV)) * (W) + \ - (dimU) * (V) + \ - (U) \ - ) /* Flip midpoint value so that relative distances between midpoint and neighbour-pair is maintained * ! Assumes that uvw <=> xyz (i.e. axis-aligned index-axes with coordinate-axes) Index: source/blender/editors/object/object_intern.h =================================================================== --- source/blender/editors/object/object_intern.h (revision 57762) +++ source/blender/editors/object/object_intern.h (working copy) @@ -141,6 +141,8 @@ void LATTICE_OT_select_ungrouped(struct wmOperatorType *ot); void LATTICE_OT_make_regular(struct wmOperatorType *ot); void LATTICE_OT_flip(struct wmOperatorType *ot); +void LATTICE_OT_select_more(struct wmOperatorType *ot); +void LATTICE_OT_select_less(struct wmOperatorType *ot); /* object_group.c */ void GROUP_OT_create(struct wmOperatorType *ot);