[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