[Bf-blender-cvs] [740f622a036] soc-2021-adaptive-cloth: adaptive_cloth: Mesh: collapse_edge_triangulate() first draft
ishbosamiya
noreply at git.blender.org
Mon Jul 12 08:23:51 CEST 2021
Commit: 740f622a036e92af54c90e1da4fc9eecf82175d3
Author: ishbosamiya
Date: Sat Jul 10 17:13:47 2021 +0530
Branches: soc-2021-adaptive-cloth
https://developer.blender.org/rB740f622a036e92af54c90e1da4fc9eecf82175d3
adaptive_cloth: Mesh: collapse_edge_triangulate() first draft
===================================================================
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 42c8f495026..9ad5f39077b 100644
--- a/source/blender/blenkernel/BKE_cloth_remesh.hh
+++ b/source/blender/blenkernel/BKE_cloth_remesh.hh
@@ -1360,7 +1360,7 @@ template<typename END, typename EVD, typename EED, typename EFD> class Mesh {
blender::Vector<Face<EFD>> deleted_faces;
auto &edge_pre = this->get_checked_edge(edge_index);
- auto [edge_vert_1_pre, edge_vert_2_pre] = this->get_checked_verts_of_edge(edge_pre);
+ auto [edge_vert_1_pre, edge_vert_2_pre] = this->get_checked_verts_of_edge(edge_pre, false);
auto &edge_node_1 = this->get_checked_node_of_vert(edge_vert_1_pre);
auto &edge_node_2 = this->get_checked_node_of_vert(edge_vert_2_pre);
@@ -1376,12 +1376,12 @@ template<typename END, typename EVD, typename EED, typename EFD> class Mesh {
for (const auto &edge_index : edge_indices) {
auto &edge_a = this->get_checked_edge(edge_index);
- auto [edge_vert_1_a, edge_vert_2_a] = this->get_checked_verts_of_edge(edge_a);
+ auto [edge_vert_1_a, edge_vert_2_a] = this->get_checked_verts_of_edge(edge_a, false);
/* Create the new vert by interpolating the verts of the edge */
auto &new_vert = this->add_empty_interp_vert(edge_vert_1_a, edge_vert_2_a);
- auto [edge_vert_1_b, edge_vert_2_b] = this->get_checked_verts_of_edge(edge_a);
+ auto [edge_vert_1_b, edge_vert_2_b] = this->get_checked_verts_of_edge(edge_a, false);
/* Link new_vert with new_node */
new_vert.node = new_node.self_index;
@@ -1478,6 +1478,122 @@ template<typename END, typename EVD, typename EED, typename EFD> class Mesh {
std::move(deleted_faces));
}
+ /**
+ * Collapses the edge from edge v1 to v2 unless `verts_swapped` is set
+ * to true and keeps the triangulation of the Mesh
+ *
+ * @param verts_swapped If true, then the edge collapsed from v2 to
+ * v1, if false, edge is collapsed from v1 to v2.
+ *
+ * @param across_seams If true, think of edge as world space edge
+ * and not UV space, this means, all the faces across all the edges
+ * formed between the nodes of the given edge are also split and
+ * triangulated regardless if it on a seam or not.
+ *
+ * Returns the `MeshDiff` that lead to the operation.
+ *
+ * Note, the caller must ensure the adjacent faces to the edge are
+ * triangulated. In debug mode, it will assert, in release mode, it
+ * is undefined behaviour.
+ **/
+ MeshDiff<END, EVD, EED, EFD> collapse_edge_triangulate(EdgeIndex edge_index,
+ bool verts_swapped,
+ bool across_seams)
+ {
+ /* This operation will delete the following-
+ * the edge specified, faces incident to the edge. v2, n2 if
+ * verts_swapped is true. v1, n1 if verts_swapped is false. One of the
+ * edge per face (edge vert and other vert).
+ *
+ * This operation will add the following-
+ * None
+ */
+
+ blender::Vector<NodeIndex> added_nodes;
+ blender::Vector<VertIndex> added_verts;
+ blender::Vector<EdgeIndex> added_edges;
+ blender::Vector<FaceIndex> added_faces;
+ blender::Vector<Node<END>> deleted_nodes;
+ blender::Vector<Vert<EVD>> deleted_verts;
+ blender::Vector<Edge<EED>> deleted_edges;
+ blender::Vector<Face<EFD>> deleted_faces;
+
+ auto &edge_a = this->get_checked_edge(edge_index);
+ auto [v1, v2] = this->get_checked_verts_of_edge(edge_a, verts_swapped);
+ auto v1_index = v1.self_index;
+ auto n1_index = v1.node.value();
+
+ /* This point forward, the vert to be removed is v1, v2 continues
+ * to exist */
+
+ auto faces = edge_a.faces;
+
+ for (const auto &face_index : faces) {
+ auto face = this->delete_face(face_index);
+
+ auto &edge_b = this->get_checked_edge(edge_index);
+
+ auto &other_vert = this->get_checked_other_vert(edge_b, face);
+
+ /* delete edge between v1 and other_vert */
+ {
+ auto op_e_index = this->get_connecting_edge_index(v1_index, other_vert.self_index);
+ BLI_assert(op_e_index);
+ auto e = this->delete_edge(op_e_index.value());
+
+ deleted_edges.append(std::move(e));
+ }
+
+ deleted_faces.append(std::move(face));
+ }
+
+ /* for each edge of v1, change that edge's verts to (vx, v2) */
+ for (const auto &e_index : v1.edges) {
+ Edge<EED> &e = this->get_checked_edge(e_index);
+
+ /* we don't want to mess with edge between v1 and v2 */
+ if (e.has_vert(v2.self_index)) {
+ continue;
+ }
+
+ BLI_assert(e.verts);
+ auto &verts = e.verts.value();
+ if (std::get<0>(verts) == v1_index) {
+ e.verts = {std::get<1>(verts), v2.self_index};
+ }
+ else {
+ e.verts = {std::get<0>(verts), v2.self_index};
+ }
+ }
+
+ /* delete edge */
+ {
+ auto edge = this->delete_edge(edge_index);
+ deleted_edges.append(std::move(edge));
+ }
+
+ /* delete v1 */
+ {
+ auto v1 = this->delete_vert(v1_index);
+ deleted_verts.append(std::move(v1));
+ }
+
+ /* delete n1 */
+ {
+ auto n1 = this->delete_node(n1_index);
+ deleted_nodes.append(std::move(n1));
+ }
+
+ return MeshDiff(std::move(added_nodes),
+ std::move(added_verts),
+ std::move(added_edges),
+ std::move(added_faces),
+ std::move(deleted_nodes),
+ std::move(deleted_verts),
+ std::move(deleted_edges),
+ std::move(deleted_faces));
+ }
+
protected:
/* all protected static methods */
/* all protected non-static methods */
@@ -1646,7 +1762,7 @@ template<typename END, typename EVD, typename EED, typename EFD> class Mesh {
}
/**
- * Delete the node and update elements' that refer to this node.
+ * Delete the node and update elements that refer to this node.
*
* This should always be followed with a `delete_vert()`
* since a `Vert` without a `Node` is invalid.
@@ -1670,7 +1786,7 @@ template<typename END, typename EVD, typename EED, typename EFD> class Mesh {
}
/**
- * Delete the vert and update elements' that refer to this vert.
+ * Delete the vert and update elements that refer to this vert.
*
* This should always be followed with a `delete_edge()`
* since a `Edge` without a both it's verts is invalid.
@@ -1691,7 +1807,7 @@ template<typename END, typename EVD, typename EED, typename EFD> class Mesh {
/* Remove this vert's references from the other edges and also
* the faces, this can lead to a mesh structure that isn't valid,
* so subsequent operations are necessary */
- for (const auto &edge_index : verts.edges) {
+ for (const auto &edge_index : vert.edges) {
auto op_edge = this->edges.get(edge_index);
BLI_assert(op_edge);
auto &edge = op_edge.value().get();
@@ -1702,7 +1818,7 @@ template<typename END, typename EVD, typename EED, typename EFD> class Mesh {
/* The ordering of the verts within the face matters, so need
* to go for this more expensive method of removal */
BLI_assert(face.verts.contains(vert.self_index));
- face.verts.remove(first_index_of(vert.self_index));
+ face.verts.remove(face.verts.first_index_of(vert.self_index));
}
/* The other vert of the edge might have been deleted first */
@@ -1715,7 +1831,7 @@ template<typename END, typename EVD, typename EED, typename EFD> class Mesh {
}
/**
- * Delete the edge and update elements' that refer to this edge.
+ * Delete the edge and update elements that refer to this edge.
*/
Edge<EED> delete_edge(EdgeIndex edge_index)
{
@@ -1804,11 +1920,18 @@ template<typename END, typename EVD, typename EED, typename EFD> class Mesh {
return op_face.value().get();
}
- inline std::tuple<Vert<EVD> &, Vert<EVD> &> get_checked_verts_of_edge(const Edge<EED> &edge)
+ inline std::tuple<Vert<EVD> &, Vert<EVD> &> get_checked_verts_of_edge(const Edge<EED> &edge,
+ bool verts_swapped)
{
BLI_assert(edge.verts);
auto &edge_verts = edge.verts.value();
+ if (verts_swapped) {
+ auto &edge_vert_1 = this->get_checked_vert(std::get<1>(edge_verts));
+ auto &edge_vert_2 = this->get_checked_vert(std::get<0>(edge_verts));
+ return {edge_vert_1, edge_vert_2};
+ }
+
auto &edge_vert_1 = this->get_checked_vert(std::get<0>(edge_verts));
auto &edge_vert_2 = this->get_checked_vert(std::get<1>(edge_verts));
More information about the Bf-blender-cvs
mailing list