[Bf-blender-cvs] [4796acef66e] soc-2021-adaptive-cloth: adaptive_cloth: mesh: read obj to Mesh

ishbosamiya noreply at git.blender.org
Mon Jun 28 08:28:22 CEST 2021


Commit: 4796acef66e0c029927907d6b5650cfb6b60bd10
Author: ishbosamiya
Date:   Wed Jun 23 12:17:34 2021 +0530
Branches: soc-2021-adaptive-cloth
https://developer.blender.org/rB4796acef66e0c029927907d6b5650cfb6b60bd10

adaptive_cloth: mesh: read obj to Mesh

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

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 05fe29404ec..8a4d739f465 100644
--- a/source/blender/blenkernel/BKE_cloth_remesh.hh
+++ b/source/blender/blenkernel/BKE_cloth_remesh.hh
@@ -82,6 +82,8 @@ using IncidentFaces = blender::Vector<FaceIndex>;
 using AdjacentVerts = IncidentVerts;
 using EdgeVerts = std::tuple<VertIndex, VertIndex>;
 
+using usize = uint64_t;
+
 /**
  * `Node`: Stores the worldspace/localspace coordinates of the
  * `Mesh`. Commonly called the vertex of the mesh (note: in this mesh
@@ -107,6 +109,8 @@ template<typename T> class Node {
   {
     this->extra_data = extra_data;
   }
+
+  template<typename, typename, typename, typename> friend class Mesh;
 };
 
 /**
@@ -138,6 +142,8 @@ template<typename T> class Vert {
   {
     this->extra_data = extra_data;
   }
+
+  template<typename, typename, typename, typename> friend class Mesh;
 };
 
 /**
@@ -170,6 +176,20 @@ template<typename T> class Edge {
   {
     this->extra_data = extra_data;
   }
+
+  bool has_vert(VertIndex vert_index)
+  {
+    if (this->verts) {
+      if (std::get<0>(this->verts.value()) == vert_index ||
+          std::get<1>(this->verts.value()) == vert_index) {
+        return true;
+      }
+    }
+
+    return false;
+  }
+
+  template<typename, typename, typename, typename> friend class Mesh;
 };
 
 /**
@@ -200,75 +220,11 @@ template<typename T> class Face {
   {
     this->extra_data = extra_data;
   }
-};
-
-template<typename END, typename EVD, typename EED, typename EFD> class Mesh {
-  /* using declarations */
-  /* static data members */
-  /* non-static data members */
-  ga::Arena<Node<END>> nodes;
-  ga::Arena<Vert<EVD>> verts;
-  ga::Arena<Edge<EED>> edges;
-  ga::Arena<Face<EFD>> faces;
-
- public:
-  /* default constructor */
-  Mesh() = default;
-  /* other constructors */
-  /* copy constructor */
-  /* move constructor */
-
-  /* destructor */
-
-  /* copy assignment operator */
-  /* move assignment operator */
-  /* other operator overloads */
-
-  /* all public static methods */
-  /* all public non-static methods */
-
- protected:
-  /* all protected static methods */
-  /* all protected non-static methods */
-
- private:
-  /* all private static methods */
-  /* all private non-static methods */
-
-  Node<END> &add_empty_node(float3 pos, float3 normal)
-  {
-    auto node_index = this->nodes.insert_with(
-        [=](NodeIndex index) { return Node<END>(index, pos, normal); });
 
-    return this->nodes.get(node_index);
-  }
-
-  Vert<EVD> &add_empty_vert(float2 uv)
-  {
-    auto vert_index = this->verts.insert_with(
-        [=](VertIndex index) { return Vert<EVD>(index, uv); });
-
-    return this->verts.get(vert_index);
-  }
-
-  Edge<EED> &add_empty_edge()
-  {
-    auto edge_index = this->edges.insert_with([=](EdgeIndex index) { return Edge<EED>(index); });
-
-    return this->edges.get(edge_index);
-  }
-
-  Face<EFD> &add_empty_face(float3 normal)
-  {
-    auto face_index = this->faces.insert_with(
-        [=](FaceIndex index) { return Face<EFD>(index, normal); });
-
-    return this->faces.get(face_index);
-  }
+  template<typename, typename, typename, typename> friend class Mesh;
 };
 
 class MeshReader {
-  using usize = uint64_t;
   using FaceData = std::tuple<usize, usize, usize>; /* position,
                                                      * uv,
                                                      * normal */
@@ -318,6 +274,8 @@ class MeshReader {
       BLI_assert_unreachable();
     }
 
+    /* TODO(ish): do some checks to ensure the data makes sense */
+
     return true;
   }
 
@@ -478,6 +436,207 @@ class MeshReader {
   }
 };
 
