From c78ebf9f26d01fcc3cf16baa9da922ee183f4b09 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 19 Mar 2018 14:49:59 +0100 Subject: Cleanup: split lattice into own library Was mixed with object functionality. --- source/blender/editors/CMakeLists.txt | 1 + source/blender/editors/include/ED_lattice.h | 18 +- source/blender/editors/include/ED_object.h | 8 - source/blender/editors/lattice/CMakeLists.txt | 45 + .../blender/editors/lattice/editlattice_select.c | 558 ++++++++++++ source/blender/editors/lattice/editlattice_tools.c | 340 +++++++ source/blender/editors/lattice/editlattice_undo.c | 113 +++ source/blender/editors/lattice/lattice_intern.h | 44 + source/blender/editors/lattice/lattice_ops.c | 80 ++ source/blender/editors/object/CMakeLists.txt | 1 - source/blender/editors/object/object_edit.c | 7 +- source/blender/editors/object/object_intern.h | 10 - source/blender/editors/object/object_lattice.c | 985 --------------------- source/blender/editors/object/object_ops.c | 33 - source/blender/editors/space_api/spacetypes.c | 5 +- .../blender/editors/space_view3d/view3d_select.c | 1 + source/blender/editors/util/undo.c | 1 + 17 files changed, 1203 insertions(+), 1047 deletions(-) create mode 100644 source/blender/editors/lattice/CMakeLists.txt create mode 100644 source/blender/editors/lattice/editlattice_select.c create mode 100644 source/blender/editors/lattice/editlattice_tools.c create mode 100644 source/blender/editors/lattice/editlattice_undo.c create mode 100644 source/blender/editors/lattice/lattice_intern.h create mode 100644 source/blender/editors/lattice/lattice_ops.c delete mode 100644 source/blender/editors/object/object_lattice.c (limited to 'source/blender/editors') diff --git a/source/blender/editors/CMakeLists.txt b/source/blender/editors/CMakeLists.txt index 1559512d713..be8829b0418 100644 --- a/source/blender/editors/CMakeLists.txt +++ b/source/blender/editors/CMakeLists.txt @@ -29,6 +29,7 @@ if(WITH_BLENDER) add_subdirectory(gpencil) add_subdirectory(interface) add_subdirectory(io) + add_subdirectory(lattice) add_subdirectory(mask) add_subdirectory(mesh) add_subdirectory(metaball) diff --git a/source/blender/editors/include/ED_lattice.h b/source/blender/editors/include/ED_lattice.h index 30d66577770..b652fb4c00b 100644 --- a/source/blender/editors/include/ED_lattice.h +++ b/source/blender/editors/include/ED_lattice.h @@ -4,7 +4,7 @@ * 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. + * 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 @@ -18,7 +18,6 @@ * The Original Code is Copyright (C) 2008 Blender Foundation. * All rights reserved. * - * * Contributor(s): Blender Foundation * * ***** END GPL LICENSE BLOCK ***** @@ -31,10 +30,17 @@ #ifndef __ED_LATTICE_H__ #define __ED_LATTICE_H__ -struct Object; +struct wmKeyConfig; -void ED_lattice_editlatt_free(struct Object *ob); -void ED_lattice_editlatt_make(struct Object *obedit); -void ED_lattice_editlatt_load(struct Object *obedit); +/* lattice_ops.c */ +void ED_operatortypes_lattice(void); +void ED_keymap_lattice(struct wmKeyConfig *keyconf); + +/* editlattice_select.c */ +void ED_lattice_flags_set(struct Object *obedit, int flag); +bool ED_lattice_select_pick(struct bContext *C, const int mval[2], bool extend, bool deselect, bool toggle); + +/* editlattice_undo.c */ +void undo_push_lattice(struct bContext *C, const char *name); #endif /* __ED_LATTICE_H__ */ diff --git a/source/blender/editors/include/ED_object.h b/source/blender/editors/include/ED_object.h index dcc6d064f92..5b2fdf29dd5 100644 --- a/source/blender/editors/include/ED_object.h +++ b/source/blender/editors/include/ED_object.h @@ -192,14 +192,6 @@ void ED_object_constraint_dependency_update(struct Main *bmain, struct Object *o void ED_object_constraint_tag_update(struct Object *ob, struct bConstraint *con); void ED_object_constraint_dependency_tag_update(struct Main *bmain, struct Object *ob, struct bConstraint *con); -/* object_lattice.c */ -bool ED_lattice_select_pick(struct bContext *C, const int mval[2], bool extend, bool deselect, bool toggle); -void undo_push_lattice(struct bContext *C, const char *name); - -/* object_lattice.c */ - -void ED_lattice_flags_set(struct Object *obedit, int flag); - /* object_modes.c */ bool ED_object_mode_compat_test(const struct Object *ob, eObjectMode mode); bool ED_object_mode_compat_set(struct bContext *C, struct Object *ob, eObjectMode mode, struct ReportList *reports); diff --git a/source/blender/editors/lattice/CMakeLists.txt b/source/blender/editors/lattice/CMakeLists.txt new file mode 100644 index 00000000000..3bb954ddf46 --- /dev/null +++ b/source/blender/editors/lattice/CMakeLists.txt @@ -0,0 +1,45 @@ +# ***** 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. +# +# Contributor(s): Jacques Beaurain. +# +# ***** END GPL LICENSE BLOCK ***** + +set(INC + ../include + ../../blenkernel + ../../blenlib + ../../makesdna + ../../makesrna + ../../render/extern/include + ../../windowmanager + ../../../../intern/guardedalloc +) + +set(INC_SYS + +) + +set(SRC + editlattice_select.c + editlattice_tools.c + editlattice_undo.c + lattice_ops.c + + lattice_intern.h +) + +blender_add_lib(bf_editor_lattice "${SRC}" "${INC}" "${INC_SYS}") diff --git a/source/blender/editors/lattice/editlattice_select.c b/source/blender/editors/lattice/editlattice_select.c new file mode 100644 index 00000000000..d0d64b85195 --- /dev/null +++ b/source/blender/editors/lattice/editlattice_select.c @@ -0,0 +1,558 @@ +/* + * ***** 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. + * + * Contributor(s): Blender Foundation + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/editors/lattice/editlattice_select.c + * \ingroup edlattice + */ + +#include + +#include "MEM_guardedalloc.h" + +#include "BLI_listbase.h" +#include "BLI_math.h" +#include "BLI_utildefines.h" +#include "BLI_rand.h" +#include "BLI_bitmap.h" + +#include "DNA_curve_types.h" +#include "DNA_lattice_types.h" +#include "DNA_meshdata_types.h" +#include "DNA_object_types.h" +#include "DNA_scene_types.h" + +#include "RNA_access.h" +#include "RNA_define.h" +#include "RNA_enum_types.h" + +#include "BKE_context.h" +#include "BKE_lattice.h" +#include "BKE_report.h" + +#include "ED_screen.h" +#include "ED_lattice.h" +#include "ED_view3d.h" + +#include "WM_api.h" +#include "WM_types.h" + +#include "lattice_intern.h" + +/* -------------------------------------------------------------------- */ +/** \name Utility Functions + * \{ */ + +static void bpoint_select_set(BPoint *bp, bool select) +{ + if (select) { + if (!bp->hide) { + bp->f1 |= SELECT; + } + } + else { + bp->f1 &= ~SELECT; + } +} + +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Select Random Operator + * \{ */ + +static int lattice_select_random_exec(bContext *C, wmOperator *op) +{ + Object *obedit = CTX_data_edit_object(C); + Lattice *lt = ((Lattice *)obedit->data)->editlatt->latt; + + const float randfac = RNA_float_get(op->ptr, "percent") / 100.0f; + const int seed = WM_operator_properties_select_random_seed_increment_get(op); + const bool select = (RNA_enum_get(op->ptr, "action") == SEL_SELECT); + + RNG *rng = BLI_rng_new_srandom(seed); + + int tot; + BPoint *bp; + + tot = lt->pntsu * lt->pntsv * lt->pntsw; + bp = lt->def; + while (tot--) { + if (!bp->hide) { + if (BLI_rng_get_float(rng) < randfac) { + bpoint_select_set(bp, select); + } + } + bp++; + } + + if (select == false) { + lt->actbp = LT_ACTBP_NONE; + } + + BLI_rng_free(rng); + + WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data); + + return OPERATOR_FINISHED; +} + +void LATTICE_OT_select_random(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Select Random"; + ot->description = "Randomly select UVW control points"; + ot->idname = "LATTICE_OT_select_random"; + + /* api callbacks */ + ot->exec = lattice_select_random_exec; + ot->poll = ED_operator_editlattice; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + /* props */ + WM_operator_properties_select_random(ot); +} + +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Select Mirror Operator + * \{ */ + +static void ed_lattice_select_mirrored(Lattice *lt, const int axis, const bool extend) +{ + const int tot = lt->pntsu * lt->pntsv * lt->pntsw; + int i; + BPoint *bp; + BLI_bitmap *selpoints; + + bool flip_uvw[3] = {false}; + flip_uvw[axis] = true; + + /* we could flip this too */ + if (!extend) { + lt->actbp = LT_ACTBP_NONE; + } + + /* store "original" selection */ + selpoints = BLI_BITMAP_NEW(tot, __func__); + BKE_lattice_bitmap_from_flag(lt, selpoints, SELECT, false, false); + + /* actual (de)selection */ + for (i = 0; i < tot; i++) { + const int i_flip = BKE_lattice_index_flip(lt, i, flip_uvw[0], flip_uvw[1], flip_uvw[2]); + bp = <->def[i]; + if (!bp->hide) { + if (BLI_BITMAP_TEST(selpoints, i_flip)) { + bp->f1 |= SELECT; + } + else { + if (!extend) { + bp->f1 &= ~SELECT; + } + } + } + } + + + MEM_freeN(selpoints); +} + +static int lattice_select_mirror_exec(bContext *C, wmOperator *op) +{ + Object *obedit = CTX_data_edit_object(C); + Lattice *lt = ((Lattice *)obedit->data)->editlatt->latt; + const int axis_flag = RNA_enum_get(op->ptr, "axis"); + const bool extend = RNA_boolean_get(op->ptr, "extend"); + + for (int axis = 0; axis < 3; axis++) { + if ((1 << axis) & axis_flag) { + ed_lattice_select_mirrored(lt, axis, extend); + } + } + + WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data); + + return OPERATOR_FINISHED; +} + +void LATTICE_OT_select_mirror(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Select Mirror"; + ot->description = "Select mirrored lattice points"; + ot->idname = "LATTICE_OT_select_mirror"; + + /* api callbacks */ + ot->exec = lattice_select_mirror_exec; + ot->poll = ED_operator_editlattice; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + /* props */ + RNA_def_enum_flag(ot->srna, "axis", rna_enum_axis_flag_xyz_items, (1 << 0), "Axis", ""); + + RNA_def_boolean(ot->srna, "extend", false, "Extend", "Extend the selection"); +} + +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Select More/Less Operator + * \{ */ + +static bool lattice_test_bitmap_uvw(Lattice *lt, BLI_bitmap *selpoints, int u, int v, int w, const bool selected) +{ + if ((u < 0 || u >= lt->pntsu) || + (v < 0 || v >= lt->pntsv) || + (w < 0 || w >= lt->pntsw)) + { + return false; + } + else { + int i = BKE_lattice_index_from_uvw(lt, u, v, w); + if (lt->def[i].hide == 0) { + return (BLI_BITMAP_TEST(selpoints, i) != 0) == selected; + } + return false; + } +} + +static int lattice_select_more_less(bContext *C, const bool select) +{ + Object *obedit = CTX_data_edit_object(C); + Lattice *lt = ((Lattice *)obedit->data)->editlatt->latt; + BPoint *bp; + const int tot = lt->pntsu * lt->pntsv * lt->pntsw; + int u, v, w; + BLI_bitmap *selpoints; + + lt->actbp = LT_ACTBP_NONE; + + selpoints = BLI_BITMAP_NEW(tot, __func__); + BKE_lattice_bitmap_from_flag(lt, selpoints, SELECT, false, false); + + bp = lt->def; + for (w = 0; w < lt->pntsw; w++) { + for (v = 0; v < lt->pntsv; v++) { + for (u = 0; u < lt->pntsu; u++) { + if ((bp->hide == 0) && (((bp->f1 & SELECT) == 0) == select)) { + if (lattice_test_bitmap_uvw(lt, selpoints, u + 1, v, w, select) || + lattice_test_bitmap_uvw(lt, selpoints, u - 1, v, w, select) || + lattice_test_bitmap_uvw(lt, selpoints, u, v + 1, w, select) || + lattice_test_bitmap_uvw(lt, selpoints, u, v - 1, w, select) || + lattice_test_bitmap_uvw(lt, selpoints, u, v, w + 1, select) || + lattice_test_bitmap_uvw(lt, selpoints, u, v, w - 1, select)) + { + SET_FLAG_FROM_TEST(bp->f1, select, SELECT); + } + } + bp++; + } + } + } + + MEM_freeN(selpoints); + + WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data); + return OPERATOR_FINISHED; +} + +static int lattice_select_more_exec(bContext *C, wmOperator *UNUSED(op)) +{ + return lattice_select_more_less(C, true); +} + +static int lattice_select_less_exec(bContext *C, wmOperator *UNUSED(op)) +{ + return lattice_select_more_less(C, false); +} + +void LATTICE_OT_select_more(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Select More"; + ot->description = "Select vertex directly linked to already selected ones"; + ot->idname = "LATTICE_OT_select_more"; + + /* api callbacks */ + ot->exec = lattice_select_more_exec; + ot->poll = ED_operator_editlattice; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; +} + +void LATTICE_OT_select_less(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Select Less"; + ot->description = "Deselect vertices at the boundary of each selection region"; + ot->idname = "LATTICE_OT_select_less"; + + /* api callbacks */ + ot->exec = lattice_select_less_exec; + ot->poll = ED_operator_editlattice; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; +} + +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Select All Operator + * \{ */ + +void ED_lattice_flags_set(Object *obedit, int flag) +{ + Lattice *lt = obedit->data; + BPoint *bp; + int a; + + bp = lt->editlatt->latt->def; + + a = lt->editlatt->latt->pntsu * lt->editlatt->latt->pntsv * lt->editlatt->latt->pntsw; + lt->editlatt->latt->actbp = LT_ACTBP_NONE; + + while (a--) { + if (bp->hide == 0) { + bp->f1 = flag; + } + bp++; + } +} + +static int lattice_select_all_exec(bContext *C, wmOperator *op) +{ + Object *obedit = CTX_data_edit_object(C); + Lattice *lt = obedit->data; + BPoint *bp; + int a; + int action = RNA_enum_get(op->ptr, "action"); + + if (action == SEL_TOGGLE) { + action = SEL_SELECT; + + bp = lt->editlatt->latt->def; + a = lt->editlatt->latt->pntsu * lt->editlatt->latt->pntsv * lt->editlatt->latt->pntsw; + + while (a--) { + if (bp->hide == 0) { + if (bp->f1 & SELECT) { + action = SEL_DESELECT; + break; + } + } + bp++; + } + } + + switch (action) { + case SEL_SELECT: + ED_lattice_flags_set(obedit, 1); + break; + case SEL_DESELECT: + ED_lattice_flags_set(obedit, 0); + break; + case SEL_INVERT: + bp = lt->editlatt->latt->def; + a = lt->editlatt->latt->pntsu * lt->editlatt->latt->pntsv * lt->editlatt->latt->pntsw; + lt->editlatt->latt->actbp = LT_ACTBP_NONE; + + while (a--) { + if (bp->hide == 0) { + bp->f1 ^= SELECT; + } + bp++; + } + break; + } + + WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data); + + return OPERATOR_FINISHED; +} + +void LATTICE_OT_select_all(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "(De)select All"; + ot->description = "Change selection of all UVW control points"; + ot->idname = "LATTICE_OT_select_all"; + + /* api callbacks */ + ot->exec = lattice_select_all_exec; + ot->poll = ED_operator_editlattice; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + WM_operator_properties_select_all(ot); +} + +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Select Ungrouped Verts Operator + * \{ */ + +static int lattice_select_ungrouped_exec(bContext *C, wmOperator *op) +{ + Object *obedit = CTX_data_edit_object(C); + Lattice *lt = ((Lattice *)obedit->data)->editlatt->latt; + MDeformVert *dv; + BPoint *bp; + int a, tot; + + if (BLI_listbase_is_empty(&obedit->defbase) || lt->dvert == NULL) { + BKE_report(op->reports, RPT_ERROR, "No weights/vertex groups on object"); + return OPERATOR_CANCELLED; + } + + if (!RNA_boolean_get(op->ptr, "extend")) { + ED_lattice_flags_set(obedit, 0); + } + + dv = lt->dvert; + tot = lt->pntsu * lt->pntsv * lt->pntsw; + + for (a = 0, bp = lt->def; a < tot; a++, bp++, dv++) { + if (bp->hide == 0) { + if (dv->dw == NULL) { + bp->f1 |= SELECT; + } + } + } + + WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data); + + return OPERATOR_FINISHED; +} + +void LATTICE_OT_select_ungrouped(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Select Ungrouped"; + ot->idname = "LATTICE_OT_select_ungrouped"; + ot->description = "Select vertices without a group"; + + /* api callbacks */ + ot->exec = lattice_select_ungrouped_exec; + ot->poll = ED_operator_editlattice; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + RNA_def_boolean(ot->srna, "extend", false, "Extend", "Extend the selection"); +} + +/** \} */ + + +/* -------------------------------------------------------------------- */ +/** \name Select Picking API + * + * Here actual select happens, + * Gets called via generic mouse select operator. + * \{ */ + + +static void findnearestLattvert__doClosest(void *userData, BPoint *bp, const float screen_co[2]) +{ + struct { BPoint *bp; float dist; int select; float mval_fl[2]; } *data = userData; + float dist_test = len_manhattan_v2v2(data->mval_fl, screen_co); + + if ((bp->f1 & SELECT) && data->select) + dist_test += 5.0f; + + if (dist_test < data->dist) { + data->dist = dist_test; + + data->bp = bp; + } +} + +static BPoint *findnearestLattvert(ViewContext *vc, const int mval[2], int sel) +{ + /* (sel == 1): selected gets a disadvantage */ + /* in nurb and bezt or bp the nearest is written */ + /* return 0 1 2: handlepunt */ + struct { BPoint *bp; float dist; int select; float mval_fl[2]; } data = {NULL}; + + data.dist = ED_view3d_select_dist_px(); + data.select = sel; + data.mval_fl[0] = mval[0]; + data.mval_fl[1] = mval[1]; + + ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); + lattice_foreachScreenVert(vc, findnearestLattvert__doClosest, &data, V3D_PROJ_TEST_CLIP_DEFAULT); + + return data.bp; +} + +bool ED_lattice_select_pick(bContext *C, const int mval[2], bool extend, bool deselect, bool toggle) +{ + ViewContext vc; + BPoint *bp = NULL; + Lattice *lt; + + ED_view3d_viewcontext_init(C, &vc); + lt = ((Lattice *)vc.obedit->data)->editlatt->latt; + bp = findnearestLattvert(&vc, mval, true); + + if (bp) { + if (extend) { + bp->f1 |= SELECT; + } + else if (deselect) { + bp->f1 &= ~SELECT; + } + else if (toggle) { + bp->f1 ^= SELECT; /* swap */ + } + else { + ED_lattice_flags_set(vc.obedit, 0); + bp->f1 |= SELECT; + } + + if (bp->f1 & SELECT) { + lt->actbp = bp - lt->def; + } + else { + lt->actbp = LT_ACTBP_NONE; + } + + WM_event_add_notifier(C, NC_GEOM | ND_SELECT, vc.obedit->data); + + return true; + } + + return false; +} + +/** \} */ diff --git a/source/blender/editors/lattice/editlattice_tools.c b/source/blender/editors/lattice/editlattice_tools.c new file mode 100644 index 00000000000..c39ba44c1dc --- /dev/null +++ b/source/blender/editors/lattice/editlattice_tools.c @@ -0,0 +1,340 @@ +/* + * ***** 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. + * + * Contributor(s): Blender Foundation + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/editors/lattice/editlattice_tools.c + * \ingroup edlattice + */ + +#include "BLI_math.h" +#include "BLI_utildefines.h" + +#include "DNA_curve_types.h" +#include "DNA_lattice_types.h" +#include "DNA_object_types.h" +#include "DNA_scene_types.h" + +#include "RNA_access.h" +#include "RNA_define.h" + +#include "BKE_context.h" +#include "BKE_depsgraph.h" +#include "BKE_lattice.h" + +#include "ED_screen.h" + +#include "WM_api.h" +#include "WM_types.h" + +#include "lattice_intern.h" + +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Make Regular Operator + * \{ */ + +static int make_regular_poll(bContext *C) +{ + Object *ob; + + if (ED_operator_editlattice(C)) return 1; + + ob = CTX_data_active_object(C); + return (ob && ob->type == OB_LATTICE); +} + +static int make_regular_exec(bContext *C, wmOperator *UNUSED(op)) +{ + Object *ob = CTX_data_edit_object(C); + Lattice *lt; + + if (ob) { + lt = ob->data; + BKE_lattice_resize(lt->editlatt->latt, lt->pntsu, lt->pntsv, lt->pntsw, NULL); + } + else { + ob = CTX_data_active_object(C); + lt = ob->data; + BKE_lattice_resize(lt, lt->pntsu, lt->pntsv, lt->pntsw, NULL); + } + + DAG_id_tag_update(&ob->id, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_GEOM | ND_DATA, ob->data); + + return OPERATOR_FINISHED; +} + +void LATTICE_OT_make_regular(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Make Regular"; + ot->description = "Set UVW control points a uniform distance apart"; + ot->idname = "LATTICE_OT_make_regular"; + + /* api callbacks */ + ot->exec = make_regular_exec; + ot->poll = make_regular_poll; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; +} + +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Flip Verts Operator + * \{ */ + +/* flipping options */ +typedef enum eLattice_FlipAxes { + LATTICE_FLIP_U = 0, + LATTICE_FLIP_V = 1, + LATTICE_FLIP_W = 2 +} eLattice_FlipAxes; + +/** + * Flip midpoint value so that relative distances between midpoint and neighbor-pair is maintained + * ! Assumes that uvw <=> xyz (i.e. axis-aligned index-axes with coordinate-axes) + * - Helper for lattice_flip_exec() + */ +static void lattice_flip_point_value(Lattice *lt, int u, int v, int w, float mid, eLattice_FlipAxes axis) +{ + BPoint *bp; + float diff; + + /* just the point in the middle (unpaired) */ + bp = <->def[BKE_lattice_index_from_uvw(lt, u, v, w)]; + + /* flip over axis */ + diff = mid - bp->vec[axis]; + bp->vec[axis] = mid + diff; +} + +/** + * Swap pairs of lattice points along a specified axis + * - Helper for lattice_flip_exec() + */ +static void lattice_swap_point_pairs(Lattice *lt, int u, int v, int w, float mid, eLattice_FlipAxes axis) +{ + BPoint *bpA, *bpB; + + int numU = lt->pntsu; + int numV = lt->pntsv; + int numW = lt->pntsw; + + int u0 = u, u1 = u; + int v0 = v, v1 = v; + int w0 = w, w1 = w; + + /* get pair index by just overriding the relevant pair-value + * - "-1" else buffer overflow + */ + switch (axis) { + case LATTICE_FLIP_U: + u1 = numU - u - 1; + break; + case LATTICE_FLIP_V: + v1 = numV - v - 1; + break; + case LATTICE_FLIP_W: + w1 = numW - w - 1; + break; + } + + /* get points to operate on */ + bpA = <->def[BKE_lattice_index_from_uvw(lt, u0, v0, w0)]; + bpB = <->def[BKE_lattice_index_from_uvw(lt, u1, v1, w1)]; + + /* Swap all coordinates, so that flipped coordinates belong to + * the indices on the correct side of the lattice. + * + * Coords: (-2 4) |0| (3 4) --> (3 4) |0| (-2 4) + * Indices: (0,L) (1,R) --> (0,L) (1,R) + */ + swap_v3_v3(bpA->vec, bpB->vec); + + /* However, we need to mirror the coordinate values on the axis we're dealing with, + * otherwise we'd have effectively only rotated the points around. If we don't do this, + * we'd just be reimplementing the naive mirroring algorithm, which causes unwanted deforms + * such as flipped normals, etc. + * + * Coords: (3 4) |0| (-2 4) --\ + * \-> (-3 4) |0| (2 4) + * Indices: (0,L) (1,R) --> (0,L) (1,R) + */ + lattice_flip_point_value(lt, u0, v0, w0, mid, axis); + lattice_flip_point_value(lt, u1, v1, w1, mid, axis); +} + +static int lattice_flip_exec(bContext *C, wmOperator *op) +{ + Object *obedit = CTX_data_edit_object(C); + Lattice *lt; + + eLattice_FlipAxes axis = RNA_enum_get(op->ptr, "axis"); + int numU, numV, numW; + int totP; + + float mid = 0.0f; + short isOdd = 0; + + /* get lattice - we need the "edit lattice" from the lattice... confusing... */ + lt = (Lattice *)obedit->data; + lt = lt->editlatt->latt; + + numU = lt->pntsu; + numV = lt->pntsv; + numW = lt->pntsw; + totP = numU * numV * numW; + + /* First Pass: determine midpoint - used for flipping center verts if there are odd number of points on axis */ + switch (axis) { + case LATTICE_FLIP_U: + isOdd = numU & 1; + break; + case LATTICE_FLIP_V: + isOdd = numV & 1; + break; + case LATTICE_FLIP_W: + isOdd = numW & 1; + break; + + default: + printf("lattice_flip(): Unknown flipping axis (%u)\n", axis); + return OPERATOR_CANCELLED; + } + + if (isOdd) { + BPoint *bp; + float avgInv = 1.0f / (float)totP; + int i; + + /* midpoint calculation - assuming that u/v/w are axis-aligned */ + for (i = 0, bp = lt->def; i < totP; i++, bp++) { + mid += bp->vec[axis] * avgInv; + } + } + + /* Second Pass: swap pairs of vertices per axis, assuming they are all sorted */ + switch (axis) { + case LATTICE_FLIP_U: + { + int u, v, w; + + /* v/w strips - front to back, top to bottom */ + for (w = 0; w < numW; w++) { + for (v = 0; v < numV; v++) { + /* swap coordinates of pairs of vertices on u */ + for (u = 0; u < (numU / 2); u++) { + lattice_swap_point_pairs(lt, u, v, w, mid, axis); + } + + /* flip u-coordinate of midpoint (i.e. unpaired point on u) */ + if (isOdd) { + u = (numU / 2); + lattice_flip_point_value(lt, u, v, w, mid, axis); + } + } + } + break; + } + case LATTICE_FLIP_V: + { + int u, v, w; + + /* u/w strips - front to back, left to right */ + for (w = 0; w < numW; w++) { + for (u = 0; u < numU; u++) { + /* swap coordinates of pairs of vertices on v */ + for (v = 0; v < (numV / 2); v++) { + lattice_swap_point_pairs(lt, u, v, w, mid, axis); + } + + /* flip v-coordinate of midpoint (i.e. unpaired point on v) */ + if (isOdd) { + v = (numV / 2); + lattice_flip_point_value(lt, u, v, w, mid, axis); + } + } + } + break; + } + case LATTICE_FLIP_W: + { + int u, v, w; + + for (v = 0; v < numV; v++) { + for (u = 0; u < numU; u++) { + /* swap coordinates of pairs of vertices on w */ + for (w = 0; w < (numW / 2); w++) { + lattice_swap_point_pairs(lt, u, v, w, mid, axis); + } + + /* flip w-coordinate of midpoint (i.e. unpaired point on w) */ + if (isOdd) { + w = (numW / 2); + lattice_flip_point_value(lt, u, v, w, mid, axis); + } + } + } + break; + } + default: /* shouldn't happen, but just in case */ + break; + } + + /* updates */ + DAG_id_tag_update(&obedit->id, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data); + + return OPERATOR_FINISHED; +} + +void LATTICE_OT_flip(wmOperatorType *ot) +{ + static const EnumPropertyItem flip_items[] = { + {LATTICE_FLIP_U, "U", 0, "U (X) Axis", ""}, + {LATTICE_FLIP_V, "V", 0, "V (Y) Axis", ""}, + {LATTICE_FLIP_W, "W", 0, "W (Z) Axis", ""}, + {0, NULL, 0, NULL, NULL}}; + + /* identifiers */ + ot->name = "Flip (Distortion Free)"; + ot->description = "Mirror all control points without inverting the lattice deform"; + ot->idname = "LATTICE_OT_flip"; + + /* api callbacks */ + ot->poll = ED_operator_editlattice; + ot->invoke = WM_menu_invoke; + ot->exec = lattice_flip_exec; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + /* properties */ + ot->prop = RNA_def_enum(ot->srna, "axis", flip_items, LATTICE_FLIP_U, "Flip Axis", "Coordinates along this axis get flipped"); +} + +/** \} */ diff --git a/source/blender/editors/lattice/editlattice_undo.c b/source/blender/editors/lattice/editlattice_undo.c new file mode 100644 index 00000000000..aa817928f92 --- /dev/null +++ b/source/blender/editors/lattice/editlattice_undo.c @@ -0,0 +1,113 @@ +/* + * ***** 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. + * + * Contributor(s): Blender Foundation + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/editors/lattice/editlattice_undo.c + * \ingroup edlattice + */ + +#include +#include +#include + +#include "MEM_guardedalloc.h" + +#include "BLI_utildefines.h" + +#include "DNA_curve_types.h" +#include "DNA_lattice_types.h" +#include "DNA_object_types.h" +#include "DNA_scene_types.h" + +#include "BKE_context.h" + +#include "ED_lattice.h" +#include "ED_util.h" + +#include "lattice_intern.h" + +typedef struct UndoLattice { + BPoint *def; + int pntsu, pntsv, pntsw, actbp; +} UndoLattice; + +static void undoLatt_to_editLatt(void *data, void *edata, void *UNUSED(obdata)) +{ + UndoLattice *ult = (UndoLattice *)data; + EditLatt *editlatt = (EditLatt *)edata; + int a = editlatt->latt->pntsu * editlatt->latt->pntsv * editlatt->latt->pntsw; + + memcpy(editlatt->latt->def, ult->def, a * sizeof(BPoint)); + editlatt->latt->actbp = ult->actbp; +} + +static void *editLatt_to_undoLatt(void *edata, void *UNUSED(obdata)) +{ + UndoLattice *ult = MEM_callocN(sizeof(UndoLattice), "UndoLattice"); + EditLatt *editlatt = (EditLatt *)edata; + + ult->def = MEM_dupallocN(editlatt->latt->def); + ult->pntsu = editlatt->latt->pntsu; + ult->pntsv = editlatt->latt->pntsv; + ult->pntsw = editlatt->latt->pntsw; + ult->actbp = editlatt->latt->actbp; + + return ult; +} + +static void free_undoLatt(void *data) +{ + UndoLattice *ult = (UndoLattice *)data; + + if (ult->def) MEM_freeN(ult->def); + MEM_freeN(ult); +} + +static int validate_undoLatt(void *data, void *edata) +{ + UndoLattice *ult = (UndoLattice *)data; + EditLatt *editlatt = (EditLatt *)edata; + + return (ult->pntsu == editlatt->latt->pntsu && + ult->pntsv == editlatt->latt->pntsv && + ult->pntsw == editlatt->latt->pntsw); +} + +static void *get_editlatt(bContext *C) +{ + Object *obedit = CTX_data_edit_object(C); + + if (obedit && obedit->type == OB_LATTICE) { + Lattice *lt = obedit->data; + return lt->editlatt; + } + + return NULL; +} + +/* and this is all the undo system needs to know */ +void undo_push_lattice(bContext *C, const char *name) +{ + undo_editmode_push(C, name, get_editlatt, free_undoLatt, undoLatt_to_editLatt, editLatt_to_undoLatt, validate_undoLatt); +} diff --git a/source/blender/editors/lattice/lattice_intern.h b/source/blender/editors/lattice/lattice_intern.h new file mode 100644 index 00000000000..94f528a0457 --- /dev/null +++ b/source/blender/editors/lattice/lattice_intern.h @@ -0,0 +1,44 @@ +/* + * ***** 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) 2008 Blender Foundation. + * All rights reserved. + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/editors/metaball/lattice_intern.h + * \ingroup edlattice + */ + + +#ifndef __LATTICE_INTERN_H__ +#define __LATTICE_INTERN_H__ + +/* editlattice_select.c */ +void LATTICE_OT_select_all(struct wmOperatorType *ot); +void LATTICE_OT_select_more(struct wmOperatorType *ot); +void LATTICE_OT_select_less(struct wmOperatorType *ot); +void LATTICE_OT_select_ungrouped(struct wmOperatorType *ot); +void LATTICE_OT_select_random(struct wmOperatorType *ot); +void LATTICE_OT_select_mirror(struct wmOperatorType *ot); + +/* editlattice_tools.c */ +void LATTICE_OT_make_regular(struct wmOperatorType *ot); +void LATTICE_OT_flip(struct wmOperatorType *ot); + +#endif /* __LATTICE_INTERN_H__ */ diff --git a/source/blender/editors/lattice/lattice_ops.c b/source/blender/editors/lattice/lattice_ops.c new file mode 100644 index 00000000000..37a10cbe12a --- /dev/null +++ b/source/blender/editors/lattice/lattice_ops.c @@ -0,0 +1,80 @@ +/* + * ***** 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) 2008 Blender Foundation. + * All rights reserved. + * + * + * Contributor(s): Blender Foundation + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/editors/metaball/lattice_ops.c + * \ingroup edlattice + */ + +#include "DNA_scene_types.h" + +#include "RNA_access.h" + +#include "WM_api.h" +#include "WM_types.h" + +#include "ED_screen.h" +#include "ED_object.h" +#include "ED_lattice.h" + +#include "lattice_intern.h" + +void ED_operatortypes_lattice(void) +{ + WM_operatortype_append(LATTICE_OT_select_all); + WM_operatortype_append(LATTICE_OT_select_more); + WM_operatortype_append(LATTICE_OT_select_less); + WM_operatortype_append(LATTICE_OT_select_ungrouped); + WM_operatortype_append(LATTICE_OT_select_random); + WM_operatortype_append(LATTICE_OT_select_mirror); + WM_operatortype_append(LATTICE_OT_make_regular); + WM_operatortype_append(LATTICE_OT_flip); +} + +void ED_keymap_lattice(wmKeyConfig *keyconf) +{ + wmKeyMap *keymap; + wmKeyMapItem *kmi; + + keymap = WM_keymap_find(keyconf, "Lattice", 0, 0); + keymap->poll = ED_operator_editlattice; + + kmi = WM_keymap_add_item(keymap, "LATTICE_OT_select_all", AKEY, KM_PRESS, 0, 0); + RNA_enum_set(kmi->ptr, "action", SEL_TOGGLE); + kmi = WM_keymap_add_item(keymap, "LATTICE_OT_select_all", IKEY, KM_PRESS, KM_CTRL, 0); + RNA_enum_set(kmi->ptr, "action", SEL_INVERT); + 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); + + WM_keymap_add_item(keymap, "OBJECT_OT_vertex_parent_set", PKEY, KM_PRESS, KM_CTRL, 0); + + WM_keymap_add_item(keymap, "LATTICE_OT_flip", FKEY, KM_PRESS, KM_CTRL, 0); + + /* menus */ + WM_keymap_add_menu(keymap, "VIEW3D_MT_hook", HKEY, KM_PRESS, KM_CTRL, 0); + + ED_keymap_proportional_cycle(keyconf, keymap); + ED_keymap_proportional_editmode(keyconf, keymap, false); +} diff --git a/source/blender/editors/object/CMakeLists.txt b/source/blender/editors/object/CMakeLists.txt index a2d3a3ede07..24740a3372b 100644 --- a/source/blender/editors/object/CMakeLists.txt +++ b/source/blender/editors/object/CMakeLists.txt @@ -48,7 +48,6 @@ set(SRC object_edit.c object_group.c object_hook.c - object_lattice.c object_lod.c object_modes.c object_modifier.c diff --git a/source/blender/editors/object/object_edit.c b/source/blender/editors/object/object_edit.c index add2ab98652..f67ecbce1d0 100644 --- a/source/blender/editors/object/object_edit.c +++ b/source/blender/editors/object/object_edit.c @@ -82,6 +82,7 @@ #include "BKE_sca.h" #include "BKE_softbody.h" #include "BKE_modifier.h" +#include "BKE_editlattice.h" #include "BKE_editmesh.h" #include "BKE_report.h" @@ -416,9 +417,9 @@ static bool ED_object_editmode_load_ex(Main *bmain, Object *obedit, const bool f if (lt->editlatt == NULL) { return false; } - ED_lattice_editlatt_load(obedit); + BKE_editlattice_load(obedit); if (freedata) { - ED_lattice_editlatt_free(obedit); + BKE_editlattice_free(obedit); } } else if (obedit->type == OB_MBALL) { @@ -615,7 +616,7 @@ void ED_object_editmode_enter(bContext *C, int flag) else if (ob->type == OB_LATTICE) { scene->obedit = ob; /* XXX for context */ ok = 1; - ED_lattice_editlatt_make(ob); + BKE_editlattice_make(ob); WM_event_add_notifier(C, NC_SCENE | ND_MODE | NS_EDITMODE_LATTICE, scene); } diff --git a/source/blender/editors/object/object_intern.h b/source/blender/editors/object/object_intern.h index b8957bdedf9..d9524f40a3c 100644 --- a/source/blender/editors/object/object_intern.h +++ b/source/blender/editors/object/object_intern.h @@ -140,16 +140,6 @@ void OBJECT_OT_hook_assign(struct wmOperatorType *ot); void OBJECT_OT_hook_reset(struct wmOperatorType *ot); void OBJECT_OT_hook_recenter(struct wmOperatorType *ot); -/* object_lattice.c */ -void LATTICE_OT_select_all(struct wmOperatorType *ot); -void LATTICE_OT_select_more(struct wmOperatorType *ot); -void LATTICE_OT_select_less(struct wmOperatorType *ot); -void LATTICE_OT_select_ungrouped(struct wmOperatorType *ot); -void LATTICE_OT_select_random(struct wmOperatorType *ot); -void LATTICE_OT_select_mirror(struct wmOperatorType *ot); -void LATTICE_OT_make_regular(struct wmOperatorType *ot); -void LATTICE_OT_flip(struct wmOperatorType *ot); - /* object_group.c */ void GROUP_OT_create(struct wmOperatorType *ot); void GROUP_OT_objects_remove_all(struct wmOperatorType *ot); diff --git a/source/blender/editors/object/object_lattice.c b/source/blender/editors/object/object_lattice.c deleted file mode 100644 index 008ad62b39e..00000000000 --- a/source/blender/editors/object/object_lattice.c +++ /dev/null @@ -1,985 +0,0 @@ -/* - * ***** 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. - * - * Contributor(s): Blender Foundation - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file blender/editors/object/object_lattice.c - * \ingroup edobj - */ - - -#include -#include -#include - -#include "MEM_guardedalloc.h" - -#include "BLI_listbase.h" -#include "BLI_math.h" -#include "BLI_utildefines.h" -#include "BLI_rand.h" -#include "BLI_bitmap.h" - -#include "DNA_curve_types.h" -#include "DNA_key_types.h" -#include "DNA_lattice_types.h" -#include "DNA_meshdata_types.h" -#include "DNA_object_types.h" -#include "DNA_scene_types.h" - -#include "RNA_access.h" -#include "RNA_define.h" -#include "RNA_enum_types.h" - -#include "BKE_context.h" -#include "BKE_depsgraph.h" -#include "BKE_key.h" -#include "BKE_lattice.h" -#include "BKE_deform.h" -#include "BKE_report.h" - -#include "ED_lattice.h" -#include "ED_object.h" -#include "ED_screen.h" -#include "ED_view3d.h" -#include "ED_util.h" - -#include "WM_api.h" -#include "WM_types.h" - -#include "object_intern.h" - -/********************** Load/Make/Free ********************/ - -void ED_lattice_editlatt_free(Object *ob) -{ - Lattice *lt = ob->data; - - if (lt->editlatt) { - Lattice *editlt = lt->editlatt->latt; - - if (editlt->def) - MEM_freeN(editlt->def); - if (editlt->dvert) - BKE_defvert_array_free(editlt->dvert, editlt->pntsu * editlt->pntsv * editlt->pntsw); - - MEM_freeN(editlt); - MEM_freeN(lt->editlatt); - - lt->editlatt = NULL; - } -} - -void ED_lattice_editlatt_make(Object *obedit) -{ - Lattice *lt = obedit->data; - KeyBlock *actkey; - - ED_lattice_editlatt_free(obedit); - - actkey = BKE_keyblock_from_object(obedit); - if (actkey) - BKE_keyblock_convert_to_lattice(actkey, lt); - - lt->editlatt = MEM_callocN(sizeof(EditLatt), "editlatt"); - lt->editlatt->latt = MEM_dupallocN(lt); - lt->editlatt->latt->def = MEM_dupallocN(lt->def); - - if (lt->dvert) { - int tot = lt->pntsu * lt->pntsv * lt->pntsw; - lt->editlatt->latt->dvert = MEM_mallocN(sizeof(MDeformVert) * tot, "Lattice MDeformVert"); - BKE_defvert_array_copy(lt->editlatt->latt->dvert, lt->dvert, tot); - } - - if (lt->key) lt->editlatt->shapenr = obedit->shapenr; -} - -void ED_lattice_editlatt_load(Object *obedit) -{ - Lattice *lt, *editlt; - KeyBlock *actkey; - BPoint *bp; - float *fp; - int tot; - - lt = obedit->data; - editlt = lt->editlatt->latt; - - if (lt->editlatt->shapenr) { - actkey = BLI_findlink(<->key->block, lt->editlatt->shapenr - 1); - - /* active key: vertices */ - tot = editlt->pntsu * editlt->pntsv * editlt->pntsw; - - if (actkey->data) MEM_freeN(actkey->data); - - fp = actkey->data = MEM_callocN(lt->key->elemsize * tot, "actkey->data"); - actkey->totelem = tot; - - bp = editlt->def; - while (tot--) { - copy_v3_v3(fp, bp->vec); - fp += 3; - bp++; - } - } - else { - MEM_freeN(lt->def); - - lt->def = MEM_dupallocN(editlt->def); - - lt->flag = editlt->flag; - - lt->pntsu = editlt->pntsu; - lt->pntsv = editlt->pntsv; - lt->pntsw = editlt->pntsw; - - lt->typeu = editlt->typeu; - lt->typev = editlt->typev; - lt->typew = editlt->typew; - lt->actbp = editlt->actbp; - } - - if (lt->dvert) { - BKE_defvert_array_free(lt->dvert, lt->pntsu * lt->pntsv * lt->pntsw); - lt->dvert = NULL; - } - - if (editlt->dvert) { - tot = lt->pntsu * lt->pntsv * lt->pntsw; - - lt->dvert = MEM_mallocN(sizeof(MDeformVert) * tot, "Lattice MDeformVert"); - BKE_defvert_array_copy(lt->dvert, editlt->dvert, tot); - } -} - -static void bpoint_select_set(BPoint *bp, bool select) -{ - if (select) { - if (!bp->hide) { - bp->f1 |= SELECT; - } - } - else { - bp->f1 &= ~SELECT; - } -} - -/************************** Select Random Operator **********************/ - -static int lattice_select_random_exec(bContext *C, wmOperator *op) -{ - Object *obedit = CTX_data_edit_object(C); - Lattice *lt = ((Lattice *)obedit->data)->editlatt->latt; - - const float randfac = RNA_float_get(op->ptr, "percent") / 100.0f; - const int seed = WM_operator_properties_select_random_seed_increment_get(op); - const bool select = (RNA_enum_get(op->ptr, "action") == SEL_SELECT); - - RNG *rng = BLI_rng_new_srandom(seed); - - int tot; - BPoint *bp; - - tot = lt->pntsu * lt->pntsv * lt->pntsw; - bp = lt->def; - while (tot--) { - if (!bp->hide) { - if (BLI_rng_get_float(rng) < randfac) { - bpoint_select_set(bp, select); - } - } - bp++; - } - - if (select == false) { - lt->actbp = LT_ACTBP_NONE; - } - - BLI_rng_free(rng); - - WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data); - - return OPERATOR_FINISHED; -} - -void LATTICE_OT_select_random(wmOperatorType *ot) -{ - /* identifiers */ - ot->name = "Select Random"; - ot->description = "Randomly select UVW control points"; - ot->idname = "LATTICE_OT_select_random"; - - /* api callbacks */ - ot->exec = lattice_select_random_exec; - ot->poll = ED_operator_editlattice; - - /* flags */ - ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; - - /* props */ - WM_operator_properties_select_random(ot); -} - - -/* -------------------------------------------------------------------- */ -/* Select Mirror Operator */ - -static void ed_lattice_select_mirrored(Lattice *lt, const int axis, const bool extend) -{ - const int tot = lt->pntsu * lt->pntsv * lt->pntsw; - int i; - BPoint *bp; - BLI_bitmap *selpoints; - - bool flip_uvw[3] = {false}; - flip_uvw[axis] = true; - - /* we could flip this too */ - if (!extend) { - lt->actbp = LT_ACTBP_NONE; - } - - /* store "original" selection */ - selpoints = BLI_BITMAP_NEW(tot, __func__); - BKE_lattice_bitmap_from_flag(lt, selpoints, SELECT, false, false); - - /* actual (de)selection */ - for (i = 0; i < tot; i++) { - const int i_flip = BKE_lattice_index_flip(lt, i, flip_uvw[0], flip_uvw[1], flip_uvw[2]); - bp = <->def[i]; - if (!bp->hide) { - if (BLI_BITMAP_TEST(selpoints, i_flip)) { - bp->f1 |= SELECT; - } - else { - if (!extend) { - bp->f1 &= ~SELECT; - } - } - } - } - - - MEM_freeN(selpoints); -} - -static int lattice_select_mirror_exec(bContext *C, wmOperator *op) -{ - Object *obedit = CTX_data_edit_object(C); - Lattice *lt = ((Lattice *)obedit->data)->editlatt->latt; - const int axis_flag = RNA_enum_get(op->ptr, "axis"); - const bool extend = RNA_boolean_get(op->ptr, "extend"); - - for (int axis = 0; axis < 3; axis++) { - if ((1 << axis) & axis_flag) { - ed_lattice_select_mirrored(lt, axis, extend); - } - } - - WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data); - - return OPERATOR_FINISHED; -} - -void LATTICE_OT_select_mirror(wmOperatorType *ot) -{ - /* identifiers */ - ot->name = "Select Mirror"; - ot->description = "Select mirrored lattice points"; - ot->idname = "LATTICE_OT_select_mirror"; - - /* api callbacks */ - ot->exec = lattice_select_mirror_exec; - ot->poll = ED_operator_editlattice; - - /* flags */ - ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; - - /* props */ - RNA_def_enum_flag(ot->srna, "axis", rna_enum_axis_flag_xyz_items, (1 << 0), "Axis", ""); - - RNA_def_boolean(ot->srna, "extend", false, "Extend", "Extend the selection"); -} - - -/************************** Select More/Less Operator *************************/ - -static bool lattice_test_bitmap_uvw(Lattice *lt, BLI_bitmap *selpoints, int u, int v, int w, const bool selected) -{ - if ((u < 0 || u >= lt->pntsu) || - (v < 0 || v >= lt->pntsv) || - (w < 0 || w >= lt->pntsw)) - { - return false; - } - else { - int i = BKE_lattice_index_from_uvw(lt, u, v, w); - if (lt->def[i].hide == 0) { - return (BLI_BITMAP_TEST(selpoints, i) != 0) == selected; - } - return false; - } -} - -static int lattice_select_more_less(bContext *C, const bool select) -{ - Object *obedit = CTX_data_edit_object(C); - Lattice *lt = ((Lattice *)obedit->data)->editlatt->latt; - BPoint *bp; - const int tot = lt->pntsu * lt->pntsv * lt->pntsw; - int u, v, w; - BLI_bitmap *selpoints; - - lt->actbp = LT_ACTBP_NONE; - - selpoints = BLI_BITMAP_NEW(tot, __func__); - BKE_lattice_bitmap_from_flag(lt, selpoints, SELECT, false, false); - - bp = lt->def; - for (w = 0; w < lt->pntsw; w++) { - for (v = 0; v < lt->pntsv; v++) { - for (u = 0; u < lt->pntsu; u++) { - if ((bp->hide == 0) && (((bp->f1 & SELECT) == 0) == select)) { - if (lattice_test_bitmap_uvw(lt, selpoints, u + 1, v, w, select) || - lattice_test_bitmap_uvw(lt, selpoints, u - 1, v, w, select) || - lattice_test_bitmap_uvw(lt, selpoints, u, v + 1, w, select) || - lattice_test_bitmap_uvw(lt, selpoints, u, v - 1, w, select) || - lattice_test_bitmap_uvw(lt, selpoints, u, v, w + 1, select) || - lattice_test_bitmap_uvw(lt, selpoints, u, v, w - 1, select)) - { - SET_FLAG_FROM_TEST(bp->f1, select, SELECT); - } - } - bp++; - } - } - } - - MEM_freeN(selpoints); - - WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data); - return OPERATOR_FINISHED; -} - -static int lattice_select_more_exec(bContext *C, wmOperator *UNUSED(op)) -{ - return lattice_select_more_less(C, true); -} - -static int lattice_select_less_exec(bContext *C, wmOperator *UNUSED(op)) -{ - return lattice_select_more_less(C, false); -} - -void LATTICE_OT_select_more(wmOperatorType *ot) -{ - /* identifiers */ - ot->name = "Select More"; - ot->description = "Select vertex directly linked to already selected ones"; - ot->idname = "LATTICE_OT_select_more"; - - /* api callbacks */ - ot->exec = lattice_select_more_exec; - ot->poll = ED_operator_editlattice; - - /* flags */ - ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; -} - -void LATTICE_OT_select_less(wmOperatorType *ot) -{ - /* identifiers */ - ot->name = "Select Less"; - ot->description = "Deselect vertices at the boundary of each selection region"; - ot->idname = "LATTICE_OT_select_less"; - - /* api callbacks */ - ot->exec = lattice_select_less_exec; - ot->poll = ED_operator_editlattice; - - /* flags */ - ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; -} - -/************************** Select All Operator *************************/ - -void ED_lattice_flags_set(Object *obedit, int flag) -{ - Lattice *lt = obedit->data; - BPoint *bp; - int a; - - bp = lt->editlatt->latt->def; - - a = lt->editlatt->latt->pntsu * lt->editlatt->latt->pntsv * lt->editlatt->latt->pntsw; - lt->editlatt->latt->actbp = LT_ACTBP_NONE; - - while (a--) { - if (bp->hide == 0) { - bp->f1 = flag; - } - bp++; - } -} - -static int lattice_select_all_exec(bContext *C, wmOperator *op) -{ - Object *obedit = CTX_data_edit_object(C); - Lattice *lt = obedit->data; - BPoint *bp; - int a; - int action = RNA_enum_get(op->ptr, "action"); - - if (action == SEL_TOGGLE) { - action = SEL_SELECT; - - bp = lt->editlatt->latt->def; - a = lt->editlatt->latt->pntsu * lt->editlatt->latt->pntsv * lt->editlatt->latt->pntsw; - - while (a--) { - if (bp->hide == 0) { - if (bp->f1 & SELECT) { - action = SEL_DESELECT; - break; - } - } - bp++; - } - } - - switch (action) { - case SEL_SELECT: - ED_lattice_flags_set(obedit, 1); - break; - case SEL_DESELECT: - ED_lattice_flags_set(obedit, 0); - break; - case SEL_INVERT: - bp = lt->editlatt->latt->def; - a = lt->editlatt->latt->pntsu * lt->editlatt->latt->pntsv * lt->editlatt->latt->pntsw; - lt->editlatt->latt->actbp = LT_ACTBP_NONE; - - while (a--) { - if (bp->hide == 0) { - bp->f1 ^= SELECT; - } - bp++; - } - break; - } - - WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data); - - return OPERATOR_FINISHED; -} - -void LATTICE_OT_select_all(wmOperatorType *ot) -{ - /* identifiers */ - ot->name = "(De)select All"; - ot->description = "Change selection of all UVW control points"; - ot->idname = "LATTICE_OT_select_all"; - - /* api callbacks */ - ot->exec = lattice_select_all_exec; - ot->poll = ED_operator_editlattice; - - /* flags */ - ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; - - WM_operator_properties_select_all(ot); -} - -/************************** Select Ungrouped Verts Operator *************************/ - -static int lattice_select_ungrouped_exec(bContext *C, wmOperator *op) -{ - Object *obedit = CTX_data_edit_object(C); - Lattice *lt = ((Lattice *)obedit->data)->editlatt->latt; - MDeformVert *dv; - BPoint *bp; - int a, tot; - - if (BLI_listbase_is_empty(&obedit->defbase) || lt->dvert == NULL) { - BKE_report(op->reports, RPT_ERROR, "No weights/vertex groups on object"); - return OPERATOR_CANCELLED; - } - - if (!RNA_boolean_get(op->ptr, "extend")) { - ED_lattice_flags_set(obedit, 0); - } - - dv = lt->dvert; - tot = lt->pntsu * lt->pntsv * lt->pntsw; - - for (a = 0, bp = lt->def; a < tot; a++, bp++, dv++) { - if (bp->hide == 0) { - if (dv->dw == NULL) { - bp->f1 |= SELECT; - } - } - } - - WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data); - - return OPERATOR_FINISHED; -} - -void LATTICE_OT_select_ungrouped(wmOperatorType *ot) -{ - /* identifiers */ - ot->name = "Select Ungrouped"; - ot->idname = "LATTICE_OT_select_ungrouped"; - ot->description = "Select vertices without a group"; - - /* api callbacks */ - ot->exec = lattice_select_ungrouped_exec; - ot->poll = ED_operator_editlattice; - - /* flags */ - ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; - - RNA_def_boolean(ot->srna, "extend", false, "Extend", "Extend the selection"); -} - -/************************** Make Regular Operator *************************/ - -static int make_regular_poll(bContext *C) -{ - Object *ob; - - if (ED_operator_editlattice(C)) return 1; - - ob = CTX_data_active_object(C); - return (ob && ob->type == OB_LATTICE); -} - -static int make_regular_exec(bContext *C, wmOperator *UNUSED(op)) -{ - Object *ob = CTX_data_edit_object(C); - Lattice *lt; - - if (ob) { - lt = ob->data; - BKE_lattice_resize(lt->editlatt->latt, lt->pntsu, lt->pntsv, lt->pntsw, NULL); - } - else { - ob = CTX_data_active_object(C); - lt = ob->data; - BKE_lattice_resize(lt, lt->pntsu, lt->pntsv, lt->pntsw, NULL); - } - - DAG_id_tag_update(&ob->id, OB_RECALC_DATA); - WM_event_add_notifier(C, NC_GEOM | ND_DATA, ob->data); - - return OPERATOR_FINISHED; -} - -void LATTICE_OT_make_regular(wmOperatorType *ot) -{ - /* identifiers */ - ot->name = "Make Regular"; - ot->description = "Set UVW control points a uniform distance apart"; - ot->idname = "LATTICE_OT_make_regular"; - - /* api callbacks */ - ot->exec = make_regular_exec; - ot->poll = make_regular_poll; - - /* flags */ - ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; -} - -/************************** Flip Verts Operator *************************/ - -/* flipping options */ -typedef enum eLattice_FlipAxes { - LATTICE_FLIP_U = 0, - LATTICE_FLIP_V = 1, - LATTICE_FLIP_W = 2 -} eLattice_FlipAxes; - -/* Flip midpoint value so that relative distances between midpoint and neighbor-pair is maintained - * ! Assumes that uvw <=> xyz (i.e. axis-aligned index-axes with coordinate-axes) - * - Helper for lattice_flip_exec() - */ -static void lattice_flip_point_value(Lattice *lt, int u, int v, int w, float mid, eLattice_FlipAxes axis) -{ - BPoint *bp; - float diff; - - /* just the point in the middle (unpaired) */ - bp = <->def[BKE_lattice_index_from_uvw(lt, u, v, w)]; - - /* flip over axis */ - diff = mid - bp->vec[axis]; - bp->vec[axis] = mid + diff; -} - -/* Swap pairs of lattice points along a specified axis - * - Helper for lattice_flip_exec() - */ -static void lattice_swap_point_pairs(Lattice *lt, int u, int v, int w, float mid, eLattice_FlipAxes axis) -{ - BPoint *bpA, *bpB; - - int numU = lt->pntsu; - int numV = lt->pntsv; - int numW = lt->pntsw; - - int u0 = u, u1 = u; - int v0 = v, v1 = v; - int w0 = w, w1 = w; - - /* get pair index by just overriding the relevant pair-value - * - "-1" else buffer overflow - */ - switch (axis) { - case LATTICE_FLIP_U: - u1 = numU - u - 1; - break; - case LATTICE_FLIP_V: - v1 = numV - v - 1; - break; - case LATTICE_FLIP_W: - w1 = numW - w - 1; - break; - } - - /* get points to operate on */ - bpA = <->def[BKE_lattice_index_from_uvw(lt, u0, v0, w0)]; - bpB = <->def[BKE_lattice_index_from_uvw(lt, u1, v1, w1)]; - - /* Swap all coordinates, so that flipped coordinates belong to - * the indices on the correct side of the lattice. - * - * Coords: (-2 4) |0| (3 4) --> (3 4) |0| (-2 4) - * Indices: (0,L) (1,R) --> (0,L) (1,R) - */ - swap_v3_v3(bpA->vec, bpB->vec); - - /* However, we need to mirror the coordinate values on the axis we're dealing with, - * otherwise we'd have effectively only rotated the points around. If we don't do this, - * we'd just be reimplementing the naive mirroring algorithm, which causes unwanted deforms - * such as flipped normals, etc. - * - * Coords: (3 4) |0| (-2 4) --\ - * \-> (-3 4) |0| (2 4) - * Indices: (0,L) (1,R) --> (0,L) (1,R) - */ - lattice_flip_point_value(lt, u0, v0, w0, mid, axis); - lattice_flip_point_value(lt, u1, v1, w1, mid, axis); -} - -static int lattice_flip_exec(bContext *C, wmOperator *op) -{ - Object *obedit = CTX_data_edit_object(C); - Lattice *lt; - - eLattice_FlipAxes axis = RNA_enum_get(op->ptr, "axis"); - int numU, numV, numW; - int totP; - - float mid = 0.0f; - short isOdd = 0; - - /* get lattice - we need the "edit lattice" from the lattice... confusing... */ - lt = (Lattice *)obedit->data; - lt = lt->editlatt->latt; - - numU = lt->pntsu; - numV = lt->pntsv; - numW = lt->pntsw; - totP = numU * numV * numW; - - /* First Pass: determine midpoint - used for flipping center verts if there are odd number of points on axis */ - switch (axis) { - case LATTICE_FLIP_U: - isOdd = numU & 1; - break; - case LATTICE_FLIP_V: - isOdd = numV & 1; - break; - case LATTICE_FLIP_W: - isOdd = numW & 1; - break; - - default: - printf("lattice_flip(): Unknown flipping axis (%u)\n", axis); - return OPERATOR_CANCELLED; - } - - if (isOdd) { - BPoint *bp; - float avgInv = 1.0f / (float)totP; - int i; - - /* midpoint calculation - assuming that u/v/w are axis-aligned */ - for (i = 0, bp = lt->def; i < totP; i++, bp++) { - mid += bp->vec[axis] * avgInv; - } - } - - /* Second Pass: swap pairs of vertices per axis, assuming they are all sorted */ - switch (axis) { - case LATTICE_FLIP_U: - { - int u, v, w; - - /* v/w strips - front to back, top to bottom */ - for (w = 0; w < numW; w++) { - for (v = 0; v < numV; v++) { - /* swap coordinates of pairs of vertices on u */ - for (u = 0; u < (numU / 2); u++) { - lattice_swap_point_pairs(lt, u, v, w, mid, axis); - } - - /* flip u-coordinate of midpoint (i.e. unpaired point on u) */ - if (isOdd) { - u = (numU / 2); - lattice_flip_point_value(lt, u, v, w, mid, axis); - } - } - } - break; - } - case LATTICE_FLIP_V: - { - int u, v, w; - - /* u/w strips - front to back, left to right */ - for (w = 0; w < numW; w++) { - for (u = 0; u < numU; u++) { - /* swap coordinates of pairs of vertices on v */ - for (v = 0; v < (numV / 2); v++) { - lattice_swap_point_pairs(lt, u, v, w, mid, axis); - } - - /* flip v-coordinate of midpoint (i.e. unpaired point on v) */ - if (isOdd) { - v = (numV / 2); - lattice_flip_point_value(lt, u, v, w, mid, axis); - } - } - } - break; - } - case LATTICE_FLIP_W: - { - int u, v, w; - - for (v = 0; v < numV; v++) { - for (u = 0; u < numU; u++) { - /* swap coordinates of pairs of vertices on w */ - for (w = 0; w < (numW / 2); w++) { - lattice_swap_point_pairs(lt, u, v, w, mid, axis); - } - - /* flip w-coordinate of midpoint (i.e. unpaired point on w) */ - if (isOdd) { - w = (numW / 2); - lattice_flip_point_value(lt, u, v, w, mid, axis); - } - } - } - break; - } - default: /* shouldn't happen, but just in case */ - break; - } - - /* updates */ - DAG_id_tag_update(&obedit->id, OB_RECALC_DATA); - WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data); - - return OPERATOR_FINISHED; -} - -void LATTICE_OT_flip(wmOperatorType *ot) -{ - static const EnumPropertyItem flip_items[] = { - {LATTICE_FLIP_U, "U", 0, "U (X) Axis", ""}, - {LATTICE_FLIP_V, "V", 0, "V (Y) Axis", ""}, - {LATTICE_FLIP_W, "W", 0, "W (Z) Axis", ""}, - {0, NULL, 0, NULL, NULL}}; - - /* identifiers */ - ot->name = "Flip (Distortion Free)"; - ot->description = "Mirror all control points without inverting the lattice deform"; - ot->idname = "LATTICE_OT_flip"; - - /* api callbacks */ - ot->poll = ED_operator_editlattice; - ot->invoke = WM_menu_invoke; - ot->exec = lattice_flip_exec; - - /* flags */ - ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; - - /* properties */ - ot->prop = RNA_def_enum(ot->srna, "axis", flip_items, LATTICE_FLIP_U, "Flip Axis", "Coordinates along this axis get flipped"); -} - -/****************************** Mouse Selection *************************/ - -static void findnearestLattvert__doClosest(void *userData, BPoint *bp, const float screen_co[2]) -{ - struct { BPoint *bp; float dist; int select; float mval_fl[2]; } *data = userData; - float dist_test = len_manhattan_v2v2(data->mval_fl, screen_co); - - if ((bp->f1 & SELECT) && data->select) - dist_test += 5.0f; - - if (dist_test < data->dist) { - data->dist = dist_test; - - data->bp = bp; - } -} - -static BPoint *findnearestLattvert(ViewContext *vc, const int mval[2], int sel) -{ - /* (sel == 1): selected gets a disadvantage */ - /* in nurb and bezt or bp the nearest is written */ - /* return 0 1 2: handlepunt */ - struct { BPoint *bp; float dist; int select; float mval_fl[2]; } data = {NULL}; - - data.dist = ED_view3d_select_dist_px(); - data.select = sel; - data.mval_fl[0] = mval[0]; - data.mval_fl[1] = mval[1]; - - ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); - lattice_foreachScreenVert(vc, findnearestLattvert__doClosest, &data, V3D_PROJ_TEST_CLIP_DEFAULT); - - return data.bp; -} - -bool ED_lattice_select_pick(bContext *C, const int mval[2], bool extend, bool deselect, bool toggle) -{ - ViewContext vc; - BPoint *bp = NULL; - Lattice *lt; - - ED_view3d_viewcontext_init(C, &vc); - lt = ((Lattice *)vc.obedit->data)->editlatt->latt; - bp = findnearestLattvert(&vc, mval, true); - - if (bp) { - if (extend) { - bp->f1 |= SELECT; - } - else if (deselect) { - bp->f1 &= ~SELECT; - } - else if (toggle) { - bp->f1 ^= SELECT; /* swap */ - } - else { - ED_lattice_flags_set(vc.obedit, 0); - bp->f1 |= SELECT; - } - - if (bp->f1 & SELECT) { - lt->actbp = bp - lt->def; - } - else { - lt->actbp = LT_ACTBP_NONE; - } - - WM_event_add_notifier(C, NC_GEOM | ND_SELECT, vc.obedit->data); - - return true; - } - - return false; -} - -/******************************** Undo *************************/ - -typedef struct UndoLattice { - BPoint *def; - int pntsu, pntsv, pntsw, actbp; -} UndoLattice; - -static void undoLatt_to_editLatt(void *data, void *edata, void *UNUSED(obdata)) -{ - UndoLattice *ult = (UndoLattice *)data; - EditLatt *editlatt = (EditLatt *)edata; - int a = editlatt->latt->pntsu * editlatt->latt->pntsv * editlatt->latt->pntsw; - - memcpy(editlatt->latt->def, ult->def, a * sizeof(BPoint)); - editlatt->latt->actbp = ult->actbp; -} - -static void *editLatt_to_undoLatt(void *edata, void *UNUSED(obdata)) -{ - UndoLattice *ult = MEM_callocN(sizeof(UndoLattice), "UndoLattice"); - EditLatt *editlatt = (EditLatt *)edata; - - ult->def = MEM_dupallocN(editlatt->latt->def); - ult->pntsu = editlatt->latt->pntsu; - ult->pntsv = editlatt->latt->pntsv; - ult->pntsw = editlatt->latt->pntsw; - ult->actbp = editlatt->latt->actbp; - - return ult; -} - -static void free_undoLatt(void *data) -{ - UndoLattice *ult = (UndoLattice *)data; - - if (ult->def) MEM_freeN(ult->def); - MEM_freeN(ult); -} - -static int validate_undoLatt(void *data, void *edata) -{ - UndoLattice *ult = (UndoLattice *)data; - EditLatt *editlatt = (EditLatt *)edata; - - return (ult->pntsu == editlatt->latt->pntsu && - ult->pntsv == editlatt->latt->pntsv && - ult->pntsw == editlatt->latt->pntsw); -} - -static void *get_editlatt(bContext *C) -{ - Object *obedit = CTX_data_edit_object(C); - - if (obedit && obedit->type == OB_LATTICE) { - Lattice *lt = obedit->data; - return lt->editlatt; - } - - return NULL; -} - -/* and this is all the undo system needs to know */ -void undo_push_lattice(bContext *C, const char *name) -{ - undo_editmode_push(C, name, get_editlatt, free_undoLatt, undoLatt_to_editLatt, editLatt_to_undoLatt, validate_undoLatt); -} - diff --git a/source/blender/editors/object/object_ops.c b/source/blender/editors/object/object_ops.c index 9b9f77a1dbb..c090b8684d0 100644 --- a/source/blender/editors/object/object_ops.c +++ b/source/blender/editors/object/object_ops.c @@ -219,15 +219,6 @@ void ED_operatortypes_object(void) WM_operatortype_append(OBJECT_OT_shape_key_mirror); WM_operatortype_append(OBJECT_OT_shape_key_move); - WM_operatortype_append(LATTICE_OT_select_all); - WM_operatortype_append(LATTICE_OT_select_more); - WM_operatortype_append(LATTICE_OT_select_less); - WM_operatortype_append(LATTICE_OT_select_ungrouped); - WM_operatortype_append(LATTICE_OT_select_random); - WM_operatortype_append(LATTICE_OT_select_mirror); - WM_operatortype_append(LATTICE_OT_make_regular); - WM_operatortype_append(LATTICE_OT_flip); - WM_operatortype_append(OBJECT_OT_group_add); WM_operatortype_append(OBJECT_OT_group_link); WM_operatortype_append(OBJECT_OT_group_remove); @@ -443,30 +434,6 @@ void ED_keymap_object(wmKeyConfig *keyconf) kmi = WM_keymap_add_item(keymap, "OBJECT_OT_subdivision_set", ZEROKEY + i, KM_PRESS, KM_CTRL, 0); RNA_int_set(kmi->ptr, "level", i); } - - /* ############################################################################ */ - /* ################################ LATTICE ################################### */ - /* ############################################################################ */ - - keymap = WM_keymap_find(keyconf, "Lattice", 0, 0); - keymap->poll = ED_operator_editlattice; - - kmi = WM_keymap_add_item(keymap, "LATTICE_OT_select_all", AKEY, KM_PRESS, 0, 0); - RNA_enum_set(kmi->ptr, "action", SEL_TOGGLE); - kmi = WM_keymap_add_item(keymap, "LATTICE_OT_select_all", IKEY, KM_PRESS, KM_CTRL, 0); - RNA_enum_set(kmi->ptr, "action", SEL_INVERT); - 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); - - WM_keymap_add_item(keymap, "OBJECT_OT_vertex_parent_set", PKEY, KM_PRESS, KM_CTRL, 0); - - WM_keymap_add_item(keymap, "LATTICE_OT_flip", FKEY, KM_PRESS, KM_CTRL, 0); - - /* menus */ - WM_keymap_add_menu(keymap, "VIEW3D_MT_hook", HKEY, KM_PRESS, KM_CTRL, 0); - - ED_keymap_proportional_cycle(keyconf, keymap); - ED_keymap_proportional_editmode(keyconf, keymap, false); } void ED_keymap_proportional_cycle(struct wmKeyConfig *UNUSED(keyconf), struct wmKeyMap *keymap) diff --git a/source/blender/editors/space_api/spacetypes.c b/source/blender/editors/space_api/spacetypes.c index ac6e3123e4e..9247cdb1ae7 100644 --- a/source/blender/editors/space_api/spacetypes.c +++ b/source/blender/editors/space_api/spacetypes.c @@ -60,6 +60,7 @@ #include "ED_space_api.h" #include "ED_sound.h" #include "ED_uvedit.h" +#include "ED_lattice.h" #include "ED_mball.h" #include "ED_logic.h" #include "ED_clip.h" @@ -104,6 +105,7 @@ void ED_spacetypes_init(void) ED_operatortypes_animchannels(); ED_operatortypes_gpencil(); ED_operatortypes_object(); + ED_operatortypes_lattice(); ED_operatortypes_mesh(); ED_operatortypes_sculpt(); ED_operatortypes_uvedit(); @@ -176,7 +178,8 @@ void ED_spacetypes_keymap(wmKeyConfig *keyconf) ED_keymap_anim(keyconf); ED_keymap_animchannels(keyconf); ED_keymap_gpencil(keyconf); - ED_keymap_object(keyconf); /* defines lattice also */ + ED_keymap_object(keyconf); + ED_keymap_lattice(keyconf); ED_keymap_mesh(keyconf); ED_keymap_uvedit(keyconf); ED_keymap_curve(keyconf); diff --git a/source/blender/editors/space_view3d/view3d_select.c b/source/blender/editors/space_view3d/view3d_select.c index 1f9f941a507..30455460660 100644 --- a/source/blender/editors/space_view3d/view3d_select.c +++ b/source/blender/editors/space_view3d/view3d_select.c @@ -83,6 +83,7 @@ #include "ED_armature.h" #include "ED_curve.h" +#include "ED_lattice.h" #include "ED_particle.h" #include "ED_mesh.h" #include "ED_object.h" diff --git a/source/blender/editors/util/undo.c b/source/blender/editors/util/undo.c index e224dc6484c..d791818331e 100644 --- a/source/blender/editors/util/undo.c +++ b/source/blender/editors/util/undo.c @@ -52,6 +52,7 @@ #include "ED_particle.h" #include "ED_curve.h" #include "ED_gpencil.h" +#include "ED_lattice.h" #include "ED_mball.h" #include "ED_mesh.h" #include "ED_object.h" -- cgit v1.2.3 From e7ca9d3477393eb3e15f6916982fa43d97dfc49e Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 19 Mar 2018 16:30:53 +0100 Subject: Cleanup: move curve undo into own file --- source/blender/editors/curve/CMakeLists.txt | 1 + source/blender/editors/curve/curve_intern.h | 5 + source/blender/editors/curve/editcurve.c | 127 +------------------- source/blender/editors/curve/editcurve_undo.c | 163 ++++++++++++++++++++++++++ source/blender/editors/include/ED_curve.h | 4 +- 5 files changed, 174 insertions(+), 126 deletions(-) create mode 100644 source/blender/editors/curve/editcurve_undo.c (limited to 'source/blender/editors') diff --git a/source/blender/editors/curve/CMakeLists.txt b/source/blender/editors/curve/CMakeLists.txt index 2f5b2ab6e87..13f12f62d95 100644 --- a/source/blender/editors/curve/CMakeLists.txt +++ b/source/blender/editors/curve/CMakeLists.txt @@ -42,6 +42,7 @@ set(SRC editcurve_add.c editcurve_paint.c editcurve_select.c + editcurve_undo.c editfont.c editfont_undo.c diff --git a/source/blender/editors/curve/curve_intern.h b/source/blender/editors/curve/curve_intern.h index bf1e22ae170..020d34f2767 100644 --- a/source/blender/editors/curve/curve_intern.h +++ b/source/blender/editors/curve/curve_intern.h @@ -35,6 +35,7 @@ /* internal exports only */ struct ListBase; struct EditNurb; +struct GHash; struct Object; struct wmOperatorType; struct ViewContext; @@ -129,6 +130,10 @@ void CURVE_OT_cyclic_toggle(struct wmOperatorType *ot); void CURVE_OT_match_texture_space(struct wmOperatorType *ot); +/* exported for editcurve_undo.c */ +struct GHash *ED_curve_keyindex_hash_duplicate(struct GHash *keyindex); +void ED_curve_keyindex_update_nurb(struct EditNurb *editnurb, struct Nurb *nu, struct Nurb *newnu); + 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); diff --git a/source/blender/editors/curve/editcurve.c b/source/blender/editors/curve/editcurve.c index 86a7c58972e..0dbe526117c 100644 --- a/source/blender/editors/curve/editcurve.c +++ b/source/blender/editors/curve/editcurve.c @@ -81,16 +81,6 @@ #include "RNA_define.h" #include "RNA_enum_types.h" -/* Undo stuff */ -typedef struct { - ListBase nubase; - int actvert; - GHash *undoIndex; - ListBase fcurves, drivers; - int actnu; - int flag; -} UndoCurve; - void selectend_nurb(Object *obedit, enum eEndPoint_Types selfirst, bool doswap, 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); @@ -343,7 +333,7 @@ static void keyIndex_updateBP(EditNurb *editnurb, BPoint *bp, keyIndex_updateCV(editnurb, (char *)bp, (char *)newbp, count, sizeof(BPoint)); } -static void keyIndex_updateNurb(EditNurb *editnurb, Nurb *nu, Nurb *newnu) +void ED_curve_keyindex_update_nurb(EditNurb *editnurb, Nurb *nu, Nurb *newnu) { if (nu->bezt) { keyIndex_updateBezt(editnurb, nu->bezt, newnu->bezt, newnu->pntsu); @@ -522,7 +512,7 @@ static void keyData_switchDirectionNurb(Curve *cu, Nurb *nu) switch_keys_direction(cu, nu); } -static GHash *dupli_keyIndexHash(GHash *keyindex) +GHash *ED_curve_keyindex_hash_duplicate(GHash *keyindex) { GHash *gh; GHashIterator gh_iter; @@ -6198,119 +6188,6 @@ void CURVE_OT_tilt_clear(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; } -/****************** undo for curves ****************/ - -static void undoCurve_to_editCurve(void *ucu, void *UNUSED(edata), void *cu_v) -{ - Curve *cu = cu_v; - UndoCurve *undoCurve = ucu; - ListBase *undobase = &undoCurve->nubase; - ListBase *editbase = BKE_curve_editNurbs_get(cu); - Nurb *nu, *newnu; - EditNurb *editnurb = cu->editnurb; - AnimData *ad = BKE_animdata_from_id(&cu->id); - - BKE_nurbList_free(editbase); - - if (undoCurve->undoIndex) { - BKE_curve_editNurb_keyIndex_free(&editnurb->keyindex); - editnurb->keyindex = dupli_keyIndexHash(undoCurve->undoIndex); - } - - if (ad) { - if (ad->action) { - free_fcurves(&ad->action->curves); - copy_fcurves(&ad->action->curves, &undoCurve->fcurves); - } - - free_fcurves(&ad->drivers); - copy_fcurves(&ad->drivers, &undoCurve->drivers); - } - - /* copy */ - for (nu = undobase->first; nu; nu = nu->next) { - newnu = BKE_nurb_duplicate(nu); - - if (editnurb->keyindex) { - keyIndex_updateNurb(editnurb, nu, newnu); - } - - BLI_addtail(editbase, newnu); - } - - cu->actvert = undoCurve->actvert; - cu->actnu = undoCurve->actnu; - cu->flag = undoCurve->flag; - ED_curve_updateAnimPaths(cu); -} - -static void *editCurve_to_undoCurve(void *UNUSED(edata), void *cu_v) -{ - Curve *cu = cu_v; - ListBase *nubase = BKE_curve_editNurbs_get(cu); - UndoCurve *undoCurve; - EditNurb *editnurb = cu->editnurb, tmpEditnurb; - Nurb *nu, *newnu; - AnimData *ad = BKE_animdata_from_id(&cu->id); - - undoCurve = MEM_callocN(sizeof(UndoCurve), "undoCurve"); - - if (editnurb->keyindex) { - undoCurve->undoIndex = dupli_keyIndexHash(editnurb->keyindex); - tmpEditnurb.keyindex = undoCurve->undoIndex; - } - - if (ad) { - if (ad->action) - copy_fcurves(&undoCurve->fcurves, &ad->action->curves); - - copy_fcurves(&undoCurve->drivers, &ad->drivers); - } - - /* copy */ - for (nu = nubase->first; nu; nu = nu->next) { - newnu = BKE_nurb_duplicate(nu); - - if (undoCurve->undoIndex) { - keyIndex_updateNurb(&tmpEditnurb, nu, newnu); - } - - BLI_addtail(&undoCurve->nubase, newnu); - } - - undoCurve->actvert = cu->actvert; - undoCurve->actnu = cu->actnu; - undoCurve->flag = cu->flag; - - return undoCurve; -} - -static void free_undoCurve(void *ucv) -{ - UndoCurve *undoCurve = ucv; - - BKE_nurbList_free(&undoCurve->nubase); - - BKE_curve_editNurb_keyIndex_free(&undoCurve->undoIndex); - - free_fcurves(&undoCurve->fcurves); - free_fcurves(&undoCurve->drivers); - - MEM_freeN(undoCurve); -} - -static void *get_data(bContext *C) -{ - Object *obedit = CTX_data_edit_object(C); - return obedit; -} - -/* and this is all the undo system needs to know */ -void undo_push_curve(bContext *C, const char *name) -{ - undo_editmode_push(C, name, get_data, free_undoCurve, undoCurve_to_editCurve, editCurve_to_undoCurve, NULL); -} - void ED_curve_beztcpy(EditNurb *editnurb, BezTriple *dst, BezTriple *src, int count) { memcpy(dst, src, count * sizeof(BezTriple)); diff --git a/source/blender/editors/curve/editcurve_undo.c b/source/blender/editors/curve/editcurve_undo.c new file mode 100644 index 00000000000..f8f96eb3bc9 --- /dev/null +++ b/source/blender/editors/curve/editcurve_undo.c @@ -0,0 +1,163 @@ +/* + * ***** 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. + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/editors/curve/editcurve_undo.c + * \ingroup edcurve + */ + +#include "DNA_object_types.h" +#include "DNA_scene_types.h" +#include "DNA_anim_types.h" + +#include "MEM_guardedalloc.h" + +#include "BLI_blenlib.h" +#include "BLI_ghash.h" + +#include "BKE_context.h" +#include "BKE_curve.h" +#include "BKE_fcurve.h" +#include "BKE_library.h" +#include "BKE_animsys.h" + +#include "ED_util.h" +#include "ED_curve.h" + +#include "curve_intern.h" + +typedef struct { + ListBase nubase; + int actvert; + GHash *undoIndex; + ListBase fcurves, drivers; + int actnu; + int flag; +} UndoCurve; + +static void undoCurve_to_editCurve(void *ucu, void *UNUSED(edata), void *cu_v) +{ + Curve *cu = cu_v; + UndoCurve *undoCurve = ucu; + ListBase *undobase = &undoCurve->nubase; + ListBase *editbase = BKE_curve_editNurbs_get(cu); + Nurb *nu, *newnu; + EditNurb *editnurb = cu->editnurb; + AnimData *ad = BKE_animdata_from_id(&cu->id); + + BKE_nurbList_free(editbase); + + if (undoCurve->undoIndex) { + BKE_curve_editNurb_keyIndex_free(&editnurb->keyindex); + editnurb->keyindex = ED_curve_keyindex_hash_duplicate(undoCurve->undoIndex); + } + + if (ad) { + if (ad->action) { + free_fcurves(&ad->action->curves); + copy_fcurves(&ad->action->curves, &undoCurve->fcurves); + } + + free_fcurves(&ad->drivers); + copy_fcurves(&ad->drivers, &undoCurve->drivers); + } + + /* copy */ + for (nu = undobase->first; nu; nu = nu->next) { + newnu = BKE_nurb_duplicate(nu); + + if (editnurb->keyindex) { + ED_curve_keyindex_update_nurb(editnurb, nu, newnu); + } + + BLI_addtail(editbase, newnu); + } + + cu->actvert = undoCurve->actvert; + cu->actnu = undoCurve->actnu; + cu->flag = undoCurve->flag; + ED_curve_updateAnimPaths(cu); +} + +static void *editCurve_to_undoCurve(void *UNUSED(edata), void *cu_v) +{ + Curve *cu = cu_v; + ListBase *nubase = BKE_curve_editNurbs_get(cu); + UndoCurve *undoCurve; + EditNurb *editnurb = cu->editnurb, tmpEditnurb; + Nurb *nu, *newnu; + AnimData *ad = BKE_animdata_from_id(&cu->id); + + undoCurve = MEM_callocN(sizeof(UndoCurve), "undoCurve"); + + if (editnurb->keyindex) { + undoCurve->undoIndex = ED_curve_keyindex_hash_duplicate(editnurb->keyindex); + tmpEditnurb.keyindex = undoCurve->undoIndex; + } + + if (ad) { + if (ad->action) + copy_fcurves(&undoCurve->fcurves, &ad->action->curves); + + copy_fcurves(&undoCurve->drivers, &ad->drivers); + } + + /* copy */ + for (nu = nubase->first; nu; nu = nu->next) { + newnu = BKE_nurb_duplicate(nu); + + if (undoCurve->undoIndex) { + ED_curve_keyindex_update_nurb(&tmpEditnurb, nu, newnu); + } + + BLI_addtail(&undoCurve->nubase, newnu); + } + + undoCurve->actvert = cu->actvert; + undoCurve->actnu = cu->actnu; + undoCurve->flag = cu->flag; + + return undoCurve; +} + +static void free_undoCurve(void *ucv) +{ + UndoCurve *undoCurve = ucv; + + BKE_nurbList_free(&undoCurve->nubase); + + BKE_curve_editNurb_keyIndex_free(&undoCurve->undoIndex); + + free_fcurves(&undoCurve->fcurves); + free_fcurves(&undoCurve->drivers); + + MEM_freeN(undoCurve); +} + +static void *get_data(bContext *C) +{ + Object *obedit = CTX_data_edit_object(C); + return obedit; +} + +/* and this is all the undo system needs to know */ +void undo_push_curve(bContext *C, const char *name) +{ + undo_editmode_push(C, name, get_data, free_undoCurve, undoCurve_to_editCurve, editCurve_to_undoCurve, NULL); +} diff --git a/source/blender/editors/include/ED_curve.h b/source/blender/editors/include/ED_curve.h index 859d45e9c86..d45e52d4c5a 100644 --- a/source/blender/editors/include/ED_curve.h +++ b/source/blender/editors/include/ED_curve.h @@ -48,7 +48,6 @@ void ED_operatormacros_curve(void); void ED_keymap_curve(struct wmKeyConfig *keyconf); /* editcurve.c */ -void undo_push_curve(struct bContext *C, const char *name); ListBase *object_editcurve_get(struct Object *ob); void ED_curve_editnurb_load(struct Object *obedit); @@ -72,6 +71,9 @@ 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); +/* editcurve_undo.c */ +void undo_push_curve(struct bContext *C, const char *name); + /* editfont.c */ void ED_curve_editfont_load(struct Object *obedit); void ED_curve_editfont_make(struct Object *obedit); -- cgit v1.2.3 From 566f4e06ba39665bbaabdada6766daa973dbc911 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 19 Mar 2018 16:46:48 +0100 Subject: Cleanup: move metaball undo into own file --- source/blender/editors/metaball/CMakeLists.txt | 1 + source/blender/editors/metaball/editmball_undo.c | 131 +++++++++++++++++++++++ source/blender/editors/metaball/mball_edit.c | 93 ---------------- 3 files changed, 132 insertions(+), 93 deletions(-) create mode 100644 source/blender/editors/metaball/editmball_undo.c (limited to 'source/blender/editors') diff --git a/source/blender/editors/metaball/CMakeLists.txt b/source/blender/editors/metaball/CMakeLists.txt index 0f9de8dbf87..7815240b7a4 100644 --- a/source/blender/editors/metaball/CMakeLists.txt +++ b/source/blender/editors/metaball/CMakeLists.txt @@ -34,6 +34,7 @@ set(INC_SYS ) set(SRC + editmball_undo.c mball_edit.c mball_ops.c diff --git a/source/blender/editors/metaball/editmball_undo.c b/source/blender/editors/metaball/editmball_undo.c new file mode 100644 index 00000000000..974bfb237d3 --- /dev/null +++ b/source/blender/editors/metaball/editmball_undo.c @@ -0,0 +1,131 @@ +/* + * ***** 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. + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/editors/metaball/editmball_undo.c + * \ingroup edmeta + */ + +#include +#include + +#include "MEM_guardedalloc.h" + +#include "BLI_utildefines.h" +#include "BLI_listbase.h" + +#include "DNA_defs.h" +#include "DNA_meta_types.h" +#include "DNA_object_types.h" + +#include "BKE_context.h" + +#include "ED_mball.h" +#include "ED_util.h" + +typedef struct UndoMBall { + ListBase editelems; + int lastelem_index; +} UndoMBall; + +/* free all MetaElems from ListBase */ +static void freeMetaElemlist(ListBase *lb) +{ + MetaElem *ml; + + if (lb == NULL) { + return; + } + + while ((ml = BLI_pophead(lb))) { + MEM_freeN(ml); + } +} + +static void undoMball_to_editMball(void *umb_v, void *mb_v, void *UNUSED(obdata)) +{ + MetaBall *mb = mb_v; + UndoMBall *umb = umb_v; + + freeMetaElemlist(mb->editelems); + mb->lastelem = NULL; + + /* copy 'undo' MetaElems to 'edit' MetaElems */ + int index = 0; + for (MetaElem *ml_undo = umb->editelems.first; ml_undo; ml_undo = ml_undo->next, index += 1) { + MetaElem *ml_edit = MEM_dupallocN(ml_undo); + BLI_addtail(mb->editelems, ml_edit); + if (index == umb->lastelem_index) { + mb->lastelem = ml_edit; + } + } + +} + +static void *editMball_to_undoMball(void *mb_v, void *UNUSED(obdata)) +{ + MetaBall *mb = mb_v; + UndoMBall *umb; + + /* allocate memory for undo ListBase */ + umb = MEM_callocN(sizeof(UndoMBall), __func__); + umb->lastelem_index = -1; + + /* copy contents of current ListBase to the undo ListBase */ + int index = 0; + for (MetaElem *ml_edit = mb->editelems->first; ml_edit; ml_edit = ml_edit->next, index += 1) { + MetaElem *ml_undo = MEM_dupallocN(ml_edit); + BLI_addtail(&umb->editelems, ml_undo); + if (ml_edit == mb->lastelem) { + umb->lastelem_index = index; + } + } + + return umb; +} + +/* free undo ListBase of MetaElems */ +static void free_undoMball(void *umb_v) +{ + UndoMBall *umb = umb_v; + + freeMetaElemlist(&umb->editelems); + MEM_freeN(umb); +} + +static MetaBall *metaball_get_obdata(Object *ob) +{ + if (ob && ob->type == OB_MBALL) { + return ob->data; + } + return NULL; +} + + +static void *get_data(bContext *C) +{ + Object *obedit = CTX_data_edit_object(C); + return metaball_get_obdata(obedit); +} + +/* this is undo system for MetaBalls */ +void undo_push_mball(bContext *C, const char *name) +{ + undo_editmode_push(C, name, get_data, free_undoMball, undoMball_to_editMball, editMball_to_undoMball, NULL); +} diff --git a/source/blender/editors/metaball/mball_edit.c b/source/blender/editors/metaball/mball_edit.c index e948de02f40..27140bcdf3b 100644 --- a/source/blender/editors/metaball/mball_edit.c +++ b/source/blender/editors/metaball/mball_edit.c @@ -29,7 +29,6 @@ * \ingroup edmeta */ - #include #include @@ -55,7 +54,6 @@ #include "ED_mball.h" #include "ED_screen.h" #include "ED_view3d.h" -#include "ED_util.h" #include "WM_api.h" #include "WM_types.h" @@ -665,94 +663,3 @@ bool ED_mball_select_pick(bContext *C, const int mval[2], bool extend, bool dese } -/* ************* undo for MetaBalls ************* */ - -typedef struct UndoMBall { - ListBase editelems; - int lastelem_index; -} UndoMBall; - -/* free all MetaElems from ListBase */ -static void freeMetaElemlist(ListBase *lb) -{ - MetaElem *ml; - - if (lb == NULL) return; - - while ((ml = BLI_pophead(lb))) { - MEM_freeN(ml); - } -} - - -static void undoMball_to_editMball(void *umb_v, void *mb_v, void *UNUSED(obdata)) -{ - MetaBall *mb = mb_v; - UndoMBall *umb = umb_v; - - freeMetaElemlist(mb->editelems); - mb->lastelem = NULL; - - /* copy 'undo' MetaElems to 'edit' MetaElems */ - int index = 0; - for (MetaElem *ml_undo = umb->editelems.first; ml_undo; ml_undo = ml_undo->next, index += 1) { - MetaElem *ml_edit = MEM_dupallocN(ml_undo); - BLI_addtail(mb->editelems, ml_edit); - if (index == umb->lastelem_index) { - mb->lastelem = ml_edit; - } - } - -} - -static void *editMball_to_undoMball(void *mb_v, void *UNUSED(obdata)) -{ - MetaBall *mb = mb_v; - UndoMBall *umb; - - /* allocate memory for undo ListBase */ - umb = MEM_callocN(sizeof(UndoMBall), __func__); - umb->lastelem_index = -1; - - /* copy contents of current ListBase to the undo ListBase */ - int index = 0; - for (MetaElem *ml_edit = mb->editelems->first; ml_edit; ml_edit = ml_edit->next, index += 1) { - MetaElem *ml_undo = MEM_dupallocN(ml_edit); - BLI_addtail(&umb->editelems, ml_undo); - if (ml_edit == mb->lastelem) { - umb->lastelem_index = index; - } - } - - return umb; -} - -/* free undo ListBase of MetaElems */ -static void free_undoMball(void *umb_v) -{ - UndoMBall *umb = umb_v; - - freeMetaElemlist(&umb->editelems); - MEM_freeN(umb); -} - -static MetaBall *metaball_get_obdata(Object *ob) -{ - if (ob && ob->type == OB_MBALL) { - return ob->data; - } - return NULL; -} - - -static void *get_data(bContext *C) -{ - Object *obedit = CTX_data_edit_object(C); - return metaball_get_obdata(obedit); -} - -/* this is undo system for MetaBalls */ -void undo_push_mball(bContext *C, const char *name) -{ - undo_editmode_push(C, name, get_data, free_undoMball, undoMball_to_editMball, editMball_to_undoMball, NULL); -} -- cgit v1.2.3 From a5fc0ae150d737109ee1bd179bc5de81f9120f32 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 19 Mar 2018 17:10:07 +0100 Subject: Cleanup: move armature undo into own file --- source/blender/editors/armature/CMakeLists.txt | 1 + source/blender/editors/armature/armature_utils.c | 78 +------------- .../blender/editors/armature/editarmature_undo.c | 112 +++++++++++++++++++++ source/blender/editors/include/ED_armature.h | 6 +- 4 files changed, 121 insertions(+), 76 deletions(-) create mode 100644 source/blender/editors/armature/editarmature_undo.c (limited to 'source/blender/editors') diff --git a/source/blender/editors/armature/CMakeLists.txt b/source/blender/editors/armature/CMakeLists.txt index b213aca478f..4c394d7836a 100644 --- a/source/blender/editors/armature/CMakeLists.txt +++ b/source/blender/editors/armature/CMakeLists.txt @@ -48,6 +48,7 @@ set(SRC editarmature_generate.c editarmature_retarget.c editarmature_sketch.c + editarmature_undo.c meshlaplacian.c pose_edit.c pose_lib.c diff --git a/source/blender/editors/armature/armature_utils.c b/source/blender/editors/armature/armature_utils.c index a55264bd020..0efd9cec959 100644 --- a/source/blender/editors/armature/armature_utils.c +++ b/source/blender/editors/armature/armature_utils.c @@ -710,11 +710,11 @@ void ED_armature_to_edit(bArmature *arm) } /* *************************************************************** */ -/* Undo for Armature EditMode*/ +/* Used by Undo for Armature EditMode*/ /* free's bones and their properties */ -static void ED_armature_ebone_listbase_free(ListBase *lb) +void ED_armature_ebone_listbase_free(ListBase *lb) { EditBone *ebone, *ebone_next; @@ -732,7 +732,7 @@ static void ED_armature_ebone_listbase_free(ListBase *lb) BLI_listbase_clear(lb); } -static void ED_armature_ebone_listbase_copy(ListBase *lb_dst, ListBase *lb_src) +void ED_armature_ebone_listbase_copy(ListBase *lb_dst, ListBase *lb_src) { EditBone *ebone_src; EditBone *ebone_dst; @@ -765,78 +765,6 @@ void ED_armature_ebone_listbase_temp_clear(ListBase *lb) } } -typedef struct UndoArmature { - EditBone *act_edbone; - ListBase lb; -} UndoArmature; - -static void undoBones_to_editBones(void *uarmv, void *armv, void *UNUSED(data)) -{ - UndoArmature *uarm = uarmv; - bArmature *arm = armv; - EditBone *ebone; - - ED_armature_ebone_listbase_free(arm->edbo); - ED_armature_ebone_listbase_copy(arm->edbo, &uarm->lb); - - /* active bone */ - if (uarm->act_edbone) { - ebone = uarm->act_edbone; - arm->act_edbone = ebone->temp.ebone; - } - else { - arm->act_edbone = NULL; - } - - ED_armature_ebone_listbase_temp_clear(arm->edbo); -} - -static void *editBones_to_undoBones(void *armv, void *UNUSED(obdata)) -{ - bArmature *arm = armv; - UndoArmature *uarm; - EditBone *ebone; - - uarm = MEM_callocN(sizeof(UndoArmature), "listbase undo"); - - ED_armature_ebone_listbase_copy(&uarm->lb, arm->edbo); - - /* active bone */ - if (arm->act_edbone) { - ebone = arm->act_edbone; - uarm->act_edbone = ebone->temp.ebone; - } - - ED_armature_ebone_listbase_temp_clear(&uarm->lb); - - return uarm; -} - -static void free_undoBones(void *uarmv) -{ - UndoArmature *uarm = uarmv; - - ED_armature_ebone_listbase_free(&uarm->lb); - - MEM_freeN(uarm); -} - -static void *get_armature_edit(bContext *C) -{ - Object *obedit = CTX_data_edit_object(C); - if (obedit && obedit->type == OB_ARMATURE) { - return obedit->data; - } - return NULL; -} - -/* and this is all the undo system needs to know */ -void undo_push_armature(bContext *C, const char *name) -{ - // XXX solve getdata() - undo_editmode_push(C, name, get_armature_edit, free_undoBones, undoBones_to_editBones, editBones_to_undoBones, NULL); -} - /* *************************************************************** */ /* Low level selection functions which hide connected-parent * flag behavior which gets tricky to handle in selection operators. diff --git a/source/blender/editors/armature/editarmature_undo.c b/source/blender/editors/armature/editarmature_undo.c new file mode 100644 index 00000000000..36e6ec4ba7f --- /dev/null +++ b/source/blender/editors/armature/editarmature_undo.c @@ -0,0 +1,112 @@ +/* + * ***** 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. + * + * Contributor(s): Blender Foundation, 2002-2009 full recode. + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/editors/armature/editarmature_undo.c + * \ingroup edarmature + */ + +#include "DNA_armature_types.h" +#include "DNA_object_types.h" + +#include "MEM_guardedalloc.h" + +#include "BLI_math.h" + +#include "BKE_context.h" + +#include "ED_armature.h" +#include "ED_util.h" + +typedef struct UndoArmature { + EditBone *act_edbone; + ListBase lb; +} UndoArmature; + +static void undoBones_to_editBones(void *uarmv, void *armv, void *UNUSED(data)) +{ + UndoArmature *uarm = uarmv; + bArmature *arm = armv; + EditBone *ebone; + + ED_armature_ebone_listbase_free(arm->edbo); + ED_armature_ebone_listbase_copy(arm->edbo, &uarm->lb); + + /* active bone */ + if (uarm->act_edbone) { + ebone = uarm->act_edbone; + arm->act_edbone = ebone->temp.ebone; + } + else { + arm->act_edbone = NULL; + } + + ED_armature_ebone_listbase_temp_clear(arm->edbo); +} + +static void *editBones_to_undoBones(void *armv, void *UNUSED(obdata)) +{ + bArmature *arm = armv; + UndoArmature *uarm; + EditBone *ebone; + + uarm = MEM_callocN(sizeof(UndoArmature), "listbase undo"); + + ED_armature_ebone_listbase_copy(&uarm->lb, arm->edbo); + + /* active bone */ + if (arm->act_edbone) { + ebone = arm->act_edbone; + uarm->act_edbone = ebone->temp.ebone; + } + + ED_armature_ebone_listbase_temp_clear(&uarm->lb); + + return uarm; +} + +static void free_undoBones(void *uarmv) +{ + UndoArmature *uarm = uarmv; + + ED_armature_ebone_listbase_free(&uarm->lb); + + MEM_freeN(uarm); +} + +static void *get_armature_edit(bContext *C) +{ + Object *obedit = CTX_data_edit_object(C); + if (obedit && obedit->type == OB_ARMATURE) { + return obedit->data; + } + return NULL; +} + +/* and this is all the undo system needs to know */ +void undo_push_armature(bContext *C, const char *name) +{ + // XXX solve getdata() + undo_editmode_push(C, name, get_armature_edit, free_undoBones, undoBones_to_editBones, editBones_to_undoBones, NULL); +} diff --git a/source/blender/editors/include/ED_armature.h b/source/blender/editors/include/ED_armature.h index 42bda265375..39e95eb9ee1 100644 --- a/source/blender/editors/include/ED_armature.h +++ b/source/blender/editors/include/ED_armature.h @@ -128,7 +128,6 @@ void ED_keymap_armature(struct wmKeyConfig *keyconf); void ED_armature_from_edit(struct bArmature *arm); void ED_armature_to_edit(struct bArmature *arm); void ED_armature_edit_free(struct bArmature *arm); -void ED_armature_ebone_listbase_temp_clear(struct ListBase *lb); void ED_armature_deselect_all(struct Object *obedit); void ED_armature_deselect_all_visible(struct Object *obedit); @@ -186,6 +185,11 @@ void ED_armature_ebone_select_set(EditBone *ebone, bool select); void ED_armature_ebone_selectflag_enable(EditBone *ebone, int flag); void ED_armature_ebone_selectflag_disable(EditBone *ebone, int flag); +/* armature_utils.c */ +void ED_armature_ebone_listbase_temp_clear(struct ListBase *lb); +void ED_armature_ebone_listbase_free(struct ListBase *lb); +void ED_armature_ebone_listbase_copy(struct ListBase *lb_dst, struct ListBase *lb_src); + /* poseobject.c */ void ED_armature_exit_posemode(struct bContext *C, struct Base *base); void ED_armature_enter_posemode(struct bContext *C, struct Base *base); -- cgit v1.2.3 From a3486e735f7e5af6ca78dafc8608cced5a121096 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 19 Mar 2018 17:46:49 +0100 Subject: Cleanup: move particle undo into own file Also avoid extern declarations which can get out of sync. --- source/blender/editors/physics/CMakeLists.txt | 2 + source/blender/editors/physics/particle_edit.c | 310 +------------------ .../blender/editors/physics/particle_edit_undo.c | 344 +++++++++++++++++++++ .../editors/physics/particle_edit_utildefines.h | 50 +++ source/blender/editors/physics/particle_object.c | 6 - source/blender/editors/physics/physics_intern.h | 11 + 6 files changed, 408 insertions(+), 315 deletions(-) create mode 100644 source/blender/editors/physics/particle_edit_undo.c create mode 100644 source/blender/editors/physics/particle_edit_utildefines.h (limited to 'source/blender/editors') diff --git a/source/blender/editors/physics/CMakeLists.txt b/source/blender/editors/physics/CMakeLists.txt index 898422dac51..a04ebb24d2c 100644 --- a/source/blender/editors/physics/CMakeLists.txt +++ b/source/blender/editors/physics/CMakeLists.txt @@ -40,6 +40,7 @@ set(SRC dynamicpaint_ops.c particle_boids.c particle_edit.c + particle_edit_undo.c particle_object.c physics_fluid.c physics_ops.c @@ -48,6 +49,7 @@ set(SRC rigidbody_object.c rigidbody_world.c + particle_edit_utildefines.h physics_intern.h ) diff --git a/source/blender/editors/physics/particle_edit.c b/source/blender/editors/physics/particle_edit.c index 3c7cb90eba4..93bfd156707 100644 --- a/source/blender/editors/physics/particle_edit.c +++ b/source/blender/editors/physics/particle_edit.c @@ -29,7 +29,6 @@ * \ingroup edphys */ - #include #include #include @@ -47,7 +46,6 @@ #include "BLI_math.h" #include "BLI_lasso_2d.h" #include "BLI_listbase.h" -#include "BLI_string.h" #include "BLI_kdtree.h" #include "BLI_rand.h" #include "BLI_utildefines.h" @@ -83,26 +81,7 @@ #include "physics_intern.h" -void PE_create_particle_edit(Scene *scene, Object *ob, PointCache *cache, ParticleSystem *psys); -void PTCacheUndo_clear(PTCacheEdit *edit); -void recalc_lengths(PTCacheEdit *edit); -void recalc_emitter_field(Object *ob, ParticleSystem *psys); -void update_world_cos(Object *ob, PTCacheEdit *edit); - -#define KEY_K PTCacheEditKey *key; int k -#define POINT_P PTCacheEditPoint *point; int p -#define LOOP_POINTS for (p=0, point=edit->points; ptotpoint; p++, point++) -#define LOOP_VISIBLE_POINTS for (p=0, point=edit->points; ptotpoint; p++, point++) if (!(point->flag & PEP_HIDE)) -#define LOOP_SELECTED_POINTS for (p=0, point=edit->points; ptotpoint; p++, point++) if (point_is_selected(point)) -#define LOOP_UNSELECTED_POINTS for (p=0, point=edit->points; ptotpoint; p++, point++) if (!point_is_selected(point)) -#define LOOP_EDITED_POINTS for (p=0, point=edit->points; ptotpoint; p++, point++) if (point->flag & PEP_EDIT_RECALC) -#define LOOP_TAGGED_POINTS for (p=0, point=edit->points; ptotpoint; p++, point++) if (point->flag & PEP_TAG) -#define LOOP_KEYS for (k=0, key=point->keys; ktotkey; k++, key++) -#define LOOP_VISIBLE_KEYS for (k=0, key=point->keys; ktotkey; k++, key++) if (!(key->flag & PEK_HIDE)) -#define LOOP_SELECTED_KEYS for (k=0, key=point->keys; ktotkey; k++, key++) if ((key->flag & PEK_SELECT) && !(key->flag & PEK_HIDE)) -#define LOOP_TAGGED_KEYS for (k=0, key=point->keys; ktotkey; k++, key++) if (key->flag & PEK_TAG) - -#define KEY_WCO ((key->flag & PEK_USE_WCO) ? key->world_co : key->co) +#include "particle_edit_utildefines.h" /**************************** utilities *******************************/ @@ -4256,293 +4235,6 @@ void PARTICLE_OT_shape_cut(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO; } -/*********************** undo ***************************/ - -static void free_PTCacheUndo(PTCacheUndo *undo) -{ - PTCacheEditPoint *point; - int i; - - for (i=0, point=undo->points; itotpoint; i++, point++) { - if (undo->particles && (undo->particles + i)->hair) - MEM_freeN((undo->particles + i)->hair); - if (point->keys) - MEM_freeN(point->keys); - } - if (undo->points) - MEM_freeN(undo->points); - - if (undo->particles) - MEM_freeN(undo->particles); - - BKE_ptcache_free_mem(&undo->mem_cache); -} - -static void make_PTCacheUndo(PTCacheEdit *edit, PTCacheUndo *undo) -{ - PTCacheEditPoint *point; - int i; - - undo->totpoint= edit->totpoint; - - if (edit->psys) { - ParticleData *pa; - - pa= undo->particles= MEM_dupallocN(edit->psys->particles); - - for (i=0; itotpoint; i++, pa++) - pa->hair= MEM_dupallocN(pa->hair); - - undo->psys_flag = edit->psys->flag; - } - else { - PTCacheMem *pm; - - BLI_duplicatelist(&undo->mem_cache, &edit->pid.cache->mem_cache); - pm = undo->mem_cache.first; - - for (; pm; pm=pm->next) { - for (i=0; idata[i] = MEM_dupallocN(pm->data[i]); - } - } - - point= undo->points = MEM_dupallocN(edit->points); - undo->totpoint = edit->totpoint; - - for (i=0; itotpoint; i++, point++) { - point->keys= MEM_dupallocN(point->keys); - /* no need to update edit key->co & key->time pointers here */ - } -} - -static void get_PTCacheUndo(PTCacheEdit *edit, PTCacheUndo *undo) -{ - ParticleSystem *psys = edit->psys; - ParticleData *pa; - HairKey *hkey; - POINT_P; KEY_K; - - LOOP_POINTS { - if (psys && psys->particles[p].hair) - MEM_freeN(psys->particles[p].hair); - - if (point->keys) - MEM_freeN(point->keys); - } - if (psys && psys->particles) - MEM_freeN(psys->particles); - if (edit->points) - MEM_freeN(edit->points); - if (edit->mirror_cache) { - MEM_freeN(edit->mirror_cache); - edit->mirror_cache= NULL; - } - - edit->points= MEM_dupallocN(undo->points); - edit->totpoint = undo->totpoint; - - LOOP_POINTS { - point->keys= MEM_dupallocN(point->keys); - } - - if (psys) { - psys->particles= MEM_dupallocN(undo->particles); - - psys->totpart= undo->totpoint; - - LOOP_POINTS { - pa = psys->particles + p; - hkey= pa->hair = MEM_dupallocN(pa->hair); - - LOOP_KEYS { - key->co= hkey->co; - key->time= &hkey->time; - hkey++; - } - } - - psys->flag = undo->psys_flag; - } - else { - PTCacheMem *pm; - int i; - - BKE_ptcache_free_mem(&edit->pid.cache->mem_cache); - - BLI_duplicatelist(&edit->pid.cache->mem_cache, &undo->mem_cache); - - pm = edit->pid.cache->mem_cache.first; - - for (; pm; pm=pm->next) { - for (i=0; idata[i] = MEM_dupallocN(pm->data[i]); - - BKE_ptcache_mem_pointers_init(pm); - - LOOP_POINTS { - LOOP_KEYS { - if ((int)key->ftime == (int)pm->frame) { - key->co = pm->cur[BPHYS_DATA_LOCATION]; - key->vel = pm->cur[BPHYS_DATA_VELOCITY]; - key->rot = pm->cur[BPHYS_DATA_ROTATION]; - key->time = &key->ftime; - } - } - BKE_ptcache_mem_pointers_incr(pm); - } - } - } -} - -void PE_undo_push(Scene *scene, const char *str) -{ - PTCacheEdit *edit= PE_get_current(scene, OBACT); - PTCacheUndo *undo; - int nr; - - if (!edit) return; - - /* remove all undos after (also when curundo==NULL) */ - while (edit->undo.last != edit->curundo) { - undo= edit->undo.last; - BLI_remlink(&edit->undo, undo); - free_PTCacheUndo(undo); - MEM_freeN(undo); - } - - /* make new */ - edit->curundo= undo= MEM_callocN(sizeof(PTCacheUndo), "particle undo file"); - BLI_strncpy(undo->name, str, sizeof(undo->name)); - BLI_addtail(&edit->undo, undo); - - /* and limit amount to the maximum */ - nr= 0; - undo= edit->undo.last; - while (undo) { - nr++; - if (nr==U.undosteps) break; - undo= undo->prev; - } - if (undo) { - while (edit->undo.first != undo) { - PTCacheUndo *first= edit->undo.first; - BLI_remlink(&edit->undo, first); - free_PTCacheUndo(first); - MEM_freeN(first); - } - } - - /* copy */ - make_PTCacheUndo(edit, edit->curundo); -} - -void PE_undo_step(Scene *scene, int step) -{ - PTCacheEdit *edit= PE_get_current(scene, OBACT); - - if (!edit) return; - - if (step==0) { - get_PTCacheUndo(edit, edit->curundo); - } - else if (step==1) { - - if (edit->curundo==NULL || edit->curundo->prev==NULL) { - /* pass */ - } - else { - if (G.debug & G_DEBUG) printf("undo %s\n", edit->curundo->name); - edit->curundo= edit->curundo->prev; - get_PTCacheUndo(edit, edit->curundo); - } - } - else { - /* curundo has to remain current situation! */ - - if (edit->curundo==NULL || edit->curundo->next==NULL) { - /* pass */ - } - else { - get_PTCacheUndo(edit, edit->curundo->next); - edit->curundo= edit->curundo->next; - if (G.debug & G_DEBUG) printf("redo %s\n", edit->curundo->name); - } - } - - DAG_id_tag_update(&OBACT->id, OB_RECALC_DATA); -} - -bool PE_undo_is_valid(Scene *scene) -{ - PTCacheEdit *edit= PE_get_current(scene, OBACT); - - if (edit) { - return (edit->undo.last != edit->undo.first); - } - return 0; -} - -void PTCacheUndo_clear(PTCacheEdit *edit) -{ - PTCacheUndo *undo; - - if (edit==NULL) return; - - undo= edit->undo.first; - while (undo) { - free_PTCacheUndo(undo); - undo= undo->next; - } - BLI_freelistN(&edit->undo); - edit->curundo= NULL; -} - -void PE_undo(Scene *scene) -{ - PE_undo_step(scene, 1); -} - -void PE_redo(Scene *scene) -{ - PE_undo_step(scene, -1); -} - -void PE_undo_number(Scene *scene, int nr) -{ - PTCacheEdit *edit= PE_get_current(scene, OBACT); - PTCacheUndo *undo; - int a=0; - - for (undo= edit->undo.first; undo; undo= undo->next, a++) { - if (a==nr) break; - } - edit->curundo= undo; - PE_undo_step(scene, 0); -} - - -/* get name of undo item, return null if no item with this index */ -/* if active pointer, set it to 1 if true */ -const char *PE_undo_get_name(Scene *scene, int nr, bool *r_active) -{ - PTCacheEdit *edit= PE_get_current(scene, OBACT); - PTCacheUndo *undo; - - if (r_active) *r_active = false; - - if (edit) { - undo= BLI_findlink(&edit->undo, nr); - if (undo) { - if (r_active && (undo == edit->curundo)) { - *r_active = true; - } - return undo->name; - } - } - return NULL; -} - /************************ utilities ******************************/ int PE_minmax(Scene *scene, float min[3], float max[3]) diff --git a/source/blender/editors/physics/particle_edit_undo.c b/source/blender/editors/physics/particle_edit_undo.c new file mode 100644 index 00000000000..3899d445b78 --- /dev/null +++ b/source/blender/editors/physics/particle_edit_undo.c @@ -0,0 +1,344 @@ +/* + * ***** 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) 2007 by Janne Karhu. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/editors/physics/particle_edit_undo.c + * \ingroup edphys + */ + +#include +#include +#include +#include + +#include "MEM_guardedalloc.h" + +#include "DNA_scene_types.h" +#include "DNA_meshdata_types.h" + +#include "BLI_listbase.h" +#include "BLI_string.h" +#include "BLI_utildefines.h" + +#include "BKE_depsgraph.h" +#include "BKE_global.h" +#include "BKE_particle.h" +#include "BKE_pointcache.h" + + +#include "ED_particle.h" + + + + +#include "particle_edit_utildefines.h" + +#include "physics_intern.h" + +static void free_PTCacheUndo(PTCacheUndo *undo) +{ + PTCacheEditPoint *point; + int i; + + for (i=0, point=undo->points; itotpoint; i++, point++) { + if (undo->particles && (undo->particles + i)->hair) + MEM_freeN((undo->particles + i)->hair); + if (point->keys) + MEM_freeN(point->keys); + } + if (undo->points) + MEM_freeN(undo->points); + + if (undo->particles) + MEM_freeN(undo->particles); + + BKE_ptcache_free_mem(&undo->mem_cache); +} + +static void make_PTCacheUndo(PTCacheEdit *edit, PTCacheUndo *undo) +{ + PTCacheEditPoint *point; + int i; + + undo->totpoint= edit->totpoint; + + if (edit->psys) { + ParticleData *pa; + + pa= undo->particles= MEM_dupallocN(edit->psys->particles); + + for (i=0; itotpoint; i++, pa++) + pa->hair= MEM_dupallocN(pa->hair); + + undo->psys_flag = edit->psys->flag; + } + else { + PTCacheMem *pm; + + BLI_duplicatelist(&undo->mem_cache, &edit->pid.cache->mem_cache); + pm = undo->mem_cache.first; + + for (; pm; pm=pm->next) { + for (i=0; idata[i] = MEM_dupallocN(pm->data[i]); + } + } + + point= undo->points = MEM_dupallocN(edit->points); + undo->totpoint = edit->totpoint; + + for (i=0; itotpoint; i++, point++) { + point->keys= MEM_dupallocN(point->keys); + /* no need to update edit key->co & key->time pointers here */ + } +} + +static void get_PTCacheUndo(PTCacheEdit *edit, PTCacheUndo *undo) +{ + ParticleSystem *psys = edit->psys; + ParticleData *pa; + HairKey *hkey; + POINT_P; KEY_K; + + LOOP_POINTS { + if (psys && psys->particles[p].hair) + MEM_freeN(psys->particles[p].hair); + + if (point->keys) + MEM_freeN(point->keys); + } + if (psys && psys->particles) + MEM_freeN(psys->particles); + if (edit->points) + MEM_freeN(edit->points); + if (edit->mirror_cache) { + MEM_freeN(edit->mirror_cache); + edit->mirror_cache= NULL; + } + + edit->points= MEM_dupallocN(undo->points); + edit->totpoint = undo->totpoint; + + LOOP_POINTS { + point->keys= MEM_dupallocN(point->keys); + } + + if (psys) { + psys->particles= MEM_dupallocN(undo->particles); + + psys->totpart= undo->totpoint; + + LOOP_POINTS { + pa = psys->particles + p; + hkey= pa->hair = MEM_dupallocN(pa->hair); + + LOOP_KEYS { + key->co= hkey->co; + key->time= &hkey->time; + hkey++; + } + } + + psys->flag = undo->psys_flag; + } + else { + PTCacheMem *pm; + int i; + + BKE_ptcache_free_mem(&edit->pid.cache->mem_cache); + + BLI_duplicatelist(&edit->pid.cache->mem_cache, &undo->mem_cache); + + pm = edit->pid.cache->mem_cache.first; + + for (; pm; pm=pm->next) { + for (i=0; idata[i] = MEM_dupallocN(pm->data[i]); + + BKE_ptcache_mem_pointers_init(pm); + + LOOP_POINTS { + LOOP_KEYS { + if ((int)key->ftime == (int)pm->frame) { + key->co = pm->cur[BPHYS_DATA_LOCATION]; + key->vel = pm->cur[BPHYS_DATA_VELOCITY]; + key->rot = pm->cur[BPHYS_DATA_ROTATION]; + key->time = &key->ftime; + } + } + BKE_ptcache_mem_pointers_incr(pm); + } + } + } +} + +void PE_undo_push(Scene *scene, const char *str) +{ + PTCacheEdit *edit= PE_get_current(scene, OBACT); + PTCacheUndo *undo; + int nr; + + if (!edit) return; + + /* remove all undos after (also when curundo==NULL) */ + while (edit->undo.last != edit->curundo) { + undo= edit->undo.last; + BLI_remlink(&edit->undo, undo); + free_PTCacheUndo(undo); + MEM_freeN(undo); + } + + /* make new */ + edit->curundo= undo= MEM_callocN(sizeof(PTCacheUndo), "particle undo file"); + BLI_strncpy(undo->name, str, sizeof(undo->name)); + BLI_addtail(&edit->undo, undo); + + /* and limit amount to the maximum */ + nr= 0; + undo= edit->undo.last; + while (undo) { + nr++; + if (nr==U.undosteps) break; + undo= undo->prev; + } + if (undo) { + while (edit->undo.first != undo) { + PTCacheUndo *first= edit->undo.first; + BLI_remlink(&edit->undo, first); + free_PTCacheUndo(first); + MEM_freeN(first); + } + } + + /* copy */ + make_PTCacheUndo(edit, edit->curundo); +} + +void PE_undo_step(Scene *scene, int step) +{ + PTCacheEdit *edit= PE_get_current(scene, OBACT); + + if (!edit) return; + + if (step==0) { + get_PTCacheUndo(edit, edit->curundo); + } + else if (step==1) { + + if (edit->curundo==NULL || edit->curundo->prev==NULL) { + /* pass */ + } + else { + if (G.debug & G_DEBUG) printf("undo %s\n", edit->curundo->name); + edit->curundo= edit->curundo->prev; + get_PTCacheUndo(edit, edit->curundo); + } + } + else { + /* curundo has to remain current situation! */ + + if (edit->curundo==NULL || edit->curundo->next==NULL) { + /* pass */ + } + else { + get_PTCacheUndo(edit, edit->curundo->next); + edit->curundo= edit->curundo->next; + if (G.debug & G_DEBUG) printf("redo %s\n", edit->curundo->name); + } + } + + DAG_id_tag_update(&OBACT->id, OB_RECALC_DATA); +} + +bool PE_undo_is_valid(Scene *scene) +{ + PTCacheEdit *edit= PE_get_current(scene, OBACT); + + if (edit) { + return (edit->undo.last != edit->undo.first); + } + return 0; +} + +void PTCacheUndo_clear(PTCacheEdit *edit) +{ + PTCacheUndo *undo; + + if (edit==NULL) return; + + undo= edit->undo.first; + while (undo) { + free_PTCacheUndo(undo); + undo= undo->next; + } + BLI_freelistN(&edit->undo); + edit->curundo= NULL; +} + +void PE_undo(Scene *scene) +{ + PE_undo_step(scene, 1); +} + +void PE_redo(Scene *scene) +{ + PE_undo_step(scene, -1); +} + +void PE_undo_number(Scene *scene, int nr) +{ + PTCacheEdit *edit= PE_get_current(scene, OBACT); + PTCacheUndo *undo; + int a=0; + + for (undo= edit->undo.first; undo; undo= undo->next, a++) { + if (a==nr) break; + } + edit->curundo= undo; + PE_undo_step(scene, 0); +} + + +/* get name of undo item, return null if no item with this index */ +/* if active pointer, set it to 1 if true */ +const char *PE_undo_get_name(Scene *scene, int nr, bool *r_active) +{ + PTCacheEdit *edit= PE_get_current(scene, OBACT); + PTCacheUndo *undo; + + if (r_active) *r_active = false; + + if (edit) { + undo= BLI_findlink(&edit->undo, nr); + if (undo) { + if (r_active && (undo == edit->curundo)) { + *r_active = true; + } + return undo->name; + } + } + return NULL; +} diff --git a/source/blender/editors/physics/particle_edit_utildefines.h b/source/blender/editors/physics/particle_edit_utildefines.h new file mode 100644 index 00000000000..7608b885459 --- /dev/null +++ b/source/blender/editors/physics/particle_edit_utildefines.h @@ -0,0 +1,50 @@ +/* + * ***** 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) 2007 by Janne Karhu. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/editors/physics/particle_edit_utildefines.h + * \ingroup edphys + */ + +#ifndef __PARTICLE_EDIT_UTILDEFNIES_H__ +#define __PARTICLE_EDIT_UTILDEFNIES_H__ + +#define KEY_K PTCacheEditKey *key; int k +#define POINT_P PTCacheEditPoint *point; int p +#define LOOP_POINTS for (p=0, point=edit->points; ptotpoint; p++, point++) +#define LOOP_VISIBLE_POINTS for (p=0, point=edit->points; ptotpoint; p++, point++) if (!(point->flag & PEP_HIDE)) +#define LOOP_SELECTED_POINTS for (p=0, point=edit->points; ptotpoint; p++, point++) if (point_is_selected(point)) +#define LOOP_UNSELECTED_POINTS for (p=0, point=edit->points; ptotpoint; p++, point++) if (!point_is_selected(point)) +#define LOOP_EDITED_POINTS for (p=0, point=edit->points; ptotpoint; p++, point++) if (point->flag & PEP_EDIT_RECALC) +#define LOOP_TAGGED_POINTS for (p=0, point=edit->points; ptotpoint; p++, point++) if (point->flag & PEP_TAG) +#define LOOP_KEYS for (k=0, key=point->keys; ktotkey; k++, key++) +#define LOOP_VISIBLE_KEYS for (k=0, key=point->keys; ktotkey; k++, key++) if (!(key->flag & PEK_HIDE)) +#define LOOP_SELECTED_KEYS for (k=0, key=point->keys; ktotkey; k++, key++) if ((key->flag & PEK_SELECT) && !(key->flag & PEK_HIDE)) +#define LOOP_TAGGED_KEYS for (k=0, key=point->keys; ktotkey; k++, key++) if (key->flag & PEK_TAG) + +#define KEY_WCO ((key->flag & PEK_USE_WCO) ? key->world_co : key->co) + +#endif /* __PARTICLE_EDIT_UTILDEFNIES_H__ */ diff --git a/source/blender/editors/physics/particle_object.c b/source/blender/editors/physics/particle_object.c index ce18083917f..b3e166ad56a 100644 --- a/source/blender/editors/physics/particle_object.c +++ b/source/blender/editors/physics/particle_object.c @@ -69,12 +69,6 @@ #include "physics_intern.h" -extern void PE_create_particle_edit(Scene *scene, Object *ob, PointCache *cache, ParticleSystem *psys); -extern void PTCacheUndo_clear(PTCacheEdit *edit); -extern void recalc_lengths(PTCacheEdit *edit); -extern void recalc_emitter_field(Object *ob, ParticleSystem *psys); -extern void update_world_cos(Object *ob, PTCacheEdit *edit); - #define KEY_K PTCacheEditKey *key; int k #define POINT_P PTCacheEditPoint *point; int p #define LOOP_POINTS for (p=0, point=edit->points; ptotpoint; p++, point++) diff --git a/source/blender/editors/physics/physics_intern.h b/source/blender/editors/physics/physics_intern.h index 6b6df15e987..cb281936634 100644 --- a/source/blender/editors/physics/physics_intern.h +++ b/source/blender/editors/physics/physics_intern.h @@ -33,6 +33,11 @@ #ifndef __PHYSICS_INTERN_H__ #define __PHYSICS_INTERN_H__ +struct Object; +struct PTCacheEdit; +struct ParticleSystem; +struct PointCache; +struct Scene; struct wmOperatorType; /* particle_edit.c */ @@ -63,6 +68,12 @@ void PARTICLE_OT_edited_clear(struct wmOperatorType *ot); void PARTICLE_OT_unify_length(struct wmOperatorType *ot); +void PTCacheUndo_clear(struct PTCacheEdit *edit); +void PE_create_particle_edit(struct Scene *scene, struct Object *ob, struct PointCache *cache, struct ParticleSystem *psys); +void recalc_lengths(struct PTCacheEdit *edit); +void recalc_emitter_field(struct Object *ob, struct ParticleSystem *psys); +void update_world_cos(struct Object *ob, struct PTCacheEdit *edit); + /* particle_object.c */ void OBJECT_OT_particle_system_add(struct wmOperatorType *ot); void OBJECT_OT_particle_system_remove(struct wmOperatorType *ot); -- cgit v1.2.3