Commit: 9ac8def136f5b3aa3520ea21274b29d85bb80b81
Author: Ankit Meel
Date:   Fri Aug 28 03:13:36 2020 +0530
Branches: soc-2020-io-performance
https://developer.blender.org/rB9ac8def136f5b3aa3520ea21274b29d85bb80b81

Fix ngon_tessellate filling the holes.

Fix several issues from the commit {rBefab0bc704ece3a}.
Previously, `ngon_tessellate` was filling the holes instead of
triangulating around them by using the "triangle-fan" method.

Now it triangulates around the holes and doesn't fill them.

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

M       source/blender/io/wavefront_obj/intern/mesh_utils.cc

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

diff --git a/source/blender/io/wavefront_obj/intern/mesh_utils.cc 
b/source/blender/io/wavefront_obj/intern/mesh_utils.cc
index 21c65583344..bf2cee2fff8 100644
--- a/source/blender/io/wavefront_obj/intern/mesh_utils.cc
+++ b/source/blender/io/wavefront_obj/intern/mesh_utils.cc
@@ -45,7 +45,7 @@ struct vert_treplet {
   }
   friend bool operator==(const vert_treplet &one, const vert_treplet &other)
   {
-    return other.i == one.i;
+    return other.v == one.v;
   }
   friend bool operator!=(const vert_treplet &one, const vert_treplet &other)
   {
@@ -53,34 +53,43 @@ struct vert_treplet {
   }
 };
 
