[Bf-blender-cvs] [440b4866030] soc-2021-adaptive-cloth: adaptive_cloth: MeshIO: write DNA Mesh
ishbosamiya
noreply at git.blender.org
Mon Jul 5 17:33:38 CEST 2021
Commit: 440b48660309eeeb0e8bb3419c41b541e4313944
Author: ishbosamiya
Date: Fri Jul 2 12:49:33 2021 +0530
Branches: soc-2021-adaptive-cloth
https://developer.blender.org/rB440b48660309eeeb0e8bb3419c41b541e4313944
adaptive_cloth: MeshIO: write DNA Mesh
===================================================================
M source/blender/blenkernel/BKE_cloth_remesh.hh
M source/blender/blenkernel/tests/BKE_cloth_remesh_test.cc
===================================================================
diff --git a/source/blender/blenkernel/BKE_cloth_remesh.hh b/source/blender/blenkernel/BKE_cloth_remesh.hh
index c836a3e98e1..72124fccf19 100644
--- a/source/blender/blenkernel/BKE_cloth_remesh.hh
+++ b/source/blender/blenkernel/BKE_cloth_remesh.hh
@@ -100,6 +100,19 @@ using EdgeVerts = std::tuple<VertIndex, VertIndex>;
using usize = uint64_t;
+inline void copy_v2_float2(float *res, const float2 &v2)
+{
+ res[0] = v2[0];
+ res[1] = v2[1];
+}
+
+inline void copy_v3_float3(float *res, const float3 &v3)
+{
+ res[0] = v3[0];
+ res[1] = v3[1];
+ res[2] = v3[2];
+}
+
template<typename T> std::ostream &operator<<(std::ostream &stream, const blender::Vector<T> &vec)
{
if (vec.size() == 0) {
@@ -495,6 +508,64 @@ class MeshIO {
}
}
+ ::Mesh *write()
+ {
+ auto num_verts = this->positions.size();
+ auto num_loops = 0;
+ for (const auto &face : this->face_indices) {
+ num_loops += face.size();
+ }
+ auto num_uvs = num_loops; /* for `::Mesh` the number of uvs has
+ * to match number of loops */
+ auto num_poly = this->face_indices.size();
+ auto *mesh = BKE_mesh_new_nomain(num_verts, 0, 0, num_loops, num_poly);
+ if (!mesh) {
+ return nullptr;
+ }
+
+ CustomData_add_layer(&mesh->ldata, CD_MLOOPUV, CD_CALLOC, nullptr, num_uvs);
+
+ BKE_mesh_update_customdata_pointers(mesh, false);
+
+ auto *mverts = mesh->mvert;
+ auto *mloopuvs = mesh->mloopuv;
+ auto *mloops = mesh->mloop;
+ auto *mpolys = mesh->mpoly;
+
+ for (auto i = 0; i < this->positions.size(); i++) {
+ copy_v3_float3(mverts[i].co, this->positions[i]);
+ }
+
+ auto loopstart = 0;
+ for (auto i = 0; i < this->face_indices.size(); i++) {
+ auto &face = this->face_indices[i];
+ auto &mpoly = mpolys[i];
+ mpoly.loopstart = loopstart;
+ mpoly.totloop = face.size();
+
+ for (auto j = 0; j < face.size(); j++) {
+ auto [pos_index, uv_index, normal_index] = face[j];
+ /* TODO(ish): handle normal index */
+ mloops[loopstart + j].v = pos_index;
+
+ /* Need to update mloopuvs here since `mesh->mloop` and
+ * `mesh->mloopuv` need to maintain same size and correspond
+ * with one another */
+ copy_v2_float2(mloopuvs[loopstart + j].uv, this->uvs[uv_index]);
+ }
+
+ loopstart += face.size();
+ }
+
+ BKE_mesh_ensure_normals(mesh);
+ BKE_mesh_calc_edges(mesh, false, false);
+
+ /* TODO(ish): handle vertex normals */
+ /* TODO(ish): handle line_indices/mesh wires (edges without faces) */
+
+ return mesh;
+ }
+
void set_positions(blender::Vector<float3> &&positions)
{
this->positions = std::move(positions);
diff --git a/source/blender/blenkernel/tests/BKE_cloth_remesh_test.cc b/source/blender/blenkernel/tests/BKE_cloth_remesh_test.cc
index db921f6af8d..0c55030d460 100644
--- a/source/blender/blenkernel/tests/BKE_cloth_remesh_test.cc
+++ b/source/blender/blenkernel/tests/BKE_cloth_remesh_test.cc
@@ -24,6 +24,20 @@
namespace blender::bke::tests {
+static std::string stringify_v2(const float *v2)
+{
+ std::ostringstream stream;
+ stream << "(" << v2[0] << ", " << v2[1] << ")";
+ return stream.str();
+}
+
+static std::string stringify_v3(const float *v3)
+{
+ std::ostringstream stream;
+ stream << "(" << v3[0] << ", " << v3[1] << ", " << v3[2] << ")";
+ return stream.str();
+}
+
using namespace internal;
static const char *cube_pos_uv_normal =
@@ -226,6 +240,151 @@ TEST(cloth_remesh, MeshIO_ReadDNAMesh)
EXPECT_EQ(stream_out.str(), expected);
}
+TEST(cloth_remesh, MeshIO_WriteDNAMesh)
+{
+ MeshIO reader;
+ std::istringstream stream_in(cube_pos_uv_normal);
+ auto res = reader.read(std::move(stream_in), MeshIO::IOTYPE_OBJ);
+ EXPECT_TRUE(res);
+
+ auto *mesh = reader.write();
+ EXPECT_NE(mesh, nullptr);
+
+ EXPECT_NE(mesh->mvert, nullptr);
+ EXPECT_NE(mesh->medge, nullptr);
+ EXPECT_NE(mesh->mpoly, nullptr);
+ EXPECT_NE(mesh->mloop, nullptr);
+ EXPECT_NE(mesh->mloopuv, nullptr);
+
+ auto format_string_mvert = [](const MVert &mvert) {
+ std::ostringstream stream;
+ stream << "[mvert: ("
+ << "co: " << stringify_v3(mvert.co) << ")]";
+ return stream.str();
+ };
+ auto format_string_mloopuv = [](const MLoopUV &mloopuv) {
+ std::ostringstream stream;
+ stream << "[mloopuv: ("
+ << "uv: " << stringify_v2(mloopuv.uv) << ")]";
+ return stream.str();
+ };
+ auto format_string_medge = [](const MEdge &medge) {
+ std::ostringstream stream;
+ stream << "[medge: ("
+ << "v1: " << medge.v1 << ", v2: " << medge.v2 << ")]";
+ return stream.str();
+ };
+ auto format_string_mpoly = [](const MPoly &mpoly) {
+ std::ostringstream stream;
+ stream << "[mpoly: ("
+ << "loopstart: " << mpoly.loopstart << ", totloop: " << mpoly.totloop << ")]";
+ return stream.str();
+ };
+ auto format_string_mloop = [](const MLoop &mloop) {
+ std::ostringstream stream;
+ stream << "[mloop: ("
+ << "v: " << mloop.v << ", e: " << mloop.e << ")]";
+ return stream.str();
+ };
+
+ std::string expected =
+ "[mvert: (co: (1, 1, -1))]\n"
+ "[mvert: (co: (1, -1, -1))]\n"
+ "[mvert: (co: (1, 1, 1))]\n"
+ "[mvert: (co: (1, -1, 1))]\n"
+ "[mvert: (co: (-1, 1, -1))]\n"
+ "[mvert: (co: (-1, -1, -1))]\n"
+ "[mvert: (co: (-1, 1, 1))]\n"
+ "[mvert: (co: (-1, -1, 1))]\n"
+ "[mloopuv: (uv: (0.625, 0.5))]\n"
+ "[mloopuv: (uv: (0.875, 0.5))]\n"
+ "[mloopuv: (uv: (0.875, 0.75))]\n"
+ "[mloopuv: (uv: (0.625, 0.75))]\n"
+ "[mloopuv: (uv: (0.375, 0.75))]\n"
+ "[mloopuv: (uv: (0.625, 0.75))]\n"
+ "[mloopuv: (uv: (0.625, 1))]\n"
+ "[mloopuv: (uv: (0.375, 1))]\n"
+ "[mloopuv: (uv: (0.375, 0))]\n"
+ "[mloopuv: (uv: (0.625, 0))]\n"
+ "[mloopuv: (uv: (0.625, 0.25))]\n"
+ "[mloopuv: (uv: (0.375, 0.25))]\n"
+ "[mloopuv: (uv: (0.125, 0.5))]\n"
+ "[mloopuv: (uv: (0.375, 0.5))]\n"
+ "[mloopuv: (uv: (0.375, 0.75))]\n"
+ "[mloopuv: (uv: (0.125, 0.75))]\n"
+ "[mloopuv: (uv: (0.375, 0.5))]\n"
+ "[mloopuv: (uv: (0.625, 0.5))]\n"
+ "[mloopuv: (uv: (0.625, 0.75))]\n"
+ "[mloopuv: (uv: (0.375, 0.75))]\n"
+ "[mloopuv: (uv: (0.375, 0.25))]\n"
+ "[mloopuv: (uv: (0.625, 0.25))]\n"
+ "[mloopuv: (uv: (0.625, 0.5))]\n"
+ "[mloopuv: (uv: (0.375, 0.5))]\n"
+ "[mpoly: (loopstart: 0, totloop: 4)]\n"
+ "[mpoly: (loopstart: 4, totloop: 4)]\n"
+ "[mpoly: (loopstart: 8, totloop: 4)]\n"
+ "[mpoly: (loopstart: 12, totloop: 4)]\n"
+ "[mpoly: (loopstart: 16, totloop: 4)]\n"
+ "[mpoly: (loopstart: 20, totloop: 4)]\n"
+ "[mloop: (v: 0, e: 3)]\n"
+ "[mloop: (v: 4, e: 5)]\n"
+ "[mloop: (v: 6, e: 9)]\n"
+ "[mloop: (v: 2, e: 1)]\n"
+ "[mloop: (v: 3, e: 2)]\n"
+ "[mloop: (v: 2, e: 9)]\n"
+ "[mloop: (v: 6, e: 10)]\n"
+ "[mloop: (v: 7, e: 6)]\n"
+ "[mloop: (v: 7, e: 10)]\n"
+ "[mloop: (v: 6, e: 5)]\n"
+ "[mloop: (v: 4, e: 4)]\n"
+ "[mloop: (v: 5, e: 8)]\n"
+ "[mloop: (v: 5, e: 7)]\n"
+ "[mloop: (v: 1, e: 11)]\n"
+ "[mloop: (v: 3, e: 6)]\n"
+ "[mloop: (v: 7, e: 8)]\n"
+ "[mloop: (v: 1, e: 0)]\n"
+ "[mloop: (v: 0, e: 1)]\n"
+ "[mloop: (v: 2, e: 2)]\n"
+ "[mloop: (v: 3, e: 11)]\n"
+ "[mloop: (v: 5, e: 4)]\n"
+ "[mloop: (v: 4, e: 3)]\n"
+ "[mloop: (v: 0, e: 0)]\n"
+ "[mloop: (v: 1, e: 7)]\n"
+ "[medge: (v1: 0, v2: 1)]\n"
+ "[medge: (v1: 0, v2: 2)]\n"
+ "[medge: (v1: 2, v2: 3)]\n"
+ "[medge: (v1: 0, v2: 4)]\n"
+ "[medge: (v1: 4, v2: 5)]\n"
+ "[medge: (v1: 4, v2: 6)]\n"
+ "[medge: (v1: 3, v2: 7)]\n"
+ "[medge: (v1: 1, v2: 5)]\n"
+ "[medge: (v1: 5, v2: 7)]\n"
+ "[medge: (v1: 2, v2: 6)]\n"
+ "[medge: (v1: 6, v2: 7)]\n"
+ "[medge: (v1: 1, v2: 3)]\n";
+
+ std::ostringstream sout;
+ for (auto i = 0; i < mesh->totvert; i++) {
+ sout << format_string_mvert(mesh->mvert[i]) << std::endl;
+ }
+ for (auto i = 0; i < mesh->totloop; i++) {
+ sout << format_string_mloopuv(mesh->mloopuv[i]) << std::endl;
+ }
+ for (auto i = 0; i < mesh->totpoly; i++) {
+ sout << format_string_mpoly(mesh->mpoly[i]) << std::endl;
+ }
+ for (auto i = 0; i < mesh->totloop; i++) {
+ sout << format_string_mloop(mesh->mloop[i]) << std::endl;
+ }
+ for (auto i = 0; i < mesh->totedge; i++) {
+ sout << format_string_medge(mesh->medge[i]) << std::endl;
+ }
+
+ EXPECT_EQ(sout.str(), expected);
+
+ BKE_mesh_eval_delete(mesh);
+}
+
TEST(cloth_remesh, Mesh_Read)
{
MeshIO reader;
More information about the Bf-blender-cvs
mailing list