[Bf-blender-cvs] [ed500956c38] soc-2021-adaptive-cloth: adaptive_cloth: MeshIO: read DNA Mesh

ishbosamiya noreply at git.blender.org
Mon Jul 5 17:33:37 CEST 2021


Commit: ed500956c389ef515bac5b3833d605da7d0fb53f
Author: ishbosamiya
Date:   Thu Jul 1 18:34:51 2021 +0530
Branches: soc-2021-adaptive-cloth
https://developer.blender.org/rBed500956c389ef515bac5b3833d605da7d0fb53f

adaptive_cloth: MeshIO: read DNA Mesh

The conversion was easy enough but the test case for this is extremely difficult.

Creating `Mesh` is not possible without initializing `idtype` using `BKE_idtype_init()` (there should actually be a check for this, at least in debug mode).

Converting this `Mesh` to `BMesh` is simple without any hassles.

Using the `BMesh`, create a cube. Now turns out that is also simple if `BMO_op_callf()` is known about. The previous approach was to create a copy of the code in `bmo_primitive.c` and use that. This also leads to problems because without the `BMOperator` functions pre-applied on the `BMesh`, `BMO_face_flag_enable()` crashes without any proper indication of what could have caused the error. Simplest way to fix is to just remove that flag check. Then found out about `BMO_op_callf()`, this r [...]

Now that we have the cube in the `BMesh`, converting it back to `Mesh` is another massive problem. There are many functions that can do this `BM_mesh_bm_to_me()` and `BKE_mesh_from_bmesh_eval_nomain()` are most appropriate. These functions write the CustomData blocks to `Mesh` but before doing do, set the `mvert->co` and such. For some reason, `BMesh` has not updated the blocks so `mvert->co` just has (0.0, 0.0, 0.0). After spending multiple hours on this, found one way to fix this, copy  [...]

===================================================================

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 febba7dfb5f..b762effc18e 100644
--- a/source/blender/blenkernel/BKE_cloth_remesh.hh
+++ b/source/blender/blenkernel/BKE_cloth_remesh.hh
@@ -36,13 +36,19 @@
  * https://doi.org/10.1145/604471.604503
  * ********************************************************************/
 
+#include "BKE_mesh.h"
 #include "BLI_assert.h"
