[Bf-blender-cvs] [d650162ecd4] master: Curves: Add initial undo system
Falk David
noreply at git.blender.org
Fri Jan 20 16:32:41 CET 2023
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);
More information about the Bf-blender-cvs
mailing list