Cleanup: some refactoring in mapped mesh extraction

* Flip the logic to first detect if we are dealing with an unmodified mesh
  in editmode. And then if not, detect if we need a mapping or not.
* runtime.is_original is only valid for the bmesh wrapper. Rename it to clarify
  that and only check it when the mesh is a bmesh wrapper.
* Remove MR_EXTRACT_MAPPED and instead check only for the existence of the
  origindex arrays. Previously it would sometimes access those arrays without
  MR_EXTRACT_MAPPED set, which according to a comment means they are invalid.

Differential Revision: https://developer.blender.org/D15676
This commit is contained in:
Brecht Van Lommel 2022-08-16 17:34:40 +02:00
parent 74d716ce23
commit b247588dc0
Notes: blender-bot 2024-04-29 13:07:32 +02:00
Referenced by commit 9ca1abe042, Fix T101100: missing smooth shading with linked subdivision surface in editmode
Referenced by issue #103706, Generative modifiers (Bevel, Triangulate, ...) wireframe not drawn correctly in Edit Mode
Referenced by issue #103700, Regression: Optimal Display still can't be turned off in Edit Mode (New problem)
Referenced by issue #103396, Regression: Crash when extruding a creased vertex in GPU subdivision
Referenced by issue #102579, Regresion: Wireframe overlay not displayed on objects (with geometry nodes modifier using mesh primitives) with particle systems
Referenced by issue #102393, With enabled Modifier On Cage option crashes on entering Edit Mode if in Render Viewport Shading
Referenced by issue #101100, Regression: Linked duplicate does not respect the smooth shading property in edit mode
24 changed files with 95 additions and 108 deletions

View File

@ -113,7 +113,7 @@ static void mesh_copy_data(Main *bmain, ID *id_dst, const ID *id_src, const int
*
* While this could be the callers responsibility, keep here since it's
* highly unlikely we want to create a duplicate and not use it for drawing. */
mesh_dst->runtime.is_original = false;
mesh_dst->runtime.is_original_bmesh = false;
/* Only do tessface if we have no polys. */
const bool do_tessface = ((mesh_src->totface != 0) && (mesh_src->totpoly == 0));

View File

@ -58,7 +58,8 @@ char *BKE_mesh_debug_info(const Mesh *me)
BLI_dynstr_appendf(dynstr, " 'totpoly': %d,\n", me->totpoly);
BLI_dynstr_appendf(dynstr, " 'runtime.deformed_only': %d,\n", me->runtime.deformed_only);
BLI_dynstr_appendf(dynstr, " 'runtime.is_original': %d,\n", me->runtime.is_original);
BLI_dynstr_appendf(
dynstr, " 'runtime.is_original_bmesh': %d,\n", me->runtime.is_original_bmesh);
BLI_dynstr_append(dynstr, " 'vert_layers': (\n");
CustomData_debug_info_from_layers(&me->vdata, indent8, dynstr);

View File

@ -61,7 +61,7 @@ Mesh *BKE_mesh_wrapper_from_editmesh_with_coords(BMEditMesh *em,
}
/* Use edit-mesh directly where possible. */
me->runtime.is_original = true;
me->runtime.is_original_bmesh = true;
me->edit_mesh = static_cast<BMEditMesh *>(MEM_dupallocN(em));
me->edit_mesh->is_shallow_copy = true;
@ -133,7 +133,7 @@ void BKE_mesh_wrapper_ensure_mdata(Mesh *me)
EditMeshData *edit_data = me->runtime.edit_data;
if (edit_data->vertexCos) {
BKE_mesh_vert_coords_apply(me, edit_data->vertexCos);
me->runtime.is_original = false;
me->runtime.is_original_bmesh = false;
}
break;
}

View File