-static std::pair<int, int> ed_key_mlen(const vert_treplet &v1, const 
vert_treplet &v2)
+static std::pair<float3, float3> ed_key_mlen(const vert_treplet &v1, const 
vert_treplet &v2)
 {
-  if (v1.mlen > v2.mlen) {
-    return {v2.i, v1.i};
+  if (v2.mlen < v1.mlen) {
+    return {v2.v, v1.v};
   }
-  return {v1.i, v2.i};
+  return {v1.v, v2.v};
 }
 
-static bool join_segments(Vector<vert_treplet> &seg1, Vector<vert_treplet> 
&seg2)
+static bool join_segments(Vector<vert_treplet> *r_seg1, Vector<vert_treplet> 
*r_seg2)
 {
-  if (seg1.last().v == seg2.last().v) {
-    Vector<vert_treplet> &temp = seg1;
-    seg1 = seg2;
-    seg2 = temp;
+  if ((*r_seg1)[0].v == r_seg2->last().v) {
+    Vector<vert_treplet> *temp = r_seg1;
+    r_seg1 = r_seg2;
+    r_seg2 = temp;
+  }
+  else if (r_seg1->last().v == (*r_seg2)[0].v) {
   }
   else {
     return false;
   }
-  seg1.remove_last();
-  seg2.extend(seg1);
-  if (seg1.last().v == seg1[0].v) {
-    seg1.remove_last();
+  r_seg1->remove_last();
+  r_seg1->extend(*r_seg2);
+  if (r_seg1->last().v == (*r_seg1)[0].v) {
+    r_seg1->remove_last();
   }
-  seg2.clear();
+  r_seg2->clear();
   return true;
 }
 
-static void tessellate_polygon(Vector<Vector<const float3 *>> &polyLineSeq,
+/**
+ *  A simplified version of `M_Geometry_tessellate_polygon`.
+ *
+ * \param polyLineSeq List of polylines.
+ * \param r_new_line_seq Empty vector that fill be filled with indices of 
corners of triangles.
+ */
+
+static void tessellate_polygon(const Vector<Vector<float3>> &polyLineSeq,
                                Vector<Vector<int>> &r_new_line_seq)
 {
   int64_t totpoints = 0;
@@ -90,39 +99,41 @@ static void tessellate_polygon(Vector<Vector<const float3 
*>> &polyLineSeq,
   const int64_t len_polylines{polyLineSeq.size()};
 
   for (int i = 0; i < len_polylines; i++) {
-    Vector<const float3 *> &polyLine = polyLineSeq[i];
+    Span<float3> polyLine = polyLineSeq[i];
 
     const int64_t len_polypoints{polyLine.size()};
     totpoints += len_polypoints;
-    if (len_polypoints > 0) { /* don't bother adding edges as polylines */
-      dl = static_cast<DispList *>(MEM_callocN(sizeof(DispList), __func__));
-      BLI_addtail(&dispbase, dl);
-      dl->type = DL_INDEX3;
-      dl->nr = len_polypoints;
-      dl->type = DL_POLY;
-      dl->parts = 1; /* no faces, 1 edge loop */
-      dl->col = 0;   /* no material */
-      dl->verts = static_cast<float *>(MEM_mallocN(sizeof(float[3]) * 
len_polypoints, "dl verts"));
-      dl->index = static_cast<int *>(MEM_callocN(sizeof(int[3]) * 
len_polypoints, "dl index"));
+    if (len_polypoints <= 0) { /* don't bother adding edges as polylines */
+      continue;
+    }
+    dl = static_cast<DispList *>(MEM_callocN(sizeof(DispList), __func__));
+    BLI_addtail(&dispbase, dl);
+    dl->type = DL_INDEX3;
+    dl->nr = len_polypoints;
+    dl->type = DL_POLY;
+    dl->parts = 1; /* no faces, 1 edge loop */
+    dl->col = 0;   /* no material */
+    dl->verts = static_cast<float *>(MEM_mallocN(sizeof(float[3]) * 
len_polypoints, "dl verts"));
+    dl->index = static_cast<int *>(MEM_callocN(sizeof(int[3]) * 
len_polypoints, "dl index"));
+    float *fp_verts = dl->verts;
+    for (int j = 0; j < len_polypoints; j++, fp_verts += 3) {
+      copy_v3_v3(fp_verts, polyLine[j]);
     }
   }
 
   if (totpoints) {
-    /* now make the list to return */
+    /* now make the list to fill */
     BKE_displist_fill(&dispbase, &dispbase, NULL, false);
 
     /* The faces are stored in a new DisplayList
      * that's added to the head of the #ListBase. */
     dl = static_cast<DispList *>(dispbase.first);
 
-    int *dl_face = dl->index;
-    r_new_line_seq.append({dl_face[0], dl_face[1], dl_face[2]});
+    for (int index = 0, *dl_face = dl->index; index < dl->parts; index++, 
dl_face += 3) {
+      r_new_line_seq.append({dl_face[0], dl_face[1], dl_face[2]});
+    }
     BKE_displist_free(&dispbase);
   }
-  else {
-    /* no points, do this so scripts don't barf */
-    BKE_displist_free(&dispbase); /* possible some dl was allocated */
-  }
 }
 
 /**
@@ -149,37 +160,39 @@ Vector<Vector<int>> ngon_tessellate(Span<float3> 
vertex_coords, Span<int> face_v
   }
   edges[0] = {0, static_cast<int>(face_vertex_indices.size() - 1)};
 
-  Set<std::pair<int, int>> used_edges;
-  Set<std::pair<int, int>> double_edges;
-
-  for (const Array<int, 2> &edge : edges) {
-    std::pair<int, int> edge_key = ed_key_mlen(verts[edge[0]], verts[edge[1]]);
-    if (used_edges.contains(edge_key)) {
-      double_edges.add(edge_key);
-    }
-    else {
-      used_edges.add(edge_key);
+  Set<std::pair<float3, float3>> edges_double;
+  {
+    Set<std::pair<float3, float3>> edges_used;
+    for (Span<int> edge : edges) {
+      std::pair<float3, float3> edge_key{ed_key_mlen(verts[edge[0]], 
verts[edge[1]])};
+      if (edges_used.contains(edge_key)) {
+        edges_double.add(edge_key);
+      }
+      else {
+        edges_used.add(edge_key);
+      }
     }
   }
 
   Vector<Vector<vert_treplet>> loop_segments;
   {
     const vert_treplet *vert_prev = &verts[0];
-    Vector<vert_treplet> contex_loop{1, *vert_prev};
-    loop_segments.append(contex_loop);
+    Vector<vert_treplet> context_loop{1, *vert_prev};
+    loop_segments.append(context_loop);
     for (const vert_treplet &vertex : verts) {
       if (vertex == *vert_prev) {
         continue;
       }
-      if (double_edges.contains(ed_key_mlen(vertex, *vert_prev))) {
-        contex_loop = {vertex};
-        loop_segments.append(contex_loop);
+      if (edges_double.contains(ed_key_mlen(vertex, *vert_prev))) {
+        context_loop = {vertex};
+        loop_segments.append(context_loop);
       }
       else {
-        if (!contex_loop.is_empty() && contex_loop.last() == vertex) {
+        if (!context_loop.is_empty() && context_loop.last() == vertex) {
         }
         else {
-          contex_loop.append(vertex);
+          loop_segments.last().append(vertex);
+          context_loop.append(vertex);
         }
       }
       vert_prev = &vertex;
@@ -189,9 +202,8 @@ Vector<Vector<int>> ngon_tessellate(Span<float3> 
vertex_coords, Span<int> face_v
   bool joining_segements = true;
   while (joining_segements) {
     joining_segements = false;
-    const int segcount = loop_segments.size();
-    for (int j = segcount - 1; j >= 0; j--) {
-      Vector<vert_treplet> seg_j = loop_segments[j];
+    for (int j = loop_segments.size() - 1; j >= 0; j--) {
+      Vector<vert_treplet> &seg_j = loop_segments[j];
       if (seg_j.is_empty()) {
         continue;
       }
@@ -199,8 +211,8 @@ Vector<Vector<int>> ngon_tessellate(Span<float3> 
vertex_coords, Span<int> face_v
         if (seg_j.is_empty()) {
           break;
         }
-        Vector<vert_treplet> seg_k = loop_segments[k];
-        if (!seg_j.is_empty() && join_segments(seg_j, seg_k)) {
+        Vector<vert_treplet> &seg_k = loop_segments[k];
+        if (!seg_k.is_empty() && join_segments(&seg_j, &seg_k)) {
           joining_segements = true;
         }
       }
@@ -208,7 +220,7 @@ Vector<Vector<int>> ngon_tessellate(Span<float3> 
vertex_coords, Span<int> face_v
   }
 
   for (Vector<vert_treplet> &loop : loop_segments) {
-    if (!loop.is_empty() && loop[0].v == loop.last().v) {
+    while (!loop.is_empty() && loop[0].v == loop.last().v) {
       loop.remove_last();
     }
   }
@@ -221,37 +233,39 @@ Vector<Vector<int>> ngon_tessellate(Span<float3> 
vertex_coords, Span<int> face_v
   }
   // Done with loop fixing.
 
-  Vector<int> vert_map{face_vertex_indices.size()};
+  Vector<int> vert_map(face_vertex_indices.size(), 0);
   int ii = 0;
-  for (Vector<vert_treplet> &verts : loop_list) {
+  for (Span<vert_treplet> verts : loop_list) {
     if (verts.size() <= 2) {
       continue;
     }
     for (int i = 0; i < verts.size(); i++) {
       vert_map[i + ii] = verts[i].i;
     }
+    ii += verts.size();
   }
 
-  Vector<Vector<const float3 *>> coord_list;
-  for (int i = 0; i < loop_list.size(); i++) {
-    Span<vert_treplet> loop = loop_list[i];
-    Vector<const float3 *> vert_ptrs;
-    for (const vert_treplet &vert : loop) {
-      vert_ptrs.append(&vert.v);
+  Vector<Vector<int>> fill;
+  {
+    Vector<Vector<float3>> coord_list;
+    for (Span<vert_treplet> loop : loop_list) {
+      Vector<float3> coord;
+      for (const vert_treplet &vert : loop) {
+        coord.append(vert.v);
+      }
+      coord_list.append(coord);
     }
-    coord_list.append(vert_ptrs);
+    tessellate_polygon(coord_list, fill);
   }
-  Vector<Vector<int>> fill;
-  tessellate_polygon(coord_list, fill);
 
   Vector<Vector<int>> fill_indices;
   Vector<Vector<int>> fill_indices_reversed;
   for (Span<int> f : fill) {
-    Vector<int> corner(f.size());
+    Vector<int> tri;
     for (const int i : f) {
-      corner.append(vert_map[i]);
+      tri.append(vert_map[i]);
     }
-    fill_indices.append(corner);
+    fill_indices.append(tri);
   }
 
   if (fill_indices.is_empty()) {
@@ -277,11 +291,12 @@ Vector<Vector<int>> ngon_tessellate(Span<float3> 
vertex_coords, Span<int> face_v
         }
       }
     }
-    if (flip != 1) {
+    if (flip == 1) {
       for (int i = 0; i < fill_indices.size(); i++) {
-        Vector<int> rev_face(fill_indices[i].size());
-        for (const int fi : fill_indices[i]) {
-          rev_face.append(fi);
+        Span<int> fi = fill_indices[i];
+        Vector<int> rev_face(fi.size());
+        for (int j = 0; j < rev_face.size(); j++) {
+          rev_face[j] = fi[rev_face.size() - 1 - j];
         }
         fill_indices_reversed.append(rev_face);
       }
@@ -289,7 +304,6 @@ Vector<Vector<int>> ngon_tessellate(

@@ Diff output truncated at 10240 characters. @@

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
https://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to