Fix T74686: Loading btx file in multires modifier is not working
Was happening when object does not have CD_MDISPS allocated yet. Need to make sure totdisp and level is specified on CD_MDISPS data prior to loading (as the load expects them to be properly set).
This commit is contained in:
@@ -130,6 +130,10 @@ int multires_mdisp_corners(struct MDisps *s);
|
||||
/* update multires data after topology changing */
|
||||
void multires_topology_changed(struct Mesh *me);
|
||||
|
||||
void multires_ensure_external_read(struct Mesh *mesh, int top_level);
|
||||
void multiresModifier_ensure_external_read(struct Mesh *mesh,
|
||||
const struct MultiresModifierData *mmd);
|
||||
|
||||
/**** interpolation stuff ****/
|
||||
void old_mdisps_bilinear(float out[3], float (*disps)[3], const int st, float u, float v);
|
||||
int mdisp_rot_face_to_crn(struct MVert *mvert,
|
||||
|
||||
@@ -3576,6 +3576,7 @@ void BKE_mesh_convert_mfaces_to_mpolys_ex(ID *id,
|
||||
|
||||
if (id) {
|
||||
/* ensure external data is transferred */
|
||||
/* TODO(sergey): Use multiresModifier_ensure_external_read(). */
|
||||
CustomData_external_read(fdata, id, CD_MASK_MDISPS, totface_i);
|
||||
}
|
||||
|
||||
|
||||
@@ -647,7 +647,7 @@ static void multires_del_higher(MultiresModifierData *mmd, Object *ob, int lvl)
|
||||
GridPaintMask *gpm;
|
||||
|
||||
multires_set_tot_mdisps(me, mmd->totlvl);
|
||||
CustomData_external_read(&me->ldata, &me->id, CD_MASK_MDISPS, me->totloop);
|
||||
multiresModifier_ensure_external_read(me, mmd);
|
||||
mdisps = CustomData_get_layer(&me->ldata, CD_MDISPS);
|
||||
gpm = CustomData_get_layer(&me->ldata, CD_GRID_PAINT_MASK);
|
||||
|
||||
@@ -713,7 +713,7 @@ void multiresModifier_del_levels(MultiresModifierData *mmd,
|
||||
MDisps *mdisps;
|
||||
|
||||
multires_set_tot_mdisps(me, mmd->totlvl);
|
||||
CustomData_external_read(&me->ldata, &me->id, CD_MASK_MDISPS, me->totloop);
|
||||
multiresModifier_ensure_external_read(me, mmd);
|
||||
mdisps = CustomData_get_layer(&me->ldata, CD_MDISPS);
|
||||
|
||||
multires_force_sculpt_rebuild(ob);
|
||||
@@ -1144,7 +1144,7 @@ void multires_modifier_update_mdisps(struct DerivedMesh *dm, Scene *scene)
|
||||
me = ccgdm->multires.ob->data;
|
||||
mmd = ccgdm->multires.mmd;
|
||||
multires_set_tot_mdisps(me, mmd->totlvl);
|
||||
CustomData_external_read(&me->ldata, &me->id, CD_MASK_MDISPS, me->totloop);
|
||||
multiresModifier_ensure_external_read(me, mmd);
|
||||
mdisps = CustomData_get_layer(&me->ldata, CD_MDISPS);
|
||||
|
||||
if (mdisps) {
|
||||
@@ -1372,7 +1372,7 @@ DerivedMesh *multires_make_derived_from_derived(
|
||||
}
|
||||
|
||||
multires_set_tot_mdisps(me, mmd->totlvl);
|
||||
CustomData_external_read(&me->ldata, &me->id, CD_MASK_MDISPS, me->totloop);
|
||||
multiresModifier_ensure_external_read(me, mmd);
|
||||
|
||||
/*run displacement*/
|
||||
multiresModifier_disp_run(result, ob->data, dm, APPLY_DISPLACEMENTS, subGridData, mmd->totlvl);
|
||||
@@ -2224,7 +2224,7 @@ static void multires_apply_smat(struct Depsgraph *UNUSED(depsgraph),
|
||||
}
|
||||
/* Make sure layer present. */
|
||||
Mesh *mesh = (Mesh *)object->data;
|
||||
CustomData_external_read(&mesh->ldata, &mesh->id, CD_MASK_MDISPS, mesh->totloop);
|
||||
multiresModifier_ensure_external_read(mesh, mmd);
|
||||
if (!CustomData_get_layer(&mesh->ldata, CD_MDISPS)) {
|
||||
return;
|
||||
}
|
||||
@@ -2318,6 +2318,44 @@ void multires_topology_changed(Mesh *me)
|
||||
}
|
||||
}
|
||||
|
||||
/* Makes sure data from an external file is fully read.
|
||||
*
|
||||
* Since the multires data files only contain displacement vectors without knowledge about
|
||||
* subdivision level some extra work is needed. Namely make is to all displacement grids have
|
||||
* proper level and number of displacement vectors set. */
|
||||
void multires_ensure_external_read(struct Mesh *mesh, int top_level)
|
||||
{
|
||||
if (!CustomData_external_test(&mesh->ldata, CD_MDISPS)) {
|
||||
return;
|
||||
}
|
||||
|
||||
MDisps *mdisps = CustomData_get_layer(&mesh->ldata, CD_MDISPS);
|
||||
if (mdisps == NULL) {
|
||||
mdisps = CustomData_add_layer(&mesh->ldata, CD_MDISPS, CD_DEFAULT, NULL, mesh->totloop);
|
||||
}
|
||||
|
||||
const int totloop = mesh->totloop;
|
||||
|
||||
for (int i = 0; i < totloop; ++i) {
|
||||
if (mdisps[i].level != top_level) {
|
||||
MEM_SAFE_FREE(mdisps[i].disps);
|
||||
}
|
||||
|
||||
/* NOTE: CustomData_external_read will take care of allocation of displacement vectors if
|
||||
* they are missing. */
|
||||
|
||||
const int totdisp = multires_grid_tot[top_level];
|
||||
mdisps[i].totdisp = totdisp;
|
||||
mdisps[i].level = top_level;
|
||||
}
|
||||
|
||||
CustomData_external_read(&mesh->ldata, &mesh->id, CD_MASK_MDISPS, mesh->totloop);
|
||||
}
|
||||
void multiresModifier_ensure_external_read(struct Mesh *mesh, const MultiresModifierData *mmd)
|
||||
{
|
||||
multires_ensure_external_read(mesh, mmd->totlvl);
|
||||
}
|
||||
|
||||
/***************** Multires interpolation stuff *****************/
|
||||
|
||||
/* Find per-corner coordinate with given per-face UV coord */
|
||||
|
||||
@@ -149,8 +149,7 @@ bool multiresModifier_reshapeFromCCG(const int tot_level,
|
||||
return false;
|
||||
}
|
||||
|
||||
CustomData_external_read(
|
||||
&coarse_mesh->ldata, &coarse_mesh->id, CD_MASK_MDISPS, coarse_mesh->totloop);
|
||||
multires_ensure_external_read(coarse_mesh, reshape_context.top.level);
|
||||
|
||||
multires_reshape_store_original_grids(&reshape_context);
|
||||
multires_reshape_ensure_grids(coarse_mesh, reshape_context.top.level);
|
||||
|
||||
@@ -47,6 +47,7 @@ typedef struct MultiresDisplacementData {
|
||||
int grid_size;
|
||||
/* Mesh is used to read external displacement. */
|
||||
Mesh *mesh;
|
||||
const MultiresModifierData *mmd;
|
||||
const MPoly *mpoly;
|
||||
const MDisps *mdisps;
|
||||
/* Indexed by ptex face index, contains polygon/corner which corresponds
|
||||
@@ -328,9 +329,7 @@ static int displacement_get_face_corner(MultiresDisplacementData *data,
|
||||
static void initialize(SubdivDisplacement *displacement)
|
||||
{
|
||||
MultiresDisplacementData *data = displacement->user_data;
|
||||
Mesh *mesh = data->mesh;
|
||||
/* Make sure external displacement is read. */
|
||||
CustomData_external_read(&mesh->ldata, &mesh->id, CD_MASK_MDISPS, mesh->totloop);
|
||||
multiresModifier_ensure_external_read(data->mesh, data->mmd);
|
||||
data->is_initialized = true;
|
||||
}
|
||||
|
||||
@@ -421,6 +420,7 @@ static void displacement_init_data(SubdivDisplacement *displacement,
|
||||
data->subdiv = subdiv;
|
||||
data->grid_size = BKE_subdiv_grid_size_from_level(mmd->totlvl);
|
||||
data->mesh = mesh;
|
||||
data->mmd = mmd;
|
||||
data->mpoly = mesh->mpoly;
|
||||
data->mdisps = CustomData_get_layer(&mesh->ldata, CD_MDISPS);
|
||||
data->face_ptex_offset = BKE_subdiv_face_ptex_offset_get(subdiv);
|
||||
|
||||
Reference in New Issue
Block a user