Cleanup: Move legacy mesh conversions to proper file
This commit is contained in:
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
|
@ -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.
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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) */
|
||||
|
||||
|
|
|
@ -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)
|
||||
* \{ */
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
Loading…
Reference in New Issue