[Bf-blender-cvs] [4a313b82529] master: Cleanup: Move legacy mesh conversions to proper file

Hans Goudey noreply at git.blender.org
Fri Nov 4 23:28:47 CET 2022


Commit: 4a313b82529b95aa267086ca0c4f113e65bb79c8
Author: Hans Goudey
Date:   Fri Nov 4 23:28:10 2022 +0100
Branches: master
https://developer.blender.org/rB4a313b82529b95aa267086ca0c4f113e65bb79c8

Cleanup: Move legacy mesh conversions to proper file

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

M	source/blender/blenkernel/BKE_mesh.h
M	source/blender/blenkernel/BKE_mesh_legacy_convert.h
M	source/blender/blenkernel/intern/mesh.cc
M	source/blender/blenkernel/intern/mesh_legacy_convert.cc
M	source/blender/blenkernel/intern/mesh_validate.cc
M	source/blender/blenloader/intern/versioning_260.c
M	source/blender/blenloader/intern/versioning_legacy.c

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

diff --git a/source/blender/blenkernel/BKE_mesh.h b/source/blender/blenkernel/BKE_mesh.h
index 0ff7f50f71c..8f6786d4113 100644
--- a/source/blender/blenkernel/BKE_mesh.h
+++ b/source/blender/blenkernel/BKE_mesh.h
@@ -307,8 +307,6 @@ void BKE_mesh_translate(struct Mesh *me, const float offset[3], bool do_keys);
 
 void BKE_mesh_tessface_clear(struct Mesh *mesh);
 
-void BKE_mesh_do_versions_cd_flag_init(struct Mesh *mesh);
-
 void BKE_mesh_mselect_clear(struct Mesh *me);
 void BKE_mesh_mselect_validate(struct Mesh *me);
 /**
@@ -974,11 +972,6 @@ void BKE_mesh_strip_loose_faces(struct Mesh *me);
 void BKE_mesh_strip_loose_polysloops(struct Mesh *me);
 void BKE_mesh_strip_loose_edges(struct Mesh *me);
 
-/**
- * If the mesh is from a very old blender version,
- * convert #MFace.edcode to edge #ME_EDGEDRAW.
- */
-void BKE_mesh_calc_edges_legacy(struct Mesh *me, bool use_old);
 void BKE_mesh_calc_edges_loose(struct Mesh *mesh);
 /**
  * Calculate edges from polygons.
diff --git a/source/blender/blenkernel/BKE_mesh_legacy_convert.h b/source/blender/blenkernel/BKE_mesh_legacy_convert.h
index 92182f8045b..02c2bc9c330 100644
--- a/source/blender/blenkernel/BKE_mesh_legacy_convert.h
+++ b/source/blender/blenkernel/BKE_mesh_legacy_convert.h
@@ -123,6 +123,13 @@ void BKE_mesh_convert_mfaces_to_mpolys(struct Mesh *mesh);
  */
 void BKE_mesh_do_versions_convert_mfaces_to_mpolys(struct Mesh *mesh);
 
+/**
+ * Convert legacy #MFace.edcode to edge #ME_EDGEDRAW.
+ */
+void BKE_mesh_calc_edges_legacy(struct Mesh *me, bool use_old);
+
+void BKE_mesh_do_versions_cd_flag_init(struct Mesh *mesh);
+
 /* Inlines */
 
 /* NOTE(@sybren): Instead of -1 that function uses ORIGINDEX_NONE as defined in BKE_customdata.h,
diff --git a/source/blender/blenkernel/intern/mesh.cc b/source/blender/blenkernel/intern/mesh.cc
index 0018c217964..2d613f24a0a 100644
--- a/source/blender/blenkernel/intern/mesh.cc
+++ b/source/blender/blenkernel/intern/mesh.cc
@@ -1608,38 +1608,6 @@ void BKE_mesh_tessface_clear(Mesh *mesh)
   mesh_tessface_clear_intern(mesh, true);
 }
 
-void BKE_mesh_do_versions_cd_flag_init(Mesh *mesh)
-{
-  if (UNLIKELY(mesh->cd_flag)) {
-    return;
-  }
-
-  const Span<MVert> verts = mesh->verts();
-  const Span<MEdge> edges = mesh->edges();
-
-  for (const MVert &vert : verts) {
-    if (vert.bweight_legacy != 0) {
-      mesh->cd_flag |= ME_CDFLAG_VERT_BWEIGHT;
-      break;
-    }
-  }
-
-  for (const MEdge &edge : edges) {
-    if (edge.bweight_legacy != 0) {
-      mesh->cd_flag |= ME_CDFLAG_EDGE_BWEIGHT;
-      if (mesh->cd_flag & ME_CDFLAG_EDGE_CREASE) {
-        break;
-      }
-    }
-    if (edge.crease_legacy != 0) {
-      mesh->cd_flag |= ME_CDFLAG_EDGE_CREASE;
-      if (mesh->cd_flag & ME_CDFLAG_EDGE_BWEIGHT) {
-        break;
-      }
-    }
-  }
-}
-
 /* -------------------------------------------------------------------- */
 /* MSelect functions (currently used in weight paint mode) */
 
