Page MenuHome
Paste P2847

(An Untitled Masterwork)
ActivePublic

Authored by Sergey Sharybin (sergey) on Mar 23 2022, 11:56 AM.
diff --git a/source/blender/blenkernel/intern/mesh_convert.cc b/source/blender/blenkernel/intern/mesh_convert.cc
index 40c6fbcf67e..c2c5b98e43a 100644
--- a/source/blender/blenkernel/intern/mesh_convert.cc
+++ b/source/blender/blenkernel/intern/mesh_convert.cc
@@ -910,7 +910,8 @@ static void curve_to_mesh_eval_ensure(Object &object)
*
* So we create temporary copy of the object which will use same data as the original bevel, but
* will have no modifiers. */
- Object bevel_object = {{nullptr}};
+ Object bevel_object;
+ BKE_object_runtime_reset(&bevel_object);
if (curve.bevobj != nullptr) {
memcpy(&bevel_object, curve.bevobj, sizeof(bevel_object));
BLI_listbase_clear(&bevel_object.modifiers);
@@ -919,7 +920,8 @@ static void curve_to_mesh_eval_ensure(Object &object)
}
/* Same thing for taper. */
- Object taper_object = {{nullptr}};
+ Object taper_object;
+ BKE_object_runtime_reset(&taper_object);
if (curve.taperobj != nullptr) {
memcpy(&taper_object, curve.taperobj, sizeof(taper_object));
BLI_listbase_clear(&taper_object.modifiers);
diff --git a/source/blender/blenkernel/intern/object.cc b/source/blender/blenkernel/intern/object.cc
index 1e3b5d77fa7..f4ef6b86fff 100644
--- a/source/blender/blenkernel/intern/object.cc
+++ b/source/blender/blenkernel/intern/object.cc
@@ -3946,7 +3946,7 @@ bool BKE_object_minmax_dupli(Depsgraph *depsgraph,
/* pass */
}
else {
- Object temp_ob = *dob->ob;
+ Object temp_ob = DNA_shallow_copy(*dob->ob);
/* Do not modify the original boundbox. */
temp_ob.runtime.bb = nullptr;
BKE_object_replace_data_on_shallow_copy(&temp_ob, dob->ob_data);
diff --git a/source/blender/depsgraph/intern/depsgraph_query_iter.cc b/source/blender/depsgraph/intern/depsgraph_query_iter.cc
index 5788e8efa07..5e6ca61c6ee 100644
--- a/source/blender/depsgraph/intern/depsgraph_query_iter.cc
+++ b/source/blender/depsgraph/intern/depsgraph_query_iter.cc
@@ -167,7 +167,7 @@ bool deg_iterator_duplis_step(DEGObjectIterData *data)
/* Temporary object to evaluate. */
Object *dupli_parent = data->dupli_parent;
Object *temp_dupli_object = &data->temp_dupli_object;
- *temp_dupli_object = *dob->ob;
+ *temp_dupli_object = DNA_shallow_copy(*dob->ob);
temp_dupli_object->base_flag = dupli_parent->base_flag | BASE_FROM_DUPLI;
temp_dupli_object->base_local_view_bits = dupli_parent->base_local_view_bits;
temp_dupli_object->runtime.local_collections_bits =
diff --git a/source/blender/editors/object/object_transform.cc b/source/blender/editors/object/object_transform.cc
index 1970851c326..e3a577424e1 100644
--- a/source/blender/editors/object/object_transform.cc
+++ b/source/blender/editors/object/object_transform.cc
@@ -1695,13 +1695,13 @@ static void object_apply_rotation(Object *ob, const float rmat[3][3])
static void object_apply_location(Object *ob, const float loc[3])
{
/* quick but weak */
- Object ob_prev = *ob;
+ Object ob_prev = DNA_shallow_copy(*ob);
float mat[4][4];
copy_m4_m4(mat, ob->obmat);
copy_v3_v3(mat[3], loc);
BKE_object_apply_mat4(ob, mat, true, true);
copy_v3_v3(mat[3], ob->loc);
- *ob = ob_prev;
+ *ob = DNA_shallow_copy(ob_prev);
copy_v3_v3(ob->loc, mat[3]);
}
diff --git a/source/blender/freestyle/intern/python/BPy_Freestyle.cpp b/source/blender/freestyle/intern/python/BPy_Freestyle.cpp
index 63585df97a9..57c14c98395 100644
--- a/source/blender/freestyle/intern/python/BPy_Freestyle.cpp
+++ b/source/blender/freestyle/intern/python/BPy_Freestyle.cpp
@@ -31,6 +31,8 @@
#include "BPy_ViewMap.h"
#include "BPy_ViewShape.h"
+#include "DNA_scene_types.h"
+
#ifdef __cplusplus
extern "C" {
#endif
@@ -40,7 +42,6 @@ extern "C" {
//------------------------ MODULE FUNCTIONS ----------------------------------
#include "BKE_appdir.h"
-#include "DNA_scene_types.h"
#include "FRS_freestyle.h"
#include "RNA_access.h"
#include "RNA_prototypes.h"
diff --git a/source/blender/io/wavefront_obj/exporter/obj_export_mesh.cc b/source/blender/io/wavefront_obj/exporter/obj_export_mesh.cc
index 603e8ac755b..6eeea64c141 100644
--- a/source/blender/io/wavefront_obj/exporter/obj_export_mesh.cc
+++ b/source/blender/io/wavefront_obj/exporter/obj_export_mesh.cc
@@ -33,7 +33,7 @@ OBJMesh::OBJMesh(Depsgraph *depsgraph, const OBJExportParams &export_params, Obj
{
/* We need to copy the object because it may be in temporary space. */
Object *obj_eval = DEG_get_evaluated_object(depsgraph, mesh_object);
- export_object_eval_ = *obj_eval;
+ export_object_eval_ = DNA_shallow_copy(*obj_eval);
export_mesh_eval_ = export_params.apply_modifiers ?
BKE_object_get_evaluated_mesh(&export_object_eval_) :
BKE_object_get_pre_modified_mesh(&export_object_eval_);
@@ -382,8 +382,8 @@ void OBJMesh::store_normal_coords_and_indices()
normal_to_index.reserve(export_mesh_eval_->totpoly);
loop_to_normal_index_.resize(export_mesh_eval_->totloop);
loop_to_normal_index_.fill(-1);
- const float(*lnors)[3] = (const float(*)[3])(
- CustomData_get_layer(&export_mesh_eval_->ldata, CD_NORMAL));
+ const float(
+ *lnors)[3] = (const float(*)[3])(CustomData_get_layer(&export_mesh_eval_->ldata, CD_NORMAL));
for (int poly_index = 0; poly_index < export_mesh_eval_->totpoly; ++poly_index) {
const MPoly &mpoly = export_mesh_eval_->mpoly[poly_index];
bool need_per_loop_normals = lnors != nullptr || (mpoly.flag & ME_SMOOTH);
diff --git a/source/blender/makesdna/DNA_defs.h b/source/blender/makesdna/DNA_defs.h
index b4230209dd5..496afd3b663 100644
--- a/source/blender/makesdna/DNA_defs.h
+++ b/source/blender/makesdna/DNA_defs.h
@@ -46,3 +46,80 @@
/* non-id name variables should use this length */
#define MAX_NAME 64
+
+/* #DNA_DEFINE_CXX_METHODS is used to define C++ methods which are needed for proper/safe resource
+ * management, making unsafe (from ownership) operations explicit, and taking care of compiler
+ * specific warnings when dealing with members marked with DNA_DEPRECATED.
+ *
+ * The `class_name` argument is to match the structure name the macro is used from.
+ *
+ * Typical usage example:
+ *
+ * typedef struct Object {
+ * DNA_DEFINE_CXX_METHODS(Object)
+ * }
+ */
+#ifndef __cplusplus
+# define DNA_DEFINE_CXX_METHODS(class_name)
+#else
+
+/* Forward-declared here since there is no simple header file to be pulled for this functionality.
+ * Avoids pulling `string.h` from this header to get access to #memcpy. */
+extern "C" void _DNA_internal_memcpy(void *dst, const void *src, size_t size);
+
+namespace dna_internal {
+
+template<class T> class ShallowDataConstRef {
+ public:
+ constexpr explicit ShallowDataConstRef(const T &ref) : ref_(ref)
+ {
+ }
+
+ const T *operator&() const
+ {
+ return &ref_;
+ }
+
+ private:
+ const T &ref_;
+};
+
+} /* namespace dna_internal */
+
+# define DNA_DEFINE_CXX_METHODS(class_name) \
+ class_name() = default; \
+ ~class_name() = default; \
+ /* Delete copy and assignment which is not safe for resource ownership. */ \
+ /* If such copy is needed do it explicitly via #DNA_shallow_copy. */ \
+ class_name(const class_name &other) = delete; \
+ class_name(class_name &&other) noexcept = delete; \
+ class_name &operator=(const class_name &other) = delete; \
+ class_name &operator=(class_name &&other) = delete; \
+ /* Support for shallow copy. */ \
+ class_name(const dna_internal::ShallowDataConstRef<class_name> ref) \
+ { \
+ _DNA_internal_memcpy(this, &ref, sizeof(class_name)); \
+ } \
+ class_name &operator=(const dna_internal::ShallowDataConstRef<class_name> ref) \
+ { \
+ if (this != &ref) { \
+ _DNA_internal_memcpy(this, &ref, sizeof(class_name)); \
+ } \
+ return *this; \
+ }
+
+/* Create s shallow copy of the given object.
+ * The entire object is copied as-is using memory copy.
+ *
+ * Typical usage:
+ * Object temp_object = DNA_shallow_copy(*input_object);
+ *
+ * From the implementation detail go via copy constructor/assign operator defined in the structure.
+ */
+template<class T>
+[[nodiscard]] inline dna_internal::ShallowDataConstRef<T> DNA_shallow_copy(const T &other)
+{
+ return dna_internal::ShallowDataConstRef(other);
+}
+
+#endif
diff --git a/source/blender/makesdna/DNA_object_types.h b/source/blender/makesdna/DNA_object_types.h
index 9e0bf7dcc5a..c3708e25ee7 100644
--- a/source/blender/makesdna/DNA_object_types.h
+++ b/source/blender/makesdna/DNA_object_types.h
@@ -233,6 +233,8 @@ enum eObjectLineArt_Flags {
};
typedef struct Object {
+ DNA_DEFINE_CXX_METHODS(Object)
+
ID id;
/** Animation data (must be immediately after id for utilities to use it). */
struct AnimData *adt;
diff --git a/source/blender/makesdna/intern/dna_utils.c b/source/blender/makesdna/intern/dna_utils.c
index 8c86ef69ebd..089d7dd0e71 100644
--- a/source/blender/makesdna/intern/dna_utils.c
+++ b/source/blender/makesdna/intern/dna_utils.c
@@ -308,3 +308,15 @@ const char *DNA_struct_rename_legacy_hack_alias_from_static(const char *name)
}
/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Internal helpers for C++
+ * \{ */
+
+void _DNA_internal_memcpy(void *dst, const void *src, size_t size);
+void _DNA_internal_memcpy(void *dst, const void *src, size_t size)
+{
+ memcpy(dst, src, size);
+}
+
+/** \} */
diff --git a/source/blender/makesdna/intern/makesdna.c b/source/blender/makesdna/intern/makesdna.c
index 0d2f265a9b5..12ec7262906 100644
--- a/source/blender/makesdna/intern/makesdna.c
+++ b/source/blender/makesdna/intern/makesdna.c
@@ -620,6 +620,7 @@ static int preprocess_include(char *maindata, const int maindata_len)
int newlen = 0;
comment = 0;
a = maindata_len;
+ bool skip_until_closing_brace = false;
while (a--) {
if (cp[0] == '/' && cp[1] == '*') {
@@ -646,6 +647,17 @@ static int preprocess_include(char *maindata, const int maindata_len)
a -= 13;
cp += 13;
}
+ else if (match_identifier(cp, "DNA_DEFINE_CXX_METHODS")) {
+ /* single values are skipped already, so decrement 1 less */
+ a -= 21;
+ cp += 21;
+ skip_until_closing_brace = true;
+ }
+ else if (skip_until_closing_brace) {
+ if (cp[0] == ')') {
+ skip_until_closing_brace = false;
+ }
+ }
else {
md[0] = cp[0];
md++;

Event Timeline

Sergey Sharybin (sergey) created this object with edit policy "Administrators".