Commit: d650162ecd47d6c12e1d66ffbd413e4f3acb120d Author: Falk David Date: Fri Jan 20 16:32:25 2023 +0100 Branches: master https://developer.blender.org/rBd650162ecd47d6c12e1d66ffbd413e4f3acb120d
Curves: Add initial undo system This adds an `UndoType` for the `Curves` object, for edit mode. For now, this will only store the `CurvesGeometry` at every step. Other properties such as the `selection_domain` or the `surface` object will have to be dealt with in subsequent commits. Differential Revision: https://developer.blender.org/D16979 =================================================================== M source/blender/editors/curves/CMakeLists.txt M source/blender/editors/curves/intern/curves_ops.cc A source/blender/editors/curves/intern/curves_undo.cc M source/blender/editors/include/ED_curves.h M source/blender/editors/undo/CMakeLists.txt M source/blender/editors/undo/undo_system_types.c =================================================================== diff --git a/source/blender/editors/curves/CMakeLists.txt b/source/blender/editors/curves/CMakeLists.txt index bba85f9c77a..873df89b40c 100644 --- a/source/blender/editors/curves/CMakeLists.txt +++ b/source/blender/editors/curves/CMakeLists.txt @@ -12,6 +12,7 @@ set(INC ../../makesdna ../../makesrna ../../windowmanager + ../../../../intern/clog ../../../../intern/guardedalloc ../../bmesh @@ -24,6 +25,7 @@ set(SRC intern/curves_data.cc intern/curves_ops.cc intern/curves_selection.cc + intern/curves_undo.cc ) set(LIB diff --git a/source/blender/editors/curves/intern/curves_ops.cc b/source/blender/editors/curves/intern/curves_ops.cc index d084317014d..24aa362b973 100644 --- a/source/blender/editors/curves/intern/curves_ops.cc +++ b/source/blender/editors/curves/intern/curves_ops.cc @@ -60,7 +60,7 @@ namespace blender::ed::curves { -static bool object_has_editable_curves(const Main &bmain, const Object &object) +bool object_has_editable_curves(const Main &bmain, const Object &object) { if (object.type != OB_CURVES) { return false; @@ -95,7 +95,10 @@ VectorSet<Curves *> get_unique_editable_curves(const bContext &C) return unique_curves; } -static bool curves_poll_impl(bContext *C, const bool check_editable, const bool check_surface) +static bool curves_poll_impl(bContext *C, + const bool check_editable, + const bool check_surface, + const bool check_edit_mode) { Object *object = CTX_data_active_object(C); if (object == nullptr || object->type != OB_CURVES) { @@ -113,27 +116,37 @@ static bool curves_poll_impl(bContext *C, const bool check_editable, const bool return false; } } + if (check_edit_mode) { + if ((object->mode & OB_MODE_EDIT) == 0) { + return false; + } + } return true; } +bool editable_curves_in_edit_mode_poll(bContext *C) +{ + return curves_poll_impl(C, true, false, true); +} + bool editable_curves_with_surface_poll(bContext *C) { - return curves_poll_impl(C, true, true); + return curves_poll_impl(C, true, true, false); } bool curves_with_surface_poll(bContext *C) { - return curves_poll_impl(C, false, true); + return curves_poll_impl(C, false, true, false); } bool editable_curves_poll(bContext *C) { - return curves_poll_impl(C, false, false); + return curves_poll_impl(C, false, false, false); } bool curves_poll(bContext *C) { - return curves_poll_impl(C, false, false); + return curves_poll_impl(C, false, false, false); } using bke::CurvesGeometry; diff --git a/source/blender/editors/curves/intern/curves_undo.cc b/source/blender/editors/curves/intern/curves_undo.cc new file mode 100644 index 00000000000..551fbadfefc --- /dev/null +++ b/source/blender/editors/curves/intern/curves_undo.cc @@ -0,0 +1,141 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +/** \file + * \ingroup edcurves + */ + +#include "BKE_context.h" +#include "BKE_curves.hh" +#include "BKE_main.h" +#include "BKE_object.h" +#include "BKE_undo_system.h" + +#include "CLG_log.h" + +#include "DEG_depsgraph.h" + +#include "ED_curves.h" +#include "ED_undo.h" + +#include "MEM_guardedalloc.h" + +#include "WM_api.h" +#include "WM_types.h" + +static CLG_LogRef LOG = {"ed.undo.curves"}; + +namespace blender::ed::curves::undo { + +/* -------------------------------------------------------------------- */ +/** \name Implements ED Undo System + * + * \note This is similar for all edit-mode types. + * \{ */ + +struct StepObject { + UndoRefID_Object obedit_ref = {}; + bke::CurvesGeometry geometry = {}; +}; + +struct CurvesUndoStep { + UndoStep step; + Array<StepObject> objects; +}; + +static bool step_encode(bContext *C, Main *bmain, UndoStep *us_p) +{ + CurvesUndoStep *us = reinterpret_cast<CurvesUndoStep *>(us_p); + + const Scene *scene = CTX_data_scene(C); + ViewLayer *view_layer = CTX_data_view_layer(C); + uint objects_num = 0; + Object **objects = ED_undo_editmode_objects_from_view_layer(scene, view_layer, &objects_num); + + new (&us->objects) Array<StepObject>(objects_num); + + threading::parallel_for(us->objects.index_range(), 8, [&](const IndexRange range) { + for (const int i : range) { + Object *ob = objects[i]; + const Curves &curves_id = *static_cast<Curves *>(ob->data); + StepObject &object = us->objects[i]; + + object.obedit_ref.ptr = ob; + object.geometry = bke::CurvesGeometry::wrap(curves_id.geometry); + } + }); + MEM_SAFE_FREE(objects); + + bmain->is_memfile_undo_flush_needed = true; + + return true; +} + +static void step_decode( + bContext *C, Main *bmain, UndoStep *us_p, const eUndoStepDir /*dir*/, bool /*is_final*/) +{ + CurvesUndoStep *us = reinterpret_cast<CurvesUndoStep *>(us_p); + + ED_undo_object_editmode_restore_helper(C, + &us->objects.first().obedit_ref.ptr, + us->objects.size(), + sizeof(decltype(us->objects)::value_type)); + + BLI_assert(BKE_object_is_in_editmode(us->objects.first().obedit_ref.ptr)); + + for (const StepObject &object : us->objects) { + Curves &curves_id = *static_cast<Curves *>(object.obedit_ref.ptr->data); + + /* Overwrite the curves geometry. */ + bke::CurvesGeometry::wrap(curves_id.geometry) = object.geometry; + + DEG_id_tag_update(&curves_id.id, ID_RECALC_GEOMETRY); + } + + ED_undo_object_set_active_or_warn(CTX_data_scene(C), + CTX_data_view_layer(C), + us->objects.first().obedit_ref.ptr, + us_p->name, + &LOG); + + bmain->is_memfile_undo_flush_needed = true; + + WM_event_add_notifier(C, NC_GEOM | ND_DATA, nullptr); +} + +static void step_free(UndoStep *us_p) +{ + CurvesUndoStep *us = reinterpret_cast<CurvesUndoStep *>(us_p); + us->objects.~Array(); +} + +static void foreach_ID_ref(UndoStep *us_p, + UndoTypeForEachIDRefFn foreach_ID_ref_fn, + void *user_data) +{ + CurvesUndoStep *us = reinterpret_cast<CurvesUndoStep *>(us_p); + + for (const StepObject &object : us->objects) { + foreach_ID_ref_fn(user_data, ((UndoRefID *)&object.obedit_ref)); + } +} + +/** \} */ + +} // namespace blender::ed::curves::undo + +void ED_curves_undosys_type(UndoType *ut) +{ + using namespace blender::ed; + + ut->name = "Edit Curves"; + ut->poll = curves::editable_curves_in_edit_mode_poll; + ut->step_encode = curves::undo::step_encode; + ut->step_decode = curves::undo::step_decode; + ut->step_free = curves::undo::step_free; + + ut->step_foreach_ID_ref = curves::undo::foreach_ID_ref; + + ut->flags = UNDOTYPE_FLAG_NEED_CONTEXT_FOR_ENCODE; + + ut->step_size = sizeof(curves::undo::CurvesUndoStep); +} diff --git a/source/blender/editors/include/ED_curves.h b/source/blender/editors/include/ED_curves.h index bf6b78676b9..74eb290e98a 100644 --- a/source/blender/editors/include/ED_curves.h +++ b/source/blender/editors/include/ED_curves.h @@ -18,6 +18,7 @@ extern "C" { * \{ */ void ED_operatortypes_curves(void); +void ED_curves_undosys_type(struct UndoType *ut); /** * Return an owning pointer to an array of point normals the same size as the number of control @@ -43,6 +44,7 @@ float (*ED_curves_point_normals_array_create(const struct Curves *curves_id))[3] namespace blender::ed::curves { +bool object_has_editable_curves(const Main &bmain, const Object &object); bke::CurvesGeometry primitive_random_sphere(int curves_size, int points_per_curve); VectorSet<Curves *> get_unique_editable_curves(const bContext &C); void ensure_surface_deformation_node_exists(bContext &C, Object &curves_ob); @@ -52,6 +54,7 @@ void ensure_surface_deformation_node_exists(bContext &C, Object &curves_ob); * \{ */ bool editable_curves_with_surface_poll(bContext *C); +bool editable_curves_in_edit_mode_poll(bContext *C); bool curves_with_surface_poll(bContext *C); bool editable_curves_poll(bContext *C); bool curves_poll(bContext *C); diff --git a/source/blender/editors/undo/CMakeLists.txt b/source/blender/editors/undo/CMakeLists.txt index 11101bb6b25..cfebb2cab1c 100644 --- a/source/blender/editors/undo/CMakeLists.txt +++ b/source/blender/editors/undo/CMakeLists.txt @@ -29,6 +29,7 @@ set(LIB bf_blenkernel bf_blenlib bf_editor_curve + bf_editor_curves bf_editor_lattice bf_editor_mesh bf_editor_metaball diff --git a/source/blender/editors/undo/undo_system_types.c b/source/blender/editors/undo/undo_system_types.c index a4d6df9b5c2..af74a7f3c04 100644 --- a/source/blender/editors/undo/undo_system_types.c +++ b/source/blender/editors/undo/undo_system_types.c @@ -10,6 +10,7 @@ #include "ED_armature.h" #include "ED_curve.h" +#include "ED_curves.h" #include "ED_lattice.h" #include "ED_mball.h" #include "ED_mesh.h" @@ -32,6 +33,7 @@ void ED_undosys_type_init(void) BKE_undosys_type_append(ED_lattice_undosys_type); BKE_undosys_type_append(ED_mball_undosys_type); BKE_undosys_type_append(ED_mesh_undosys_type); + BKE_undosys_type_append(ED_curves_undosys_type); /* Paint Modes */ BKE_UNDOSYS_TYPE_IMAGE = BKE_undosys_type_append(ED_image_undosys_type); _______________________________________________ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org List details, subscription details or unsubscribe: https://lists.blender.org/mailman/listinfo/bf-blender-cvs