[Bf-blender-cvs] [8e8946c5458] soc-2021-adaptive-cloth: adaptive_cloth: AdaptiveMesh: sewing edge: get set of opposite edges
ishbosamiya
noreply at git.blender.org
Mon Aug 30 09:15:08 CEST 2021
Commit: 8e8946c5458b9557e72be3adc85139bafa96714a
Author: ishbosamiya
Date: Sat Aug 28 00:15:57 2021 +0530
Branches: soc-2021-adaptive-cloth
https://developer.blender.org/rB8e8946c5458b9557e72be3adc85139bafa96714a
adaptive_cloth: AdaptiveMesh: sewing edge: get set of opposite edges
Given a vertex, the function is supposed to add a sewing edge to it if
possible.
Currently the function gets the set of opposite edges. An opposite
edge is an edge that is in between 2 loose edges and these loose edges
are connected to edges that connect to the given vert.
e1 vert e5
e1_ov.________.________.e4_ov
| |
e2| |e4
._________________.
e2_ov opposite_edge e3_ov
(e3)
What needs to be done: With the set of opposite edges, if the edge is
splittable then it should be split and a new edge should be added
between vert and the newly created vert (vert created when splitting
the opposite edge).
===================================================================
M source/blender/blenkernel/intern/cloth_remesh.cc
===================================================================
diff --git a/source/blender/blenkernel/intern/cloth_remesh.cc b/source/blender/blenkernel/intern/cloth_remesh.cc
index 3e739151b32..89de321fdff 100644
--- a/source/blender/blenkernel/intern/cloth_remesh.cc
+++ b/source/blender/blenkernel/intern/cloth_remesh.cc
@@ -22,6 +22,7 @@
*/
#include "BLI_float2.hh"
+#include "BLI_vector.hh"
#include "DNA_cloth_types.h"
#include "DNA_mesh_types.h"
#include "DNA_modifier_types.h"
@@ -454,12 +455,14 @@ class AdaptiveMesh : public Mesh<NodeData<END>, VertData, EdgeData, internal::Em
/**
* Splits edges whose "size" is greater than 1.0
*
+ * If sewing is enabled, it tried to add sewing edges if necessary.
+ *
* Based on [1]
*
* Here "size" is determined by `Sizing` stores in `Vert`s of the
* `Edge`, using the function `Sizing::get_edge_size_sq()`.
*/
- void split_edges()
+ void split_edges(bool sewing_enabled)
{
auto splittable_edges_set = this->get_splittable_edge_indices_set();
do {
@@ -468,23 +471,8 @@ class AdaptiveMesh : public Mesh<NodeData<END>, VertData, EdgeData, internal::Em
if (!op_edge) {
continue;
}
- auto &edge = this->get_checked_edge(edge_index);
- auto mesh_diff = this->split_edge_triangulate(edge.get_self_index(), true);
-
-#if SHOULD_REMESH_DUMP_FILE
- auto after_split_msgpack = this->serialize();
- auto after_split_filename = static_remesh_name_gen.get_curr(
- "after_split_" + get_number_as_string(std::get<0>(edge_index.get_raw())));
- static_remesh_name_gen.gen_next();
- dump_file(after_split_filename, after_split_msgpack);
-#endif
-
- this->compute_info_adaptivemesh(mesh_diff);
- /* Flip edges of those faces that were created during the
- * split edge operation */
- auto added_faces = mesh_diff.get_added_faces();
- this->flip_edges(added_faces);
+ this->split_edge_adaptivemesh(edge_index, sewing_enabled);
}
splittable_edges_set = this->get_splittable_edge_indices_set();
@@ -568,7 +556,8 @@ class AdaptiveMesh : public Mesh<NodeData<END>, VertData, EdgeData, internal::Em
} while (active_faces.size() != 0);
}
- void static_remesh(const Sizing &sizing)
+ template<typename ExtraData>
+ void static_remesh(const Sizing &sizing, const AdaptiveRemeshParams<END, ExtraData> ¶ms)
{
#if SHOULD_REMESH_DUMP_FILE
auto static_remesh_start_msgpack = this->serialize();
@@ -590,8 +579,10 @@ class AdaptiveMesh : public Mesh<NodeData<END>, VertData, EdgeData, internal::Em
this->set_edge_sizes();
+ bool sewing_enabled = params.flags & ADAPTIVE_REMESH_PARAMS_SEWING;
+
/* Split the edges */
- this->split_edges();
+ this->split_edges(sewing_enabled);
/* Collapse the edges */
this->collapse_edges();
@@ -680,6 +671,145 @@ class AdaptiveMesh : public Mesh<NodeData<END>, VertData, EdgeData, internal::Em
return splittable_edge_indices;
}
+ /**
+ * Split the given edge and handle adaptivemesh specific
+ * requirements like running `this->flip_edges` on faces created
+ * during splitting, handling sewing if enabled.
+ */
+ void split_edge_adaptivemesh(const EdgeIndex &edge_index, bool sewing_enabled)
+ {
+ auto &edge = this->get_checked_edge(edge_index);
+ auto mesh_diff = this->split_edge_triangulate(edge.get_self_index(), true);
+
+#if SHOULD_REMESH_DUMP_FILE
+ auto after_split_msgpack = this->serialize();
+ auto after_split_filename = static_remesh_name_gen.get_curr(
+ "after_split_" + get_number_as_string(std::get<0>(edge_index.get_raw())));
+ static_remesh_name_gen.gen_next();
+ dump_file(after_split_filename, after_split_msgpack);
+#endif
+
+ this->compute_info_adaptivemesh(mesh_diff);
+
+ if (sewing_enabled) {
+ BLI_assert(mesh_diff.get_added_nodes().size() == 1);
+ std::cout << "mesh_diff.get_added_verts().size(): " << mesh_diff.get_added_verts().size()
+ << std::endl;
+ this->try_adding_sewing_edge(mesh_diff.get_added_verts()[0]);
+ }
+
+ /* Flip edges of those faces that were created during the
+ * split edge operation */
+ auto added_faces = mesh_diff.get_added_faces();
+ this->flip_edges(added_faces);
+ }
+
+ /**
+ * Tries to add a sewing edge to `vert_index` if it is possible.
+ *
+ * Adding a sewing edge is possible if the following checks are
+ * true.
+ *
+ * => If there is a loose edge attached to one of the adjacent edges
+ * of the given vert.
+ *
+ * => There is an adjacent edge to that loose edge which can be
+ * split and it has another loose edge adjacent to it which can loop
+ * back the given vert via an edge.
+ */
+ void try_adding_sewing_edge(const VertIndex &vert_index)
+ {
+ /* vert: is the vert that is being tested.
+ *
+ * e1: is an incident edge of `vert`.
+ * e1_ov: is the other vertex of `e1` compared to `vert`.
+ *
+ * e2: is supposed to be the loose edge
+ * e2_ov: is the other vertex of `e2` compared to `e1_ov`.
+ *
+ * opposite_edges: list of all edges that may be split to add the
+ * sewing edge between `vert` and and the vert created when
+ * `opposite_edge` is split.
+ */
+ /*
+ * e1 vert e5
+ * e1_ov.________.________.e4_ov
+ * | |
+ * e2| |e4
+ * ._________________.
+ * e2_ov opposite_edge e3_ov
+ * (e3)
+ *
+ */
+
+ /* TODO(ish): Optimizations can be done, do an early check if
+ * there are at least 2 edges incident on `vert` that have an
+ * adjacent loose edge. (check if e1 and e5 exist).
+ *
+ * Another optimization can be to find the opposite edge before
+ * splitting the edge. This does mean that it is not so
+ * generalized, like it would not be able to add a sewing edge to
+ * an existing vert but it will be a lot faster.
+ */
+ const auto &vert = this->get_checked_vert(vert_index);
+
+ blender::Vector<EdgeIndex> opposite_edges;
+
+ /* Get the list of all opposite edges */
+ for (const auto &e1_index : vert.get_edges()) {
+ const auto &e1 = this->get_checked_edge(e1_index);
+
+ const auto e1_ov_index = e1.get_checked_other_vert(vert_index);
+ const auto &e1_ov = this->get_checked_vert(e1_ov_index);
+
+ for (const auto &e2_index : e1_ov.get_edges()) {
+ const auto &e2 = this->get_checked_edge(e2_index);
+
+ if (e2.is_loose() == false) {
+ continue;
+ }
+
+ const auto e2_ov_index = e2.get_checked_other_vert(e1_ov_index);
+ const auto &e2_ov = this->get_checked_vert(e2_ov_index);
+
+ for (const auto &e3_index : e2_ov.get_edges()) {
+ const auto &e3 = this->get_checked_edge(e3_index);
+
+ const auto e3_ov_index = e3.get_checked_other_vert(e2_ov_index);
+ const auto &e3_ov = this->get_checked_vert(e3_ov_index);
+
+ for (const auto &e4_index : e3_ov.get_edges()) {
+ const auto &e4 = this->get_checked_edge(e4_index);
+
+ if (e4.is_loose() == false) {
+ continue;
+ }
+
+ const auto e4_ov_index = e4.get_checked_other_vert(e3_ov_index);
+ const auto &e4_ov = this->get_checked_vert(e4_ov_index);
+
+ for (const auto &e5_index : e4_ov.get_edges()) {
+ const auto &e5 = this->get_checked_edge(e5_index);
+
+ const auto e5_ov_index = e5.get_checked_other_vert(e4_ov_index);
+
+ if (e5_ov_index == vert_index) {
+ opposite_edges.append_non_duplicates(e3_index);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ /* Iterate over `opposite_edges`, if an `opposite_edge` is
+ * splittable, then split it and create a new edge between the
+ * `new_vert` and `vert` */
+
+ std::cout << "vert_index: " << vert_index << " opposite_edges: " << opposite_edges
+ << std::endl;
+ }
+
/**
* Checks if the edge is flippable nor not.
*
@@ -1303,7 +1433,7 @@ Mesh *adaptive_remesh(const AdaptiveRemeshParams<END, ExtraData> ¶ms,
auto m = float2x2::identity();
m = m * (1.0 / size_min);
internal::Sizing vert_sizing(std::move(m));
- adaptive_mesh.static_remesh(vert_sizing);
+ adaptive_mesh.static_remesh(vert_sizing, params);
}
/* set back data from `AdaptiveMesh` to whatever needs it */
More information about the Bf-blender-cvs
mailing list