[Bf-blender-cvs] [161fa5b4daa] soc-2021-adaptive-cloth: adaptive_cloth: AdaptiveMesh: aspect ratio test when collapsing edge
ishbosamiya
noreply at git.blender.org
Sun Aug 22 17:23:39 CEST 2021
Commit: 161fa5b4daa8403464caaa8783bbd33067c2d527
Author: ishbosamiya
Date: Fri Aug 13 14:35:38 2021 +0530
Branches: soc-2021-adaptive-cloth
https://developer.blender.org/rB161fa5b4daa8403464caaa8783bbd33067c2d527
adaptive_cloth: AdaptiveMesh: aspect ratio test when collapsing edge
Test to see if the faces generated when collapsing the edge will not
meet the aspect ratio criterion.
There is a lot more information about which algorithm is used for
calculating the aspect ratio in the code comments. A gist of it would
be that there many different ways to calculate the aspect ratio of a
triangle and each provides a different end result suitable for
different needs. This makes it hard to select the right algorithm.
===================================================================
M source/blender/blenkernel/BKE_cloth_remesh.hh
M source/blender/blenkernel/intern/cloth_remesh.cc
===================================================================
diff --git a/source/blender/blenkernel/BKE_cloth_remesh.hh b/source/blender/blenkernel/BKE_cloth_remesh.hh
index 6e7dd9e8db3..bee40696436 100644
--- a/source/blender/blenkernel/BKE_cloth_remesh.hh
+++ b/source/blender/blenkernel/BKE_cloth_remesh.hh
@@ -40,6 +40,9 @@
* https://dl.acm.org/doi/10.1145/2461912.2462010
* http://graphics.berkeley.edu/papers/Narain-FCA-2013-07/Narain-FCA-2013-07.pdf
*
+ * [4] "What Is a Good Linear Finite Element? Interpolation,
+ * Conditioning, Anisotropy, and Quality Measures" by Jonathan Richard Shewchuk
+ *
* *****************************************************************************/
#include "BKE_mesh.h"
diff --git a/source/blender/blenkernel/intern/cloth_remesh.cc b/source/blender/blenkernel/intern/cloth_remesh.cc
index 32f21e709bd..88c87362cf6 100644
--- a/source/blender/blenkernel/intern/cloth_remesh.cc
+++ b/source/blender/blenkernel/intern/cloth_remesh.cc
@@ -21,6 +21,7 @@
* \ingroup bke
*/
+#include "BLI_float2.hh"
#include "DNA_cloth_types.h"
#include "DNA_mesh_types.h"
#include "DNA_modifier_types.h"
@@ -29,6 +30,7 @@
#include "BLI_assert.h"
#include "BLI_float2x2.hh"
#include "BLI_kdopbvh.h"
+#include "BLI_math.h"
#include "BLI_math_vector.h"
#include "BLI_utildefines.h"
@@ -833,10 +835,77 @@ class AdaptiveMesh : public Mesh<NodeData<END>, VertData, EdgeData, internal::Em
return flippable_edge_indices;
}
+ /**
+ * Calculates the aspect ratio of the triangle formed by the given
+ * positions (p1, p2, p3).
+ *
+ * Refer to [4] for more information about the aspect ratio
+ * calculation. Using "The measure associated with interpolation
+ * error in the usual (weaker) bounds given by approximation
+ * theory. Nonsmooth." in table 7.
+ */
+ float compute_aspect_ratio(const float2 &p1, const float2 &p2, const float2 &p3) const
+ {
+ /* It is possible to use "The aspect ratio, or ratio
+ * between the minimum and maximum dimensions of the triangle.
+ * Nonsmooth." from [4] but the current implemention seems to
+ * provide results closer to that of [1] */
+
+ const auto l1 = (p2 - p1).length();
+ const auto l2 = (p3 - p2).length();
+ const auto l3 = (p1 - p3).length();
+
+ const auto l_max = max_ff(max_ff(l1, l2), l3);
+
+ const auto cross_2d = [](const float2 &a, const float2 &b) { return a.x * b.y - a.y * b.x; };
+
+ const auto area = cross_2d(p2 - p1, p3 - p1) * 0.5;
+
+ return 4.0 * M_SQRT3 * area / (l_max * (l1 + l2 + l3));
+ }
+
+ /**
+ * Calculates the aspect ratio of the triangle described by the UVs
+ * of the `Vert`s provided.
+ */
+ float compute_aspect_ratio(const AdaptiveVert &v1,
+ const AdaptiveVert &v2,
+ const AdaptiveVert &v3) const
+ {
+ return this->compute_aspect_ratio(v1.get_uv(), v2.get_uv(), v3.get_uv());
+ }
+
+ /**
+ * Easy call to above when only indices available
+ */
+ float compute_aspect_ratio(const VertIndex &v1_index,
+ const VertIndex &v2_index,
+ const VertIndex &v3_index) const
+ {
+ return this->compute_aspect_ratio(this->get_checked_vert(v1_index),
+ this->get_checked_vert(v2_index),
+ this->get_checked_vert(v3_index));
+ }
+
+ /**
+ * Calculates the aspect ratio of given triangle
+ *
+ * Note: This function asserts in debug mode that the given face is
+ * a triangle. In release mode it will lead to undefined behaviour
+ * when the number of verts in the face is not 3.
+ */
+ float compute_aspect_ratio(const AdaptiveFace &face) const
+ {
+ BLI_assert(face.get_verts().size() == 3);
+ return this->compute_aspect_ratio(
+ face.get_verts()[0], face.get_verts()[1], face.get_verts()[2]);
+ }
+
bool is_edge_collapseable_adaptivemesh(const AdaptiveEdge &edge, bool verts_swapped) const
{
- /* TODO(ish): expose small_value to gui */
+ /* TODO(ish): expose small_value, aspect_ratio_min to gui */
const auto small_value = 0.2;
+ const auto aspect_ratio_min = 0.1;
if (this->is_edge_collapseable(edge.get_self_index(), verts_swapped, true) == false) {
return false;
@@ -900,7 +969,7 @@ class AdaptiveMesh : public Mesh<NodeData<END>, VertData, EdgeData, internal::Em
}
}
- /* Face inversion check */
+ /* Face inversion check and aspect ratio check */
const auto v1_face_indices = this->get_checked_face_indices_of_vert(v1_index);
for (const auto &face_index : v1_face_indices) {
auto &f = this->get_checked_face(face_index);
@@ -935,13 +1004,19 @@ class AdaptiveMesh : public Mesh<NodeData<END>, VertData, EdgeData, internal::Em
this->get_checked_vert(vert_indices[2]));
const auto &expected_normal = f.get_normal();
+ /* Face inversion check */
if (float3::dot(new_normal, expected_normal) <= 0.0) {
return false;
}
+
+ /* Aspect ratio check */
+ if (this->compute_aspect_ratio(vert_indices[0], vert_indices[1], vert_indices[2]) <
+ aspect_ratio_min) {
+ return false;
+ }
}
}
- /* TODO(ish): aspect ratio test */
return true;
}
More information about the Bf-blender-cvs
mailing list