diff --git a/source/blender/blenkernel/intern/mesh_legacy_convert.cc b/source/blender/blenkernel/intern/mesh_legacy_convert.cc
index df3057d9592..feb40808704 100644
--- a/source/blender/blenkernel/intern/mesh_legacy_convert.cc
+++ b/source/blender/blenkernel/intern/mesh_legacy_convert.cc
@@ -29,6 +29,258 @@
 #include "BKE_mesh_legacy_convert.h"
 #include "BKE_multires.h"
 
+/* -------------------------------------------------------------------- */
+/** \name Legacy Edge Calculation
+ * \{ */
+
+struct EdgeSort {
+  uint v1, v2;
+  char is_loose, is_draw;
+};
+
+/* edges have to be added with lowest index first for sorting */
+static void to_edgesort(struct EdgeSort *ed, uint v1, uint v2, char is_loose, short is_draw)
+{
+  if (v1 < v2) {
+    ed->v1 = v1;
+    ed->v2 = v2;
+  }
+  else {
+    ed->v1 = v2;
+    ed->v2 = v1;
+  }
+  ed->is_loose = is_loose;
+  ed->is_draw = is_draw;
+}
+
+static int vergedgesort(const void *v1, const void *v2)
+{
+  const struct EdgeSort *x1 = static_cast<const struct EdgeSort *>(v1);
+  const struct EdgeSort *x2 = static_cast<const struct EdgeSort *>(v2);
+
+  if (x1->v1 > x2->v1) {
+    return 1;
+  }
+  if (x1->v1 < x2->v1) {
+    return -1;
+  }
+  if (x1->v2 > x2->v2) {
+    return 1;
+  }
+  if (x1->v2 < x2->v2) {
+    return -1;
+  }
+
+  return 0;
+}
+
+/* Create edges based on known verts and faces,
+ * this function is only used when loading very old blend files */
+static void mesh_calc_edges_mdata(const MVert * /*allvert*/,
+                                  const MFace *allface,
+                                  MLoop *allloop,
+                                  const MPoly *allpoly,
+                                  int /*totvert*/,
+                                  int totface,
+                                  int /*totloop*/,
+                                  int totpoly,
+                                  const bool use_old,
+                                  MEdge **r_medge,
+                                  int *r_totedge)
+{
+  const MPoly *mpoly;
+  const MFace *mface;
+  MEdge *medge, *med;
+  EdgeHash *hash;
+  struct EdgeSort *edsort, *ed;
+  int a, totedge = 0;
+  uint totedge_final = 0;
+  uint edge_index;
+
+  /* we put all edges in array, sort them, and detect doubles that way */
+
+  for (a = totface, mface = allface; a > 0; a--, mface++) {
+    if (mface->v4) {
+      totedge += 4;
+    }
+    else if (mface->v3) {
+      totedge += 3;
+    }
+    else {
+      totedge += 1;
+    }
+  }
+
+  if (totedge == 0) {
+    /* flag that mesh has edges */
+    (*r_medge) = (MEdge *)MEM_callocN(0, __func__);
+    (*r_totedge) = 0;
+    return;
+  }
+
+  ed = edsort = (EdgeSort *)MEM_mallocN(totedge * sizeof(struct EdgeSort), "EdgeSort");
+
+  for (a = totface, mface = allface; a > 0; a--, mface++) {
+    to_edgesort(ed++, mface->v1, mface->v2, !mface->v3, mface->edcode & ME_V1V2);
+    if (mface->v4) {
+      to_edgesort(ed++, mface->v2, mface->v3, 0, mface->edcode & ME_V2V3);
+      to_edgesort(ed++, mface->v3, mface->v4, 0, mface->edcode & ME_V3V4);
+      to_edgesort(ed++, mface->v4, mface->v1, 0, mface->edcode & ME_V4V1);
+    }
+    else if (mface->v3) {
+      to_edgesort(ed++, mface->v2, mface->v3, 0, mface->edcode & ME_V2V3);
+      to_edgesort(ed++, mface->v3, mface->v1, 0, mface->edcode & ME_V3V1);
+    }
+  }
+
+  qsort(edsort, totedge, sizeof(struct EdgeSort), vergedgesort);
+
+  /* count final amount */
+  for (a = totedge, ed = edsort; a > 1; a--, ed++) {
+    /* edge is unique when it differs from next edge, or is last */
+    if (ed->v1 != (ed + 1)->v1 || ed->v2 != (ed + 1)->v2) {
+      totedge_final++;
+    }
+  }
+  totedge_final++;
+
+  medge = (MEdge *)MEM_callocN(sizeof(MEdge) * totedge_final, __func__);
+
+  for (a = totedge, med = medge, ed = edsort; a > 1; a--, ed++) {
+    /* edge is unique when it differs from next edge, or is last */
+    if (ed->v1 != (ed + 1)->v1 || ed->v2 != (ed + 1)->v2) {
+      med->v1 = ed->v1;
+      med->v2 = ed->v2;
+      if (use_old == false || ed->is_draw) {
+        med->flag = ME_EDGEDRAW;
+      }
+      if (ed->is_loose) {
+        med->flag |= ME_LOOSEEDGE;
+      }
+
+      /* order is swapped so extruding this edge as a surface won't flip face normals
+       * with cyclic curves */
+      if (ed->v1 + 1 != ed->v2) {
+        SWAP(uint, med->v1, med->v2);
+      }
+      med++;
+    }
+    else {
+      /* Equal edge, merge the draw-flag. */
+      (ed + 1)->is_draw |= ed->is_draw;
+    }
+  }
+  /* last edge */
+  med->v1 = ed->v1;
+  med->v2 = ed->v2;
+  med->flag = ME_EDGEDRAW;
+  if (ed->is_loose) {
+    med->flag |= ME_LOOSEEDGE;
+  }
+
+  MEM_freeN(edsort);
+
+  /* set edge members of mloops */
+  hash = BLI_edgehash_new_ex(__func__, totedge_final);
+  for (edge_index = 0, med = medge; edge_index < totedge_final; edge_index++, med++) {
+    BLI_edgehash_insert(hash, med->v1, med->v2, POINTER_FROM_UINT(edge_index));
+  }
+
+  mpoly = allpoly;
+  for (a = 0; a < totpoly; a++, mpoly++) {
+    MLoop *ml, *ml_next;
+    int i = mpoly->totloop;
+
+    ml_next = allloop + mpoly->loopstart; /* first loop */
+    ml = &ml_next[i - 1];                 /* last loop */
+
+    while (i-- != 0) {
+      ml->e = POINTER_AS_UINT(BLI_edgehash_lookup(hash, ml->v, ml_next->v));
+      ml = ml_next;
+      ml_next++;
+    }
+  }
+
+  BLI_edgehash_free(hash, nullptr);
+
+  *r_medge = medge;
+  *r_totedge = totedge_final;
+}
+
+void BKE_mesh_calc_edges_legacy(Mesh *me, const bool use_old)
+{
+  using namespace blender;
+  MEdge *medge;
+  int totedge = 0;
+  const Span<MVert> verts = me->verts();
+  const Span<MPoly> polys = me->polys();
+  MutableSpan<MLoop> loops = me->loops_for_write();
+
+  mesh_calc_edges_mdata(verts.data(),
+                        (MFace *)CustomData_get_layer(&me->fdata, CD_MFACE),
+                        loops.data(),
+                        polys.data(),
+                        verts.size(),
+                        me->totface,
+                        loops.size(),
+                        polys.size(),
+                        use_old,
+                        &medge,
+                        &totedge);
+
+  if (totedge == 0) {
+    /* flag that mesh has edges */
+    me->totedge = 0;
+    return;
+  }
+
+  medge = (MEdge *)CustomData_add_layer(&me->edata, CD_MEDGE, CD_ASSIGN, medge, totedge);
+  me->totedge = totedge;
+
+  BKE_mesh_strip_loose_faces(me);
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name CD Flag Initialization
+ * \{ */
+
+void BKE_mesh_do_versions_cd_flag_init(Mesh *mesh)
+{
+  using namespace blender;
+  if (UNLIKELY(mesh->cd_flag)) {
+    return;
+  }
+
+  const Span<MVert> verts = mesh->verts();
+  const Span<MEdge> edges = mesh->edges();
+
+  for (const MVert &vert : verts) {
+    if (vert.bweight_legacy != 0) {
+      mesh->cd_flag |= ME_CDFLAG_VERT_BWEIGHT;
+      break;
+    }
+  }
+
+  for (const MEdge &edge : edges) {
+    if (edge.bweight_legacy != 0) {
+      mesh->cd_flag |= ME_CDFLAG_EDGE_BWEIGHT;
+      if (mesh->cd_flag & ME_CDFLAG_EDGE_CREASE) {
+        break;
+      }
+    }
+    if (edge.crease_legacy != 0) {
+      mesh->cd_flag |= ME_CDFLAG_EDGE_CREASE;
+      if (mesh->cd_flag & ME_CDFLAG_EDGE_BWEIGHT) {
+        break;
+      }
+    }


@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list