@ -494,17 +494,6 @@ MeshRenderData *mesh_render_data_create(Object *object,
mr->bm_poly_centers = mr->edit_data->polyCos;
}
/* A subdivision wrapper may be created in edit mode when X-ray is turned on to ensure that the
* topology seen by the user matches the one used for the selection routines. This wrapper
* seemingly takes precedence over the MDATA one, however the mesh we use for rendering is not
* the subdivided one, but the one where the MDATA wrapper would have been added. So consider
* the subdivision wrapper as well for the `has_mdata` case. */
bool has_mdata = is_mode_active && ELEM(mr->me->runtime.wrapper_type,
ME_WRAPPER_TYPE_MDATA,
ME_WRAPPER_TYPE_SUBD);
bool use_mapped = is_mode_active &&
(has_mdata && !do_uvedit && mr->me && !mr->me->runtime.is_original);
int bm_ensure_types = BM_VERT | BM_EDGE | BM_LOOP | BM_FACE;
BM_mesh_elem_index_ensure(mr->bm, bm_ensure_types);
@ -523,43 +512,51 @@ MeshRenderData *mesh_render_data_create(Object *object,
mr->freestyle_face_ofs = CustomData_get_offset(&mr->bm->pdata, CD_FREESTYLE_FACE);
#endif
if (use_mapped) {
mr->v_origindex = static_cast<const int *>(
CustomData_get_layer(&mr->me->vdata, CD_ORIGINDEX));
mr->e_origindex = static_cast<const int *>(
CustomData_get_layer(&mr->me->edata, CD_ORIGINDEX));
mr->p_origindex = static_cast<const int *>(
CustomData_get_layer(&mr->me->pdata, CD_ORIGINDEX));
use_mapped = (mr->v_origindex || mr->e_origindex || mr->p_origindex);
/* Use bmesh directly when the object is in edit mode unchanged by any modifiers.
* For non-final UVs, always use original bmesh since the UV editor does not support
* using the cage mesh with deformed coordinates. */
if ((is_mode_active && mr->me->runtime.is_original_bmesh &&
mr->me->runtime.wrapper_type == ME_WRAPPER_TYPE_BMESH) ||
(do_uvedit && !do_final)) {
mr->extract_type = MR_EXTRACT_BMESH;
}
mr->extract_type = use_mapped ? MR_EXTRACT_MAPPED : MR_EXTRACT_BMESH;
/* Seems like the mesh_eval_final do not have the right origin indices.
* Force not mapped in this case. */
if (has_mdata && do_final && editmesh_eval_final != editmesh_eval_cage) {
// mr->edit_bmesh = NULL;
else {
mr->extract_type = MR_EXTRACT_MESH;
/* Use mapping from final to original mesh when the object is in edit mode. */
if (is_mode_active && do_final) {
mr->v_origindex = static_cast<const int *>(
CustomData_get_layer(&mr->me->vdata, CD_ORIGINDEX));
mr->e_origindex = static_cast<const int *>(
CustomData_get_layer(&mr->me->edata, CD_ORIGINDEX));
mr->p_origindex = static_cast<const int *>(
CustomData_get_layer(&mr->me->pdata, CD_ORIGINDEX));
}
else {
mr->v_origindex = nullptr;
mr->e_origindex = nullptr;
mr->p_origindex = nullptr;
}
}
}
else {
mr->me = me;
mr->edit_bmesh = nullptr;
mr->extract_type = MR_EXTRACT_MESH;
bool use_mapped = is_paint_mode && mr->me && !mr->me->runtime.is_original;
if (use_mapped) {
if (is_paint_mode && mr->me) {
mr->v_origindex = static_cast<const int *>(
CustomData_get_layer(&mr->me->vdata, CD_ORIGINDEX));
mr->e_origindex = static_cast<const int *>(
CustomData_get_layer(&mr->me->edata, CD_ORIGINDEX));
mr->p_origindex = static_cast<const int *>(
CustomData_get_layer(&mr->me->pdata, CD_ORIGINDEX));
use_mapped = (mr->v_origindex || mr->e_origindex || mr->p_origindex);
}
mr->extract_type = use_mapped ? MR_EXTRACT_MAPPED : MR_EXTRACT_MESH;
else {
mr->v_origindex = nullptr;
mr->e_origindex = nullptr;
mr->p_origindex = nullptr;
}
}
if (mr->extract_type != MR_EXTRACT_BMESH) {

View File

@ -1514,7 +1514,7 @@ void DRW_mesh_batch_cache_create_requested(struct TaskGraph *task_graph,
Mesh *editmesh_eval_cage = BKE_object_get_editmesh_eval_cage(ob);
do_cage = editmesh_eval_final != editmesh_eval_cage;
do_uvcage = !(editmesh_eval_final->runtime.is_original &&
do_uvcage = !(editmesh_eval_final->runtime.is_original_bmesh &&
editmesh_eval_final->runtime.wrapper_type == ME_WRAPPER_TYPE_BMESH);
}

View File

@ -724,7 +724,7 @@ static void draw_subdiv_cache_update_extra_coarse_face_data(DRWSubdivCache *cach
if (mr->extract_type == MR_EXTRACT_BMESH) {
draw_subdiv_cache_extra_coarse_face_data_bm(cache->bm, mr->efa_act, flags_data);
}
else if (mr->extract_type == MR_EXTRACT_MAPPED) {
else if (mr->p_origindex != NULL) {
draw_subdiv_cache_extra_coarse_face_data_mapped(mesh, cache->bm, mr, flags_data);
}
else {

View File

@ -29,7 +29,6 @@ struct DRWSubdivCache;
enum eMRExtractType {
MR_EXTRACT_BMESH,
MR_EXTRACT_MAPPED,
MR_EXTRACT_MESH,
};

View File

@ -58,14 +58,13 @@ static void extract_lines_iter_poly_mesh(const MeshRenderData *mr,
GPUIndexBufBuilder *elb = static_cast<GPUIndexBufBuilder *>(data);
/* Using poly & loop iterator would complicate accessing the adjacent loop. */
const MLoop *mloop = mr->mloop;
if (mr->use_hide || (mr->extract_type == MR_EXTRACT_MAPPED) || (mr->e_origindex != nullptr)) {
if (mr->use_hide || (mr->e_origindex != nullptr)) {
const int ml_index_last = mp->loopstart + (mp->totloop - 1);
int ml_index = ml_index_last, ml_index_next = mp->loopstart;
do {
const MLoop *ml = &mloop[ml_index];
if (!((mr->use_hide && mr->hide_edge && mr->hide_edge[ml->e]) ||
((mr->extract_type == MR_EXTRACT_MAPPED) && (mr->e_origindex) &&
(mr->e_origindex[ml->e] == ORIGINDEX_NONE)))) {
((mr->e_origindex) && (mr->e_origindex[ml->e] == ORIGINDEX_NONE)))) {
GPU_indexbuf_set_line_verts(elb, ml->e, ml_index, ml_index_next);
}
else {
@ -110,8 +109,7 @@ static void extract_lines_iter_ledge_mesh(const MeshRenderData *mr,
const int l_index_offset = mr->edge_len + ledge_index;
const int e_index = mr->ledges[ledge_index];
if (!((mr->use_hide && mr->hide_edge && mr->hide_edge[med - mr->medge]) ||
((mr->extract_type == MR_EXTRACT_MAPPED) && (mr->e_origindex) &&
(mr->e_origindex[e_index] == ORIGINDEX_NONE)))) {
((mr->e_origindex) && (mr->e_origindex[e_index] == ORIGINDEX_NONE)))) {
const int l_index = mr->loop_len + ledge_index * 2;
GPU_indexbuf_set_line_verts(elb, l_index_offset, l_index, l_index + 1);
}
@ -183,42 +181,43 @@ static void extract_lines_loose_geom_subdiv(const DRWSubdivCache *subdiv_cache,
switch (mr->extract_type) {
case MR_EXTRACT_MESH: {
const bool *hide_edge = mr->hide_edge;
if (hide_edge) {
for (DRWSubdivLooseEdge edge : loose_edges) {
*flags_data++ = hide_edge[edge.coarse_edge_index];
}
}
else {
MutableSpan<uint>(flags_data, loose_edges.size()).fill(0);
}
break;
}
case MR_EXTRACT_MAPPED: {
if (mr->bm) {
for (DRWSubdivLooseEdge edge : loose_edges) {
const BMEdge *bm_edge = bm_original_edge_get(mr, edge.coarse_edge_index);
*flags_data++ = BM_elem_flag_test_bool(bm_edge, BM_ELEM_HIDDEN) != 0;
}
}
else {
if (mr->e_origindex == nullptr) {
const bool *hide_edge = mr->hide_edge;
if (hide_edge) {
for (DRWSubdivLooseEdge edge : loose_edges) {
int e = edge.coarse_edge_index;
if (mr->e_origindex && mr->e_origindex[e] != ORIGINDEX_NONE) {
*flags_data++ = hide_edge[edge.coarse_edge_index];
}
else {
*flags_data++ = false;
}
*flags_data++ = hide_edge[edge.coarse_edge_index];
}
}
else {
MutableSpan<uint>(flags_data, loose_edges.size()).fill(0);
}
}
else {
if (mr->bm) {
for (DRWSubdivLooseEdge edge : loose_edges) {
const BMEdge *bm_edge = bm_original_edge_get(mr, edge.coarse_edge_index);
*flags_data++ = BM_elem_flag_test_bool(bm_edge, BM_ELEM_HIDDEN) != 0;
}
}
else {
const bool *hide_edge = mr->hide_edge;
if (hide_edge) {
for (DRWSubdivLooseEdge edge : loose_edges) {
int e = edge.coarse_edge_index;
if (mr->e_origindex && mr->e_origindex[e] != ORIGINDEX_NONE) {
*flags_data++ = hide_edge[edge.coarse_edge_index];
}
else {
*flags_data++ = false;
}
}
}
else {
MutableSpan<uint>(flags_data, loose_edges.size()).fill(0);
}
}
}
break;
}
case MR_EXTRACT_BMESH: {

View File

@ -48,8 +48,7 @@ static void extract_lines_paint_mask_iter_poly_mesh(const MeshRenderData *mr,
const int e_index = ml->e;
if (!((mr->use_hide && mr->hide_edge && mr->hide_edge[e_index]) ||
((mr->extract_type == MR_EXTRACT_MAPPED) && (mr->e_origindex) &&
(mr->e_origindex[e_index] == ORIGINDEX_NONE)))) {
((mr->e_origindex) && (mr->e_origindex[e_index] == ORIGINDEX_NONE)))) {
const int ml_index_last = mp->totloop + mp->loopstart - 1;
const int ml_index_other = (ml_index == ml_index_last) ? mp->loopstart : (ml_index + 1);
@ -122,8 +121,7 @@ static void extract_lines_paint_mask_iter_subdiv_mesh(const DRWSubdivCache *subd
}
else {
if (!((mr->use_hide && mr->hide_edge && mr->hide_edge[coarse_edge_index]) ||
((mr->extract_type == MR_EXTRACT_MAPPED) && (mr->e_origindex) &&
(mr->e_origindex[coarse_edge_index] == ORIGINDEX_NONE)))) {
((mr->e_origindex) && (mr->e_origindex[coarse_edge_index] == ORIGINDEX_NONE)))) {
const uint ml_index_other = (loop_idx == (end_loop_idx - 1)) ? start_loop_idx :
loop_idx + 1;
if (coarse_quad->flag & ME_FACE_SEL) {

View File

@ -45,8 +45,7 @@ BLI_INLINE void vert_set_mesh(GPUIndexBufBuilder *elb,
{
const bool hidden = mr->use_hide && mr->hide_vert && mr->hide_vert[v_index];
if (!(hidden || ((mr->extract_type == MR_EXTRACT_MAPPED) && (mr->v_origindex) &&
(mr->v_origindex[v_index] == ORIGINDEX_NONE)))) {
if (!(hidden || ((mr->v_origindex) && (mr->v_origindex[v_index] == ORIGINDEX_NONE)))) {
GPU_indexbuf_set_point_vert(elb, v_index, l_index);
}
else {

View File

@ -97,7 +97,7 @@ static void extract_edituv_stretch_angle_init(const MeshRenderData *mr,
data->cd_ofs = CustomData_get_offset(&mr->bm->ldata, CD_MLOOPUV);
}
else {
BLI_assert(ELEM(mr->extract_type, MR_EXTRACT_MAPPED, MR_EXTRACT_MESH));
BLI_assert(mr->extract_type == MR_EXTRACT_MESH);
data->luv = (const MLoopUV *)CustomData_get_layer(&mr->me->ldata, CD_MLOOPUV);
}
}

View File

@ -72,7 +72,7 @@ static void compute_area_ratio(const MeshRenderData *mr,
}
}
else {
BLI_assert(ELEM(mr->extract_type, MR_EXTRACT_MAPPED, MR_EXTRACT_MESH));
BLI_assert(mr->extract_type == MR_EXTRACT_MESH);
const MLoopUV *uv_data = (const MLoopUV *)CustomData_get_layer(&mr->me->ldata, CD_MLOOPUV);
const MPoly *mp = mr->mpoly;
for (int mp_index = 0; mp_index < mr->poly_len; mp_index++, mp++) {
@ -117,7 +117,7 @@ static void extract_edituv_stretch_area_finish(const MeshRenderData *mr,
}
}
else {
BLI_assert(ELEM(mr->extract_type, MR_EXTRACT_MAPPED, MR_EXTRACT_MESH));
BLI_assert(mr->extract_type == MR_EXTRACT_MESH);
const MPoly *mp = mr->mpoly;
for (int mp_index = 0, l_index = 0; mp_index < mr->poly_len; mp_index++, mp++) {
for (int i = 0; i < mp->totloop; i++, l_index++) {

View File

@ -48,8 +48,7 @@ static void extract_fdots_nor_finish(const MeshRenderData *mr,
for (int f = 0; f < mr->poly_len; f++) {
efa = BM_face_at_index(mr->bm, f);
const bool is_face_hidden = BM_elem_flag_test(efa, BM_ELEM_HIDDEN);
if (is_face_hidden || (mr->extract_type == MR_EXTRACT_MAPPED && mr->p_origindex &&
mr->p_origindex[f] == ORIGINDEX_NONE)) {
if (is_face_hidden || (mr->p_origindex && mr->p_origindex[f] == ORIGINDEX_NONE)) {
nor[f] = GPU_normal_convert_i10_v3(invalid_normal);
nor[f].w = NOR_AND_FLAG_HIDDEN;
}
@ -66,8 +65,7 @@ static void extract_fdots_nor_finish(const MeshRenderData *mr,
for (int f = 0; f < mr->poly_len; f++) {
efa = bm_original_face_get(mr, f);
const bool is_face_hidden = efa && BM_elem_flag_test(efa, BM_ELEM_HIDDEN);
if (is_face_hidden || (mr->extract_type == MR_EXTRACT_MAPPED && mr->p_origindex &&
mr->p_origindex[f] == ORIGINDEX_NONE)) {
if (is_face_hidden || (mr->p_origindex && mr->p_origindex[f] == ORIGINDEX_NONE)) {
nor[f] = GPU_normal_convert_i10_v3(invalid_normal);
nor[f].w = NOR_AND_FLAG_HIDDEN;
}
@ -130,8 +128,7 @@ static void extract_fdots_nor_hq_finish(const MeshRenderData *mr,
for (int f = 0; f < mr->poly_len; f++) {
efa = BM_face_at_index(mr->bm, f);
const bool is_face_hidden = BM_elem_flag_test(efa, BM_ELEM_HIDDEN);
if (is_face_hidden || (mr->extract_type == MR_EXTRACT_MAPPED && mr->p_origindex &&
mr->p_origindex[f] == ORIGINDEX_NONE)) {
if (is_face_hidden || (mr->p_origindex && mr->p_origindex[f] == ORIGINDEX_NONE)) {
normal_float_to_short_v3(&nor[f * 4], invalid_normal);
nor[f * 4 + 3] = NOR_AND_FLAG_HIDDEN;
}
@ -148,8 +145,7 @@ static void extract_fdots_nor_hq_finish(const MeshRenderData *mr,
for (int f = 0; f < mr->poly_len; f++) {
efa = bm_original_face_get(mr, f);
const bool is_face_hidden = efa && BM_elem_flag_test(efa, BM_ELEM_HIDDEN);
if (is_face_hidden || (mr->extract_type == MR_EXTRACT_MAPPED && mr->p_origindex &&
mr->p_origindex[f] == ORIGINDEX_NONE)) {
if (is_face_hidden || (mr->p_origindex && mr->p_origindex[f] == ORIGINDEX_NONE)) {
normal_float_to_short_v3(&nor[f * 4], invalid_normal);
nor[f * 4 + 3] = NOR_AND_FLAG_HIDDEN;
}

View File

@ -80,10 +80,10 @@ static void extract_lnor_iter_poly_mesh(const MeshRenderData *mr,
}
/* Flag for paint mode overlay.
* Only use MR_EXTRACT_MAPPED in edit mode where it is used to display the edge-normals.
* Only use origindex in edit mode where it is used to display the edge-normals.
* In paint mode it will use the un-mapped data to draw the wire-frame. */
if (hidden || (mr->edit_bmesh && mr->extract_type == MR_EXTRACT_MAPPED && (mr->v_origindex) &&
mr->v_origindex[ml->v] == ORIGINDEX_NONE)) {
if (hidden ||
(mr->edit_bmesh && (mr->v_origindex) && mr->v_origindex[ml->v] == ORIGINDEX_NONE)) {
lnor_data->w = -1;
}
else if (mp->flag & ME_FACE_SEL) {
@ -205,10 +205,10 @@ static void extract_lnor_hq_iter_poly_mesh(const MeshRenderData *mr,
}
/* Flag for paint mode overlay.
* Only use #MR_EXTRACT_MAPPED in edit mode where it is used to display the edge-normals.
* Only use origindex in edit mode where it is used to display the edge-normals.
* In paint mode it will use the un-mapped data to draw the wire-frame. */
if (hidden || (mr->edit_bmesh && mr->extract_type == MR_EXTRACT_MAPPED && (mr->v_origindex) &&
mr->v_origindex[ml->v] == ORIGINDEX_NONE)) {
if (hidden ||
(mr->edit_bmesh && (mr->v_origindex) && mr->v_origindex[ml->v] == ORIGINDEX_NONE)) {
lnor_data->w = -1;
}
else if (mp->flag & ME_FACE_SEL) {

View File

@ -101,8 +101,7 @@ static void extract_pos_nor_iter_poly_mesh(const MeshRenderData *mr,
vert->nor = data->normals[ml->v].low;
/* Flag for paint mode overlay. */
if (poly_hidden || vert_hidden ||
((mr->extract_type == MR_EXTRACT_MAPPED) && (mr->v_origindex) &&
(mr->v_origindex[ml->v] == ORIGINDEX_NONE))) {
((mr->v_origindex) && (mr->v_origindex[ml->v] == ORIGINDEX_NONE))) {
vert->nor.w = -1;
}
else if (mv->flag & SELECT) {
@ -449,8 +448,7 @@ static void extract_pos_nor_hq_iter_poly_mesh(const MeshRenderData *mr,
/* Flag for paint mode overlay. */
if (poly_hidden || vert_hidden ||
((mr->extract_type == MR_EXTRACT_MAPPED) && (mr->v_origindex) &&
(mr->v_origindex[ml->v] == ORIGINDEX_NONE))) {
((mr->v_origindex) && (mr->v_origindex[ml->v] == ORIGINDEX_NONE))) {
vert->nor[3] = -1;
}
else if (mv->flag & SELECT) {

View File

@ -112,7 +112,7 @@ typedef struct Mesh_Runtime {
* (most #eModifierTypeType_NonGeometrical modifiers). Otherwise the edit-mesh
* data will be used for drawing, missing changes from modifiers. See T79517.
*/
char is_original;
char is_original_bmesh;
/** #eMeshWrapperType and others. */
char wrapper_type;

View File

@ -211,7 +211,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
dtmd->defgrp_name,
invert_vgroup,
&reports)) {
result->runtime.is_original = false;
result->runtime.is_original_bmesh = false;
}
if (BKE_reports_contain(&reports, RPT_ERROR)) {

View File

@ -616,7 +616,7 @@ static Mesh *normalEditModifier_do(NormalEditModifierData *enmd,
MEM_SAFE_FREE(loopnors);
result->runtime.is_original = false;
result->runtime.is_original_bmesh = false;
return result;
}

View File

@ -284,7 +284,7 @@ static Mesh *uvprojectModifier_do(UVProjectModifierData *umd,
}
}
mesh->runtime.is_original = false;
mesh->runtime.is_original_bmesh = false;
return mesh;
}

View File

@ -220,7 +220,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
settings.use_threading = (polys_num > 1000);
BLI_task_parallel_range(0, polys_num, &data, uv_warp_compute, &settings);
mesh->runtime.is_original = false;
mesh->runtime.is_original_bmesh = false;
return mesh;
}

View File

@ -660,7 +660,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
MEM_SAFE_FREE(wn_data.mode_pair);
MEM_SAFE_FREE(wn_data.items_data);
result->runtime.is_original = false;
result->runtime.is_original_bmesh = false;
return result;
}

View File

@ -287,7 +287,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
MEM_freeN(new_w);
MEM_freeN(dw);
mesh->runtime.is_original = false;
mesh->runtime.is_original_bmesh = false;
/* Return the vgroup-modified mesh. */
return mesh;

View File

@ -444,7 +444,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
MEM_freeN(dw2);
MEM_SAFE_FREE(indices);
mesh->runtime.is_original = false;
mesh->runtime.is_original_bmesh = false;
/* Return the vgroup-modified mesh. */
return mesh;

View File

@ -640,7 +640,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
TIMEIT_END(perf);
#endif
mesh->runtime.is_original = false;
mesh->runtime.is_original_bmesh = false;
/* Return the vgroup-modified mesh. */
return mesh;