Fix T68857 EditUV: Crash on Remesh modifier with 'Display in Edit Mode'

This commit is contained in:
Clément Foucault 2019-10-08 18:35:57 +02:00
parent 656228945e
commit d98ae27f02
Notes: blender-bot 2023-02-14 08:59:10 +01:00
Referenced by commit dbb1f56e55, Fix T77290: Crash displaying vertex colors in edit mode
Referenced by commit b50b91c25d, Cleanup: Fix wrong assert introduced by rBd98ae27f02c7
Referenced by issue #77893, Crash doing certain modeling operations [customdata_typemap_is_valid]
Referenced by issue #68857, Crash on Remesh modifier with 'Display in Edit Mode'
3 changed files with 42 additions and 10 deletions

View File

@ -48,6 +48,9 @@ typedef struct DRW_MeshCDMask {
uint32_t vcol : 8;
uint32_t orco : 1;
uint32_t tan_orco : 1;
/** Edit uv layer is from the base edit mesh as
* modifiers could remove it. (see T68857) */
uint32_t edit_uv : 1;
} DRW_MeshCDMask;
typedef enum eMRIterType {

View File

@ -1601,6 +1601,14 @@ static void *extract_uv_init(const MeshRenderData *mr, void *buf)
CustomData *cd_ldata = (mr->extract_type == MR_EXTRACT_BMESH) ? &mr->bm->ldata : &mr->me->ldata;
uint32_t uv_layers = mr->cache->cd_used.uv;
/* HACK to fix T68857 */
if (mr->extract_type == MR_EXTRACT_BMESH && mr->cache->cd_used.edit_uv == 1) {
int layer = CustomData_get_active_layer(cd_ldata, CD_MLOOPUV);
if (layer != -1) {
uv_layers |= (1 << layer);
}
}
for (int i = 0; i < MAX_MTFACE; i++) {
if (uv_layers & (1 << i)) {
char attr_name[32], attr_safe_name[GPU_MAX_SAFE_ATTRIB_NAME];

View File

@ -90,9 +90,15 @@ BLI_INLINE void mesh_cd_layers_type_clear(DRW_MeshCDMask *a)
*((uint32_t *)a) = 0;
}
static void mesh_cd_calc_edit_uv_layer(const Mesh *UNUSED(me), DRW_MeshCDMask *cd_used)
{
cd_used->edit_uv = 1;
}
static void mesh_cd_calc_active_uv_layer(const Mesh *me, DRW_MeshCDMask *cd_used)
{
const CustomData *cd_ldata = (me->edit_mesh) ? &me->edit_mesh->bm->ldata : &me->ldata;
const Mesh *me_final = (me->edit_mesh) ? me->edit_mesh->mesh_eval_final : me;
const CustomData *cd_ldata = &me_final->ldata;
int layer = CustomData_get_active_layer(cd_ldata, CD_MLOOPUV);
if (layer != -1) {
@ -102,7 +108,8 @@ static void mesh_cd_calc_active_uv_layer(const Mesh *me, DRW_MeshCDMask *cd_used
static void mesh_cd_calc_active_mask_uv_layer(const Mesh *me, DRW_MeshCDMask *cd_used)
{
const CustomData *cd_ldata = (me->edit_mesh) ? &me->edit_mesh->bm->ldata : &me->ldata;
const Mesh *me_final = (me->edit_mesh) ? me->edit_mesh->mesh_eval_final : me;
const CustomData *cd_ldata = &me_final->ldata;
int layer = CustomData_get_stencil_layer(cd_ldata, CD_MLOOPUV);
if (layer != -1) {
@ -112,7 +119,8 @@ static void mesh_cd_calc_active_mask_uv_layer(const Mesh *me, DRW_MeshCDMask *cd
static void mesh_cd_calc_active_vcol_layer(const Mesh *me, DRW_MeshCDMask *cd_used)
{
const CustomData *cd_ldata = (me->edit_mesh) ? &me->edit_mesh->bm->ldata : &me->ldata;
const Mesh *me_final = (me->edit_mesh) ? me->edit_mesh->mesh_eval_final : me;
const CustomData *cd_ldata = &me_final->ldata;
int layer = CustomData_get_active_layer(cd_ldata, CD_MLOOPCOL);
if (layer != -1) {
@ -884,6 +892,19 @@ GPUBatch *DRW_mesh_batch_cache_get_verts_with_select_id(Mesh *me)
/** \name UV Image editor API
* \{ */
static void edituv_request_active_uv(MeshBatchCache *cache, Mesh *me)
{
DRW_MeshCDMask cd_needed;
mesh_cd_layers_type_clear(&cd_needed);
mesh_cd_calc_edit_uv_layer(me, &cd_needed);
BLI_assert(cd_needed.uv != 0 &&
"No uv layer available in edituv, but batches requested anyway!");
mesh_cd_calc_active_mask_uv_layer(me, &cd_needed);
mesh_cd_layers_type_merge(&cache->cd_needed, cd_needed);
}
/* Creates the GPUBatch for drawing the UV Stretching Area Overlay.
* Optional retrieves the total area or total uv area of the mesh.
*
@ -894,7 +915,7 @@ GPUBatch *DRW_mesh_batch_cache_get_edituv_faces_stretch_area(Mesh *me,
float **tot_uv_area)
{
MeshBatchCache *cache = mesh_batch_cache_get(me);
texpaint_request_active_uv(cache, me);
edituv_request_active_uv(cache, me);
mesh_batch_cache_add_request(cache, MBC_EDITUV_FACES_STRETCH_AREA);
if (tot_area != NULL) {
@ -909,7 +930,7 @@ GPUBatch *DRW_mesh_batch_cache_get_edituv_faces_stretch_area(Mesh *me,
GPUBatch *DRW_mesh_batch_cache_get_edituv_faces_stretch_angle(Mesh *me)
{
MeshBatchCache *cache = mesh_batch_cache_get(me);
texpaint_request_active_uv(cache, me);
edituv_request_active_uv(cache, me);
mesh_batch_cache_add_request(cache, MBC_EDITUV_FACES_STRETCH_ANGLE);
return DRW_batch_request(&cache->batch.edituv_faces_stretch_angle);
}
@ -917,7 +938,7 @@ GPUBatch *DRW_mesh_batch_cache_get_edituv_faces_stretch_angle(Mesh *me)
GPUBatch *DRW_mesh_batch_cache_get_edituv_faces(Mesh *me)
{
MeshBatchCache *cache = mesh_batch_cache_get(me);
texpaint_request_active_uv(cache, me);
edituv_request_active_uv(cache, me);
mesh_batch_cache_add_request(cache, MBC_EDITUV_FACES);
return DRW_batch_request(&cache->batch.edituv_faces);
}
@ -925,7 +946,7 @@ GPUBatch *DRW_mesh_batch_cache_get_edituv_faces(Mesh *me)
GPUBatch *DRW_mesh_batch_cache_get_edituv_edges(Mesh *me)
{
MeshBatchCache *cache = mesh_batch_cache_get(me);
texpaint_request_active_uv(cache, me);
edituv_request_active_uv(cache, me);
mesh_batch_cache_add_request(cache, MBC_EDITUV_EDGES);
return DRW_batch_request(&cache->batch.edituv_edges);
}
@ -933,7 +954,7 @@ GPUBatch *DRW_mesh_batch_cache_get_edituv_edges(Mesh *me)
GPUBatch *DRW_mesh_batch_cache_get_edituv_verts(Mesh *me)
{
MeshBatchCache *cache = mesh_batch_cache_get(me);
texpaint_request_active_uv(cache, me);
edituv_request_active_uv(cache, me);
mesh_batch_cache_add_request(cache, MBC_EDITUV_VERTS);
return DRW_batch_request(&cache->batch.edituv_verts);
}
@ -941,7 +962,7 @@ GPUBatch *DRW_mesh_batch_cache_get_edituv_verts(Mesh *me)
GPUBatch *DRW_mesh_batch_cache_get_edituv_facedots(Mesh *me)
{
MeshBatchCache *cache = mesh_batch_cache_get(me);
texpaint_request_active_uv(cache, me);
edituv_request_active_uv(cache, me);
mesh_batch_cache_add_request(cache, MBC_EDITUV_FACEDOTS);
return DRW_batch_request(&cache->batch.edituv_fdots);
}
@ -949,7 +970,7 @@ GPUBatch *DRW_mesh_batch_cache_get_edituv_facedots(Mesh *me)
GPUBatch *DRW_mesh_batch_cache_get_uv_edges(Mesh *me)
{
MeshBatchCache *cache = mesh_batch_cache_get(me);
texpaint_request_active_uv(cache, me);
edituv_request_active_uv(cache, me);
mesh_batch_cache_add_request(cache, MBC_WIRE_LOOPS_UVS);
return DRW_batch_request(&cache->batch.wire_loops_uvs);
}