Cleanup: Move legacy mesh conversions to proper file

This commit is contained in:
Hans Goudey 2022-11-04 23:28:10 +01:00
parent 23dafa4ad6
commit 4a313b8252
Notes: blender-bot 2023-02-14 04:31:04 +01:00
Referenced by issue #102482, GN: Crash with Shift+A when editing files containing node group assets
Referenced by issue #102308, Grease Pencil depth merge is broken when multiple GP objects are displayed in viewport
7 changed files with 261 additions and 248 deletions

View File

@ -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.

View File

@ -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,

View File

@ -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) */

View File

@ -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;
}
}
}
}
/** \} */
/* -------------------------------------------------------------------- */
/** \name NGon Tessellation (NGon to MFace Conversion)
* \{ */

View File

@ -1315,215 +1315,6 @@ void BKE_mesh_strip_loose_edges(Mesh *me)
/** \name Mesh Edge Calculation
* \{ */
/* make edges in a Mesh, for outside of editmode */
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)
{
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);
}
void BKE_mesh_calc_edges_loose(Mesh *mesh)
{
const Span<MLoop> loops = mesh->loops();

View File

@ -44,6 +44,7 @@
#include "BKE_image.h"
#include "BKE_main.h" /* for Main */
#include "BKE_mesh.h" /* for ME_ defines (patching) */
#include "BKE_mesh_legacy_convert.h"
#include "BKE_modifier.h"
#include "BKE_particle.h"
#include "BKE_pointcache.h"

View File

@ -62,6 +62,7 @@
#include "BKE_object.h"
#include "BKE_particle.h"
#include "BKE_pointcache.h"
#include "BKE_mesh_legacy_convert.h"
#include "SEQ_iterator.h"
#include "SEQ_sequencer.h"