+template<typename END, typename EVD, typename EED, typename EFD> class Mesh {
+  /* using declarations */
+  /* static data members */
+  /* non-static data members */
+  ga::Arena<Node<END>> nodes;
+  ga::Arena<Vert<EVD>> verts;
+  ga::Arena<Edge<EED>> edges;
+  ga::Arena<Face<EFD>> faces;
+
+  bool node_normals_dirty;
+  bool face_normals_dirty;
+
+ public:
+  /* default constructor */
+  Mesh() = default;
+
+  /* other constructors */
+  /* copy constructor */
+  /* move constructor */
+
+  /* destructor */
+
+  /* copy assignment operator */
+  /* move assignment operator */
+  /* other operator overloads */
+
+  /* all public static methods */
+  /* all public non-static methods */
+  std::optional<EdgeIndex> get_connecting_edge_index(VertIndex vert_1_index,
+                                                     VertIndex vert_2_index)
+  {
+    auto vert_1 = this->verts.get(vert_1_index);
+    if (vert_1 == std::nullopt) {
+      return std::nullopt;
+    }
+
+    for (const auto &edge_index : vert_1.edges) {
+      auto edge = this->edges.get(edge_index);
+
+      if (edge == std::nullopt) {
+        return std::nullopt;
+      }
+
+      if (edge.has_vert(vert_2_index)) {
+        return edge_index;
+      }
+    }
+
+    return std::nullopt;
+  }
+
+  void read_obj(const fs::path &filepath)
+  {
+    MeshReader reader;
+    const auto reader_success = reader.read(filepath, MeshReader::FILETYPE_OBJ);
+    BLI_assert(reader_success); /* must successfully load obj */
+
+    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();
+
+    /* TODO(ish): add support for when uvs doesn't exist */
+    BLI_assert(uvs.size() != 0);
+
+    this->node_normals_dirty = true;
+    this->face_normals_dirty = true;
+
+    /* create all `Node`(s) */
+    for (const auto &pos : positions) {
+      this->add_empty_node(pos, float3_unknown());
+    }
+
+    /* create all `Vert`(s) */
+    for (const auto &uv : uvs) {
+      this->add_empty_vert(uv);
+    }
+
+    /* use face information for create `Face`(s), `Edge`(s) and
+     * create the necessary references */
+    for (const auto &face_index_data : face_indices) {
+
+      /* update verts and nodes */
+      for (const auto &[pos_index, uv_index, normal_index] : face_index_data) {
+        auto vert = this->verts.get_no_gen(uv_index);
+        auto node = this->node.get_no_gen(pos_index);
+        BLI_assert(vert && node);
+
+        vert.node = node.self_index;
+        node.verts.append(vert.self_index);
+
+        /* if vertex normals exist */
+        if (normals.size() > normal_index) {
+          node.normal = normals[normal_index];
+        }
+      }
+
+      /* update edges */
+      auto vert_1_i = face_index_data[0];
+      auto vert_2_i = face_index_data[0];
+      blender::Vector<VertIndex> face_verts;
+      blender::Vector<EdgeIndex> face_edges;
+      for (auto i = 1; i <= face_index_data.size(); i++) {
+        vert_1_i = vert_2_i;
+        if (i == face_index_data.size()) {
+          vert_2_i = face_index_data[0];
+        }
+        else {
+          vert_2_i = face_index_data[i];
+        }
+
+        auto vert_1_index = this->verts.get_no_gen_index(vert_1_i);
+        auto vert_2_index = this->verts.get_no_gen_index(vert_2_i);
+        BLI_assert(vert_1_index && vert_2_index);
+
+        if (auto edge_index = this->get_connecting_edge_index(vert_1_index, vert_2_index)) {
+          face_edges.append(edge_index);
+        }
+        else {
+          auto edge = this->add_empty_edge();
+
+          edge.verts = std::make_tuple(vert_1_index, vert_2_index);
+
+          auto vert_1 = this->verts.get(vert_1_index);
+          vert_1.edges.append(edge.self_index);
+
+          auto vert_2 = this->verts.get(vert_2_index);
+          vert_2.edges.append(edge.self_index);
+
+          face_edges.append(edge.self_index);
+        }
+      }
+
+      /* update faces */
+      {
+        auto face = this->add_empty_face(float3_unknown());
+
+        face.verts = face_verts;
+
+        for (const auto &edge_index : face_edges) {
+          auto edge = this->edges.get(edge_index);
+          BLI_assert(edge);
+
+          edge.faces.push(face.self_index);
+        }
+      }
+    }
+
+    /* TODO(ish): add support for lines */
+  }
+
+ protected:
+  /* all protected static methods */
+  /* all protected non-static methods */
+
+ private:
+  /* all private static methods */
+  static constexpr inline float3 float3_unknown()
+  {
+    return float3(std::numeric_limits<float>::signaling_NaN());
+  }
+
+  static constexpr inline float2 float2_unknown()
+  {
+    return float2(std::numeric_limits<float>::signaling_NaN());
+  }
+
+  /* all private non-static methods */
+  Node<END> &add_empty_node(float3 pos, float3 normal)
+  {
+    auto node_index = this->nodes.insert_with(
+        [=](NodeIndex index) { return Node<END>(index, pos, normal); });
+
+    return this->nodes.get(node_index);
+  }
+
+  Vert<EVD> &add_empty_vert(float2 uv)
+  {
+    auto vert_index = this->verts.insert_with(
+        [=](VertIndex index) { return Vert<EVD>(index, uv); });
+
+    return this->verts.get(vert_index);
+  }
+
+  Edge<EED> &add_empty_edge()
+  {
+    auto edge_index = this->edges.insert_with([=](EdgeIndex index) { return Edge<EED>(index); });
+
+    return this->edges.get(edge_index);
+  }
+
+  Face<EFD> &add_empty_face(float3 normal)
+  {
+    auto face_index = this->faces.insert_with(
+        [=](FaceIndex index) { return Face<EFD>(index, normal); });
+
+    return this->faces.get(face_index);
+  }
+};
+
 } /* namespace blender::bke::internal */
 
 #endif /* __cplusplus */



More information about the Bf-blender-cvs mailing list