+
+#include "BKE_customdata.h"
+
+#include "DNA_mesh_types.h"
+#include "DNA_meshdata_types.h"
+
 #ifdef __cplusplus
 extern "C" {
 #endif
 
 struct ClothModifierData;
-struct Mesh;
 struct Object;
 
 void BKE_cloth_remesh(const struct Object *ob,
@@ -398,6 +404,63 @@ class MeshIO {
     return true;
   }
 
+  bool read(::Mesh *mesh)
+  {
+    BLI_assert(mesh != nullptr);
+
+    /* Update the mesh internal pointers with the customdata stuff */
+    BKE_mesh_update_customdata_pointers(mesh, false);
+
+    if (mesh->totvert == 0) {
+      return false;
+    }
+
+    /* We need uv information */
+    if (mesh->mloopuv == nullptr) {
+      return false;
+    }
+
+    auto &positions = this->positions;
+    auto &uvs = this->uvs;
+    auto &normals = this->normals;
+    auto &face_indices = this->face_indices;
+    auto &line_indices = this->line_indices;
+
+    /* TODO(ish): check if normals must be recalcuated */
+
+    for (auto i = 0; i < mesh->totvert; i++) {
+      positions.append(mesh->mvert[i].co);
+      /* TODO(ish): figure out short normal conversion to float3 */
+      normals.append(float3(mesh->mvert[i].no[0], mesh->mvert[i].no[1], mesh->mvert[i].no[2]));
+    }
+
+    /* TODO(ish): ensure that we need to loop until mesh->totloop only */
+    for (auto i = 0; i < mesh->totloop; i++) {
+      uvs.append(mesh->mloopuv[i].uv);
+    }
+
+    for (auto i = 0; i < mesh->totpoly; i++) {
+      const auto mp = mesh->mpoly[i];
+      blender::Vector<FaceData> face;
+      face.reserve(mp.totloop);
+
+      for (auto j = 0; j < mp.totloop; j++) {
+        const auto ml = mesh->mloop[mp.loopstart + j];
+        usize pos_index = ml.v;
+        usize uv_index = mp.loopstart + j;
+        usize normal_index = ml.v;
+
+        face.append(std::make_tuple(pos_index, uv_index, normal_index));
+      }
+
+      face_indices.append(face);
+    }
+
+    /* TODO(ish): support line indices */
+
+    return true;
+  }
+
   bool write(const fs::path &filepath, IOType type)
   {
     if (type != IOTYPE_OBJ) {
diff --git a/source/blender/blenkernel/tests/BKE_cloth_remesh_test.cc b/source/blender/blenkernel/tests/BKE_cloth_remesh_test.cc
index b6adb1d0fd7..1d4f1cec76a 100644
--- a/source/blender/blenkernel/tests/BKE_cloth_remesh_test.cc
+++ b/source/blender/blenkernel/tests/BKE_cloth_remesh_test.cc
@@ -1,6 +1,24 @@
 #include "BKE_cloth_remesh.hh"
 
+#include "BKE_customdata.h"
+#include "BKE_idtype.h"
+#include "BKE_main.h"
+#include "DNA_customdata_types.h"
+#include "DNA_meshdata_types.h"
+#include "bmesh.h"
+
+#include "BKE_mesh.h"
+
+#include "DNA_mesh_types.h"
+
+#include "bmesh_class.h"
+#include "intern/bmesh_construct.h"
+#include "intern/bmesh_iterators.h"
+#include "intern/bmesh_mesh.h"
+#include "intern/bmesh_mesh_convert.h"
+#include "intern/bmesh_operators.h"
 #include "testing/testing.h"
+
 #include <gtest/gtest.h>
 #include <sstream>
 
@@ -120,6 +138,75 @@ TEST(cloth_remesh, MeshIO_WriteObj)
   EXPECT_EQ(stream_out.str(), expected);
 }
 
+TEST(cloth_remesh, MeshIO_ReadDNAMesh)
+{
+  BKE_idtype_init();
+  MeshIO reader;
+  auto *mesh = BKE_mesh_new_nomain(0, 0, 0, 0, 0);
+  CustomData_add_layer(&mesh->ldata, CD_MLOOPUV, CD_CALLOC, nullptr, 0);
+  BMeshCreateParams bmesh_create_params = {0};
+  bmesh_create_params.use_toolflags = true;
+  BMeshFromMeshParams bmesh_from_mesh_params = {0};
+  bmesh_from_mesh_params.cd_mask_extra = CD_MASK_MESH;
+
+  auto *bm = BKE_mesh_to_bmesh_ex(mesh, &bmesh_create_params, &bmesh_from_mesh_params);
+
+  BMO_op_callf(bm, (BMO_FLAG_DEFAULTS & ~BMO_FLAG_RESPECT_HIDE), "create_cube calc_uvs=%b", true);
+
+  BMeshToMeshParams bmesh_to_mesh_params = {0};
+  bmesh_to_mesh_params.cd_mask_extra = CD_MASK_MESH;
+
+  auto *bm_copy = BM_mesh_copy(bm);
+
+  auto *result = BKE_mesh_new_nomain(0, 0, 0, 0, 0);
+  BM_mesh_bm_to_me(nullptr, bm_copy, result, &bmesh_to_mesh_params);
+
+  /* auto *result = BKE_mesh_from_bmesh_for_eval_nomain( */
+  /*     bm, &bmesh_to_mesh_params.cd_mask_extra, mesh); */
+
+  {
+    BMVert *v;
+    BMIter v_iter;
+    BM_ITER_MESH (v, &v_iter, bm, BM_VERTS_OF_MESH) {
+      std::cout << "(" << v->co[0] << ", " << v->co[1] << ", " << v->co[2] << ")";
+    }
+    std::cout << std::endl;
+  }
+  {
+    for (auto i = 0; i < result->totvert; i++) {
+      std::cout << "(" << result->mvert[i].co[0] << ", " << result->mvert[i].co[1] << ", "
+                << result->mvert[i].co[2] << ")";
+    }
+    std::cout << std::endl;
+  }
+
+  auto res = reader.read(result);
+
+  EXPECT_TRUE(res);
+
+  std::ostringstream stream_out;
+  reader.write(stream_out, MeshIO::IOTYPE_OBJ);
+
+  std::cout << stream_out.str() << std::endl;
+
+  const auto &positions = reader.get_positions();
+  const auto &uvs = reader.get_uvs();
+  const auto &normals = reader.get_normals();
+  const auto &face_indices = reader.get_face_indices();
+  const auto &line_indices = reader.get_line_indices();
+
+  std::cout << "positions: " << positions << std::endl;
+  std::cout << "uvs: " << uvs << std::endl;
+  std::cout << "normals: " << normals << std::endl;
+  std::cout << "face_indices: " << face_indices << std::endl;
+  std::cout << "line_indices: " << line_indices << std::endl;
+
+  BM_mesh_free(bm);
+  BM_mesh_free(bm_copy);
+  BKE_mesh_eval_delete(mesh);
+  BKE_mesh_eval_delete(result);
+}
+
 TEST(cloth_remesh, Mesh_Read)
 {
   MeshIO reader;



More information about the Bf-blender-cvs mailing list