[Bf-blender-cvs] [5143a10288a] soc-2021-adaptive-cloth: adaptive_cloth: fix: add_empty_interp_element() crash sometimes

ishbosamiya noreply at git.blender.org
Mon Jul 12 08:23:47 CEST 2021


Commit: 5143a10288a67ab8e2a3ccf0232675004cb962a7
Author: ishbosamiya
Date:   Wed Jul 7 17:54:41 2021 +0530
Branches: soc-2021-adaptive-cloth
https://developer.blender.org/rB5143a10288a67ab8e2a3ccf0232675004cb962a7

adaptive_cloth: fix: add_empty_interp_element() crash sometimes

Since the elements have a reference to the `Arena`, if the `Arena` changes in size, which can happen because of `add_empty_element()`, then the references can become invalid. Realloc can create memory space elsewhere and copy the contents, the references to the previous memory space are not updated which means references to the previous memory space are invalid.

There are three ways to fix this:
 - Create a copy and work on the copy, this is inefficient
 - Get a reference to that element again, this is efficient but may not be possible always
 - Don't use the reference after an operation that can lead to the invalidation of the reference, this is the most efficient way but may not be possible always

Decided to go with the third way in this case.

Side note: Having a borrow checker completely eliminates such problems. Rust should be the way forward.

===================================================================

M	source/blender/blenkernel/BKE_cloth_remesh.hh

===================================================================

diff --git a/source/blender/blenkernel/BKE_cloth_remesh.hh b/source/blender/blenkernel/BKE_cloth_remesh.hh
index 3587659fd36..1979b0dc2ab 100644
--- a/source/blender/blenkernel/BKE_cloth_remesh.hh
+++ b/source/blender/blenkernel/BKE_cloth_remesh.hh
@@ -1340,8 +1340,21 @@ template<typename END, typename EVD, typename EED, typename EFD> class Mesh {
     auto pos = (node_1.pos + node_2.pos) * 0.5;
     /* The normal calculation might not be valid but good enough */
     auto normal = (node_1.normal + node_2.normal) * 0.5;
+
+    std::optional<END> extra_data = std::nullopt;
+    if (node_1.extra_data && node_2.extra_data) {
+      extra_data = node_1.extra_data.value().interp(node_2.extra_data.value());
+    }
+    else if (node_1.extra_data) {
+      extra_data = node_1.extra_data;
+    }
+    else if (node_2.extra_data) {
+      extra_data = node_2.extra_data;
+    }
+
     auto &new_node = this->add_empty_node(pos, normal);
-    new_node.extra_data = interp(node_1.extra_data, node_2.extra_data);
+    new_node.extra_data = extra_data;
+
     return new_node;
   }
 
@@ -1354,8 +1367,21 @@ template<typename END, typename EVD, typename EED, typename EFD> class Mesh {
   Vert<EVD> &add_empty_interp_vert(const Vert<EVD> &vert_1, const Vert<EVD> &vert_2)
   {
     auto uv = (vert_1.uv + vert_2.uv) * 0.5;
+
+    std::optional<EVD> extra_data = std::nullopt;
+    if (vert_1.extra_data && vert_2.extra_data) {
+      extra_data = vert_1.extra_data.value().interp(vert_2.extra_data.value());
+    }
+    else if (vert_1.extra_data) {
+      extra_data = vert_1.extra_data;
+    }
+    else if (vert_2.extra_data) {
+      extra_data = vert_2.extra_data;
+    }
+
     auto &new_vert = this->add_empty_vert(uv);
-    new_vert.extra_data = interp(vert_1.extra_data, vert_2.extra_data);
+    new_vert.extra_data = extra_data;
+
     return new_vert;
   }
 
@@ -1367,8 +1393,20 @@ template<typename END, typename EVD, typename EED, typename EFD> class Mesh {
    */
   Edge<EED> &add_empty_interp_edge(const Edge<EED> &edge_1, const Edge<EED> &edge_2)
   {
+    std::optional<EED> extra_data = std::nullopt;
+    if (edge_1.extra_data && edge_2.extra_data) {
+      extra_data = edge_1.extra_data.value().interp(edge_2.extra_data.value());
+    }
+    else if (edge_1.extra_data) {
+      extra_data = edge_1.extra_data;
+    }
+    else if (edge_2.extra_data) {
+      extra_data = edge_2.extra_data;
+    }
+
     auto &new_edge = this->add_empty_edge();
-    new_edge.extra_data = interp(edge_1.extra_data, edge_2.extra_data);
+    new_edge.extra_data = extra_data;
+
     return new_edge;
   }
 
@@ -1382,8 +1420,21 @@ template<typename END, typename EVD, typename EED, typename EFD> class Mesh {
   {
     /* The normal calculation might not be valid but good enough */
     auto normal = (face_1.normal + face_2.normal) * 0.5;
+
+    std::optional<EFD> extra_data = std::nullopt;
+    if (face_1.extra_data && face_2.extra_data) {
+      extra_data = face_1.extra_data.value().interp(face_2.extra_data.value());
+    }
+    else if (face_1.extra_data) {
+      extra_data = face_1.extra_data;
+    }
+    else if (face_2.extra_data) {
+      extra_data = face_2.extra_data;
+    }
+
     auto &new_face = this->add_empty_face(normal);
-    new_face.extra_data = interp(face_1.extra_data, face_2.extra_data);
+    new_face.extra_data = extra_data;
+
     return new_face;
   }



More information about the Bf-blender-cvs mailing list