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;
}
_______________________________________________
Bf-blender-cvs mailing list
[email protected]
List details, subscription details or unsubscribe:
https://lists.blender.org/mailman/listinfo/bf-blender-cvs