[Bf-blender-cvs] [1780f2aaf8b] soc-2021-adaptive-cloth: adaptive_cloth: create an abstraction for adaptive_remesh
ishbosamiya
noreply at git.blender.org
Mon Jul 26 08:17:41 CEST 2021
Commit: 1780f2aaf8bbdc77db2599400b4376b85b9f8d7b
Author: ishbosamiya
Date: Wed Jul 21 21:55:59 2021 +0530
Branches: soc-2021-adaptive-cloth
https://developer.blender.org/rB1780f2aaf8bbdc77db2599400b4376b85b9f8d7b
adaptive_cloth: create an abstraction for adaptive_remesh
The adaptive remeshing algorithm is not dependent on the cloth
modifier so it makes sense to abstract at least to a point of not
needing all of the `ClothVertex` data.
This will help with testing of the implementation by adding it to the
`AdaptiveRemesh` modifier.
===================================================================
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 d04834caf70..8b7b5f59f19 100644
--- a/source/blender/blenkernel/BKE_cloth_remesh.hh
+++ b/source/blender/blenkernel/BKE_cloth_remesh.hh
@@ -65,6 +65,7 @@ Mesh *BKE_cloth_remesh(struct Object *ob, struct ClothModifierData *clmd, struct
# include <cmath>
# include <filesystem>
# include <fstream>
+# include <functional>
# include <iostream>
# include <istream>
# include <limits>
@@ -79,6 +80,60 @@ Mesh *BKE_cloth_remesh(struct Object *ob, struct ClothModifierData *clmd, struct
# include "BLI_map.hh"
# include "BLI_vector.hh"
+/* Public C++ code */
+namespace blender::bke {
+
+/**
+ * @param END Extra Node Data
+ *
+ * @param ExtraData Extra Data that might be needed to get the `Extra
+ * "Element" Data`
+ */
+template<typename END, typename ExtraData> struct AdaptiveRemeshParams {
+ float size_min;
+
+ /* For handling Extra Node Data */
+ /**
+ * function that takes `ExtraData` along with the index for the
+ * `Node` as input and returns the `END` to be stored in that
+ * `Node`.
+ */
+ std::function<END(const ExtraData &, size_t)> extra_data_to_end;
+ /**
+ * function that is run after `extra_data_to_end` for every `Node` of
+ * the `Mesh`.
+ *
+ * useful for cleanup. (memory management of resources within `ExtraData`)
+ */
+ std::function<void(ExtraData &)> post_extra_data_to_end;
+ /**
+ * function that takes `ExtraData` along with the `END` and
+ * corresponding index of the `Node`
+ *
+ * useful to store `END` into `ExtraData`
+ */
+ std::function<void(ExtraData &, END, size_t)> end_to_extra_data;
+ /**
+ * function that takes `ExtraData` along with the number of `Node`s
+ * in `Mesh`.
+ *
+ * is run before `end_to_extra_data` is run for every `Node` of the
+ * `Mesh`.
+ *
+ * useful for memory management of resources within `ExtraData`.
+ */
+ std::function<void(ExtraData &, size_t)> pre_end_to_extra_data;
+};
+
+/* `mesh` cannot be made const because function defined on `struct
+ * Mesh` do not take `struct Mesh` as const even when they can be const */
+template<typename END, typename ExtraData>
+Mesh *adaptive_remesh(const AdaptiveRemeshParams<END, ExtraData> ¶ms,
+ Mesh *mesh,
+ const ExtraData &extra_data);
+
+} /* namespace blender::bke */
+
namespace blender::bke::internal {
template<typename> class Node;
diff --git a/source/blender/blenkernel/intern/cloth_remesh.cc b/source/blender/blenkernel/intern/cloth_remesh.cc
index 623fcc1f420..b22e7245f72 100644
--- a/source/blender/blenkernel/intern/cloth_remesh.cc
+++ b/source/blender/blenkernel/intern/cloth_remesh.cc
@@ -35,11 +35,19 @@
#include "BKE_cloth.h"
#include "BKE_cloth_remesh.hh"
+
+#include <cstddef>
+#include <functional>
#include <limits>
namespace blender::bke::internal {
-class NodeData;
+class ClothNodeData;
+
+template<typename T> class NodeData;
+/* TODO(ish): make the other "XData" generic */
class VertData;
+class EdgeData;
+
class Sizing;
template<typename T> static inline T simple_interp(const T &a, const T &b)
@@ -47,15 +55,46 @@ template<typename T> static inline T simple_interp(const T &a, const T &b)
return (a + b) * 0.5;
}
-class NodeData {
+template<typename T> class NodeData {
+ T extra_data;
+
+ public:
+ /* NodeData can be created only if `extra_data` is provided for so
+ * it is fine to not store `extra_data` as an optional */
+ NodeData(T extra_data) : extra_data(extra_data)
+ {
+ }
+
+ void set_extra_data(T extra_data)
+ {
+ this->extra_data = extra_data;
+ }
+
+ const auto &get_extra_data() const
+ {
+ return this->extra_data;
+ }
+
+ auto &get_extra_data_mut()
+ {
+ return this->extra_data;
+ }
+
+ NodeData interp(const NodeData &other) const
+ {
+ return NodeData(this->extra_data.interp(other.get_extra_data()));
+ }
+};
+
+class ClothNodeData {
ClothVertex cloth_node_data; /* The cloth simulation calls it
* Vertex, internal::Mesh calls it Node */
public:
- NodeData(const ClothVertex &cloth_node_data) : cloth_node_data(cloth_node_data)
+ ClothNodeData(const ClothVertex &cloth_node_data) : cloth_node_data(cloth_node_data)
{
}
- NodeData(ClothVertex &&cloth_node_data) : cloth_node_data(cloth_node_data)
+ ClothNodeData(ClothVertex &&cloth_node_data) : cloth_node_data(cloth_node_data)
{
}
@@ -64,7 +103,7 @@ class NodeData {
return this->cloth_node_data;
}
- NodeData interp(const NodeData &other) const
+ ClothNodeData interp(const ClothNodeData &other) const
{
{
/* This check is to ensure that any new element added to
@@ -110,7 +149,7 @@ class NodeData {
cn.pressure_factor = simple_interp(this->cloth_node_data.pressure_factor,
other.cloth_node_data.pressure_factor);
}
- return NodeData(std::move(cn));
+ return ClothNodeData(std::move(cn));
}
};
@@ -226,26 +265,14 @@ class EdgeData {
}
};
-using AdaptiveNode = Node<NodeData>;
+template<typename T> using AdaptiveNode = Node<NodeData<T>>;
using AdaptiveVert = Vert<VertData>;
using AdaptiveEdge = Edge<EdgeData>;
using AdaptiveFace = Face<internal::EmptyExtraData>;
-class AdaptiveMesh : public Mesh<NodeData, VertData, EdgeData, internal::EmptyExtraData> {
+template<typename END>
+class AdaptiveMesh : public Mesh<NodeData<END>, VertData, EdgeData, internal::EmptyExtraData> {
public:
- void set_nodes_extra_data(const Cloth &cloth)
- {
- /* The layout of the `this->get_nodes()` and `cloth.verts` should
- * be the same, so just directly copy it over */
- BLI_assert(cloth.mvert_num == this->get_nodes().size());
-
- auto i = 0;
- for (auto &node : this->get_nodes_mut()) {
- node.set_extra_data(NodeData(cloth.verts[i]));
- i++;
- }
- }
-
void edge_set_size(AdaptiveEdge &edge)
{
const auto [v1, v2] = this->get_checked_verts_of_edge(edge, false);
@@ -295,7 +322,6 @@ class AdaptiveMesh : public Mesh<NodeData, VertData, EdgeData, internal::EmptyEx
auto &edge = this->get_checked_edge(edge_index);
auto mesh_diff = this->split_edge_triangulate(edge.get_self_index(), true);
-
/* For each new edge added, set it's sizing */
for (const auto &edge_index : mesh_diff.get_added_edges()) {
auto &edge = this->get_checked_edge(edge_index);
@@ -310,6 +336,28 @@ class AdaptiveMesh : public Mesh<NodeData, VertData, EdgeData, internal::EmptyEx
} while (splittable_edges_set.size() != 0);
}
+ void static_remesh(const Sizing &sizing)
+ {
+ /* Set sizing for all verts */
+ for (auto &vert : this->get_verts_mut()) {
+ auto &op_vert_data = vert.get_extra_data_mut();
+ if (op_vert_data) {
+ auto &vert_data = op_vert_data.value();
+ vert_data.set_sizing(sizing);
+ }
+ else {
+ vert.set_extra_data(VertData(sizing));
+ }
+ }
+
+ this->set_edge_sizes();
+
+ /* Split the edges */
+ this->split_edges();
+
+ /* Collapse the edges */
+ }
+
private:
/**
* Gets the maximal independent set of splittable edge indices in
@@ -352,85 +400,108 @@ class AdaptiveMesh : public Mesh<NodeData, VertData, EdgeData, internal::EmptyEx
}
};
-static void cloth_delete_verts(Cloth &cloth)
-{
- BLI_assert(cloth.verts);
- MEM_freeN(cloth.verts);
- cloth.verts = nullptr;
-}
-
-static void cloth_set_verts_from_adaptive_mesh(Cloth &cloth, const AdaptiveMesh &mesh)
-{
- /* caller should have deleted the verts earlier */
- BLI_assert(cloth.verts == nullptr);
-
- cloth.verts = static_cast<ClothVertex *>(
- MEM_callocN(sizeof(ClothVertex) * mesh.get_nodes().size(), __func__));
-
- auto i = 0;
- for (const auto &node : mesh.get_nodes()) {
- const auto &op_extra_data = node.get_extra_data();
- BLI_assert(op_extra_data);
- cloth.verts[i] = op_extra_data.value().get_cloth_node_data();
- i++;
- }
-}
-
-static void static_remesh(AdaptiveMesh &mesh, const Sizing &sizing)
-{
- /* Set sizing for all verts */
- for (auto &vert : mesh.get_verts_mut()) {
- auto &op_vert_data = vert.get_extra_data_mut();
- if (op_vert_data) {
- auto &vert_data = op_vert_data.value();
- vert_data.set_sizing(sizing);
- }
- else {
- vert.set_extra_data(VertData(sizing));
- }
- }
-
- mesh.set_edge_sizes();
-
- /* Split the edges */
- mesh.split_edges();
-
- /* Collapse the edges */
-}
-
} // namespace blender::bke::internal
namespace blender::bke {
-Mesh *BKE_cloth_remesh(Object *ob, ClothModifierData *clmd, Mesh *mesh)
+template<typename END, typename ExtraData>
+Mesh *adaptive_remesh(const AdaptiveRemeshParams<END, ExtraData> ¶ms,
+ Mesh *mesh,
+ ExtraData &extra_data)
{
- auto *cloth_to_object_res = cloth_to_object(ob, clmd, mesh, false);
- BLI_assert(cloth_to_object_res == nullptr);
-
internal::MeshIO meshio_input;
meshio_input.read(mesh);
- internal::AdaptiveMesh adaptive_mesh;
+ internal::AdaptiveMesh<END> adaptive_mesh;
adaptive_mesh.read(meshio_input);
+ /* Load up the `NodeData`'s extra_data */
{
- adaptive_mesh.set_nodes_extra_data(*clmd->clothObject);
- internal::cloth_delete_verts(*clmd->clothObject);
+ auto i = 0;
+ for (auto &node : adaptive_mesh.get_nodes_mut()) {
+ node.set_extra_data(internal::NodeData(params.extra_data_to_end(extra_data, i)));
+ i++;
+ }
+
+ params.post_extra_data_to_end(extra_data);
}
- /* Actual remeshing part */
+ /* Actual Remeshing Part */
{
- float size_min = clmd->sim_parms->remeshing_size_min;
+ float size_min = params.size_min;
auto m = float2x2::identity();
m = m * (1.0 / size_min);
internal::Sizing vert_sizing(std::move(m));
- internal::static_remesh(adaptive_mesh, vert_sizing);
+ adaptive_mesh.static_remesh(vert_sizing);
}
- internal::cloth_set_verts_from_adaptive_mesh(*clmd->clothObject, adaptive_mesh);
+ /* set back data from `AdaptiveMesh` to whatever needs it */
+ {
+ params.pre_end_to_extra_data(extra_data, adaptive_mesh.get_nodes().si
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list