Multires: Remove legacy compatibility code

It was rather a huge chunk of code, which started to become
more harder to maintain with the transition to OpenSubdiv based
implementation. Because of this transition, the compatibility was
also rather on a poor side.

Remove compatibility support for pre-2.50.9 multires.

Ref T77107

Reviewed By: brecht, mont29

Differential Revision: https://developer.blender.org/D9238
This commit is contained in:
Sergey Sharybin 2020-10-22 12:05:48 +02:00
parent f68c3d557a
commit d11e357824
Notes: blender-bot 2023-02-13 22:24:11 +01:00
Referenced by issue #77107, Multires: Remove pre-2.5 compatibility code
7 changed files with 1 additions and 857 deletions

View File

@ -36,7 +36,6 @@ struct DerivedMesh;
struct MDisps;
struct Mesh;
struct ModifierData;
struct Multires;
struct MultiresModifierData;
struct Object;
struct Scene;
@ -125,11 +124,6 @@ void multiresModifier_sync_levels_ex(struct Object *ob_dst,
void multires_stitch_grids(struct Object *);
/* Related to the old multires */
void multires_free(struct Multires *mr);
void multires_load_old(struct Object *ob, struct Mesh *me);
void multires_load_old_250(struct Mesh *);
void multiresModifier_scale_disp(struct Depsgraph *depsgraph,
struct Scene *scene,
struct Object *ob);

View File

@ -275,50 +275,6 @@ static void mesh_blend_read_data(BlendDataReader *reader, ID *id)
mesh->totselect = 0;
}
/* Multires data */
BLO_read_data_address(reader, &mesh->mr);
if (mesh->mr) {
BLO_read_list(reader, &mesh->mr->levels);
MultiresLevel *lvl = mesh->mr->levels.first;
CustomData_blend_read(reader, &mesh->mr->vdata, lvl->totvert);
BKE_defvert_blend_read(
reader, lvl->totvert, CustomData_get(&mesh->mr->vdata, 0, CD_MDEFORMVERT));
CustomData_blend_read(reader, &mesh->mr->fdata, lvl->totface);
BLO_read_data_address(reader, &mesh->mr->edge_flags);
BLO_read_data_address(reader, &mesh->mr->edge_creases);
BLO_read_data_address(reader, &mesh->mr->verts);
/* If mesh has the same number of vertices as the
* highest multires level, load the current mesh verts
* into multires and discard the old data. Needed
* because some saved files either do not have a verts
* array, or the verts array contains out-of-date
* data. */
if (mesh->totvert == ((MultiresLevel *)mesh->mr->levels.last)->totvert) {
if (mesh->mr->verts) {
MEM_freeN(mesh->mr->verts);
}
mesh->mr->verts = MEM_dupallocN(mesh->mvert);
}
for (; lvl; lvl = lvl->next) {
BLO_read_data_address(reader, &lvl->verts);
BLO_read_data_address(reader, &lvl->faces);
BLO_read_data_address(reader, &lvl->edges);
BLO_read_data_address(reader, &lvl->colfaces);
}
}
/* if multires is present but has no valid vertex data,
* there's no way to recover it; silently remove multires */
if (mesh->mr && !mesh->mr->verts) {
multires_free(mesh->mr);
mesh->mr = NULL;
}
if ((BLO_read_requires_endian_switch(reader)) && mesh->tface) {
TFace *tf = mesh->tface;
for (int i = 0; i < mesh->totface; i++, tf++) {

View File

@ -1449,9 +1449,6 @@ DerivedMesh *multires_make_derived_from_derived(
return result;
}
/**** Old Multires code ****
***************************/
/* Adapted from sculptmode.c */
void old_mdisps_bilinear(float out[3], float (*disps)[3], const int st, float u, float v)
{
@ -1506,723 +1503,6 @@ void old_mdisps_bilinear(float out[3], float (*disps)[3], const int st, float u,
add_v3_v3v3(out, d2[0], d2[1]);
}
static void old_mdisps_rotate(
int S, int UNUSED(newside), int oldside, int x, int y, float *u, float *v)
{
float offset = oldside * 0.5f - 0.5f;
if (S == 1) {
*u = offset + x;
*v = offset - y;
}
if (S == 2) {
*u = offset + y;
*v = offset + x;
}
if (S == 3) {
*u = offset - x;
*v = offset + y;
}
if (S == 0) {
*u = offset - y;
*v = offset - x;
}
}
static void old_mdisps_convert(MFace *mface, MDisps *mdisp)
{
int newlvl = log(sqrt(mdisp->totdisp) - 1) / M_LN2;
int oldlvl = newlvl + 1;
int oldside = multires_side_tot[oldlvl];
int newside = multires_side_tot[newlvl];
int nvert = (mface->v4) ? 4 : 3;
int newtotdisp = multires_grid_tot[newlvl] * nvert;
int x, y, S;
float(*disps)[3], (*out)[3], u = 0.0f, v = 0.0f; /* Quite gcc barking. */
disps = MEM_calloc_arrayN(newtotdisp, sizeof(float[3]), "multires disps");
out = disps;
for (S = 0; S < nvert; S++) {
for (y = 0; y < newside; y++) {
for (x = 0; x < newside; x++, out++) {
old_mdisps_rotate(S, newside, oldside, x, y, &u, &v);
old_mdisps_bilinear(*out, mdisp->disps, oldside, u, v);
if (S == 1) {
(*out)[1] = -(*out)[1];
}
else if (S == 2) {
SWAP(float, (*out)[0], (*out)[1]);
}
else if (S == 3) {
(*out)[0] = -(*out)[0];
}
else if (S == 0) {
SWAP(float, (*out)[0], (*out)[1]);
(*out)[0] = -(*out)[0];
(*out)[1] = -(*out)[1];
}
}
}
}
MEM_freeN(mdisp->disps);
mdisp->totdisp = newtotdisp;
mdisp->level = newlvl;
mdisp->disps = disps;
}
void multires_load_old_250(Mesh *me)
{
MDisps *mdisps, *mdisps2;
MFace *mf;
int i, j, k;
mdisps = CustomData_get_layer(&me->fdata, CD_MDISPS);
if (mdisps) {
for (i = 0; i < me->totface; i++) {
if (mdisps[i].totdisp) {
old_mdisps_convert(&me->mface[i], &mdisps[i]);
}
}
CustomData_add_layer(&me->ldata, CD_MDISPS, CD_CALLOC, NULL, me->totloop);
mdisps2 = CustomData_get_layer(&me->ldata, CD_MDISPS);
k = 0;
mf = me->mface;
for (i = 0; i < me->totface; i++, mf++) {
int nvert = mf->v4 ? 4 : 3;
int totdisp = mdisps[i].totdisp / nvert;
for (j = 0; j < nvert; j++, k++) {
mdisps2[k].disps = MEM_calloc_arrayN(
totdisp, sizeof(float[3]), "multires disp in conversion");
mdisps2[k].totdisp = totdisp;
mdisps2[k].level = mdisps[i].level;
memcpy(mdisps2[k].disps, mdisps[i].disps + totdisp * j, totdisp);
}
}
}
}
/* Does not actually free lvl itself */
static void multires_free_level(MultiresLevel *lvl)
{
if (lvl) {
if (lvl->faces) {
MEM_freeN(lvl->faces);
}
if (lvl->edges) {
MEM_freeN(lvl->edges);
}
if (lvl->colfaces) {
MEM_freeN(lvl->colfaces);
}
}
}
void multires_free(Multires *mr)
{
if (mr) {
MultiresLevel *lvl = mr->levels.first;
/* Free the first-level data */
if (lvl) {
CustomData_free(&mr->vdata, lvl->totvert);
CustomData_free(&mr->fdata, lvl->totface);
if (mr->edge_flags) {
MEM_freeN(mr->edge_flags);
}
if (mr->edge_creases) {
MEM_freeN(mr->edge_creases);
}
}
while (lvl) {
multires_free_level(lvl);
lvl = lvl->next;
}
/* mr->verts may be NULL when loading old files,
* see direct_link_mesh() in readfile.c, and T43560. */
MEM_SAFE_FREE(mr->verts);
BLI_freelistN(&mr->levels);
MEM_freeN(mr);
}
}
typedef struct IndexNode {
struct IndexNode *next, *prev;
int index;
} IndexNode;
static void create_old_vert_face_map(ListBase **map,
IndexNode **mem,
const MultiresFace *mface,
const int totvert,
const int totface)
{
int i, j;
IndexNode *node = NULL;
(*map) = MEM_calloc_arrayN(totvert, sizeof(ListBase), "vert face map");
(*mem) = MEM_calloc_arrayN(totface, sizeof(IndexNode[4]), "vert face map mem");
node = *mem;
/* Find the users */
for (i = 0; i < totface; i++) {
for (j = 0; j < (mface[i].v[3] ? 4 : 3); j++, node++) {
node->index = i;
BLI_addtail(&(*map)[mface[i].v[j]], node);
}
}
}
static void create_old_vert_edge_map(ListBase **map,
IndexNode **mem,
const MultiresEdge *medge,
const int totvert,
const int totedge)
{
int i, j;
IndexNode *node = NULL;
(*map) = MEM_calloc_arrayN(totvert, sizeof(ListBase), "vert edge map");
(*mem) = MEM_calloc_arrayN(totedge, sizeof(IndexNode[2]), "vert edge map mem");
node = *mem;
/* Find the users */
for (i = 0; i < totedge; i++) {
for (j = 0; j < 2; j++, node++) {
node->index = i;
BLI_addtail(&(*map)[medge[i].v[j]], node);
}
}
}
static MultiresFace *find_old_face(
ListBase *map, MultiresFace *faces, int v1, int v2, int v3, int v4)
{
IndexNode *n1;
int v[4], i, j;
v[0] = v1;
v[1] = v2;
v[2] = v3;
v[3] = v4;
for (n1 = map[v1].first; n1; n1 = n1->next) {
int fnd[4] = {0, 0, 0, 0};
for (i = 0; i < 4; i++) {
for (j = 0; j < 4; j++) {
if (v[i] == faces[n1->index].v[j]) {
fnd[i] = 1;
}
}
}
if (fnd[0] && fnd[1] && fnd[2] && fnd[3]) {
return &faces[n1->index];
}
}
return NULL;
}
static MultiresEdge *find_old_edge(ListBase *map, MultiresEdge *edges, int v1, int v2)
{
IndexNode *n1, *n2;
for (n1 = map[v1].first; n1; n1 = n1->next) {
for (n2 = map[v2].first; n2; n2 = n2->next) {
if (n1->index == n2->index) {
return &edges[n1->index];
}
}
}
return NULL;
}
static void multires_load_old_edges(
ListBase **emap, MultiresLevel *lvl, int *vvmap, int dst, int v1, int v2, int mov)
{
int emid = find_old_edge(emap[2], lvl->edges, v1, v2)->mid;
vvmap[dst + mov] = emid;
if (lvl->next->next) {
multires_load_old_edges(emap + 1, lvl->next, vvmap, dst + mov, v1, emid, mov / 2);
multires_load_old_edges(emap + 1, lvl->next, vvmap, dst + mov, v2, emid, -mov / 2);
}
}
static void multires_load_old_faces(ListBase **fmap,
ListBase **emap,
MultiresLevel *lvl,
int *vvmap,
int dst,
int v1,
int v2,
int v3,
int v4,
int st2,
int st3)
{
int fmid;
int emid13, emid14, emid23, emid24;
if (lvl && lvl->next) {
fmid = find_old_face(fmap[1], lvl->faces, v1, v2, v3, v4)->mid;
vvmap[dst] = fmid;
emid13 = find_old_edge(emap[1], lvl->edges, v1, v3)->mid;
emid14 = find_old_edge(emap[1], lvl->edges, v1, v4)->mid;
emid23 = find_old_edge(emap[1], lvl->edges, v2, v3)->mid;
emid24 = find_old_edge(emap[1], lvl->edges, v2, v4)->mid;
multires_load_old_faces(fmap + 1,
emap + 1,
lvl->next,
vvmap,
dst + st2 * st3 + st3,
fmid,
v2,
emid23,
emid24,
st2,
st3 / 2);
multires_load_old_faces(fmap + 1,
emap + 1,
lvl->next,
vvmap,
dst - st2 * st3 + st3,
emid14,
emid24,
fmid,
v4,
st2,
st3 / 2);
multires_load_old_faces(fmap + 1,
emap + 1,
lvl->next,
vvmap,
dst + st2 * st3 - st3,
emid13,
emid23,
v3,
fmid,
st2,
st3 / 2);
multires_load_old_faces(fmap + 1,
emap + 1,
lvl->next,
vvmap,
dst - st2 * st3 - st3,
v1,
fmid,
emid13,
emid14,
st2,
st3 / 2);
if (lvl->next->next) {
multires_load_old_edges(emap, lvl->next, vvmap, dst, emid24, fmid, st3);
multires_load_old_edges(emap, lvl->next, vvmap, dst, emid13, fmid, -st3);
multires_load_old_edges(emap, lvl->next, vvmap, dst, emid14, fmid, -st2 * st3);
multires_load_old_edges(emap, lvl->next, vvmap, dst, emid23, fmid, st2 * st3);
}
}
}
static void multires_mvert_to_ss(DerivedMesh *dm, MVert *mvert)
{
CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm;
CCGSubSurf *ss = ccgdm->ss;
CCGElem *vd;
CCGKey key;
int index;
int totvert, totedge, totface;
int gridSize = ccgSubSurf_getGridSize(ss);
int edgeSize = ccgSubSurf_getEdgeSize(ss);
int i = 0;
dm->getGridKey(dm, &key);
totface = ccgSubSurf_getNumFaces(ss);
for (index = 0; index < totface; index++) {
CCGFace *f = ccgdm->faceMap[index].face;
int x, y, S, numVerts = ccgSubSurf_getFaceNumVerts(f);
vd = ccgSubSurf_getFaceCenterData(f);
copy_v3_v3(CCG_elem_co(&key, vd), mvert[i].co);
i++;
for (S = 0; S < numVerts; S++) {
for (x = 1; x < gridSize - 1; x++, i++) {
vd = ccgSubSurf_getFaceGridEdgeData(ss, f, S, x);
copy_v3_v3(CCG_elem_co(&key, vd), mvert[i].co);
}
}
for (S = 0; S < numVerts; S++) {
for (y = 1; y < gridSize - 1; y++) {
for (x = 1; x < gridSize - 1; x++, i++) {
vd = ccgSubSurf_getFaceGridData(ss, f, S, x, y);
copy_v3_v3(CCG_elem_co(&key, vd), mvert[i].co);
}
}
}
}
totedge = ccgSubSurf_getNumEdges(ss);
for (index = 0; index < totedge; index++) {
CCGEdge *e = ccgdm->edgeMap[index].edge;
int x;
for (x = 1; x < edgeSize - 1; x++, i++) {
vd = ccgSubSurf_getEdgeData(ss, e, x);
copy_v3_v3(CCG_elem_co(&key, vd), mvert[i].co);
}
}
totvert = ccgSubSurf_getNumVerts(ss);
for (index = 0; index < totvert; index++) {
CCGVert *v = ccgdm->vertMap[index].vert;
vd = ccgSubSurf_getVertData(ss, v);
copy_v3_v3(CCG_elem_co(&key, vd), mvert[i].co);
i++;
}
ccgSubSurf_updateToFaces(ss, 0, NULL, 0);
}
/* Loads a multires object stored in the old Multires struct into the new format */
static void multires_load_old_dm(DerivedMesh *dm, Mesh *me, int totlvl)
{
MultiresLevel *lvl, *lvl1;
Multires *mr = me->mr;
MVert *vsrc, *vdst;
unsigned int src, dst;
int st_last = multires_side_tot[totlvl - 1] - 1;
int extedgelen = multires_side_tot[totlvl] - 2;
int *vvmap; // inorder for dst, map to src
int crossedgelen;
int s, x, tottri, totquad;
unsigned int i, j, totvert;
src = 0;
vsrc = mr->verts;
vdst = dm->getVertArray(dm);
totvert = (unsigned int)dm->getNumVerts(dm);
vvmap = MEM_calloc_arrayN(totvert, sizeof(int), "multires vvmap");
if (!vvmap) {
return;
}
lvl1 = mr->levels.first;
/* Load base verts */
for (i = 0; i < lvl1->totvert; i++) {
vvmap[totvert - lvl1->totvert + i] = src;
src++;
}
/* Original edges */
dst = totvert - lvl1->totvert - extedgelen * lvl1->totedge;
for (i = 0; i < lvl1->totedge; i++) {
int ldst = dst + extedgelen * i;
int lsrc = src;
lvl = lvl1->next;
for (j = 2; j <= mr->level_count; j++) {
int base = multires_side_tot[totlvl - j + 1] - 2;
int skip = multires_side_tot[totlvl - j + 2] - 1;
int st = multires_side_tot[j - 1] - 1;
for (x = 0; x < st; x++) {
vvmap[ldst + base + x * skip] = lsrc + st * i + x;
}
lsrc += lvl->totvert - lvl->prev->totvert;
lvl = lvl->next;
}
}
/* Center points */
dst = 0;
for (i = 0; i < lvl1->totface; i++) {
int sides = lvl1->faces[i].v[3] ? 4 : 3;
vvmap[dst] = src + lvl1->totedge + i;
dst += 1 + sides * (st_last - 1) * st_last;
}
/* The rest is only for level 3 and up */
if (lvl1->next && lvl1->next->next) {
ListBase **fmap, **emap;
IndexNode **fmem, **emem;
/* Face edge cross */
tottri = totquad = 0;
crossedgelen = multires_side_tot[totlvl - 1] - 2;
dst = 0;
for (i = 0; i < lvl1->totface; i++) {
int sides = lvl1->faces[i].v[3] ? 4 : 3;
lvl = lvl1->next->next;
dst++;
for (j = 3; j <= mr->level_count; j++) {
int base = multires_side_tot[totlvl - j + 1] - 2;
int skip = multires_side_tot[totlvl - j + 2] - 1;
int st = pow(2, j - 2);
int st2 = pow(2, j - 3);
int lsrc = lvl->prev->totvert;
/* Skip exterior edge verts */
lsrc += lvl1->totedge * st;
/* Skip earlier face edge crosses */
lsrc += st2 * (tottri * 3 + totquad * 4);
for (s = 0; s < sides; s++) {
for (x = 0; x < st2; x++) {
vvmap[dst + crossedgelen * (s + 1) - base - x * skip - 1] = lsrc;
lsrc++;
}
}
lvl = lvl->next;
}
dst += sides * (st_last - 1) * st_last;
if (sides == 4) {
totquad++;
}
else {
tottri++;
}
}
/* calculate vert to edge/face maps for each level (except the last) */
fmap = MEM_calloc_arrayN((mr->level_count - 1), sizeof(ListBase *), "multires fmap");
emap = MEM_calloc_arrayN((mr->level_count - 1), sizeof(ListBase *), "multires emap");
fmem = MEM_calloc_arrayN((mr->level_count - 1), sizeof(IndexNode *), "multires fmem");
emem = MEM_calloc_arrayN((mr->level_count - 1), sizeof(IndexNode *), "multires emem");
lvl = lvl1;
for (i = 0; i < (unsigned int)mr->level_count - 1; i++) {
create_old_vert_face_map(fmap + i, fmem + i, lvl->faces, lvl->totvert, lvl->totface);
create_old_vert_edge_map(emap + i, emem + i, lvl->edges, lvl->totvert, lvl->totedge);
lvl = lvl->next;
}
/* Interior face verts */
/* lvl = lvl1->next->next; */ /* UNUSED */
dst = 0;
for (j = 0; j < lvl1->totface; j++) {
int sides = lvl1->faces[j].v[3] ? 4 : 3;
int ldst = dst + 1 + sides * (st_last - 1);
for (s = 0; s < sides; s++) {
int st2 = multires_side_tot[totlvl - 1] - 2;
int st3 = multires_side_tot[totlvl - 2] - 2;
int st4 = st3 == 0 ? 1 : (st3 + 1) / 2;
int mid = ldst + st2 * st3 + st3;
int cv = lvl1->faces[j].v[s];
int nv = lvl1->faces[j].v[s == sides - 1 ? 0 : s + 1];
int pv = lvl1->faces[j].v[s == 0 ? sides - 1 : s - 1];
multires_load_old_faces(fmap,
emap,
lvl1->next,
vvmap,
mid,
vvmap[dst],
cv,
find_old_edge(emap[0], lvl1->edges, pv, cv)->mid,
find_old_edge(emap[0], lvl1->edges, cv, nv)->mid,
st2,
st4);
ldst += (st_last - 1) * (st_last - 1);
}
dst = ldst;
}
/*lvl = lvl->next;*/ /*UNUSED*/
for (i = 0; i < (unsigned int)(mr->level_count - 1); i++) {
MEM_freeN(fmap[i]);
MEM_freeN(fmem[i]);
MEM_freeN(emap[i]);
MEM_freeN(emem[i]);
}
MEM_freeN(fmap);
MEM_freeN(emap);
MEM_freeN(fmem);
MEM_freeN(emem);
}
/* Transfer verts */
for (i = 0; i < totvert; i++) {
copy_v3_v3(vdst[i].co, vsrc[vvmap[i]].co);
}
MEM_freeN(vvmap);
multires_mvert_to_ss(dm, vdst);
}
/* Copy the first-level vcol data to the mesh, if it exists */
/* Warning: higher-level vcol data will be lost */
static void multires_load_old_vcols(Mesh *me)
{
MultiresLevel *lvl;
MultiresColFace *colface;
MCol *mcol;
int i, j;
if (!(lvl = me->mr->levels.first)) {
return;
}
if (!(colface = lvl->colfaces)) {
return;
}
/* older multires format never supported multiple vcol layers,
* so we can assume the active vcol layer is the correct one */
if (!(mcol = CustomData_get_layer(&me->fdata, CD_MCOL))) {
return;
}
for (i = 0; i < me->totface; i++) {
for (j = 0; j < 4; j++) {
mcol[i * 4 + j].a = colface[i].col[j].a;
mcol[i * 4 + j].r = colface[i].col[j].r;
mcol[i * 4 + j].g = colface[i].col[j].g;
mcol[i * 4 + j].b = colface[i].col[j].b;
}
}
}
/* Copy the first-level face-flag data to the mesh */
static void multires_load_old_face_flags(Mesh *me)
{
MultiresLevel *lvl;
MultiresFace *faces;
int i;
if (!(lvl = me->mr->levels.first)) {
return;
}
if (!(faces = lvl->faces)) {
return;
}
for (i = 0; i < me->totface; i++) {
me->mface[i].flag = faces[i].flag;
}
}
void multires_load_old(Object *ob, Mesh *me)
{
MultiresLevel *lvl;
ModifierData *md;
MultiresModifierData *mmd;
DerivedMesh *dm, *orig;
CustomDataLayer *l;
int i;
/* Load original level into the mesh */
lvl = me->mr->levels.first;
CustomData_free_layers(&me->vdata, CD_MVERT, lvl->totvert);
CustomData_free_layers(&me->edata, CD_MEDGE, lvl->totedge);
CustomData_free_layers(&me->fdata, CD_MFACE, lvl->totface);
me->totvert = lvl->totvert;
me->totedge = lvl->totedge;
me->totface = lvl->totface;
me->mvert = CustomData_add_layer(&me->vdata, CD_MVERT, CD_CALLOC, NULL, me->totvert);
me->medge = CustomData_add_layer(&me->edata, CD_MEDGE, CD_CALLOC, NULL, me->totedge);
me->mface = CustomData_add_layer(&me->fdata, CD_MFACE, CD_CALLOC, NULL, me->totface);
memcpy(me->mvert, me->mr->verts, sizeof(MVert) * me->totvert);
for (i = 0; i < me->totedge; i++) {
me->medge[i].v1 = lvl->edges[i].v[0];
me->medge[i].v2 = lvl->edges[i].v[1];
}
for (i = 0; i < me->totface; i++) {
me->mface[i].v1 = lvl->faces[i].v[0];
me->mface[i].v2 = lvl->faces[i].v[1];
me->mface[i].v3 = lvl->faces[i].v[2];
me->mface[i].v4 = lvl->faces[i].v[3];
me->mface[i].mat_nr = lvl->faces[i].mat_nr;
}
/* Copy the first-level data to the mesh */
/* XXX We must do this before converting tessfaces to polys/lopps! */
for (i = 0, l = me->mr->vdata.layers; i < me->mr->vdata.totlayer; i++, l++) {
CustomData_add_layer(&me->vdata, l->type, CD_REFERENCE, l->data, me->totvert);
}
for (i = 0, l = me->mr->fdata.layers; i < me->mr->fdata.totlayer; i++, l++) {
CustomData_add_layer(&me->fdata, l->type, CD_REFERENCE, l->data, me->totface);
}
CustomData_reset(&me->mr->vdata);
CustomData_reset(&me->mr->fdata);
multires_load_old_vcols(me);
multires_load_old_face_flags(me);
/* multiresModifier_subdivide_legacy (actually, multires_subdivide_legacy) expects polys, not
* tessfaces! */
BKE_mesh_convert_mfaces_to_mpolys(me);
/* Add a multires modifier to the object */
md = ob->modifiers.first;
while (md && BKE_modifier_get_info(md->type)->type == eModifierTypeType_OnlyDeform) {
md = md->next;
}
mmd = (MultiresModifierData *)BKE_modifier_new(eModifierType_Multires);
BLI_insertlinkbefore(&ob->modifiers, md, mmd);
for (i = 0; i < me->mr->level_count - 1; i++) {
multiresModifier_subdivide_legacy(mmd, NULL, ob, 1, 0);
}
mmd->lvl = mmd->totlvl;
orig = CDDM_from_mesh(me);
/* XXX We *must* alloc paint mask here, else we have some kind of mismatch in
* multires_modifier_update_mdisps() (called by dm->release(dm)), which always creates the
* reference subsurfed dm with this option, before calling multiresModifier_disp_run(),
* which implicitly expects both subsurfs from its first dm and oldGridData parameters to
* be of the same "format"! */
dm = multires_make_derived_from_derived(orig, mmd, NULL, ob, 0);
multires_load_old_dm(dm, me, mmd->totlvl + 1);
multires_dm_mark_as_modified(dm, MULTIRES_COORDS_MODIFIED);
dm->release(dm);
orig->release(orig);
/* Remove the old multires */
multires_free(me->mr);
me->mr = NULL;
}
/* If 'ob_src' and 'ob_dst' both have multires modifiers, synchronize them
* such that 'ob_dst' has the same total number of levels as 'ob_src'. */
void multiresModifier_sync_levels_ex(Object *ob_dst,

View File

@ -799,20 +799,6 @@ void blo_do_versions_250(FileData *fd, Library *lib, Main *bmain)
// BLI_freelistN(&pidlist);
if (ob->type == OB_MESH) {
Mesh *me = blo_do_versions_newlibadr(fd, lib, ob->data);
void *olddata = ob->data;
ob->data = me;
/* XXX - library meshes crash on loading most yoFrankie levels,
* the multires pointer gets invalid - Campbell */
if (me && me->id.lib == NULL && me->mr && me->mr->level_count > 1) {
multires_load_old(ob, me);
}
ob->data = olddata;
}
if (ob->totcol && ob->matbits == NULL) {
int a;
@ -1152,7 +1138,7 @@ void blo_do_versions_250(FileData *fd, Library *lib, Main *bmain)
if (bmain->versionfile == 250 && bmain->subversionfile > 1) {
for (me = bmain->meshes.first; me; me = me->id.next) {
multires_load_old_250(me);
CustomData_free_layer_active(&me->fdata, CD_MDISPS, me->totface);
}
for (ob = bmain->objects.first; ob; ob = ob->id.next) {

View File

@ -1959,7 +1959,6 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *bmain)
Light *la;
Material *ma;
ParticleSettings *part;
Mesh *me;
bNodeTree *ntree;
Tex *tex;
ModifierData *md;
@ -2074,23 +2073,6 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *bmain)
}
}
/* Copy over old per-level multires vertex data
* into a single vertex array in struct Multires */
for (me = bmain->meshes.first; me; me = me->id.next) {
if (me->mr && !me->mr->verts) {
MultiresLevel *lvl = me->mr->levels.last;
if (lvl) {
me->mr->verts = lvl->verts;
lvl->verts = NULL;
/* Don't need the other vert arrays */
for (lvl = lvl->prev; lvl; lvl = lvl->prev) {
MEM_freeN(lvl->verts);
lvl->verts = NULL;
}
}
}
}
if (bmain->versionfile != 245 || bmain->subversionfile < 1) {
for (la = bmain->lights.first; la; la = la->id.next) {
la->falloff_type = LA_FALLOFF_INVLINEAR;

View File

@ -48,7 +48,6 @@ struct MPropCol;
struct MVert;
struct Material;
struct Mesh;
struct Multires;
struct SubdivCCG;
#
@ -230,9 +229,6 @@ typedef struct Mesh {
* default and Face Sets can be used without affecting the color of the mesh. */
int face_sets_color_default;
/** Deprecated multiresolution modeling data, only keep for loading old files. */
struct Multires *mr DNA_DEPRECATED;
Mesh_Runtime runtime;
} Mesh;

View File

@ -518,54 +518,4 @@ typedef struct MRecast {
int i;
} MRecast;
/** Multires structs kept for compatibility with old files. */
typedef struct MultiresCol {
float a, r, g, b;
} MultiresCol;
typedef struct MultiresColFace {
/* vertex colors */
MultiresCol col[4];
} MultiresColFace;
typedef struct MultiresFace {
unsigned int v[4];
unsigned int mid;
char flag, mat_nr, _pad[2];
} MultiresFace;
typedef struct MultiresEdge {
unsigned int v[2];
unsigned int mid;
} MultiresEdge;
typedef struct MultiresLevel {
struct MultiresLevel *next, *prev;
MultiresFace *faces;
MultiresColFace *colfaces;
MultiresEdge *edges;
unsigned int totvert, totface, totedge;
char _pad[4];
/* Kept for compatibility with even older files */
MVert *verts;
} MultiresLevel;
typedef struct Multires {
ListBase levels;
MVert *verts;
unsigned char level_count, current, newlvl, edgelvl, pinlvl, renderlvl;
unsigned char use_col, flag;
/* Special level 1 data that cannot be modified from other levels */
CustomData vdata;
CustomData fdata;
short *edge_flags;
char *edge_creases;
} Multires;
/* End multi-res structs. */
/** \} */